mirror of
https://github.com/galaxyhaxz/devilution.git
synced 2026-02-06 16:24:41 +00:00
initial up
This commit is contained in:
266
2020_03_31/Source/nthread.cpp
Normal file
266
2020_03_31/Source/nthread.cpp
Normal file
@@ -0,0 +1,266 @@
|
||||
#include "diablo.h"
|
||||
#include "../3rdParty/Storm/Source/storm.h"
|
||||
|
||||
BYTE gbDeltaTurnsSec; // weak
|
||||
DWORD gdwMsgLenTbl[4];
|
||||
static CCritSect sgMemCrit;
|
||||
int gdwDeltaBytesSec; // weak
|
||||
static BOOLEAN sgbThreadIsActive; // weak
|
||||
DWORD gdwTurnsInTransit; // weak
|
||||
DWORD *glpMsgTbl[4];
|
||||
static unsigned int sgnThreadId;
|
||||
char sgbSyncCountdown; // weak
|
||||
int dword_679754; // weak
|
||||
char byte_679758; // weak
|
||||
char sgbPacketCountdown; // weak
|
||||
char sgbThreadIsRunning; // weak
|
||||
int gdwLargestMsgSize; // weak
|
||||
int gdwNormalMsgSize; // weak
|
||||
int dword_679764; // weak
|
||||
|
||||
/* data */
|
||||
static HANDLE sghThread = INVALID_HANDLE_VALUE; // idb
|
||||
|
||||
void nthread_terminate_game(const char *pszFcn)
|
||||
{
|
||||
DWORD dwError;
|
||||
|
||||
/// ASSERT: assert(pszFcn);
|
||||
|
||||
dwError = SErrGetLastError();
|
||||
|
||||
if(dwError == STORM_ERROR_INVALID_PLAYER) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(dwError == STORM_ERROR_GAME_TERMINATED) {
|
||||
gbGameDestroyed = 1;
|
||||
} else if(dwError == STORM_ERROR_NOT_IN_GAME) {
|
||||
gbGameDestroyed = 1;
|
||||
} else {
|
||||
app_fatal("%s:\n%s", pszFcn, TraceLastError());
|
||||
}
|
||||
}
|
||||
|
||||
DWORD nthread_send_and_recv_turn(DWORD cur_turn, int turn_delta)
|
||||
{
|
||||
DWORD dwCount, dwTurn;
|
||||
|
||||
if(!SNetGetTurnsInTransit(&dwCount)) {
|
||||
nthread_terminate_game("SNetGetTurnsInTransit");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// ASSERT: assert(gdwTurnsInTransit);
|
||||
while(dwCount++ < gdwTurnsInTransit) {
|
||||
dwTurn = dword_679754 | cur_turn & 0x7FFFFFFF;
|
||||
dword_679754 = 0;
|
||||
if(!SNetSendTurn(&dwTurn, sizeof(dwTurn))) {
|
||||
nthread_terminate_game("SNetSendTurn");
|
||||
return 0;
|
||||
}
|
||||
cur_turn += turn_delta;
|
||||
if(cur_turn >= 0x7FFFFFFF) {
|
||||
cur_turn &= 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
return cur_turn;
|
||||
}
|
||||
|
||||
BOOL nthread_recv_turns(BOOL *pfSendAsync)
|
||||
{
|
||||
/// ASSERT: assert(pfSendAsync);
|
||||
*pfSendAsync = FALSE;
|
||||
|
||||
#if 0
|
||||
if(is_debug_nthread) {
|
||||
nthread_debug_413D97();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// ASSERT: assert(sgbPacketCountdown);
|
||||
sgbPacketCountdown--;
|
||||
if(sgbPacketCountdown != 0) {
|
||||
dword_679764 += 50;
|
||||
return TRUE;
|
||||
}
|
||||
sgbPacketCountdown = gbDeltaTurnsSec;
|
||||
|
||||
/// ASSERT: assert(sgbSyncCountdown);
|
||||
sgbSyncCountdown--;
|
||||
if(sgbSyncCountdown == 0) {
|
||||
if(!SNetReceiveTurns(0, 4, &glpMsgTbl, &gdwMsgLenTbl, &player_state)) {
|
||||
if(SErrGetLastError() != STORM_ERROR_NO_MESSAGES_WAITING) {
|
||||
nthread_terminate_game("SNetReceiveTurns");
|
||||
}
|
||||
sgbSyncCountdown = 1;
|
||||
sgbPacketCountdown = sgbSyncCountdown;
|
||||
byte_679758 = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
if(!byte_679758) {
|
||||
byte_679758 = TRUE;
|
||||
dword_679764 = GetTickCount();
|
||||
}
|
||||
sgbSyncCountdown = 4;
|
||||
multi_msg_countdown();
|
||||
}
|
||||
|
||||
*pfSendAsync = TRUE;
|
||||
dword_679764 += 50;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void nthread_set_turn_upper_bit()
|
||||
{
|
||||
dword_679754 = 0x80000000;
|
||||
}
|
||||
|
||||
void nthread_start(BOOL set_turn_upper_bit)
|
||||
{
|
||||
_SNETCAPS caps;
|
||||
|
||||
dword_679764 = GetTickCount();
|
||||
sgbPacketCountdown = 1;
|
||||
sgbSyncCountdown = 1;
|
||||
byte_679758 = TRUE;
|
||||
|
||||
if(set_turn_upper_bit) {
|
||||
nthread_set_turn_upper_bit();
|
||||
} else {
|
||||
dword_679754 = 0;
|
||||
}
|
||||
|
||||
caps.size = sizeof(caps);
|
||||
if(!SNetGetProviderCaps(&caps)) {
|
||||
app_fatal("SNetGetProviderCaps:\n%s", TraceLastError());
|
||||
}
|
||||
|
||||
if(caps.defaultturnsintransit != 0) {
|
||||
gdwTurnsInTransit = caps.defaultturnsintransit;
|
||||
} else {
|
||||
gdwTurnsInTransit = 1;
|
||||
}
|
||||
|
||||
if(caps.defaultturnssec > 20 || caps.defaultturnssec == 0) {
|
||||
gbDeltaTurnsSec = 1;
|
||||
} else {
|
||||
gbDeltaTurnsSec = 20 / caps.defaultturnssec;
|
||||
}
|
||||
|
||||
gdwLargestMsgSize = caps.maxmessagesize < 512 ? caps.maxmessagesize : 512;
|
||||
/// ASSERT: assert(gdwLargestMsgSize >= MIN_MSG_SIZE);
|
||||
|
||||
gdwNormalMsgSize = caps.bytessec * gbDeltaTurnsSec / 20;
|
||||
gdwDeltaBytesSec = caps.bytessec >> 2;
|
||||
|
||||
gdwNormalMsgSize *= 3;
|
||||
gdwNormalMsgSize >>= 2;
|
||||
|
||||
/// ASSERT: assert(caps.maxplayers);
|
||||
if(caps.maxplayers > 4) {
|
||||
caps.maxplayers = 4;
|
||||
}
|
||||
|
||||
gdwNormalMsgSize /= caps.maxplayers;
|
||||
|
||||
while(gdwNormalMsgSize < MIN_MSG_SIZE) {
|
||||
gdwNormalMsgSize <<= 1;
|
||||
gbDeltaTurnsSec <<= 1;
|
||||
}
|
||||
|
||||
if(gdwNormalMsgSize > gdwLargestMsgSize) {
|
||||
gdwNormalMsgSize = gdwLargestMsgSize;
|
||||
}
|
||||
|
||||
if(gbMaxPlayers > 1) {
|
||||
sgbThreadIsRunning = FALSE;
|
||||
sgMemCrit.Enter();
|
||||
sgbThreadIsActive = TRUE;
|
||||
/// ASSERT: assert(sghThread == INVALID_HANDLE_VALUE);
|
||||
sghThread = (HANDLE)_beginthreadex(NULL, 0, nthread_handler, NULL, 0, &sgnThreadId);
|
||||
if(sghThread == INVALID_HANDLE_VALUE) {
|
||||
app_fatal("nthread2:\n%s", TraceLastError());
|
||||
}
|
||||
SetThreadPriority(sghThread, THREAD_PRIORITY_HIGHEST);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int __stdcall nthread_handler(void *dummy)
|
||||
{
|
||||
int nTicks;
|
||||
BOOL fSendAsync;
|
||||
|
||||
while(sgbThreadIsActive) {
|
||||
sgMemCrit.Enter();
|
||||
if(!sgbThreadIsActive) {
|
||||
sgMemCrit.Leave();
|
||||
return 0;
|
||||
}
|
||||
nthread_send_and_recv_turn(0, 0);
|
||||
if(nthread_recv_turns(&fSendAsync)) {
|
||||
nTicks = dword_679764 - GetTickCount();
|
||||
} else {
|
||||
nTicks = 50;
|
||||
}
|
||||
sgMemCrit.Leave();
|
||||
if(nTicks > 0) {
|
||||
Sleep(nTicks);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nthread_cleanup()
|
||||
{
|
||||
sgbThreadIsActive = FALSE;
|
||||
gdwTurnsInTransit = 0;
|
||||
gdwNormalMsgSize = 0;
|
||||
gdwLargestMsgSize = 0;
|
||||
|
||||
if(sghThread != INVALID_HANDLE_VALUE && sgnThreadId != GetCurrentThreadId()) {
|
||||
if(!sgbThreadIsRunning) {
|
||||
sgMemCrit.Leave();
|
||||
}
|
||||
if(WaitForSingleObject(sghThread, INFINITE) == WAIT_FAILED) {
|
||||
app_fatal("nthread3:\n(%s)", TraceLastError());
|
||||
}
|
||||
CloseHandle(sghThread);
|
||||
sghThread = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
void nthread_ignore_mutex(BOOL bStart)
|
||||
{
|
||||
if(sghThread == INVALID_HANDLE_VALUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/// ASSERT: assert(sgbThreadIsRunning != bStart);
|
||||
|
||||
if(bStart) {
|
||||
sgMemCrit.Leave();
|
||||
} else {
|
||||
sgMemCrit.Enter();
|
||||
}
|
||||
|
||||
sgbThreadIsRunning = bStart;
|
||||
}
|
||||
|
||||
BOOL nthread_has_500ms_passed(BOOL unused)
|
||||
{
|
||||
int nPassed;
|
||||
DWORD dwTicks;
|
||||
|
||||
dwTicks = GetTickCount();
|
||||
nPassed = dwTicks - dword_679764;
|
||||
|
||||
if(gbMaxPlayers == 1 && nPassed > 500) {
|
||||
dword_679764 = dwTicks;
|
||||
nPassed = 0;
|
||||
}
|
||||
|
||||
return nPassed >= 0;
|
||||
}
|
||||
Reference in New Issue
Block a user