Commit 732821e4 authored by sm's avatar sm

Add modifiers and improve interface

Improve initialization and xml parsing of RotateModifier, MaskModifier,
TileAniModifier
Add FadeModifier and corresponding xml parser
Add GrowModifier and corresponding xml parser
Increase minor version
parent de6eb1da
stmm-games (0.3) unstable; urgency=low
* Improve initialization and xml parsing of RotateModifier, MaskModifier, TileAniModifier
* Add FadeModifier and corresponding xml parser
* Add GrowModifier and corresponding xml parser
* Increase minor version
-- Stefano Marsili <efanomars@gmx.ch> Sun, 24 Feb 2019 19:29:39 +0100
stmm-games (0.2) unstable; urgency=low
* Jason Turner, C++ Weekly Ep.154, eliminate empty destructors
......@@ -7,10 +16,10 @@ stmm-games (0.2) unstable; urgency=low
* Improve deb package creation script
* Increase minor version
-- Stefano Marsili <efanomars@gmx.ch> Tue, 12 Feb 2018 19:29:39 +0100
-- Stefano Marsili <efanomars@gmx.ch> Tue, 12 Feb 2019 19:29:39 +0100
stmm-games (0.1) unstable; urgency=low
* Initial release
-- Stefano Marsili <efanomars@gmx.ch> Fri, 30 Nov 2018 18:28:38 +0100
-- Stefano Marsili <efanomars@gmx.ch> Thu, 24 Jan 2019 14:24:34 +0100
......@@ -59,6 +59,7 @@ public:
NRect m_oArea;
};
void boardAnimateTiles(NRect oArea) override;
void boardAnimateTile(NPoint oXY) override;
struct AnimationCreate : public Called
{
......
......@@ -43,6 +43,18 @@ void FakeLevelView::boardAnimateTiles(NRect oArea)
m_oAllCalls.push_back(std::move(refCalled));
// m_eAnimateTilesCalls.push_back(oArea);
}
void FakeLevelView::boardAnimateTile(NPoint oXY)
{
auto refCalled = make_unique<BoardAnimateTiles>();
NRect oArea;
oArea.m_nX = oXY.m_nX;
oArea.m_nY = oXY.m_nY;
oArea.m_nW = 1;
oArea.m_nH = 1;
refCalled->m_oArea = std::move(oArea);
m_oAllCalls.push_back(std::move(refCalled));
// m_eAnimateTilesCalls.push_back(oArea);
}
bool FakeLevelView::animationCreate(const shared_ptr<LevelAnimation>& refLevelAnimation)
{
assert(refLevelAnimation);
......
......@@ -20,12 +20,12 @@
# MINOR is REVISION (implementation of interface)
# AGE is always 0
set(STMM_GAMES_FAKE_MAJOR_VERSION 0)
set(STMM_GAMES_FAKE_MINOR_VERSION 2)
set(STMM_GAMES_FAKE_MINOR_VERSION 3)
set(STMM_GAMES_FAKE_VERSION "${STMM_GAMES_FAKE_MAJOR_VERSION}.${STMM_GAMES_FAKE_MINOR_VERSION}.0")
# required stmm-games version
set(STMM_GAMES_FAKE_REQ_STMM_GAMES_MAJOR_VERSION 0)
set(STMM_GAMES_FAKE_REQ_STMM_GAMES_MINOR_VERSION 2)
set(STMM_GAMES_FAKE_REQ_STMM_GAMES_MINOR_VERSION 3)
set(STMM_GAMES_FAKE_REQ_STMM_GAMES_VERSION "${STMM_GAMES_FAKE_REQ_STMM_GAMES_MAJOR_VERSION}.${STMM_GAMES_FAKE_REQ_STMM_GAMES_MINOR_VERSION}")
include("${PROJECT_SOURCE_DIR}/../libstmm-games/stmm-games-defs.cmake")
......
......@@ -48,6 +48,7 @@ set(STMMI_HEADERS_MODIFIERS
${STMMI_HEADERS_DIR}/modifiers/casemodifier.h
${STMMI_HEADERS_DIR}/modifiers/fademodifier.h
${STMMI_HEADERS_DIR}/modifiers/fillmodifier.h
${STMMI_HEADERS_DIR}/modifiers/growmodifier.h
${STMMI_HEADERS_DIR}/modifiers/ifelsemodifier.h
${STMMI_HEADERS_DIR}/modifiers/imagemodifier.h
${STMMI_HEADERS_DIR}/modifiers/maskmodifier.h
......@@ -164,6 +165,7 @@ set(STMMI_SOURCES
${STMMI_SOURCES_DIR}/modifiers/casemodifier.cc
${STMMI_SOURCES_DIR}/modifiers/fademodifier.cc
${STMMI_SOURCES_DIR}/modifiers/fillmodifier.cc
${STMMI_SOURCES_DIR}/modifiers/growmodifier.cc
${STMMI_SOURCES_DIR}/modifiers/ifelsemodifier.cc
${STMMI_SOURCES_DIR}/modifiers/imagemodifier.cc
${STMMI_SOURCES_DIR}/modifiers/maskmodifier.cc
......
......@@ -27,9 +27,16 @@ namespace stmg
class StdTheme;
/** Alpha tile modifier.
* Draws the sub modifiers with the alpha (transparency) defined by the
* to be drawn tile.
*/
class AlphaModifier : public ContainerModifier
{
public:
/** Constructor.
* @param p1Owner The owner. Cannot be null.
*/
explicit AlphaModifier(StdTheme* p1Owner);
FLOW_CONTROL drawTile(const Cairo::RefPtr<Cairo::Context>& refCc, StdThemeDrawingContext& oDc
, const Tile& oTile, int32_t nPlayer, const std::vector<double>& aAniElapsed) override;
......
......@@ -27,19 +27,28 @@ namespace stmg
class StdTheme;
// This modifier fades the submodifiers: from [elapsed == 0.0] alpha=255 (opaque), to [elapsed == 1.0] alpha=0 (invisible)
/** Fader.
* This modifier fades the submodifiers: from [elapsed == 0.0] alpha=255 (opaque), to [elapsed == 1.0] alpha=0 (invisible)
*/
class FadeModifier : public ContainerModifier
{
public:
FadeModifier(StdTheme* p1Owner, int32_t nElapsedIdx, bool bInvert);
FadeModifier(StdTheme* p1Owner, bool bElapsedSet, double fElapsed, bool bInvert);
struct Init
{
int32_t m_nElapsedTileAniIdx = -1; /**< The tileanimation that determines the fade value. Default -1 (undefined).*/
double m_fDefaultElapsed = -1.0; /**< The default elapsed value. From 0.0 to 1.0 or -1.0 if not defined. */
bool m_bInvert = false; /**< Whether the fading should be inverted. Default is false.*/
};
/** Constructor.
* The two params m_nElapsedTileAniIdx and m_fDefaultElapsed cannot be both undefined.
* @param p1Owner The owner. Cannot be null.
* @param oInit The initialization data.
*/
FadeModifier(StdTheme* p1Owner, Init&& oInit);
FLOW_CONTROL drawTile(const Cairo::RefPtr<Cairo::Context>& refCc, StdThemeDrawingContext& oDc
, const Tile& oTile, int32_t nPlayer, const std::vector<double>& aAniElapsed) override;
private:
int32_t m_nElapsedIdx;
const bool m_bElapsedSet;
const double m_fElapsed;
bool m_bInvert;
Init m_oData;
private:
FadeModifier(const FadeModifier& oSource) = delete;
FadeModifier& operator=(const FadeModifier& oSource) = delete;
......
/*
* File: growmodifier.h
*
* Copyright © 2019 Stefano Marsili, <stemars@gmx.ch>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>
*/
#ifndef STMG_GROW_MODIFIER_H
#define STMG_GROW_MODIFIER_H
#include "../containermodifier.h"
namespace stmg
{
class StdTheme;
class GrowModifier : public ContainerModifier
{
public:
struct Init
{
int32_t m_nElapsedTileAniIdx = -1; /**< The tileanimation that determines the grow value. Default -1 (undefined).*/
double m_fDefaultElapsed = -1.0; /**< The default elapsed value. From 0.0 to 1.0 or -1.0 if not defined. */
bool m_bInvert = false; /**< Whether the rotation should be inverted. Default is false.*/
};
/** Constructor.
* The two params m_nElapsedTileAniIdx and m_fDefaultElapsed cannot be both undefined.
* @param p1Owner The owner. Cannot be null.
* @param oInit The initialization data.
*/
GrowModifier(StdTheme* p1Owner, Init&& oInit);
FLOW_CONTROL drawTile(const Cairo::RefPtr<Cairo::Context>& refCc, StdThemeDrawingContext& oDc
, const Tile& oTile, int32_t nPlayer, const std::vector<double>& aAniElapsed) override;
private:
void growImageInRect(const Cairo::RefPtr<Cairo::Context>& refCc
, int32_t nImgW, int32_t nImgH, int32_t nRectW, int32_t nRectH
, double fFactor);
Init m_oData;
private:
GrowModifier() = delete;
GrowModifier(const GrowModifier& oSource) = delete;
GrowModifier& operator=(const GrowModifier& oSource) = delete;
};
} // namespace stmg
#endif /* STMG_GROW_MODIFIER_H */
......@@ -34,9 +34,19 @@ class StdTheme;
class MaskModifier : public ContainerModifier
{
public:
MaskModifier(StdTheme* p1Owner, shared_ptr<TileAni>& refTileAni, int32_t nElapsedIdx, bool bInvert);
MaskModifier(StdTheme* p1Owner, shared_ptr<TileAni>& refTileAni, bool bElapsedSet, double fElapsed, bool bInvert);
MaskModifier(StdTheme* p1Owner, shared_ptr<Image>& refMask);
struct Init
{
int32_t m_nElapsedTileAniIdx = -1; /**< The tileanimation that determines the mask to apply. Default -1 (undefined).*/
double m_fDefaultElapsed = -1.0; /**< The default elapsed value. From 0.0 to 1.0 or -1.0 if not defined. */
bool m_bInvert = false; /**< Whether the mask animation should be inverted. Default is false.*/
shared_ptr<Image> m_refMask; /**< The default image. Can be null. */
shared_ptr<TileAni> m_refTileAni; /**< The image tile ani. Can be null. */
};
/** Constructor.
* @param p1Owner The owner. Cannot be null.
* @param oInit The initialization data.
*/
MaskModifier(StdTheme* p1Owner, Init&& oInit);
FLOW_CONTROL drawTile(const Cairo::RefPtr<Cairo::Context>& refCc, StdThemeDrawingContext& oDc
, const Tile& oTile, int32_t nPlayer, const std::vector<double>& aAniElapsed) override;
......@@ -44,14 +54,7 @@ public:
void registerTileSize(int32_t nW, int32_t nH) override;
void unregisterTileSize(int32_t nW, int32_t nH) override;
private:
shared_ptr<TileAni> m_refTileAni;
const int32_t m_nElapsedIdx;
const bool m_bElapsedSet;
const double m_fElapsed;
shared_ptr<Image> m_refMask;
const bool m_bInvert;
static const int32_t s_nUseImage;
static const int32_t s_nUseElapsed;
Init m_oData;
private:
MaskModifier() = delete;
MaskModifier(const MaskModifier& oSource) = delete;
......
......@@ -30,20 +30,27 @@ class StdTheme;
class RotateModifier : public ContainerModifier
{
public:
RotateModifier(StdTheme* p1Owner, int32_t nElapsedIdx, bool bInvert);
RotateModifier(StdTheme* p1Owner, bool bElapsedSet, double fElapsed, bool bInvert);
struct Init
{
int32_t m_nElapsedTileAniIdx = -1; /**< The tileanimation that determines the rotate value. Default -1 (undefined).*/
double m_fDefaultElapsed = -1.0; /**< The default elapsed value. From 0.0 to 1.0 or -1.0 if not defined. */
bool m_bInvert = false; /**< Whether the rotation should be inverted. Default is false.*/
};
/** Constructor.
* The two params m_nElapsedTileAniIdx and m_fDefaultElapsed cannot be both undefined.
* @param p1Owner The owner. Cannot be null.
* @param oInit The initialization data.
*/
RotateModifier(StdTheme* p1Owner, Init&& oInit);
FLOW_CONTROL drawTile(const Cairo::RefPtr<Cairo::Context>& refCc, StdThemeDrawingContext& oDc
, const Tile& oTile, int32_t nPlayer, const std::vector<double>& aAniElapsed) override;
private:
void rotateImageInRect(const Cairo::RefPtr<Cairo::Context>& cr
void rotateImageInRect(const Cairo::RefPtr<Cairo::Context>& refCc
, int32_t nImgW, int32_t nImgH, int32_t nRectW, int32_t nRectH
, double fShrink, double fAngleDeg);
int32_t m_nElapsedIdx;
const bool m_bElapsedSet;
const double m_fElapsed;
const bool m_bInvert;
Init m_oData;
private:
RotateModifier() = delete;
RotateModifier(const RotateModifier& oSource) = delete;
......
......@@ -36,19 +36,26 @@ class StdTheme;
class TileAniModifier : public StdThemeModifier
{
public:
TileAniModifier(StdTheme* p1Owner, shared_ptr<TileAni>& refTileAni, int32_t nElapsedIdx, bool bInvert);
TileAniModifier(StdTheme* p1Owner, shared_ptr<TileAni>& refTileAni, bool bElapsedSet, double fElapsed, bool bInvert);
struct Init
{
int32_t m_nElapsedTileAniIdx = -1; /**< The tileanimation that determines the image to show. Default -1 (undefined).*/
double m_fDefaultElapsed = -1.0; /**< The default elapsed value. From 0.0 to 1.0 or -1.0 if not defined. */
bool m_bInvert = false; /**< Whether the tile animation should be inverted. Default is false.*/
shared_ptr<Image> m_refImg; /**< The default image. Can be null. */
shared_ptr<TileAni> m_refTileAni; /**< The image tile ani. Can be null. */
};
/** Constructor.
* @param p1Owner The owner. Cannot be null.
* @param oInit The initialization data.
*/
TileAniModifier(StdTheme* p1Owner, Init&& oInit);
FLOW_CONTROL drawTile(const Cairo::RefPtr<Cairo::Context>& refCc, StdThemeDrawingContext& oDc
, const Tile& oTile, int32_t nPlayer, const std::vector<double>& aAniElapsed) override;
void registerTileSize(int32_t nW, int32_t nH) override;
void unregisterTileSize(int32_t nW, int32_t nH) override;
private:
shared_ptr<TileAni> m_refTileAni;
int32_t m_nElapsedIdx;
const bool m_bElapsedSet;
const double m_fElapsed;
const bool m_bInvert;
Init m_oData;
private:
TileAniModifier() = delete;
TileAniModifier(const TileAniModifier& oSource) = delete;
......
......@@ -17,11 +17,6 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>
*/
// #include <gtkmm.h>
// #include <librsvg/rsvg.h>
// #include <cairomm/surface.h>
// #include <limits>
#include "cachedsurfaces.h"
#include <cassert>
......
......@@ -40,6 +40,8 @@ const Glib::ustring GameWindow::s_sScreenNameMain = "Main";
const Glib::ustring GameWindow::s_sScreenNamePaused = "Paused";
const Glib::ustring GameWindow::s_sScreenNameEmpty = "Empty";
static constexpr int32_t s_nNewGameTransitionMillisec = 100;
std::pair<Glib::RefPtr<GameWindow>, std::string> GameWindow::create(MainWindowData&& oMainWindowData)
{
auto refStdConfig = oMainWindowData.m_refStdConfig; // make copy
......@@ -706,7 +708,7 @@ void GameWindow::onButtonNewGame()
changeScreen(STATUS_PLAY, s_nScreenPlay);
m_bWaitingForDrawingAreaSizeAllocate = true;
const int32_t nWaitTransitionToFinish = 1; // Doesn't work for 0
const int32_t nWaitTransitionToFinish = s_nNewGameTransitionMillisec; // Doesn't work for 0
Glib::signal_timeout().connect_once(sigc::mem_fun(*this, &GameWindow::onButtonNewGameOut), nWaitTransitionToFinish);
}
void GameWindow::onButtonNewGameOut()
......
......@@ -23,51 +23,33 @@
namespace stmg
{
// bInvert == false: 0.0: opaque, 1.0 transparent
// bInvert == true: 0.0: transparent, 1.0 opaque
// if tile animation not defined: same as if fElapsed == 0.0
FadeModifier::FadeModifier(StdTheme* p1Owner, int32_t nElapsedIdx, bool bInvert)
FadeModifier::FadeModifier(StdTheme* p1Owner, Init&& oInit)
: ContainerModifier(p1Owner)
, m_nElapsedIdx(nElapsedIdx)
, m_bElapsedSet(false)
, m_fElapsed(-2.0)
, m_bInvert(bInvert)
, m_oData(std::move(oInit))
{
assert(nElapsedIdx >= 0);
}
FadeModifier::FadeModifier(StdTheme* p1Owner, bool bElapsedSet, double fElapsed, bool bInvert)
: ContainerModifier(p1Owner)
, m_nElapsedIdx(-1)
, m_bElapsedSet(bElapsedSet)
, m_fElapsed(fElapsed)
, m_bInvert(bInvert)
{
assert((!bElapsedSet) || ((fElapsed >= 0.0) && (fElapsed <= 1.0)));
assert(((m_oData.m_fDefaultElapsed >= 0.0) && (m_oData.m_fDefaultElapsed <= 1.0)) || (m_oData.m_fDefaultElapsed == -1.0));
assert(m_oData.m_nElapsedTileAniIdx >= -1);
assert((m_oData.m_nElapsedTileAniIdx >= 0) || (m_oData.m_fDefaultElapsed != -1.0));
}
StdThemeModifier::FLOW_CONTROL FadeModifier::drawTile(const Cairo::RefPtr<Cairo::Context>& refCc, StdThemeDrawingContext& oDc
, const Tile& oTile, int32_t nPlayer, const std::vector<double>& aAniElapsed)
{
double fElapsed = -1.0;
if (m_nElapsedIdx < 0) {
if (m_bElapsedSet) {
fElapsed = m_fElapsed;
} else {
fElapsed = -1.0;
}
if (m_oData.m_nElapsedTileAniIdx < 0) {
fElapsed = m_oData.m_fDefaultElapsed;
} else {
assert(m_nElapsedIdx < static_cast<int32_t>(aAniElapsed.size()));
fElapsed = aAniElapsed[m_nElapsedIdx];
assert(m_oData.m_nElapsedTileAniIdx < static_cast<int32_t>(aAniElapsed.size()));
fElapsed = aAniElapsed[m_oData.m_nElapsedTileAniIdx];
if (fElapsed < 0.0) {
fElapsed = m_oData.m_fDefaultElapsed;
}
}
if (fElapsed < 0.0) {
if (!m_bInvert) {
// draw opaque
return ContainerModifier::drawTile(refCc, oDc, oTile, nPlayer, aAniElapsed);
} else {
// draw nothing
return FLOW_CONTROL_CONTINUE; //------------------------------------
}
// draw opaque
const FLOW_CONTROL eCtl = ContainerModifier::drawTile(refCc, oDc, oTile, nPlayer, aAniElapsed);
return eCtl; //---------------------------------------------------------
}
const double fAlpha1 = (m_bInvert ? fElapsed : (1.0 - fElapsed));
const double fAlpha1 = (m_oData.m_bInvert ? fElapsed : (1.0 - fElapsed));
if (fAlpha1 == 0.0) {
// transparent, draw nothing
return FLOW_CONTROL_CONTINUE; //----------------------------------------
......
/*
* File: growmodifier.cc
*
* Copyright © 2019 Stefano Marsili, <stemars@gmx.ch>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>
*/
#include "modifiers/growmodifier.h"
#include "stdtheme.h"
namespace stmg
{
GrowModifier::GrowModifier(StdTheme* p1Owner, Init&& oInit)
: ContainerModifier(p1Owner)
, m_oData(std::move(oInit))
{
assert(((m_oData.m_fDefaultElapsed >= 0.0) && (m_oData.m_fDefaultElapsed <= 1.0)) || (m_oData.m_fDefaultElapsed == -1.0));
assert(m_oData.m_nElapsedTileAniIdx >= -1);
assert((m_oData.m_nElapsedTileAniIdx >= 0) || (m_oData.m_fDefaultElapsed != -1.0));
}
void GrowModifier::growImageInRect(const Cairo::RefPtr<Cairo::Context>& refCc
, int32_t nImgW, int32_t nImgH, int32_t nRectW, int32_t nRectH
, double fFactor)
{
const double fShrink = fFactor;
const int32_t nMaxWH = std::max(nImgW, nImgH);
{
double fTransX = 0.5 * nRectW * (1 - fShrink);
double fTransY = 0.5 * nRectH * (1 - fShrink);
refCc->translate(fTransX, fTransY);
}
{
const double fWScale = 1.0 * nRectW * fShrink / nMaxWH;
const double fHScale = 1.0 * nRectH * fShrink / nMaxWH;
refCc->scale(fWScale, fHScale);
}
{
const double fTransX = 0.5 * nMaxWH;
const double fTransY = 0.5 * nMaxWH;
refCc->translate(fTransX, fTransY);
}
{
const double fWScale = 1.0 * nMaxWH / nImgW;
const double fHScale = 1.0 * nMaxWH / nImgH;
refCc->scale(fWScale, fHScale);
}
{
const double fTransX = - 0.5 * nImgW;
const double fTransY = - 0.5 * nImgH;
refCc->translate(fTransX, fTransY);
}
}
StdThemeModifier::FLOW_CONTROL GrowModifier::drawTile(const Cairo::RefPtr<Cairo::Context>& refCc, StdThemeDrawingContext& oDc
, const Tile& oTile, int32_t nPlayer, const std::vector<double>& aAniElapsed)
{
double fElapsed = -1.0;
if (m_oData.m_nElapsedTileAniIdx < 0) {
fElapsed = m_oData.m_fDefaultElapsed;
} else {
assert(m_oData.m_nElapsedTileAniIdx < static_cast<int32_t>(aAniElapsed.size()));
fElapsed = aAniElapsed[m_oData.m_nElapsedTileAniIdx];
if (fElapsed < 0.0) {
fElapsed = m_oData.m_fDefaultElapsed;
}
}
if ((fElapsed >= 0.0) && m_oData.m_bInvert) {
fElapsed = 1.0 - fElapsed;
}
if (fElapsed <= 0.0) {
// no grow
const FLOW_CONTROL eCtl = ContainerModifier::drawTile(refCc, oDc, oTile, nPlayer, aAniElapsed);
return eCtl; //---------------------------------------------------------
}
//std::cout << "GrowModifier::drawTile fElapsed=" << fElapsed << '\n';
const NSize oSize = oDc.getTileSize();
const int32_t& nW = oSize.m_nW;
const int32_t& nH = oSize.m_nH;
refCc->save();
refCc->rectangle(0, 0, nW, nH);
refCc->clip();
growImageInRect(refCc, nW, nH, nW, nH, fElapsed);
refCc->rectangle(0, 0, nW, nH);
refCc->clip();
const FLOW_CONTROL eCtl = ContainerModifier::drawTile(refCc, oDc, oTile, nPlayer, aAniElapsed);
refCc->restore();
return eCtl;
}
} // namespace stmg
......@@ -23,109 +23,87 @@
namespace stmg
{
const int32_t MaskModifier::s_nUseImage = -77;
const int32_t MaskModifier::s_nUseElapsed = -99;
MaskModifier::MaskModifier(StdTheme* p1Owner, shared_ptr<TileAni>& refTileAni, int32_t nElapsedIdx, bool bInvert)
MaskModifier::MaskModifier(StdTheme* p1Owner, Init&& oInit)
: ContainerModifier(p1Owner)
, m_refTileAni(refTileAni)
, m_nElapsedIdx(nElapsedIdx)
, m_bElapsedSet(false)
, m_fElapsed(-2.0)
, m_bInvert(bInvert)
, m_oData(std::move(oInit))
{
assert(nElapsedIdx >= 0);
assert(m_refTileAni);
}
MaskModifier::MaskModifier(StdTheme* p1Owner, shared_ptr<TileAni>& refTileAni, bool bElapsedSet, double fElapsed, bool bInvert)
: ContainerModifier(p1Owner)
, m_refTileAni(refTileAni)
, m_nElapsedIdx(s_nUseElapsed)
, m_bElapsedSet(bElapsedSet)
, m_fElapsed(fElapsed)
, m_bInvert(bInvert)
{
assert((!bElapsedSet) || ((fElapsed >= 0.0) && (fElapsed <= 1.0)));
assert(m_refTileAni);
}
MaskModifier::MaskModifier(StdTheme* p1Owner, shared_ptr<Image>& refMask)
: ContainerModifier(p1Owner)
, m_nElapsedIdx(s_nUseImage)
, m_bElapsedSet(false)
, m_fElapsed(-2.0)
, m_refMask(refMask)
, m_bInvert(false)
{
assert(refMask);
assert(m_oData.m_refTileAni || m_oData.m_refMask);
assert((m_oData.m_nElapsedTileAniIdx >= -1) && (m_oData.m_nElapsedTileAniIdx < p1Owner->getNamed().tileAnis().size()));
assert(((m_oData.m_fDefaultElapsed >= 0.0) && (m_oData.m_fDefaultElapsed <= 1.0)) || (m_oData.m_fDefaultElapsed == -1.0));
if (! m_oData.m_refTileAni) {
assert((!m_oData.m_bInvert) && (m_oData.m_fDefaultElapsed < 0.0) && (m_oData.m_nElapsedTileAniIdx < 0));
} else if (!m_oData.m_refMask) {
assert((m_oData.m_fDefaultElapsed >= 0.0) || (m_oData.m_nElapsedTileAniIdx >= 0) || m_oData.m_refTileAni->getDefaultImage());
m_oData.m_refMask = m_oData.m_refTileAni->getDefaultImage();
} else {
assert((m_oData.m_fDefaultElapsed < 0.0) && (m_oData.m_nElapsedTileAniIdx >= 0));
}
}
StdThemeModifier::FLOW_CONTROL MaskModifier::drawTile(const Cairo::RefPtr<Cairo::Context>& refCc, StdThemeDrawingContext& oDc
, const Tile& oTile, int32_t nPlayer, const std::vector<double>& aAniElapsed)
{
shared_ptr<Image> refImage;
if (m_nElapsedIdx == s_nUseImage) {
refImage = m_refMask;
} else {
double fElapsed = -1.0;
if (m_nElapsedIdx == s_nUseElapsed) {
if (m_bElapsedSet) {
fElapsed = m_fElapsed;
} else {
fElapsed = -1.0;
}
} else {
assert(m_nElapsedIdx < static_cast<int32_t>(aAniElapsed.size()));
fElapsed = aAniElapsed[m_nElapsedIdx];
}
const auto oDrawMask = [&](const shared_ptr<Image>& refImage) -> FLOW_CONTROL
{
Cairo::RefPtr<Cairo::Surface> refWork;
const FLOW_CONTROL eCtl = drawContainedToWorkSurface(oDc, oTile, nPlayer, aAniElapsed, refWork);
const NSize oSize = oDc.getTileSize();
const int32_t& nW = oSize.m_nW;
const int32_t& nH = oSize.m_nH;
refCc->save();
refCc->rectangle(0, 0, nW, nH);
refCc->clip();
refCc->set_source(refWork,0,0);
const Cairo::RefPtr<const Cairo::Surface>& refMaskSurf = refImage->getAsMaskSurface(nW, nH);
refCc->mask(refMaskSurf, 0,0);
refCc->restore();
return eCtl;
};
double fElapsed = -1.0;
if (m_oData.m_nElapsedTileAniIdx >= 0) {
assert(m_oData.m_nElapsedTileAniIdx < static_cast<int32_t>(aAniElapsed.size()));
fElapsed = aAniElapsed[m_oData.m_nElapsedTileAniIdx];
}
if (fElapsed < 0.0) {
fElapsed = m_oData.m_fDefaultElapsed;
if (fElapsed < 0.0) {
refImage = m_refTileAni->getDefaultImage();
if (!refImage) {
// don't mask
return ContainerModifier::drawTile(refCc, oDc, oTile, nPlayer, aAniElapsed);
}
} else {
if (m_bInvert) {
fElapsed = 1.0 - fElapsed;
const auto& refMask = m_oData.m_refMask;
if (refMask) {
return oDrawMask(refMask); //-----------------------------------
}
refImage = m_refTileAni->getImage(fElapsed);
assert(refImage);
// don't mask;
const FLOW_CONTROL eCtl = ContainerModifier::drawTile(refCc, oDc, oTile, nPlayer, aAniElapsed);
return eCtl; //-----------------------------------------------------
}
}
Cairo::RefPtr<Cairo::Surface> refWork;
const FLOW_CONTROL eCtl = drawContainedToWorkSurface(oDc, oTile, nPlayer, aAniElapsed, refWork);
const NSize oSize = oDc.getTileSize();
const int32_t& nW = oSize.m_nW;
const int32_t& nH = oSize.m_nH;
refCc->save();
refCc->rectangle(0, 0, nW, nH);
refCc->clip();
refCc->set_source(refWork,0,0);
const Cairo::RefPtr<const Cairo::Surface>& refMaskSurf = refImage->getAsMaskSurface(nW, nH);
refCc->mask(refMaskSurf, 0,0);
refCc->restore();
return eCtl;
if (m_oData.m_bInvert) {
fElapsed = 1.0 - fElapsed;
}
return oDrawMask(m_oData.m_refTileAni->getImage(fElapsed));
}
void MaskModifier::registerTileSize(int32_t nW, int32_t nH)
{
if (m_nElapsedIdx == s_nUseImage) {
m_refMask->addCachedSize(nW, nH);
} else {
const int32_t nTotImgs = m_refTileAni->getTotImages();
if (m_oData.m_refMask) {
m_oData.m_refMask->addCachedSize(nW, nH);
}
if (m_oData.m_refTileAni) {
const int32_t nTotImgs = m_oData.m_refTileAni->getTotImages();