Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

578 lines
9.7 KiB

  1. /****************************************************************************
  2. PROGRAM: 3-D TicTacToe (a.k.a. Qubic, TicTactics)
  3. ****************************************************************************/
  4. #define _WINDOWS
  5. #include <windows.h>
  6. #include <port1632.h>
  7. #include "main.h"
  8. #include "rtns.h"
  9. #include "grafix.h"
  10. #include "util.h"
  11. #include "res.h"
  12. #include "pref.h"
  13. #include "sound.h"
  14. #include "string.h"
  15. #include "context.h"
  16. #include "dos.h"
  17. HANDLE hInst;
  18. HWND hwndMain;
  19. HMENU hMenu;
  20. STATUS status = fstatusIcon;
  21. BOOL fEGA;
  22. extern fUpdateIni;
  23. BOOL fButton1Down = fFalse;
  24. extern BLK rgBlk[cBlkMax];
  25. INT dxpWindow;
  26. INT dypWindow;
  27. INT dypCaption;
  28. INT dypMenu;
  29. INT dypAdjust;
  30. INT dypBorder;
  31. INT dxpBorder;
  32. INT dxpGridOff;
  33. INT dyBlkPlane;
  34. INT dypPlane;
  35. INT dxpPlane;
  36. INT dxpGrid;
  37. INT dypGrid;
  38. BLK blkCurr;
  39. CHAR szClass[cchNameMax];
  40. #define szWindowTitle szClass
  41. extern INT cBlkRow;
  42. extern INT cBlkPlane;
  43. extern INT cBlkMac;
  44. extern INT cPlane;
  45. extern BOOL f4;
  46. extern PREF Preferences;
  47. extern BOOL fUpdateIni;
  48. /****** W I N M A I N ******/
  49. MMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
  50. /* { */
  51. MSG msg;
  52. HANDLE hAccel;
  53. hInst = hInstance;
  54. InitConst();
  55. if (hPrevInstance)
  56. {
  57. HWND hwnd = FindWindow(szClass, NULL);
  58. hwnd = GetLastActivePopup(hwnd);
  59. BringWindowToTop(hwnd);
  60. if (IsIconic(hwnd))
  61. ShowWindow(hwnd, SW_RESTORE);
  62. return fFalse;
  63. }
  64. #ifdef NOSERVER /* Not in final version */
  65. {
  66. CHAR szFile[256];
  67. GetModuleFileName(hInst, szFile, 250);
  68. if (szFile[0] > 'C')
  69. {
  70. szFile[0] = 'X';
  71. if (!strcmp(szFile, "X:\\WINGAMES\\TICTACTO\\TIC.EXE"))
  72. {
  73. MessageBox(GetFocus(),
  74. "Please copy tic.exe and aboutwep.dll to your machine and run it from there.",
  75. "NO NO NO NO NO",
  76. MB_OK);
  77. return fFalse;
  78. }
  79. }
  80. }
  81. #endif
  82. #ifdef EXPIRE /*** Not in final release ***/
  83. {
  84. struct dosdate_t ddt;
  85. _dos_getdate(&ddt);
  86. if ((ddt.month + ddt.year*12) > (10 + 1990*12))
  87. {
  88. MessageBox(GetFocus(),
  89. "This game has expired. Please obtain an official copy from the Windows Entertainment Package.",
  90. "SORRY",
  91. MB_OK);
  92. return fFalse;
  93. }
  94. }
  95. #endif
  96. {
  97. WNDCLASS wc;
  98. wc.style = 0;
  99. wc.lpfnWndProc = MainWndProc;
  100. wc.cbClsExtra = 0;
  101. wc.cbWndExtra = 0;
  102. wc.hInstance = hInst;
  103. wc.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(ID_ICON_TIC2));
  104. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  105. wc.hbrBackground = GetStockObject(BLACK_BRUSH);
  106. wc.lpszMenuName = NULL;
  107. wc.lpszClassName = szClass;
  108. if (!RegisterClass(&wc))
  109. return fFalse;
  110. }
  111. hMenu = LoadMenu(hInst, MAKEINTRESOURCE(ID_MENU));
  112. hAccel = LoadAccelerators(hInst, MAKEINTRESOURCE(ID_MENU_ACCEL));
  113. ReadPreferences();
  114. AdjustWindow(fCalc);
  115. hwndMain = CreateWindow(szClass, szWindowTitle,
  116. WS_OVERLAPPED | WS_MINIMIZE | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU,
  117. Preferences.xWindow-dxpBorder, Preferences.yWindow-dypAdjust,
  118. dxpWindow+dxpBorder, dypWindow+dypAdjust,
  119. NULL, NULL, hInst, NULL);
  120. if (!hwndMain)
  121. {
  122. ReportErr(1000);
  123. return (fFalse);
  124. }
  125. if (SetTimer(hwndMain, ID_TIME_FLASH, 500 , NULL) == 0)
  126. {
  127. ReportErr(ID_ERR_TIMER);
  128. return fFalse;
  129. }
  130. if (!FInitLocal())
  131. {
  132. ReportErr(ID_ERR_MEM);
  133. return fFalse;
  134. }
  135. SetMenuBar(Preferences.fMenu);
  136. ShowWindow(hwndMain, SW_SHOWNORMAL);
  137. UpdateWindow(hwndMain);
  138. StartGame();
  139. while (GetMessage(&msg, NULL, 0, 0))
  140. {
  141. if (!TranslateAccelerator(hwndMain, hAccel, &msg))
  142. {
  143. TranslateMessage(&msg);
  144. DispatchMessage(&msg);
  145. }
  146. }
  147. CleanUp();
  148. if (fUpdateIni)
  149. WritePreferences();
  150. return (INT)(msg.wParam);
  151. }
  152. /****** B L K F R O M X Y ******/
  153. /* Rewrite ! - just one return */
  154. BLK BlkFromXY(INT x, INT y)
  155. {
  156. BLK blk = 0;
  157. if (((x-=dxpGridOff) >= 0) &&
  158. (x < dxpGrid) &&
  159. ((y-=(dypGridOff+dyBlkDiff-2)) >= 0) &&
  160. (y < dypGrid) )
  161. {
  162. while (y >= dyBlkPlane)
  163. {
  164. if ((y -= (dyLevel+dypPlane)) < 0)
  165. return iBlkNil; /* No allow hits between levels */
  166. blk++;
  167. }
  168. x -= (dyBlkPlane-y);
  169. if ((x >= 0) && (x < (cBlkRow*(dxBlk-1))) )
  170. return (blk*cBlkPlane + cBlkRow*(y/dyBlk) + (x/(dxBlk-1)) );
  171. }
  172. return iBlkNil;
  173. }
  174. /****** F V A L I D M O V E ******/
  175. BOOL FValidMove(BLK blk)
  176. {
  177. if (blk != iBlkNil)
  178. if (rgBlk[blk] == iBallBlank)
  179. return fTrue;
  180. return fFalse;
  181. }
  182. /****** F I X M E N U S ******/
  183. VOID FixMenus(VOID)
  184. {
  185. CheckEm(IDM_3x3, Preferences.iGameType == iGame3x3);
  186. CheckEm(IDM_3x3x3, Preferences.iGameType == iGame3x3x3);
  187. CheckEm(IDM_4x4x4, Preferences.iGameType == iGame4x4x4);
  188. #ifdef NOISEY
  189. CheckEm(IDM_SOUND, Preferences.fSound);
  190. #endif
  191. CheckEm(IDM_COLOR, Preferences.fColor);
  192. CheckEm(IDM_RND, Preferences.iStart == iStartRnd);
  193. CheckEm(IDM_RED, Preferences.iStart == iStartRed);
  194. CheckEm(IDM_BLUE, Preferences.iStart == iStartBlue);
  195. CheckEm(IDM_BEGIN, Preferences.skill == skillBegin);
  196. CheckEm(IDM_INTER, Preferences.skill == skillInter);
  197. CheckEm(IDM_EXPERT, Preferences.skill == skillExpert);
  198. }
  199. /****** M A I N W N D P R O C ******/
  200. LRESULT APIENTRY MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  201. {
  202. switch (message)
  203. {
  204. case WM_SYSCOMMAND:
  205. switch (wParam & 0xFFF0)
  206. {
  207. case SC_MINIMIZE:
  208. SetStatusPause();
  209. SetStatusIcon();
  210. break;
  211. case SC_RESTORE:
  212. ClrStatusPause();
  213. ClrStatusIcon();
  214. break;
  215. default:
  216. break;
  217. }
  218. break;
  219. case WM_COMMAND:
  220. switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  221. /** GAME **/
  222. case IDM_NEW:
  223. StartGame();
  224. break;
  225. case IDM_3x3:
  226. case IDM_3x3x3:
  227. case IDM_4x4x4:
  228. Preferences.iGameType = GET_WM_COMMAND_ID(wParam, lParam) - IDM_3x3;
  229. AdjustWindow(fCalc | fResize);
  230. StartGame();
  231. goto LUpdateMenu;
  232. case IDM_EXIT:
  233. ShowWindow(hwndMain, SW_HIDE);
  234. #ifdef ORGCODE
  235. goto LExit;
  236. #else
  237. SendMessage(hwndMain, WM_SYSCOMMAND, SC_CLOSE, 0);
  238. return(0);
  239. #endif
  240. /** SKILL **/
  241. case IDM_BEGIN:
  242. Preferences.skill = skillBegin;
  243. goto LUpdateMenu;
  244. case IDM_INTER:
  245. Preferences.skill = skillInter;
  246. goto LUpdateMenu;
  247. case IDM_EXPERT:
  248. Preferences.skill = skillExpert;
  249. goto LUpdateMenu;
  250. /** OPTIONS **/
  251. #ifdef NOISEY
  252. case IDM_SOUND:
  253. if (Preferences.fSound)
  254. {
  255. EndTunes();
  256. Preferences.fSound = fFalse;
  257. }
  258. else
  259. {
  260. Preferences.fSound = FInitTunes();
  261. }
  262. goto LUpdateMenu;
  263. #endif
  264. case IDM_COLOR:
  265. Preferences.fColor = !Preferences.fColor;
  266. GetTheBitmap();
  267. ReDoDisplay();
  268. DisplayScreen();
  269. goto LUpdateMenu;
  270. case IDM_RND:
  271. case IDM_RED:
  272. case IDM_BLUE:
  273. Preferences.iStart = GET_WM_COMMAND_ID(wParam, lParam) - IDM_RND;
  274. StartGame();
  275. /* IE goto LUpdateMenu; */
  276. LUpdateMenu:
  277. fUpdateIni = fTrue;
  278. FixMenus();
  279. break;
  280. /** HELP **/
  281. case IDM_INDEX:
  282. DoHelp(HELP_INDEX, 0L);
  283. break;
  284. case IDM_HOW2PLAY:
  285. DoHelp(HELP_CONTEXT, HLP_HOWTOPLAY);
  286. break;
  287. case IDM_COMMANDS:
  288. DoHelp(HELP_CONTEXT, HLP_COMMANDS);
  289. break;
  290. case IDM_HELP_HELP:
  291. DoHelp(HELP_HELPONHELP, 0L);
  292. break;
  293. case IDM_HELP_ABOUT:
  294. DoAbout();
  295. return 0;
  296. default:
  297. break;
  298. }
  299. case WM_KEYDOWN:
  300. switch (wParam)
  301. {
  302. case VK_ESCAPE:
  303. PostMessage(hwndMain, WM_SYSCOMMAND, SC_MINIMIZE, 0L);
  304. break;
  305. #if 0
  306. case VK_F1:
  307. DoHelp(HELP_INDEX, 0L);
  308. break;
  309. case VK_F2:
  310. StartGame();
  311. break;
  312. #endif
  313. case VK_F4:
  314. if (FSoundSwitchable())
  315. if (FSoundOn())
  316. {
  317. EndTunes();
  318. Preferences.fSound = fsoundOff;
  319. }
  320. else
  321. Preferences.fSound = FInitTunes();
  322. break;
  323. case VK_F5:
  324. if (FMenuSwitchable())
  325. SetMenuBar(fmenuOff);
  326. break;
  327. case VK_F6:
  328. if (FMenuSwitchable())
  329. SetMenuBar(fmenuOn);
  330. break;
  331. default:
  332. break;
  333. }
  334. break;
  335. // case WM_QUERYENDSESSION:
  336. case WM_DESTROY:
  337. //LExit:
  338. KillTimer(hwndMain,ID_TIME_FLASH);
  339. DoHelp(HELP_QUIT, 0L);
  340. PostQuitMessage(0);
  341. break;
  342. case WM_CHAR:
  343. break;
  344. case WM_LBUTTONDOWN:
  345. if (!FPlay())
  346. {
  347. return 0;
  348. }
  349. fButton1Down = fTrue;
  350. blkCurr = iBlkNil;
  351. SetCapture(hwndMain);
  352. case WM_MOUSEMOVE:
  353. if (fButton1Down)
  354. {
  355. BLK blk = BlkFromXY(LOWORD(lParam), HIWORD(lParam));
  356. if ((blk != blkCurr) && FValidMove(blk))
  357. {
  358. if (FValidMove(blkCurr))
  359. DisplayBall(blkCurr, iBallBlank);
  360. blkCurr = blk;
  361. PlayTune(TUNE_MOVE);
  362. DisplayBall(blk, iBallGrey);
  363. }
  364. }
  365. break;
  366. case WM_LBUTTONUP:
  367. if (fButton1Down)
  368. {
  369. fButton1Down = fFalse;
  370. ReleaseCapture();
  371. if (FValidMove(blkCurr))
  372. DoMove(blkCurr);
  373. }
  374. break;
  375. case WM_RBUTTONDOWN:
  376. if (FPlay())
  377. UnDoMove();
  378. else
  379. StartGame();
  380. break;
  381. case WM_TIMER:
  382. DoTimer();
  383. return 0;
  384. case WM_PAINT:
  385. {
  386. PAINTSTRUCT ps;
  387. HDC hDC = BeginPaint(hwnd,&ps);
  388. DrawScreen(hDC);
  389. EndPaint(hwnd, &ps);
  390. }
  391. return 0;
  392. case WM_MOVE:
  393. if (!FIcon())
  394. {
  395. Preferences.xWindow = 1+LOWORD(lParam);
  396. Preferences.yWindow = 1+HIWORD(lParam);
  397. }
  398. break;
  399. default:
  400. break;
  401. }
  402. return (DefWindowProc(hwnd, message, wParam, lParam));
  403. }
  404. /****** A D J U S T W I N D O W ******/
  405. VOID AdjustWindow(INT fAdjust)
  406. {
  407. SetupData();
  408. dypAdjust = dypCaption;
  409. if (FMenuOn())
  410. dypAdjust += dypMenu;
  411. if (GetSystemMetrics(SM_CYSCREEN) >= 480) /* Is display 8514 ? */
  412. {
  413. #define stupid8514 40
  414. dxpWindow = 180 + stupid8514;
  415. if (f4)
  416. dxpGridOff = 16 + stupid8514/2;
  417. else
  418. dxpGridOff = 34 + stupid8514/2;
  419. }
  420. else
  421. {
  422. dxpWindow = 180; /* Aren't constants fun ? */
  423. if (f4)
  424. dxpGridOff = 16;
  425. else
  426. dxpGridOff = 34;
  427. }
  428. dyBlkPlane = dyBlk * cBlkRow;
  429. dxpGrid = dxpPlane = (dxBall-1)*cBlkRow;
  430. dypPlane = dyBlkPlane + dyLevel;
  431. dypGrid = (((dyBlk * cBlkRow) + dyLevel+dyBlkDiff) * cPlane);
  432. dypWindow = dypGridOff + dypGrid + dyEdge;
  433. if (fAdjust & fResize)
  434. {
  435. SetupBoard();
  436. InvalidateRect(hwndMain, NULL, fTrue);
  437. MoveWindow(hwndMain, Preferences.xWindow - dxpBorder,
  438. Preferences.yWindow - dypAdjust,
  439. dxpWindow+dxpBorder, dypWindow + dypAdjust, fTrue);
  440. }
  441. }
  442.