mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-04 09:18:38 +00:00
DIRECTOR: Move methods from Window to DirectorPlotData
This commit is contained in:
parent
e4f767c916
commit
8963cf211a
@ -126,6 +126,8 @@ struct MacShape {
|
||||
Graphics::MacPlotData *pd;
|
||||
};
|
||||
|
||||
const int SCALE_THRESHOLD = 0x100;
|
||||
|
||||
// An extension of MacPlotData for interfacing with inks and patterns without
|
||||
// needing extra surfaces.
|
||||
struct DirectorPlotData {
|
||||
@ -148,7 +150,12 @@ struct DirectorPlotData {
|
||||
uint32 foreColor;
|
||||
bool applyColor;
|
||||
|
||||
void setApplyColor(); // graphics.cpp
|
||||
// graphics.cpp
|
||||
void setApplyColor();
|
||||
uint32 preprocessColor(uint32 src);
|
||||
void inkBlitShape(Common::Rect &srcRect);
|
||||
void inkBlitSurface(Common::Rect &srcRect, const Graphics::Surface *mask);
|
||||
void inkBlitStretchSurface(Common::Rect &srcRect, const Graphics::Surface *mask);
|
||||
|
||||
DirectorPlotData(Graphics::MacWindowManager *w, SpriteType s, InkType i, int a, uint32 b, uint32 f) : _wm(w), sprite(s), ink(i), alpha(a), backColor(b), foreColor(f) {
|
||||
srf = nullptr;
|
||||
|
@ -300,4 +300,184 @@ void DirectorPlotData::setApplyColor() {
|
||||
}
|
||||
}
|
||||
|
||||
uint32 DirectorPlotData::preprocessColor(uint32 src) {
|
||||
// HACK: Right now this method is just used for adjusting the colourization on text
|
||||
// sprites, as it would be costly to colourize the chunks on the fly each
|
||||
// time a section needs drawing. It's ugly but mostly works.
|
||||
if (sprite == kTextSprite) {
|
||||
switch(ink) {
|
||||
case kInkTypeMask:
|
||||
src = (src == backColor ? foreColor : 0xff);
|
||||
break;
|
||||
case kInkTypeReverse:
|
||||
src = (src == foreColor ? 0 : colorWhite);
|
||||
break;
|
||||
case kInkTypeNotReverse:
|
||||
src = (src == backColor ? colorWhite : 0);
|
||||
break;
|
||||
// looks like this part is wrong, maybe it's very same as reverse?
|
||||
// check warlock/DATA/WARLOCKSHIP/ENG/ABOUT to see more detail.
|
||||
// case kInkTypeGhost:
|
||||
// src = (src == foreColor ? backColor : colorWhite);
|
||||
// break;
|
||||
case kInkTypeNotGhost:
|
||||
src = (src == backColor ? colorWhite : backColor);
|
||||
break;
|
||||
case kInkTypeNotCopy:
|
||||
src = (src == foreColor ? backColor : foreColor);
|
||||
break;
|
||||
case kInkTypeNotTrans:
|
||||
src = (src == foreColor ? backColor : colorWhite);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
void DirectorPlotData::inkBlitShape(Common::Rect &srcRect) {
|
||||
if (!ms)
|
||||
return;
|
||||
|
||||
// Preprocess shape colours
|
||||
switch (ink) {
|
||||
case kInkTypeNotTrans:
|
||||
case kInkTypeNotReverse:
|
||||
case kInkTypeNotGhost:
|
||||
return;
|
||||
case kInkTypeReverse:
|
||||
ms->foreColor = 0;
|
||||
ms->backColor = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Common::Rect fillAreaRect((int)srcRect.width(), (int)srcRect.height());
|
||||
fillAreaRect.moveTo(srcRect.left, srcRect.top);
|
||||
Graphics::MacPlotData plotFill(dst, nullptr, &g_director->getPatterns(), ms->pattern, srcRect.left, srcRect.top, 1, ms->backColor);
|
||||
|
||||
Common::Rect strokeRect(MAX((int)srcRect.width() - ms->lineSize, 0), MAX((int)srcRect.height() - ms->lineSize, 0));
|
||||
strokeRect.moveTo(srcRect.left, srcRect.top);
|
||||
Graphics::MacPlotData plotStroke(dst, nullptr, &g_director->getPatterns(), 1, strokeRect.left, strokeRect.top, ms->lineSize, ms->backColor);
|
||||
|
||||
switch (ms->spriteType) {
|
||||
case kRectangleSprite:
|
||||
ms->pd = &plotFill;
|
||||
Graphics::drawFilledRect(fillAreaRect, ms->foreColor, g_director->getInkDrawPixel(), this);
|
||||
// fall through
|
||||
case kOutlinedRectangleSprite:
|
||||
// if we have lineSize <= 0, means we are not drawing anything. so we may return directly.
|
||||
if (ms->lineSize <= 0)
|
||||
break;
|
||||
ms->pd = &plotStroke;
|
||||
Graphics::drawRect(strokeRect, ms->foreColor, g_director->getInkDrawPixel(), this);
|
||||
break;
|
||||
case kRoundedRectangleSprite:
|
||||
ms->pd = &plotFill;
|
||||
Graphics::drawRoundRect(fillAreaRect, 12, ms->foreColor, true, g_director->getInkDrawPixel(), this);
|
||||
// fall through
|
||||
case kOutlinedRoundedRectangleSprite:
|
||||
if (ms->lineSize <= 0)
|
||||
break;
|
||||
ms->pd = &plotStroke;
|
||||
Graphics::drawRoundRect(strokeRect, 12, ms->foreColor, false, g_director->getInkDrawPixel(), this);
|
||||
break;
|
||||
case kOvalSprite:
|
||||
ms->pd = &plotFill;
|
||||
Graphics::drawEllipse(fillAreaRect.left, fillAreaRect.top, fillAreaRect.right, fillAreaRect.bottom, ms->foreColor, true, g_director->getInkDrawPixel(), this);
|
||||
// fall through
|
||||
case kOutlinedOvalSprite:
|
||||
if (ms->lineSize <= 0)
|
||||
break;
|
||||
ms->pd = &plotStroke;
|
||||
Graphics::drawEllipse(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, ms->foreColor, false, g_director->getInkDrawPixel(), this);
|
||||
break;
|
||||
case kLineTopBottomSprite:
|
||||
ms->pd = &plotStroke;
|
||||
Graphics::drawLine(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, ms->foreColor, g_director->getInkDrawPixel(), this);
|
||||
break;
|
||||
case kLineBottomTopSprite:
|
||||
ms->pd = &plotStroke;
|
||||
Graphics::drawLine(strokeRect.left, strokeRect.bottom, strokeRect.right, strokeRect.top, ms->foreColor, g_director->getInkDrawPixel(), this);
|
||||
break;
|
||||
default:
|
||||
warning("DirectorPlotData::inkBlitShape: Expected shape type but got type %d", ms->spriteType);
|
||||
}
|
||||
}
|
||||
|
||||
void DirectorPlotData::inkBlitSurface(Common::Rect &srcRect, const Graphics::Surface *mask) {
|
||||
if (!srf)
|
||||
return;
|
||||
|
||||
// TODO: Determine why colourization causes problems in Warlock
|
||||
if (sprite == kTextSprite)
|
||||
applyColor = false;
|
||||
|
||||
srcPoint.y = abs(srcRect.top - destRect.top);
|
||||
for (int i = 0; i < destRect.height(); i++, srcPoint.y++) {
|
||||
if (_wm->_pixelformat.bytesPerPixel == 1) {
|
||||
srcPoint.x = abs(srcRect.left - destRect.left);
|
||||
const byte *msk = mask ? (const byte *)mask->getBasePtr(srcPoint.x, srcPoint.y) : nullptr;
|
||||
|
||||
for (int j = 0; j < destRect.width(); j++, srcPoint.x++) {
|
||||
if (!mask || (msk && !(*msk++))) {
|
||||
(g_director->getInkDrawPixel())(destRect.left + j, destRect.top + i,
|
||||
preprocessColor(*((byte *)srf->getBasePtr(srcPoint.x, srcPoint.y))), this);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
srcPoint.x = abs(srcRect.left - destRect.left);
|
||||
const uint32 *msk = mask ? (const uint32 *)mask->getBasePtr(srcPoint.x, srcPoint.y) : nullptr;
|
||||
|
||||
for (int j = 0; j < destRect.width(); j++, srcPoint.x++) {
|
||||
if (!mask || (msk && !(*msk++))) {
|
||||
(g_director->getInkDrawPixel())(destRect.left + j, destRect.top + i,
|
||||
preprocessColor(*((int *)srf->getBasePtr(srcPoint.x, srcPoint.y))), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DirectorPlotData::inkBlitStretchSurface(Common::Rect &srcRect, const Graphics::Surface *mask) {
|
||||
if (!srf)
|
||||
return;
|
||||
|
||||
// TODO: Determine why colourization causes problems in Warlock
|
||||
if (sprite == kTextSprite)
|
||||
applyColor = false;
|
||||
|
||||
int scaleX = SCALE_THRESHOLD * srcRect.width() / destRect.width();
|
||||
int scaleY = SCALE_THRESHOLD * srcRect.height() / destRect.height();
|
||||
|
||||
srcPoint.y = abs(srcRect.top - destRect.top);
|
||||
|
||||
for (int i = 0, scaleYCtr = 0; i < destRect.height(); i++, scaleYCtr += scaleY, srcPoint.y++) {
|
||||
if (_wm->_pixelformat.bytesPerPixel == 1) {
|
||||
srcPoint.x = abs(srcRect.left - destRect.left);
|
||||
const byte *msk = mask ? (const byte *)mask->getBasePtr(srcPoint.x, srcPoint.y) : nullptr;
|
||||
|
||||
for (int xCtr = 0, scaleXCtr = 0; xCtr < destRect.width(); xCtr++, scaleXCtr += scaleX, srcPoint.x++) {
|
||||
if (!mask || !(*msk++)) {
|
||||
(g_director->getInkDrawPixel())(destRect.left + xCtr, destRect.top + i,
|
||||
preprocessColor(*((byte *)srf->getBasePtr(scaleXCtr / SCALE_THRESHOLD, scaleYCtr / SCALE_THRESHOLD))), this);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
srcPoint.x = abs(srcRect.left - destRect.left);
|
||||
const uint32 *msk = mask ? (const uint32 *)mask->getBasePtr(srcPoint.x, srcPoint.y) : nullptr;
|
||||
|
||||
for (int xCtr = 0, scaleXCtr = 0; xCtr < destRect.width(); xCtr++, scaleXCtr += scaleX, srcPoint.x++) {
|
||||
if (!mask || !(*msk++)) {
|
||||
(g_director->getInkDrawPixel())(destRect.left + xCtr, destRect.top + i,
|
||||
preprocessColor(*((int *)srf->getBasePtr(scaleXCtr / SCALE_THRESHOLD, scaleYCtr / SCALE_THRESHOLD))), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Director
|
||||
|
@ -198,13 +198,13 @@ void Window::inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::Mana
|
||||
pd.dst = blitTo;
|
||||
|
||||
if (pd.ms) {
|
||||
inkBlitShape(&pd, srcRect);
|
||||
pd.inkBlitShape(srcRect);
|
||||
} else if (pd.srf) {
|
||||
if (channel->isStretched()) {
|
||||
srcRect = channel->getBbox(true);
|
||||
inkBlitStretchSurface(&pd, srcRect, channel->getMask());
|
||||
pd.inkBlitStretchSurface(srcRect, channel->getMask());
|
||||
} else {
|
||||
inkBlitSurface(&pd, srcRect, channel->getMask());
|
||||
pd.inkBlitSurface(srcRect, channel->getMask());
|
||||
}
|
||||
} else {
|
||||
if (debugChannelSet(kDebugImages, 2))
|
||||
@ -212,186 +212,6 @@ void Window::inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::Mana
|
||||
}
|
||||
}
|
||||
|
||||
void Window::inkBlitShape(DirectorPlotData *pd, Common::Rect &srcRect) {
|
||||
if (!pd->ms)
|
||||
return;
|
||||
|
||||
// Preprocess shape colours
|
||||
switch (pd->ink) {
|
||||
case kInkTypeNotTrans:
|
||||
case kInkTypeNotReverse:
|
||||
case kInkTypeNotGhost:
|
||||
return;
|
||||
case kInkTypeReverse:
|
||||
pd->ms->foreColor = 0;
|
||||
pd->ms->backColor = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Common::Rect fillAreaRect((int)srcRect.width(), (int)srcRect.height());
|
||||
fillAreaRect.moveTo(srcRect.left, srcRect.top);
|
||||
Graphics::MacPlotData plotFill(pd->dst, nullptr, &g_director->getPatterns(), pd->ms->pattern, srcRect.left, srcRect.top, 1, pd->ms->backColor);
|
||||
|
||||
Common::Rect strokeRect(MAX((int)srcRect.width() - pd->ms->lineSize, 0), MAX((int)srcRect.height() - pd->ms->lineSize, 0));
|
||||
strokeRect.moveTo(srcRect.left, srcRect.top);
|
||||
Graphics::MacPlotData plotStroke(pd->dst, nullptr, &g_director->getPatterns(), 1, strokeRect.left, strokeRect.top, pd->ms->lineSize, pd->ms->backColor);
|
||||
|
||||
switch (pd->ms->spriteType) {
|
||||
case kRectangleSprite:
|
||||
pd->ms->pd = &plotFill;
|
||||
Graphics::drawFilledRect(fillAreaRect, pd->ms->foreColor, g_director->getInkDrawPixel(), pd);
|
||||
// fall through
|
||||
case kOutlinedRectangleSprite:
|
||||
// if we have lineSize <= 0, means we are not drawing anything. so we may return directly.
|
||||
if (pd->ms->lineSize <= 0)
|
||||
break;
|
||||
pd->ms->pd = &plotStroke;
|
||||
Graphics::drawRect(strokeRect, pd->ms->foreColor, g_director->getInkDrawPixel(), pd);
|
||||
break;
|
||||
case kRoundedRectangleSprite:
|
||||
pd->ms->pd = &plotFill;
|
||||
Graphics::drawRoundRect(fillAreaRect, 12, pd->ms->foreColor, true, g_director->getInkDrawPixel(), pd);
|
||||
// fall through
|
||||
case kOutlinedRoundedRectangleSprite:
|
||||
if (pd->ms->lineSize <= 0)
|
||||
break;
|
||||
pd->ms->pd = &plotStroke;
|
||||
Graphics::drawRoundRect(strokeRect, 12, pd->ms->foreColor, false, g_director->getInkDrawPixel(), pd);
|
||||
break;
|
||||
case kOvalSprite:
|
||||
pd->ms->pd = &plotFill;
|
||||
Graphics::drawEllipse(fillAreaRect.left, fillAreaRect.top, fillAreaRect.right, fillAreaRect.bottom, pd->ms->foreColor, true, g_director->getInkDrawPixel(), pd);
|
||||
// fall through
|
||||
case kOutlinedOvalSprite:
|
||||
if (pd->ms->lineSize <= 0)
|
||||
break;
|
||||
pd->ms->pd = &plotStroke;
|
||||
Graphics::drawEllipse(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, pd->ms->foreColor, false, g_director->getInkDrawPixel(), pd);
|
||||
break;
|
||||
case kLineTopBottomSprite:
|
||||
pd->ms->pd = &plotStroke;
|
||||
Graphics::drawLine(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, pd->ms->foreColor, g_director->getInkDrawPixel(), pd);
|
||||
break;
|
||||
case kLineBottomTopSprite:
|
||||
pd->ms->pd = &plotStroke;
|
||||
Graphics::drawLine(strokeRect.left, strokeRect.bottom, strokeRect.right, strokeRect.top, pd->ms->foreColor, g_director->getInkDrawPixel(), pd);
|
||||
break;
|
||||
default:
|
||||
warning("Window::inkBlitFrom: Expected shape type but got type %d", pd->ms->spriteType);
|
||||
}
|
||||
}
|
||||
|
||||
void Window::inkBlitSurface(DirectorPlotData *pd, Common::Rect &srcRect, const Graphics::Surface *mask) {
|
||||
if (!pd->srf)
|
||||
return;
|
||||
|
||||
// TODO: Determine why colourization causes problems in Warlock
|
||||
if (pd->sprite == kTextSprite)
|
||||
pd->applyColor = false;
|
||||
|
||||
pd->srcPoint.y = abs(srcRect.top - pd->destRect.top);
|
||||
for (int i = 0; i < pd->destRect.height(); i++, pd->srcPoint.y++) {
|
||||
if (_wm->_pixelformat.bytesPerPixel == 1) {
|
||||
pd->srcPoint.x = abs(srcRect.left - pd->destRect.left);
|
||||
const byte *msk = mask ? (const byte *)mask->getBasePtr(pd->srcPoint.x, pd->srcPoint.y) : nullptr;
|
||||
|
||||
for (int j = 0; j < pd->destRect.width(); j++, pd->srcPoint.x++) {
|
||||
if (!mask || (msk && !(*msk++))) {
|
||||
(g_director->getInkDrawPixel())(pd->destRect.left + j, pd->destRect.top + i,
|
||||
preprocessColor(pd, *((byte *)pd->srf->getBasePtr(pd->srcPoint.x, pd->srcPoint.y))), pd);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pd->srcPoint.x = abs(srcRect.left - pd->destRect.left);
|
||||
const uint32 *msk = mask ? (const uint32 *)mask->getBasePtr(pd->srcPoint.x, pd->srcPoint.y) : nullptr;
|
||||
|
||||
for (int j = 0; j < pd->destRect.width(); j++, pd->srcPoint.x++) {
|
||||
if (!mask || (msk && !(*msk++))) {
|
||||
(g_director->getInkDrawPixel())(pd->destRect.left + j, pd->destRect.top + i,
|
||||
preprocessColor(pd, *((int *)pd->srf->getBasePtr(pd->srcPoint.x, pd->srcPoint.y))), pd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Window::inkBlitStretchSurface(DirectorPlotData *pd, Common::Rect &srcRect, const Graphics::Surface *mask) {
|
||||
if (!pd->srf)
|
||||
return;
|
||||
|
||||
// TODO: Determine why colourization causes problems in Warlock
|
||||
if (pd->sprite == kTextSprite)
|
||||
pd->applyColor = false;
|
||||
|
||||
int scaleX = SCALE_THRESHOLD * srcRect.width() / pd->destRect.width();
|
||||
int scaleY = SCALE_THRESHOLD * srcRect.height() / pd->destRect.height();
|
||||
|
||||
pd->srcPoint.y = abs(srcRect.top - pd->destRect.top);
|
||||
|
||||
for (int i = 0, scaleYCtr = 0; i < pd->destRect.height(); i++, scaleYCtr += scaleY, pd->srcPoint.y++) {
|
||||
if (_wm->_pixelformat.bytesPerPixel == 1) {
|
||||
pd->srcPoint.x = abs(srcRect.left - pd->destRect.left);
|
||||
const byte *msk = mask ? (const byte *)mask->getBasePtr(pd->srcPoint.x, pd->srcPoint.y) : nullptr;
|
||||
|
||||
for (int xCtr = 0, scaleXCtr = 0; xCtr < pd->destRect.width(); xCtr++, scaleXCtr += scaleX, pd->srcPoint.x++) {
|
||||
if (!mask || !(*msk++)) {
|
||||
(g_director->getInkDrawPixel())(pd->destRect.left + xCtr, pd->destRect.top + i,
|
||||
preprocessColor(pd, *((byte *)pd->srf->getBasePtr(scaleXCtr / SCALE_THRESHOLD, scaleYCtr / SCALE_THRESHOLD))), pd);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pd->srcPoint.x = abs(srcRect.left - pd->destRect.left);
|
||||
const uint32 *msk = mask ? (const uint32 *)mask->getBasePtr(pd->srcPoint.x, pd->srcPoint.y) : nullptr;
|
||||
|
||||
for (int xCtr = 0, scaleXCtr = 0; xCtr < pd->destRect.width(); xCtr++, scaleXCtr += scaleX, pd->srcPoint.x++) {
|
||||
if (!mask || !(*msk++)) {
|
||||
(g_director->getInkDrawPixel())(pd->destRect.left + xCtr, pd->destRect.top + i,
|
||||
preprocessColor(pd, *((int *)pd->srf->getBasePtr(scaleXCtr / SCALE_THRESHOLD, scaleYCtr / SCALE_THRESHOLD))), pd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Window::preprocessColor(DirectorPlotData *p, uint32 src) {
|
||||
// HACK: Right now this method is just used for adjusting the colourization on text
|
||||
// sprites, as it would be costly to colourize the chunks on the fly each
|
||||
// time a section needs drawing. It's ugly but mostly works.
|
||||
if (p->sprite == kTextSprite) {
|
||||
switch(p->ink) {
|
||||
case kInkTypeMask:
|
||||
src = (src == p->backColor ? p->foreColor : 0xff);
|
||||
break;
|
||||
case kInkTypeReverse:
|
||||
src = (src == p->foreColor ? 0 : p->colorWhite);
|
||||
break;
|
||||
case kInkTypeNotReverse:
|
||||
src = (src == p->backColor ? p->colorWhite : 0);
|
||||
break;
|
||||
// looks like this part is wrong, maybe it's very same as reverse?
|
||||
// check warlock/DATA/WARLOCKSHIP/ENG/ABOUT to see more detail.
|
||||
// case kInkTypeGhost:
|
||||
// src = (src == p->foreColor ? p->backColor : p->colorWhite);
|
||||
// break;
|
||||
case kInkTypeNotGhost:
|
||||
src = (src == p->backColor ? p->colorWhite : p->backColor);
|
||||
break;
|
||||
case kInkTypeNotCopy:
|
||||
src = (src == p->foreColor ? p->backColor : p->foreColor);
|
||||
break;
|
||||
case kInkTypeNotTrans:
|
||||
src = (src == p->foreColor ? p->backColor : p->colorWhite);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
Common::Point Window::getMousePos() {
|
||||
return g_system->getEventManager()->getMousePos() - Common::Point(_innerDims.left, _innerDims.top);
|
||||
}
|
||||
|
@ -38,8 +38,6 @@ class MacWindowManager;
|
||||
|
||||
namespace Director {
|
||||
|
||||
const int SCALE_THRESHOLD = 0x100;
|
||||
|
||||
class Channel;
|
||||
class MacArchive;
|
||||
struct MacShape;
|
||||
@ -201,13 +199,9 @@ private:
|
||||
bool _titleVisible;
|
||||
|
||||
private:
|
||||
int preprocessColor(DirectorPlotData *p, uint32 src);
|
||||
|
||||
void inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::ManagedSurface *blitTo = nullptr);
|
||||
void inkBlitShape(DirectorPlotData *pd, Common::Rect &srcRect);
|
||||
|
||||
void inkBlitSurface(DirectorPlotData *pd, Common::Rect &srcRect, const Graphics::Surface *mask);
|
||||
void inkBlitStretchSurface(DirectorPlotData *pd, Common::Rect &srcRect, const Graphics::Surface *mask);
|
||||
};
|
||||
|
||||
} // End of namespace Director
|
||||
|
Loading…
x
Reference in New Issue
Block a user