444 lines
8.6 KiB
C
444 lines
8.6 KiB
C
|
#include "sol.h"
|
||
|
VSZASSERT
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
VOID *PAlloc(INT cb)
|
||
|
{
|
||
|
TCHAR *p;
|
||
|
|
||
|
// KLUDGE: solve overwriting memory by allocating more
|
||
|
#define MEMORYPAD 200
|
||
|
p = (TCHAR *)LocalAlloc(LPTR, cb+MEMORYPAD);
|
||
|
Assert(p != NULL);
|
||
|
return (VOID *)p;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID FreeP(VOID *p)
|
||
|
{
|
||
|
LocalFree((HANDLE) p);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
VOID InvertRc(RC *prc)
|
||
|
{
|
||
|
Assert(xOrgCur == 0);
|
||
|
Assert(yOrgCur == 0);
|
||
|
AssertHdcCur();
|
||
|
|
||
|
InvertRect(hdcCur, (LPRECT) prc);
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID DrawCard(CRD *pcrd)
|
||
|
{
|
||
|
AssertHdcCur();
|
||
|
cdtDrawExt( hdcCur,
|
||
|
pcrd->pt.x-xOrgCur,
|
||
|
pcrd->pt.y-yOrgCur,
|
||
|
dxCrd,
|
||
|
dyCrd,
|
||
|
pcrd->fUp ? pcrd->cd : modeFaceDown,
|
||
|
pcrd->fUp ? FACEUP : FACEDOWN,
|
||
|
rgbTable);
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID DrawOutline(PT *ppt, INT ccrd, DX dx, DY dy)
|
||
|
{
|
||
|
Y y;
|
||
|
PT pt;
|
||
|
INT rop2;
|
||
|
if(!FGetHdc())
|
||
|
return;
|
||
|
|
||
|
pt = *ppt;
|
||
|
|
||
|
rop2 = SetROP2(hdcCur, R2_NOT);
|
||
|
MMoveTo(hdcCur, pt.x, pt.y);
|
||
|
LineTo(hdcCur, pt.x+dxCrd, pt.y);
|
||
|
LineTo(hdcCur, pt.x+dxCrd, y = pt.y+dyCrd+(ccrd-1) * dy);
|
||
|
LineTo(hdcCur, pt.x, y);
|
||
|
LineTo(hdcCur, pt.x, pt.y);
|
||
|
y = pt.y;
|
||
|
while(--ccrd)
|
||
|
{
|
||
|
y += dy;
|
||
|
MMoveTo(hdcCur, pt.x, y);
|
||
|
LineTo(hdcCur, pt.x+dxCrd, y);
|
||
|
}
|
||
|
SetROP2(hdcCur, rop2);
|
||
|
ReleaseHdc();
|
||
|
}
|
||
|
|
||
|
VOID DrawCardPt(CRD *pcrd, PT *ppt)
|
||
|
{
|
||
|
DWORD dwModeExt=0; // turn on sign bit if moving fast
|
||
|
// cdtDrawExt must support this!
|
||
|
|
||
|
if( fKlondWinner )
|
||
|
{
|
||
|
dwModeExt= MINLONG;
|
||
|
}
|
||
|
|
||
|
AssertHdcCur();
|
||
|
cdtDrawExt(hdcCur,
|
||
|
ppt->x-xOrgCur,
|
||
|
ppt->y-yOrgCur,
|
||
|
dxCrd,
|
||
|
dyCrd,
|
||
|
pcrd->fUp ? pcrd->cd : modeFaceDown,
|
||
|
(pcrd->fUp ? FACEUP : FACEDOWN ) | dwModeExt,
|
||
|
rgbTable);
|
||
|
}
|
||
|
|
||
|
VOID DrawCardExt(PT *ppt, INT cd, INT mode)
|
||
|
{
|
||
|
VOID DrawBackground();
|
||
|
|
||
|
AssertHdcCur();
|
||
|
|
||
|
cdtDrawExt( hdcCur,
|
||
|
ppt->x-xOrgCur,
|
||
|
ppt->y-yOrgCur,
|
||
|
dxCrd,
|
||
|
dyCrd,
|
||
|
cd,
|
||
|
mode,
|
||
|
rgbTable);
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID DrawBackground(X xLeft, Y yTop, X xRight, Y yBot)
|
||
|
{
|
||
|
HBRUSH hbr;
|
||
|
|
||
|
|
||
|
AssertHdcCur();
|
||
|
MSetBrushOrg(hdcCur, xOrgCur, yOrgCur);
|
||
|
MUnrealizeObject(hbrTable);
|
||
|
if((hbr = SelectObject(hdcCur, hbrTable)) != NULL)
|
||
|
{
|
||
|
Assert(xRight >= xLeft);
|
||
|
Assert(yBot >= yTop);
|
||
|
PatBlt( hdcCur,
|
||
|
xLeft-xOrgCur,
|
||
|
yTop-yOrgCur,
|
||
|
xRight-xLeft,
|
||
|
yBot-yTop,
|
||
|
PATCOPY);
|
||
|
SelectObject(hdcCur, hbr);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID EraseScreen(VOID)
|
||
|
{
|
||
|
RC rc;
|
||
|
HDC HdcSet();
|
||
|
|
||
|
if(!FGetHdc())
|
||
|
return;
|
||
|
GetClientRect(hwndApp, (LPRECT) &rc);
|
||
|
DrawBackground(rc.xLeft, rc.yTop, rc.xRight, rc.yBot);
|
||
|
ReleaseHdc();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
BOOL FPtInCrd(CRD *pcrd, PT pt)
|
||
|
{
|
||
|
|
||
|
return(pt.x >= pcrd->pt.x && pt.x < pcrd->pt.x+dxCrd &&
|
||
|
pt.y >= pcrd->pt.y && pt.y < pcrd->pt.y+dyCrd);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
BOOL FRectIsect(RC *prc1, RC *prc2)
|
||
|
{
|
||
|
RC rcDummy;
|
||
|
|
||
|
return(IntersectRect((LPRECT) &rcDummy, (LPRECT) prc1, (LPRECT) prc2));
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID CrdRcFromPt(PT *ppt, RC *prc)
|
||
|
{
|
||
|
prc->xRight = (prc->xLeft = ppt->x) + dxCrd;
|
||
|
prc->yBot = (prc->yTop = ppt->y) + dyCrd;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL FCrdRectIsect(CRD *pcrd, RC *prc)
|
||
|
{
|
||
|
RC rcDummy;
|
||
|
RC rcCrd;
|
||
|
|
||
|
CrdRcFromPt(&pcrd->pt, &rcCrd);
|
||
|
return(IntersectRect((LPRECT) &rcDummy, (LPRECT) &rcCrd, (LPRECT) prc));
|
||
|
}
|
||
|
|
||
|
/* BUG: only considers upper left and lower right corners */
|
||
|
/* this is ok for my purposes now, but beware... */
|
||
|
BOOL FRectAllVisible(HDC hdc, RC *prc)
|
||
|
{
|
||
|
return PtVisible(hdc, prc->xLeft, prc->yTop) && PtVisible(hdc, prc->xRight, prc->yBot);
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID OffsetPt(PT *ppt, DEL *pdel, PT *pptDest)
|
||
|
{
|
||
|
pptDest->x = ppt->x + pdel->dx;
|
||
|
pptDest->y = ppt->y + pdel->dy;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID SwapCards(CRD *pcrd1, CRD *pcrd2)
|
||
|
{
|
||
|
CRD crdT;
|
||
|
|
||
|
crdT = *pcrd1;
|
||
|
*pcrd1 = *pcrd2;
|
||
|
*pcrd2 = crdT;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
TCHAR *PszCopy(TCHAR *pszFrom, TCHAR *rgchTo)
|
||
|
{
|
||
|
while (*rgchTo++ = *pszFrom++)
|
||
|
;
|
||
|
return(rgchTo-1);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
INT CchDecodeInt(TCHAR *rgch, INT_PTR w)
|
||
|
{
|
||
|
INT fNeg;
|
||
|
TCHAR *pch, *pchT;
|
||
|
TCHAR rgchT[20];
|
||
|
|
||
|
if (fNeg = w<0)
|
||
|
w = -w;
|
||
|
|
||
|
pchT = rgchT;
|
||
|
do
|
||
|
{
|
||
|
*pchT++ = (TCHAR)(TEXT('0') + (TCHAR) (w % 10));
|
||
|
w /= 10;
|
||
|
}
|
||
|
while (w);
|
||
|
pch = rgch;
|
||
|
if (fNeg)
|
||
|
*pch++ = TEXT('-');
|
||
|
do
|
||
|
*pch++ = *--pchT;
|
||
|
while (pchT > rgchT);
|
||
|
*pch = TEXT('\000');
|
||
|
return((INT)(pch - rgch));
|
||
|
}
|
||
|
|
||
|
VOID Error(TCHAR *sz)
|
||
|
{
|
||
|
|
||
|
MessageBox(hwndApp, (LPTSTR)sz, (LPTSTR)szAppName, MB_OK|MB_ICONEXCLAMATION);
|
||
|
}
|
||
|
|
||
|
/* returns fTrue if yes is clicked */
|
||
|
BOOL FYesNoAlert( INT ids )
|
||
|
{
|
||
|
TCHAR sz[128];
|
||
|
INT id;
|
||
|
|
||
|
CchString(sz, ids, ARRAYSIZE(sz));
|
||
|
id = MessageBox(hwndApp, sz, szAppName, MB_YESNO|MB_ICONEXCLAMATION);
|
||
|
return id == IDYES || id == IDOK;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID ErrorIds(INT ids)
|
||
|
{
|
||
|
TCHAR sz[128];
|
||
|
|
||
|
CchString(sz, ids, ARRAYSIZE(sz));
|
||
|
Error(sz);
|
||
|
}
|
||
|
|
||
|
INT WMin(INT w1, INT w2)
|
||
|
{
|
||
|
return(w1 < w2 ? w1 : w2);
|
||
|
}
|
||
|
|
||
|
|
||
|
INT WMax(INT w1, INT w2)
|
||
|
{
|
||
|
return(w1 > w2 ? w1 : w2);
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL FInRange(INT w, INT wFirst, INT wLast)
|
||
|
{
|
||
|
Assert(wFirst <= wLast);
|
||
|
return(w >= wFirst && w <= wLast);
|
||
|
}
|
||
|
|
||
|
|
||
|
INT PegRange(INT w, INT wFirst, INT wLast)
|
||
|
{
|
||
|
Assert(wFirst <= wLast);
|
||
|
if(w < wFirst)
|
||
|
return wFirst;
|
||
|
else if(w > wLast)
|
||
|
return wLast;
|
||
|
else
|
||
|
return w;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID OOM()
|
||
|
{
|
||
|
Error(szOOM);
|
||
|
}
|
||
|
|
||
|
VOID NYI()
|
||
|
{
|
||
|
Error(TEXT("Not Yet Implemented"));
|
||
|
}
|
||
|
|
||
|
INT CchString(TCHAR *sz, INT ids, UINT cchBuf)
|
||
|
{
|
||
|
return LoadString(hinstApp, (WORD)ids, (LPTSTR)sz, cchBuf);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
BOOL FWriteIniString(INT idsTopic, INT idsItem, TCHAR *szValue)
|
||
|
{
|
||
|
TCHAR szItem[32];
|
||
|
HKEY hKey; // key to our registry root
|
||
|
LONG lStatus; // status from RegCreateKey
|
||
|
INT iLen;
|
||
|
BOOL fRet = FALSE;
|
||
|
|
||
|
// create the key
|
||
|
lStatus = RegCreateKeyEx(HKEY_CURRENT_USER, SOLKEYNAME, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL);
|
||
|
if(lStatus != ERROR_SUCCESS)
|
||
|
{
|
||
|
return FALSE; // just return quietly
|
||
|
}
|
||
|
|
||
|
CchString(szItem, idsItem, ARRAYSIZE(szItem));
|
||
|
iLen = (lstrlen(szValue)+1) * sizeof(TCHAR);
|
||
|
|
||
|
// write the key and value to the registry
|
||
|
if (RegSetValueEx(hKey, szItem, 0, REG_SZ, (BYTE*)szValue, iLen) == ERROR_SUCCESS)
|
||
|
fRet = TRUE;
|
||
|
else
|
||
|
fRet = FALSE;
|
||
|
|
||
|
RegCloseKey(hKey);
|
||
|
return fRet;
|
||
|
}
|
||
|
|
||
|
BOOL FWriteIniInt(INT idsTopic, INT idsItem, DWORD w)
|
||
|
{
|
||
|
TCHAR szItem[32];
|
||
|
HKEY hKey; // key to our registry root
|
||
|
LONG lStatus; // status from RegCreateKey
|
||
|
BOOL fRet = FALSE;
|
||
|
|
||
|
// create the key
|
||
|
lStatus = RegCreateKeyEx(HKEY_CURRENT_USER, SOLKEYNAME, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL);
|
||
|
if(lStatus != ERROR_SUCCESS)
|
||
|
{
|
||
|
return FALSE; // just return quietly
|
||
|
}
|
||
|
|
||
|
CchString(szItem, idsItem, ARRAYSIZE(szItem));
|
||
|
|
||
|
// write the key and value to the registry
|
||
|
if (RegSetValueEx(hKey, szItem, 0, REG_DWORD, (BYTE*) &w, sizeof(DWORD)) == ERROR_SUCCESS)
|
||
|
fRet = TRUE;
|
||
|
else
|
||
|
fRet = FALSE;
|
||
|
|
||
|
RegCloseKey(hKey);
|
||
|
return fRet;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL FGetIniString(INT idsTopic, INT idsItem, TCHAR *sz, TCHAR *szDefault, INT cchMax)
|
||
|
{
|
||
|
TCHAR szItem[32];
|
||
|
HKEY hKey; // key to our registry root
|
||
|
LONG lStatus;
|
||
|
DWORD dwType;
|
||
|
|
||
|
// open the key
|
||
|
lStatus = RegCreateKeyEx(HKEY_CURRENT_USER, SOLKEYNAME, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL);
|
||
|
if(lStatus != ERROR_SUCCESS)
|
||
|
{
|
||
|
CopyMemory(sz, szDefault, min(cchMax, lstrlen(szDefault)+1));
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
CchString(szItem, idsItem, ARRAYSIZE(szItem));
|
||
|
|
||
|
if(hKey)
|
||
|
{
|
||
|
lStatus= RegQueryValueEx(hKey, szItem, NULL, &dwType, (BYTE*) szDefault, &cchMax);
|
||
|
RegCloseKey(hKey);
|
||
|
|
||
|
if(lStatus != ERROR_SUCCESS || dwType != REG_SZ)
|
||
|
{
|
||
|
CopyMemory(sz, szDefault, min(cchMax, lstrlen(szDefault)+1));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD GetIniInt(INT idsTopic, INT idsItem, DWORD wDefault)
|
||
|
{
|
||
|
TCHAR szItem[32];
|
||
|
HKEY hKey; // key to our registry root
|
||
|
LONG lStatus;
|
||
|
DWORD dwResult = wDefault;
|
||
|
DWORD dwSize = sizeof(DWORD);
|
||
|
DWORD dwType = 0;
|
||
|
|
||
|
lStatus = RegCreateKeyEx(HKEY_CURRENT_USER, SOLKEYNAME, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL);
|
||
|
if(lStatus != ERROR_SUCCESS)
|
||
|
{
|
||
|
return wDefault;
|
||
|
}
|
||
|
|
||
|
CchString(szItem, idsItem, ARRAYSIZE(szItem));
|
||
|
|
||
|
if(hKey)
|
||
|
{
|
||
|
lStatus = RegQueryValueEx(hKey, szItem, NULL, &dwType, (BYTE*) &dwResult, &dwSize);
|
||
|
RegCloseKey(hKey);
|
||
|
|
||
|
if(lStatus != ERROR_SUCCESS || dwType != REG_DWORD)
|
||
|
{
|
||
|
dwResult = wDefault;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(dwResult);
|
||
|
|
||
|
}
|