1 /* Copyright (C) 2001 by Alex Kompel <shurikk@pacbell.net> */
2 /* NetHack may be freely redistributed. See license for details. */
7 // #include "wceconf.h"
22 #define IS_LEAP(yr) (((yr)%4==0 || (yr)%100==0) && !(yr)%400==0)
23 static char _day_mo_leap[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
24 static char _day_mo[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
26 struct tm * __cdecl localtime ( const time_t *ptime )
30 if( !ptime ) return NULL;
32 _t_cnv.t_val = *ptime;
34 ptm.tm_sec = _t_cnv.tm_val.ss ; /* seconds after the minute - [0,59] */
35 ptm.tm_min = _t_cnv.tm_val.mm; /* minutes after the hour - [0,59] */
36 ptm.tm_hour = _t_cnv.tm_val.hh; /* hours since midnight - [0,23] */
37 ptm.tm_mday = _t_cnv.tm_val.dd; /* day of the month - [1,31] */
38 ptm.tm_mon = _t_cnv.tm_val.mo-1; /* months since January - [0,11] */
39 ptm.tm_year = _t_cnv.tm_val.yr; /* years since 1900 */
40 ptm.tm_wday = _t_cnv.tm_val.wd; /* days since Sunday - [0,6] */
42 ptm.tm_yday = _t_cnv.tm_val.dd; /* days since January 1 - [0,365] */
43 for( i=0; i<ptm.tm_mon; i++ )
44 ptm.tm_yday += IS_LEAP(_t_cnv.tm_val.yr+1900)?_day_mo_leap[i] : _day_mo[i] ;
46 ptm.tm_isdst = 0; /* daylight savings time flag - NOT IMPLEMENTED */
50 time_t __cdecl time(time_t * timeptr)
55 _t_cnv.tm_val.yr = stm.wYear-1900;
56 _t_cnv.tm_val.mo = stm.wMonth;
57 _t_cnv.tm_val.dd = stm.wDay;
58 _t_cnv.tm_val.hh = stm.wHour;
59 _t_cnv.tm_val.mm = stm.wMinute;
60 _t_cnv.tm_val.ss = stm.wSecond;
61 _t_cnv.tm_val.wd = stm.wDayOfWeek;
64 *timeptr = _t_cnv.t_val;
68 /*------------------------------------------------------------------------------*/
70 /* Hack io.h function with stdio.h functions */
71 /* ASSUMPTION : int can hold FILE* */
72 static TCHAR _nh_cwd[MAX_PATH];
73 const int MAGIC_OFFSET=5;
74 #define FILE_TABLE_SIZE 256
75 static HANDLE _nh_file_table[FILE_TABLE_SIZE];
76 static int file_pointer = -1;
78 static HANDLE get_file_handle(int i)
81 if( i>=0 && i<FILE_TABLE_SIZE )
82 return _nh_file_table[i];
84 return INVALID_HANDLE_VALUE;
87 static int alloc_file_handle(HANDLE h)
90 if( file_pointer==-1 ) {
92 for(i=0; i<FILE_TABLE_SIZE; i++ )
93 _nh_file_table[i] = INVALID_HANDLE_VALUE;
96 i = (file_pointer+1)%FILE_TABLE_SIZE;
97 while(_nh_file_table[i]!=INVALID_HANDLE_VALUE ) {
98 if( i==file_pointer ) {
99 MessageBox(NULL, _T("Ran out of file handles."), _T("Fatal Error"), MB_OK);
102 i = (i+1) % FILE_TABLE_SIZE;
106 _nh_file_table[file_pointer] = h;
107 return file_pointer+MAGIC_OFFSET;
110 int __cdecl close(int f) {
113 if( f<0 || f>=FILE_TABLE_SIZE ) return -1;
114 retval = (CloseHandle(_nh_file_table[f])? 0 : -1);
115 _nh_file_table[f] = INVALID_HANDLE_VALUE;
119 int __cdecl creat(const char *fname , int mode)
122 TCHAR wbuf[MAX_PATH+1];
123 ZeroMemory(wbuf, sizeof(wbuf));
124 NH_A2W(fname, wbuf, MAX_PATH);
128 GENERIC_READ | GENERIC_WRITE,
132 FILE_ATTRIBUTE_NORMAL,
135 if( f==INVALID_HANDLE_VALUE ) return -1;
136 else return alloc_file_handle(f);
139 int __cdecl eof(int f)
142 HANDLE p = get_file_handle(f);
144 if( f==-1 ) return -1;
146 fpos = SetFilePointer(p, 0, NULL, FILE_CURRENT);
147 fsize = SetFilePointer(p, 0, NULL, FILE_END);
148 if( fpos==0xFFFFFFFF || fsize==0xFFFFFFFF ) return -1;
149 if( fpos==fsize ) return 1;
151 SetFilePointer(p, fpos, NULL, FILE_BEGIN);
156 long __cdecl lseek( int f, long offset, int origin )
158 HANDLE p = get_file_handle(f);
162 fpos = SetFilePointer(p, offset, NULL, FILE_BEGIN);
165 fpos = SetFilePointer(p, offset, NULL, FILE_CURRENT);
168 fpos = SetFilePointer(p, offset, NULL, FILE_END);
174 if( fpos==0xFFFFFFFF ) return -1;
175 else return (long)fpos;
178 int __cdecl open( const char *filename, int oflag, ... )
180 TCHAR fname[MAX_PATH+1];
181 TCHAR path[MAX_PATH+1];
186 /* O_TEXT is not supported */
189 * decode the access flags
191 switch( oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR) ) {
193 case _O_RDONLY: /* read access */
194 fileaccess = GENERIC_READ;
196 case _O_WRONLY: /* write access */
197 fileaccess = GENERIC_READ | GENERIC_WRITE;
199 case _O_RDWR: /* read and write access */
200 fileaccess = GENERIC_READ | GENERIC_WRITE;
202 default: /* error, bad oflag */
207 * decode open/create method flags
209 switch ( oflag & (_O_CREAT | _O_EXCL | _O_TRUNC) ) {
211 case _O_EXCL: // ignore EXCL w/o CREAT
212 filecreate = OPEN_EXISTING;
216 filecreate = OPEN_ALWAYS;
219 case _O_CREAT | _O_EXCL:
220 case _O_CREAT | _O_TRUNC | _O_EXCL:
221 filecreate = CREATE_NEW;
225 case _O_TRUNC | _O_EXCL: // ignore EXCL w/o CREAT
226 filecreate = TRUNCATE_EXISTING;
229 case _O_CREAT | _O_TRUNC:
230 filecreate = CREATE_ALWAYS;
237 /* assemple the file name */
238 ZeroMemory(fname, sizeof(fname));
239 ZeroMemory(path, sizeof(path));
240 NH_A2W(filename, fname, MAX_PATH);
241 if( *filename!='\\' && *filename!='/' ) {
242 _tcscpy(path, _nh_cwd);
243 _tcsncat(path, _T("\\"), MAX_PATH - _tcslen(path));
245 _tcsncat(path, fname, MAX_PATH - _tcslen(path));
248 * try to open/create the file
250 if ( (f = CreateFile( path,
255 FILE_ATTRIBUTE_NORMAL,
257 == INVALID_HANDLE_VALUE )
262 if( !(oflag & O_APPEND) ) SetFilePointer(f, 0, NULL, FILE_BEGIN);
263 return alloc_file_handle(f);
266 int __cdecl read( int f, void *buffer, unsigned int count )
268 HANDLE p = get_file_handle(f);
270 if( !ReadFile(p, buffer, count, &bytes_read, NULL) )
273 return (int)bytes_read;
276 int __cdecl unlink(const char * filename)
278 TCHAR wbuf[MAX_PATH+1];
279 TCHAR fname[MAX_PATH+1];
281 ZeroMemory(wbuf, sizeof(wbuf));
282 ZeroMemory(fname, sizeof(fname));
283 NH_A2W(filename, wbuf, MAX_PATH);
284 if( *filename!='\\' && *filename!='/' ) {
285 _tcscpy(fname, _nh_cwd);
286 _tcsncat(fname, _T("\\"), MAX_PATH - _tcslen(fname));
288 _tcsncat(fname, wbuf, MAX_PATH - _tcslen(fname));
290 return !DeleteFileW(fname);
293 int __cdecl write( int f, const void *buffer, unsigned int count )
295 HANDLE p = get_file_handle(f);
297 if( !WriteFile(p, buffer, count, &bytes_written, NULL) )
300 return (int)bytes_written;
303 int __cdecl rename( const char *oldname, const char *newname )
305 WCHAR f1[MAX_PATH+1];
306 WCHAR f2[MAX_PATH+1];
307 ZeroMemory(f1, sizeof(f1));
308 ZeroMemory(f2, sizeof(f2));
309 MultiByteToWideChar(CP_ACP, 0, oldname, -1, f1, MAX_PATH);
310 MultiByteToWideChar(CP_ACP, 0, newname, -1, f2, MAX_PATH);
311 return !MoveFile(f1, f2);
314 int __cdecl access( const char *path, int mode )
318 ZeroMemory(f, sizeof(f));
319 MultiByteToWideChar(CP_ACP, 0, path, -1, f, MAX_PATH);
321 attr = GetFileAttributes(f);
322 if( attr == (DWORD)-1 ) return -1;
324 if ( (attr & FILE_ATTRIBUTE_READONLY) && (mode & 2) )
330 int chdir( const char *dirname )
332 ZeroMemory(_nh_cwd, sizeof(_nh_cwd));
333 NH_A2W(dirname, _nh_cwd, MAX_PATH);
337 char *getcwd( char *buffer, int maxlen )
339 if( maxlen<(int)_tcslen(_nh_cwd) ) return NULL;
340 else return NH_W2A(_nh_cwd, buffer, maxlen);
343 /*------------------------------------------------------------------------------*/
347 /*------------------------------------------------------------------------------*/
349 * Chdrive() changes the default drive.
358 * This is used in nhlan.c to implement some of the LAN_FEATURES.
360 char *get_username(lan_username_size)
361 int *lan_username_size;
363 static char username_buffer[BUFSZ];
364 strcpy(username_buffer, "nhsave");
365 return username_buffer;
384 #if defined(WIN_CE_PS2xx) || defined(WIN32_PLATFORM_HPCPRO)
385 int __cdecl isupper(int c)
392 NH_A2W(str, wstr, 1);
393 return iswupper(wstr[0]);
396 int __cdecl isdigit(int c)
398 return ('0' <= c && c <= '9');
401 int __cdecl isxdigit(int c)
403 return (('0' <= c && c <= '9') ||
404 ('a' <= c && c <= 'f') ||
405 ('A' <= c && c <= 'F'));
408 int __cdecl isspace(int c)
415 NH_A2W(str, wstr, 1);
416 return iswspace(wstr[0]);
419 int __cdecl isprint(int c)
426 NH_A2W(str, wstr, 1);
427 return iswprint(wstr[0]);
430 char* __cdecl _strdup(const char* s)
433 p = malloc(strlen(s)+1);
437 char* __cdecl strrchr( const char *s, int c )
441 w = wcsrchr(NH_A2W(s, wstr, 1024), c);
442 if(w) return (char*)(s + (w - wstr));
446 int __cdecl _stricmp(const char* a, const char* b)
448 return strncmpi(a, b, 65535u);
453 #if defined(WIN_CE_PS2xx)
454 /* stdio.h functions are missing from PAlm Size PC SDK 1.2 (SH3 and MIPS) */
456 #pragma warning(disable:4273)
458 FILE * __cdecl fopen(const char* filename, const char *mode)
464 /* First mode character must be 'r', 'w', or 'a'. */
467 modeflag = _O_RDONLY;
470 modeflag = _O_WRONLY | _O_CREAT | _O_TRUNC;
473 modeflag = _O_WRONLY | _O_CREAT | _O_APPEND;
480 while(*++mode && whileflag)
484 if (modeflag & _O_RDWR)
488 modeflag &= ~(_O_RDONLY | _O_WRONLY);
493 if (modeflag & (_O_TEXT | _O_BINARY))
496 modeflag |= _O_BINARY;
499 case 't': /* not supported */
508 if ((filedes = open(filename, modeflag))==-1) return NULL;
510 return (FILE*)filedes;
513 int __cdecl fscanf(FILE *f , const char *format, ...)
515 /* Format spec: %[*] [width] [l] type ] */
528 #define RETURN_SCANF(i) { va_end(args); return i; }
529 #define NEXT_CHAR(f) (n_read++, fgetc(f))
531 va_start(args, format);
535 while( ch && sch!=EOF ) {
537 while( ch && isspace(ch) ) ch = *format++;
538 while( sch!=EOF && isspace(sch) ) sch = NEXT_CHAR(f);
545 if( sch!=ch ) RETURN_SCANF(matched);
552 if( sch!='%' ) RETURN_SCANF(matched);
558 /* read skip flag - '*' */
566 while(ch && isdigit(ch)) {
567 width = width*10 + (ch-'0');
582 *(va_arg(args, char*))=sch;
590 while(sch!=EOF && isspace(sch)) sch=NEXT_CHAR(f);
591 while(sch!=EOF && isdigit(sch) && --width>=0) { *p++ = sch; sch=NEXT_CHAR(f); }
595 if( modifier=='l' ) {
596 *(va_arg(args, long*))=wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 10);
598 *(va_arg(args, int*))=wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 10);
604 while(sch!=EOF && isspace(sch)) sch=NEXT_CHAR(f);
605 while(sch!=EOF && isxdigit(sch) && --width>=0) { *p++ = sch; sch=NEXT_CHAR(f); }
609 if( modifier=='l' ) {
610 *(va_arg(args, long*))=wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 16);
612 *(va_arg(args, int*))=wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 16);
617 *(va_arg(args, int*)) = n_read;
622 while(sch!=EOF && !isspace(sch) && --width>=0) { sch=NEXT_CHAR(f); }
624 p = va_arg(args, char*);
625 while(sch!=EOF && !isspace(sch) && --width>=0) { *p++ = sch; sch=NEXT_CHAR(f); }
635 ZeroMemory(pattern, sizeof(pattern));
638 /* try to parse '^' modifier */
640 if( ch=='^' ) { negate=1; ch=*format++; }
642 if( ch==0 ) RETURN_SCANF(EOF);
644 for( ; ch && ch!=']'; ch = *format++ ) {
645 /* try to parse range: a-z */
646 if( format[0]=='-' &&
647 format[1] && format[1]!=']' ) {
652 if(!strchr(pattern, (char)start))
657 if(!strchr(pattern, (char)ch)) *p++ = (char)ch;
662 while(sch!=EOF && strchr(pattern, sch) && --width>=0) { sch=NEXT_CHAR(f); }
664 p = va_arg(args, char*);
666 while(sch!=EOF && !strchr(pattern, sch) && --width>=0) { *p++ = sch; sch=NEXT_CHAR(f); }
668 while(sch!=EOF && strchr(pattern, sch) && --width>=0) { *p++ = sch; sch=NEXT_CHAR(f); }
684 fseek(f, -1, SEEK_CUR);
685 RETURN_SCANF(matched);
691 int __cdecl fprintf(FILE *f , const char *format, ...)
696 if( !f || !format ) return 0;
698 va_start(args, format);
699 retval = vfprintf(f, format, args);
705 int __cdecl vfprintf(FILE* f, const char *format, va_list args)
710 if( !f || !format ) return 0;
712 retval = vsprintf(buf, format, args);
714 write((int)f, buf, strlen(buf));
719 int __cdecl fgetc(FILE * f)
725 if( read(fh, &c, 1)==1 ) return c;
729 char * __cdecl fgets(char *s, int size, FILE *f)
731 /* not the best performance but it will do for now...*/
733 if( !f || !s || size==0 ) return NULL;
735 if( (c = fgetc(f))==EOF ) return NULL;
744 int __cdecl printf(const char *format, ...)
749 if( !format ) return 0;
751 va_start(args, format);
752 retval = vprintf(format, args);
758 int __cdecl vprintf(const char *format, va_list args)
763 retval = vsprintf(buf, format, args);
768 // int __cdecl putchar(int);
769 int __cdecl puts(const char * s)
772 NH_A2W(s, wbuf, 4096);
773 MessageBox(NULL, wbuf, _T("stdout"), MB_OK);
777 FILE* __cdecl _getstdfilex(int desc)
782 int __cdecl fclose(FILE * f)
785 return close((int)f)==-1? EOF : 0;
788 size_t __cdecl fread(void *p, size_t size, size_t count, FILE *f)
791 if(!f || !p || size==0 || count==0) return 0;
792 read_bytes = read((int)f, p, size*count);
793 return read_bytes>0? (read_bytes/size) : 0;
796 size_t __cdecl fwrite(const void *p, size_t size, size_t count, FILE * f)
799 if(!f || !p || size==0 || count==0) return 0;
800 write_bytes = write((int)f, p, size*count);
801 return write_bytes>0? write_bytes/size : 0;
804 int __cdecl fflush(FILE *f)
809 int __cdecl feof(FILE *f)
811 return (f && eof((int)f)==0)? 0 : 1;
814 int __cdecl fseek(FILE *f, long offset, int from)
816 return (f && lseek((int)f, offset, from)>=0)? 0 : 1;
819 long __cdecl ftell(FILE * f)
821 return f? lseek((int)f, 0, SEEK_CUR) : -1;