1st step in refactoring some of the card rendering logic - currently, each 'client' has duplicated code having to deal with how to render the full card graphic vs text mode vs using a 'back' image if a card isn't found. This is a first pass at consolidating some of that logic to one location - the ultimate goal being, eventually, the resource cache will actually own the notion of whether it's handing out a real card image or a default filler if the card isn't available, and the client code rendering the card should be oblivious.

In this change, I made the CardGui's RenderBig() and AlternateRender() functions protected; anyone wanting to render a card simply calls RenderCard(), and the card drawing mode is passed along as a param.
This commit is contained in:
wrenczes@gmail.com
2010-11-14 08:15:26 +00:00
parent e758c7eea1
commit 27fd107208
9 changed files with 125 additions and 110 deletions
+31 -7
View File
@@ -12,9 +12,35 @@
class MTGCardInstance;
class PlayGuiObject;
namespace DrawMode
{
enum
{
kNormal = 0,
kText,
kHidden
};
const int kNumDrawModes = 3;
}
struct CardGui : public PlayGuiObject {
protected:
/*
** Tries to render the Big version of a card picture, backups to text version in case of failure
*/
void RenderBig(const Pos&);
static void RenderBig(MTGCard * card, const Pos& pos);
/*
** Renders Text Version of a card
*/
void AlternateRenderBig(const Pos&);
void RenderCountersBig(const Pos& pos);
static void AlternateRender(MTGCard * card, const Pos& pos);
static void TinyCropRender(MTGCard * card, const Pos& pos, JQuad * quad);
public:
static const float Width;
static const float Height;
@@ -25,14 +51,12 @@ struct CardGui : public PlayGuiObject {
CardGui(MTGCardInstance* card, float x, float y);
CardGui(MTGCardInstance* card, const Pos& ref);
virtual void Render();
void RenderBig(const Pos&); //Tries to render the Big version of a card picture, backups to text version in case of failure
static void RenderBig(MTGCard * card, const Pos& pos);
void alternateRenderBig(const Pos&); //Renders Text Version of a card
void renderCountersBig(const Pos& pos);
virtual void Update(float dt);
static void alternateRender(MTGCard * card, const Pos& pos);
static void tinyCropRender(MTGCard * card, const Pos& pos, JQuad * quad);
static JQuad * alternateThumbQuad(MTGCard * card);
void DrawCard(const Pos& inPosition, int inMode = DrawMode::kNormal);
static void DrawCard(MTGCard* inCard, const Pos& inPosition, int inMode = DrawMode::kNormal);
static JQuad * AlternateThumbQuad(MTGCard * card);
virtual ostream& toString(ostream&) const;
};
+1 -9
View File
@@ -12,14 +12,6 @@ using std::vector;
class PlayGuiObject;
class DuelLayers;
enum {
BIG_MODE_SHOW = 0,
BIG_MODE_TEXT = 1,
BIG_MODE_HIDE = 2,
NB_BIG_MODES = 3
};
template <typename T>
struct LimitorFunctor
{
@@ -32,7 +24,7 @@ class CardSelectorBase : public GuiLayer
{
public:
CardSelectorBase(int inDrawMode) : mDrawMode(inDrawMode) {};
CardSelectorBase(int inDrawMode = DrawMode::kNormal) : mDrawMode(inDrawMode) {};
virtual void Add(PlayGuiObject*) = 0;
virtual void Remove(PlayGuiObject*) = 0;
virtual bool CheckUserInput(JButton key) = 0;
+4 -13
View File
@@ -74,7 +74,7 @@ void Interruptible::Render(MTGCardInstance * source, JQuad * targetQuad, string
JRenderer * renderer = JRenderer::GetInstance();
JQuad * quad = resources.RetrieveCard(source,CACHE_THUMB);
if (!quad)
quad = CardGui::alternateThumbQuad(source);
quad = CardGui::AlternateThumbQuad(source);
if (quad){
quad->SetColor(ARGB(255,255,255,255));
float scale = mHeight / quad->mHeight;
@@ -83,19 +83,10 @@ void Interruptible::Render(MTGCardInstance * source, JQuad * targetQuad, string
mFont->DrawString(_(alt1).c_str(),x,y-15);
}
if (bigQuad){
int showMode = CardSelectorSingleton::Instance()->GetDrawMode();
if (bigQuad)
{
Pos pos = Pos(CardGui::BigWidth / 2, CardGui::BigHeight / 2 - 10, 1.0, 0.0, 220);
switch(showMode){
case BIG_MODE_SHOW:
CardGui::RenderBig(source,pos);
break;
case BIG_MODE_TEXT:
CardGui::alternateRender(source, pos);
break;
default:
break;
}
CardGui::DrawCard(source, pos, CardSelectorSingleton::Instance()->GetDrawMode());
}
if (targetQuad){
+5 -15
View File
@@ -212,28 +212,18 @@ void CardDisplay::Render(){
}
//TODO: CardSelector should handle the graveyard and the library in the future...
if (mCount && mObjects[mCurr] != NULL){
if (mCount && mObjects[mCurr] != NULL)
{
mObjects[mCurr]->Render();
CardGui * cardg = ((CardGui *)mObjects[mCurr]);
Pos pos = Pos(CardGui::BigWidth / 2, CardGui::BigHeight / 2 - 10, 1.0, 0.0, 220);
int showMode = BIG_MODE_SHOW;
if (game){
showMode = CardSelectorSingleton::Instance()->GetDrawMode();
if (game)
{
pos.actY = 150;
if (x < (CardGui::BigWidth / 2)) pos.actX = SCREEN_WIDTH - 10 - CardGui::BigWidth / 2;
}
switch(showMode){
case BIG_MODE_SHOW:
cardg->RenderBig(pos);
break;
case BIG_MODE_TEXT:
cardg->alternateRenderBig(pos);
break;
default:
break;
}
cardg->DrawCard(pos, CardSelectorSingleton::Instance()->GetDrawMode());
}
}
+32 -11
View File
@@ -61,6 +61,27 @@ void CardGui::Update(float dt)
PlayGuiObject::Update(dt);
}
void CardGui::DrawCard(const Pos& inPosition, int inMode)
{
DrawCard(card, inPosition, inMode);
RenderCountersBig(inPosition);
}
void CardGui::DrawCard(MTGCard* inCard, const Pos& inPosition, int inMode)
{
switch(inMode)
{
case DrawMode::kNormal:
RenderBig(inCard, inPosition);
break;
case DrawMode::kText:
AlternateRender(inCard, inPosition);
break;
default:
break;
}
}
void CardGui::Render()
{
@@ -79,7 +100,7 @@ void CardGui::Render()
if (!quad) quad = resources.RetrieveCard(card);
#endif
if (quad) alternate = false;
else quad = alternateThumbQuad(card);
else quad = AlternateThumbQuad(card);
float cardScale = quad ? 40 / quad->mHeight : 1;
float scale = actZ * cardScale;
@@ -161,7 +182,7 @@ void CardGui::Render()
JQuad * CardGui::alternateThumbQuad(MTGCard * card){
JQuad * CardGui::AlternateThumbQuad(MTGCard * card){
JQuad * q;
if(card->data->countColors() > 1){
@@ -185,7 +206,7 @@ JQuad * CardGui::alternateThumbQuad(MTGCard * card){
return q;
}
void CardGui::alternateRender(MTGCard * card, const Pos& pos){
void CardGui::AlternateRender(MTGCard * card, const Pos& pos){
// Draw the "unknown" card model
JRenderer * renderer = JRenderer::GetInstance();
JQuad * q;
@@ -373,7 +394,7 @@ void CardGui::alternateRender(MTGCard * card, const Pos& pos){
}
void CardGui::tinyCropRender(MTGCard * card, const Pos& pos, JQuad * quad) {
void CardGui::TinyCropRender(MTGCard * card, const Pos& pos, JQuad * quad) {
if (!quad) return;
@@ -572,9 +593,9 @@ void CardGui::tinyCropRender(MTGCard * card, const Pos& pos, JQuad * quad) {
font->SetScale(backup_scale);
}
void CardGui::alternateRenderBig(const Pos& pos){
alternateRender(card,pos);
renderCountersBig(pos);
void CardGui::AlternateRenderBig(const Pos& pos){
AlternateRender(card,pos);
RenderCountersBig(pos);
}
//Renders a big card on screen. Defaults to the "alternate" rendering if no image is found
@@ -586,7 +607,7 @@ void CardGui::RenderBig(MTGCard* card, const Pos& pos){
JQuad * quad = resources.RetrieveCard(card);
if (quad){
if (quad->mHeight < quad->mWidth) {
return tinyCropRender(card, pos, quad);
return TinyCropRender(card, pos, quad);
}
quad->SetColor(ARGB(255,255,255,255));
float scale = pos.actZ * 257.f / quad->mHeight;
@@ -605,10 +626,10 @@ void CardGui::RenderBig(MTGCard* card, const Pos& pos){
}
// If we come here, we do not have the picture.
alternateRender(card,pos);
AlternateRender(card,pos);
}
void CardGui::renderCountersBig(const Pos& pos){
void CardGui::RenderCountersBig(const Pos& pos){
// Write Named Counters
if (card->counters) {
WFont * font = resources.GetWFont(Fonts::MAGIC_FONT);
@@ -640,7 +661,7 @@ void CardGui::renderCountersBig(const Pos& pos){
void CardGui::RenderBig(const Pos& pos){
RenderBig(card,pos);
renderCountersBig(pos);
RenderCountersBig(pos);
}
+6 -14
View File
@@ -34,7 +34,7 @@ CardSelector::SelectorMemory::SelectorMemory(PlayGuiObject* object) : object(obj
CardSelector::SelectorMemory::SelectorMemory() { object = NULL; x = y = 0; }
CardSelector::CardSelector(DuelLayers* duel) : CardSelectorBase(BIG_MODE_SHOW), active(NULL), duel(duel), limitor(NULL), bigpos(300, 150, 1.0, 0.0, 220) {}
CardSelector::CardSelector(DuelLayers* duel) : active(NULL), duel(duel), limitor(NULL), bigpos(300, 150, 1.0, 0.0, 220) {}
void CardSelector::Add(CardSelector::Target* target)
{
@@ -132,8 +132,8 @@ bool CardSelector::CheckUserInput(JButton key)
active = closest<Down>(cards, limitor, active);
break;
case JGE_BTN_CANCEL:
mDrawMode = (mDrawMode+1) % NB_BIG_MODES;
if(mDrawMode == BIG_MODE_TEXT)
mDrawMode = (mDrawMode+1) % DrawMode::kNumDrawModes;
if(mDrawMode == DrawMode::kText)
options[Options::DISABLECARDS].number = 1;
else
options[Options::DISABLECARDS].number = 0;
@@ -236,17 +236,9 @@ void CardSelector::Update(float dt) {
void CardSelector::Render() {
if (active) {
active->Render();
if (CardView* c = dynamic_cast<CardView*>(active)) {
switch(mDrawMode) {
case BIG_MODE_SHOW:
c->RenderBig(bigpos);
break;
case BIG_MODE_TEXT:
c->alternateRenderBig(bigpos);
break;
default:
break;
}
if (CardView* card = dynamic_cast<CardView*>(active))
{
card->DrawCard(bigpos, mDrawMode);
}
}
}
+25 -14
View File
@@ -1301,10 +1301,12 @@ void GameStateDeckViewer::renderCard(int id, float rotation){
int cacheError = CACHE_ERROR_NONE;
if(!options[Options::DISABLECARDS].number){
if(!options[Options::DISABLECARDS].number)
{
quad = resources.RetrieveCard(card,RETRIEVE_EXISTING);
cacheError = resources.RetrieveError();
if (!quad && cacheError != CACHE_ERROR_404){
if (!quad && cacheError != CACHE_ERROR_404)
{
if(last_user_activity > (abs(2-id) + 1)* NO_USER_ACTIVITY_SHOWCARD_DELAY)
quad = resources.RetrieveCard(card);
else{
@@ -1315,31 +1317,40 @@ void GameStateDeckViewer::renderCard(int id, float rotation){
int quadAlpha = alpha;
if ( !displayed_deck->count(card)) quadAlpha /=2;
if (quad){
if (quad == backQuad) {
if (quad)
{
if (quad == backQuad)
{
quad->SetColor(ARGB(255,255,255,255));
float _scale = scale *(285 / quad->mHeight);
JRenderer::GetInstance()->RenderQuad(quad, x , y , 0.0f,_scale,_scale);
} else {
Pos pos = Pos(x, y, scale* 285/250, 0.0, 255);
CardGui::RenderBig(card, pos);
JRenderer::GetInstance()->RenderQuad(quad, x, y, 0.0f, _scale, _scale);
}
}else{
else
{
Pos pos = Pos(x, y, scale* 285/250, 0.0, 255);
CardGui::DrawCard(card, pos);
}
}
else
{
Pos pos = Pos(x, y, scale* 285/250, 0.0, 255);
CardGui::alternateRender(card, pos);
CardGui::DrawCard(card, pos, DrawMode::kText);
if(!options[Options::DISABLECARDS].number)
quad = resources.RetrieveCard(card,CACHE_THUMB);
if (quad){
if (quad)
{
float _scale = 285 * scale / quad->mHeight;
quad->SetColor(ARGB(40,255,255,255));
JRenderer::GetInstance()->RenderQuad(quad,x,y,0,_scale,_scale);
JRenderer::GetInstance()->RenderQuad(quad, x, y, 0, _scale, _scale);
}
}
quadAlpha = 255 - quadAlpha;
if (quadAlpha > 0){
if (quadAlpha > 0)
{
JRenderer::GetInstance()->FillRect(x - scale * 100.0f ,y - scale * 142.5f , scale * 200.0f, scale * 285.0f, ARGB(quadAlpha,0,0,0));
}
if (last_user_activity < 3){
if (last_user_activity < 3)
{
int fontAlpha = alpha;
float qtY = y -135*scale;
float qtX = x + 40*scale;
+4 -14
View File
@@ -377,7 +377,7 @@ CardZone* LandCardZone::EnterZone(JButton inDirection)
** Constructor. All the navigation logic is initialized here, by pairing up each card zone with a set of neighbours.
*/
Navigator::Navigator(DuelLayers* inDuelLayers)
: CardSelectorBase(BIG_MODE_SHOW), mDrawPosition(kDefaultCardPosition), mDuelLayers(inDuelLayers), mLimitorEnabled(false)
: mDrawPosition(kDefaultCardPosition), mDuelLayers(inDuelLayers), mLimitorEnabled(false)
{
assert(mDuelLayers);
@@ -506,8 +506,8 @@ bool Navigator::CheckUserInput(JButton inKey)
HandleKeyStroke(inKey);
break;
case JGE_BTN_CANCEL:
mDrawMode = (mDrawMode+1) % NB_BIG_MODES;
if(mDrawMode == BIG_MODE_TEXT)
mDrawMode = (mDrawMode+1) % DrawMode::kNumDrawModes;
if(mDrawMode == DrawMode::kText)
options[Options::DISABLECARDS].number = 1;
else
options[Options::DISABLECARDS].number = 0;
@@ -568,17 +568,7 @@ void Navigator::Render()
CardView* card = dynamic_cast<CardView*>(GetCurrentCard());
if (card)
{
switch(mDrawMode)
{
case BIG_MODE_SHOW:
card->RenderBig(mDrawPosition);
break;
case BIG_MODE_TEXT:
card->alternateRenderBig(mDrawPosition);
break;
default:
break;
}
card->DrawCard(mDrawPosition, mDrawMode);
}
}
}
+17 -13
View File
@@ -1142,10 +1142,10 @@ void WGuiImage::Render(){
WGuiCardImage::WGuiCardImage(WDataSource * wds, bool _thumb) : WGuiImage(wds){
bThumb = _thumb;
};
void WGuiCardImage::Render(){
void WGuiCardImage::Render()
{
JRenderer * renderer = JRenderer::GetInstance();
MTGCard * c = NULL;
Pos p(x+margin, y+margin, 1,0,255);
@@ -1163,26 +1163,30 @@ void WGuiCardImage::Render(){
float scale = p.actZ * 257.f / q->mHeight;
q->SetColor(ARGB(255,255,255,255));
renderer->RenderQuad(q,p.x,p.y,0,scale,scale);
}else{ //Have card.
if(bThumb){ //Thumbnail.
}
else
{ //Have card.
if(bThumb)
{ //Thumbnail.
JQuad * q = NULL;
if(!options[Options::DISABLECARDS].number){
if(!options[Options::DISABLECARDS].number)
{
q = source->getThumb(mOffset.getPos());
#if defined WIN32 || defined LINUX
if(!q)
q = source->getImage(mOffset.getPos());
#endif
}
if(!q && (q = CardGui::alternateThumbQuad(c)) == NULL)
if(!q && (q = CardGui::AlternateThumbQuad(c)) == NULL)
return; //TODO Some kind of error image.
renderer->RenderQuad(q,p.x,p.y);
}
else{ //Normal card.
else
{ //Normal card.
JQuad * q = source->getImage(mOffset.getPos());
if(!q || options[Options::DISABLECARDS].number)
CardGui::alternateRender(c,p);
else
CardGui::RenderBig(c,p);
int mode = (!q || options[Options::DISABLECARDS].number) ? DrawMode::kText : DrawMode::kNormal;
CardGui::DrawCard(c,p, mode);
}
}
}
@@ -1229,12 +1233,12 @@ void WGuiCardDistort::Render(){
q = source->getImage(mOffset.getPos());
#endif
if(!q || options[Options::DISABLECARDS].number)
q = CardGui::alternateThumbQuad(c);
q = CardGui::AlternateThumbQuad(c);
}
else {
q = source->getImage(mOffset.getPos());
if(!q || options[Options::DISABLECARDS].number)
q = CardGui::alternateThumbQuad(c); //TODO alternateX should render to texture.
q = CardGui::AlternateThumbQuad(c); //TODO alternateX should render to texture.
}
}
if(!q)