725 lines
17 KiB
C
725 lines
17 KiB
C
|
#include "sol.h"
|
||
|
VSZASSERT
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
VOID FreeGm(GM *pgm)
|
||
|
{
|
||
|
INT icol;
|
||
|
COL *pcol;
|
||
|
|
||
|
if(pgm != NULL)
|
||
|
{
|
||
|
for(icol = pgm->icolMac-1; icol >= 0; icol--)
|
||
|
if((pcol = pgm->rgpcol[icol]) != NULL)
|
||
|
SendColMsg(pcol, msgcEnd, 0, 0);
|
||
|
if(pgm == pgmCur)
|
||
|
pgmCur = NULL;
|
||
|
FreeUndo(&pgm->udr);
|
||
|
FreeP(pgm);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL FCreateDCBM(HDC hdc, HDC *phdc, HBITMAP *phbmOld, DY dyCol)
|
||
|
{
|
||
|
HDC hdcT;
|
||
|
HBITMAP hbm;
|
||
|
|
||
|
if((hdcT = CreateCompatibleDC(hdc)) == NULL)
|
||
|
return fFalse;
|
||
|
|
||
|
if((hbm = CreateCompatibleBitmap(hdc, dxCrd, dyCol)) == NULL)
|
||
|
{
|
||
|
Error:
|
||
|
DeleteDC(hdcT);
|
||
|
return fFalse;
|
||
|
}
|
||
|
|
||
|
if((*phbmOld = SelectObject(hdcT, hbm)) == NULL)
|
||
|
{
|
||
|
/* Delete the bitmap */
|
||
|
DeleteObject(hbm);
|
||
|
goto Error;
|
||
|
}
|
||
|
*phdc = hdcT;
|
||
|
|
||
|
return fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL FSetDrag(BOOL fOutline)
|
||
|
{
|
||
|
HDC hdc;
|
||
|
|
||
|
fOutlineDrag = fOutline;
|
||
|
|
||
|
if(fOutline && move.fHdc)
|
||
|
{
|
||
|
Assert(move.hdcScreenSave);
|
||
|
Assert(move.hdcCol);
|
||
|
Assert(move.hbmScreenSaveOld);
|
||
|
Assert(move.hbmColOld);
|
||
|
Assert(move.hdcT);
|
||
|
|
||
|
DeleteObject(SelectObject(move.hdcCol, move.hbmColOld));
|
||
|
DeleteDC(move.hdcCol);
|
||
|
|
||
|
DeleteObject(SelectObject(move.hdcScreenSave, move.hbmScreenSaveOld));
|
||
|
DeleteDC(move.hdcScreenSave);
|
||
|
|
||
|
DeleteObject(SelectObject(move.hdcT, move.hbmT));
|
||
|
DeleteDC(move.hdcT);
|
||
|
move.fHdc = fFalse;
|
||
|
}
|
||
|
|
||
|
|
||
|
if(!fOutline && !move.fHdc)
|
||
|
{
|
||
|
hdc = GetDC(hwndApp);
|
||
|
if(hdc == NULL)
|
||
|
{
|
||
|
OOM:
|
||
|
ErrorIds(idsNoFullDrag);
|
||
|
fOutlineDrag = fFalse;
|
||
|
move.fHdc = fFalse;
|
||
|
return fFalse;
|
||
|
}
|
||
|
|
||
|
move.hdcScreen = NULL;
|
||
|
|
||
|
if(!FCreateDCBM(hdc, &move.hdcScreenSave, &move.hbmScreenSaveOld, pgmCur->dyDragMax))
|
||
|
{
|
||
|
ReleaseDC(hwndApp,hdc);
|
||
|
goto OOM;
|
||
|
}
|
||
|
|
||
|
if(!FCreateDCBM(hdc, &move.hdcT, &move.hbmT, pgmCur->dyDragMax))
|
||
|
{
|
||
|
OOM1:
|
||
|
|
||
|
ReleaseDC(hwndApp,hdc);
|
||
|
DeleteObject(SelectObject(move.hdcScreenSave, move.hbmScreenSaveOld));
|
||
|
DeleteDC(move.hdcScreenSave);
|
||
|
goto OOM;
|
||
|
}
|
||
|
|
||
|
if(!FCreateDCBM(hdc, &move.hdcCol, &move.hbmColOld, pgmCur->dyDragMax))
|
||
|
{
|
||
|
DeleteObject(SelectObject(move.hdcT, move.hbmT));
|
||
|
DeleteDC(move.hdcT);
|
||
|
goto OOM1;
|
||
|
}
|
||
|
|
||
|
move.fHdc = fTrue;
|
||
|
ReleaseDC(hwndApp, hdc);
|
||
|
}
|
||
|
return fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
BOOL FInitGm()
|
||
|
{
|
||
|
BOOL FInitKlondGm();
|
||
|
|
||
|
return FInitKlondGm();
|
||
|
}
|
||
|
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
LRESULT SendGmMsg(GM *pgm, INT msgg, WPARAM wp1, LPARAM wp2)
|
||
|
{
|
||
|
INT imdbg;
|
||
|
LRESULT wResult;
|
||
|
|
||
|
Assert(pgm != NULL);
|
||
|
imdbg = ILogMsg(pgm, msgg, wp1, wp2, fTrue);
|
||
|
|
||
|
wResult =(*(pgm->lpfnGmProc))(pgm, msgg, wp1, wp2);
|
||
|
LogMsgResult(imdbg, wResult);
|
||
|
return wResult;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
BOOL DefGmInit(GM *pgm, BOOL fResetScore)
|
||
|
{
|
||
|
|
||
|
pgm->fDealt = fFalse;
|
||
|
if(fResetScore)
|
||
|
pgm->sco = 0;
|
||
|
pgm->iqsecScore = 0;
|
||
|
pgm->irep = 0;
|
||
|
pgm->icolHilight = pgm->icolSel = icolNil;
|
||
|
pgm->icolKbd = 0;
|
||
|
pgm->icrdKbd = 0;
|
||
|
pgm->fInput = fFalse;
|
||
|
pgm->fWon = fFalse;
|
||
|
pgm->ccrdDeal = ccrdDeal;
|
||
|
return fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
BOOL DefGmMouseDown(GM *pgm, PT *ppt, INT icolFirst)
|
||
|
{
|
||
|
INT icol;
|
||
|
|
||
|
/* sel already in effect */
|
||
|
if(FSelOfGm(pgm))
|
||
|
return fFalse;
|
||
|
if(!pgm->fDealt)
|
||
|
return fFalse;
|
||
|
pgm->fInput = fTrue;
|
||
|
pgm->fButtonDown = fTrue;
|
||
|
for(icol = icolFirst; icol < pgm->icolMac; icol++)
|
||
|
{
|
||
|
if(SendColMsg(pgm->rgpcol[icol], msgcHit, (INT_PTR) ppt, 0) != icrdNil)
|
||
|
{
|
||
|
pgm->icolSel = icol;
|
||
|
pgm->ptMousePrev = ptNil;
|
||
|
|
||
|
/* KLUDGE: in col render, we redraw the column after a selection
|
||
|
is made. if the mouse isn't moved, no image of the selected
|
||
|
card shows up.
|
||
|
*/
|
||
|
if(!fOutlineDrag)
|
||
|
{
|
||
|
/* SendGmMsg(pgm, msggMouseMove, (INT_PTR) ppt, 0); */
|
||
|
pgm->ptMousePrev = *ppt;
|
||
|
}
|
||
|
return fTrue;
|
||
|
}
|
||
|
}
|
||
|
return fFalse;
|
||
|
}
|
||
|
|
||
|
BOOL DefGmMouseUp(GM *pgm, PT *pptBogus, BOOL fNoMove)
|
||
|
{
|
||
|
COL *pcolSel, *pcolHilight;
|
||
|
BOOL fResult = fFalse;
|
||
|
|
||
|
pgm->fButtonDown = fFalse;
|
||
|
if(FSelOfGm(pgm))
|
||
|
{
|
||
|
pcolSel = pgm->rgpcol[pgm->icolSel];
|
||
|
if(FHilightOfGm(pgm))
|
||
|
{
|
||
|
pcolHilight = pgm->rgpcol[pgm->icolHilight];
|
||
|
SendGmMsg(pgm, msggSaveUndo, pgm->icolHilight, pgm->icolSel);
|
||
|
SendColMsg(pcolHilight, msgcDragInvert, 0, 0);
|
||
|
if(fNoMove)
|
||
|
{
|
||
|
SendColMsg(pcolSel, msgcMouseUp, (INT_PTR) &pgm->ptMousePrev, fTrue);
|
||
|
fResult = fTrue;
|
||
|
goto Return;
|
||
|
}
|
||
|
SendColMsg(pcolSel, msgcMouseUp, (INT_PTR) &pgm->ptMousePrev, fFalse);
|
||
|
fResult = SendColMsg(pcolHilight, msgcMove, (INT_PTR) pcolSel, icrdToEnd) &&
|
||
|
SendGmMsg(pgm, msggScore, (INT_PTR) pcolHilight, (INT_PTR) pcolSel);
|
||
|
pgm->icolHilight = icolNil;
|
||
|
if(SendGmMsg(pgm, msggIsWinner, 0, 0))
|
||
|
SendGmMsg(pgm, msggWinner, 0, 0);
|
||
|
}
|
||
|
else
|
||
|
SendColMsg(pcolSel, msgcMouseUp, (INT_PTR) &pgm->ptMousePrev, fTrue);
|
||
|
|
||
|
Return:
|
||
|
SendColMsg(pcolSel, msgcEndSel, fFalse, 0);
|
||
|
}
|
||
|
pgm->icolSel = icolNil;
|
||
|
return fResult;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
BOOL DefGmMouseDblClk(GM *pgm, PT * ppt)
|
||
|
{
|
||
|
INT icol;
|
||
|
|
||
|
for(icol = 0; icol < pgm->icolMac; icol++)
|
||
|
if(SendColMsg(pgm->rgpcol[icol], msgcDblClk, (INT_PTR) ppt, icol))
|
||
|
return fTrue;
|
||
|
return fFalse;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// This routine moves all the "playable" cards
|
||
|
// to the four suit stacks.
|
||
|
// It's invoked when the user right-clicks or
|
||
|
// presses Ctrl-A.
|
||
|
|
||
|
|
||
|
BOOL DefGmMouseRightClk(GM *pgm, PT * ppt)
|
||
|
{
|
||
|
INT icol;
|
||
|
CRD *pcrd;
|
||
|
INT icolDest;
|
||
|
COL *pcolDest;
|
||
|
BOOL fResult;
|
||
|
COL *pcol;
|
||
|
INT iContinue;
|
||
|
|
||
|
fResult = fFalse;
|
||
|
|
||
|
// Keep doing this as long as in every iteration
|
||
|
// we move one card to the suit stack.
|
||
|
do
|
||
|
{
|
||
|
iContinue = 0;
|
||
|
for(icol = 0; icol < pgm->icolMac; icol++)
|
||
|
{
|
||
|
// We don't want to move cards from one suit stack
|
||
|
// to another.
|
||
|
if (icol >= icolFoundFirst && icol < icolFoundFirst+ccolFound)
|
||
|
continue;
|
||
|
|
||
|
// Now the column we have is one of the 7 columns
|
||
|
// or the deck.
|
||
|
pcol = pgm->rgpcol[icol];
|
||
|
|
||
|
// If this column contains cards and the top one faces up
|
||
|
if(pcol->icrdMac > 0 && (pcrd=&pcol->rgcrd[pcol->icrdMac-1])->fUp)
|
||
|
{
|
||
|
if(pcol->pmove == NULL)
|
||
|
SendColMsg(pcol, msgcSel, icrdEnd, ccrdToEnd);
|
||
|
Assert(pcol->pmove != NULL);
|
||
|
|
||
|
// Check if it can be moved to any of the suit stacks.
|
||
|
for(icolDest = icolFoundFirst; icolDest < icolFoundFirst+ccolFound; icolDest++)
|
||
|
{
|
||
|
pcolDest = pgmCur->rgpcol[icolDest];
|
||
|
if(SendColMsg(pcolDest, msgcValidMove, (INT_PTR)pcol, 0))
|
||
|
{
|
||
|
SendGmMsg(pgmCur, msggSaveUndo, icolDest, icol);
|
||
|
fResult = SendColMsg(pcolDest, msgcMove, (INT_PTR) pcol, icrdToEnd) &&
|
||
|
(fOutlineDrag || SendColMsg(pcol, msgcRender, pcol->icrdMac-1, icrdToEnd)) &&
|
||
|
SendGmMsg(pgmCur, msggScore, (INT_PTR) pcolDest, (INT_PTR) pcol);
|
||
|
|
||
|
iContinue ++;
|
||
|
|
||
|
if(SendGmMsg(pgmCur, msggIsWinner, 0, 0))
|
||
|
SendGmMsg(pgmCur, msggWinner, 0, 0);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SendColMsg(pcol, msgcEndSel, fFalse, 0);
|
||
|
}
|
||
|
} while (iContinue > 0);
|
||
|
|
||
|
return fResult;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
BOOL DefGmMouseMove(GM *pgm, PT *ppt)
|
||
|
{
|
||
|
COL *pcol;
|
||
|
INT icol;
|
||
|
|
||
|
if(FSelOfGm(pgm))
|
||
|
{
|
||
|
Assert(pgm->icolSel < pgm->icolMac);
|
||
|
/* draw new outline */
|
||
|
pcol = pgm->rgpcol[pgm->icolSel];
|
||
|
SendColMsg(pcol, msgcDrawOutline, (INT_PTR) ppt, (INT_PTR) &pgm->ptMousePrev);
|
||
|
pgm->ptMousePrev = *ppt;
|
||
|
for(icol = 0; icol < pgm->icolMac; icol++)
|
||
|
if(SendColMsg(pgm->rgpcol[icol], msgcValidMovePt, (INT_PTR)pgm->rgpcol[pgm->icolSel], (INT_PTR) ppt) != icrdNil)
|
||
|
{
|
||
|
if(icol != pgm->icolHilight)
|
||
|
{
|
||
|
if(FHilightOfGm(pgm))
|
||
|
SendColMsg(pgm->rgpcol[pgm->icolHilight], msgcDragInvert, 0, 0);
|
||
|
pgm->icolHilight = icol;
|
||
|
return SendColMsg(pgm->rgpcol[icol], msgcDragInvert, 0, 0);
|
||
|
}
|
||
|
else
|
||
|
return fTrue;
|
||
|
}
|
||
|
/* nothing to hilight */
|
||
|
if(FHilightOfGm(pgm))
|
||
|
{
|
||
|
SendColMsg(pgm->rgpcol[pgm->icolHilight], msgcDragInvert, 0, 0);
|
||
|
pgm->icolHilight = icolNil;
|
||
|
return fTrue;
|
||
|
}
|
||
|
}
|
||
|
return fFalse;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL DefGmPaint(GM *pgm, PAINTSTRUCT *ppaint)
|
||
|
{
|
||
|
INT icol;
|
||
|
HDC hdc;
|
||
|
|
||
|
hdc = HdcSet(ppaint->hdc, 0, 0);
|
||
|
|
||
|
if(!pgm->fDealt)
|
||
|
goto Return;
|
||
|
for(icol = 0; icol < pgm->icolMac; icol++)
|
||
|
SendColMsg(pgm->rgpcol[icol], msgcPaint, (INT_PTR) ppaint, 0);
|
||
|
Return:
|
||
|
HdcSet(hdc, 0, 0);
|
||
|
return fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL DefGmUndo(GM *pgm)
|
||
|
{
|
||
|
UDR *pudr;
|
||
|
|
||
|
Assert(!FSelOfGm(pgm));
|
||
|
pudr = &pgm->udr;
|
||
|
if(!pudr->fAvail)
|
||
|
return fFalse;
|
||
|
Assert(pudr->icol1 != icolNil);
|
||
|
Assert(pudr->icol2 != icolNil);
|
||
|
|
||
|
Assert(pudr->icol1 < pgm->icolMax);
|
||
|
Assert(pudr->icol2 < pgm->icolMax);
|
||
|
|
||
|
pgm->sco = pudr->sco;
|
||
|
pgm->irep = pudr->irep;
|
||
|
|
||
|
SendGmMsg(pgm, msggChangeScore, 0, 0);
|
||
|
|
||
|
|
||
|
SendColMsg(pgm->rgpcol[pudr->icol1], msgcCopy, (INT_PTR) pudr->rgpcol[0], fTrue);
|
||
|
SendColMsg(pgm->rgpcol[pudr->icol2], msgcCopy, (INT_PTR) pudr->rgpcol[1], fTrue);
|
||
|
/* end any selectons if we had 'em */
|
||
|
SendColMsg(pgm->rgpcol[pudr->icol1], msgcEndSel, 0, 0);
|
||
|
SendColMsg(pgm->rgpcol[pudr->icol2], msgcEndSel, 0, 0);
|
||
|
|
||
|
SendGmMsg(pgm, msggKillUndo, 0, 0);
|
||
|
return fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* in future: may want to alloc columns */
|
||
|
BOOL DefGmSaveUndo(GM *pgm, INT icol1, INT icol2)
|
||
|
{
|
||
|
Assert(icol1 != icolNil);
|
||
|
Assert(icol2 != icolNil);
|
||
|
Assert(icol1 < pgm->icolMac);
|
||
|
Assert(icol2 < pgm->icolMac);
|
||
|
Assert(icol1 != icol2);
|
||
|
|
||
|
/* should use msgcCopy, but undo colcls's may not be set correctly */
|
||
|
bltb(pgm->rgpcol[icol1], pgm->udr.rgpcol[0], sizeof(COL)+(pgm->rgpcol[icol1]->icrdMac-1)*sizeof(CRD));
|
||
|
bltb(pgm->rgpcol[icol2], pgm->udr.rgpcol[1], sizeof(COL)+(pgm->rgpcol[icol2]->icrdMac-1)*sizeof(CRD));
|
||
|
pgm->udr.icol1 = icol1;
|
||
|
pgm->udr.icol2 = icol2;
|
||
|
pgm->udr.fAvail = fTrue;
|
||
|
pgm->udr.sco = pgm->sco;
|
||
|
pgm->udr.irep = pgm->irep;
|
||
|
|
||
|
if(pgm->udr.fEndDeck)
|
||
|
{
|
||
|
pgm->udr.fEndDeck = FALSE;
|
||
|
pgm->udr.irep--;
|
||
|
}
|
||
|
|
||
|
return fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
VOID DisplayKbdSel(GM *pgm)
|
||
|
{
|
||
|
HDC hdc;
|
||
|
TCHAR sz[20];
|
||
|
INT cch;
|
||
|
|
||
|
hdc = GetDC(hwndApp);
|
||
|
PszCopy(TEXT(" "), sz);
|
||
|
cch = CchDecodeInt(sz, pgm->icolKbd);
|
||
|
TextOut(hdc, 0, 10, sz, 5);
|
||
|
PszCopy(TEXT(" "), sz);
|
||
|
cch = CchDecodeInt(sz, pgm->icrdKbd);
|
||
|
TextOut(hdc, 0, 20, sz, 5);
|
||
|
PszCopy(TEXT(" "), sz);
|
||
|
cch = CchDecodeInt(sz, pgm->icolSel);
|
||
|
TextOut(hdc, 0, 30, sz, 5);
|
||
|
ReleaseDC(hwndApp, hdc);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
VOID NewKbdColAbs(GM *pgm, INT icol)
|
||
|
{
|
||
|
Assert(icol >= 0);
|
||
|
Assert(icol < pgm->icolMac);
|
||
|
|
||
|
if(!SendColMsg(pgm->rgpcol[icol], msgcValidKbdColSel, FSelOfGm(pgm), 0))
|
||
|
/* beep? */
|
||
|
return;
|
||
|
|
||
|
pgm->icolKbd = icol;
|
||
|
pgm->icrdKbd = SendColMsg(pgm->rgpcol[pgm->icolKbd], msgcNumCards, fFalse, 0)-1;
|
||
|
if(pgm->icrdKbd < 0)
|
||
|
pgm->icrdKbd = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID NewKbdCol(GM *pgm, INT dcol, BOOL fNextGroup)
|
||
|
{
|
||
|
INT icolNew;
|
||
|
|
||
|
icolNew = pgm->icolKbd;
|
||
|
if(icolNew == icolNil)
|
||
|
icolNew = 0;
|
||
|
if(dcol != 0)
|
||
|
{
|
||
|
do
|
||
|
{
|
||
|
icolNew += dcol;
|
||
|
if(icolNew < 0)
|
||
|
icolNew = pgm->icolMac-1;
|
||
|
else if(icolNew >= pgm->icolMac)
|
||
|
icolNew = 0;
|
||
|
|
||
|
/* only one col class and looped through all col's */
|
||
|
if(icolNew == pgm->icolKbd)
|
||
|
break;
|
||
|
}
|
||
|
while (!SendColMsg(pgm->rgpcol[icolNew], msgcValidKbdColSel, FSelOfGm(pgm), 0) ||
|
||
|
(fNextGroup &&
|
||
|
pgm->rgpcol[icolNew]->pcolcls->tcls ==
|
||
|
pgm->rgpcol[pgm->icolKbd]->pcolcls->tcls));
|
||
|
|
||
|
}
|
||
|
|
||
|
NewKbdColAbs(pgm, icolNew);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
VOID NewKbdCrd(GM *pgm, INT dcrd)
|
||
|
{
|
||
|
INT icrdUpMac, icrdMac;
|
||
|
INT icrdKbdNew;
|
||
|
|
||
|
icrdUpMac = SendColMsg(pgm->rgpcol[pgm->icolKbd], msgcNumCards, fTrue, 0);
|
||
|
icrdMac = SendColMsg(pgm->rgpcol[pgm->icolKbd], msgcNumCards, fFalse, 0);
|
||
|
|
||
|
if(icrdMac == 0)
|
||
|
icrdKbdNew = 0;
|
||
|
else
|
||
|
{
|
||
|
if(icrdUpMac == 0)
|
||
|
icrdKbdNew = icrdMac-1;
|
||
|
else
|
||
|
icrdKbdNew = PegRange(pgm->icrdKbd+dcrd, icrdMac-icrdUpMac, icrdMac-1);
|
||
|
}
|
||
|
if(SendColMsg(pgm->rgpcol[pgm->icolKbd], msgcValidKbdCrdSel, icrdKbdNew, 0))
|
||
|
pgm->icrdKbd = icrdKbdNew;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
BOOL DefGmKeyHit(GM *pgm, INT vk)
|
||
|
{
|
||
|
PT pt, ptCurs;
|
||
|
COLCLS *pcolcls;
|
||
|
|
||
|
/* cancel any mouse selections */
|
||
|
|
||
|
switch(vk)
|
||
|
{
|
||
|
case VK_SPACE:
|
||
|
case VK_RETURN:
|
||
|
if(!FSelOfGm(pgm))
|
||
|
{
|
||
|
/* begin a selection */
|
||
|
NewKbdCrd(pgm, 0); /* !!! */
|
||
|
SendColMsg(pgm->rgpcol[pgm->icolKbd], msgcGetPtInCrd, pgm->icrdKbd, (INT_PTR) &pt);
|
||
|
if(!SendGmMsg(pgm, msggMouseDown, (INT_PTR) &pt, 0))
|
||
|
return fFalse;
|
||
|
NewKbdCol(pgm, 0, fFalse);
|
||
|
goto Display;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* possibly make a move */
|
||
|
SendGmMsg(pgm, msggMouseUp, 0, fFalse);
|
||
|
NewKbdCol(pgm, 0, fFalse);
|
||
|
return fTrue;
|
||
|
}
|
||
|
|
||
|
case VK_ESCAPE:
|
||
|
SendGmMsg(pgm, msggMouseUp, 0, fTrue);
|
||
|
return fTrue;
|
||
|
|
||
|
case VK_A:
|
||
|
if (GetKeyState(VK_CONTROL) < 0)
|
||
|
SendGmMsg(pgm, msggMouseRightClk, 0, fTrue);
|
||
|
return fTrue;
|
||
|
|
||
|
case VK_LEFT:
|
||
|
/* Should these be VK_CONTROL??? */
|
||
|
NewKbdCol(pgm, -1, GetKeyState(VK_SHIFT) < 0);
|
||
|
goto Display;
|
||
|
|
||
|
case VK_RIGHT:
|
||
|
NewKbdCol(pgm, 1, GetKeyState(VK_SHIFT) < 0);
|
||
|
goto Display;
|
||
|
|
||
|
case VK_UP:
|
||
|
NewKbdCrd(pgm, -1);
|
||
|
goto Display;
|
||
|
|
||
|
case VK_DOWN:
|
||
|
NewKbdCrd(pgm, 1);
|
||
|
goto Display;
|
||
|
|
||
|
case VK_HOME:
|
||
|
NewKbdColAbs(pgm, 0);
|
||
|
goto Display;
|
||
|
|
||
|
case VK_END:
|
||
|
NewKbdColAbs(pgm, pgm->icolMac-1);
|
||
|
goto Display;
|
||
|
|
||
|
case VK_TAB:
|
||
|
NewKbdCol(pgm, GetKeyState(VK_SHIFT) < 0 ? -1 : 1, fTrue);
|
||
|
Display:
|
||
|
SendColMsg(pgm->rgpcol[pgm->icolKbd], msgcGetPtInCrd, pgm->icrdKbd, (INT_PTR) &pt);
|
||
|
ptCurs = pt;
|
||
|
ClientToScreen(hwndApp, (LPPOINT) &ptCurs);
|
||
|
if(FSelOfGm(pgm))
|
||
|
{
|
||
|
if(SendColMsg(pgm->rgpcol[pgm->icolKbd], msgcNumCards, fFalse, 0) > 0)
|
||
|
{
|
||
|
pcolcls = pgm->rgpcol[pgm->icolKbd]->pcolcls;
|
||
|
ptCurs.y += pcolcls->dyUp;
|
||
|
/* dxUp ? */
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* SetCursorPos will cause WM_MOUSEMOVE to be sent */
|
||
|
SetCursorPos(ptCurs.x, ptCurs.y);
|
||
|
return fTrue;
|
||
|
}
|
||
|
return fFalse;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
BOOL DefGmChangeScore(GM *pgm, INT cs, INT sco)
|
||
|
{
|
||
|
|
||
|
if(smd == smdNone)
|
||
|
return fTrue;
|
||
|
switch(cs)
|
||
|
{
|
||
|
default:
|
||
|
return fTrue;
|
||
|
case csAbs:
|
||
|
pgm->sco = sco;
|
||
|
break;
|
||
|
case csDel:
|
||
|
pgm->sco += sco;
|
||
|
break;
|
||
|
case csDelPos:
|
||
|
pgm->sco = WMax(pgm->sco+sco, 0);
|
||
|
break;
|
||
|
}
|
||
|
StatUpdate();
|
||
|
|
||
|
return fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL DefGmWinner(GM *pgm)
|
||
|
{
|
||
|
pgm->fWon = fFalse;
|
||
|
if(FYesNoAlert(idsDealAgain))
|
||
|
PostMessage(hwndApp, WM_COMMAND, idsInitiate, 0L);
|
||
|
return fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
INT DefGmProc(GM *pgm, INT msgg, WPARAM wp1, LPARAM wp2)
|
||
|
{
|
||
|
|
||
|
switch(msgg)
|
||
|
{
|
||
|
case msggInit:
|
||
|
return DefGmInit(pgm, (BOOL)wp1);
|
||
|
case msggEnd:
|
||
|
FreeGm(pgm);
|
||
|
break;
|
||
|
|
||
|
case msggKeyHit:
|
||
|
return DefGmKeyHit(pgm, (INT)wp1);
|
||
|
|
||
|
case msggMouseRightClk:
|
||
|
return DefGmMouseRightClk(pgm, (PT *)wp1);
|
||
|
|
||
|
case msggMouseDown: /* wp1 == ppt, wp2 = icolFirst (normally 0) */
|
||
|
return DefGmMouseDown(pgm, (PT *)wp1, (INT)wp2);
|
||
|
|
||
|
case msggMouseUp:
|
||
|
return DefGmMouseUp(pgm, (PT *)wp1, (BOOL)wp2);
|
||
|
|
||
|
case msggMouseMove:
|
||
|
return DefGmMouseMove(pgm, (PT *)wp1);
|
||
|
|
||
|
case msggMouseDblClk:
|
||
|
return DefGmMouseDblClk(pgm, (PT *)wp1);
|
||
|
|
||
|
case msggPaint:
|
||
|
return DefGmPaint(pgm, (PAINTSTRUCT *)wp1);
|
||
|
|
||
|
case msggDeal:
|
||
|
Assert(fFalse);
|
||
|
break;
|
||
|
|
||
|
case msggUndo:
|
||
|
return DefGmUndo(pgm);
|
||
|
|
||
|
case msggSaveUndo:
|
||
|
|
||
|
return DefGmSaveUndo(pgm, (INT)wp1, (INT)wp2);
|
||
|
|
||
|
case msggKillUndo:
|
||
|
/* in future may want to free columns */
|
||
|
pgm->udr.fAvail = fFalse;
|
||
|
break;
|
||
|
case msggIsWinner:
|
||
|
return fFalse;
|
||
|
case msggWinner:
|
||
|
return DefGmWinner(pgm);
|
||
|
case msggForceWin:
|
||
|
NYI();
|
||
|
break;
|
||
|
case msggTimer:
|
||
|
return fFalse;
|
||
|
case msggScore:
|
||
|
return fTrue;
|
||
|
case msggChangeScore:
|
||
|
return DefGmChangeScore(pgm, (INT)wp1, (INT)wp2);
|
||
|
|
||
|
}
|
||
|
|
||
|
return fFalse;
|
||
|
}
|
||
|
|