1 /* $Id: winXThread.c,v 5.0 2001/04/07 20:00:59 dik Exp $
2 *
3 * XPilot, a multiplayer gravity war game. Copyright (C) 1991-2001 by
4 *
5 * Bj�rn Stabell <bjoern@xpilot.org>
6 * Ken Ronny Schouten <ken@xpilot.org>
7 * Bert Gijsbers <bert@xpilot.org>
8 * Dick Balaska <dick@xpilot.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 /***************************************************************************\
26 * winXThread.c - X11 to Windoze converter *
27 * *
28 * XPilot specific: *
29 * This module is an attempt at running the BitBlt in another thread. *
30 * *
31 * $Id: winXThread.c,v 5.0 2001/04/07 20:00:59 dik Exp $ *
32 \***************************************************************************/
33
34 #include "../../common/NT/winX.h"
35 #include "../../common/NT/winX_.h"
36 #include "winXThread.h"
37 #include "../../common/error.h"
38
39 HANDLE dthread = NULL;
40 _dinfo dinfo;
41
42 DWORD tid; // threadID
43
44 DWORD WINAPI DrawThreadProc(LPVOID data);
45
winXTDraw(HDC hDCx,Window w,RECT * rect)46 void winXTDraw(HDC hDCx, Window w, RECT* rect)
47 {
48
49 if (!dthread)
50 {
51 dinfo.eventDraw = CreateEvent(NULL, FALSE, FALSE, NULL);
52 dinfo.eventNotDrawing = CreateEvent(NULL, TRUE, TRUE, NULL); // manual reset, initially set
53 dinfo.eventKillServerThread = CreateEvent(NULL, FALSE, FALSE, NULL); // auto reset, initially reset
54 dinfo.eventServerThreadKilled = CreateEvent(NULL, FALSE, FALSE, NULL); // auto reset, initially reset
55 dinfo.isDrawing = FALSE;
56 dinfo.hDC = GetDC(xid[w].hwnd.hWnd);
57
58 dthread = CreateThread(NULL, 16000, DrawThreadProc, &dinfo, 0, &tid);
59 SetThreadPriority(dthread, THREAD_PRIORITY_BELOW_NORMAL);
60 // SetThreadPriority(dthread, THREAD_PRIORITY_HIGHEST);
61
62 }
63 if (WaitForSingleObject(dinfo.eventNotDrawing, 0) // 1 second timeout
64 == WAIT_OBJECT_0)
65 {
66 // dinfo.hDC = hDC;
67 dinfo.w = w;
68 dinfo.hWnd = xid[w].hwnd.hWnd;
69 dinfo.rect = *rect;
70 dinfo.hBmpDC = xid[w].hwnd.hBmpDCa[xid[w].hwnd.filling];
71 dinfo.myPal = myPal;
72 xid[w].hwnd.filling ^= 1;
73 xid[w].hwnd.hBmpDC = xid[w].hwnd.hBmpDCa[xid[w].hwnd.filling];
74 xid[w].hwnd.hBmp = xid[w].hwnd.hBmpa[xid[w].hwnd.filling];
75
76 // SelectPalette(xid[w].hwnd.hBmpDC, myPal, FALSE);
77 // RealizePalette(xid[w].hwnd.hBmpDC);
78
79 SetEvent(dinfo.eventDraw);
80 }
81 else
82 {
83 // error("Draw Thread is dead");
84 // redraw this frame
85 }
86 }
87
88 int serverkilled;
89
DrawThreadProc(LPVOID data)90 DWORD WINAPI DrawThreadProc(LPVOID data)
91 {
92 _dinfo* d = (_dinfo*)data;
93 BOOL ServerKilled = FALSE;
94 HDC myDC;
95
96 // This draw thread runs in an infinite loop, waiting to recalculate the
97 // result whenever the main application thread sets the "start recalc" event.
98 // The recalc thread exits the loop only when the main application sets the
99 // "kill recalc" event.
100
101 while (TRUE)
102 {
103
104 // Wait until the main application thread asks this thread to do
105 // something
106 if (WaitForSingleObject(d->eventDraw, INFINITE)
107 != WAIT_OBJECT_0)
108 break;
109 // d->isDrawing = TRUE;
110
111 // Exit the thread if the main application sets the "kill server"
112 // event. The main application will set the "kill server" event
113 // before setting the "draw" event.
114
115 if (WaitForSingleObject(d->eventKillServerThread, 0)
116 == WAIT_OBJECT_0)
117 break; // Terminate this thread by existing the proc.
118
119 // Reset event to indicate "not done", that is, game is in progress.
120 // ResetEvent(d->m_hEventGameTerminated);
121 ResetEvent(d->eventNotDrawing);
122 // main(pServerInfo->argc, pServerInfo->argv);
123 myDC = GetDC(d->hWnd);
124 SelectPalette(myDC, d->myPal, FALSE);
125 RealizePalette(myDC);
126 // BitBlt(d->hDC, d->rect.left, d->rect.top, d->rect.right, d->rect.bottom,
127 BitBlt(myDC, d->rect.left, d->rect.top, d->rect.right, d->rect.bottom,
128 d->hBmpDC, d->rect.left, d->rect.top, SRCCOPY);
129 // if (xid[d->w].hwnd.filling)
130 // FillRect(myDC, &d->rect, GetStockObject(WHITE_BRUSH));
131 // else
132 // FillRect(myDC, &d->rect, GetStockObject(DKGRAY_BRUSH));
133 ReleaseDC(d->hWnd, myDC);
134 SetEvent(d->eventNotDrawing);
135
136 // Sleep(10*1000); // debug
137 // Set event to indicate that drawing is done (i.e., no longer in progres),
138 // even if perhaps interrupted by "kill recalc" event detected in the SlowAdd function.
139 // SetEvent(pServerInfo->m_hEventGameTerminated);
140
141 if (ServerKilled) // If interrupted by kill then...
142 break; // terminate this thread by exiting the proc.
143
144 //PostMessage(pServerInfo->m_hwndNotifyRecalcDone,
145 // WM_USER_RECALC_DONE, 0, 0);
146 }
147
148 if (ServerKilled)
149 SetEvent(d->eventServerThreadKilled);
150 return 0;
151 }
152