Initial commit
This commit is contained in:
523
engines/bagel/hodjnpodj/barbershop/paint.cpp
Normal file
523
engines/bagel/hodjnpodj/barbershop/paint.cpp
Normal file
@@ -0,0 +1,523 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bagel/hodjnpodj/hnplibs/stdafx.h"
|
||||
#include "bagel/hodjnpodj/barbershop/paint.h"
|
||||
#include "bagel/hodjnpodj/barbershop/barb.h"
|
||||
#include "bagel/hodjnpodj/hnplibs/bitmaps.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace HodjNPodj {
|
||||
namespace Barbershop {
|
||||
|
||||
static const char *DECKS[] = { // bitmap loading
|
||||
"art\\deck0.bmp",
|
||||
"art\\deck1.bmp",
|
||||
"art\\deck2.bmp",
|
||||
"art\\deck3.bmp",
|
||||
"art\\deck4.bmp",
|
||||
"art\\deck5.bmp",
|
||||
"art\\deck6.bmp",
|
||||
"art\\deck7.bmp"
|
||||
};
|
||||
|
||||
/*****************************************************************
|
||||
*
|
||||
* CPaint
|
||||
*
|
||||
* FUNCTIONAL DESCRIPTION:
|
||||
*
|
||||
* [Description of function]
|
||||
*
|
||||
* FORMAL PARAMETERS:
|
||||
*
|
||||
* [Show arguments]
|
||||
*
|
||||
* IMPLICIT INPUT PARAMETERS:
|
||||
*
|
||||
* [External data read]
|
||||
*
|
||||
* IMPLICIT OUTPUT PARAMETERS:
|
||||
*
|
||||
* [External data modified]
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* [Discuss return value]
|
||||
*
|
||||
****************************************************************/
|
||||
CPaint::CPaint(CDC *pDC) {
|
||||
CBitmap *pBmpCardSet = nullptr;
|
||||
CBitmap *pCard = nullptr;
|
||||
bool bSuccess;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < CARDS_PER_COL; i++) { // Initialize master alphabet list
|
||||
pBmpCardSet = FetchBitmap(pDC, (CPalette**) nullptr, DECKS[i]);
|
||||
ASSERT(pBmpCardSet);
|
||||
|
||||
for (j = 0; j < CARDS_PER_ROW; j ++) {
|
||||
pCard = ExtractBitmap( // fetch the proper card
|
||||
pDC,
|
||||
pBmpCardSet,
|
||||
pGamePalette,
|
||||
j * BITMAP_WTH,
|
||||
0,
|
||||
BITMAP_WTH,
|
||||
BITMAP_HEI
|
||||
);
|
||||
|
||||
ASSERT(pCard);
|
||||
|
||||
m_cCardSet[(i * CARDS_PER_ROW) + j] = new OSpr(); // Initize the individual letter of the alphabet list
|
||||
bSuccess = (*m_cCardSet[(i * CARDS_PER_ROW) + j]).LoadSprite(pCard, pGamePalette);
|
||||
ASSERT(bSuccess);
|
||||
|
||||
(*m_cCardSet[(i * CARDS_PER_ROW) + j]).SetHotspot(CARD_HOT_X, CARD_HOT_Y);
|
||||
(*m_cCardSet[(i * CARDS_PER_ROW) + j]).SetMobile(true);
|
||||
(*m_cCardSet[(i * CARDS_PER_ROW) + j]).SetMasked(true);
|
||||
} // end for
|
||||
|
||||
delete pBmpCardSet;
|
||||
pBmpCardSet = nullptr;
|
||||
} // end for
|
||||
|
||||
m_nCardBack = CARD_BACK1;
|
||||
m_nUsedInd = 0; // Used in Stack() proc; for indenting cards placed on used stack
|
||||
|
||||
m_cFound.SetRect(
|
||||
FND_LEF,
|
||||
FND_TOP,
|
||||
FND_RIG,
|
||||
FND_BOT
|
||||
);
|
||||
|
||||
for (i = 0; i < TAB_COUNT; i++)
|
||||
m_cTab[i].SetRect(
|
||||
TAB_LEF + (TAB_OFFSET * i),
|
||||
TAB_TOP,
|
||||
TAB_RIG + (TAB_OFFSET * i),
|
||||
TAB_BOT
|
||||
);
|
||||
|
||||
m_cStock.SetRect(
|
||||
STOC_LEF,
|
||||
STOC_TOP,
|
||||
STOC_RIG,
|
||||
STOC_BOT
|
||||
);
|
||||
|
||||
m_cUsed.SetRect(
|
||||
STOC_LEF + USED_OFFSET,
|
||||
STOC_TOP,
|
||||
STOC_RIG + USED_OFFSET,
|
||||
STOC_BOT
|
||||
);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
*
|
||||
* ~CPaint
|
||||
*
|
||||
* FUNCTIONAL DESCRIPTION:
|
||||
*
|
||||
* [Description of function]
|
||||
*
|
||||
* FORMAL PARAMETERS:
|
||||
*
|
||||
* [Show arguments]
|
||||
*
|
||||
* IMPLICIT INPUT PARAMETERS:
|
||||
*
|
||||
* [External data read]
|
||||
*
|
||||
* IMPLICIT OUTPUT PARAMETERS:
|
||||
*
|
||||
* [External data modified]
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* [Discuss return value]
|
||||
*
|
||||
****************************************************************/
|
||||
CPaint::~CPaint() {
|
||||
int i;
|
||||
|
||||
CSprite::FlushSpriteChain();
|
||||
for (i = 0; i < CARD_SET; i++)
|
||||
delete m_cCardSet[i]; // each letter in the alpha
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
*
|
||||
* Board
|
||||
*
|
||||
* FUNCTIONAL DESCRIPTION:
|
||||
*
|
||||
* [Description of function]
|
||||
*
|
||||
* FORMAL PARAMETERS:
|
||||
*
|
||||
* [Show arguments]
|
||||
*
|
||||
* IMPLICIT INPUT PARAMETERS:
|
||||
*
|
||||
* [External data read]
|
||||
*
|
||||
* IMPLICIT OUTPUT PARAMETERS:
|
||||
*
|
||||
* [External data modified]
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* [Discuss return value]
|
||||
*
|
||||
****************************************************************/
|
||||
void CPaint::Board(CDC *pDC, CBoard *pBoard) {
|
||||
int i, j;
|
||||
CCard *pCard[TAB_COUNT];
|
||||
|
||||
/************************************************************
|
||||
* Goes thru each stack on the tableau, dealing cards one at *
|
||||
* a time rotating to next stack, in turn. *
|
||||
************************************************************/
|
||||
for (i = 0; i < TAB_COUNT; i++)
|
||||
pCard[i] = pBoard->GetStack((loc)(tab + (loc) i))->Bottom();
|
||||
|
||||
for (i = 0; i < TABLEAU; i++) {
|
||||
j = i % TAB_COUNT;
|
||||
|
||||
m_pSprite = new OSpr();
|
||||
if (pCard[j] == pCard[j]->m_pStack->Top()) {
|
||||
m_cCardSet[pCard[j]->GetValue()]->DuplicateSprite(pDC, (CSprite*) m_pSprite);
|
||||
m_pSprite->m_cCard = pCard[j];
|
||||
(*m_pSprite).LinkSprite();
|
||||
|
||||
pCard[j]->m_bIsBack = false;
|
||||
} else {
|
||||
m_cCardSet[m_nCardBack]->DuplicateSprite(pDC, (CSprite*) m_pSprite);
|
||||
m_pSprite->m_cCard = pCard[j];
|
||||
(*m_pSprite).LinkSprite();
|
||||
|
||||
pCard[j]->m_bIsBack = true;
|
||||
} // end if
|
||||
|
||||
pCard[j]->m_pSprite = m_pSprite;
|
||||
Stack(pDC, pCard[j], (int) i / TAB_COUNT);
|
||||
pCard[j] = pCard[j]->m_pNextCard; // Advance to next card
|
||||
} // end for
|
||||
|
||||
/************************************************************
|
||||
* used any random pCard index, didn't matter, so 0 is used. *
|
||||
************************************************************/
|
||||
pCard[0] = pBoard->GetStack(stock)->Bottom(); // Get first card in stack
|
||||
i = 0;
|
||||
while (pCard[0] != nullptr) {
|
||||
m_pSprite = new OSpr(); // set up visual sprite
|
||||
m_cCardSet[m_nCardBack]->DuplicateSprite(pDC, (CSprite*) m_pSprite);
|
||||
(*m_pSprite).LinkSprite();
|
||||
|
||||
m_pSprite->m_cCard = pCard[0]; // update internal card struct
|
||||
pCard[0]->m_pSprite = m_pSprite;
|
||||
pCard[0]->m_bIsBack = true;
|
||||
|
||||
Stack(pDC, pCard[0], i); // paint it on screen
|
||||
pCard[0] = pCard[0]->m_pNextCard; // Advance to next card
|
||||
i++;
|
||||
} // end while
|
||||
}
|
||||
|
||||
void CPaint::Refresh(CDC *pDC, CBoard *pBoard) {
|
||||
int i;
|
||||
int nCardPos; // card pos in stack
|
||||
CStack *pStack;
|
||||
CCard *pCard;
|
||||
CPoint cPos;
|
||||
|
||||
m_pSprite = (OSpr*) OSpr::GetSpriteChain();
|
||||
if (m_pSprite == nullptr) // any sprites to refresh?
|
||||
return; // no
|
||||
|
||||
OSpr::ClearBackgrounds();
|
||||
|
||||
pStack = pBoard->GetStack(fnd); // refresh foundation
|
||||
pCard = pStack->Bottom();
|
||||
nCardPos = 0;
|
||||
while (pCard != nullptr) {
|
||||
if (pCard->m_pSprite != nullptr) {
|
||||
pCard->m_pSprite->RefreshSprite(pDC);
|
||||
}
|
||||
pCard = pCard->m_pNextCard;
|
||||
nCardPos++;
|
||||
}
|
||||
|
||||
for (i = tab; i < stock; i++) { // refresh tableau
|
||||
pStack = pBoard->GetStack((loc) i);
|
||||
pCard = pStack->Bottom();
|
||||
nCardPos = 0;
|
||||
|
||||
while (pCard != nullptr) {
|
||||
if (pCard->m_pSprite != nullptr) {
|
||||
pCard->m_pSprite->RefreshSprite(pDC);
|
||||
}
|
||||
pCard = pCard->m_pNextCard;
|
||||
nCardPos++;
|
||||
} // end while
|
||||
} // end for
|
||||
|
||||
pStack = pBoard->GetStack(stock); // refresh stock top card only
|
||||
pCard = pStack->Bottom();
|
||||
nCardPos = 0;
|
||||
while (pCard != nullptr) {
|
||||
if (pCard->m_pSprite != nullptr) {
|
||||
pCard->m_pSprite->RefreshSprite(pDC);
|
||||
}
|
||||
pCard = pCard->m_pNextCard;
|
||||
nCardPos++;
|
||||
}
|
||||
|
||||
pStack = pBoard->GetStack(used); // refresh used stack
|
||||
pCard = pStack->Bottom();
|
||||
nCardPos = 0;
|
||||
while (pCard != nullptr) {
|
||||
if (pCard->m_pSprite != nullptr) {
|
||||
pCard->m_pSprite->RefreshSprite(pDC);
|
||||
}
|
||||
pCard = pCard->m_pNextCard;
|
||||
nCardPos++;
|
||||
}
|
||||
|
||||
(void)nCardPos; // avoid unused variable warning
|
||||
}
|
||||
|
||||
CCard *CPaint::IsOnCard(CPoint cPoint) {
|
||||
if ((m_pSprite = (OSpr *) m_pSprite->Touched(cPoint)) == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return m_pSprite->m_cCard->m_pStack->Top();
|
||||
}
|
||||
|
||||
void CPaint::MoveCard(CDC *pDC, CCard *pCard, CPoint point) {
|
||||
point.x -= pCard->m_pSprite->GetHotspot().x; // causes the point to appear in the
|
||||
point.y -= pCard->m_pSprite->GetHotspot().y; // center of the card.
|
||||
pCard->m_pSprite->PaintSprite(pDC, point);
|
||||
}
|
||||
|
||||
void CPaint::UpdateCard(CDC *pDC, CCard *pCard) {
|
||||
pCard->m_pSprite->PaintSprite(pDC, pCard->m_cOrigin); // paint card @ cur pos
|
||||
}
|
||||
|
||||
void CPaint::FlipCard(CDC *pDC, CCard *pCard) {
|
||||
/**********************************
|
||||
* Get rid of current card bitmap. *
|
||||
**********************************/
|
||||
pCard->m_pSprite->RefreshBackground(pDC); // ...repaint background
|
||||
pCard->m_pSprite->UnlinkSprite(); // unlink from refresh chain
|
||||
delete pCard->m_pSprite;
|
||||
|
||||
/******************************************************************
|
||||
* Reverse card. If it is a back, flip it forward, and vise versa. *
|
||||
******************************************************************/
|
||||
pCard->m_pSprite = new OSpr();
|
||||
if (pCard->m_bIsBack == true) {
|
||||
(*m_cCardSet[pCard->GetValue()]).DuplicateSprite(pDC, (CSprite*) pCard->m_pSprite);
|
||||
pCard->m_bIsBack = false;
|
||||
} else {
|
||||
(*m_cCardSet[m_nCardBack]).DuplicateSprite(pDC, (CSprite*) pCard->m_pSprite);
|
||||
pCard->m_bIsBack = true;
|
||||
}
|
||||
|
||||
pCard->m_pSprite->LinkSprite();
|
||||
pCard->m_pSprite->m_cCard = pCard; // update internal rep
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
*
|
||||
* Stack
|
||||
*
|
||||
* FUNCTIONAL DESCRIPTION:
|
||||
*
|
||||
* Indents top card properly relative to it's current stack.
|
||||
* Assigns pCard->m_cOrigin to correct position.
|
||||
*
|
||||
* FORMAL PARAMETERS:
|
||||
*
|
||||
* [Show arguments]
|
||||
*
|
||||
* IMPLICIT INPUT PARAMETERS:
|
||||
*
|
||||
* [External data read]
|
||||
*
|
||||
* IMPLICIT OUTPUT PARAMETERS:
|
||||
*
|
||||
* [External data modified]
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* [Discuss return value]
|
||||
*
|
||||
****************************************************************/
|
||||
void CPaint::Stack(CDC *pDC, CCard *pCard, int nSize) {
|
||||
int i;
|
||||
|
||||
if (pCard == nullptr)
|
||||
return;
|
||||
|
||||
if (nSize == -1) { // funct overloaded?
|
||||
i = pCard->m_pStack->Size() - 1;// no, use stack size info
|
||||
} else {
|
||||
i = nSize; // yes, use info from param
|
||||
}
|
||||
|
||||
switch (pCard->m_pStack->GetID()) { // Update card visual coordinates
|
||||
case fnd:
|
||||
case stock:
|
||||
pCard->m_cOrigin = pCard->m_pStack->m_cRect.TopLeft();
|
||||
pCard->m_cOrigin.x += ((int) i / STACK_INDENT) * STACK_DX;
|
||||
pCard->m_cOrigin.y += ((int) i / STACK_INDENT) * STACK_DY;
|
||||
break;
|
||||
|
||||
case used:
|
||||
if (pCard->m_pStack->Bottom() == pCard) // bottom card?
|
||||
m_nUsedInd = 0; // reset stack offset counter
|
||||
|
||||
pCard->m_cOrigin = pCard->m_pStack->m_cRect.TopLeft();
|
||||
pCard->m_cOrigin.x += ((int) m_nUsedInd % USED_INDENT) * USED_DX;
|
||||
pCard->m_cOrigin.y += ((int) m_nUsedInd % USED_INDENT) * USED_DY;
|
||||
|
||||
m_nUsedInd++;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (pCard->m_pPrevCard != nullptr) { // card face req pos?
|
||||
if (pCard->m_pPrevCard->m_bIsBack == false) {
|
||||
pCard->m_cOrigin.x = pCard->m_pPrevCard->m_cOrigin.x + STACK_FACE_DX;
|
||||
pCard->m_cOrigin.y = pCard->m_pPrevCard->m_cOrigin.y + STACK_FACE_DY;
|
||||
break;
|
||||
} // end if
|
||||
}
|
||||
|
||||
//
|
||||
// Card back requires positioning
|
||||
//
|
||||
pCard->m_cOrigin = pCard->m_pStack->m_cRect.TopLeft();
|
||||
pCard->m_cOrigin.x += ((int) i / TAB_INDENT) * TAB_DX;
|
||||
pCard->m_cOrigin.y += ((int) i / TAB_INDENT) * TAB_DY;
|
||||
break;
|
||||
}
|
||||
|
||||
pCard->m_pSprite->PaintSprite(pDC, pCard->m_cOrigin);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
*
|
||||
* IsNewBack
|
||||
*
|
||||
* FUNCTIONAL DESCRIPTION:
|
||||
*
|
||||
*
|
||||
* FORMAL PARAMETERS:
|
||||
*
|
||||
* [Show arguments]
|
||||
*
|
||||
* IMPLICIT INPUT PARAMETERS:
|
||||
*
|
||||
* [External data read]
|
||||
*
|
||||
* IMPLICIT OUTPUT PARAMETERS:
|
||||
*
|
||||
* [External data modified]
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* [Discuss return value]
|
||||
*
|
||||
****************************************************************/
|
||||
bool CPaint::IsNewBack(int nBack) {
|
||||
if (m_nCardBack == nBack) { // any change?
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
*
|
||||
* ChangeBack
|
||||
*
|
||||
* FUNCTIONAL DESCRIPTION:
|
||||
*
|
||||
*
|
||||
* FORMAL PARAMETERS:
|
||||
*
|
||||
* [Show arguments]
|
||||
*
|
||||
* IMPLICIT INPUT PARAMETERS:
|
||||
*
|
||||
* [External data read]
|
||||
*
|
||||
* IMPLICIT OUTPUT PARAMETERS:
|
||||
*
|
||||
* [External data modified]
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* [Discuss return value]
|
||||
*
|
||||
****************************************************************/
|
||||
void CPaint::ChangeBack(CDC *pDC, CBoard *pBoard, int nBack) {
|
||||
int i;
|
||||
CStack *pStack;
|
||||
CCard *pCard;
|
||||
|
||||
if (m_nCardBack == nBack) { // any change?
|
||||
return; // no - just return
|
||||
} else {
|
||||
m_nCardBack = nBack;
|
||||
}
|
||||
|
||||
for (i = fnd; i <= used; i++) { // refresh tableau
|
||||
pStack = pBoard->GetStack((loc) i);
|
||||
pCard = pStack->Bottom();
|
||||
|
||||
while (pCard != nullptr) {
|
||||
if (pCard->m_bIsBack == false) {
|
||||
pCard = pCard->m_pNextCard;
|
||||
continue;
|
||||
}
|
||||
|
||||
pCard->m_pSprite->UnlinkSprite(); // unlink from refresh chain
|
||||
delete pCard->m_pSprite;
|
||||
|
||||
pCard->m_pSprite = new OSpr();
|
||||
(*m_cCardSet[m_nCardBack]).DuplicateSprite(pDC, (CSprite*) pCard->m_pSprite);
|
||||
pCard->m_pSprite->LinkSprite();
|
||||
pCard->m_pSprite->SetPosition(pCard->m_cOrigin);
|
||||
pCard->m_pSprite->m_cCard = pCard; // update internal rep
|
||||
|
||||
pCard = pCard->m_pNextCard;
|
||||
} // end while
|
||||
} // end for
|
||||
}
|
||||
|
||||
} // namespace Barbershop
|
||||
} // namespace HodjNPodj
|
||||
} // namespace Bagel
|
||||
Reference in New Issue
Block a user