[Scummvm-git-logs] scummvm master -> 0886091f7d23734b779538dc7a2946421f877d4e
sev-
sev at scummvm.org
Wed Jun 10 13:43:06 UTC 2020
This automated email contains information about 20 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
f099b6a073 GRAPHICS: MACGUI: Generalize pixel inversion plotproc
b49f3f6cd3 GRAPHICS: MACGUI: MacEditableText: Stay sane
9f06150a36 GRAPHICS: MACGUI: MacEditableText: Add text features
c38ad8bd5e GRAPHICS: MACGUI: MacText: Add shadow
d64e41eca2 GRAPHICS: MACGUI: Add MacButton widget
ecb0df0620 GRAPHICS: MACGUI: Ensure proper cursor change
dcb0bded11 GRAPHICS: MACGUI: Delete unnecessary helper functions
67bc0b0e88 GRAPHICS: MACGUI: MacEditableText: Properly handle cursor state change
4160ce4f86 GRAPHICS: MACGUI: MacEditableText: Start off inert
2eecd518b1 GRAPHICS: MACGUI: MacWidget: Make non-abstract
033e025365 GRAPHICS: MACGUI: MacWindowManager: Deactivate widget when mouse leaves
a2e230803d DIRECTOR: Render texts and buttons with widgets
bd216b237c DIRECTOR: Fix previous rendering typos
f112b2b564 DIRECTOR: Implement kTheHilite
d6176f8ed1 DIRECTOR: Implement kTheStageColor
5711e4399a DIRECTOR: Use WM button activation styles
d6f87f22df DIRECTOR: Make puppetSprite version-sensitive
3095637e60 DIRECTOR: Convert texts to buttons if necessary
c3bfd99d50 DIRECTOR: Render bitmaps with widgets
0886091f7d DIRECTOR: Fix puppetSprite de-activation
Commit: f099b6a073ac7d7d9fcf9070f370a6d07cec2c56
https://github.com/scummvm/scummvm/commit/f099b6a073ac7d7d9fcf9070f370a6d07cec2c56
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
GRAPHICS: MACGUI: Generalize pixel inversion plotproc
Changed paths:
graphics/macgui/macwindow.cpp
graphics/macgui/macwindowmanager.cpp
graphics/macgui/macwindowmanager.h
diff --git a/graphics/macgui/macwindow.cpp b/graphics/macgui/macwindow.cpp
index f9913a9bc8..36ad8eded6 100644
--- a/graphics/macgui/macwindow.cpp
+++ b/graphics/macgui/macwindow.cpp
@@ -195,18 +195,6 @@ const int arrowPixels[ARROW_H][ARROW_W] = {
{0,1,1,1,1,1,1,1,1,1,1,0},
{1,1,1,1,1,1,1,1,1,1,1,1}};
-int localColorWhite, localColorBlack;
-
-static void drawPixelInverted(int x, int y, int color, void *data) {
- ManagedSurface *surface = (ManagedSurface *)data;
-
- if (x >= 0 && x < surface->w && y >= 0 && y < surface->h) {
- byte *p = (byte *)surface->getBasePtr(x, y);
-
- *p = *p == localColorWhite ? localColorBlack : localColorWhite;
- }
-}
-
void MacWindow::updateInnerDims() {
if (_dims.isEmpty())
return;
@@ -304,10 +292,7 @@ void MacWindow::drawSimpleBorder(ManagedSurface *g) {
int ry2 = ry1 + _dims.height() * _scrollSize;
Common::Rect rr(rx1, ry1, rx2, ry2);
- localColorWhite = _wm->_colorWhite;
- localColorBlack = _wm->_colorBlack;
-
- Graphics::drawFilledRect(rr, _wm->_colorBlack, drawPixelInverted, g);
+ Graphics::drawFilledRect(rr, _wm->_colorBlack, Graphics::macInvertPixel, g);
}
}
if (closeable) {
diff --git a/graphics/macgui/macwindowmanager.cpp b/graphics/macgui/macwindowmanager.cpp
index 526f8b17c0..462517cf8b 100644
--- a/graphics/macgui/macwindowmanager.cpp
+++ b/graphics/macgui/macwindowmanager.cpp
@@ -359,6 +359,17 @@ void macDrawPixel(int x, int y, int color, void *data) {
}
}
+void macInvertPixel(int x, int y, int color, void *data) {
+ // Argument color is unused; we just invert the colors as they are in the surface.
+ Graphics::ManagedSurface *surface = (Graphics::ManagedSurface *)data;
+
+ if (x >= 0 && x < surface->w && y >= 0 && y < surface->h) {
+ byte *p = (byte *)surface->getBasePtr(x, y);
+
+ *p = abs(255 - *p);
+ }
+}
+
void MacWindowManager::drawDesktop() {
Common::Rect r(_screen->getBounds());
diff --git a/graphics/macgui/macwindowmanager.h b/graphics/macgui/macwindowmanager.h
index 70cd0de4aa..e962a3827a 100644
--- a/graphics/macgui/macwindowmanager.h
+++ b/graphics/macgui/macwindowmanager.h
@@ -102,6 +102,7 @@ struct MacPlotData {
};
void macDrawPixel(int x, int y, int color, void *data);
+void macInvertPixel(int x, int y, int color, void *data);
/**
* A manager class to handle window creation, destruction,
Commit: b49f3f6cd3ff94d459a782205eb38412782d9545
https://github.com/scummvm/scummvm/commit/b49f3f6cd3ff94d459a782205eb38412782d9545
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
GRAPHICS: MACGUI: MacEditableText: Stay sane
Changed paths:
graphics/macgui/maceditabletext.cpp
diff --git a/graphics/macgui/maceditabletext.cpp b/graphics/macgui/maceditabletext.cpp
index 4a6ae664da..c83c4f5871 100644
--- a/graphics/macgui/maceditabletext.cpp
+++ b/graphics/macgui/maceditabletext.cpp
@@ -108,10 +108,9 @@ void MacEditableText::setActive(bool active) {
MacWidget::setActive(active);
+ g_system->getTimerManager()->removeTimerProc(&cursorTimerHandler);
if (_active) {
g_system->getTimerManager()->installTimerProc(&cursorTimerHandler, 200000, this, "macEditableText");
- } else {
- g_system->getTimerManager()->removeTimerProc(&cursorTimerHandler);
}
if (!_cursorOff && _cursorState == true) {
@@ -161,6 +160,11 @@ bool MacEditableText::draw(bool forceRedraw) {
if (!_contentIsDirty && !_cursorDirty && !forceRedraw)
return false;
+ if (!_surface) {
+ warning("MacEditableText::draw: Null surface");
+ return false;
+ }
+
_composeSurface->clear(_bgcolor);
_contentIsDirty = false;
@@ -179,7 +183,7 @@ bool MacEditableText::draw(bool forceRedraw) {
}
bool MacEditableText::draw(ManagedSurface *g, bool forceRedraw) {
- if (!draw(forceRedraw))
+ if (!MacEditableText::draw(forceRedraw))
return false;
g->transBlitFrom(*_composeSurface, _composeSurface->getBounds(), Common::Point(_dims.left - 2, _dims.top - 2), kColorGreen2);
Commit: 9f06150a36984174e831bbeaf752ac7e75faff1f
https://github.com/scummvm/scummvm/commit/9f06150a36984174e831bbeaf752ac7e75faff1f
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
GRAPHICS: MACGUI: MacEditableText: Add text features
Border, gutter, box shadow, text alignment
Changed paths:
graphics/macgui/maceditabletext.cpp
graphics/macgui/maceditabletext.h
graphics/macgui/macwidget.cpp
graphics/macgui/macwidget.h
diff --git a/graphics/macgui/maceditabletext.cpp b/graphics/macgui/maceditabletext.cpp
index c83c4f5871..167a595797 100644
--- a/graphics/macgui/maceditabletext.cpp
+++ b/graphics/macgui/maceditabletext.cpp
@@ -40,8 +40,8 @@ enum {
static void cursorTimerHandler(void *refCon);
-MacEditableText::MacEditableText(MacWidget *parent, int x, int y, int w, int h, MacWindowManager *wm, const Common::U32String &s, const MacFont *macFont, int fgcolor, int bgcolor, int maxWidth, TextAlign textAlignment, int interlinear) :
- MacWidget(parent, x, y, w, h, true), MacText(s, wm, macFont, fgcolor, bgcolor, maxWidth, textAlignment, interlinear) {
+MacEditableText::MacEditableText(MacWidget *parent, int x, int y, int w, int h, MacWindowManager *wm, const Common::U32String &s, const MacFont *macFont, int fgcolor, int bgcolor, int maxWidth, TextAlign textAlignment, int interlinear, uint16 border, uint16 gutter, uint16 boxShadow, uint16 textShadow) :
+ MacWidget(parent, x, y, w, h, true, border, gutter, boxShadow), MacText(s, wm, macFont, fgcolor, bgcolor, maxWidth, textAlignment, interlinear, textShadow) {
_maxWidth = maxWidth;
@@ -50,10 +50,12 @@ MacEditableText::MacEditableText(MacWidget *parent, int x, int y, int w, int h,
setDefaultFormatting(macFont->getId(), macFont->getSlant(), macFont->getSize(), 0, 0, 0);
MacText::render();
+ setAlignOffset(_textAlignment);
+ updateCursorPos();
}
-MacEditableText::MacEditableText(MacWidget *parent, int x, int y, int w, int h, MacWindowManager *wm, const Common::String &s, const MacFont *macFont, int fgcolor, int bgcolor, int maxWidth, TextAlign textAlignment, int interlinear) :
- MacWidget(parent, x, y, w, h, true), MacText(s, wm, macFont, fgcolor, bgcolor, maxWidth, textAlignment, interlinear) {
+MacEditableText::MacEditableText(MacWidget *parent, int x, int y, int w, int h, MacWindowManager *wm, const Common::String &s, const MacFont *macFont, int fgcolor, int bgcolor, int maxWidth, TextAlign textAlignment, int interlinear, uint16 border, uint16 gutter, uint16 boxShadow, uint16 textShadow) :
+ MacWidget(parent, x, y, w, h, true, border, gutter, boxShadow), MacText(s, wm, macFont, fgcolor, bgcolor, maxWidth, textAlignment, interlinear, textShadow) {
_maxWidth = maxWidth;
@@ -62,6 +64,8 @@ MacEditableText::MacEditableText(MacWidget *parent, int x, int y, int w, int h,
setDefaultFormatting(macFont->getId(), macFont->getSlant(), macFont->getSize(), 0, 0, 0);
MacText::render();
+ setAlignOffset(_textAlignment);
+ updateCursorPos();
}
void MacEditableText::init() {
@@ -83,8 +87,6 @@ void MacEditableText::init() {
_cursorRow = getLineCount() - 1;
_cursorCol = getLineCharWidth(_cursorRow);
- updateCursorPos();
-
_cursorRect = new Common::Rect(0, 0, 1, kCursorHeight);
_cursorSurface = new ManagedSurface(1, kCursorHeight);
@@ -102,6 +104,25 @@ MacEditableText::~MacEditableText() {
delete _composeSurface;
}
+void MacEditableText::setAlignOffset(TextAlign align) {
+ switch(align) {
+ case kTextAlignLeft:
+ default:
+ _alignOffset = Common::Point(0, 0);
+ break;
+ case kTextAlignCenter:
+ _alignOffset = Common::Point((_maxWidth / 2) - (_surface->w / 2), 0);
+ break;
+ case kTextAlignRight:
+ _alignOffset = Common::Point(_maxWidth - (_surface->w + 1), 0);
+ break;
+ }
+}
+
+Common::Point MacEditableText::calculateOffset() {
+ return Common::Point(_alignOffset.x + _border + _gutter + 1, _alignOffset.y + _border + _gutter/2);
+}
+
void MacEditableText::setActive(bool active) {
if (_active == active)
return;
@@ -171,10 +192,21 @@ bool MacEditableText::draw(bool forceRedraw) {
_cursorDirty = false;
// Compose
- MacText::draw(_composeSurface, 0, _scrollPos, _surface->w, _scrollPos + _surface->h, 0, 0);
+ for (int bb = 0; bb < _shadow; bb ++) {
+ _composeSurface->hLine(_shadow, _composeSurface->h - _shadow + bb, _composeSurface->w, 0);
+ _composeSurface->vLine(_composeSurface->w - _shadow + bb, _shadow, _composeSurface->h - _shadow, 0);
+ }
+
+ for (int bb = 0; bb < _border; bb++) {
+ Common::Rect borderRect(bb, bb, _composeSurface->w - _shadow - bb, _composeSurface->h - _shadow - bb);
+ _composeSurface->frameRect(borderRect, 0);
+ }
+
+ Common::Point offset(calculateOffset());
+ MacText::draw(_composeSurface, 0, _scrollPos, _surface->w, _scrollPos + _surface->h, offset.x, offset.y);
if (_cursorState)
- _composeSurface->blitFrom(*_cursorSurface, *_cursorRect, Common::Point(_cursorX, _cursorY));
+ _composeSurface->blitFrom(*_cursorSurface, *_cursorRect, Common::Point(_cursorX, _cursorY + offset.y + 1));
if (_selectedText.endY != -1)
drawSelection();
@@ -524,8 +556,16 @@ void MacEditableText::updateCursorPos() {
} else {
_cursorRow = MIN<int>(_cursorRow, _textLines.size() - 1);
- _cursorY = _textLines[_cursorRow].y;
- _cursorX = getLineWidth(_cursorRow, false, _cursorCol);
+ Common::Point offset(calculateOffset());
+
+ int alignOffset = 0;
+ if (_textAlignment == kTextAlignRight)
+ alignOffset = _textMaxWidth - getLineWidth(_cursorRow);
+ else if (_textAlignment == kTextAlignCenter)
+ alignOffset = (_textMaxWidth / 2) - (getLineWidth(_cursorRow) / 2);
+
+ _cursorY = _textLines[_cursorRow].y + offset.y - 2;
+ _cursorX = getLineWidth(_cursorRow, false, _cursorCol) + alignOffset + offset.x - 1;
}
_cursorDirty = true;
diff --git a/graphics/macgui/maceditabletext.h b/graphics/macgui/maceditabletext.h
index cdde33620c..f61a7587f8 100644
--- a/graphics/macgui/maceditabletext.h
+++ b/graphics/macgui/maceditabletext.h
@@ -53,10 +53,8 @@ struct SelectedText {
class MacEditableText : public MacText, public MacWidget {
public:
- MacEditableText(MacWidget *parent, int x, int y, int w, int h, MacWindowManager *wm, const Common::U32String &s, const MacFont *font, int fgcolor, int bgcolor,
- int maxWidth, TextAlign textAlignment = kTextAlignLeft, int interlinear = 0);
- MacEditableText(MacWidget *parent, int x, int y, int w, int h, MacWindowManager *wm, const Common::String &s, const MacFont *font, int fgcolor, int bgcolor,
- int maxWidth, TextAlign textAlignment = kTextAlignLeft, int interlinear = 0);
+ MacEditableText(MacWidget *parent, int x, int y, int w, int h, MacWindowManager *wm, const Common::U32String &s, const MacFont *font, int fgcolor, int bgcolor, int maxWidth, TextAlign textAlignment = kTextAlignLeft, int interlinear = 0, uint16 border = 0, uint16 gutter = 0, uint16 boxShadow = 0, uint16 textShadow = 0);
+ MacEditableText(MacWidget *parent, int x, int y, int w, int h, MacWindowManager *wm, const Common::String &s, const MacFont *font, int fgcolor, int bgcolor, int maxWidth, TextAlign textAlignment = kTextAlignLeft, int interlinear = 0, uint16 border = 0, uint16 gutter = 0, uint16 boxShadow = 0, uint16 textShadow = 0);
// 0 pixels between the lines by default
virtual ~MacEditableText();
@@ -68,6 +66,8 @@ public:
virtual bool draw(bool forceRedraw = false) override;
virtual void blit(ManagedSurface *g, Common::Rect &dest) override;
+ void setAlignOffset(TextAlign align);
+ Common::Point calculateOffset();
virtual void setActive(bool active) override;
void appendText(const Common::U32String &str, const MacFont *macFont, bool skipAdd = false);
@@ -110,6 +110,9 @@ public:
int _scrollPos;
+protected:
+ Common::Point _alignOffset;
+
private:
ManagedSurface *_cursorSurface;
diff --git a/graphics/macgui/macwidget.cpp b/graphics/macgui/macwidget.cpp
index 051c45839d..5cd8e0df84 100644
--- a/graphics/macgui/macwidget.cpp
+++ b/graphics/macgui/macwidget.cpp
@@ -26,14 +26,14 @@
namespace Graphics {
-MacWidget::MacWidget(MacWidget *parent, int x, int y, int w, int h, bool focusable) :
- _focusable(focusable), _parent(parent) {
+MacWidget::MacWidget(MacWidget *parent, int x, int y, int w, int h, bool focusable, uint16 border, uint16 gutter, uint16 shadow) :
+ _focusable(focusable), _parent(parent), _border(border), _gutter(gutter), _shadow(shadow) {
_contentIsDirty = true;
_dims.left = x;
- _dims.right = x + w;
+ _dims.right = x + w + 2 * border + 2 * gutter + shadow + 1;
_dims.top = y;
- _dims.bottom = y + h;
+ _dims.bottom = y + h + 2 * border + gutter + shadow;
if (parent)
parent->_children.push_back(this);
diff --git a/graphics/macgui/macwidget.h b/graphics/macgui/macwidget.h
index e919568be0..ca9322b2d0 100644
--- a/graphics/macgui/macwidget.h
+++ b/graphics/macgui/macwidget.h
@@ -39,7 +39,7 @@ class MacWidget {
friend class MacEditableText;
public:
- MacWidget(MacWidget *parent, int x, int y, int w, int h, bool focusable);
+ MacWidget(MacWidget *parent, int x, int y, int w, int h, bool focusable, uint16 border = 0, uint16 gutter = 0, uint16 shadow = 0);
virtual ~MacWidget();
/**
@@ -87,6 +87,10 @@ protected:
bool _active;
bool _editable;
+ uint16 _border;
+ uint16 _gutter;
+ uint16 _shadow;
+
Common::Rect _dims;
Graphics::ManagedSurface *_composeSurface;
Commit: c38ad8bd5ecd826142fdcbbd3a8dc70967fd9e5c
https://github.com/scummvm/scummvm/commit/c38ad8bd5ecd826142fdcbbd3a8dc70967fd9e5c
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
GRAPHICS: MACGUI: MacText: Add shadow
Changed paths:
graphics/macgui/mactext.cpp
graphics/macgui/mactext.h
diff --git a/graphics/macgui/mactext.cpp b/graphics/macgui/mactext.cpp
index 8675b12f74..54908256e9 100644
--- a/graphics/macgui/mactext.cpp
+++ b/graphics/macgui/mactext.cpp
@@ -83,7 +83,7 @@ MacText::~MacText() {
delete _surface;
}
-MacText::MacText(const Common::U32String &s, MacWindowManager *wm, const MacFont *macFont, int fgcolor, int bgcolor, int maxWidth, TextAlign textAlignment, int interlinear) {
+MacText::MacText(const Common::U32String &s, MacWindowManager *wm, const MacFont *macFont, int fgcolor, int bgcolor, int maxWidth, TextAlign textAlignment, int interlinear, uint16 textShadow) {
_str = s;
_wm = wm;
_macFont = macFont;
@@ -95,6 +95,7 @@ MacText::MacText(const Common::U32String &s, MacWindowManager *wm, const MacFont
_surface = nullptr;
_textAlignment = textAlignment;
_interLinear = interlinear;
+ _textShadow = textShadow;
if (macFont) {
_defaultFormatting = MacFontRun(_wm, macFont->getId(), macFont->getSlant(), macFont->getSize(), 0, 0, 0);
@@ -114,7 +115,7 @@ MacText::MacText(const Common::U32String &s, MacWindowManager *wm, const MacFont
_fullRefresh = true;
}
-MacText::MacText(const Common::String &s, MacWindowManager *wm, const MacFont *macFont, int fgcolor, int bgcolor, int maxWidth, TextAlign textAlignment, int interlinear) {
+MacText::MacText(const Common::String &s, MacWindowManager *wm, const MacFont *macFont, int fgcolor, int bgcolor, int maxWidth, TextAlign textAlignment, int interlinear, uint16 textShadow) {
_str = Common::U32String(s);
_wm = wm;
_macFont = macFont;
@@ -126,6 +127,7 @@ MacText::MacText(const Common::String &s, MacWindowManager *wm, const MacFont *m
_surface = nullptr;
_textAlignment = textAlignment;
_interLinear = interlinear;
+ _textShadow = textShadow;
if (macFont) {
_defaultFormatting = MacFontRun(_wm, macFont->getId(), macFont->getSlant(), macFont->getSize(), 0, 0, 0);
@@ -592,6 +594,12 @@ void MacText::draw(ManagedSurface *g, int x, int y, int w, int h, int xoff, int
g->blitFrom(*_surface, Common::Rect(MIN<int>(_surface->w, x), MIN<int>(_surface->h, y),
MIN<int>(_surface->w, x + w), MIN<int>(_surface->h, y + h)),
Common::Point(xoff, yoff));
+
+ if (_textShadow)
+ g->transBlitFrom(*_surface, Common::Rect(MIN<int>(_surface->w, x), MIN<int>(_surface->h, y),
+ MIN<int>(_surface->w, x + w), MIN<int>(_surface->h, y + h)),
+ Common::Point(xoff + _textShadow, yoff + _textShadow), 0xff);
+
}
void MacText::drawToPoint(ManagedSurface *g, Common::Rect srcRect, Common::Point dstPoint) {
diff --git a/graphics/macgui/mactext.h b/graphics/macgui/mactext.h
index 9df142c6bd..5567459fe8 100644
--- a/graphics/macgui/mactext.h
+++ b/graphics/macgui/mactext.h
@@ -109,9 +109,9 @@ class MacText {
public:
MacText(const Common::U32String &s, MacWindowManager *wm, const MacFont *font, int fgcolor, int bgcolor,
- int maxWidth = -1, TextAlign textAlignment = kTextAlignLeft, int interlinear = 0);
+ int maxWidth = -1, TextAlign textAlignment = kTextAlignLeft, int interlinear = 0, uint16 textShadow = 0);
MacText(const Common::String &s, MacWindowManager *wm, const MacFont *font, int fgcolor, int bgcolor,
- int maxWidth = -1, TextAlign textAlignment = kTextAlignLeft, int interlinear = 0);
+ int maxWidth = -1, TextAlign textAlignment = kTextAlignLeft, int interlinear = 0, uint16 textShadow = 0);
// 0 pixels between the lines by default
~MacText();
@@ -182,6 +182,7 @@ protected:
int _maxWidth;
int _interLinear;
+ int _textShadow;
int _textMaxWidth;
int _textMaxHeight;
Commit: d64e41eca240aefe24ab1664c9b24485afc33c23
https://github.com/scummvm/scummvm/commit/d64e41eca240aefe24ab1664c9b24485afc33c23
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
GRAPHICS: MACGUI: Add MacButton widget
Changed paths:
A graphics/macgui/macbutton.cpp
A graphics/macgui/macbutton.h
graphics/module.mk
diff --git a/graphics/macgui/macbutton.cpp b/graphics/macgui/macbutton.cpp
new file mode 100644
index 0000000000..54b5934ee5
--- /dev/null
+++ b/graphics/macgui/macbutton.cpp
@@ -0,0 +1,165 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/timer.h"
+#include "common/system.h"
+
+#include "graphics/primitives.h"
+#include "graphics/macgui/macwindowmanager.h"
+#include "graphics/macgui/macfontmanager.h"
+#include "graphics/macgui/maceditabletext.h"
+#include "graphics/macgui/macmenu.h"
+#include "graphics/macgui/macbutton.h"
+#include "graphics/macgui/macwidget.h"
+#include "graphics/macgui/macwindow.h"
+
+namespace Graphics {
+
+MacButton::MacButton(MacButtonType buttonType, TextAlign textAlignment, MacWidget *parent, int x, int y, int w, int h, MacWindowManager *wm, const Common::U32String &s, const MacFont *macFont, int fgcolor, int bgcolor) :
+ MacEditableText(parent, x, y, w, h, wm, s, macFont, fgcolor, bgcolor, w, textAlignment) {
+
+ _buttonType = buttonType;
+ delete _composeSurface;
+
+ int offset;
+ switch (buttonType) {
+ case kCheckBox:
+ offset = 16;
+ break;
+ case kRound:
+ offset = 4;
+ _dims.top -= 2;
+ _dims.bottom += 2;
+ _alignOffset.y += 2;
+ break;
+ case kRadio:
+ offset = 16;
+ break;
+ }
+
+ _alignOffset.x += offset;
+ _dims.right += offset;
+ _composeSurface = new ManagedSurface(_dims.width(), _dims.height());
+}
+
+void MacButton::setActive(bool active) {
+ if (active == _active)
+ return;
+
+ MacWidget::setActive(active);
+ if (_composeSurface)
+ invertOuter();
+}
+
+void MacButton::invertOuter() {
+ Common::Rect r(_dims.width() - 1, _dims.height() - 1);
+
+ switch (_buttonType) {
+ case kCheckBox: {
+ Common::Rect c = Common::Rect(r.left + 1, r.top + 3, r.left + 9, r.top + 11);
+ Graphics::drawRect(c, 0, Graphics::macInvertPixel, _composeSurface);
+ }
+ break;
+ case kRound:
+ Graphics::drawRoundRect(r, 4, 0, true, Graphics::macInvertPixel, _composeSurface);
+ break;
+ case kRadio:
+ Graphics::drawEllipse(r.left + 1, r.top + 3, r.left + 10, r.top + 12, 0, false, Graphics::macInvertPixel, _composeSurface);
+ break;
+ }
+}
+
+void MacButton::invertInner() {
+ Common::Rect r(_dims.width() - 1, _dims.height() - 1);
+
+ switch (_buttonType) {
+ case kCheckBox:
+ Graphics::drawLine(r.left + 1, r.top + 3, r.left + 9, r.top + 11, 0, Graphics::macInvertPixel, _composeSurface);
+ Graphics::drawLine(r.left + 1, r.top + 11, r.left + 9, r.top + 3, 0, Graphics::macInvertPixel, _composeSurface);
+ Graphics::macInvertPixel(5, 7, 0, _composeSurface);
+ break;
+ case kRound:
+ break;
+ case kRadio:
+ Graphics::drawEllipse(r.left + 3, r.top + 5, r.left + 8, r.top + 10, 0, true, Graphics::macInvertPixel, _composeSurface);
+ break;
+ }
+}
+
+bool MacButton::draw(bool forceRedraw) {
+ if (!_contentIsDirty && !forceRedraw)
+ return false;
+
+ MacEditableText::draw();
+
+ Common::Rect r(_dims.width() - 1, _dims.height() - 1);
+ Graphics::MacPlotData pd(_composeSurface, nullptr, &_wm->getPatterns(), 1, 0, 0, 1, 0);
+
+ switch (_buttonType) {
+ case kCheckBox: {
+ Common::Rect c = Common::Rect(r.left, r.top + 2, r.left + 10, r.top + 2 + 10);
+ Graphics::drawRect(c, 0, Graphics::macDrawPixel, &pd);
+ break;
+ }
+ case kRound:
+ Graphics::drawRoundRect(r, 4, 0, _active, Graphics::macDrawPixel, &pd);
+ break;
+ case kRadio:
+ Graphics::drawEllipse(r.left, r.top + 2, r.left + 11, r.top + 13, 0, false, Graphics::macDrawPixel, &pd);
+ break;
+ }
+
+ _contentIsDirty = false;
+ return true;
+}
+
+bool MacButton::draw(ManagedSurface *g, bool forceRedraw) {
+ if (!MacButton::draw(forceRedraw))
+ return false;
+
+ g->transBlitFrom(*_composeSurface, _composeSurface->getBounds(), Common::Point(_dims.left - 2, _dims.top - 2), kColorGreen2);
+
+ return true;
+}
+
+void MacButton::blit(ManagedSurface *g, Common::Rect &dest) {
+ g->transBlitFrom(*_composeSurface, _composeSurface->getBounds(), dest, kColorGreen2);
+}
+
+bool MacButton::processEvent(Common::Event &event) {
+ switch (event.type) {
+ case Common::EVENT_MOUSEMOVE:
+ break;
+ case Common::EVENT_LBUTTONDOWN:
+ setActive(true);
+ break;
+ case Common::EVENT_LBUTTONUP:
+ setActive(false);
+ invertInner();
+ break;
+ default:
+ warning("MacButton:: processEvent: Event not handled");
+ }
+ return false;
+}
+
+} // End of namespace Graphics
diff --git a/graphics/macgui/macbutton.h b/graphics/macgui/macbutton.h
new file mode 100644
index 0000000000..c1302a5e60
--- /dev/null
+++ b/graphics/macgui/macbutton.h
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GRAPHICS_MACGUI_MACBUTTON_H
+#define GRAPHICS_MACGUI_MACBUTTON_H
+
+#include "graphics/macgui/mactext.h"
+#include "graphics/macgui/maceditabletext.h"
+#include "graphics/macgui/macwidget.h"
+
+namespace Graphics {
+
+class MacWidget;
+class MacText;
+
+enum MacButtonType {
+ kRound,
+ kCheckBox,
+ kRadio
+};
+
+class MacButton : public MacEditableText {
+public:
+ MacButton(MacButtonType buttonType, TextAlign textAlignment, MacWidget *parent, int x, int y, int w, int h, MacWindowManager *wm, const Common::U32String &s, const MacFont *macFont, int fgcolor, int bgcolor);
+
+ virtual void setActive(bool active) override;
+
+ void invertOuter();
+ void invertInner();
+ virtual bool draw(ManagedSurface *g, bool forceRedraw = false) override;
+ virtual bool draw(bool forceRedraw = false) override;
+ virtual void blit(ManagedSurface *g, Common::Rect &dest) override;
+ virtual bool processEvent(Common::Event &event) override;
+
+private:
+ MacButtonType _buttonType;
+};
+
+} // End of namespace Graphics
+
+#endif
diff --git a/graphics/module.mk b/graphics/module.mk
index f2a0a52364..8068b389be 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -14,6 +14,7 @@ MODULE_OBJS := \
fonts/winfont.o \
larryScale.o \
maccursor.o \
+ macgui/macbutton.o \
macgui/maceditabletext.o \
macgui/macfontmanager.o \
macgui/macmenu.o \
Commit: ecb0df0620e7856aaa8d07567b5d962fc24e7a26
https://github.com/scummvm/scummvm/commit/ecb0df0620e7856aaa8d07567b5d962fc24e7a26
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
GRAPHICS: MACGUI: Ensure proper cursor change
Changed paths:
graphics/macgui/macwindowmanager.cpp
diff --git a/graphics/macgui/macwindowmanager.cpp b/graphics/macgui/macwindowmanager.cpp
index 462517cf8b..204abcbab0 100644
--- a/graphics/macgui/macwindowmanager.cpp
+++ b/graphics/macgui/macwindowmanager.cpp
@@ -446,8 +446,9 @@ bool MacWindowManager::processEvent(Common::Event &event) {
if (_activeWindow != -1) {
if ((_windows[_activeWindow]->isEditable() && _windows[_activeWindow]->getType() == kWindowWindow &&
- ((MacWindow *)_windows[_activeWindow])->getInnerDimensions().contains(event.mouse.x, event.mouse.y))
- || (_activeWidget && _activeWidget->isEditable())) {
+ ((MacWindow *)_windows[_activeWindow])->getInnerDimensions().contains(event.mouse.x, event.mouse.y)) ||
+ (_activeWidget && _activeWidget->isEditable() &&
+ _activeWidget->getDimensions().contains(event.mouse.x, event.mouse.y))) {
if (_cursorIsArrow) {
CursorMan.replaceCursor(macCursorBeam, 11, 16, 3, 8, 3);
_cursorIsArrow = false;
Commit: dcb0bded11fbb923e854e2fb1aa75d53ecbaf916
https://github.com/scummvm/scummvm/commit/dcb0bded11fbb923e854e2fb1aa75d53ecbaf916
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
GRAPHICS: MACGUI: Delete unnecessary helper functions
Changed paths:
graphics/macgui/maceditabletext.h
graphics/macgui/macwidget.h
diff --git a/graphics/macgui/maceditabletext.h b/graphics/macgui/maceditabletext.h
index f61a7587f8..2ec58129f3 100644
--- a/graphics/macgui/maceditabletext.h
+++ b/graphics/macgui/maceditabletext.h
@@ -74,9 +74,6 @@ public:
void appendText(const Common::String &str, const MacFont *macFont, bool skipAdd = false);
void clearText();
- void setEditable(bool editable) { _editable = editable; }
- void setSelectable(bool selectable) { _selectable = selectable; }
-
void undrawCursor();
Common::U32String getSelection(bool formatted = false, bool newlines = true);
diff --git a/graphics/macgui/macwidget.h b/graphics/macgui/macwidget.h
index ca9322b2d0..f59492af1d 100644
--- a/graphics/macgui/macwidget.h
+++ b/graphics/macgui/macwidget.h
@@ -48,8 +48,6 @@ public:
*/
const Common::Rect &getDimensions() { return _dims; }
- bool isFocusable() { return _focusable; }
-
/**
* Method for indicating whether the widget is active or inactive.
* Used by the WM to handle focus on windows, etc.
@@ -82,20 +80,20 @@ public:
Graphics::ManagedSurface *getSurface() { return _composeSurface; }
protected:
- bool _focusable;
- bool _contentIsDirty;
- bool _active;
- bool _editable;
-
uint16 _border;
uint16 _gutter;
uint16 _shadow;
- Common::Rect _dims;
-
Graphics::ManagedSurface *_composeSurface;
public:
+ bool _focusable;
+ bool _contentIsDirty;
+ bool _active;
+ bool _editable;
+
+ Common::Rect _dims;
+
MacWidget *_parent;
Common::Array<MacWidget *> _children;
};
Commit: 67bc0b0e88a0e4030a3db7531419f865fbc0488e
https://github.com/scummvm/scummvm/commit/67bc0b0e88a0e4030a3db7531419f865fbc0488e
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
GRAPHICS: MACGUI: MacEditableText: Properly handle cursor state change
Changed paths:
graphics/macgui/maceditabletext.cpp
graphics/macgui/maceditabletext.h
diff --git a/graphics/macgui/maceditabletext.cpp b/graphics/macgui/maceditabletext.cpp
index 167a595797..875fad4537 100644
--- a/graphics/macgui/maceditabletext.cpp
+++ b/graphics/macgui/maceditabletext.cpp
@@ -134,9 +134,24 @@ void MacEditableText::setActive(bool active) {
g_system->getTimerManager()->installTimerProc(&cursorTimerHandler, 200000, this, "macEditableText");
}
- if (!_cursorOff && _cursorState == true) {
- _cursorState = false;
- _cursorDirty = true;
+ if (!_cursorOff && _cursorState == true)
+ undrawCursor();
+}
+
+void MacEditableText::setEditable(bool editable) {
+ if (editable == _editable)
+ return;
+
+ _editable = editable;
+ _cursorOff = !editable;
+
+ if (editable) {
+ // TODO: Select whole region. This is done every time the text is set from
+ // uneditable to editable.
+ setActive(editable);
+ _wm->setActiveWidget(this);
+ } else {
+ undrawCursor();
}
}
diff --git a/graphics/macgui/maceditabletext.h b/graphics/macgui/maceditabletext.h
index 2ec58129f3..d97b4184b4 100644
--- a/graphics/macgui/maceditabletext.h
+++ b/graphics/macgui/maceditabletext.h
@@ -69,6 +69,7 @@ public:
void setAlignOffset(TextAlign align);
Common::Point calculateOffset();
virtual void setActive(bool active) override;
+ void setEditable(bool editable);
void appendText(const Common::U32String &str, const MacFont *macFont, bool skipAdd = false);
void appendText(const Common::String &str, const MacFont *macFont, bool skipAdd = false);
Commit: 4160ce4f86fa80bb6304490a634cb16629237038
https://github.com/scummvm/scummvm/commit/4160ce4f86fa80bb6304490a634cb16629237038
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
GRAPHICS: MACGUI: MacEditableText: Start off inert
Changed paths:
graphics/macgui/maceditabletext.cpp
diff --git a/graphics/macgui/maceditabletext.cpp b/graphics/macgui/maceditabletext.cpp
index 875fad4537..89773b63aa 100644
--- a/graphics/macgui/maceditabletext.cpp
+++ b/graphics/macgui/maceditabletext.cpp
@@ -72,8 +72,8 @@ void MacEditableText::init() {
_inTextSelection = false;
_scrollPos = 0;
- _editable = true;
- _selectable = true;
+ _editable = false;
+ _selectable = false;
_editableRow = 0;
Commit: 2eecd518b169a9d40dc403eaf18998563bbf88a0
https://github.com/scummvm/scummvm/commit/2eecd518b169a9d40dc403eaf18998563bbf88a0
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
GRAPHICS: MACGUI: MacWidget: Make non-abstract
Changed paths:
graphics/macgui/macbutton.cpp
graphics/macgui/macbutton.h
graphics/macgui/maceditabletext.cpp
graphics/macgui/maceditabletext.h
graphics/macgui/macwidget.cpp
graphics/macgui/macwidget.h
diff --git a/graphics/macgui/macbutton.cpp b/graphics/macgui/macbutton.cpp
index 54b5934ee5..cc2c9cb871 100644
--- a/graphics/macgui/macbutton.cpp
+++ b/graphics/macgui/macbutton.cpp
@@ -38,7 +38,6 @@ MacButton::MacButton(MacButtonType buttonType, TextAlign textAlignment, MacWidge
MacEditableText(parent, x, y, w, h, wm, s, macFont, fgcolor, bgcolor, w, textAlignment) {
_buttonType = buttonType;
- delete _composeSurface;
int offset;
switch (buttonType) {
@@ -58,7 +57,8 @@ MacButton::MacButton(MacButtonType buttonType, TextAlign textAlignment, MacWidge
_alignOffset.x += offset;
_dims.right += offset;
- _composeSurface = new ManagedSurface(_dims.width(), _dims.height());
+ _composeSurface->create(_dims.width(), _dims.height());
+ _maskSurface->create(_dims.width(), _dims.height());
}
void MacButton::setActive(bool active) {
@@ -109,10 +109,11 @@ bool MacButton::draw(bool forceRedraw) {
if (!_contentIsDirty && !forceRedraw)
return false;
+ _maskSurface->clear(0);
MacEditableText::draw();
Common::Rect r(_dims.width() - 1, _dims.height() - 1);
- Graphics::MacPlotData pd(_composeSurface, nullptr, &_wm->getPatterns(), 1, 0, 0, 1, 0);
+ Graphics::MacPlotData pd(_composeSurface, _maskSurface, &_wm->getPatterns(), 1, 0, 0, 1, 0);
switch (_buttonType) {
case kCheckBox: {
@@ -141,10 +142,6 @@ bool MacButton::draw(ManagedSurface *g, bool forceRedraw) {
return true;
}
-void MacButton::blit(ManagedSurface *g, Common::Rect &dest) {
- g->transBlitFrom(*_composeSurface, _composeSurface->getBounds(), dest, kColorGreen2);
-}
-
bool MacButton::processEvent(Common::Event &event) {
switch (event.type) {
case Common::EVENT_MOUSEMOVE:
diff --git a/graphics/macgui/macbutton.h b/graphics/macgui/macbutton.h
index c1302a5e60..fead5fee37 100644
--- a/graphics/macgui/macbutton.h
+++ b/graphics/macgui/macbutton.h
@@ -48,7 +48,6 @@ public:
void invertInner();
virtual bool draw(ManagedSurface *g, bool forceRedraw = false) override;
virtual bool draw(bool forceRedraw = false) override;
- virtual void blit(ManagedSurface *g, Common::Rect &dest) override;
virtual bool processEvent(Common::Event &event) override;
private:
diff --git a/graphics/macgui/maceditabletext.cpp b/graphics/macgui/maceditabletext.cpp
index 89773b63aa..c0dadba278 100644
--- a/graphics/macgui/maceditabletext.cpp
+++ b/graphics/macgui/maceditabletext.cpp
@@ -91,9 +91,6 @@ void MacEditableText::init() {
_cursorSurface = new ManagedSurface(1, kCursorHeight);
_cursorSurface->clear(_wm->_colorBlack);
-
- _composeSurface = new ManagedSurface(_dims.width(), _dims.height());
- _composeSurface->clear(_bgcolor);
}
MacEditableText::~MacEditableText() {
@@ -238,10 +235,6 @@ bool MacEditableText::draw(ManagedSurface *g, bool forceRedraw) {
return true;
}
-void MacEditableText::blit(ManagedSurface *g, Common::Rect &dest) {
- g->transBlitFrom(*_composeSurface, _composeSurface->getBounds(), dest, kColorGreen2);
-}
-
void MacEditableText::drawSelection() {
if (_selectedText.endY == -1)
return;
diff --git a/graphics/macgui/maceditabletext.h b/graphics/macgui/maceditabletext.h
index d97b4184b4..62ef25fd19 100644
--- a/graphics/macgui/maceditabletext.h
+++ b/graphics/macgui/maceditabletext.h
@@ -64,7 +64,6 @@ public:
virtual bool draw(ManagedSurface *g, bool forceRedraw = false) override;
virtual bool draw(bool forceRedraw = false) override;
- virtual void blit(ManagedSurface *g, Common::Rect &dest) override;
void setAlignOffset(TextAlign align);
Common::Point calculateOffset();
diff --git a/graphics/macgui/macwidget.cpp b/graphics/macgui/macwidget.cpp
index 5cd8e0df84..a98f25480d 100644
--- a/graphics/macgui/macwidget.cpp
+++ b/graphics/macgui/macwidget.cpp
@@ -22,11 +22,12 @@
#include "common/system.h"
+#include "graphics/macgui/macwindowmanager.h"
#include "graphics/macgui/macwidget.h"
namespace Graphics {
-MacWidget::MacWidget(MacWidget *parent, int x, int y, int w, int h, bool focusable, uint16 border, uint16 gutter, uint16 shadow) :
+ MacWidget::MacWidget(MacWidget *parent, int x, int y, int w, int h, bool focusable, uint16 border, uint16 gutter, uint16 shadow) :
_focusable(focusable), _parent(parent), _border(border), _gutter(gutter), _shadow(shadow) {
_contentIsDirty = true;
@@ -39,6 +40,13 @@ MacWidget::MacWidget(MacWidget *parent, int x, int y, int w, int h, bool focusab
parent->_children.push_back(this);
_composeSurface = nullptr;
+ _maskSurface = nullptr;
+
+ _composeSurface = new ManagedSurface(_dims.width(), _dims.height());
+ _composeSurface->clear(255);
+
+ _maskSurface = new ManagedSurface(_dims.width(), _dims.height());
+ _maskSurface->clear(0);
_active = false;
_editable = false;
@@ -59,6 +67,23 @@ void MacWidget::setActive(bool active) {
_active = active;
}
+bool MacWidget::draw(bool forceRedraw) {
+ return false;
+}
+
+bool MacWidget::draw(ManagedSurface *g, bool forceRedraw) {
+ return false;
+}
+
+void MacWidget::blit(ManagedSurface *g, Common::Rect &dest) {
+ g->transBlitFrom(*_composeSurface, _composeSurface->getBounds(), dest, kColorGreen2);
+}
+
+bool MacWidget::processEvent(Common::Event &event) {
+ warning("MacWidget::processEvent");
+ return false;
+}
+
void MacWidget::removeWidget(MacWidget *child, bool del) {
for (uint i = 0; i < _children.size(); i++) {
if (_children[i] == child) {
diff --git a/graphics/macgui/macwidget.h b/graphics/macgui/macwidget.h
index f59492af1d..8fbada8977 100644
--- a/graphics/macgui/macwidget.h
+++ b/graphics/macgui/macwidget.h
@@ -26,6 +26,7 @@
#include "common/array.h"
#include "common/events.h"
#include "common/rect.h"
+#include "graphics/managed_surface.h"
namespace Common {
struct Event;
@@ -34,6 +35,7 @@ namespace Common {
namespace Graphics {
class ManagedSurface;
+class MacWindowManager;
class MacWidget {
friend class MacEditableText;
@@ -61,10 +63,10 @@ public:
*/
void setDirty(bool dirty) { _contentIsDirty = dirty; }
- virtual bool draw(ManagedSurface *g, bool forceRedraw = false) = 0;
- virtual bool draw(bool forceRedraw = false) = 0;
- virtual void blit(ManagedSurface *g, Common::Rect &dest) = 0;
- virtual bool processEvent(Common::Event &event) = 0;
+ virtual bool draw(ManagedSurface *g, bool forceRedraw = false);
+ virtual bool draw(bool forceRedraw = false);
+ virtual void blit(ManagedSurface *g, Common::Rect &dest);
+ virtual bool processEvent(Common::Event &event);
virtual bool hasAllFocus() { return _active; }
virtual bool isEditable() { return _editable; }
@@ -78,6 +80,7 @@ public:
void removeWidget(MacWidget *child, bool del = true);
Graphics::ManagedSurface *getSurface() { return _composeSurface; }
+ Graphics::ManagedSurface *getMask() { return _maskSurface; }
protected:
uint16 _border;
@@ -85,6 +88,7 @@ protected:
uint16 _shadow;
Graphics::ManagedSurface *_composeSurface;
+ Graphics::ManagedSurface *_maskSurface;
public:
bool _focusable;
Commit: 033e02536568f479d5715e60c67719238eb6c246
https://github.com/scummvm/scummvm/commit/033e02536568f479d5715e60c67719238eb6c246
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
GRAPHICS: MACGUI: MacWindowManager: Deactivate widget when mouse leaves
Changed paths:
graphics/macgui/macbutton.cpp
graphics/macgui/macwidget.cpp
graphics/macgui/macwindow.cpp
graphics/macgui/macwindowmanager.cpp
graphics/macgui/macwindowmanager.h
diff --git a/graphics/macgui/macbutton.cpp b/graphics/macgui/macbutton.cpp
index cc2c9cb871..4b77b12800 100644
--- a/graphics/macgui/macbutton.cpp
+++ b/graphics/macgui/macbutton.cpp
@@ -145,6 +145,12 @@ bool MacButton::draw(ManagedSurface *g, bool forceRedraw) {
bool MacButton::processEvent(Common::Event &event) {
switch (event.type) {
case Common::EVENT_MOUSEMOVE:
+ if (_wm->_mouseDown) {
+ if (_wm->_mode & kWMModeButtonDialogStyle)
+ return true;
+
+ setActive(true);
+ }
break;
case Common::EVENT_LBUTTONDOWN:
setActive(true);
diff --git a/graphics/macgui/macwidget.cpp b/graphics/macgui/macwidget.cpp
index a98f25480d..400ffd8e0d 100644
--- a/graphics/macgui/macwidget.cpp
+++ b/graphics/macgui/macwidget.cpp
@@ -80,11 +80,13 @@ void MacWidget::blit(ManagedSurface *g, Common::Rect &dest) {
}
bool MacWidget::processEvent(Common::Event &event) {
- warning("MacWidget::processEvent");
return false;
}
void MacWidget::removeWidget(MacWidget *child, bool del) {
+ if (_children.size() == 0)
+ return;
+
for (uint i = 0; i < _children.size(); i++) {
if (_children[i] == child) {
if (del)
diff --git a/graphics/macgui/macwindow.cpp b/graphics/macgui/macwindow.cpp
index 36ad8eded6..a71bcbb7e8 100644
--- a/graphics/macgui/macwindow.cpp
+++ b/graphics/macgui/macwindow.cpp
@@ -479,6 +479,11 @@ bool MacWindow::processEvent(Common::Event &event) {
switch (event.type) {
case Common::EVENT_MOUSEMOVE:
+ if (_wm->_mouseDown && _wm->_hoveredWidget && !_wm->_hoveredWidget->_dims.contains(event.mouse.x, event.mouse.y)) {
+ _wm->_hoveredWidget->setActive(false);
+ _wm->_hoveredWidget = nullptr;
+ }
+
if (_beingDragged) {
_dims.translate(event.mouse.x - _draggedX, event.mouse.y - _draggedY);
updateInnerDims();
@@ -527,6 +532,7 @@ bool MacWindow::processEvent(Common::Event &event) {
case Common::EVENT_LBUTTONUP:
_beingDragged = false;
_beingResized = false;
+ _wm->_mouseDownWidget = nullptr;
setHighlight(kBorderNone);
break;
@@ -544,9 +550,16 @@ bool MacWindow::processEvent(Common::Event &event) {
return false;
}
- MacWidget *w = findEventHandler(event, _dims.left, _dims.top);
- if (w && w != this && w->processEvent(event))
- return true;
+ MacWidget *w = _wm->_mouseDownWidget ? _wm->_mouseDownWidget : findEventHandler(event, _dims.left, _dims.top);
+ if (w && w != this) {
+ _wm->_hoveredWidget = w;
+
+ if (event.type == Common::EVENT_LBUTTONDOWN)
+ _wm->_mouseDownWidget = w;
+
+ if (w->processEvent(event))
+ return true;
+ }
if (_callback)
return (*_callback)(click, event, _dataPtr);
diff --git a/graphics/macgui/macwindowmanager.cpp b/graphics/macgui/macwindowmanager.cpp
index 204abcbab0..2bf4528b88 100644
--- a/graphics/macgui/macwindowmanager.cpp
+++ b/graphics/macgui/macwindowmanager.cpp
@@ -159,6 +159,9 @@ MacWindowManager::MacWindowManager(uint32 mode) {
_needsRemoval = false;
_activeWidget = nullptr;
+ _mouseDown = false;
+ _hoveredWidget = nullptr;
+ _mouseDownWidget = nullptr;
_mode = mode;
@@ -313,6 +316,8 @@ void MacWindowManager::setActiveWindow(int id) {
void MacWindowManager::removeWindow(MacWindow *target) {
_windowsToRemove.push_back(target);
_needsRemoval = true;
+ _hoveredWidget = nullptr;
+ _mouseDownWidget = nullptr;
if (target->getId() == _activeWindow)
_activeWindow = -1;
@@ -427,8 +432,19 @@ static void menuTimerHandler(void *refCon) {
}
bool MacWindowManager::processEvent(Common::Event &event) {
- if (event.type == Common::EVENT_MOUSEMOVE)
+ switch (event.type) {
+ case Common::EVENT_MOUSEMOVE:
_lastMousePos = event.mouse;
+ break;
+ case Common::EVENT_LBUTTONDOWN:
+ _mouseDown = true;
+ break;
+ case Common::EVENT_LBUTTONUP:
+ _mouseDown = false;
+ break;
+ default:
+ break;
+ }
if (_menu && !_menu->isVisible()) {
if ((_mode & kWMModeAutohideMenu) && event.type == Common::EVENT_MOUSEMOVE) {
diff --git a/graphics/macgui/macwindowmanager.h b/graphics/macgui/macwindowmanager.h
index e962a3827a..158428704d 100644
--- a/graphics/macgui/macwindowmanager.h
+++ b/graphics/macgui/macwindowmanager.h
@@ -66,7 +66,8 @@ enum {
kWMModeForceBuiltinFonts= (1 << 3),
kWMModeUnicode = (1 << 4),
kWMModeManualDrawWidgets= (1 << 5),
- kWMModeFullscreen = (1 << 6)
+ kWMModeFullscreen = (1 << 6),
+ kWMModeButtonDialogStyle= (1 << 7)
};
}
@@ -256,9 +257,13 @@ public:
Common::Rect _menuHotzone;
bool _menuTimerActive;
+ bool _mouseDown;
int _colorBlack, _colorWhite;
+ MacWidget *_hoveredWidget;
+ MacWidget *_mouseDownWidget;
+
private:
void drawDesktop();
Commit: a2e230803df0e84bdd1aeb0bd4af8778537c2f16
https://github.com/scummvm/scummvm/commit/a2e230803df0e84bdd1aeb0bd4af8778537c2f16
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
DIRECTOR: Render texts and buttons with widgets
Changed paths:
R engines/director/cachedmactext.cpp
R engines/director/cachedmactext.h
engines/director/cast.cpp
engines/director/cast.h
engines/director/events.cpp
engines/director/lingo/lingo-the.cpp
engines/director/module.mk
engines/director/score-loading.cpp
engines/director/score.cpp
engines/director/score.h
engines/director/sprite.cpp
engines/director/sprite.h
diff --git a/engines/director/cachedmactext.cpp b/engines/director/cachedmactext.cpp
deleted file mode 100644
index 4d690f828e..0000000000
--- a/engines/director/cachedmactext.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "graphics/macgui/macfontmanager.h"
-#include "graphics/macgui/macwindowmanager.h"
-#include "graphics/macgui/mactext.h"
-
-#include "director/director.h"
-#include "director/cast.h"
-#include "director/cachedmactext.h"
-
-namespace Director {
-
-void CachedMacText::makeMacText() {
- assert(_width != -1);
- assert(_wm != NULL);
-
- delete _macText;
- _macText = nullptr;
-
- if ((int)_textCast->_textAlign == -1)
- _align = (Graphics::TextAlign)3;
- else
- _align = (Graphics::TextAlign)((int)_textCast->_textAlign + 1);
-
- Graphics::MacFont *macFont = new Graphics::MacFont(_textCast->_fontId,
- _textCast->_fontSize,
- _textCast->_textSlant);
-
- debugC(5, kDebugText, "CachedMacText::makeMacText(): font id: %d size: %d slant: %d name: %s '%s'",
- _textCast->_fontId, _textCast->_fontSize, _textCast->_textSlant, macFont->getName().c_str(),
- Common::toPrintable(_textCast->_ftext).c_str());
-
- uint color = _wm->findBestColor(_textCast->_palinfo1 & 0xff, _textCast->_palinfo2 & 0xff, _textCast->_palinfo3 & 0xff);
-
- _macText = new Graphics::MacText(_textCast->_ftext, _wm, macFont, color, _bgcolor, _width, _align, 1);
-
- delete macFont;
-}
-
-CachedMacText::~CachedMacText() {
- delete _macText;
-}
-
-CachedMacText::CachedMacText(TextCast *const textCast, int32 bgcolor, int version, int defaultWidth,
- Graphics::MacWindowManager *const wm) :
- _surface(NULL), _macText(NULL), _width(defaultWidth), _dirty(true),
- _textCast(textCast), _wm(wm), _bgcolor(bgcolor), _align(Graphics::kTextAlignLeft) {
-
- debugC(5, kDebugText, "CachedMacText::CachedMacText(): font id: %d '%s'", _textCast->_fontId, Common::toPrintable(_textCast->_ftext).c_str());
-
- if (_width == -1) {
- if (version >= 4) {
- // This came from frame.cpp
- _width = _textCast->_initialRect.right;
- } else {
- _width = _textCast->_initialRect.width();
- }
- }
-
- if (_wm != NULL)
- makeMacText();
-}
-
-void CachedMacText::setWm(Graphics::MacWindowManager *wm) {
- if (wm != _wm) {
- _dirty = true;
- _wm = wm;
- makeMacText();
- }
-}
-
-void CachedMacText::clip(int width) {
- if (width != _width) {
- _dirty = true;
- _width = width;
- if (_wm != NULL)
- makeMacText();
- }
-}
-
-void CachedMacText::forceDirty() {
- _dirty = true;
-
- makeMacText();
-}
-
-const Graphics::ManagedSurface *CachedMacText::getSurface() {
- assert(_wm != NULL);
- if (_dirty) {
- _macText->render();
- _surface = _macText->getSurface();
- _dirty = false;
- }
- return _surface;
-}
-
-int CachedMacText::getLineCount() {
- assert(_macText != NULL);
- return _macText->getLineCount();
-}
-
-} // End of namespace Director
diff --git a/engines/director/cachedmactext.h b/engines/director/cachedmactext.h
deleted file mode 100644
index 2b4c3a27ca..0000000000
--- a/engines/director/cachedmactext.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef DIRECTOR_CACHEDMACTEXT_H
-#define DIRECTOR_CACHEDMACTEXT_H
-
-#include "graphics/font.h"
-
-namespace Graphics {
-class ManagedSurface;
-class MacText;
-class MacWindowManager;
-}
-
-namespace Director {
-
-class TextCast;
-
-class CachedMacText {
-private:
- int _width;
- const TextCast *_textCast;
- Graphics::MacWindowManager *_wm;
- Graphics::MacText *_macText;
- Graphics::TextAlign _align;
- bool _dirty;
- Graphics::ManagedSurface *_surface;
- void makeMacText();
- int32 _bgcolor;
-
-public:
- CachedMacText(TextCast *const textCast, int32 bgcolor, int version, int defaultWidth = -1,
- Graphics::MacWindowManager *const wm = NULL);
- ~CachedMacText();
-
- void setWm(Graphics::MacWindowManager *wm);
- void clip(int width);
- void setBgColor(int color) { _bgcolor = color; }
- void forceDirty();
- const Graphics::ManagedSurface *getSurface();
- int getLineCount();
-
- void setStxt(const TextCast *stxt) { _textCast = stxt; forceDirty(); }
-};
-
-} // End of namespace Director
-
-#endif
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 7264fb9c42..fa557f70d6 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -22,11 +22,12 @@
#include "common/substream.h"
#include "graphics/surface.h"
+#include "graphics/macgui/macwindowmanager.h"
#include "graphics/macgui/maceditabletext.h"
+#include "graphics/macgui/macbutton.h"
#include "image/image_decoder.h"
#include "director/director.h"
-#include "director/cachedmactext.h"
#include "director/cast.h"
#include "director/score.h"
#include "director/sound.h"
@@ -47,6 +48,18 @@ Cast::Cast() {
Cast::~Cast() {
if (_img)
delete _img;
+
+ if (_widget)
+ delete _widget;
+}
+
+bool Cast::isEditable() {
+ return false;
+}
+
+bool Cast::setEditable(bool editable) {
+ warning("Cast::setEditable: Attempted to set editable of non-editable cast");
+ return false;
}
BitmapCast::BitmapCast(Common::ReadStreamEndian &stream, uint32 castTag, uint16 version) {
@@ -255,13 +268,22 @@ TextCast::TextCast(Common::ReadStreamEndian &stream, uint16 version, int32 bgcol
stream.readUint16();
}
- _cachedMacText = new CachedMacText(this, _bgcolor, version, -1, g_director->_wm);
-
_modified = false;
}
-TextCast::~TextCast() {
- delete _cachedMacText;
+Graphics::TextAlign TextCast::getAlignment() {
+ switch (_textAlign) {
+ case kTextAlignRight:
+ return Graphics::kTextAlignRight;
+ break;
+ case kTextAlignCenter:
+ return Graphics::kTextAlignCenter;
+ break;
+ case kTextAlignLeft:
+ default:
+ return Graphics::kTextAlignLeft;
+ break;
+ }
}
void TextCast::importStxt(const Stxt *stxt) {
@@ -273,11 +295,21 @@ void TextCast::importStxt(const Stxt *stxt) {
_palinfo3 = stxt->_palinfo3;
_ftext = stxt->_ftext;
_ptext = stxt->_ptext;
+}
+
+void TextCast::createWidget() {
+ uint fgcolor = g_director->_wm->findBestColor(_palinfo1 & 0xff, _palinfo2 & 0xff, _palinfo3 & 0xff);
+ warning("TextCast::createWidget: bgcolor: %d, fgcolor: %d", _bgcolor, fgcolor);
+
+ Graphics::MacFont *macFont = new Graphics::MacFont(_fontId, _fontSize, _textSlant);
+
+ _widget = new Graphics::MacEditableText(g_director->getCurrentScore()->_window, 0, 0, _initialRect.width(), _initialRect.height(), g_director->_wm, _ftext, macFont, fgcolor, _bgcolor, _initialRect.width(), getAlignment(), 1, _borderSize, _gutterSize, _boxShadow, _textShadow);
- _cachedMacText->setStxt(this);
+ ((Graphics::MacEditableText *)_widget)->draw();
+ delete macFont;
}
-void TextCast::importRTE(byte *text) {
+void TextCast::importRTE(byte *text) {
//assert(rteList.size() == 3);
//child0 is probably font data.
//child1 is the raw text.
@@ -292,12 +324,14 @@ void TextCast::setText(const char *text) {
_ptext = _ftext = text;
- _cachedMacText->forceDirty();
-
if (_widget) {
- ((Graphics::MacEditableText *)_widget)->clearText();
- ((Graphics::MacEditableText *)_widget)->appendTextDefault(_ftext);
+ Graphics::MacEditableText *wtext = (Graphics::MacEditableText *)_widget;
+ wtext->clearText();
+ wtext->appendTextDefault(_ftext);
+ wtext->draw();
}
+
+ _modified = true;
}
Common::String TextCast::getText() {
@@ -307,6 +341,34 @@ Common::String TextCast::getText() {
return _ptext;
}
+bool TextCast::isModified() {
+ return _modified || (_widget ? ((Graphics::MacEditableText *)_widget)->_contentIsDirty : false);
+}
+
+bool TextCast::isEditable() {
+ if (!_widget) {
+ warning("TextCast::setEditable: Attempt to set editable of null widget");
+ return false;
+ }
+
+ return (Graphics::MacEditableText *)_widget->_editable;
+}
+
+bool TextCast::setEditable(bool editable) {
+ if (!_widget) {
+ warning("TextCast::setEditable: Attempt to set editable of null widget");
+ return false;
+ }
+
+ Graphics::MacEditableText *text = (Graphics::MacEditableText *)_widget;
+ text->_focusable = editable;
+ text->setEditable(editable);
+ text->_selectable = editable;
+ // text->setActive(editable);
+
+ return true;
+}
+
ShapeCast::ShapeCast(Common::ReadStreamEndian &stream, uint16 version) {
_type = kCastShape;
@@ -379,6 +441,19 @@ ButtonCast::ButtonCast(Common::ReadStreamEndian &stream, uint16 version) : TextC
}
}
+void ButtonCast::createWidget() {
+ uint fgcolor = g_director->_wm->findBestColor(_palinfo1 & 0xff, _palinfo2 & 0xff, _palinfo3 & 0xff);
+
+ Graphics::MacFont *macFont = new Graphics::MacFont(_fontId, _fontSize, _textSlant);
+
+ _widget = new Graphics::MacButton(Graphics::MacButtonType(_buttonType), getAlignment(), g_director->getCurrentScore()->_window, 0, 0, _initialRect.width(), _initialRect.height(), g_director->_wm, _ftext, macFont, fgcolor, _bgcolor);
+
+ _widget->_focusable = true;
+
+ ((Graphics::MacButton *)(_widget))->draw();
+ delete macFont;
+}
+
ScriptCast::ScriptCast(Common::ReadStreamEndian &stream, uint16 version) {
_type = kCastLingoScript;
_scriptType = kNoneScript;
diff --git a/engines/director/cast.h b/engines/director/cast.h
index c3bac04fc7..2c8c94823a 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -26,8 +26,13 @@
#include "director/archive.h"
#include "director/types.h"
+#include "graphics/font.h"
+
namespace Graphics {
struct Surface;
+class MacEditableText;
+class MacWindowManager;
+class MacButton;
class MacWidget;
}
@@ -43,13 +48,15 @@ class ImageDecoder;
namespace Director {
class Stxt;
-class CachedMacText;
class SNDDecoder;
class Cast {
public:
Cast();
virtual ~Cast();
+ virtual bool isEditable();
+ virtual bool setEditable(bool editable);
+ virtual bool isModified() { return _modified; }
CastType _type;
Common::Rect _initialRect;
@@ -105,9 +112,14 @@ public:
class TextCast : public Cast {
public:
TextCast(Common::ReadStreamEndian &stream, uint16 version, int32 bgcolor);
- virtual ~TextCast();
void setText(const char *text);
+ virtual void createWidget();
+
+ virtual bool isModified() override;
+ virtual bool isEditable() override;
+ virtual bool setEditable(bool editable) override;
+ Graphics::TextAlign getAlignment();
SizeType _borderSize;
SizeType _gutterSize;
@@ -128,7 +140,6 @@ public:
Common::String _ptext;
void importStxt(const Stxt *stxt);
void importRTE(byte* text);
- CachedMacText *_cachedMacText;
Common::String getText();
};
@@ -136,6 +147,7 @@ public:
class ButtonCast : public TextCast {
public:
ButtonCast(Common::ReadStreamEndian &stream, uint16 version);
+ virtual void createWidget() override;
ButtonType _buttonType;
};
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index 0571c34140..e37522ab28 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -85,9 +85,7 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
if (draggedSprite->_moveable) {
pos = g_system->getEventManager()->getMousePos();
Common::Point delta = pos - _draggingSpritePos;
- draggedSprite->_currentPoint.x += delta.x;
- draggedSprite->_currentPoint.y += delta.y;
- draggedSprite->_dirty = true;
+ draggedSprite->translate(delta);
_draggingSpritePos = pos;
} else {
releaseDraggedSprite();
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 806f926bc8..4b7d3576e6 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -683,7 +683,7 @@ Datum Lingo::getTheSprite(Datum &id1, int field) {
d.u.i = sprite->_constraint;
break;
case kTheEditableText:
- d = Datum(sprite->_editableText);
+ d.u.i = sprite->_cast ? sprite->_cast->isEditable() : 0;
break;
case kTheForeColor:
d.u.i = sprite->_foreColor;
@@ -798,7 +798,7 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
sprite->_constraint = d.asInt();
break;
case kTheEditableText:
- sprite->_editableText = d.asString();
+ sprite->_cast ? sprite->_cast->setEditable(d.asInt()) : false;
break;
case kTheForeColor:
sprite->_foreColor = d.asInt();
diff --git a/engines/director/module.mk b/engines/director/module.mk
index 914a5c0e51..6b6c755bf7 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -3,7 +3,6 @@ MODULE := engines/director
MODULE_OBJS = \
archive.o \
cast.o \
- cachedmactext.o \
detection.o \
director.o \
events.o \
diff --git a/engines/director/score-loading.cpp b/engines/director/score-loading.cpp
index 1ecf0eebd0..840affb61a 100644
--- a/engines/director/score-loading.cpp
+++ b/engines/director/score-loading.cpp
@@ -119,6 +119,10 @@ bool Score::loadArchive() {
_stageColor = 1;
}
+ _window = _vm->_wm->addWindow(false, false, false);
+ _window->disableBorder();
+ _window->resize(_movieRect.width(), _movieRect.height());
+
// Cast Information Array
if (_movieArchive->hasResource(MKTAG('V', 'W', 'C', 'R'), -1)) {
_castIDoffset = _movieArchive->getResourceIDList(MKTAG('V', 'W', 'C', 'R'))[0];
@@ -224,11 +228,6 @@ bool Score::loadArchive() {
debug("STUB: Unhandled 'SCVW' resource");
}
- setSpriteCasts();
- setSpriteBboxes();
- loadSpriteImages(false);
- loadSpriteSounds(false);
-
// Now process STXTs
Common::Array<uint16> stxt = _movieArchive->getResourceIDList(MKTAG('S','T','X','T'));
debugC(2, kDebugLoading, "****** Loading %d STXT resources", stxt.size());
@@ -250,6 +249,11 @@ bool Score::loadArchive() {
}
copyCastStxts();
+ setSpriteCasts();
+ setSpriteBboxes();
+ loadSpriteImages(false);
+ loadSpriteSounds(false);
+
return true;
}
@@ -267,7 +271,9 @@ void Score::copyCastStxts() {
if (_loadedStxts->getVal(stxtid)) {
const Stxt *stxt = _loadedStxts->getVal(stxtid);
TextCast *tc = (TextCast *)c->_value;
+
tc->importStxt(stxt);
+ tc->createWidget();
}
}
}
@@ -673,6 +679,12 @@ void Score::setSpriteBboxes() {
for (uint16 i = 0; i < _frames.size(); i++) {
for (uint16 j = 0; j < _frames[i]->_sprites.size(); j++) {
Sprite *sp = _frames[i]->_sprites[j];
+ if (i == 1)
+ // Only call updateCast on the first frame sprites, because renderSprite
+ // calls updateCast for us after that. We need to get widget bounding info here.
+ // if (i == 1)
+ sp->updateCast();
+
sp->_startBbox = sp->getBbox();
sp->_currentBbox = sp->_startBbox;
}
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 197b91c521..721bf5e105 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -26,7 +26,6 @@
#include "graphics/primitives.h"
#include "graphics/macgui/macwindowmanager.h"
#include "graphics/macgui/maceditabletext.h"
-#include "director/cachedmactext.h"
#include "director/director.h"
#include "director/cast.h"
@@ -296,10 +295,6 @@ void Score::startLoop() {
initGraphics(_movieRect.width(), _movieRect.height());
- _window = _vm->_wm->addWindow(false, false, false);
- _window->disableBorder();
- _window->resize(_movieRect.width(), _movieRect.height());
-
_surface = _window->getWindowSurface();
_maskSurface = new Graphics::ManagedSurface;
_backSurface = new Graphics::ManagedSurface;
@@ -324,6 +319,7 @@ void Score::startLoop() {
_vm->_backSurface.create(_movieRect.width(), _movieRect.height());
_vm->_wm->setScreen(_surface);
+ _vm->_wm->_lastWidget = nullptr;
_surface->clear(_stageColor);
@@ -434,9 +430,6 @@ void Score::update() {
_vm->_newMovieStarted = false;
- // _surface->clear(_stageColor);
- // _surface->copyFrom(*_trailSurface);
-
_lingo->executeImmediateScripts(_frames[_currentFrame]);
if (_vm->getVersion() >= 6) {
@@ -509,7 +502,7 @@ void Score::renderFrame(uint16 frameId, bool forceUpdate, bool updateStageOnly)
// - The cast member ID of the sprite has changed (_dirty flag set)
// - The sprite slot from the current frame is different (cast member ID or bounding box) from the cached sprite slot
// (maybe we have to compare all the sprite attributes, not just these two?)
- bool needsUpdate = currentSprite->_dirty || currentSprite->_castId != nextSprite->_castId || currentSprite->_currentBbox != nextSprite->_currentBbox;
+ bool needsUpdate = currentSprite->isDirty() || currentSprite->_castId != nextSprite->_castId || currentSprite->_currentBbox != nextSprite->_currentBbox;
if (needsUpdate || forceUpdate)
unrenderSprite(i);
@@ -551,11 +544,15 @@ void Score::unrenderSprite(uint16 spriteId) {
currentSprite->_currentBbox = currentSprite->getBbox();
currentSprite->_dirty = false;
+
+ if (currentSprite->_cast)
+ currentSprite->_cast->_modified = false;
}
void Score::renderSprite(uint16 id) {
Sprite *sprite = _sprites[id];
+ sprite->updateCast();
if (!sprite || !sprite->_enabled)
return;
@@ -573,7 +570,7 @@ void Score::renderSprite(uint16 id) {
if (castType == kCastShape) {
renderShape(id);
} else if (castType == kCastText || castType == kCastRTE) {
- renderText(id, NULL);
+ renderText(id);
} else if (castType == kCastButton) {
renderButton(id);
} else {
@@ -588,6 +585,8 @@ void Score::renderSprite(uint16 id) {
renderBitmap(id);
}
+
+ sprite->setClean();
}
void Score::renderShape(uint16 spriteId) {
@@ -708,7 +707,6 @@ void Score::renderShape(uint16 spriteId) {
inkBasedBlit(&maskSurface, tmpSurface, ink, shapeRect, spriteId);
}
-
void Score::renderButton(uint16 spriteId) {
uint16 castId = _sprites[spriteId]->_castId;
@@ -723,241 +721,31 @@ void Score::renderButton(uint16 spriteId) {
}
ButtonCast *button = (ButtonCast *)member;
- // Sometimes, at least in the D3 Workshop Examples, these buttons are just TextCast.
- // If they are, then we just want to use the spriteType as the button type.
- // If they are full-bown Cast members, then use the actual cast member type.
- int buttonType = _sprites[spriteId]->_spriteType;
- if (buttonType == kCastMemberSprite) {
- switch (button->_buttonType) {
- case kTypeCheckBox:
- buttonType = kCheckboxSprite;
- break;
- case kTypeButton:
- buttonType = kButtonSprite;
- break;
- case kTypeRadio:
- buttonType = kRadioButtonSprite;
- break;
- }
- }
-
- bool invert = spriteId == _vm->getCurrentScore()->_currentMouseDownSpriteId;
-
// TODO: review all cases to confirm if we should use text height.
// height = textRect.height();
- Common::Rect _rect = _sprites[spriteId]->_currentBbox;
- int16 x = _rect.left;
- int16 y = _rect.top;
-
- Common::Rect textRect(0, 0, _rect.width(), _rect.height());
-
- // WORKAROUND, HACK
- // Because we're not drawing text with transparency
- // We swap drawing depending on whether the button is
- // inverted or not, to prevent destroying the border
- if (!invert)
- renderText(spriteId, &textRect);
-
- Graphics::MacPlotData plotStroke(_surface, nullptr, &_vm->getPatterns(), 1, 0, 0, 1, 0);
-
- switch (buttonType) {
- case kCheckboxSprite:
- _surface->frameRect(_rect, 0);
- break;
- case kButtonSprite: {
- Graphics::MacPlotData pd(_surface, nullptr, &_vm->getMacWindowManager()->getPatterns(), Graphics::MacGUIConstants::kPatternSolid, 0, 0, 1, invert ? Graphics::kColorBlack : Graphics::kColorWhite);
+ Common::Rect bbox = _sprites[spriteId]->_currentBbox;
- Graphics::drawRoundRect(_rect, 4, 0, invert, Graphics::macDrawPixel, &pd);
- }
- break;
- case kRadioButtonSprite:
- Graphics::drawEllipse(x, y + 2, x + 11, y + 13, 0, false, Graphics::macDrawPixel, &plotStroke);
- break;
- default:
- warning("renderButton: Unknown buttonType");
- break;
- }
-
- if (invert)
- renderText(spriteId, &textRect);
+ inkBasedBlit(nullptr, button->_widget->getSurface()->rawSurface(), _sprites[spriteId]->_ink, bbox, spriteId);
}
-void Score::renderText(uint16 spriteId, Common::Rect *textRect) {
- TextCast *textCast = (TextCast*)_sprites[spriteId]->_cast;
- if (textCast == nullptr) {
+void Score::renderText(uint16 spriteId) {
+ TextCast *text = (TextCast*)_sprites[spriteId]->_cast;
+ if (text == nullptr) {
warning("Score::renderText(): TextCast #%d is a nullptr", spriteId);
return;
}
- Score *score = _vm->getCurrentScore();
- Sprite *sprite = _sprites[spriteId];
-
- Common::Rect bbox = sprite->_currentBbox;
- int width = bbox.width();
- int height = bbox.height();
- int x = bbox.left;
- int y = bbox.top;
+ Common::Rect bbox = _sprites[spriteId]->_currentBbox;
+ text->_widget->draw();
- if (_vm->getCurrentScore()->_fontMap.contains(textCast->_fontId)) {
+ if (_fontMap.contains(text->_fontId)) {
// We need to make sure that the Shared Cast fonts have been loaded in?
// might need a mapping table here of our own.
// textCast->fontId = _vm->_wm->_fontMan->getFontIdByName(_vm->getCurrentScore()->_fontMap[textCast->fontId]);
}
- if (width == 0 || height == 0) {
- warning("Score::renderText(): Requested to draw on an empty surface: %d x %d", width, height);
- return;
- }
-
- if (sprite->_editable) {
- if (!textCast->_widget) {
- warning("Creating MacEditableText with '%s'", toPrintable(textCast->_ftext).c_str());
- textCast->_widget = new Graphics::MacEditableText(score->_window, x, y, width, height, g_director->_wm, textCast->_ftext, new Graphics::MacFont(), 0, 255, width);
- warning("Finished creating MacEditableText");
- }
-
- textCast->_widget->draw();
-
- InkType ink = sprite->_ink;
-
- // if (spriteId == score->_currentMouseDownSpriteId)
- // ink = kInkTypeReverse;
-
- inkBasedBlit(nullptr, textCast->_widget->getSurface()->rawSurface(), ink, Common::Rect(x, y, x + width, y + height), spriteId);
-
- return;
- }
-
- debugC(3, kDebugText, "renderText: sprite: %d x: %d y: %d w: %d h: %d fontId: '%d' text: '%s'", spriteId, x, y, width, height, textCast->_fontId, Common::toPrintable(textCast->_ftext).c_str());
-
- uint16 boxShadow = (uint16)textCast->_boxShadow;
- uint16 borderSize = (uint16)textCast->_borderSize;
- if (textRect != NULL)
- borderSize = 0;
- uint16 padding = (uint16)textCast->_gutterSize;
- uint16 textShadow = (uint16)textCast->_textShadow;
-
- //uint32 rectLeft = textCast->initialRect.left;
- //uint32 rectTop = textCast->initialRect.top;
-
- textCast->_cachedMacText->clip(width);
- const Graphics::ManagedSurface *textSurface = textCast->_cachedMacText->getSurface();
-
- if (!textSurface)
- return;
-
- height = textSurface->h;
- if (textRect != NULL) {
- // TODO: this offset could be due to incorrect fonts loaded!
- textRect->bottom = height + textCast->_cachedMacText->getLineCount();
- }
-
- uint16 textX = 0, textY = 0;
-
- if (textRect == NULL) {
- if (borderSize > 0) {
- if (_vm->getVersion() <= 3) {
- height += (borderSize * 2);
- textX += (borderSize + 2);
- } else {
- height += borderSize;
- textX += (borderSize + 1);
- }
- textY += borderSize;
- } else {
- x += 1;
- }
-
- if (padding > 0) {
- width += padding * 2;
- height += padding;
- textY += padding / 2;
- }
-
- if (textCast->_textAlign == kTextAlignRight)
- textX -= 1;
-
- if (textShadow > 0)
- textX--;
- } else {
- x++;
- if (width % 2 != 0)
- x++;
-
- if (sprite->_spriteType != kCastMemberSprite) {
- y += 2;
- switch (sprite->_spriteType) {
- case kCheckboxSprite:
- textX += 16;
- break;
- case kRadioButtonSprite:
- textX += 17;
- break;
- default:
- break;
- }
- } else {
- ButtonType buttonType = ((ButtonCast*)textCast)->_buttonType;
- switch (buttonType) {
- case kTypeCheckBox:
- width += 4;
- textX += 16;
- break;
- case kTypeRadio:
- width += 4;
- textX += 17;
- break;
- case kTypeButton:
- width += 4;
- y += 2;
- break;
- default:
- warning("Score::renderText(): Expected button but got unexpected button type: %d", buttonType);
- y += 2;
- break;
- }
- }
- }
-
- switch (textCast->_textAlign) {
- case kTextAlignLeft:
- default:
- break;
- case kTextAlignCenter:
- textX = (width / 2) - (textSurface->w / 2) + (padding / 2) + borderSize;
- break;
- case kTextAlignRight:
- textX = width - (textSurface->w + 1) + (borderSize * 2) - (textShadow * 2) - (padding);
- break;
- }
-
- Graphics::ManagedSurface textWithFeatures(width + (borderSize * 2) + boxShadow + textShadow, height + borderSize + boxShadow + textShadow);
- textWithFeatures.fillRect(Common::Rect(textWithFeatures.w, textWithFeatures.h), score->getStageColor());
-
- if (textRect == NULL && boxShadow > 0) {
- textWithFeatures.fillRect(Common::Rect(boxShadow, boxShadow, textWithFeatures.w + boxShadow, textWithFeatures.h), 0);
- }
-
- if (textRect == NULL && borderSize != kSizeNone) {
- for (int bb = 0; bb < borderSize; bb++) {
- Common::Rect borderRect(bb, bb, textWithFeatures.w - bb - boxShadow - textShadow, textWithFeatures.h - bb - boxShadow - textShadow);
- textWithFeatures.fillRect(borderRect, 0xff);
- textWithFeatures.frameRect(borderRect, 0);
- }
- }
-
- if (textShadow > 0)
- textWithFeatures.transBlitFrom(textSurface->rawSurface(), Common::Point(textX + textShadow, textY + textShadow), 0xff);
-
- textWithFeatures.transBlitFrom(textSurface->rawSurface(), Common::Point(textX, textY), 0xff);
-
- InkType ink = sprite->_ink;
-
- // if (spriteId == score->_currentMouseDownSpriteId)
- // ink = kInkTypeReverse;
-
- inkBasedBlit(nullptr, textWithFeatures, ink, Common::Rect(x, y, x + width, y + height), spriteId);
+ inkBasedBlit(nullptr, text->_widget->getSurface()->rawSurface(), _sprites[spriteId]->_ink, bbox, spriteId);
}
void Score::renderBitmap(uint16 spriteId) {
diff --git a/engines/director/score.h b/engines/director/score.h
index 22c438e015..48dc4d2119 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -149,7 +149,7 @@ public:
private:
void update();
- void renderText(uint16 spriteId, Common::Rect *textSize);
+ void renderText(uint16 spriteId);
void renderShape(uint16 spriteId);
void renderButton(uint16 spriteId);
void renderBitmap(uint16 spriteId);
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index 0b1da06a03..d99eaef0b7 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -24,6 +24,8 @@
#include "director/cast.h"
#include "director/sprite.h"
+#include "graphics/macgui/macwidget.h"
+
namespace Director {
Sprite::Sprite() {
@@ -69,6 +71,37 @@ Sprite::Sprite() {
Sprite::~Sprite() {
}
+void Sprite::updateCast() {
+ if (_cast && _cast->_widget) {
+ if (_cast->isEditable() != _editable && !_puppet)
+ _cast->setEditable(_editable);
+ _cast->_widget->_dims.moveTo(_currentPoint.x, _currentPoint.y);
+ }
+}
+
+void Sprite::translate(Common::Point delta, bool moveTo) {
+ _currentPoint += delta;
+
+ if (_cast && _cast->_widget) {
+ if (moveTo)
+ _cast->_widget->_dims.translate(delta.x, delta.y);
+ else
+ _cast->_widget->_dims.moveTo(delta.x, delta.y);
+ }
+
+ _dirty = true;
+}
+
+bool Sprite::isDirty() {
+ return _dirty || (_cast && _cast->isModified());
+}
+
+void Sprite::setClean() {
+ _dirty = false;
+ if (_cast)
+ _cast->_modified = false;
+}
+
uint16 Sprite::getPattern() {
switch (_spriteType) {
case kRectangleSprite:
@@ -196,89 +229,15 @@ Common::Rect Sprite::getBbox() {
_currentPoint.y + _height);
break;
case kCastRTE:
- case kCastText: {
- if (!_cast)
- return result;
-
- TextCast *textCast = (TextCast*)_cast;
- int x = _currentPoint.x; // +rectLeft;
- int y = _currentPoint.y; // +rectTop;
- int height = textCast->_initialRect.height(); //_sprites[spriteId]->_height;
- int width;
- Common::Rect *textRect = NULL;
-
- if (g_director->getVersion() >= 4) {
- // where does textRect come from?
- if (textRect == NULL) {
- width = textCast->_initialRect.right;
- } else {
- width = textRect->width();
- }
- } else {
- width = textCast->_initialRect.width(); //_sprites[spriteId]->_width;
- }
+ case kCastText:
+ case kCastButton:
+ {
+ if (!_cast)
+ return result;
- result = Common::Rect(x, y, x + width, y + height);
- break;
- }
- case kCastButton: {
- // This may not be a button cast. It could be a textcast with the
- // channel forcing it to be a checkbox or radio button!
- if (!_cast)
- return result;
-
- ButtonCast *button = (ButtonCast *)_cast;
-
- // Sometimes, at least in the D3 Workshop Examples, these buttons are
- // just TextCast. If they are, then we just want to use the spriteType
- // as the button type. If they are full-bown Cast members, then use the
- // actual cast member type.
- int buttonType = _spriteType;
- if (buttonType == kCastMemberSprite) {
- switch (button->_buttonType) {
- case kTypeCheckBox:
- buttonType = kCheckboxSprite;
- break;
- case kTypeButton:
- buttonType = kButtonSprite;
- break;
- case kTypeRadio:
- buttonType = kRadioButtonSprite;
- break;
- }
- }
-
- uint32 rectLeft = button->_initialRect.left;
- uint32 rectTop = button->_initialRect.top;
-
- int x = _currentPoint.x;
- int y = _currentPoint.y;
-
- if (g_director->getVersion() > 3) {
- x += rectLeft;
- y += rectTop;
- }
-
- int height = button->_initialRect.height();
- int width = button->_initialRect.width() + 3;
-
- switch (buttonType) {
- case kCheckboxSprite:
- // Magic numbers: checkbox square need to move left about 5px from
- // text and 12px side size (D4)
- result = Common::Rect(x, y + 2, x + 12, y + 14);
- break;
- case kButtonSprite:
- result = Common::Rect(x, y, x + width, y + height + 3);
+ result = _cast->_widget->getDimensions();
break;
- case kRadioButtonSprite:
- result = Common::Rect(x, y + 2, x + 12, y + 14);
- break;
- default:
- warning("Score::getBbox(): Unknown buttonType");
}
- break;
- }
case kCastBitmap: {
if (!_cast)
return result;
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index e97e73d87f..58e28a900b 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -62,6 +62,10 @@ public:
Sprite();
~Sprite();
+ void updateCast();
+ void translate(Common::Point delta, bool moveTo = false);
+ bool isDirty();
+ void setClean();
uint16 getPattern();
void setPattern(uint16 pattern);
@@ -113,9 +117,6 @@ public:
uint16 _stopTime;
byte _volume;
byte _stretch;
-
- // Using in text sprites
- Common::String _editableText;
};
} // End of namespace Director
Commit: bd216b237c40a0b87fa5954adc1485fb978abc9a
https://github.com/scummvm/scummvm/commit/bd216b237c40a0b87fa5954adc1485fb978abc9a
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
DIRECTOR: Fix previous rendering typos
Changed paths:
engines/director/ink.cpp
engines/director/score.cpp
diff --git a/engines/director/ink.cpp b/engines/director/ink.cpp
index 1b7fb2bd00..f12310af5b 100644
--- a/engines/director/ink.cpp
+++ b/engines/director/ink.cpp
@@ -55,10 +55,7 @@ void Score::inkBasedBlit(Graphics::ManagedSurface *maskSurface, const Graphics::
switch (ink) {
case kInkTypeCopy:
- if (maskSurface)
_surface->transBlitFrom(spriteSurface, Common::Point(drawRect.left, drawRect.top), *maskSurface);
- else
- _surface->blitFrom(spriteSurface, Common::Point(drawRect.left, drawRect.top));
break;
case kInkTypeTransparent:
// FIXME: is it always white (last entry in pallette)?
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 721bf5e105..1cc5437da3 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -304,8 +304,6 @@ void Score::startLoop() {
_backSurface->create(_movieRect.width(), _movieRect.height());
_backSurface2->create(_movieRect.width(), _movieRect.height());
- _sprites.resize(_frames[0]->_sprites.size());
-
if (_vm->_backSurface.w > 0) {
// Persist screen between the movies
// TODO: this is a workaround until the rendering pipeline is reworked
@@ -330,7 +328,6 @@ void Score::startLoop() {
_sprites = _frames[_currentFrame]->_sprites;
_lingo->processEvent(kEventStartMovie);
- _sprites = _frames[_currentFrame]->_sprites;
renderFrame(_currentFrame, true);
if (_frames.size() <= 1) { // We added one empty sprite
@@ -507,6 +504,7 @@ void Score::renderFrame(uint16 frameId, bool forceUpdate, bool updateStageOnly)
if (needsUpdate || forceUpdate)
unrenderSprite(i);
+ _maskSurface->fillRect(nextSprite->_currentBbox, 1);
_sprites[i] = nextSprite;
}
@@ -558,8 +556,6 @@ void Score::renderSprite(uint16 id) {
CastType castType = sprite->_castType;
- _maskSurface->fillRect(sprite->_currentBbox, 1);
-
if (castType == kCastTypeNull)
return;
Commit: f112b2b564fe3a09f34aa34a234eca9638f44fd3
https://github.com/scummvm/scummvm/commit/f112b2b564fe3a09f34aa34a234eca9638f44fd3
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
DIRECTOR: Implement kTheHilite
Changed paths:
engines/director/cast.cpp
engines/director/cast.h
engines/director/events.cpp
engines/director/lingo/lingo-the.cpp
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index fa557f70d6..9c17dd244f 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -39,6 +39,7 @@ Cast::Cast() {
_type = kCastTypeNull;
_surface = nullptr;
_widget = nullptr;
+ _hilite = false;
_img = nullptr;
diff --git a/engines/director/cast.h b/engines/director/cast.h
index 2c8c94823a..9a0ff5fc42 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -67,6 +67,7 @@ public:
Image::ImageDecoder *_img;
bool _modified;
+ bool _hilite;
Graphics::MacWidget *_widget;
};
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index e37522ab28..36220d1ba4 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -28,6 +28,7 @@
#include "director/frame.h"
#include "director/score.h"
#include "director/sprite.h"
+#include "director/cast.h"
#include "director/lingo/lingo.h"
namespace Director {
@@ -125,6 +126,12 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
sc->_mouseIsDown = false;
releaseDraggedSprite();
+ {
+ Cast *cast = g_director->getCastMember(sc->_sprites[spriteId]->_castId);
+ if (cast && cast->_type == kCastButton)
+ cast->_hilite = !cast->_hilite;
+ }
+
_lingo->registerEvent(kEventMouseUp);
sc->_currentMouseDownSpriteId = 0;
break;
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 4b7d3576e6..34cc8295ce 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -23,6 +23,9 @@
#include "common/system.h"
#include "common/events.h"
+#include "graphics/macgui/macwindowmanager.h"
+#include "graphics/macgui/macbutton.h"
+
#include "director/director.h"
#include "director/cast.h"
#include "director/frame.h"
@@ -896,6 +899,11 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
return d;
}
+ if (field == kTheHilite) {
+ d.u.i = member->_hilite;
+ return d;
+ }
+
CastType castType = member->_type;
CastInfo *castInfo = nullptr;
if (score->_castsInfo.contains(id)) {
@@ -1047,6 +1055,18 @@ void Lingo::setTheCast(Datum &id1, int field, Datum &d) {
score->getCastMemberInitialRect(id).setHeight(d.asInt());
score->setCastMemberModified(id);
break;
+ case kTheHilite:
+ // TODO: Understand how texts can be selected programmatically as well.
+ if (member->_type == kCastButton) {
+ TextCast *button = (TextCast *)member;
+ if ((bool)d.asInt() != member->_hilite) {
+ ((Graphics::MacButton *) button->_widget)->invertInner();
+ button->_hilite = !!d.asInt();
+ }
+ } else {
+ warning("Lingo::setTheCast: Attempted to set hilite of unsupported cast type");
+ }
+ break;
case kTheName:
if (!castInfo) {
warning("Lingo::setTheCast(): The cast %d not found. type: %d", id, castType);
Commit: d6176f8ed156321e179ca8c55a9510e563cd876f
https://github.com/scummvm/scummvm/commit/d6176f8ed156321e179ca8c55a9510e563cd876f
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
DIRECTOR: Implement kTheStageColor
Changed paths:
engines/director/ink.cpp
engines/director/lingo/lingo-the.cpp
engines/director/score.cpp
engines/director/score.h
diff --git a/engines/director/ink.cpp b/engines/director/ink.cpp
index f12310af5b..9d228de5d3 100644
--- a/engines/director/ink.cpp
+++ b/engines/director/ink.cpp
@@ -85,6 +85,10 @@ void Score::inkBasedBlit(Graphics::ManagedSurface *maskSurface, const Graphics::
void Score::drawBackgndTransSprite(const Graphics::Surface &sprite, Common::Rect &drawRect, int spriteId) {
byte skipColor = _sprites[spriteId]->_backColor;
+ if (_sprites[spriteId]->_castType == kCastText && _sprites[spriteId]->_cast) {
+ skipColor = ((TextCast *)_sprites[spriteId]->_cast)->_bgcolor;
+ }
+
Common::Rect srcRect(sprite.w, sprite.h);
if (!_surface->clip(srcRect, drawRect))
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 34cc8295ce..9eb0ee52f6 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -622,6 +622,13 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
}
}
break;
+ case kTheStageColor: {
+ Score *score = _vm->getCurrentScore();
+ score->_stageColor = d.asInt();
+ score->_surface->clear(score->_stageColor);
+ score->renderFrame(score->getCurrentFrame(), true);
+ }
+ break;
case kTheSprite:
setTheSprite(id, field, d);
break;
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 1cc5437da3..dfa301c073 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -72,7 +72,6 @@ Score::Score(DirectorEngine *vm) {
_nextFrameTime = 0;
_flags = 0;
_stopPlay = false;
- _stageColor = 0;
_castIDoffset = 0;
diff --git a/engines/director/score.h b/engines/director/score.h
index 48dc4d2119..97a20850ef 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -140,8 +140,6 @@ public:
void renderZoomBox(bool redraw = false);
bool haveZoomBox() { return !_zoomBoxes.empty(); }
- int32 getStageColor() { return _stageColor; }
-
Cast *getCastMember(int castId);
void renderFrame(uint16 frameId, bool forceUpdate = false, bool updateStageOnly = false);
void renderSprite(uint16 id);
@@ -211,6 +209,7 @@ public:
uint32 _lastClickTime;
uint32 _lastKeyTime;
uint32 _lastTimerReset;
+ uint16 _stageColor;
bool _stopPlay;
uint32 _nextFrameTime;
@@ -243,7 +242,6 @@ private:
uint32 _flags;
uint16 _castArrayEnd;
uint16 _movieScriptCount;
- uint16 _stageColor;
Lingo *_lingo;
DirectorSound *_soundManager;
DirectorEngine *_vm;
Commit: 5711e4399aed80f82772e8f3cf6e425cc7a96743
https://github.com/scummvm/scummvm/commit/5711e4399aed80f82772e8f3cf6e425cc7a96743
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
DIRECTOR: Use WM button activation styles
Changed paths:
engines/director/director.cpp
engines/director/director.h
engines/director/events.cpp
engines/director/lingo/lingo-the.cpp
engines/director/score.cpp
engines/director/score.h
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index 0ef6a2867d..a47bde07f1 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -40,6 +40,9 @@
namespace Director {
+const uint32 wmMode = Graphics::kWMModalMenuMode | Graphics::kWMModeNoDesktop
+ | Graphics::kWMModeManualDrawWidgets | Graphics::kWMModeFullscreen;
+
DirectorEngine *g_director;
DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc),
@@ -135,8 +138,7 @@ Common::Error DirectorEngine::run() {
_macBinary = nullptr;
_soundManager = nullptr;
- _wm = new Graphics::MacWindowManager(Graphics::kWMModalMenuMode | Graphics::kWMModeNoDesktop
- | Graphics::kWMModeManualDrawWidgets | Graphics::kWMModeFullscreen);
+ _wm = new Graphics::MacWindowManager(wmMode);
_wm->setEngine(this);
_lingo = new Lingo(this);
diff --git a/engines/director/director.h b/engines/director/director.h
index af98ebbd66..2cb867a5a6 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -208,6 +208,7 @@ private:
};
extern DirectorEngine *g_director;
+extern const uint32 wmMode;
} // End of namespace Director
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index 36220d1ba4..4222ab2a5a 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -104,7 +104,6 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
if (sc->_sprites[spriteId]->_scriptId)
sc->_currentClickOnSpriteId = spriteId;
- sc->_mouseIsDown = true;
sc->_lastEventTime = g_director->getMacTicks();
sc->_lastClickTime = sc->_lastEventTime;
@@ -121,9 +120,14 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
spriteId = sc->getSpriteIDFromPos(pos);
+ if (!sc->_sprites[sc->_currentMouseDownSpriteId]->_currentBbox.contains(pos))
+ sc->_currentMouseDownSpriteId = 0;
+
+ if (!(g_director->_wm->_mode & Graphics::kWMModeButtonDialogStyle))
+ sc->_currentMouseDownSpriteId = spriteId;
+
debugC(3, kDebugEvents, "event: Button Up @(%d, %d), sprite id: %d", pos.x, pos.y, spriteId);
- sc->_mouseIsDown = false;
releaseDraggedSprite();
{
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 9eb0ee52f6..1984aeca9a 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -549,7 +549,7 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
break;
case kTheStillDown:
d.type = INT;
- d.u.i = _vm->getCurrentScore()->_mouseIsDown;
+ d.u.i = _vm->_wm->_mouseDown;
break;
case kTheTimer:
d.type = INT;
@@ -576,6 +576,12 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
}
switch (entity) {
+ case kTheButtonStyle:
+ if (d.asInt())
+ g_director->_wm->_mode = Director::wmMode | Graphics::kWMModeButtonDialogStyle;
+ else
+ g_director->_wm->_mode = Director::wmMode;
+ break;
case kTheCast:
setTheCast(id, field, d);
break;
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index dfa301c073..1d326be718 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -48,7 +48,6 @@ Score::Score(DirectorEngine *vm) {
_soundManager = _vm->getSoundManager();
_currentMouseDownSpriteId = 0;
_currentClickOnSpriteId = 0;
- _mouseIsDown = false;
_lastEventTime = _vm->getMacTicks();
_lastKeyTime = _lastEventTime;
_lastClickTime = _lastEventTime;
diff --git a/engines/director/score.h b/engines/director/score.h
index 97a20850ef..a95a0fc763 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -203,7 +203,6 @@ public:
Common::Rect _movieRect;
uint16 _currentMouseDownSpriteId;
uint16 _currentClickOnSpriteId;
- bool _mouseIsDown;
uint32 _lastEventTime;
uint32 _lastRollTime;
uint32 _lastClickTime;
Commit: d6f87f22dfa369dfc8a29dd50ca3658120788d2a
https://github.com/scummvm/scummvm/commit/d6f87f22dfa369dfc8a29dd50ca3658120788d2a
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
DIRECTOR: Make puppetSprite version-sensitive
Changed paths:
engines/director/lingo/lingo-builtins.cpp
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index b1f0fbd626..4f098e4fda 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1682,19 +1682,33 @@ void LB::b_puppetSound(int nargs) {
}
void LB::b_puppetSprite(int nargs) {
- if (!g_director->getCurrentScore()) {
+ Score *sc = g_director->getCurrentScore();
+ if (!sc) {
warning("b_puppetSprite: no score");
-
+ g_lingo->dropStack(nargs);
return;
}
- Frame *frame = g_director->getCurrentScore()->_frames[g_director->getCurrentScore()->getCurrentFrame()];
+ if (nargs == 2 && g_director->getVersion() >= 4) {
+ Datum state = g_lingo->pop();
+ Datum sprite = g_lingo->pop();
+ if ((uint)sprite.asInt() < sc->_sprites.size()) {
+ sc->_sprites[sprite.asInt()]->_puppet = state.asInt();
+ } else {
+ warning("b_puppetSprite: sprite index out of bounds");
+ }
+ } else if (nargs == 0 && g_director->getVersion() < 4) {
+ g_lingo->dropStack(nargs);
- if (g_lingo->_currentChannelId == -1) {
- warning("b_puppetSprite: channel Id is missing");
- return;
+ if (g_lingo->_currentChannelId == -1) {
+ warning("b_puppetSprite: channel Id is missing");
+ return;
+ }
+ sc->_sprites[g_lingo->_currentChannelId]->_puppet = true;
+ } else {
+ warning("b_puppetSprite: unexpectedly received %d arguments", nargs);
+ g_lingo->dropStack(nargs);
}
- frame->_sprites[g_lingo->_currentChannelId]->_puppet = true;
}
void LB::b_puppetTempo(int nargs) {
Commit: 3095637e601ae7bb7f7c8aaf0280eb6e68ceacd7
https://github.com/scummvm/scummvm/commit/3095637e601ae7bb7f7c8aaf0280eb6e68ceacd7
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
DIRECTOR: Convert texts to buttons if necessary
Changed paths:
engines/director/cast.cpp
engines/director/cast.h
engines/director/score-loading.cpp
engines/director/score.cpp
engines/director/score.h
engines/director/sprite.cpp
engines/director/sprite.h
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 9c17dd244f..24cff1b433 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -155,13 +155,14 @@ SoundCast::SoundCast(Common::ReadStreamEndian &stream, uint16 version) {
}
}
-TextCast::TextCast(Common::ReadStreamEndian &stream, uint16 version, int32 bgcolor) {
+TextCast::TextCast(Common::ReadStreamEndian &stream, uint16 version, int32 bgcolor, bool asButton) {
_type = kCastText;
_bgcolor = bgcolor;
_borderSize = kSizeNone;
_gutterSize = kSizeNone;
_boxShadow = kSizeNone;
+ _buttonType = kTypeButton;
_flags = 0;
_textFlags = 0;
@@ -269,7 +270,24 @@ TextCast::TextCast(Common::ReadStreamEndian &stream, uint16 version, int32 bgcol
stream.readUint16();
}
- _modified = false;
+ if (asButton) {
+ _type = kCastButton;
+
+ if (version < 4) {
+ _buttonType = static_cast<ButtonType>(stream.readUint16BE() - 1);
+ } else {
+ stream.readByte();
+ stream.readByte();
+
+ // This has already been populated in the super TextCast constructor
+ //initialRect = Score::readRect(stream);
+ //boundingRect = Score::readRect(stream);
+
+ _buttonType = static_cast<ButtonType>(stream.readUint16BE());
+ }
+ }
+
+ _modified = true;
}
Graphics::TextAlign TextCast::getAlignment() {
@@ -299,14 +317,34 @@ void TextCast::importStxt(const Stxt *stxt) {
}
void TextCast::createWidget() {
+ if (g_director->getCurrentScore()->_window)
+ g_director->getCurrentScore()->_window->removeWidget(_widget);
+ else if (_widget)
+ delete _widget;
+
uint fgcolor = g_director->_wm->findBestColor(_palinfo1 & 0xff, _palinfo2 & 0xff, _palinfo3 & 0xff);
- warning("TextCast::createWidget: bgcolor: %d, fgcolor: %d", _bgcolor, fgcolor);
Graphics::MacFont *macFont = new Graphics::MacFont(_fontId, _fontSize, _textSlant);
- _widget = new Graphics::MacEditableText(g_director->getCurrentScore()->_window, 0, 0, _initialRect.width(), _initialRect.height(), g_director->_wm, _ftext, macFont, fgcolor, _bgcolor, _initialRect.width(), getAlignment(), 1, _borderSize, _gutterSize, _boxShadow, _textShadow);
+ switch (_type) {
+ case kCastText:
+ _widget = new Graphics::MacEditableText(g_director->getCurrentScore()->_window, 0, 0, _initialRect.width(), _initialRect.height(), g_director->_wm, _ftext, macFont, fgcolor, _bgcolor, _initialRect.width(), getAlignment(), 1, _borderSize, _gutterSize, _boxShadow, _textShadow);
+
+ ((Graphics::MacEditableText *)_widget)->draw();
+ break;
+
+ case kCastButton:
+ _widget = new Graphics::MacButton(Graphics::MacButtonType(_buttonType), getAlignment(), g_director->getCurrentScore()->_window, 0, 0, _initialRect.width(), _initialRect.height(), g_director->_wm, _ftext, macFont, fgcolor, _bgcolor);
+ ((Graphics::MacButton *)_widget)->draw();
+ _widget->_focusable = true;
+
+ ((Graphics::MacButton *)(_widget))->draw();
+ break;
+
+ default:
+ break;
+ }
- ((Graphics::MacEditableText *)_widget)->draw();
delete macFont;
}
@@ -425,36 +463,6 @@ ShapeCast::ShapeCast(Common::ReadStreamEndian &stream, uint16 version) {
_initialRect.debugPrint(0, "ShapeCast: rect:");
}
-ButtonCast::ButtonCast(Common::ReadStreamEndian &stream, uint16 version) : TextCast(stream, version, 0xff) {
- _type = kCastButton;
-
- if (version < 4) {
- _buttonType = static_cast<ButtonType>(stream.readUint16BE() - 1);
- } else {
- stream.readByte();
- stream.readByte();
-
- // This has already been populated in the super TextCast constructor
- //initialRect = Score::readRect(stream);
- //boundingRect = Score::readRect(stream);
-
- _buttonType = static_cast<ButtonType>(stream.readUint16BE());
- }
-}
-
-void ButtonCast::createWidget() {
- uint fgcolor = g_director->_wm->findBestColor(_palinfo1 & 0xff, _palinfo2 & 0xff, _palinfo3 & 0xff);
-
- Graphics::MacFont *macFont = new Graphics::MacFont(_fontId, _fontSize, _textSlant);
-
- _widget = new Graphics::MacButton(Graphics::MacButtonType(_buttonType), getAlignment(), g_director->getCurrentScore()->_window, 0, 0, _initialRect.width(), _initialRect.height(), g_director->_wm, _ftext, macFont, fgcolor, _bgcolor);
-
- _widget->_focusable = true;
-
- ((Graphics::MacButton *)(_widget))->draw();
- delete macFont;
-}
-
ScriptCast::ScriptCast(Common::ReadStreamEndian &stream, uint16 version) {
_type = kCastLingoScript;
_scriptType = kNoneScript;
diff --git a/engines/director/cast.h b/engines/director/cast.h
index 9a0ff5fc42..4f19364671 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -112,7 +112,7 @@ public:
class TextCast : public Cast {
public:
- TextCast(Common::ReadStreamEndian &stream, uint16 version, int32 bgcolor);
+ TextCast(Common::ReadStreamEndian &stream, uint16 version, int32 bgcolor, bool asButton = false);
void setText(const char *text);
virtual void createWidget();
@@ -136,6 +136,7 @@ public:
byte _textFlags;
uint16 _palinfo1, _palinfo2, _palinfo3;
int32 _bgcolor;
+ ButtonType _buttonType;
Common::String _ftext;
Common::String _ptext;
@@ -145,14 +146,6 @@ public:
Common::String getText();
};
-class ButtonCast : public TextCast {
-public:
- ButtonCast(Common::ReadStreamEndian &stream, uint16 version);
- virtual void createWidget() override;
-
- ButtonType _buttonType;
-};
-
class ScriptCast : public Cast {
public:
ScriptCast(Common::ReadStreamEndian &stream, uint16 version);
diff --git a/engines/director/score-loading.cpp b/engines/director/score-loading.cpp
index 840affb61a..bbfd8d4850 100644
--- a/engines/director/score-loading.cpp
+++ b/engines/director/score-loading.cpp
@@ -273,7 +273,6 @@ void Score::copyCastStxts() {
TextCast *tc = (TextCast *)c->_value;
tc->importStxt(stxt);
- tc->createWidget();
}
}
}
@@ -654,7 +653,7 @@ void Score::loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream) {
break;
case kCastButton:
debugC(3, kDebugLoading, "Score::loadCastDataVWCR(): CastTypes id: %d(%s) ButtonCast", id, numToCastNum(id));
- _loadedCast->setVal(id, new ButtonCast(stream, _vm->getVersion()));
+ _loadedCast->setVal(id, new TextCast(stream, _vm->getVersion(), 0xff, true));
break;
default:
warning("Score::loadCastDataVWCR(): Unhandled cast id: %d(%s), type: %d, %d bytes", id, numToCastNum(id), castType, size);
@@ -679,7 +678,6 @@ void Score::setSpriteBboxes() {
for (uint16 i = 0; i < _frames.size(); i++) {
for (uint16 j = 0; j < _frames[i]->_sprites.size(); j++) {
Sprite *sp = _frames[i]->_sprites[j];
- if (i == 1)
// Only call updateCast on the first frame sprites, because renderSprite
// calls updateCast for us after that. We need to get widget bounding info here.
// if (i == 1)
@@ -774,7 +772,7 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
break;
case kCastButton:
debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastButton (%d children)", res->children.size());
- _loadedCast->setVal(id, new ButtonCast(castStream, _vm->getVersion()));
+ _loadedCast->setVal(id, new TextCast(castStream, _vm->getVersion(), 0xff, true));
break;
case kCastLingoScript:
debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastLingoScript");
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 1d326be718..ef8e9a5cbd 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -713,7 +713,7 @@ void Score::renderButton(uint16 spriteId) {
warning("renderButton: cast id %d not of type kCastButton", castId);
return;
}
- ButtonCast *button = (ButtonCast *)member;
+ TextCast *button = (TextCast *)member;
// TODO: review all cases to confirm if we should use text height.
// height = textRect.height();
diff --git a/engines/director/score.h b/engines/director/score.h
index a95a0fc763..f31c38191a 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -49,7 +49,6 @@ struct Resource;
class Sprite;
class Stxt;
class BitmapCast;
-class ButtonCast;
class ScriptCast;
class ShapeCast;
class TextCast;
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index d99eaef0b7..3a761132c1 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -72,11 +72,23 @@ Sprite::~Sprite() {
}
void Sprite::updateCast() {
- if (_cast && _cast->_widget) {
- if (_cast->isEditable() != _editable && !_puppet)
- _cast->setEditable(_editable);
- _cast->_widget->_dims.moveTo(_currentPoint.x, _currentPoint.y);
+ if (!_cast)
+ return;
+
+ if (!_cast->_widget) {
+ if (_cast->_type == kCastText && _spriteType != kTextSprite) {
+ _cast->_type = kCastButton;
+ ((TextCast *)_cast)->_buttonType = (ButtonType)(_spriteType - 8);
+ }
+
+ if (_cast->_type == kCastText || _cast->_type == kCastButton) {
+ ((TextCast *)_cast)->createWidget();
+ _cast->_widget->_dims.moveTo(_currentPoint.x, _currentPoint.y);
+ }
}
+
+ if (_cast->isEditable() != _editable && !_puppet)
+ _cast->setEditable(_editable);
}
void Sprite::translate(Common::Point delta, bool moveTo) {
@@ -199,6 +211,7 @@ void Sprite::setCast(uint16 castId) {
case kCheckboxSprite:
case kRadioButtonSprite:
_castType = kCastButton;
+
break;
default:
warning("Sprite::setCast(): Unhandled sprite type %d", _spriteType);
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index 58e28a900b..d966740e8e 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -26,7 +26,6 @@
namespace Director {
class BitmapCast;
-class ButtonCast;
class ShapeCast;
class TextCast;
Commit: c3bfd99d509316c87980ddaabc35b2c54670accb
https://github.com/scummvm/scummvm/commit/c3bfd99d509316c87980ddaabc35b2c54670accb
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
DIRECTOR: Render bitmaps with widgets
Changed paths:
engines/director/cast.cpp
engines/director/cast.h
engines/director/ink.cpp
engines/director/lingo/lingo-funcs.cpp
engines/director/score-loading.cpp
engines/director/score.cpp
engines/director/score.h
engines/director/sprite.cpp
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 24cff1b433..be44a9d725 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -37,34 +37,25 @@ namespace Director {
Cast::Cast() {
_type = kCastTypeNull;
- _surface = nullptr;
_widget = nullptr;
_hilite = false;
- _img = nullptr;
-
_modified = true;
}
Cast::~Cast() {
- if (_img)
- delete _img;
-
if (_widget)
delete _widget;
}
-bool Cast::isEditable() {
- return false;
-}
-
-bool Cast::setEditable(bool editable) {
- warning("Cast::setEditable: Attempted to set editable of non-editable cast");
- return false;
+void Cast::createWidget() {
+ if (_widget)
+ error("TextCast::createWidget: Attempted to create widget twice");
}
BitmapCast::BitmapCast(Common::ReadStreamEndian &stream, uint32 castTag, uint16 version) {
_type = kCastBitmap;
+ _img = nullptr;
if (version < 4) {
_pitch = 0;
@@ -142,6 +133,23 @@ BitmapCast::BitmapCast(Common::ReadStreamEndian &stream, uint32 castTag, uint16
_tag = castTag;
}
+BitmapCast::~BitmapCast() {
+ if (_img)
+ delete _img;
+}
+
+void BitmapCast::createWidget() {
+ Cast::createWidget();
+
+ if (!_img) {
+ warning("BitmapCast::createWidget: No image decoder");
+ return;
+ }
+
+ _widget = new Graphics::MacWidget(g_director->getCurrentScore()->_window, 0, 0, _initialRect.width() - 1, _initialRect.height() - 1, false);
+ _widget->getSurface()->blitFrom(*_img->getSurface());
+}
+
SoundCast::SoundCast(Common::ReadStreamEndian &stream, uint16 version) {
_type = kCastSound;
_audio = nullptr;
@@ -294,14 +302,11 @@ Graphics::TextAlign TextCast::getAlignment() {
switch (_textAlign) {
case kTextAlignRight:
return Graphics::kTextAlignRight;
- break;
case kTextAlignCenter:
return Graphics::kTextAlignCenter;
- break;
case kTextAlignLeft:
default:
return Graphics::kTextAlignLeft;
- break;
}
}
@@ -317,10 +322,7 @@ void TextCast::importStxt(const Stxt *stxt) {
}
void TextCast::createWidget() {
- if (g_director->getCurrentScore()->_window)
- g_director->getCurrentScore()->_window->removeWidget(_widget);
- else if (_widget)
- delete _widget;
+ Cast::createWidget();
uint fgcolor = g_director->_wm->findBestColor(_palinfo1 & 0xff, _palinfo2 & 0xff, _palinfo3 & 0xff);
@@ -463,6 +465,17 @@ ShapeCast::ShapeCast(Common::ReadStreamEndian &stream, uint16 version) {
_initialRect.debugPrint(0, "ShapeCast: rect:");
}
+ShapeCast::ShapeCast() {
+ _shapeType = kShapeRectangle;
+ _pattern = 0;
+ _fgCol = 0;
+ _bgCol = 0;
+ _fillType = 0;
+ _lineThickness = 0;
+ _lineDirection = 0;
+ _ink = kInkTypeCopy;
+}
+
ScriptCast::ScriptCast(Common::ReadStreamEndian &stream, uint16 version) {
_type = kCastLingoScript;
_scriptType = kNoneScript;
diff --git a/engines/director/cast.h b/engines/director/cast.h
index 4f19364671..bbc2e576cd 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -54,18 +54,16 @@ class Cast {
public:
Cast();
virtual ~Cast();
- virtual bool isEditable();
- virtual bool setEditable(bool editable);
+ virtual bool isEditable() { return false; }
+ virtual bool setEditable(bool editable) { return false; }
virtual bool isModified() { return _modified; }
+ virtual void createWidget();
CastType _type;
Common::Rect _initialRect;
Common::Rect _boundingRect;
Common::Array<Resource> _children;
- const Graphics::Surface *_surface;
- Image::ImageDecoder *_img;
-
bool _modified;
bool _hilite;
@@ -75,6 +73,10 @@ public:
class BitmapCast : public Cast {
public:
BitmapCast(Common::ReadStreamEndian &stream, uint32 castTag, uint16 version);
+ ~BitmapCast();
+ virtual void createWidget() override;
+
+ Image::ImageDecoder *_img;
uint16 _pitch;
uint16 _regX;
@@ -99,6 +101,7 @@ public:
class ShapeCast : public Cast {
public:
ShapeCast(Common::ReadStreamEndian &stream, uint16 version);
+ ShapeCast();
ShapeType _shapeType;
uint16 _pattern;
diff --git a/engines/director/ink.cpp b/engines/director/ink.cpp
index 9d228de5d3..a329ff9623 100644
--- a/engines/director/ink.cpp
+++ b/engines/director/ink.cpp
@@ -33,23 +33,12 @@ void Score::inkBasedBlit(Graphics::ManagedSurface *maskSurface, const Graphics::
t.moveTo(drawRect.left, drawRect.top);
bool nullMask = false;
- // combine the given mask with the maskSurface
- if (!maskSurface) {
- nullMask = true;
- maskSurface = new Graphics::ManagedSurface;
- maskSurface->create(spriteSurface.w, spriteSurface.h, Graphics::PixelFormat::createFormatCLUT8());
- maskSurface->clear(0);
- }
-
drawRect.clip(Common::Rect(_maskSurface->w, _maskSurface->h));
-
-
- if (drawRect.isEmpty()) {
- warning("Score::inkBasedBlit(): empty drawRect");
- return;
+ if (maskSurface->w != drawRect.width() || maskSurface->h != drawRect.height()) {
+ warning("Score::inkBasedBlit: Mismatched dimensions of mask surface and drawRect: %d", spriteId);
}
- maskSurface->blitFrom(*_maskSurface, drawRect, Common::Point(0, 0));
+ maskSurface->transBlitFrom(*_maskSurface, drawRect, Common::Point(0, 0), _stageColor);
drawRect.clip(t);
diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp
index 63f6d9e975..9d4702e48c 100644
--- a/engines/director/lingo/lingo-funcs.cpp
+++ b/engines/director/lingo/lingo-funcs.cpp
@@ -346,30 +346,21 @@ void Lingo::func_cursor(int cursorId, int maskId) {
return;
}
- if (cursorCast->_surface == nullptr) {
- warning("func_cursor(): empty surface for bitmap cast %d", cursorId);
- return;
- }
- if (maskCast->_surface == nullptr) {
- warning("func_cursor(): empty surface for bitmap cast %d", maskId);
- return;
- }
-
byte *assembly = (byte *)malloc(16 * 16);
byte *dst = assembly;
for (int y = 0; y < 16; y++) {
const byte *cursor = nullptr, *mask = nullptr;
- if (y < cursorCast->_surface->h &&
- y < maskCast->_surface->h) {
- cursor = (const byte *)cursorCast->_surface->getBasePtr(0, y);
- mask = (const byte *)maskCast->_surface->getBasePtr(0, y);
+ if (y < cursorCast->_widget->getSurface()->h &&
+ y < maskCast->_widget->getSurface()->h) {
+ cursor = (const byte *)cursorCast->_widget->getSurface()->getBasePtr(0, y);
+ mask = (const byte *)maskCast->_widget->getSurface()->getBasePtr(0, y);
}
for (int x = 0; x < 16; x++) {
- if (x >= cursorCast->_surface->w ||
- x >= maskCast->_surface->w) {
+ if (x >= cursorCast->_widget->getSurface()->w ||
+ x >= maskCast->_widget->getSurface()->w) {
cursor = mask = nullptr;
}
diff --git a/engines/director/score-loading.cpp b/engines/director/score-loading.cpp
index bbfd8d4850..2ceb96735a 100644
--- a/engines/director/score-loading.cpp
+++ b/engines/director/score-loading.cpp
@@ -250,9 +250,9 @@ bool Score::loadArchive() {
copyCastStxts();
setSpriteCasts();
- setSpriteBboxes();
loadSpriteImages(false);
loadSpriteSounds(false);
+ setSpriteBboxes();
return true;
}
@@ -358,8 +358,8 @@ void Score::loadSpriteImages(bool isSharedCast) {
delete pic;
- bitmapCast->_surface = img->getSurface();
bitmapCast->_img = img;
+ bitmapCast->createWidget();
debugC(4, kDebugImages, "Score::loadSpriteImages(): id: %d, w: %d, h: %d, flags: %x, bytes: %x, bpp: %d clut: %x",
imgId, w, h, bitmapCast->_flags, bitmapCast->_bytes, bitmapCast->_bitsPerPixel, bitmapCast->_clut);
@@ -678,10 +678,7 @@ void Score::setSpriteBboxes() {
for (uint16 i = 0; i < _frames.size(); i++) {
for (uint16 j = 0; j < _frames[i]->_sprites.size(); j++) {
Sprite *sp = _frames[i]->_sprites[j];
- // Only call updateCast on the first frame sprites, because renderSprite
- // calls updateCast for us after that. We need to get widget bounding info here.
- // if (i == 1)
- sp->updateCast();
+ sp->updateCast();
sp->_startBbox = sp->getBbox();
sp->_currentBbox = sp->_startBbox;
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index ef8e9a5cbd..38c5b5e0aa 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -315,7 +315,6 @@ void Score::startLoop() {
_vm->_backSurface.create(_movieRect.width(), _movieRect.height());
_vm->_wm->setScreen(_surface);
- _vm->_wm->_lastWidget = nullptr;
_surface->clear(_stageColor);
@@ -539,45 +538,27 @@ void Score::unrenderSprite(uint16 spriteId) {
}
currentSprite->_currentBbox = currentSprite->getBbox();
- currentSprite->_dirty = false;
-
- if (currentSprite->_cast)
- currentSprite->_cast->_modified = false;
}
void Score::renderSprite(uint16 id) {
Sprite *sprite = _sprites[id];
- sprite->updateCast();
- if (!sprite || !sprite->_enabled)
+ if (!sprite || !sprite->_enabled || !sprite->_castType)
return;
- CastType castType = sprite->_castType;
-
- if (castType == kCastTypeNull)
- return;
+ sprite->updateCast();
- debugC(1, kDebugImages, "Score::renderFrame(): channel: %d, castType: %d", id, castType);
- // this needs precedence to be hit first... D3 does something really tricky
- // with cast IDs for shapes. I don't like this implementation 100% as the
- // 'cast' above might not actually hit a member and be null?
- if (castType == kCastShape) {
+ debugC(1, kDebugImages, "Score::renderFrame(): channel: %d, castType: %d", id, sprite->_castType);
+ if (sprite->_castType == kCastShape) {
renderShape(id);
- } else if (castType == kCastText || castType == kCastRTE) {
- renderText(id);
- } else if (castType == kCastButton) {
- renderButton(id);
} else {
- if (!sprite->_cast || sprite->_cast->_type != kCastBitmap) {
- warning("Score::renderFrame(): No cast ID for sprite %d", id);
- return;
- }
- if (sprite->_cast->_surface == nullptr) {
- warning("Score::renderFrame(): No cast surface for sprite %d", id);
- return;
+ Cast *cast = _sprites[id]->_cast;
+ if (cast && cast->_widget) {
+ cast->_widget->draw();
+ inkBasedBlit(cast->_widget->getMask(), cast->_widget->getSurface()->rawSurface(), _sprites[id]->_ink, _sprites[id]->_currentBbox, id);
+ } else {
+ warning("Score::renderSprite: No widget for channel ID %d", id);
}
-
- renderBitmap(id);
}
sprite->setClean();
@@ -701,62 +682,6 @@ void Score::renderShape(uint16 spriteId) {
inkBasedBlit(&maskSurface, tmpSurface, ink, shapeRect, spriteId);
}
-void Score::renderButton(uint16 spriteId) {
- uint16 castId = _sprites[spriteId]->_castId;
-
- // This may not be a button cast. It could be a textcast with the channel forcing it
- // to be a checkbox or radio button!
- Cast *member = _vm->getCastMember(castId);
- if (!member) {
- warning("renderButton: unknown cast id %d", castId);
- } else if (member->_type != kCastButton) {
- warning("renderButton: cast id %d not of type kCastButton", castId);
- return;
- }
- TextCast *button = (TextCast *)member;
-
- // TODO: review all cases to confirm if we should use text height.
- // height = textRect.height();
-
- Common::Rect bbox = _sprites[spriteId]->_currentBbox;
-
- inkBasedBlit(nullptr, button->_widget->getSurface()->rawSurface(), _sprites[spriteId]->_ink, bbox, spriteId);
-}
-
-void Score::renderText(uint16 spriteId) {
- TextCast *text = (TextCast*)_sprites[spriteId]->_cast;
- if (text == nullptr) {
- warning("Score::renderText(): TextCast #%d is a nullptr", spriteId);
- return;
- }
-
- Common::Rect bbox = _sprites[spriteId]->_currentBbox;
- text->_widget->draw();
-
- if (_fontMap.contains(text->_fontId)) {
- // We need to make sure that the Shared Cast fonts have been loaded in?
- // might need a mapping table here of our own.
- // textCast->fontId = _vm->_wm->_fontMan->getFontIdByName(_vm->getCurrentScore()->_fontMap[textCast->fontId]);
- }
-
- inkBasedBlit(nullptr, text->_widget->getSurface()->rawSurface(), _sprites[spriteId]->_ink, bbox, spriteId);
-}
-
-void Score::renderBitmap(uint16 spriteId) {
- InkType ink;
- Sprite *sprite = _sprites[spriteId];
-
- // if (spriteId == _vm->getCurrentScore()->_currentMouseDownSpriteId)
- // ink = kInkTypeReverse;
- // else
- ink = sprite->_ink;
-
- BitmapCast *bc = (BitmapCast *)sprite->_cast;
- Common::Rect drawRect = sprite->_currentBbox;
-
- inkBasedBlit(nullptr, *(bc->_surface), ink, drawRect, spriteId);
-}
-
uint16 Score::getSpriteIDFromPos(Common::Point pos) {
for (int i = _sprites.size() - 1; i >= 0; i--)
if (_sprites[i]->_currentBbox.contains(pos))
diff --git a/engines/director/score.h b/engines/director/score.h
index f31c38191a..dea4df24f1 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -146,10 +146,7 @@ public:
private:
void update();
- void renderText(uint16 spriteId);
void renderShape(uint16 spriteId);
- void renderButton(uint16 spriteId);
- void renderBitmap(uint16 spriteId);
// ink.cpp
void inkBasedBlit(Graphics::ManagedSurface *maskSurface, const Graphics::Surface &spriteSurface, InkType ink, Common::Rect drawRect, uint spriteId);
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index 3a761132c1..6ff186520a 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -24,6 +24,8 @@
#include "director/cast.h"
#include "director/sprite.h"
+#include "director/score.h"
+
#include "graphics/macgui/macwidget.h"
namespace Director {
@@ -76,17 +78,27 @@ void Sprite::updateCast() {
return;
if (!_cast->_widget) {
- if (_cast->_type == kCastText && _spriteType != kTextSprite) {
+ if (_cast->_type == kCastText && (_spriteType == kButtonSprite || _spriteType == kCheckboxSprite || _spriteType == kRadioButtonSprite)) {
+ // WORKAROUND: In D2/D3 there can be text casts that have button
+ // information set in the sprite.
+ warning("Sprite::updateCast: Working around D2/3 button glitch");
_cast->_type = kCastButton;
((TextCast *)_cast)->_buttonType = (ButtonType)(_spriteType - 8);
}
- if (_cast->_type == kCastText || _cast->_type == kCastButton) {
- ((TextCast *)_cast)->createWidget();
- _cast->_widget->_dims.moveTo(_currentPoint.x, _currentPoint.y);
- }
+ _cast->createWidget();
+ }
+
+ int offsetx, offsety = 0;
+ if (_cast->_type == kCastBitmap) {
+ BitmapCast *bc = (BitmapCast *)_cast;
+ offsety = bc->_initialRect.top - bc->_regY;
+ offsetx = bc->_initialRect.left - bc->_regX;
}
+ if (_cast && _cast->_widget)
+ _cast->_widget->_dims.moveTo(_currentPoint.x + offsetx, _currentPoint.y + offsety);
+
if (_cast->isEditable() != _editable && !_puppet)
_cast->setEditable(_editable);
}
@@ -174,8 +186,9 @@ void Sprite::setCast(uint16 castId) {
if (member)
_cast = member;
- else
+ else {
warning("Sprite::setCast: Cast id %d has null member", castId);
+ }
if (g_director->getVersion() < 4) {
switch (_spriteType) {
@@ -191,7 +204,7 @@ void Sprite::setCast(uint16 castId) {
case kOutlinedRoundedRectangleSprite:
case kOutlinedOvalSprite:
case kCastMemberSprite:
- if (_cast != nullptr) {
+ if (_cast) {
switch (_cast->_type) {
case kCastButton:
_castType = kCastButton;
@@ -202,6 +215,8 @@ void Sprite::setCast(uint16 castId) {
}
} else {
_castType = kCastShape;
+
+ g_director->getCurrentScore()->_loadedCast->setVal(_castId, new ShapeCast());
}
break;
case kTextSprite:
@@ -225,6 +240,7 @@ void Sprite::setCast(uint16 castId) {
}
}
+
_dirty = true;
}
@@ -234,49 +250,22 @@ Common::Rect Sprite::getBbox() {
return result;
}
- switch (_castType) {
- case kCastShape:
- result = Common::Rect(_currentPoint.x,
- _currentPoint.y,
- _currentPoint.x + _width,
- _currentPoint.y + _height);
- break;
- case kCastRTE:
- case kCastText:
- case kCastButton:
- {
- if (!_cast)
- return result;
-
- result = _cast->_widget->getDimensions();
- break;
- }
- case kCastBitmap: {
- if (!_cast)
- return result;
-
- BitmapCast *bc = (BitmapCast *)_cast;
-
- int32 regX = bc->_regX;
- int32 regY = bc->_regY;
- int32 rectLeft = bc->_initialRect.left;
- int32 rectTop = bc->_initialRect.top;
-
- int x = _currentPoint.x - regX + rectLeft;
- int y = _currentPoint.y - regY + rectTop;
- int height = _height;
- int width = g_director->getVersion() > 4 ? bc->_initialRect.width() : _width;
+ if (_castType == kCastShape) {
+ // WORKAROUND: Shape widgets not fully implemented.
+ result = Common::Rect(_currentPoint.x, _currentPoint.y, _currentPoint.x + _width, _currentPoint.y + _height);
+ } else {
+ result = _cast ? _cast->_widget->getDimensions() : Common::Rect(0, 0, _width, _height);
+ }
- // If one of the dimensions is invalid, invalidate whole thing
- if (width == 0 || height == 0)
- width = height = 0;
+ result.moveTo(_currentPoint.x, _currentPoint.y);
- result = Common::Rect(x, y, x + width, y + height);
- break;
- }
- default:
- warning("Sprite::getBbox(): Unhandled cast type: %d : castId: %d", _castType, _castId);
+ if (_cast && _castType == kCastBitmap) {
+ BitmapCast *bc = (BitmapCast *)_cast;
+ int offsety = bc->_initialRect.top - bc->_regY;
+ int offsetx = bc->_initialRect.left - bc->_regX;
+ result.translate(offsetx, offsety);
}
+
return result;
}
Commit: 0886091f7d23734b779538dc7a2946421f877d4e
https://github.com/scummvm/scummvm/commit/0886091f7d23734b779538dc7a2946421f877d4e
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-06-10T15:42:49+02:00
Commit Message:
DIRECTOR: Fix puppetSprite de-activation
Changed paths:
engines/director/lingo/lingo-the.cpp
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 1984aeca9a..390880c531 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -853,9 +853,13 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
sprite->setPattern(d.asInt());
break;
case kThePuppet:
+ warning("kThePuppet: %d", d.asInt());
sprite->_puppet = d.asInt();
- if (!d.u.i) {
+ if (!d.asInt()) {
sprite->_currentPoint = sprite->_startPoint;
+
+ // TODO: Properly reset sprite properties after puppet disabled.
+ sprite->_moveable = false;
}
break;
case kTheStartTime:
More information about the Scummvm-git-logs
mailing list