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