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.

567 lines
9.1 KiB

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