3
* Main file for the MS-Windows port of Netrek. Contains the "main" function,
4
* as well as Windows implemenations of major Unix functions. Handles differences
5
* between NT and Win32s, specifically the lack of consoles on Win32s.
7
* Copyright (C) 1993-1995 Jonathan Shekter
18
#include "win32/string.h"
28
#pragma warn -par //so we don't get a zillion parameter never used messages
31
#define putenv _putenv
41
int PrintfSafe = 0; //Turns off printf during critical operations
43
void Wprintf(char *format,...);
44
void Wfprintfstderr(char *format, ...);
47
void WinMainCleanup();
55
/* Micro$oft, in their infinite wisdom, no longer support main(int, char**)
56
* in Win32! (or at least in the version I got). So write a WinMain that is
57
* compatable with the rest of the code. -SAC */
58
/* Well, not quite - you have to remember to set the linker to console :/
59
* At any rate, I'm leaving this here, 'cause I bet it's gonna be need
60
* before to oft long -SAC 01 Aug 1996 */
65
HINSTANCE hPrevInstance,
70
int WINAPI wWinMain(HINSTANCE MyInstance,
71
HINSTANCE hPrevInstance,
77
char *lpCmdLineCopy; // Gotta free it later :/
81
lpCmdLineCopy = calloc(1,strlen(lpCmdLine)+10);
83
strcpy(lpCmdLineCopy, "netrek.exe");
87
lpCmdLineCopy[10] = ' ';
88
strcpy(lpCmdLineCopy+11,lpCmdLine);
91
for(argc=0, c=lpCmdLineCopy; c != NULL; c++)
95
argv = calloc(argc+1, sizeof(c));
96
argv[0] = lpCmdLineCopy;
100
int t; //MSCV can do it :)
102
c = strtok(lpCmdLineCopy," ");
103
for(t=1; c; c = strtok(" ",lpCmdLineCopy),t++)
107
#else /* Non-Visual C */
109
//Our main. Does some init before calling the actual Netrek code, which
110
//now has main2() instead of main().
111
int main(int argc, char **argv)
114
WSADATA data; //Using sockets - perform WinSock startup
116
MyInstance = GetModuleHandle(NULL);
118
#ifdef SUPPORT_WIN32S
119
fWin32s = (getenv("FORCECONSOLE") ? 1 : GetVersion() & 0x80000000);
122
#endif /* Visual C */
124
//Get home path (screwny NT environ vars), and set HOME var
125
if (c=getenv("HOMEDRIVE"))
127
strcpy(HomeDir, "HOME=");
129
if (c=getenv("HOMEPATH"))
131
if (HomeDir[strlen(HomeDir)-1] != '\\')
132
strcat(HomeDir, "\\");
136
//Get the executable file directory
137
c = ExeDir + GetModuleFileName(MyInstance, ExeDir, sizeof(ExeDir)) -1;
138
while (*c != '\\') //remove filename
140
*c = 0; //remove last backslash
143
//Kick winsock into gear
144
if (WSAStartup(MAKEWORD(1,1), &data) != 0)
146
fprintf(stderr,"Could not find WINSOCK.DLL / WINSOCK initializtion failed\n");
149
if ( data.wVersion<MAKEWORD(1,1) )
151
fprintf(stderr,"Bad WINSOCK.DLL version (need at least v1.1).\n");
156
#ifdef SUPPORT_WIN32S
157
//Create the "Console" window if running on Win32s
158
W_Initialize(NULL); /* NULL == don't need a display name as not on X */
161
console = W_MakeScrollingWindow("Console", 0, 0, 80, 10, NULL, 2);
162
PrintfSafe = 1; //Now OK to printf
166
atexit(WinMainCleanup);
168
main2(argc, argv); //Call BRM main!
174
void WinMainCleanup()
176
#ifdef SUPPORT_WIN32S
179
//If we're using our own special console window,
180
//pause before closing so the user can read
181
Wprintf("Netrek/Win32 terminating...");
182
W_DestroyWindow(console);
183
PrintfSafe=0; //Console is dead
186
WSACleanup(); //Shut down our sockets
190
//***************************************************************************//
191
// Various UNIX functions that will enable the code to compile as-is without //
192
// changes - only this file added. //
193
//***************************************************************************//
198
return (int) GetCurrentProcessId();
202
//Get user ID - fugde!
208
//getpwuid() function - does it for real under NT. Just copies the given string...
209
struct passwd *getpwuid(char *getuidstuff)
211
static struct passwd pw;
212
static char name[100];
216
memset(name,0,sizeof(name));
218
/* Try to get user w/ WNetGetUser instead of GetUserName in the
219
hope that it will retrieve the user name on WFWG */
220
if ((WNetGetUser(NULL, name, &i)!=NO_ERROR ) ||
221
!stricmp(name,"Administrator") ||
222
!stricmp(name,"admin") ||
223
!stricmp(name,"root"))
225
/* Pretty lame ids - use the one given in the rc file */
227
p = getdefault("login");
239
void sleep(int seconds)
241
Sleep(seconds * 1000);
246
double rint(double r)
252
//A more useful perror(), reports last winsock error as well
253
void perror(const char *str)
255
printf("%s: errno = %d, WSALast = %d\n", str, errno, WSAGetLastError());
260
// ********************************* select ********************************
261
// This is our implementation of select, using WaitForMultipleObjects()
262
// We support W_Socket() here too. Note that we only handle readfds
263
#define W_SOCKET 0x0CABBABE // can be anything but must match mswindow.c
264
int PASCAL select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
266
HANDLE handles[FD_SETSIZE];
269
int wsocket_present = 0;
274
ms = (timeout->tv_sec<<10) + (timeout->tv_usec>>10);
275
printf("sec = %d, usec = %d\n", timeout->tv_sec, timeout->tv_usec);
280
printf("ms=%d, ", ms);
282
/* Scan through the array, copying and looking for W_Socket */
283
for (i=j=0; i<readfds->fd_count; i++)
285
if (readfds->fd_array[i] != W_SOCKET)
287
printf("handle %d, sock=%d\n", readfds->fd_array[i], sock);
288
handles[j++] = readfds->fd_array[i];
294
printf("handles=%d, handle[0]=%d, wsocket=%d\n", j, handles[0], wsocket_present);
298
/* if (wsocket_present)
300
if (W_EventsPending()) //MsgWait... does not return if there is input ready, only
303
readfds->fd_array[1] = W_SOCKET;
306
got = MsgWaitForMultipleObjects(j, handles, FALSE, // false == wait for only one object
308
if (got == WAIT_OBJECT_0+j) // == windowing event arrived
310
readfds->fd_array[0] = W_SOCKET;
315
// got = WaitForMultipleObjects(j, handles, FALSE /* wait for one only */,ms) ;
316
got = WaitForSingleObject(handles[0], ms);
318
if (got == WAIT_TIMEOUT)
321
readfds->fd_count = 0; // clear
325
readfds->fd_array[0] = handles[got-WAIT_OBJECT_0];
328
printf("Success! Returned %d\n", got);
332
#ifdef SUPPORT_WIN32S
334
//******************************** STDIO HANDLING *****************************//
335
// Under Win32s we have to do our own stdio. Yeesh!
337
//A useful function to replace printf().
338
void Wprintf(char *format,...)
342
va_start(args, format);
343
vsprintf(buf,format,args);
345
vsprintf(buf,format,args);
346
MessageBox(NULL,buf,"Netrek/Win32",MB_OK);
349
//Another function, this one to replace fprintf(stderr,...)
350
void Wfprintfstderr(char *format, ...)
354
va_start(args, format);
355
vsprintf(buf,format,args);
357
MessageBeep(MB_ICONEXCLAMATION);
358
MessageBox(NULL,buf,"Netrek/Win32: Error",MB_OK|MB_ICONEXCLAMATION);
362
/* - The following fns not needed in Win32, as we actually have a real, live console of our own
363
- But, under Win32s we don't... so... arrgh */
366
//Yet another function, this one actually IS printf() - overrides the default
367
//definition, sends it to the console window -
368
int printf(const char *format,...)
374
va_start(args, format);
375
len = vsprintf(buf,format,args);
380
if (!PrintfSafe) //Flag that helps us avoid infinite recursions and other nasties
382
MessageBox(NULL, buf, "This is a printf", MB_OK);
386
if (!W_IsMapped(console))
387
W_MapWindow(console);
388
W_WriteText(console, 0, 0, W_White, buf, len, W_RegularFont);
389
W_FlushScrollingWindow(console);
393
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, len, &junk, NULL);
398
//Arrghh our version of fwrite...
399
int myfwrite(char *buf, int count1, FILE *file)
401
register int count = count1;
404
if (fputc(*buf, file) == EOF)
405
return ((count1 - count)-1);
412
//Redriect fprintf() to stdout and stderr to our console window under Win32s
413
int fprintf(FILE *handle, const char *format,...)
419
va_start(args, format);
420
len = vsprintf(buf,format,args);
423
if (handle == stdout || handle == stderr)
429
MessageBox(NULL, buf, "This is an fprintf to stderr/stdout", MB_OK);
433
if (!W_IsMapped(console))
434
W_MapWindow(console);
435
W_WriteText(console, 0, 0, W_White, buf, len, W_RegularFont);
436
W_FlushScrollingWindow(console);
440
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, len, &junk, NULL);
443
return myfwrite(buf, len, handle);
449
//More nastyness: this time for fwrite. I hate Win32s. No consoles!
450
size_t fwrite(char *buf, int blksz, int count, FILE *handle)
454
if (handle == stdout || handle == stderr)
460
MessageBox(NULL, buf, "This is an fwrite to stderr/stdout", MB_OK);
464
if (!W_IsMapped(console))
465
W_MapWindow(console);
466
W_WriteText(console, 0, 0, W_White, buf, blksz*count, W_RegularFont);
467
W_FlushScrollingWindow(console);
471
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, blksz*count, &junk, NULL);
474
return myfwrite(buf, count*blksz, handle);