aboutsummaryrefslogtreecommitdiff
path: root/backends/platform
diff options
context:
space:
mode:
authorMichael Ball2019-10-27 11:59:25 -0700
committerBastien Bouclet2019-11-05 05:51:45 +0100
commit78de5724047f56bd3ecbfb9ab423bb6c943f6589 (patch)
tree907d06ec001443f28c97d2d39d0acaf4c2b6aee2 /backends/platform
parentb342d42ff9b881aa4a719a7079d94fff37705dd6 (diff)
downloadscummvm-rg350-78de5724047f56bd3ecbfb9ab423bb6c943f6589.tar.gz
scummvm-rg350-78de5724047f56bd3ecbfb9ab423bb6c943f6589.tar.bz2
scummvm-rg350-78de5724047f56bd3ecbfb9ab423bb6c943f6589.zip
3DS: Implement magnify mode toggle on L and move keyboard to Y/DRIGHT
Diffstat (limited to 'backends/platform')
-rw-r--r--backends/platform/3ds/README.md29
-rw-r--r--backends/platform/3ds/osystem-events.cpp72
-rw-r--r--backends/platform/3ds/osystem-graphics.cpp15
-rw-r--r--backends/platform/3ds/osystem.cpp5
-rw-r--r--backends/platform/3ds/osystem.h12
-rw-r--r--backends/platform/3ds/sprite.cpp11
-rw-r--r--backends/platform/3ds/sprite.h5
7 files changed, 133 insertions, 16 deletions
diff --git a/backends/platform/3ds/README.md b/backends/platform/3ds/README.md
index a5e24ee91d..2ee0f71213 100644
--- a/backends/platform/3ds/README.md
+++ b/backends/platform/3ds/README.md
@@ -12,6 +12,7 @@ Table of Contents:
* 2.1 Default key mappings
* 2.2 Hover mode
* 2.3 Drag mode
+ * 2.4 Magnify mode
3.0) Supported Games
@@ -64,7 +65,8 @@ depending on if you're right or left-handed.
| A / D-left | Left-click |
| X / D-up | Right-click |
| B / D-down | ESC (skips cutscenes and such) |
-| L | Use virtual keyboard |
+| Y / D-right| Use virtual keyboard |
+| L | Toggle magnify mode on/off |
| R | Toggle hover/drag modes |
| Start | Open game menu |
| Select | Open 3DS config menu |
@@ -81,6 +83,31 @@ mouse button without using buttons mapped to right/left-click.
Every time you touch and release the touchscreen, you are simulating the click and
release of the mouse buttons. At the moment, this is only a left-click.
+2.4) Magnify mode
+-----------------
+Due to the low resolutions of the 3DS's two screens (400x240 for the top, and 320x240
+for the bottom), games that run at a higher resolution will inevitably lose some visual
+detail from being scaled down. This can result in situations where essential information
+is undiscernable, such as text. Magnify mode increases the scale factor of the top screen
+back to 1; the bottom screen remains unchanged. The touchscreen can then be used to change
+which part of the game display is being magnified. This can all be done even in situations
+where the cursor is disabled, such as during full-motion video (FMV) segments.
+
+When activating magnify mode, touchscreen controls are automatically switched to hover
+mode; this is to reduce the risk of the user accidentally inputting a click when changing
+the magnified area via dragging the stylus. Clicking can still be done at will as in normal
+hover mode. Turning off magnify mode will revert controls back to what was being used
+previously (ex: if drag mode was in use prior to activating magnify mode, drag mode will
+be reactivated upon exiting magnify mode), as well as restore the top screen's previous
+scale factor.
+
+Currently magnify mode can only be used when the following conditions are met:
+ - In the 3DS config menu, "Use Screen" is set to "Both"
+ - A game is currently being played
+ - The horizontal and/or vertical resolution in-game is greater than that of the top screen
+
+Magnify mode cannot be used in the Launcher menu.
+
3.0) Supported Games
--------------------
The full game engine compatibility list can be found here:
diff --git a/backends/platform/3ds/osystem-events.cpp b/backends/platform/3ds/osystem-events.cpp
index de0f58426c..0e635f0e1f 100644
--- a/backends/platform/3ds/osystem-events.cpp
+++ b/backends/platform/3ds/osystem-events.cpp
@@ -33,6 +33,7 @@ namespace _3DS {
static Common::Mutex *eventMutex;
static InputMode inputMode = MODE_DRAG;
+static InputMode savedInputMode = MODE_DRAG;
static aptHookCookie cookie;
static bool optionMenuOpening = false;
static Common::String messageOSD;
@@ -146,13 +147,41 @@ static void eventThreadFunc(void *arg) {
}
// Button events
+ if (keysPressed & KEY_L) {
+ if (osys->getWidth() >= 400 || osys->getHeight() >= 240) {
+ if (osys->getMagnifyMode() == MODE_MAGOFF) {
+ osys->setMagnifyMode(MODE_MAGON);
+ if (inputMode == MODE_DRAG) {
+ inputMode = MODE_HOVER;
+ osys->displayMessageOnOSD("Magnify Mode On. Switching to Hover Mode...");
+ } else
+ osys->displayMessageOnOSD("Magnify Mode On");
+ } else {
+ osys->setMagnifyMode(MODE_MAGOFF);
+ osys->updateSize();
+ if (savedInputMode == MODE_DRAG) {
+ inputMode = savedInputMode;
+ osys->displayMessageOnOSD("Magnify Mode Off. Reactivating Drag Mode...");
+ } else
+ osys->displayMessageOnOSD("Magnify Mode Off");
+ }
+ } else {
+ if (osys->getWidth() == 0 || osys->getHeight() == 0) {
+ osys->displayMessageOnOSD("Magnify Mode cannot be activated in Launcher.");
+ } else
+ osys->displayMessageOnOSD("In-game resolution too small to magnify.");
+ }
+ }
if (keysPressed & KEY_R) {
if (inputMode == MODE_DRAG) {
- inputMode = MODE_HOVER;
+ inputMode = savedInputMode = MODE_HOVER;
osys->displayMessageOnOSD("Hover Mode");
} else {
- inputMode = MODE_DRAG;
- osys->displayMessageOnOSD("Drag Mode");
+ if (osys->getMagnifyMode() == MODE_MAGOFF) {
+ inputMode = savedInputMode = MODE_DRAG;
+ osys->displayMessageOnOSD("Drag Mode");
+ } else
+ osys->displayMessageOnOSD("Cannot Switch to Drag Mode while Magnify Mode is On");
}
}
if (keysPressed & KEY_A || keysPressed & KEY_DLEFT || keysReleased & KEY_A || keysReleased & KEY_DLEFT) {
@@ -165,6 +194,16 @@ static void eventThreadFunc(void *arg) {
event.type = Common::EVENT_LBUTTONUP;
pushEventQueue(eventQueue, event);
}
+ if (keysPressed & KEY_B || keysReleased & KEY_B || keysPressed & KEY_DDOWN || keysReleased & KEY_DDOWN) {
+ if (keysPressed & KEY_B || keysPressed & KEY_DDOWN)
+ event.type = Common::EVENT_KEYDOWN;
+ else
+ event.type = Common::EVENT_KEYUP;
+ event.kbd.keycode = Common::KEYCODE_ESCAPE;
+ event.kbd.ascii = Common::ASCII_ESCAPE;
+ event.kbd.flags = 0;
+ pushEventQueue(eventQueue, event);
+ }
if (keysPressed & KEY_X || keysPressed & KEY_DUP || keysReleased & KEY_X || keysReleased & KEY_DUP) {
// SIMULATE RIGHT CLICK
event.mouse.x = lastTouch.px;
@@ -175,7 +214,7 @@ static void eventThreadFunc(void *arg) {
event.type = Common::EVENT_RBUTTONUP;
pushEventQueue(eventQueue, event);
}
- if (keysPressed & KEY_L) {
+ if (keysPressed & KEY_Y || keysPressed & KEY_DRIGHT) {
event.type = Common::EVENT_VIRTUAL_KEYBOARD;
pushEventQueue(eventQueue, event);
}
@@ -187,15 +226,18 @@ static void eventThreadFunc(void *arg) {
if (!optionMenuOpened)
optionMenuOpening = true;
}
- if (keysPressed & KEY_B || keysReleased & KEY_B || keysPressed & KEY_DDOWN || keysReleased & KEY_DDOWN) {
- if (keysPressed & KEY_B || keysPressed & KEY_DDOWN)
- event.type = Common::EVENT_KEYDOWN;
- else
- event.type = Common::EVENT_KEYUP;
- event.kbd.keycode = Common::KEYCODE_ESCAPE;
- event.kbd.ascii = Common::ASCII_ESCAPE;
- event.kbd.flags = 0;
- pushEventQueue(eventQueue, event);
+
+ // If magnify mode is on when returning to Launcher, turn it off
+ if (g_system->getEventManager()->shouldRTL()) {
+ if (osys->getMagnifyMode() == MODE_MAGON) {
+ osys->setMagnifyMode(MODE_MAGOFF);
+ osys->updateSize();
+ if (savedInputMode == MODE_DRAG) {
+ inputMode = savedInputMode;
+ osys->displayMessageOnOSD("Magnify Mode Off. Reactivating Drag Mode.\nReturning to Launcher...");
+ } else
+ osys->displayMessageOnOSD("Magnify Mode Off. Returning to Launcher...");
+ }
}
// TODO: EVENT_PREDICTIVE_DIALOG
@@ -268,6 +310,10 @@ void OSystem_3DS::transformPoint(touchPosition &point) {
}
}
+void OSystem_3DS::setMagnifyMode(MagnifyMode mode) {
+ _magnifyMode = mode;
+}
+
void OSystem_3DS::displayMessageOnOSD(const char *msg) {
messageOSD = msg;
showMessageOSD = true;
diff --git a/backends/platform/3ds/osystem-graphics.cpp b/backends/platform/3ds/osystem-graphics.cpp
index 1a86be4402..7204a9fb05 100644
--- a/backends/platform/3ds/osystem-graphics.cpp
+++ b/backends/platform/3ds/osystem-graphics.cpp
@@ -151,6 +151,8 @@ void OSystem_3DS::initSize(uint width, uint height,
_gameHeight = height;
_gameTopTexture.create(width, height, _pfGameTexture);
_overlay.create(getOverlayWidth(), getOverlayHeight(), _pfGameTexture);
+ _topHalfWidth = _topWidth / 2;
+ _topHalfHeight = _topHeight / 2;
if (format) {
debug("pixelformat: %d %d %d %d %d", format->bytesPerPixel, format->rBits(), format->gBits(), format->bBits(), format->aBits());
@@ -198,6 +200,8 @@ void OSystem_3DS::updateSize() {
}
_gameTopTexture.setPosition(_gameTopX, _gameTopY);
_gameBottomTexture.setPosition(_gameBottomX, _gameBottomY);
+ _gameTopTexture.setOffset(0, 0);
+ _gameBottomTexture.setOffset(0, 0);
if (_overlayVisible)
_cursorTexture.setScale(1.f, 1.f);
else if (config.screen == kScreenTop)
@@ -275,6 +279,17 @@ void OSystem_3DS::updateScreen() {
C3D_FrameBegin(0);
_gameTopTexture.transfer();
+ if (_magnifyMode == MODE_MAGON) {
+ _topX = (_cursorX < _topHalfWidth) ?
+ 0 : ((_cursorX < (_gameWidth - _topHalfWidth)) ?
+ _cursorX - _topHalfWidth : _gameWidth - _topWidth);
+ _topY = (_cursorY < _topHalfHeight) ?
+ 0 : ((_cursorY < _gameHeight - _topHalfHeight) ?
+ _cursorY - _topHalfHeight : _gameHeight - _topHeight);
+ _gameTopTexture.setScale(1.f,1.f);
+ _gameTopTexture.setPosition(0,0);
+ _gameTopTexture.setOffset(_topX, _topY);
+ }
if (_overlayVisible) {
_overlay.transfer();
}
diff --git a/backends/platform/3ds/osystem.cpp b/backends/platform/3ds/osystem.cpp
index e1186e4bfb..aa0b3a7503 100644
--- a/backends/platform/3ds/osystem.cpp
+++ b/backends/platform/3ds/osystem.cpp
@@ -72,7 +72,12 @@ OSystem_3DS::OSystem_3DS():
_gameBottomY(0),
_gameWidth(320),
_gameHeight(240),
+ _topX(0),
+ _topY(0),
+ _topWidth(400),
+ _topHeight(240),
_overlayVisible(false),
+ _magnifyMode(MODE_MAGOFF),
exiting(false),
sleeping(false)
{
diff --git a/backends/platform/3ds/osystem.h b/backends/platform/3ds/osystem.h
index 89271e127b..544c900102 100644
--- a/backends/platform/3ds/osystem.h
+++ b/backends/platform/3ds/osystem.h
@@ -44,6 +44,11 @@ enum {
GFX_NEAREST = 1
};
+enum MagnifyMode {
+ MODE_MAGON,
+ MODE_MAGOFF,
+};
+
enum InputMode {
MODE_HOVER,
MODE_DRAG,
@@ -143,6 +148,9 @@ public:
void updateFocus();
void updateConfig();
void updateSize();
+ void setMagnifyMode(MagnifyMode mode);
+ MagnifyMode getMagnifyMode(){ return _magnifyMode; }
+
private:
void initGraphics();
@@ -162,6 +170,9 @@ private:
u16 _gameWidth, _gameHeight;
u16 _gameTopX, _gameTopY;
u16 _gameBottomX, _gameBottomY;
+ u16 _topWidth, _topHeight;
+ u16 _topHalfWidth, _topHalfHeight;
+ u16 _topX, _topY;
// Audio
Thread audioThread;
@@ -218,6 +229,7 @@ private:
float _cursorDeltaX, _cursorDeltaY;
int _cursorHotspotX, _cursorHotspotY;
uint32 _cursorKeyColor;
+ MagnifyMode _magnifyMode;
};
} // namespace _3DS
diff --git a/backends/platform/3ds/sprite.cpp b/backends/platform/3ds/sprite.cpp
index 1f2c72e2d3..bbccf94fe6 100644
--- a/backends/platform/3ds/sprite.cpp
+++ b/backends/platform/3ds/sprite.cpp
@@ -42,6 +42,8 @@ Sprite::Sprite()
, actualHeight(0)
, posX(0)
, posY(0)
+ , offsetX(0)
+ , offsetY(0)
, scaleX(1.f)
, scaleY(1.f)
{
@@ -85,7 +87,6 @@ void Sprite::create(uint16 width, uint16 height, const Graphics::PixelFormat &f)
memcpy(vertices, tmp, sizeof(vertex) * 4);
}
-
void Sprite::free() {
linearFree(vertices);
linearFree(pixels);
@@ -138,12 +139,18 @@ void Sprite::setPosition(int x, int y) {
}
}
+void Sprite::setOffset(uint16 x, uint16 y) {
+ offsetX = x;
+ offsetY = y;
+ dirtyMatrix = true;
+}
+
C3D_Mtx* Sprite::getMatrix() {
if (dirtyMatrix) {
dirtyMatrix = false;
Mtx_Identity(&modelview);
Mtx_Scale(&modelview, scaleX, scaleY, 1.f);
- Mtx_Translate(&modelview, posX, posY, 0, true);
+ Mtx_Translate(&modelview, posX - offsetX, posY - offsetY, 0, true);
}
return &modelview;
}
diff --git a/backends/platform/3ds/sprite.h b/backends/platform/3ds/sprite.h
index 1e9c0b4c01..a7d8b77842 100644
--- a/backends/platform/3ds/sprite.h
+++ b/backends/platform/3ds/sprite.h
@@ -52,9 +52,12 @@ public:
void markDirty(){ dirtyPixels = true; }
void setPosition(int x, int y);
+ void setOffset(uint16 x, uint16 y);
void setScale(float x, float y);
float getScaleX(){ return scaleX; }
float getScaleY(){ return scaleY; }
+ int getPosX(){ return posX; }
+ int getPosY(){ return posY; }
C3D_Mtx* getMatrix();
uint16 actualWidth;
@@ -68,6 +71,8 @@ private:
vertex* vertices;
int posX;
int posY;
+ uint16 offsetX;
+ uint16 offsetY;
float scaleX;
float scaleY;
};