mirror of https://github.com/tongzx/nt5src
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.
568 lines
9.1 KiB
568 lines
9.1 KiB
/****************************************************************************
|
|
|
|
PROGRAM: Snake (a.k.a. Centipede, Train...)
|
|
|
|
****************************************************************************/
|
|
|
|
#define _WINDOWS
|
|
#include <windows.h>
|
|
#include <port1632.h>
|
|
|
|
|
|
#include "snake.h"
|
|
#include "rtns.h"
|
|
#include "grafix.h"
|
|
#include "util.h"
|
|
#include "res.h"
|
|
#include "pref.h"
|
|
#include "blk.h"
|
|
#include "context.h"
|
|
#include "string.h"
|
|
#include "stdio.h"
|
|
#include "dos.h"
|
|
|
|
|
|
#ifndef WM_ENTERMENULOOP
|
|
#define WM_ENTERMENULOOP 0x0211
|
|
#define WM_EXITMENULOOP 0x0212
|
|
#endif
|
|
|
|
HANDLE hInst;
|
|
HWND hwndMain;
|
|
HMENU hMenu;
|
|
|
|
STATUS status = fstatusIcon;
|
|
|
|
INT dxpWindow;
|
|
INT dypWindow;
|
|
INT dypCaption;
|
|
INT dypMenu;
|
|
INT dypAdjust;
|
|
INT dypBorder;
|
|
INT dxpBorder;
|
|
|
|
BOOL fLocalPause = fFalse;
|
|
BOOL fEGA;
|
|
|
|
CHAR szClass[cchNameMax];
|
|
#define szWindowTitle szClass
|
|
|
|
extern INT ctickTimeMac;
|
|
extern INT ctickMoveMac;
|
|
extern INT cLevel;
|
|
|
|
extern PREF Preferences;
|
|
extern BOOL fUpdateIni;
|
|
|
|
INT_PTR APIENTRY LevelDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
|
|
|
|
|
|
|
/****** W I N M A I N ******/
|
|
|
|
MMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
|
|
/* { */
|
|
MSG msg;
|
|
HANDLE hAccel;
|
|
|
|
hInst = hInstance;
|
|
|
|
InitConst();
|
|
|
|
#ifdef WIN16
|
|
if (hPrevInstance)
|
|
{
|
|
HWND hWnd = FindWindow(szClass, NULL);
|
|
hWnd = GetLastActivePopup(hWnd);
|
|
BringWindowToTop(hWnd);
|
|
if (IsIconic(hWnd))
|
|
ShowWindow(hWnd, SW_RESTORE);
|
|
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_MAIN));
|
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
|
|
wc.lpszMenuName = NULL;
|
|
wc.lpszClassName = szClass;
|
|
|
|
if (!RegisterClass(&wc))
|
|
return fFalse;
|
|
}
|
|
|
|
#ifdef NOSERVER /* Not in final release */
|
|
{
|
|
CHAR szFile[256];
|
|
|
|
GetModuleFileName(hInst, szFile, 250);
|
|
if (szFile[0] > 'C')
|
|
{
|
|
szFile[0] = 'X';
|
|
if (!strcmp(szFile, "X:\\WINGAMES\\SNAKE\\SNAKE.EXE"))
|
|
{
|
|
MessageBox(GetFocus(),
|
|
"Please copy snake 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) > (8 + 1990*12))
|
|
{
|
|
MessageBox(GetFocus(),
|
|
"This game has expired. Please obtain an official copy from the Windows Entertainment Package.",
|
|
"SORRY",
|
|
MB_OK);
|
|
return fFalse;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
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_TIMER, 50 , 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(cLevel);
|
|
|
|
while (GetMessage(&msg, NULL, 0, 0))
|
|
{
|
|
if (!TranslateAccelerator(hwndMain, hAccel, &msg))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
|
|
CleanUp();
|
|
|
|
if (fUpdateIni)
|
|
WritePreferences();
|
|
|
|
return (INT)(msg.wParam);
|
|
}
|
|
|
|
|
|
|
|
/****** F I X M E N U S ******/
|
|
|
|
VOID FixMenus(VOID)
|
|
{
|
|
CheckEm(IDM_SOUND, Preferences.fSound);
|
|
CheckEm(IDM_COLOR, Preferences.fColor);
|
|
|
|
CheckEm(IDM_BEGIN, Preferences.skill == skillBegin);
|
|
CheckEm(IDM_INTER, Preferences.skill == skillInter);
|
|
CheckEm(IDM_EXPERT, Preferences.skill == skillExpert);
|
|
}
|
|
|
|
|
|
|
|
/****** D O G E T R O O M ******/
|
|
|
|
VOID DoGetRoom(VOID)
|
|
{
|
|
|
|
fLocalPause = fTrue;
|
|
|
|
DialogBox(hInst, MAKEINTRESOURCE(ID_DLG_LEVEL), hwndMain, LevelDlgProc);
|
|
fLocalPause = fFalse;
|
|
StartGame(cLevel);
|
|
}
|
|
|
|
|
|
/****** 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_QUERYENDSESSION:
|
|
case WM_DESTROY:
|
|
//LExit:
|
|
KillTimer(hwndMain, ID_TIMER);
|
|
DoHelp(HELP_QUIT, 0L);
|
|
PostQuitMessage(0);
|
|
break;
|
|
|
|
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(cLevel);
|
|
break;
|
|
|
|
case IDM_PAUSE:
|
|
if (FPause())
|
|
ClrStatusPause();
|
|
else
|
|
SetStatusPause();
|
|
CheckEm(IDM_PAUSE, FPause());
|
|
break;
|
|
|
|
case IDM_ROOM:
|
|
DoGetRoom();
|
|
break;
|
|
|
|
case IDM_EXIT:
|
|
ShowWindow(hwndMain, SW_HIDE);
|
|
#ifdef ORGCODE
|
|
goto LExit;
|
|
#else
|
|
SendMessage(hwndMain, WM_SYSCOMMAND, SC_CLOSE, 0);
|
|
return(0);
|
|
#endif
|
|
|
|
// break;
|
|
|
|
/** SKILL **/
|
|
|
|
case IDM_BEGIN:
|
|
case IDM_INTER:
|
|
case IDM_EXPERT:
|
|
Preferences.skill = (INT) wParam - IDM_BEGIN;
|
|
StartGame(cLevel);
|
|
goto LUpdateMenu;
|
|
|
|
/** OPTIONS **/
|
|
case IDM_COLOR:
|
|
Preferences.fColor = !Preferences.fColor;
|
|
FreeBitmaps();
|
|
if (!FLoadBitmaps())
|
|
{
|
|
ReportErr(ID_ERR_MEM);
|
|
#ifdef ORGCODE
|
|
goto LExit;
|
|
#else
|
|
SendMessage(hwndMain, WM_SYSCOMMAND, SC_CLOSE, 0);
|
|
return(0);
|
|
#endif
|
|
}
|
|
DisplayScreen();
|
|
goto LUpdateMenu;
|
|
|
|
case IDM_SOUND:
|
|
Preferences.fSound = !Preferences.fSound;
|
|
/* 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;
|
|
}
|
|
|
|
/*** KEYS ***/
|
|
|
|
case WM_KEYDOWN:
|
|
switch (wParam)
|
|
{
|
|
case VK_ESCAPE:
|
|
PostMessage(hwndMain, WM_SYSCOMMAND, SC_MINIMIZE, 0L);
|
|
break;
|
|
|
|
case VK_UP:
|
|
DoChangeDir(dirN);
|
|
break;
|
|
|
|
case VK_DOWN:
|
|
DoChangeDir(dirS);
|
|
break;
|
|
|
|
case VK_LEFT:
|
|
DoChangeDir(dirW);
|
|
break;
|
|
|
|
case VK_RIGHT:
|
|
DoChangeDir(dirE);
|
|
break;
|
|
|
|
case VK_F5:
|
|
if (FMenuSwitchable())
|
|
SetMenuBar(fmenuOff);
|
|
break;
|
|
|
|
case VK_F6:
|
|
if (FMenuSwitchable())
|
|
SetMenuBar(fmenuOn);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case WM_CHAR:
|
|
switch (wParam)
|
|
{
|
|
case 'A':
|
|
case 'a':
|
|
case '8':
|
|
case 'i':
|
|
case 'I':
|
|
DoChangeDir(dirN);
|
|
break;
|
|
|
|
case 'Z':
|
|
case 'z':
|
|
case '2':
|
|
case '5':
|
|
case 'k':
|
|
case 'K':
|
|
DoChangeDir(dirS);
|
|
break;
|
|
|
|
case ',':
|
|
case '4':
|
|
case 'j':
|
|
case 'J':
|
|
DoChangeDir(dirW);
|
|
break;
|
|
|
|
case '.':
|
|
case '6':
|
|
case 'l':
|
|
case 'L':
|
|
DoChangeDir(dirE);
|
|
break;
|
|
|
|
#ifdef DEBUG
|
|
case '+':
|
|
case '=':
|
|
if (ctickMoveMac > 1)
|
|
ctickMoveMac--;
|
|
break;
|
|
|
|
case '-':
|
|
case '_':
|
|
ctickMoveMac++;
|
|
break;
|
|
|
|
case ';':
|
|
cLevel++;
|
|
StartLevel();
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_LBUTTONDOWN:
|
|
if (Preferences.fMouse)
|
|
DoChangeRelDir(dirLft);
|
|
break;
|
|
|
|
case WM_RBUTTONDOWN:
|
|
if (Preferences.fMouse)
|
|
DoChangeRelDir(dirRht);
|
|
break;
|
|
|
|
case WM_TIMER:
|
|
if (!FPause() && !fLocalPause)
|
|
DoTimer();
|
|
return 0;
|
|
|
|
case WM_PAINT:
|
|
{
|
|
PAINTSTRUCT ps;
|
|
HDC hDC = BeginPaint(hwnd,&ps);
|
|
|
|
DrawScreen(hDC);
|
|
|
|
EndPaint(hwnd, &ps);
|
|
}
|
|
return 0;
|
|
|
|
case WM_ENTERMENULOOP:
|
|
fLocalPause = fTrue;
|
|
break;
|
|
|
|
case WM_EXITMENULOOP:
|
|
fLocalPause = fFalse;
|
|
break;
|
|
|
|
case WM_ACTIVATE:
|
|
if (GET_WM_ACTIVATE_STATE(wParam, lParam) == 0)
|
|
fLocalPause = fTrue;
|
|
else
|
|
fLocalPause = fFalse;
|
|
break;
|
|
|
|
case WM_MOVE:
|
|
if (!FIcon())
|
|
{
|
|
Preferences.xWindow = 1+LOWORD(lParam);
|
|
Preferences.yWindow = 1+HIWORD(lParam);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
|
|
}
|
|
|
|
return (DefWindowProc(hwnd, message, wParam, lParam));
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** L E V E L D L G P R O C ***/
|
|
|
|
INT_PTR APIENTRY LevelDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
SetDlgItemInt(hDlg, ID_EDIT_LEVEL, 10, fFalse);
|
|
return (fTrue);
|
|
|
|
case WM_COMMAND:
|
|
switch(GET_WM_COMMAND_ID(wParam, lParam))
|
|
{
|
|
case ID_BTN_OK:
|
|
case IDOK:
|
|
cLevel = GetDlgInt(hDlg, ID_EDIT_LEVEL, 1, 50) -1;
|
|
|
|
/* Fall Through & Exit */
|
|
|
|
case ID_BTN_CANCEL:
|
|
case IDCANCEL:
|
|
EndDialog(hDlg, fTrue); /* Exits the dialog box */
|
|
return fTrue;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return (fFalse); /* Didn't process a message */
|
|
(lParam);
|
|
}
|
|
|
|
|
|
|
|
/****** A D J U S T W I N D O W ******/
|
|
|
|
VOID AdjustWindow(INT fAdjust)
|
|
{
|
|
|
|
dypAdjust = dypCaption;
|
|
|
|
if (FMenuOn())
|
|
dypAdjust += dypMenu;
|
|
|
|
dxpWindow = dxpGridOff + dxpGrid;
|
|
dypWindow = dypGridOff + dypGrid;
|
|
|
|
if (fAdjust & fResize)
|
|
{
|
|
MoveWindow(hwndMain, Preferences.xWindow - dxpBorder,
|
|
Preferences.yWindow - dypAdjust,
|
|
dxpWindow+dxpBorder, dypWindow + dypAdjust, fTrue);
|
|
}
|
|
}
|
|
|