Skip to content

Commit

Permalink
GRAPHICS: MACGUI: Implement drawing primitives
Browse files Browse the repository at this point in the history
This makes the code comply with the latest API changes.
The drawing calls now need to be optimized for the complex shapes.
  • Loading branch information
lephilousophe committed Jan 11, 2025
1 parent bee4b4e commit 1feeead
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 50 deletions.
2 changes: 1 addition & 1 deletion engines/director/graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ void InkPrimitives<T>::drawPoint(int x, int y, uint32 src, void *data) {
// Get the pixel that macDrawPixel will give us, but store it to apply the
// ink later
tmpDst = *dst;
(wm->getDrawPixel())(x, y, src, p->ms->pd);
wm->getDrawPrimitives().drawPoint(x, y, src, p->ms->pd);
src = *dst;

*dst = tmpDst;
Expand Down
8 changes: 5 additions & 3 deletions engines/director/sprite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,19 +157,21 @@ void Sprite::createQDMatte() {
Common::Rect fillAreaRect((int)srcRect.width(), (int)srcRect.height());
Graphics::MacPlotData plotFill(&tmp, nullptr, &g_director->getPatterns(), getPattern(), 0, 0, 1, g_director->_wm->_colorBlack);

Graphics::Primitives &primitives = g_director->_wm->getDrawPrimitives();

// it's the same for filled and outlined qd shape when we are using floodfill, so we use filled rect directly since it won't be affected by line size.
switch (_spriteType) {
case kOutlinedRectangleSprite:
case kRectangleSprite:
Graphics::drawFilledRect1(fillAreaRect, g_director->_wm->_colorBlack, g_director->_wm->getDrawPixel(), &plotFill);
primitives.drawFilledRect1(fillAreaRect, g_director->_wm->_colorBlack, &plotFill);
break;
case kOutlinedRoundedRectangleSprite:
case kRoundedRectangleSprite:
Graphics::drawRoundRect1(fillAreaRect, 12, g_director->_wm->_colorBlack, true, g_director->_wm->getDrawPixel(), &plotFill);
primitives.drawRoundRect1(fillAreaRect, 12, g_director->_wm->_colorBlack, true, &plotFill);
break;
case kOutlinedOvalSprite:
case kOvalSprite:
Graphics::drawEllipse(fillAreaRect.left, fillAreaRect.top, fillAreaRect.right, fillAreaRect.bottom, g_director->_wm->_colorBlack, true, g_director->_wm->getDrawPixel(), &plotFill);
primitives.drawEllipse(fillAreaRect.left, fillAreaRect.top, fillAreaRect.right, fillAreaRect.bottom, g_director->_wm->_colorBlack, true, &plotFill);
break;
case kLineBottomTopSprite:
case kLineTopBottomSprite:
Expand Down
32 changes: 19 additions & 13 deletions graphics/macgui/macbutton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,23 @@ void MacButton::setActive(bool active) {
_contentIsDirty = true;
}

// whether to use getDrawPixel or getDrawInvertPixel to draw invert pixel, maybe depends on the pattle we are using
// whether to use getDrawPrimitives or getDrawInvertPrimitives to draw invert pixel, maybe depends on the pattle we are using
void MacButton::invertOuter() {
Common::Rect r(_dims.width() - 1, _dims.height() - 1);

Primitives &primitives = _wm->getDrawPrimitives();

switch (_buttonType) {
case kCheckBox: {
Common::Rect c = Common::Rect(r.left + 1, r.top + 3, r.left + 9, r.top + 11);
Graphics::drawRect1(c, 0, _wm->getDrawPixel(), &_pd);
primitives.drawRect1(c, 0, &_pd);
}
break;
case kRound:
Graphics::drawRoundRect1(r, 4, 0, true, _wm->getDrawPixel(), &_pd);
primitives.drawRoundRect1(r, 4, 0, true, &_pd);
break;
case kRadio:
Graphics::drawEllipse(r.left + 1, r.top + 3, r.left + 10, r.top + 12, 0, false, _wm->getDrawPixel(), &_pd);
primitives.drawEllipse(r.left + 1, r.top + 3, r.left + 10, r.top + 12, 0, false, &_pd);
break;
}
}
Expand All @@ -100,28 +102,30 @@ void MacButton::invertInner() {
Common::Rect r(_dims.width() - 1, _dims.height() - 1);
Common::Rect checkbox;

Primitives &primitives = _wm->getDrawPrimitives();

switch (_buttonType) {
case kCheckBox:
switch (_checkBoxType) {
case kCBNormal:
Graphics::drawLine(r.left + 1, r.top + 3, r.left + 9, r.top + 11, 0, _wm->getDrawPixel(), &_pd);
Graphics::drawLine(r.left + 1, r.top + 11, r.left + 9, r.top + 3, 0, _wm->getDrawPixel(), &_pd);
(_wm->getDrawInvertPixel())(5, 7, 0, &_pd);
primitives.drawLine(r.left + 1, r.top + 3, r.left + 9, r.top + 11, 0, &_pd);
primitives.drawLine(r.left + 1, r.top + 11, r.left + 9, r.top + 3, 0, &_pd);
(_wm->getDrawInvertPrimitives()).drawPoint(5, 7, 0, &_pd);
break;
case kCBInsetBlack:
checkbox = Common::Rect(r.left + 2, r.top + 4, r.left + 2 + 6, r.top + 4 + 6);
Graphics::drawFilledRect1(checkbox, 0, _wm->getDrawPixel(), &_pd);
primitives.drawFilledRect1(checkbox, 0, &_pd);
break;
case kCBFilledBlack:
checkbox = Common::Rect(r.left + 1, r.top + 3, r.left + 1 + 8, r.top + 3 + 8);
Graphics::drawFilledRect1(checkbox, 0, _wm->getDrawPixel(), &_pd);
primitives.drawFilledRect1(checkbox, 0, &_pd);
break;
}
break;
case kRound:
break;
case kRadio:
Graphics::drawEllipse(r.left + 3, r.top + 5, r.left + 8, r.top + 10, 0, true, _wm->getDrawPixel(), &_pd);
primitives.drawEllipse(r.left + 3, r.top + 5, r.left + 8, r.top + 10, 0, true, &_pd);
break;
}
}
Expand All @@ -142,17 +146,19 @@ bool MacButton::draw(bool forceRedraw) {
Common::Rect r(_dims.width() - 1, _dims.height() - 1);
Graphics::MacPlotData pd(_composeSurface, nullptr, &_wm->getPatterns(), 1, 0, 0, 1, 0);

Primitives &primitives = _wm->getDrawPrimitives();

switch (_buttonType) {
case kCheckBox: {
Common::Rect c = Common::Rect(r.left, r.top + 2, r.left + 10, r.top + 2 + 10);
Graphics::drawRect1(c, 0xff, _wm->getDrawPixel(), &pd);
primitives.drawRect1(c, 0xff, &pd);
break;
}
case kRound:
Graphics::drawRoundRect1(r, 4, 0xff, false, _wm->getDrawPixel(), &pd);
primitives.drawRoundRect1(r, 4, 0xff, false, &pd);
break;
case kRadio:
Graphics::drawEllipse(r.left, r.top + 2, r.left + 11, r.top + 13, 0xff, false, _wm->getDrawPixel(), &pd);
primitives.drawEllipse(r.left, r.top + 2, r.left + 11, r.top + 13, 0xff, false, &pd);
break;
}

Expand Down
10 changes: 7 additions & 3 deletions graphics/macgui/macdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,10 @@ const Graphics::Font *MacDialog::getDialogFont() {
}

void MacDialog::paint() {
Primitives &primitives = _wm->getDrawPrimitives();

MacPlotData pd(_screen, nullptr, &_wm->getPatterns(), 1, 0, 0, 1, _wm->_colorBlack, false);
drawFilledRect1(_bbox, kColorWhite, _wm->getDrawPixel(), &pd);
primitives.drawFilledRect1(_bbox, kColorWhite, &pd);
_mactext->drawToPoint(_screen, Common::Point(_bbox.left + (_bbox.width() - _maxTextWidth)/2, _bbox.top + 16));
static int boxOutline[] = {1, 0, 0, 1, 1};
drawOutline(_bbox, boxOutline, ARRAYSIZE(boxOutline));
Expand All @@ -121,7 +123,7 @@ void MacDialog::paint() {
Common::Rect bb(button->bounds.left + 5, button->bounds.top + 5,
button->bounds.right - 5, button->bounds.bottom - 5);

drawFilledRect1(bb, kColorBlack, _wm->getDrawPixel(), &pd);
primitives.drawFilledRect1(bb, kColorBlack, &pd);

color = kColorWhite;
}
Expand All @@ -141,11 +143,13 @@ void MacDialog::paint() {
}

void MacDialog::drawOutline(Common::Rect &bounds, int *spec, int speclen) {
Primitives &primitives = _wm->getDrawPrimitives();

MacPlotData pd(_screen, nullptr, &_wm->getPatterns(), 1, 0, 0, 1, _wm->_colorBlack, false);
for (int i = 0; i < speclen; i++)
if (spec[i] != 0) {
Common::Rect r(bounds.left + i, bounds.top + i, bounds.right - i, bounds.bottom - i);
drawRect1(r, kColorBlack, _wm->getDrawPixel(), &pd);
primitives.drawRect1(r, kColorBlack, &pd);
}
}

Expand Down
3 changes: 2 additions & 1 deletion graphics/macgui/macwindowborder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ void MacWindowBorder::drawScrollBar(ManagedSurface *g, MacWindowManager *wm) {
Common::Rect rr(rx1, ry1, rx2, ry2);

MacPlotData pd(g, nullptr, &wm->getPatterns(), 1, 0, 0, 1, wm->_colorWhite, true);
Graphics::drawFilledRect1(rr, wm->_colorWhite, wm->getDrawInvertPixel(), &pd);
Primitives &primitives = wm->getDrawInvertPrimitives();
primitives.drawFilledRect1(rr, wm->_colorWhite, &pd);

// after drawing, we set the _scrollSize negative, to indicate no more drawing is needed
// if win95 mode is enabled, then we keep on drawing the scrollbar
Expand Down
67 changes: 42 additions & 25 deletions graphics/macgui/macwindowmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,18 @@ static const byte macCursorCrossBar[] = {
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
};

template<typename T>
class MacDrawPrimitives : public Primitives {
public:
void drawPoint(int x, int y, uint32 color, void *data) override;
};

template<typename T>
class MacDrawInvertPrimitives : public MacDrawPrimitives<T> {
public:
void drawPoint(int x, int y, uint32 color, void *data) override;
};

MacWindowManager::MacWindowManager(uint32 mode, MacPatterns *patterns, Common::Language language) {
_screen = nullptr;
_screenCopy = nullptr;
Expand Down Expand Up @@ -194,10 +206,16 @@ MacWindowManager::MacWindowManager(uint32 mode, MacPatterns *patterns, Common::L

_hilitingWidget = false;

if (mode & kWMMode32bpp)
if (mode & kWMMode32bpp) {
_pixelformat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
else
_macDrawPrimitives = new MacDrawPrimitives<uint32>();
// No implementation yet
_macDrawInvertPrimitives = nullptr;
} else {
_pixelformat = PixelFormat::createFormatCLUT8();
_macDrawPrimitives = new MacDrawPrimitives<byte>();
_macDrawInvertPrimitives = new MacDrawInvertPrimitives<byte>();
}

if (patterns) {
_patterns = *patterns;
Expand Down Expand Up @@ -255,6 +273,9 @@ MacWindowManager::~MacWindowManager() {

delete _desktop;

delete _macDrawPrimitives;
delete _macDrawInvertPrimitives;

cleanupDesktopBmp();
cleanupDataBundle();
}
Expand Down Expand Up @@ -765,7 +786,7 @@ void MacWindowManager::removeWindow(MacWindow *target) {
}

template<typename T>
void macDrawPixel(int x, int y, int color, void *data) {
void MacDrawPrimitives<T>::drawPoint(int x, int y, uint32 color, void *data) {
MacPlotData *p = (MacPlotData *)data;

if (p->fillType > p->patterns->size() || !p->fillType)
Expand All @@ -778,11 +799,11 @@ void macDrawPixel(int x, int y, int color, void *data) {
uint xu = (uint)x; // for letting compiler optimize it
uint yu = (uint)y;

*((T)p->surface->getBasePtr(xu, yu)) = p->invert ? ~(*((T)p->surface->getBasePtr(xu, yu))) :
*((T *)p->surface->getBasePtr(xu, yu)) = p->invert ? ~(*((T *)p->surface->getBasePtr(xu, yu))) :
(pat[(yu + p->fillOriginY) % 8] & (1 << (7 - (xu + p->fillOriginX) % 8))) ? color : p->bgColor;

if (p->mask)
*((T)p->mask->getBasePtr(xu, yu)) = 0xff;
*((T *)p->mask->getBasePtr(xu, yu)) = 0xff;
}
} else {
int x1 = x;
Expand All @@ -795,16 +816,19 @@ void macDrawPixel(int x, int y, int color, void *data) {
if (x >= 0 && x < p->surface->w && y >= 0 && y < p->surface->h) {
uint xu = (uint)x; // for letting compiler optimize it
uint yu = (uint)y;
*((T)p->surface->getBasePtr(xu, yu)) = p->invert ? ~(*((T)p->surface->getBasePtr(xu, yu))) :
*((T *)p->surface->getBasePtr(xu, yu)) = p->invert ? ~(*((T *)p->surface->getBasePtr(xu, yu))) :
(pat[(yu + p->fillOriginY) % 8] & (1 << (7 + (xu - p->fillOriginX) % 8))) ? color : p->bgColor;

if (p->mask)
*((T)p->mask->getBasePtr(xu, yu)) = 0xff;
*((T *)p->mask->getBasePtr(xu, yu)) = 0xff;
}
}
}

void macDrawInvertPixel(int x, int y, int color, void *data) {
// TODO: implement for other bpp

template<>
void MacDrawInvertPrimitives<byte>::drawPoint(int x, int y, uint32 color, void *data) {
MacPlotData *p = (MacPlotData *)data;

if (p->fillType > p->patterns->size() || !p->fillType)
Expand All @@ -828,19 +852,11 @@ void macDrawInvertPixel(int x, int y, int color, void *data) {
}
}

MacDrawPixPtr MacWindowManager::getDrawPixel() {
if (_pixelformat.bytesPerPixel == 1)
return &macDrawPixel<byte *>;
else
return &macDrawPixel<uint32 *>;
}

// get the function of drawing invert pixel for default palette
MacDrawPixPtr MacWindowManager::getDrawInvertPixel() {
if (_pixelformat.bytesPerPixel == 1)
return &macDrawInvertPixel;
warning("function of drawing invert pixel for default palette has not implemented yet");
return nullptr;
Primitives &MacWindowManager::getDrawInvertPrimitives() const {
if (!_macDrawInvertPrimitives)
warning("function of drawing invert pixel for default palette has not implemented yet");
return *_macDrawInvertPrimitives;
}

void MacWindowManager::loadDesktop() {
Expand Down Expand Up @@ -889,7 +905,7 @@ void MacWindowManager::drawDesktop() {

MacPlotData pd(_desktop, nullptr, &_patterns, kPatternCheckers, 0, 0, 1, _colorWhite);

Graphics::drawRoundRect(r, kDesktopArc, _colorBlack, true, getDrawPixel(), &pd);
getDrawPrimitives().drawRoundRect(r, kDesktopArc, _colorBlack, true, &pd);
}
}

Expand Down Expand Up @@ -1230,10 +1246,11 @@ void MacWindowManager::renderZoomBox(bool redraw) {
}

void MacWindowManager::zoomBoxInner(Common::Rect &r, Graphics::MacPlotData &pd) {
Graphics::drawLine(r.left, r.top, r.right, r.top, 0xff, getDrawPixel(), &pd);
Graphics::drawLine(r.right, r.top, r.right, r.bottom, 0xff, getDrawPixel(), &pd);
Graphics::drawLine(r.left, r.bottom, r.right, r.bottom, 0xff, getDrawPixel(), &pd);
Graphics::drawLine(r.left, r.top, r.left, r.bottom, 0xff, getDrawPixel(), &pd);
Primitives &primitives = getDrawPrimitives();
primitives.drawHLine(r.left, r.right, r.top, 0xff, &pd);
primitives.drawVLine(r.right, r.top, r.bottom, 0xff, &pd);
primitives.drawHLine(r.left, r.right, r.bottom, 0xff, &pd);
primitives.drawVLine(r.left, r.top, r.bottom, 0xff, &pd);
}

/////////////////
Expand Down
9 changes: 5 additions & 4 deletions graphics/macgui/macwindowmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,6 @@ struct ZoomBox {
uint32 nextTime;
};

typedef void (* MacDrawPixPtr)(int, int, int, void *);

/**
* A manager class to handle window creation, destruction,
* drawing, moving and event handling.
Expand All @@ -151,8 +149,8 @@ class MacWindowManager {
MacWindowManager(uint32 mode = 0, MacPatterns *patterns = nullptr, Common::Language language = Common::UNK_LANG);
~MacWindowManager();

MacDrawPixPtr getDrawPixel();
MacDrawPixPtr getDrawInvertPixel();
Primitives &getDrawPrimitives() const { return *_macDrawPrimitives; }
Primitives &getDrawInvertPrimitives() const;

/**
* Mutator to indicate the surface onto which the desktop will be drawn.
Expand Down Expand Up @@ -452,6 +450,9 @@ class MacWindowManager {

bool _inEditableArea;

Primitives *_macDrawPrimitives;
Primitives *_macDrawInvertPrimitives;

MacPatterns _patterns;
MacPatterns _builtinPatterns;
byte *_palette;
Expand Down

0 comments on commit 1feeead

Please sign in to comment.