1 //----------------------------------------------------------------------------
2 //  EDGE Win32 Misc System Interface Code
3 //----------------------------------------------------------------------------
4 //
5 //  Copyright (c) 1999-2008  The EDGE Team.
6 //
7 //  This program is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU General Public License
9 //  as published by the Free Software Foundation; either version 2
10 //  of the License, or (at your option) any later version.
11 //
12 //  This program is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //  GNU General Public License for more details.
16 //
17 //----------------------------------------------------------------------------
18 
19 #include "i_defs.h"
20 #include "i_sdlinc.h"
21 #include "i_net.h"
22 
23 #include <fcntl.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <time.h>
27 
28 #include "epi/timestamp.h"
29 
30 #include "con_main.h"
31 #include "dm_defs.h"
32 #include "e_main.h"
33 #include "g_game.h"
34 #include "m_argv.h"
35 #include "m_menu.h"
36 #include "m_misc.h"
37 #include "s_sound.h"
38 #include "w_wad.h"
39 #include "version.h"
40 #include "z_zone.h"
41 
42 #include "w32_sysinc.h"
43 
44 #define INTOLERANT_MATH 1  // -AJA- FIXME: temp fix to get to compile
45 
46 extern FILE* debugfile;
47 extern FILE* logfile;
48 
49 // output string buffer
50 #define MSGBUFSIZE 4096
51 static char msgbuf[MSGBUFSIZE];
52 
53 // ================ INTERNALS =================
54 
55 //
56 // FlushMessageQueue
57 //
58 // Hacktastic work around for SDL_Quit()
59 //
FlushMessageQueue()60 void FlushMessageQueue()
61 {
62 	MSG msg;
63 
64 	while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
65 	{
66 		if ( msg.message == WM_QUIT )
67 			break;
68 
69 		TranslateMessage( &msg );
70 		DispatchMessage( &msg );
71 	}
72 }
73 
74 // ============ END OF INTERNALS ==============
75 
I_SetupSignalHandlers(bool allow_coredump)76 void I_SetupSignalHandlers(bool allow_coredump)
77 {
78 	/* nothing needed */
79 }
80 
I_CheckAlreadyRunning(void)81 void I_CheckAlreadyRunning(void)
82 {
83 	HANDLE edgemap;
84 
85 	// Check we've not already running
86 	edgemap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READONLY, 0, 8, TITLE);
87 	if (edgemap)
88 	{
89 		DWORD lasterror = GetLastError();
90 		if (lasterror == ERROR_ALREADY_EXISTS)
91 		{
92 			I_MessageBox("EDGE is already running!", "EDGE Error");
93 			I_CloseProgram(9);
94 		}
95 	}
96 }
97 
98 
99 //
100 // I_SystemStartup
101 //
102 // -ACB- 1998/07/11 Reformatted the code.
103 //
I_SystemStartup(void)104 void I_SystemStartup(void)
105 {
106 	if (SDL_Init(0) < 0)
107 		I_Error("Couldn't init SDL!!\n%s\n", SDL_GetError());
108 
109 	I_StartupGraphics(); // SDL requires this to be called first
110 	I_StartupControl();
111 	I_StartupSound();
112 	I_StartupMusic(); // Startup Music System
113 	I_StartupNetwork();
114 
115 #ifndef INTOLERANT_MATH
116 	// -ACB- 2000/06/05 This switches off x87 signalling error
117 	_control87(EM_ZERODIVIDE | EM_INVALID, EM_ZERODIVIDE | EM_INVALID);
118 #endif /* INTOLERANT_MATH */
119 
120 }
121 
122 //
123 // I_DisplayExitScreen
124 //
I_DisplayExitScreen(void)125 void I_DisplayExitScreen(void)
126 {
127 }
128 
129 //
130 // I_CloseProgram
131 //
I_CloseProgram(int exitnum)132 void I_CloseProgram(int exitnum)
133 {
134 	exit(exitnum);
135 }
136 
137 //
138 // I_TraceBack
139 //
140 // Like I_CloseProgram, but may display some sort of debugging information
141 // on some systems (typically the function call stack).
142 //
I_TraceBack(void)143 void I_TraceBack(void)
144 {
145 	I_CloseProgram(-1);
146 }
147 
148 
149 //
150 // I_Warning
151 //
152 // -AJA- 1999/09/10: added this.
153 //
I_Warning(const char * warning,...)154 void I_Warning(const char *warning,...)
155 {
156 	va_list argptr;
157 
158 	va_start(argptr, warning);
159 	vsprintf(msgbuf, warning, argptr);
160 
161 	I_Printf("WARNING: %s", msgbuf);
162 	va_end(argptr);
163 }
164 
165 //
166 // I_Error
167 //
I_Error(const char * error,...)168 void I_Error(const char *error,...)
169 {
170 	va_list argptr;
171 
172 	va_start(argptr, error);
173 	vsprintf(msgbuf, error, argptr);
174 	va_end(argptr);
175 
176 	if (logfile)
177 	{
178 		fprintf(logfile, "ERROR: %s\n", msgbuf);
179 		fflush(logfile);
180 	}
181 
182 	if (debugfile)
183 	{
184 		fprintf(debugfile, "ERROR: %s\n", msgbuf);
185 		fflush(debugfile);
186 	}
187 
188 	I_SystemShutdown();
189 
190 	I_MessageBox(msgbuf, "EDGE Error");
191 
192 	I_CloseProgram(-1);
193 }
194 
195 //
196 // I_Printf
197 //
I_Printf(const char * message,...)198 void I_Printf(const char *message,...)
199 {
200 	va_list argptr;
201 	char *string;
202 	char printbuf[MSGBUFSIZE];
203 
204 	// clear the buffer
205 	memset (printbuf, 0, MSGBUFSIZE);
206 
207 	string = printbuf;
208 
209 	va_start(argptr, message);
210 
211 	// Print the message into a text string
212 	vsprintf(printbuf, message, argptr);
213 
214 	L_WriteLog("%s", printbuf);
215 
216 	// If debuging enabled, print to the debugfile
217 	L_WriteDebug("%s", printbuf);
218 
219 	// Clean up \n\r combinations
220 	while (*string)
221 	{
222 		if (*string == '\n')
223 		{
224 			memmove(string + 2, string + 1, strlen(string));
225 			string[1] = '\r';
226 			string++;
227 		}
228 		string++;
229 	}
230 
231 	// Send the message to the console.
232 	CON_Printf("%s", printbuf);
233 
234 	va_end(argptr);
235 }
236 
237 
I_MessageBox(const char * message,const char * title)238 void I_MessageBox(const char *message, const char *title)
239 {
240 	MessageBox(NULL, message, title,
241 			   MB_ICONEXCLAMATION | MB_OK |
242 			   MB_SYSTEMMODAL | MB_SETFOREGROUND);
243 }
244 
245 
246 //
247 // I_PureRandom
248 //
I_PureRandom(void)249 int I_PureRandom(void)
250 {
251 	return ((int)time(NULL) ^ (int)I_ReadMicroSeconds()) & 0x7FFFFFFF;
252 }
253 
254 //
255 // I_ReadMicroSeconds
256 //
I_ReadMicroSeconds(void)257 u32_t I_ReadMicroSeconds(void)
258 {
259 	return (u32_t) (timeGetTime() * 1000);
260 }
261 
262 //
263 // I_Sleep
264 //
I_Sleep(int millisecs)265 void I_Sleep(int millisecs)
266 {
267 	::Sleep(millisecs);
268 }
269 
270 
271 //
272 // I_SystemShutdown
273 //
274 // -ACB- 1998/07/11 Tidying the code
275 //
I_SystemShutdown(void)276 void I_SystemShutdown(void)
277 {
278 	// make sure audio is unlocked (e.g. I_Error occurred)
279 	I_UnlockAudio();
280 
281 	I_ShutdownNetwork();
282 	I_ShutdownMusic();
283 	I_ShutdownSound();
284 	I_ShutdownControl();
285 	I_ShutdownGraphics();
286 
287 	if (logfile)
288 	{
289 		fclose(logfile);
290 		logfile = NULL;
291 	}
292 
293 	// -KM- 1999/01/31 Close the debugfile
294 	if (debugfile != NULL)
295 	{
296 		fclose(debugfile);
297 		debugfile = NULL;
298 	}
299 
300 	//ShowCursor(TRUE);
301 	FlushMessageQueue();
302 }
303 
304 
305 //--- editor settings ---
306 // vi:ts=4:sw=4:noexpandtab
307