📄 duel.c
字号:
/*==========================================================================
*
* Copyright (C) 1995-1996 Microsoft Corporation. All Rights Reserved.
*
* File: duel.c
* Content: Multi-player duel
*
*
***************************************************************************/
#define INITGUID
#include "duel.h"
#include "gameproc.h"
#include "gfx.h"
#include "comm.h"
#include "input.h"
#include "lobby.h"
#include "wizard.h"
#include "util.h"
#include "sfx.h"
// {33925241-05F8-11d0-8063-00A0C90AE891}
DEFINE_GUID(DUEL_GUID,
0x33925241, 0x5f8, 0x11d0, 0x80, 0x63, 0x0, 0xa0, 0xc9, 0xa, 0xe8, 0x91);
/*
* Externals
*/
extern DWORD gdwFrameCount;
extern DWORD gdwFrameTime;
extern int gnProgramState;
extern SHIP gOurShip;
extern LPDPLCONNECTION glpdplConnection;
extern DPID gOurID;
extern BOOL gbNoField;
/*
* Globals
*/
LPGUID glpGuid; // Duel's GUID
HWND ghWndMain; // Main application window handle
HINSTANCE ghinst; // Application instance handle
BOOL gbShowFrameCount=TRUE; // Show FPS ?
BOOL gbIsActive; // Is the application active ?
BOOL gbUseEmulation; // DDHEL or DDHAL for Graphics
BOOL gbIsHost; // Are we hosting or joining a game
DWORD gdwKeys; // User keyboard input
DWORD gdwOldKeys; // Last frame's keyboard input
BOOL gbFullscreen=FALSE; // Window or FullScreen mode ?
RECT grcWindow; // client rectangle of main window
HANDLE ghThread; // handle to wizard thread
TCHAR gtszClassName[MAX_CLASSNAME]; // Duel's class name
BOOL gbReliable; // sends are reliable
/*
* Statics
*/
static BOOL gbReinitialize; // used for switching display modes
/*
* WinMain
*/
int WINAPI WinMain( HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow )
{
BOOL bHelp=FALSE;
MSG msg;
ghinst = hinstance;
// Parse command line
while( lpCmdLine[0] == '-' )
{
lpCmdLine++;
switch (*lpCmdLine++)
{
case 'e':
gbUseEmulation = TRUE;
break;
case 'd':
gbNoField = TRUE;
break;
case '?':
default:
bHelp= TRUE;
gbFullscreen= FALSE; // give help in windowed mode
break;
}
while( isspace(*lpCmdLine) )
{
lpCmdLine++;
}
}
/*
* Give user help if asked for
*/
if( bHelp )
{
TCHAR tszHelpMsg[MAX_HELPMSG];
TCHAR tszTitle[MAX_WINDOWTITLE];
LoadString(ghinst, IDS_DUEL_HELP, tszHelpMsg, MAX_HELPMSG);
LoadString(ghinst, IDS_DUEL_TITLE, tszTitle, MAX_WINDOWTITLE);
MessageBox(ghWndMain, tszHelpMsg, tszTitle, MB_OK );
return TRUE;
}
if( !InitApplication(hinstance) )
{
return FALSE;
}
// were we launched by a lobby ?
if (LaunchedByLobby())
{
// start game
PostMessage(ghWndMain, UM_LAUNCH, 0, 0);
gbIsActive = TRUE;
}
gdwFrameTime = timeGetTime();
while( TRUE )
{
if (gbIsActive)
{
// any windows messages ? (returns immediately)
if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
{
if( !GetMessage( &msg, NULL, 0, 0 ) )
{
return msg.wParam;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// Poll our receive queue. Polling is used in the sample only for simplicity.
// Receiving messages using an event is the recommended way.
if (gnProgramState != PS_SPLASH)
{
ReceiveMessages();
}
// update screen
if (!UpdateFrame())
{
ExitGame();
}
}
}
else
{
// any windows messages ? (blocks until a message arrives)
if( !GetMessage( &msg, NULL, 0, 0 ) )
{
return msg.wParam;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
} /* WinMain */
/*
* MainWndproc
*
* Callback for all Windows messages
*/
long WINAPI MainWndproc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
PAINTSTRUCT ps;
HDC hdc;
DWORD dwRetCode;
DWORD dwTid;
switch( message )
{
case WM_SIZE:
case WM_MOVE:
// get the client rectangle
if (gbFullscreen)
{
SetRect(&grcWindow, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
}
else
{
GetClientRect(hWnd, &grcWindow);
ClientToScreen(hWnd, (LPPOINT)&grcWindow);
ClientToScreen(hWnd, (LPPOINT)&grcWindow+1);
}
break;
case WM_ACTIVATE:
// ignore this message during reinitializing graphics
if (gbReinitialize) return 0;
// When we are deactivated, although we don't update our screen, we still need to
// to empty our receive queue periodically as messages will pile up otherwise.
// Polling the receive queue continuously even when we are deactivated causes our app
// to consume all the CPU time. To avoid hogging the CPU, we block on GetMessage() WIN API
// and setup a timer to wake ourselves up at regular intervals to process our messages.
if (LOWORD(wParam) == WA_INACTIVE)
{
// deactivated
gbIsActive = FALSE;
if (PS_ACTIVE == gnProgramState)
{
SetTimer(hWnd, RECEIVE_TIMER_ID, RECEIVE_TIMEOUT, NULL);
}
}
else
{
// activated
gbIsActive = TRUE;
if (PS_ACTIVE == gnProgramState)
{
KillTimer(hWnd, RECEIVE_TIMER_ID);
}
}
// set game palette, if activated in game mode
if (gbIsActive && (gnProgramState != PS_SPLASH))
SetGamePalette();
ReacquireInputDevices();
return 0;
case WM_CREATE:
break;
case WM_SYSKEYUP:
switch( wParam )
{
// handle ALT+ENTER (fullscreen/window mode)
case VK_RETURN:
// mode switch is allowed only during the game
if (gnProgramState == PS_ACTIVE)
{
gbReinitialize = TRUE;
ReleaseLocalData(); //only sound buffers have to be rels'd anyway.
CleanupSfx();
CleanupInput();
CleanupGraphics();
DestroyWindow(ghWndMain);
gbFullscreen = !gbFullscreen;
InitGraphics();
InitInput();
InitSfx();
InitLocalSoundData();
gbReinitialize = FALSE;
}
break;
}
break;
case WM_KEYDOWN:
switch( wParam )
{
case 'r':
case 'R':
// toggle reliable status
gbReliable = !gbReliable;
UpdateTitle();
break;
case VK_F1:
{
TCHAR tszHelpMsg[MAX_HELPMSG];
TCHAR tszTitle[MAX_WINDOWTITLE];
LoadString(ghinst, IDS_DUEL_HELP, tszHelpMsg, MAX_HELPMSG);
LoadString(ghinst, IDS_DUEL_TITLE, tszTitle, MAX_WINDOWTITLE);
MessageBox(ghWndMain, tszHelpMsg, tszTitle, MB_OK );
}
break;
case VK_F5:
gbShowFrameCount = !gbShowFrameCount;
if( gbShowFrameCount )
{
gdwFrameCount = 0;
gdwFrameTime = timeGetTime();
}
break;
case VK_RETURN:
if( (gnProgramState == PS_SPLASH) && !gbFullscreen)
{
// get connection settings from user
ghThread = CreateThread(NULL, 0, (LPVOID)DoWizard, 0, 0, &dwTid);
}
break;
case VK_ESCAPE:
case VK_F12:
// adios
ExitGame();
return 0;
}
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -