Devilution
Diablo devolved - magic behind the 1996 computer game
dthread.cpp
Go to the documentation of this file.
1 
6 #include "all.h"
7 #include "../3rdParty/Storm/Source/storm.h"
8 
10 
11 static CCritSect sgMemCrit;
12 SDL_threadID glpDThreadId;
13 TMegaPkt *sgpInfoHead; /* may not be right struct */
15 event_emul *sghWorkToDoEvent;
16 
17 /* rdata */
18 static SDL_Thread *sghThread = NULL;
19 
20 void dthread_remove_player(int pnum)
21 {
22  TMegaPkt *pkt;
23 
24  sgMemCrit.Enter();
25  for (pkt = sgpInfoHead; pkt; pkt = pkt->pNext) {
26  if (pkt->dwSpaceLeft == pnum)
27  pkt->dwSpaceLeft = MAX_PLRS;
28  }
29  sgMemCrit.Leave();
30 }
31 
32 void dthread_send_delta(int pnum, char cmd, void *pbSrc, int dwLen)
33 {
34  TMegaPkt *pkt;
35  TMegaPkt *p;
36 
37  if (gbMaxPlayers == 1) {
38  return;
39  }
40 
41  pkt = (TMegaPkt *)DiabloAllocPtr(dwLen + 20);
42  pkt->pNext = NULL;
43  pkt->dwSpaceLeft = pnum;
44  pkt->data[0] = cmd;
45  *(DWORD *)&pkt->data[4] = dwLen;
46  memcpy(&pkt->data[8], pbSrc, dwLen);
47  sgMemCrit.Enter();
48  p = (TMegaPkt *)&sgpInfoHead;
49  while (p->pNext) {
50  p = p->pNext;
51  }
52  p->pNext = pkt;
53 
54  SetEvent(sghWorkToDoEvent);
55  sgMemCrit.Leave();
56 }
57 
59 {
60  const char *error_buf;
61 
62  if (gbMaxPlayers == 1) {
63  return;
64  }
65 
66  sghWorkToDoEvent = StartEvent();
67  if (!sghWorkToDoEvent) {
68  error_buf = TraceLastError();
69  app_fatal("dthread:1\n%s", error_buf);
70  }
71 
72  dthread_running = TRUE;
73 
74  sghThread = CreateThread(dthread_handler, &glpDThreadId);
75  if (sghThread == NULL) {
76  error_buf = TraceLastError();
77  app_fatal("dthread2:\n%s", error_buf);
78  }
79 }
80 
81 unsigned int dthread_handler(void *data)
82 {
83  const char *error_buf;
84  TMegaPkt *pkt;
85  DWORD dwMilliseconds;
86 
87  while (dthread_running) {
88  if (!sgpInfoHead && WaitForEvent(sghWorkToDoEvent) == -1) {
89  error_buf = TraceLastError();
90  app_fatal("dthread4:\n%s", error_buf);
91  }
92 
93  sgMemCrit.Enter();
94  pkt = sgpInfoHead;
95  if (sgpInfoHead)
97  else
98  ResetEvent(sghWorkToDoEvent);
99  sgMemCrit.Leave();
100 
101  if (pkt) {
102  if (pkt->dwSpaceLeft != MAX_PLRS)
103  multi_send_zero_packet(pkt->dwSpaceLeft, pkt->data[0], &pkt->data[8], *(DWORD *)&pkt->data[4]);
104 
105  dwMilliseconds = 1000 * *(DWORD *)&pkt->data[4] / gdwDeltaBytesSec;
106  if (dwMilliseconds >= 1)
107  dwMilliseconds = 1;
108 
109  mem_free_dbg(pkt);
110 
111  if (dwMilliseconds)
112  SDL_Delay(dwMilliseconds);
113  }
114  }
115 
116  return 0;
117 }
118 
120 {
121  const char *error_buf;
122  TMegaPkt *tmp;
123 
124  if (sghWorkToDoEvent == NULL) {
125  return;
126  }
127 
128  dthread_running = FALSE;
129  SetEvent(sghWorkToDoEvent);
130  if (sghThread != NULL && glpDThreadId != SDL_GetThreadID(NULL)) {
131  SDL_WaitThread(sghThread, NULL);
132  sghThread = NULL;
133  }
134  EndEvent(sghWorkToDoEvent);
135  sghWorkToDoEvent = NULL;
136 
137  while (sgpInfoHead) {
138  tmp = sgpInfoHead->pNext;
140  sgpInfoHead = tmp;
141  }
142 }
143 
dthread_running
BOOLEAN dthread_running
Definition: dthread.cpp:14
MAX_PLRS
#define MAX_PLRS
Definition: defs.h:16
dthread_cleanup
void dthread_cleanup()
Definition: dthread.cpp:119
MemFreeDbg
#define MemFreeDbg(p)
Definition: defs.h:157
dthread_send_delta
void dthread_send_delta(int pnum, char cmd, void *pbSrc, int dwLen)
Definition: dthread.cpp:32
TMegaPkt::pNext
struct TMegaPkt * pNext
Definition: structs.h:955
all.h
sgMemCrit
static DEVILUTION_BEGIN_NAMESPACE CCritSect sgMemCrit
Definition: dthread.cpp:11
sgpInfoHead
TMegaPkt * sgpInfoHead
Definition: dthread.cpp:13
gbMaxPlayers
BYTE gbMaxPlayers
Specifies the maximum number of players in a game, where 1 represents a single player game and 4 repr...
Definition: multi.cpp:34
TMegaPkt::dwSpaceLeft
DWORD dwSpaceLeft
Definition: structs.h:956
app_fatal
void app_fatal(const char *pszFmt,...)
Definition: appfat.cpp:18
DEVILUTION_END_NAMESPACE
#define DEVILUTION_END_NAMESPACE
Definition: types.h:10
sghWorkToDoEvent
event_emul * sghWorkToDoEvent
Definition: dthread.cpp:15
dthread_remove_player
void dthread_remove_player(int pnum)
Definition: dthread.cpp:20
glpDThreadId
SDL_threadID glpDThreadId
Definition: dthread.cpp:12
sghThread
static SDL_Thread * sghThread
Definition: dthread.cpp:18
TMegaPkt::data
BYTE data[32000]
Definition: structs.h:957
DiabloAllocPtr
BYTE * DiabloAllocPtr(DWORD dwBytes)
Multithreaded safe malloc.
Definition: engine.cpp:765
dthread_handler
unsigned int dthread_handler(void *data)
Definition: dthread.cpp:81
mem_free_dbg
void mem_free_dbg(void *p)
Multithreaded safe memfree.
Definition: engine.cpp:786
TMegaPkt
Definition: structs.h:954
dthread_start
void dthread_start()
Definition: dthread.cpp:58
DEVILUTION_BEGIN_NAMESPACE
Definition: sha.cpp:10
TraceLastError
#define TraceLastError
Definition: appfat.h:15
multi_send_zero_packet
void multi_send_zero_packet(int pnum, BYTE bCmd, BYTE *pbSrc, DWORD dwLen)
Definition: multi.cpp:503
gdwDeltaBytesSec
DWORD gdwDeltaBytesSec
Definition: nthread.cpp:14