Skip to content
Permalink
Browse files

3DS: Reworked OSD message display

So the game remains interactive while OSD message are displayed.

(cherry picked from commit 3fcbbbe)
  • Loading branch information...
bgK committed Nov 5, 2019
1 parent cbfec11 commit a151356a5b657e8fe48beb9dbdfd3b140a77465d
@@ -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) {
@@ -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"

@@ -276,6 +277,10 @@ void OSystem_3DS::updateScreen() {
// updateFocus();
updateMagnify();

if (_osdMessage.getPixels() && _osdMessageEndTime <= getMillis(true)) {
_osdMessage.free();
}

C3D_FrameBegin(0);
_gameTopTexture.transfer();
if (_overlayVisible) {
@@ -284,6 +289,7 @@ void OSystem_3DS::updateScreen() {
if (_cursorVisible && config.showCursor) {
_cursorTexture.transfer();
}
_osdMessage.transfer();
_activityIcon.transfer();
C3D_FrameEnd(0);

@@ -304,6 +310,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();
@@ -326,6 +337,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();
@@ -470,6 +486,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();
@@ -130,7 +130,7 @@ class OSystem_3DS : public EventsBaseBackend, public PaletteManager {
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 @@ class OSystem_3DS : public EventsBaseBackend, public PaletteManager {
Sprite _gameBottomTexture;
Sprite _overlay;
Sprite _activityIcon;
Sprite _osdMessage;

enum {
kOSDMessageDuration = 800
};
uint32 _osdMessageEndTime;

int _screenShakeOffset;
bool _overlayVisible;

0 comments on commit a151356

Please sign in to comment.
You can’t perform that action at this time.