📄 netplaydlg.cpp
字号:
//
// 僶乕僕儑儞僟僀傾儘僌僋儔僗
//
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shellapi.h>
#include <string>
using namespace std;
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Pathlib.h"
#include "Config.h"
#include "Wnd.h"
#include "NetPlayDlg.h"
#include "EmuThread.h"
#include "NetPlay.h"
DLG_MESSAGE_BEGIN(CNetPlayDlg)
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
DLG_ON_MESSAGE( WM_NETPLAY_HOSTBYNAME, OnNetwordHostByName )
DLG_ON_MESSAGE( WM_NETPLAY_ACCEPT, OnNetworkAccept )
DLG_ON_MESSAGE( WM_NETPLAY_CONNECT, OnNetworkConnect )
DLG_ON_MESSAGE( WM_NETPLAY_CLOSE, OnNetworkClose )
DLG_ON_MESSAGE( WM_NETPLAY_ERROR, OnNetworkError )
DLG_COMMAND_BEGIN()
DLG_ON_COMMAND( IDC_NET_CONNECT, OnConnect )
DLG_ON_COMMAND( IDC_NET_SERVER, OnServer )
DLG_ON_COMMAND( IDC_NET_CLIENT, OnClient )
DLG_ON_COMMAND( IDCANCEL, OnCancel )
DLG_COMMAND_END()
DLG_MESSAGE_END()
INT CNetPlayDlg::DoModal( HWND hWndParent )
{
m_hWndParent = hWndParent;
return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_NETPLAY),
hWndParent, g_DlgProc, (LPARAM)this );
}
void CNetPlayDlg::SetStatusMessage( UINT uID )
{
CHAR szTemp[256];
CApp::LoadString( uID, szTemp, sizeof(szTemp) );
::SetDlgItemText( m_hWnd, IDC_NET_STATUS, szTemp );
}
void CNetPlayDlg::SetControlEnable( BOOL bEnable )
{
if( bEnable ) {
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_PORT_COMBO ), IsBTNCHECK(IDC_NET_SERVER)?TRUE:FALSE );
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_HOST_COMBO ), IsBTNCHECK(IDC_NET_SERVER)?FALSE:TRUE );
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_LATENCY_COMBO ), IsBTNCHECK(IDC_NET_SERVER)?TRUE:FALSE );
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_SERVER ), TRUE );
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_CLIENT ), TRUE );
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_NICKNAME ), TRUE );
} else {
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_PORT_COMBO ), FALSE );
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_HOST_COMBO ), FALSE );
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_LATENCY_COMBO ), FALSE );
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_SERVER ), FALSE );
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_CLIENT ), FALSE );
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_NICKNAME ), FALSE );
}
}
void CNetPlayDlg::AddRecentPort( LPCSTR lpszPort )
{
// 儕僗僩偵偁傞偐偳偆偐
BOOL bFound = FALSE;
INT i, j;
for( i = 0; i < 16; i++ ) {
if( ::strlen(Config.netplay.szRecentPort[i]) <= 0 )
break;
}
for( j = 0; j < i; j++ ) {
if( ::strcmp( Config.netplay.szRecentPort[j], lpszPort ) == 0 ) {
bFound = TRUE;
break;
}
}
if( j == 16 )
j--;
for( ; j > 0; j-- ) {
::lstrcpy( Config.netplay.szRecentPort[j], Config.netplay.szRecentPort[j-1] );
}
::strcpy( Config.netplay.szRecentPort[0], lpszPort );
if( !bFound ) {
Config.netplay.nRecentPort++;
}
}
void CNetPlayDlg::AddRecentHost( LPCSTR lpszHost )
{
// 儕僗僩偵偁傞偐偳偆偐
BOOL bFound = FALSE;
INT i, j;
for( i = 0; i < 16; i++ ) {
if( ::strlen(Config.netplay.szRecentHost[i]) <= 0 )
break;
}
for( j = 0; j < i; j++ ) {
if( ::strcmp( Config.netplay.szRecentHost[j], lpszHost ) == 0 ) {
bFound = TRUE;
break;
}
}
if( j == 16 )
j--;
for( ; j > 0; j-- ) {
::lstrcpy( Config.netplay.szRecentHost[j], Config.netplay.szRecentHost[j-1] );
}
::strcpy( Config.netplay.szRecentHost[0], lpszHost );
if( !bFound ) {
Config.netplay.nRecentHost++;
}
}
DLGMSG CNetPlayDlg::OnInitDialog( DLGMSGPARAM )
{
// DEBUGOUT( "CNetPlayDlg::OnInitDialog\n" );
INT i;
// 億乕僩
::SendDlgItemMessage( m_hWnd, IDC_NET_PORT_COMBO, CB_RESETCONTENT, 0, 0 );
for( i = 0; i < Config.netplay.nRecentPort; i++ ) {
::SendDlgItemMessage( m_hWnd, IDC_NET_PORT_COMBO, CB_INSERTSTRING, -1, (LPARAM)Config.netplay.szRecentPort[i] );
}
::SendDlgItemMessage( m_hWnd, IDC_NET_PORT_COMBO, CB_SETCURSEL, 0, 0 );
// 儗僀僥儞僔
::SendDlgItemMessage( m_hWnd, IDC_NET_LATENCY_COMBO, CB_RESETCONTENT, 0, 0 );
for( i = 0; i < 9; i++ ) {
CHAR szStr[64];
::wsprintf( szStr, "%d Frame buffer", i+1 );
::SendDlgItemMessage( m_hWnd, IDC_NET_LATENCY_COMBO, CB_INSERTSTRING, -1, (LPARAM)szStr );
}
::SendDlgItemMessage( m_hWnd, IDC_NET_LATENCY_COMBO, CB_SETCURSEL, 0, 0 );
// 儂僗僩儕僗僩
::SendDlgItemMessage( m_hWnd, IDC_NET_HOST_COMBO, CB_RESETCONTENT, 0, 0 );
for( i = 0; i < Config.netplay.nRecentHost; i++ ) {
::SendDlgItemMessage( m_hWnd, IDC_NET_HOST_COMBO, CB_INSERTSTRING, -1, (LPARAM)Config.netplay.szRecentHost[i] );
}
::SendDlgItemMessage( m_hWnd, IDC_NET_HOST_COMBO, CB_SETCURSEL, 0, 0 );
// 僯僢僋僱乕儉
::SetDlgItemText( m_hWnd, IDC_NET_NICKNAME, Config.netplay.szNick );
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_HOST_COMBO ), FALSE );
::CheckRadioButton( m_hWnd, IDC_NET_SERVER, IDC_NET_CLIENT, IDC_NET_SERVER );
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_LATENCY_COMBO ), IsBTNCHECK(IDC_NET_SERVER)?TRUE:FALSE );
SetStatusMessage( IDS_NET_NOCONNECT );
return TRUE;
}
DLGMSG CNetPlayDlg::OnNetwordHostByName( DLGMSGPARAM )
{
DEBUGOUT( "CNetPlayDlg::OnNetwordHostByName [%08X][%08X]\n", wParam, lParam );
HRESULT hResult = NetPlay.ASyncWndProc( hWnd, wParam, lParam );
if( hResult ) {
struct in_addr addr;
addr.s_addr = hResult;
LPSTR pHost = inet_ntoa( addr );
DEBUGOUT( "Host:%s\n", pHost );
// 僄儔乕偲偐偦偺懠傕傠傕傠傪偙偺僂僀儞僪僂偱庴偗庢傞堊
NetPlay.SetMsgWnd( m_hWnd );
if( NetPlay.Connect( FALSE, pHost, m_uPort ) ) {
SetStatusMessage( IDS_NET_CONNECTING );
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_CONNECT ), FALSE );
SetControlEnable( FALSE );
} else {
DEBUGOUT( "CNetPlayDlg::OnNetwordHostByName Connect error.\n" );
SetStatusMessage( IDS_ERROR_NETWORKERROR );
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_CONNECT ), TRUE );
SetControlEnable( TRUE );
}
} else {
DEBUGOUT( "CNetPlayDlg::OnNetwordHostByName error.\n" );
SetStatusMessage( IDS_ERROR_NETWORKERROR );
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_CONNECT ), TRUE );
SetControlEnable( TRUE );
}
return TRUE;
}
DLGMSG CNetPlayDlg::OnNetworkAccept( DLGMSGPARAM )
{
BYTE databuf;
DWORD dwStartTime, dwEndTime;
BYTE nServerLatency, nClientLatency;
BYTE nServerStep, nClientStep;
INT nLatency;
BOOL bRet = FALSE;
DWORD dwCRC;
INT i;
// 僯僢僋僱乕儉傪曐懚
CHAR szNick[_MAX_PATH+1];
::GetWindowText( ::GetDlgItem( m_hWnd, IDC_NET_NICKNAME ), szNick, _MAX_PATH );
::lstrcpy( Config.netplay.szNick, szNick );
// 嵟嬤巊偭偨億乕僩偺峏怴
CHAR szPort[_MAX_PATH+1];
::GetWindowText( ::GetDlgItem( m_hWnd, IDC_NET_PORT_COMBO ), szPort, _MAX_PATH );
AddRecentPort( szPort );
// 捠怣儗僀僥儞僔偺寁應
CHAR str[256];
::wsprintf( str, "VirtuaNES version %01d.%01d%01d",
(VIRTUANES_VERSION&0xF00)>>8,
(VIRTUANES_VERSION&0x0F0)>>4,
(VIRTUANES_VERSION&0x00F) );
dwStartTime = ::timeGetTime();
for( i = 0; i < ::strlen(str); i++ ) {
if( NetPlay.Send( (BYTE)str[i] ) ) {
goto _accept_error;
}
if( NetPlay.RecvTime( databuf, 10*1000 ) < 0 ) {
goto _accept_error;
} else {
if( databuf != (BYTE)str[i] ) {
SetStatusMessage( IDS_ERROR_NETWORKERROR_VERSION );
goto _accept_error2;
}
}
}
dwEndTime = ::timeGetTime()-dwStartTime;
DEBUGOUT( "Server: Transfer Bytes: %d byte / Time: %d ms\n", ::strlen(str), dwEndTime );
// 僀儊乕僕偺CRC傪妋擣
NES* pNes;
if( !(pNes = Emu.GetNES()) ) {
goto _accept_error;
}
if( pNes->rom->GetMapperNo() != 20 ) {
dwCRC = pNes->rom->GetPROM_CRC();
} else {
dwCRC = pNes->rom->GetGameID();
}
for( i = 0; i < 32; i+=8 ) {
if( NetPlay.Send( (BYTE)(dwCRC>>i) ) ) {
goto _accept_error;
}
if( NetPlay.RecvTime( databuf, 10*1000 ) < 0 ) {
goto _accept_error;
} else if( databuf != (BYTE)(dwCRC>>i) ) {
SetStatusMessage( IDS_ERROR_NETWORKERROR_CRC );
goto _accept_error2;
}
}
// 儗僀僥儞僔愝掕
nServerLatency = m_nNetLatency;
if( nServerLatency < 0 ) {
nServerLatency = 0;
}
if( nServerLatency > 8 ) {
nServerLatency = 8;
}
DEBUGOUT( "Latancy:%d\n", nServerLatency );
nServerStep = 0;
nClientStep = 0;
// Send Latency
if( NetPlay.Send( nServerLatency ) ) {
goto _accept_error;
}
// Recv Latency dummy
if( NetPlay.RecvTime( nClientLatency, 10*1000 ) < 0 ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -