diff options
author | Thomas Günther <tom@toms-cafe.de> | 2007-09-25 00:29:48 +0200 |
---|---|---|
committer | Thomas Günther <tom@toms-cafe.de> | 2007-09-25 00:29:48 +0200 |
commit | db35a6286cbbebdb39396466628f2292cb63b975 (patch) | |
tree | 8dc5789274dcc1e627e83a24ddfbb466291e68d1 /game.cpp | |
parent | 473eff38fb6c5ef87b218b3a66c1789e0be784e0 (diff) | |
download | vdr-plugin-spider-db35a6286cbbebdb39396466628f2292cb63b975.tar.gz vdr-plugin-spider-db35a6286cbbebdb39396466628f2292cb63b975.tar.bz2 |
Resume the last game.
Customizable width and height.
OSD error compensation (shrink width/height or reduce colors).
Added setup option to hide the top row.
Set normal variation (two decks and 10 piles) as standard, together with "shrink height" and "hide top row".
Added user-defined variations.
Improved key handling.
Diffstat (limited to 'game.cpp')
-rw-r--r-- | game.cpp | 226 |
1 files changed, 156 insertions, 70 deletions
@@ -17,7 +17,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * $Id: game.cpp 95 2007-09-21 23:01:10Z tom $ + * $Id: game.cpp 97 2007-09-24 22:29:48Z tom $ */ #include "game.h" @@ -58,30 +58,41 @@ Bitmap* cards[suitCount][rankCount]; //--- class SpiderPlugin::Game ------------------------------------------------- +const Game::Colors Game::full_colors = +{ + clrGray50, // background 50% gray + clrRed, // osd_frame red + clrWhite, // card_frame white + clrGray50, // card_frame_bg 50% gray + clrBlue, // inactive_cursor blue + clrYellow // active_cursor yellow +}; +const Game::Colors Game::reduced_colors = +{ + 0xFF0000FF, // background blue + 0xFFFF0000, // osd_frame red + 0xFFFFFFFF, // card_frame white + 0xFF000000, // card_frame_bg black + 0xFF0000FF, // inactive_cursor blue + 0xFF0000FF // active_cursor blue +}; + /** Constructor */ -Game::Game(const SetupData& setup, const char* confdir) : - cOsdObject(true), setup(setup), confdir(confdir) +Game::Game(const SetupData& setup, const char* confdir, + Deck*& deck, Tableau*& tableau) : + cOsdObject(true), setup(setup), confdir(confdir), deck(deck), tableau(tableau) { - width = 504; - height = 360; - xPos = (720 - width) / 2; - yPos = (576 - height) / 2; - xDist = 1; - yDist = cardHeight / 6; osd = NULL; - deck = NULL; - tableau = NULL; currentPile = 0; status = cursorOnPile; - info = new Bitmap(width * 2 / 3, 60); + info = new Bitmap(360, 60); infoText = NULL; + colors = full_colors; } /** Destructor */ Game::~Game() { - delete deck; - delete tableau; delete info; delete osd; for (int s = 0; s < suitCount; ++s) @@ -99,9 +110,64 @@ void Game::Show() osd = cOsdProvider::NewOsd(0, 0); if (osd) { - tArea area = { xPos, yPos, xPos + width - 1, yPos + height - 1, 4 }; + tArea area = { setup.osd_left, + setup.osd_top, + setup.osd_left + (setup.osd_width & ~0x03) - 1, + setup.osd_top + setup.osd_height - 1, + 4 }; + eOsdError err = osd->CanHandleAreas(&area, 1); + if (err == oeOutOfMemory && + setup.osd_error_compensation == SetupData::ReduceColors) + { + // Reduce colors + area.bpp = 2; + err = osd->CanHandleAreas(&area, 1); + } + while (err == oeOutOfMemory) + { + if (setup.osd_error_compensation != SetupData::ShrinkWidth) + { + // Shrink height + area.y1 += 2; + area.y2 -= 2; + } + if (setup.osd_error_compensation == SetupData::ShrinkWidth || + setup.osd_error_compensation == SetupData::ShrinkWidthHeight) + { + // Shrink width + area.x1 += 2; + area.x2 -= 2; + } + err = osd->CanHandleAreas(&area, 1); + } + + // Before setting the osd area - check if we are near the osd memory limit - + // then we use an workaround for driver error (no output near memory limit) + // I hope an extra shrink of 12 lines height is enough to avoid the error + area.y2 += 12; + err = osd->CanHandleAreas(&area, 1); + area.y2 -= 12; + if (err == oeOutOfMemory) + { + area.y1 += 6; + area.y2 -= 6; + } osd->SetAreas(&area, 1); - start(); + if (area.bpp <= 2) + colors = reduced_colors; + + // Load bitmaps + cursor = new Bitmap(cursorWidth, cursorHeight, confdir, cursorName); + back = new Bitmap(cardWidth, cardHeight, confdir, coverName); + frame = new Bitmap(cardWidth, cardHeight, colors.card_frame, + colors.card_frame_bg); + for (int s = 0; s < suitCount; ++s) + for (int r = 0; r < rankCount; ++r) + cards[s][r] = new Bitmap(cardWidth, cardHeight, confdir, + suitNames[s], rankNames[r]); + + if (deck == NULL || tableau == NULL) + start(); paint(); } } @@ -199,6 +265,16 @@ eOSState Game::ProcessKey(eKeys key) tableau->unselect(); status = cursorOnPile; break; + case kGreen: + tableau->unselect(); + tableau->backward(); + status = cursorOnPile; + break; + case kYellow: + tableau->unselect(); + tableau->forward(); + status = cursorOnPile; + break; default: return osContinue; } @@ -207,9 +283,10 @@ eOSState Game::ProcessKey(eKeys key) { switch (key) { + case kLeft: + case kRight: case kDown: status = cursorOnPile; - currentPile = 0; break; case kOk: if (tableau->pack->empty()) @@ -219,6 +296,12 @@ eOSState Game::ProcessKey(eKeys key) else tableau->deal(); break; + case kGreen: + tableau->backward(); + break; + case kYellow: + tableau->forward(); + break; default: return osContinue; } @@ -237,19 +320,6 @@ eOSState Game::ProcessKey(eKeys key) /** Start a new game */ void Game::start() { - // Load bitmaps - if (cursor == NULL) - { - cursor = new Bitmap(cursorWidth, cursorHeight, confdir, cursorName); - back = new Bitmap(cardWidth, cardHeight, confdir, coverName); - frame = new Bitmap(cardWidth, cardHeight, clrWhite, clrGray50); - - for (int s = 0; s < suitCount; ++s) - for (int r = 0; r < rankCount; ++r) - cards[s][r] = new Bitmap(cardWidth, cardHeight, confdir, - suitNames[s], rankNames[r]); - } - delete deck; delete tableau; deck = NULL; @@ -263,12 +333,17 @@ void Game::start() dealCount = 4; pileCount = 7; } - else // normal variation + else if (setup.variation == SetupData::Normal) { deckCount = 2; dealCount = 5; pileCount = 10; - xDist = -23; + } + else // SetupData::Custom: custom variation + { + deckCount = setup.deck_count; + dealCount = setup.deal_count; + pileCount = setup.pile_count; } if (pileCount > rankCount * suitCount * deckCount) @@ -281,44 +356,48 @@ void Game::start() /** Paint all pieces of the game */ void Game::paint() { - int x1 = xPos; - int x2 = xPos + width - 1; - int y1 = yPos; - int y2 = yPos + height - 1; + const cBitmap* bm = osd->GetBitmap(0); + int x1 = bm->X0(); + int x2 = bm->X0() + bm->Width() - 1; + int y1 = bm->Y0(); + int y2 = bm->Y0() + bm->Height() - 1; // Save and restore palette to reduce flickering - cPalette savePalette(*osd->GetBitmap(0)); - osd->DrawRectangle(x1, y1, x2, y2, clrGray50); + cPalette savePalette(*bm); + osd->DrawRectangle(x1, y1, x2, y2, colors.background); osd->SetPalette(savePalette, 0); // Paint red frame - osd->DrawRectangle(x1, y1, x2, y1 + 1, clrRed); - osd->DrawRectangle(x1, y1, x1 + 1, y2, clrRed); - osd->DrawRectangle(x1, y2 - 1, x2, y2, clrRed); - osd->DrawRectangle(x2 - 1, y1, x2, y2, clrRed); - - paintPack(); - - unsigned int f; - for (f = 0; f < tableau->finals.size(); ++f) - if (tableau->finals[f]->empty()) - break; - unsigned int count = f; - for (f = tableau->finals.size(); f-- > count;) - paintFinal(f); - for (f = 0; f < count; ++f) - paintFinal(f); + osd->DrawRectangle(x1, y1, x2, y1 + 1, colors.osd_frame); + osd->DrawRectangle(x1, y1, x1 + 1, y2, colors.osd_frame); + osd->DrawRectangle(x1, y2 - 1, x2, y2, colors.osd_frame); + osd->DrawRectangle(x2 - 1, y1, x2, y2, colors.osd_frame); + + if (!setup.hide_toprow || status == cursorOnPack) + { + paintPack(); + + unsigned int f; + for (f = 0; f < tableau->finals.size(); ++f) + if (tableau->finals[f]->empty()) + paintFinal(f); + for (f = 0; f < tableau->finals.size(); ++f) + if (!tableau->finals[f]->empty()) + paintFinal(f); + } unsigned int p; - for (p = tableau->piles.size(); p-- > currentPile + 1;) - paintPile(p); - for (p = 0; p <= currentPile; ++p) - paintPile(p); + for (p = 0; p < tableau->piles.size(); ++p) + if (tableau->piles[p]->empty()) + paintPile(p); + for (p = 0; p < tableau->piles.size(); ++p) + if (!tableau->piles[p]->empty()) + paintPile(p); if (infoText) { info->text(infoText); - osd->DrawBitmap(xPos + (width - info->Width()) / 2, yPos + 10, *info); + osd->DrawBitmap(x1 + (x2 - x1 + 1 - info->Width()) / 2, y1 + 10, *info); infoText = NULL; } osd->Flush(); @@ -327,8 +406,9 @@ void Game::paint() /** Paint the pack */ void Game::paintPack() { - int packX = xPos + 1; - int packY = yPos + 1; + const cBitmap* bm = osd->GetBitmap(0); + int packX = bm->X0() + 1; + int packY = bm->Y0() + 1; if (tableau->pack->empty()) paintFrame(packX, packY); else @@ -340,9 +420,11 @@ void Game::paintPack() /** Paint a final heap */ void Game::paintFinal(unsigned int f) { + const cBitmap* bm = osd->GetBitmap(0); int offset = tableau->piles.size() - tableau->finals.size(); - int finalX = xPos + 1 + (f + offset) * (cardWidth + xDist); - int finalY = yPos + 1; + int finalX = bm->X0() + 1 + ((f + offset) * (bm->Width() - 1 - cardWidth)) / + (tableau->piles.size() - 1); + int finalY = bm->Y0() + 1; if (tableau->finals[f]->empty()) paintFrame(finalX, finalY); else @@ -352,16 +434,20 @@ void Game::paintFinal(unsigned int f) /** Paint a pile */ void Game::paintPile(unsigned int p) { - int pileX = xPos + 1 + p * (cardWidth + xDist); - int pileY = yPos + 1 + cardHeight + 1; + const cBitmap* bm = osd->GetBitmap(0); + int pileX = bm->X0() + 1 + (p * (bm->Width() - 1 - cardWidth)) / + (tableau->piles.size() - 1); + int pileY = bm->Y0() + 1; + if (!setup.hide_toprow || status == cursorOnPack) + pileY += cardHeight + 1; paintFrame(pileX, pileY); int count = tableau->piles[p]->count(); int closed = count - tableau->piles[p]->open(); int unselected = count - tableau->piles[p]->selected(); - int dist = yDist; - if (pileY + (count + 1) * dist > yPos + height) - dist = (yPos + height - pileY) / (count + 1); + int dist = cardHeight / 6; + if (pileY + (count + 1) * dist > bm->Y0() + bm->Height()) + dist = (bm->Y0() + bm->Height() - pileY) / (count + 1); for (int c = 0; c < count; ++c, pileY += dist) { @@ -383,9 +469,9 @@ void Game::paintCursor(int x, int y) { int x0 = x + (cardWidth - cursorWidth) / 2; int y0 = y + (cardHeight - cursorHeight) / 2; - tColor color = clrBlue; + tColor color = colors.inactive_cursor; if (status == selectedPile) - color = clrYellow; + color = colors.active_cursor; for (x = 0; x < cursorWidth; ++x) for (y = 0; y < cursorHeight; ++y) if (cursor->Color(*cursor->Data(x, y)) != clrTransparent) |