diff options
-rw-r--r-- | backends/platform/3ds/osystem-events.cpp | 13 | ||||
-rw-r--r-- | backends/platform/3ds/osystem-graphics.cpp | 67 | ||||
-rw-r--r-- | backends/platform/3ds/osystem.h | 8 |
3 files changed, 74 insertions, 14 deletions
diff --git a/backends/platform/3ds/osystem-events.cpp b/backends/platform/3ds/osystem-events.cpp index c2239f4645..8c06187b09 100644 --- a/backends/platform/3ds/osystem-events.cpp +++ b/backends/platform/3ds/osystem-events.cpp @@ -37,8 +37,6 @@ static InputMode inputMode = MODE_DRAG; static InputMode savedInputMode = MODE_DRAG; static aptHookCookie cookie; static bool optionMenuOpening = false; -static Common::String messageOSD; -static bool showMessageOSD = false; static void pushEventQueue(Common::Queue<Common::Event> *queue, Common::Event &event) { Common::StackLock lock(*eventMutex); @@ -320,18 +318,7 @@ void OSystem_3DS::setMagnifyMode(MagnifyMode mode) { _magnifyMode = mode; } -void OSystem_3DS::displayMessageOnOSD(const char *msg) { - messageOSD = msg; - showMessageOSD = true; -} - bool OSystem_3DS::pollEvent(Common::Event &event) { - if (showMessageOSD) { - showMessageOSD = false; - StatusMessageDialog dialog(messageOSD, 800); - dialog.runModal(); - } - aptMainLoop(); // Call apt hook when necessary if (optionMenuOpening) { diff --git a/backends/platform/3ds/osystem-graphics.cpp b/backends/platform/3ds/osystem-graphics.cpp index 8d4047b6ed..1e340f84d9 100644 --- a/backends/platform/3ds/osystem-graphics.cpp +++ b/backends/platform/3ds/osystem-graphics.cpp @@ -24,6 +24,7 @@ #include "backends/platform/3ds/osystem.h" #include "backends/platform/3ds/shader_shbin.h" #include "common/rect.h" +#include "graphics/fontman.h" #include "options-dialog.h" #include "config.h" @@ -278,6 +279,10 @@ void OSystem_3DS::updateScreen() { // updateFocus(); updateMagnify(); + if (_osdMessage.getPixels() && _osdMessageEndTime <= getMillis(true)) { + _osdMessage.free(); + } + C3D_FrameBegin(0); _gameTopTexture.transfer(); if (_overlayVisible) { @@ -286,6 +291,7 @@ void OSystem_3DS::updateScreen() { if (_cursorVisible && config.showCursor) { _cursorTexture.transfer(); } + _osdMessage.transfer(); _activityIcon.transfer(); C3D_FrameEnd(0); @@ -306,6 +312,11 @@ void OSystem_3DS::updateScreen() { C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, _modelviewLocation, _activityIcon.getMatrix()); _activityIcon.render(); } + if (_osdMessage.getPixels() && config.screen == kScreenTop) { + _osdMessage.setPosition((400 - _osdMessage.actualWidth) / 2, (240 - _osdMessage.actualHeight) / 2); + C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, _modelviewLocation, _osdMessage.getMatrix()); + _osdMessage.render(); + } if (_cursorVisible && config.showCursor && config.screen == kScreenTop) { C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, _modelviewLocation, _cursorTexture.getMatrix()); _cursorTexture.render(); @@ -328,6 +339,11 @@ void OSystem_3DS::updateScreen() { C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, _modelviewLocation, _activityIcon.getMatrix()); _activityIcon.render(); } + if (_osdMessage.getPixels()) { + _osdMessage.setPosition((320 - _osdMessage.actualWidth) / 2, (240 - _osdMessage.actualHeight) / 2); + C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, _modelviewLocation, _osdMessage.getMatrix()); + _osdMessage.render(); + } if (_cursorVisible && config.showCursor) { C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, _modelviewLocation, _cursorTexture.getMatrix()); _cursorTexture.render(); @@ -472,6 +488,57 @@ void OSystem_3DS::copyRectToOverlay(const void *buf, int pitch, int x, _overlay.markDirty(); } +void OSystem_3DS::displayMessageOnOSD(const char *msg) { + // The font we are going to use: + const Graphics::Font *font = FontMan.getFontByUsage(Graphics::FontManager::kLocalizedFont); + if (!font) { + warning("No available font to render OSD messages"); + return; + } + + // Split the message into separate lines. + Common::Array<Common::String> lines; + const char *ptr; + for (ptr = msg; *ptr; ++ptr) { + if (*ptr == '\n') { + lines.push_back(Common::String(msg, ptr - msg)); + msg = ptr + 1; + } + } + lines.push_back(Common::String(msg, ptr - msg)); + + // Determine a rect which would contain the message string (clipped to the + // screen dimensions). + const int vOffset = 6; + const int lineSpacing = 1; + const int lineHeight = font->getFontHeight() + 2 * lineSpacing; + int width = 0; + int height = lineHeight * lines.size() + 2 * vOffset; + uint i; + for (i = 0; i < lines.size(); i++) { + width = MAX(width, font->getStringWidth(lines[i]) + 14); + } + + // Clip the rect + if (width > getOverlayWidth()) + width = getOverlayWidth(); + if (height > getOverlayHeight()) + height = getOverlayHeight(); + + _osdMessage.create(width, height, _pfGameTexture); + _osdMessage.fillRect(Common::Rect(width, height), _pfGameTexture.ARGBToColor(200, 0, 0, 0)); + + // Render the message, centered, and in white + for (i = 0; i < lines.size(); i++) { + font->drawString(&_osdMessage, lines[i], + 0, 0 + i * lineHeight + vOffset + lineSpacing, width, + _pfGameTexture.RGBToColor(255, 255, 255), + Graphics::kTextAlignCenter); + } + + _osdMessageEndTime = getMillis(true) + kOSDMessageDuration; +} + void OSystem_3DS::displayActivityIconOnOSD(const Graphics::Surface *icon) { if (!icon) { _activityIcon.free(); diff --git a/backends/platform/3ds/osystem.h b/backends/platform/3ds/osystem.h index a1c67826a1..51aa40ae83 100644 --- a/backends/platform/3ds/osystem.h +++ b/backends/platform/3ds/osystem.h @@ -130,7 +130,7 @@ public: int h); virtual int16 getOverlayHeight(); virtual int16 getOverlayWidth(); - virtual void displayMessageOnOSD(const char *msg); + void displayMessageOnOSD(const char *msg) override; void displayActivityIconOnOSD(const Graphics::Surface *icon) override; bool showMouse(bool visible); @@ -190,6 +190,12 @@ private: Sprite _gameBottomTexture; Sprite _overlay; Sprite _activityIcon; + Sprite _osdMessage; + + enum { + kOSDMessageDuration = 800 + }; + uint32 _osdMessageEndTime; int _screenShakeOffset; bool _overlayVisible; |