windows-nt/Source/XPSP1/NT/shell/osshell/ep/tictac/tictac.c
2020-09-26 16:20:57 +08:00

579 lines
9.7 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/****************************************************************************
PROGRAM: 3-D TicTacToe (a.k.a. Qubic, TicTactics)
****************************************************************************/
#define _WINDOWS
#include <windows.h>
#include <port1632.h>
#include "main.h"
#include "rtns.h"
#include "grafix.h"
#include "util.h"
#include "res.h"
#include "pref.h"
#include "sound.h"
#include "string.h"
#include "context.h"
#include "dos.h"
HANDLE hInst;
HWND hwndMain;
HMENU hMenu;
STATUS status = fstatusIcon;
BOOL fEGA;
extern fUpdateIni;
BOOL fButton1Down = fFalse;
extern BLK rgBlk[cBlkMax];
INT dxpWindow;
INT dypWindow;
INT dypCaption;
INT dypMenu;
INT dypAdjust;
INT dypBorder;
INT dxpBorder;
INT dxpGridOff;
INT dyBlkPlane;
INT dypPlane;
INT dxpPlane;
INT dxpGrid;
INT dypGrid;
BLK blkCurr;
CHAR szClass[cchNameMax];
#define szWindowTitle szClass
extern INT cBlkRow;
extern INT cBlkPlane;
extern INT cBlkMac;
extern INT cPlane;
extern BOOL f4;
extern PREF Preferences;
extern BOOL fUpdateIni;
/****** W I N M A I N ******/
MMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
/* { */
MSG msg;
HANDLE hAccel;
hInst = hInstance;
InitConst();
if (hPrevInstance)
{
HWND hwnd = FindWindow(szClass, NULL);
hwnd = GetLastActivePopup(hwnd);
BringWindowToTop(hwnd);
if (IsIconic(hwnd))
ShowWindow(hwnd, SW_RESTORE);
return fFalse;
}
#ifdef NOSERVER /* Not in final version */
{
CHAR szFile[256];
GetModuleFileName(hInst, szFile, 250);
if (szFile[0] > 'C')
{
szFile[0] = 'X';
if (!strcmp(szFile, "X:\\WINGAMES\\TICTACTO\\TIC.EXE"))
{
MessageBox(GetFocus(),
"Please copy tic.exe and aboutwep.dll to your machine and run it from there.",
"NO NO NO NO NO",
MB_OK);
return fFalse;
}
}
}
#endif
#ifdef EXPIRE /*** Not in final release ***/
{
struct dosdate_t ddt;
_dos_getdate(&ddt);
if ((ddt.month + ddt.year*12) > (10 + 1990*12))
{
MessageBox(GetFocus(),
"This game has expired. Please obtain an official copy from the Windows Entertainment Package.",
"SORRY",
MB_OK);
return fFalse;
}
}
#endif
{
WNDCLASS wc;
wc.style = 0;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(ID_ICON_TIC2));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szClass;
if (!RegisterClass(&wc))
return fFalse;
}
hMenu = LoadMenu(hInst, MAKEINTRESOURCE(ID_MENU));
hAccel = LoadAccelerators(hInst, MAKEINTRESOURCE(ID_MENU_ACCEL));
ReadPreferences();
AdjustWindow(fCalc);
hwndMain = CreateWindow(szClass, szWindowTitle,
WS_OVERLAPPED | WS_MINIMIZE | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU,
Preferences.xWindow-dxpBorder, Preferences.yWindow-dypAdjust,
dxpWindow+dxpBorder, dypWindow+dypAdjust,
NULL, NULL, hInst, NULL);
if (!hwndMain)
{
ReportErr(1000);
return (fFalse);
}
if (SetTimer(hwndMain, ID_TIME_FLASH, 500 , NULL) == 0)
{
ReportErr(ID_ERR_TIMER);
return fFalse;
}
if (!FInitLocal())
{
ReportErr(ID_ERR_MEM);
return fFalse;
}
SetMenuBar(Preferences.fMenu);
ShowWindow(hwndMain, SW_SHOWNORMAL);
UpdateWindow(hwndMain);
StartGame();
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(hwndMain, hAccel, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
CleanUp();
if (fUpdateIni)
WritePreferences();
return (INT)(msg.wParam);
}
/****** B L K F R O M X Y ******/
/* Rewrite ! - just one return */
BLK BlkFromXY(INT x, INT y)
{
BLK blk = 0;
if (((x-=dxpGridOff) >= 0) &&
(x < dxpGrid) &&
((y-=(dypGridOff+dyBlkDiff-2)) >= 0) &&
(y < dypGrid) )
{
while (y >= dyBlkPlane)
{
if ((y -= (dyLevel+dypPlane)) < 0)
return iBlkNil; /* No allow hits between levels */
blk++;
}
x -= (dyBlkPlane-y);
if ((x >= 0) && (x < (cBlkRow*(dxBlk-1))) )
return (blk*cBlkPlane + cBlkRow*(y/dyBlk) + (x/(dxBlk-1)) );
}
return iBlkNil;
}
/****** F V A L I D M O V E ******/
BOOL FValidMove(BLK blk)
{
if (blk != iBlkNil)
if (rgBlk[blk] == iBallBlank)
return fTrue;
return fFalse;
}
/****** F I X M E N U S ******/
VOID FixMenus(VOID)
{
CheckEm(IDM_3x3, Preferences.iGameType == iGame3x3);
CheckEm(IDM_3x3x3, Preferences.iGameType == iGame3x3x3);
CheckEm(IDM_4x4x4, Preferences.iGameType == iGame4x4x4);
#ifdef NOISEY
CheckEm(IDM_SOUND, Preferences.fSound);
#endif
CheckEm(IDM_COLOR, Preferences.fColor);
CheckEm(IDM_RND, Preferences.iStart == iStartRnd);
CheckEm(IDM_RED, Preferences.iStart == iStartRed);
CheckEm(IDM_BLUE, Preferences.iStart == iStartBlue);
CheckEm(IDM_BEGIN, Preferences.skill == skillBegin);
CheckEm(IDM_INTER, Preferences.skill == skillInter);
CheckEm(IDM_EXPERT, Preferences.skill == skillExpert);
}
/****** M A I N W N D P R O C ******/
LRESULT APIENTRY MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SYSCOMMAND:
switch (wParam & 0xFFF0)
{
case SC_MINIMIZE:
SetStatusPause();
SetStatusIcon();
break;
case SC_RESTORE:
ClrStatusPause();
ClrStatusIcon();
break;
default:
break;
}
break;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
/** GAME **/
case IDM_NEW:
StartGame();
break;
case IDM_3x3:
case IDM_3x3x3:
case IDM_4x4x4:
Preferences.iGameType = GET_WM_COMMAND_ID(wParam, lParam) - IDM_3x3;
AdjustWindow(fCalc | fResize);
StartGame();
goto LUpdateMenu;
case IDM_EXIT:
ShowWindow(hwndMain, SW_HIDE);
#ifdef ORGCODE
goto LExit;
#else
SendMessage(hwndMain, WM_SYSCOMMAND, SC_CLOSE, 0);
return(0);
#endif
/** SKILL **/
case IDM_BEGIN:
Preferences.skill = skillBegin;
goto LUpdateMenu;
case IDM_INTER:
Preferences.skill = skillInter;
goto LUpdateMenu;
case IDM_EXPERT:
Preferences.skill = skillExpert;
goto LUpdateMenu;
/** OPTIONS **/
#ifdef NOISEY
case IDM_SOUND:
if (Preferences.fSound)
{
EndTunes();
Preferences.fSound = fFalse;
}
else
{
Preferences.fSound = FInitTunes();
}
goto LUpdateMenu;
#endif
case IDM_COLOR:
Preferences.fColor = !Preferences.fColor;
GetTheBitmap();
ReDoDisplay();
DisplayScreen();
goto LUpdateMenu;
case IDM_RND:
case IDM_RED:
case IDM_BLUE:
Preferences.iStart = GET_WM_COMMAND_ID(wParam, lParam) - IDM_RND;
StartGame();
/* IE goto LUpdateMenu; */
LUpdateMenu:
fUpdateIni = fTrue;
FixMenus();
break;
/** HELP **/
case IDM_INDEX:
DoHelp(HELP_INDEX, 0L);
break;
case IDM_HOW2PLAY:
DoHelp(HELP_CONTEXT, HLP_HOWTOPLAY);
break;
case IDM_COMMANDS:
DoHelp(HELP_CONTEXT, HLP_COMMANDS);
break;
case IDM_HELP_HELP:
DoHelp(HELP_HELPONHELP, 0L);
break;
case IDM_HELP_ABOUT:
DoAbout();
return 0;
default:
break;
}
case WM_KEYDOWN:
switch (wParam)
{
case VK_ESCAPE:
PostMessage(hwndMain, WM_SYSCOMMAND, SC_MINIMIZE, 0L);
break;
#if 0
case VK_F1:
DoHelp(HELP_INDEX, 0L);
break;
case VK_F2:
StartGame();
break;
#endif
case VK_F4:
if (FSoundSwitchable())
if (FSoundOn())
{
EndTunes();
Preferences.fSound = fsoundOff;
}
else
Preferences.fSound = FInitTunes();
break;
case VK_F5:
if (FMenuSwitchable())
SetMenuBar(fmenuOff);
break;
case VK_F6:
if (FMenuSwitchable())
SetMenuBar(fmenuOn);
break;
default:
break;
}
break;
// case WM_QUERYENDSESSION:
case WM_DESTROY:
//LExit:
KillTimer(hwndMain,ID_TIME_FLASH);
DoHelp(HELP_QUIT, 0L);
PostQuitMessage(0);
break;
case WM_CHAR:
break;
case WM_LBUTTONDOWN:
if (!FPlay())
{
return 0;
}
fButton1Down = fTrue;
blkCurr = iBlkNil;
SetCapture(hwndMain);
case WM_MOUSEMOVE:
if (fButton1Down)
{
BLK blk = BlkFromXY(LOWORD(lParam), HIWORD(lParam));
if ((blk != blkCurr) && FValidMove(blk))
{
if (FValidMove(blkCurr))
DisplayBall(blkCurr, iBallBlank);
blkCurr = blk;
PlayTune(TUNE_MOVE);
DisplayBall(blk, iBallGrey);
}
}
break;
case WM_LBUTTONUP:
if (fButton1Down)
{
fButton1Down = fFalse;
ReleaseCapture();
if (FValidMove(blkCurr))
DoMove(blkCurr);
}
break;
case WM_RBUTTONDOWN:
if (FPlay())
UnDoMove();
else
StartGame();
break;
case WM_TIMER:
DoTimer();
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hwnd,&ps);
DrawScreen(hDC);
EndPaint(hwnd, &ps);
}
return 0;
case WM_MOVE:
if (!FIcon())
{
Preferences.xWindow = 1+LOWORD(lParam);
Preferences.yWindow = 1+HIWORD(lParam);
}
break;
default:
break;
}
return (DefWindowProc(hwnd, message, wParam, lParam));
}
/****** A D J U S T W I N D O W ******/
VOID AdjustWindow(INT fAdjust)
{
SetupData();
dypAdjust = dypCaption;
if (FMenuOn())
dypAdjust += dypMenu;
if (GetSystemMetrics(SM_CYSCREEN) >= 480) /* Is display 8514 ? */
{
#define stupid8514 40
dxpWindow = 180 + stupid8514;
if (f4)
dxpGridOff = 16 + stupid8514/2;
else
dxpGridOff = 34 + stupid8514/2;
}
else
{
dxpWindow = 180; /* Aren't constants fun ? */
if (f4)
dxpGridOff = 16;
else
dxpGridOff = 34;
}
dyBlkPlane = dyBlk * cBlkRow;
dxpGrid = dxpPlane = (dxBall-1)*cBlkRow;
dypPlane = dyBlkPlane + dyLevel;
dypGrid = (((dyBlk * cBlkRow) + dyLevel+dyBlkDiff) * cPlane);
dypWindow = dypGridOff + dypGrid + dyEdge;
if (fAdjust & fResize)
{
SetupBoard();
InvalidateRect(hwndMain, NULL, fTrue);
MoveWindow(hwndMain, Preferences.xWindow - dxpBorder,
Preferences.yWindow - dypAdjust,
dxpWindow+dxpBorder, dypWindow + dypAdjust, fTrue);
}
}