1 /*
2 Copyright (C) 1994-1995 Apogee Software, Ltd.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 */
20 
21 #include "rt_def.h"
22 
23 #ifdef DOS
24 #include <malloc.h>
25 #include <dos.h>
26 #include <conio.h>
27 #include <io.h>
28 #include <direct.h>
29 #elif USE_SDL
30 #include "SDL.h"
31 #endif
32 
33 #include <stdarg.h>
34 #include <fcntl.h>
35 #include <errno.h>
36 #include <string.h>
37 #include <stdio.h>
38 #include <ctype.h>
39 #include <stdlib.h>
40 #include <sys/stat.h>
41 #include <time.h>
42 #include "watcom.h"
43 #include "_rt_util.h"
44 #include "rt_util.h"
45 #include "isr.h"
46 #include "z_zone.h"
47 #include "rt_dr_a.h"
48 #include "rt_in.h"
49 #include "rt_main.h"
50 #include "scriplib.h"
51 #include "rt_menu.h"
52 #include "rt_playr.h"
53 #include "version.h"
54 #include "develop.h"
55 #include "rt_vid.h"
56 #include "rt_view.h"
57 #include "modexlib.h"
58 #include "rt_cfg.h"
59 //MED
60 #include "memcheck.h"
61 
62 int    egacolor[16];
63 byte   *  origpal;
64 FILE   *  errout;
65 FILE   *  debugout;
66 FILE   *  mapdebugout;
67 
68 static boolean SoftErrorStarted=false;
69 static boolean DebugStarted=false;
70 static boolean MapDebugStarted=false;
71 
72 static unsigned char egargb[48]={ 0x00,0x00,0x00,
73 									 0x00,0x00,0xab,
74                             0x00,0xab,0x00,
75                             0x00,0xab,0xab,
76                             0xab,0x00,0x00,
77                             0xab,0x00,0xab,
78                             0xab,0x57,0x00,
79                             0xab,0xab,0xab,
80                             0x57,0x57,0x57,
81                             0x57,0x57,0xff,
82                             0x57,0xff,0x57,
83                             0x57,0xff,0xff,
84                             0xff,0x57,0x57,
85                             0xff,0x57,0xff,
86                             0xff,0xff,0x57,
87 									 0xff,0xff,0xff};
88 
89 extern const byte * ROTT_ERR;
90 
91 #if (DEVELOPMENT == 1)
92 int TotalStaticMemory=0;
93 #endif
94 
95 #define SWAP(a,b) \
96    {              \
97    a=(a)^(b);     \
98    b=(a)^(b);     \
99    a=(a)^(b);     \
100    }              \
101 
102 //******************************************************************************
103 //
104 // FindDistance
105 //
106 //******************************************************************************
107 
FindDistance(int ix,int iy)108 int FindDistance(int ix, int iy)
109 {
110   int   t;
111 
112   ix= abs(ix);        /* absolute values */
113   iy= abs(iy);
114 
115   if (ix<iy)
116      SWAP(ix,iy);
117 
118   t = iy + (iy>>1);
119 
120   return (ix - (ix>>5) - (ix>>7)  + (t>>2) + (t>>6));
121 }
122 
123 
124 //******************************************************************************
125 //
126 // Find_3D_Distance
127 //
128 //******************************************************************************
129 
Find_3D_Distance(int ix,int iy,int iz)130 int Find_3D_Distance(int ix, int iy, int iz)
131    {
132    int   t;
133 
134    ix= abs(ix);           /* absolute values */
135    iy= abs(iy);
136    iz= abs(iz);
137 
138    if (ix<iy)
139      SWAP(ix,iy);
140 
141    if (ix<iz)
142      SWAP(ix,iz);
143 
144    t = iy + iz;
145 
146    return (ix - (ix>>4) + (t>>2) + (t>>3));
147    }
148 
149 //******************************************************************************
150 //
151 // atan2_appx
152 //
153 //******************************************************************************
154 
atan2_appx(int dx,int dy)155 int atan2_appx(int dx, int dy)
156 {int absdx, absdy;
157  fixed angle;
158  fixed ratio;
159 
160 
161  if (!(dx||dy))
162   return 0;
163  absdx = abs(dx);
164  absdy = abs(dy);
165  if (absdx >= absdy)
166   ratio = FixedDiv2(absdy,absdx);
167  else
168   ratio = FixedDiv2(absdx,absdy);
169 
170  if (dx >= 0)
171   {if (dy >= 0)
172 	 {if (absdx >= absdy)
173 		angle = ratio;	    // 1st octant
174 	  else
175 		angle = (2<<16) - ratio; // 2nd octant
176 	 }
177 	else
178 	 {if (absdx >= absdy)
179 		angle = (8<<16) - ratio; // 8th octant
180 	  else
181 		angle = (6<<16) + ratio; // 7th octant
182 	 }
183   }
184  else
185   {if (dy >= 0)
186 	 {if (absdx >= absdy)
187 		angle = (4<<16) - ratio; // 4th octant
188 	  else
189 		angle = (2<<16) + ratio; // 3rd octant
190 	 }
191 	else
192 	 {if (absdx >= absdy)
193 		angle = (4<<16) + ratio; // 5th octant
194 	  else
195 		angle = (6<<16) - ratio; // 6th octant
196 	 }
197   }
198 
199  return (((int)FixedMul(angle,ANGLESDIV8))&(FINEANGLES-1));
200 }
201 
202 
203 
204 //******************************************************************************
205 //
206 // StringsNotEqual
207 //
208 //******************************************************************************
StringsNotEqual(char * s1,char * s2,int length)209 boolean StringsNotEqual (char * s1, char * s2, int length)
210 {
211    int i;
212 
213    for (i=0;i<length;i++)
214       if (s1[i]!=s2[i])
215          return true;
216    return false;
217 }
218 
219 
220 
markgetch(void)221 void markgetch( void )
222 {
223    int done;
224    int i;
225 
226    done=0;
227    while (done==0)
228       {
229       IN_UpdateKeyboard ();
230       for (i=0;i<127;i++)
231          if (Keyboard[i]==1)
232             done=i;
233       }
234    while (Keyboard[done])
235       IN_UpdateKeyboard ();
236 }
237 
238 /*
239 ====================
240 =
241 = FindEGAColors
242 =
243 ====================
244 */
245 
FindEGAColors(void)246 void FindEGAColors ( void )
247 {
248    int i;
249 
250 	for (i=0;i<16;i++)
251 		egacolor[i]=BestColor((int)egargb[i*3],(int)egargb[i*3+1],(int)egargb[i*3+2],origpal);
252 }
253 
254 //===========================================================================
255 
256 
BestColor(int r,int g,int b,byte * palette)257 byte BestColor (int r, int g, int b, byte *palette)
258 {
259 	int	i;
260 	long	dr, dg, db;
261 	long	bestdistortion, distortion;
262 	int	bestcolor;
263 	byte	*pal;
264 
265 //
266 // let any color go to 0 as a last resort
267 //
268    bestdistortion = ( (long)WeightR*r*r + (long)WeightG*g*g + (long)WeightB*b*b )*2;
269 	bestcolor = 0;
270 
271 	pal = &palette[0];
272 	for (i=0 ; i<= 255 ; i++,pal+=3)
273 	{
274 		dr = r - (int)pal[0];
275 		dg = g - (int)pal[1];
276 		db = b - (int)pal[2];
277       distortion = WeightR*dr*dr + WeightG*dg*dg + WeightB*db*db;
278 		if (distortion < bestdistortion)
279 		{
280 			if (!distortion)
281 				return i;		// perfect match
282 
283 			bestdistortion = distortion;
284 			bestcolor = i;
285 		}
286 	}
287 
288 	return bestcolor;
289 }
290 
ClearGraphicsScreen(void)291 void ClearGraphicsScreen( void )
292 {
293 VL_ClearVideo(0);
294 }
295 
ClearBuffer(char * buf,int size)296 void ClearBuffer( char * buf, int size )
297 {
298         memset(buf,0,size);
299 }
300 
301 /*
302 =============================================================================
303 
304 						MISC FUNCTIONS
305 
306 =============================================================================
307 */
308 
309 /*
310 =================
311 =
312 = Error
313 =
314 = For abnormal program terminations
315 =
316 =================
317 */
318 
Error(char * error,...)319 void Error (char *error, ...)
320 {
321    char msgbuf[300];
322 	va_list	argptr;
323    char i;
324    int size;
325    char * sptr;
326    char buf[30];
327    int handle;
328    int x,y;
329    int level;
330    static int inerror = 0;
331    char filename[ 128 ];
332 
333 
334    inerror++;
335    if (inerror > 1)
336       return;
337 
338 
339 	SetTextMode ();
340 #ifdef DOS
341    memcpy ((byte *)0xB8000, &ROTT_ERR, 160*7);
342 #elif defined (ANSIESC)
343    DisplayTextSplash (&ROTT_ERR, 7);
344 #endif
345    memset (msgbuf, 0, 300);
346 
347 #ifdef DOS
348    px = ERRORVERSIONCOL-1;
349    py = ERRORVERSIONROW;
350 #if (SHAREWARE == 1)
351    UL_printf ("S");
352 #else
353    UL_printf ("R");
354 #endif
355 
356    px = ERRORVERSIONCOL;
357    py = ERRORVERSIONROW;
358 #if (BETA == 1)
359    UL_printf ("�");
360 #else
361    UL_printf (itoa(ROTTMAJORVERSION,&buf[0],10));
362 #endif
363 
364    // Skip the dot
365    px++;
366 
367    UL_printf (itoa(ROTTMINORVERSION,&buf[0],10));
368 #endif
369 
370 	va_start (argptr, error);
371    vsprintf (&msgbuf[0], error, argptr);
372 	va_end (argptr);
373 
374    scriptbuffer = &msgbuf[0];
375 	size = strlen (msgbuf);
376 
377 	sptr = script_p = scriptbuffer;
378 	scriptend_p = script_p + size;
379 	scriptline = 1;
380 	endofscript = false;
381 	tokenready = false;
382 
383    px = ERRORCOL;
384    py = ERRORROW;
385 
386    GetToken (true);
387    while (!endofscript)
388    {
389       if ((script_p - sptr) >= 60)
390       {
391          px = ERRORCOL;
392          py++;
393          sptr = script_p;
394       }
395 
396       UL_printf (token);
397       px++;                //SPACE
398       GetToken (true);
399    }
400 
401 #ifdef ANSIESC
402    for (i = 0; i < 8; i++)
403       printf ("\n");
404 #endif
405 
406    if (player!=NULL)
407       {
408       printf ("Player X     = %lx\n", (long int)player->x);
409       printf ("Player Y     = %lx\n", (long int)player->y);
410       printf ("Player Angle = %lx\n\n", (long int)player->angle);
411       }
412    printf ("Episode      = %ld\n", (long int)gamestate.episode);
413 
414    if (gamestate.episode > 1)
415       level = (gamestate.mapon+1) - ((gamestate.episode-1) << 3);
416    else
417       level = gamestate.mapon+1;
418 
419    printf ("Area         = %ld\n", (long int)level);
420 
421    ShutDown();	// DDOI - moved this so that it doesn't try to access player
422    		// which is freed by this function.
423 
424 #ifdef DOS
425    GetPathFromEnvironment( filename, ApogeePath, ERRORFILE );
426    handle=SafeOpenAppend ( filename );
427    for (y=0;y<16;y++)
428       {
429       for (x=0;x<160;x+=2)
430          SafeWrite(handle,(byte *)0xB8000+(y*160)+x,1);
431       i=10;
432       SafeWrite(handle,&i,1);
433       i=13;
434       SafeWrite(handle,&i,1);
435       }
436 
437    close(handle);
438 #endif
439 
440    if ( SOUNDSETUP )
441       {
442       getch();
443       }
444 
445    #if USE_SDL
446    SDL_Quit();
447    #endif
448 
449    exit (1);
450 }
451 
452 //#if (SOFTERROR==1)
453 
454 /*
455 =================
456 =
457 = SoftwareError
458 =
459 =================
460 */
SoftwareError(char * error,...)461 void SoftwareError (char *error, ...)
462 {
463 	va_list	argptr;
464 
465 	if (SoftErrorStarted==false)
466       return;
467 	va_start (argptr, error);
468    vfprintf (errout, error, argptr);
469 	va_end (argptr);
470 }
471 
472 //#endif
473 
474 
475 //#if (DEBUG == 1)
476 
477 /*
478 =================
479 =
480 = DebugError
481 =
482 =================
483 */
DebugError(char * error,...)484 void DebugError (char *error, ...)
485 {
486 	va_list	argptr;
487 
488    if (DebugStarted==false)
489       return;
490 	va_start (argptr, error);
491    vfprintf (debugout, error, argptr);
492 	va_end (argptr);
493 }
494 
495 //#endif
496 
497 /*
498 =================
499 =
500 = OpenSoftError
501 =
502 =================
503 */
OpenSoftError(void)504 void OpenSoftError ( void )
505 {
506   errout = fopen(SOFTERRORFILE,"wt+");
507   SoftErrorStarted=true;
508 }
509 
510 /*
511 =================
512 =
513 = MapDebug
514 =
515 =================
516 */
MapDebug(char * error,...)517 void MapDebug (char *error, ...)
518 {
519 	va_list	argptr;
520 
521    if (MapDebugStarted==false)
522       return;
523 	va_start (argptr, error);
524    vfprintf (mapdebugout, error, argptr);
525 	va_end (argptr);
526 }
527 
528 /*
529 =================
530 =
531 = OpenMapDebug
532 =
533 =================
534 */
OpenMapDebug(void)535 void OpenMapDebug ( void )
536 {
537   char filename[ 128 ];
538 
539   if (MapDebugStarted==true)
540      return;
541   GetPathFromEnvironment( filename, ApogeePath, MAPDEBUGFILE );
542   mapdebugout = fopen(filename,"wt+");
543   MapDebugStarted=true;
544 }
545 
546 
547 /*
548 =================
549 =
550 = StartupSoftError
551 =
552 =================
553 */
StartupSoftError(void)554 void StartupSoftError ( void )
555 {
556 #if (DEBUG == 1)
557   if (DebugStarted==false)
558      {
559      debugout = fopen(DEBUGFILE,"wt+");
560      DebugStarted=true;
561      }
562 #endif
563 #if (SOFTERROR == 1)
564   if (SoftErrorStarted==false)
565      OpenSoftError();
566 #endif
567 }
568 
569 /*
570 =================
571 =
572 = ShutdownSoftError
573 =
574 =================
575 */
ShutdownSoftError(void)576 void ShutdownSoftError ( void )
577 {
578   if (DebugStarted==true)
579      {
580      fclose(debugout);
581      DebugStarted=false;
582      }
583   if (SoftErrorStarted==true)
584      {
585      fclose(errout);
586      SoftErrorStarted=false;
587      }
588   if (MapDebugStarted==true)
589      {
590      fclose(mapdebugout);
591      MapDebugStarted=false;
592      }
593 }
594 
595 
596 /*
597 =================
598 =
599 = CheckParm
600 =
601 = Checks for the given parameter in the program's command line arguments
602 =
603 = Returns the argument number (1 to argc-1) or 0 if not present
604 =
605 =================
606 */
607 
CheckParm(char * check)608 int CheckParm (char *check)
609 {
610 	int		i;
611 	char	*parm;
612 
613 	for (i = 1;i<_argc;i++)
614 	{
615 		parm = _argv[i];
616 		if ( !isalpha(*parm) )	// skip - / \ etc.. in front of parm
617          {
618          parm++;
619          if (!*parm)
620 				continue;		// parm was only one char
621          }
622 
623 		if ( !_fstricmp(check,parm) )
624 			return i;
625 	}
626 
627 	return 0;
628 }
629 
630 
631 
SafeOpenAppend(char * _filename)632 int SafeOpenAppend (char *_filename)
633 {
634 	int	handle;
635     char filename[MAX_PATH];
636     strncpy(filename, _filename, sizeof (filename));
637     filename[sizeof (filename) - 1] = '\0';
638     FixFilePath(filename);
639 
640 	handle = open(filename,O_RDWR | O_BINARY | O_CREAT | O_APPEND
641 	, S_IREAD | S_IWRITE);
642 
643 	if (handle == -1)
644 		Error ("Error opening for append %s: %s",filename,strerror(errno));
645 
646 	return handle;
647 }
648 
SafeOpenWrite(char * _filename)649 int SafeOpenWrite (char *_filename)
650 {
651 	int	handle;
652     char filename[MAX_PATH];
653     strncpy(filename, _filename, sizeof (filename));
654     filename[sizeof (filename) - 1] = '\0';
655     FixFilePath(filename);
656 
657 	handle = open(filename,O_RDWR | O_BINARY | O_CREAT | O_TRUNC
658 	, S_IREAD | S_IWRITE);
659 
660 	if (handle == -1)
661 		Error ("Error opening %s: %s",filename,strerror(errno));
662 
663 	return handle;
664 }
665 
SafeOpenRead(char * _filename)666 int SafeOpenRead (char *_filename)
667 {
668 	int	handle;
669     char filename[MAX_PATH];
670     strncpy(filename, _filename, sizeof (filename));
671     filename[sizeof (filename) - 1] = '\0';
672     FixFilePath(filename);
673 
674 	handle = open(filename,O_RDONLY | O_BINARY);
675 
676 	if (handle == -1)
677 		Error ("Error opening %s: %s",filename,strerror(errno));
678 
679 	return handle;
680 }
681 
682 
SafeRead(int handle,void * buffer,long count)683 void SafeRead (int handle, void *buffer, long count)
684 {
685 	unsigned	iocount;
686 
687 	while (count)
688 	{
689 		iocount = count > 0x8000 ? 0x8000 : count;
690 		if (read (handle,buffer,iocount) != (int)iocount)
691 			Error ("File read failure reading %ld bytes",count);
692 		buffer = (void *)( (byte *)buffer + iocount );
693 		count -= iocount;
694 	}
695 }
696 
697 
SafeWrite(int handle,void * buffer,long count)698 void SafeWrite (int handle, void *buffer, long count)
699 {
700 	unsigned	iocount;
701 
702 	while (count)
703 	{
704 		iocount = count > 0x8000 ? 0x8000 : count;
705 		if (write (handle,buffer,iocount) != (int)iocount)
706 			Error ("File write failure writing %ld bytes",count);
707 		buffer = (void *)( (byte *)buffer + iocount );
708 		count -= iocount;
709 	}
710 }
711 
SafeWriteString(int handle,char * buffer)712 void SafeWriteString (int handle, char * buffer)
713 {
714 	unsigned	iocount;
715 
716    iocount=strlen(buffer);
717 	if (write (handle,buffer,iocount) != (int)iocount)
718 			Error ("File write string failure writing %s\n",buffer);
719 }
720 
SafeMalloc(long size)721 void *SafeMalloc (long size)
722 {
723 	void *ptr;
724 
725    if (zonememorystarted==false)
726       Error("Called SafeMalloc without starting zone memory\n");
727 	ptr = Z_Malloc (size,PU_STATIC,NULL);
728 
729 	if (!ptr)
730       Error ("SafeMalloc failure for %lu bytes",size);
731 
732 	return ptr;
733 }
734 
SafeLevelMalloc(long size)735 void *SafeLevelMalloc (long size)
736 {
737 	void *ptr;
738 
739    if (zonememorystarted==false)
740       Error("Called SafeLevelMalloc without starting zone memory\n");
741    ptr = Z_LevelMalloc (size,PU_STATIC,NULL);
742 
743 	if (!ptr)
744       Error ("SafeLevelMalloc failure for %lu bytes",size);
745 
746 	return ptr;
747 }
748 
SafeFree(void * ptr)749 void SafeFree (void * ptr)
750 {
751    if ( ptr == NULL )
752       Error ("SafeFree : Tried to free a freed pointer\n");
753 
754 	Z_Free (ptr);
755 }
756 
757 /*
758 ==============
759 =
760 = LoadFile
761 =
762 ==============
763 */
764 
LoadFile(char * filename,void ** bufferptr)765 long	LoadFile (char *filename, void **bufferptr)
766 {
767 	int		handle;
768 	long	length;
769 
770 	handle = SafeOpenRead (filename);
771 	length = filelength (handle);
772 	*bufferptr = SafeMalloc (length);
773 	SafeRead (handle,*bufferptr, length);
774 	close (handle);
775 	return length;
776 }
777 
778 
779 /*
780 ==============
781 =
782 = SaveFile
783 =
784 ==============
785 */
786 
SaveFile(char * filename,void * buffer,long count)787 void	SaveFile (char *filename, void *buffer, long count)
788 {
789 	int		handle;
790 
791 	handle = SafeOpenWrite (filename);
792 	SafeWrite (handle, buffer, count);
793 	close (handle);
794 }
795 
796 
FixFilePath(char * filename)797 void FixFilePath(char *filename)
798 {
799 #if PLATFORM_UNIX
800     char *ptr;
801     char *lastsep = filename;
802 
803     if ((!filename) || (*filename == '\0'))
804         return;
805 
806     if (access(filename, F_OK) == 0)  /* File exists; we're good to go. */
807         return;
808 
809     for (ptr = filename; 1; ptr++)
810     {
811         if (*ptr == '\\')
812             *ptr = PATH_SEP_CHAR;
813 
814         if ((*ptr == PATH_SEP_CHAR) || (*ptr == '\0'))
815         {
816             char pch = *ptr;
817             struct dirent *dent = NULL;
818             DIR *dir;
819 
820             if ((pch == PATH_SEP_CHAR) && (*(ptr + 1) == '\0'))
821                 return; /* eos is pathsep; we're done. */
822 
823             if (lastsep == ptr)
824                 continue;  /* absolute path; skip to next one. */
825 
826             *ptr = '\0';
827             if (lastsep == filename) {
828                 dir = opendir((*lastsep == PATH_SEP_CHAR) ? ROOTDIR : CURDIR);
829 
830                 if (*lastsep == PATH_SEP_CHAR) {
831                     lastsep++;
832                 }
833             }
834             else
835             {
836                 *lastsep = '\0';
837                 dir = opendir(filename);
838                 *lastsep = PATH_SEP_CHAR;
839                 lastsep++;
840             }
841 
842             if (dir == NULL)
843             {
844                 *ptr = PATH_SEP_CHAR;
845                 return;  /* maybe dir doesn't exist? give up. */
846             }
847 
848             while ((dent = readdir(dir)) != NULL)
849             {
850                 if (strcasecmp(dent->d_name, lastsep) == 0)
851                 {
852                     /* found match; replace it. */
853                     strcpy(lastsep, dent->d_name);
854                     break;
855                 }
856             }
857 
858             closedir(dir);
859             *ptr = pch;
860             lastsep = ptr;
861 
862             if (dent == NULL)
863                 return;  /* no match. oh well. */
864 
865             if (pch == '\0')  /* eos? */
866                 return;
867         }
868     }
869 #endif
870 }
871 
872 
873 #if PLATFORM_DOS
874  /* no-op. */
875 
876 #elif PLATFORM_WIN32
_dos_findfirst(char * filename,int x,struct find_t * f)877 int _dos_findfirst(char *filename, int x, struct find_t *f)
878 {
879     long rc = _findfirst(filename, &f->data);
880     f->handle = rc;
881     if (rc != -1)
882     {
883         strncpy(f->name, f->data.name, sizeof (f->name) - 1);
884         f->name[sizeof (f->name) - 1] = '\0';
885         return(0);
886     }
887     return(1);
888 }
889 
_dos_findnext(struct find_t * f)890 int _dos_findnext(struct find_t *f)
891 {
892     int rc = 0;
893     if (f->handle == -1)
894         return(1);   /* invalid handle. */
895 
896     rc = _findnext(f->handle, &f->data);
897     if (rc == -1)
898     {
899         _findclose(f->handle);
900         f->handle = -1;
901         return(1);
902     }
903 
904     strncpy(f->name, f->data.name, sizeof (f->name) - 1);
905     f->name[sizeof (f->name) - 1] = '\0';
906     return(0);
907 }
908 
909 #elif PLATFORM_UNIX
_dos_findfirst(char * filename,int x,struct find_t * f)910 int _dos_findfirst(char *filename, int x, struct find_t *f)
911 {
912     char *ptr;
913 
914     if (strlen(filename) >= sizeof (f->pattern))
915         return(1);
916 
917     strcpy(f->pattern, filename);
918     FixFilePath(f->pattern);
919     ptr = strrchr(f->pattern, PATH_SEP_CHAR);
920 
921     if (ptr == NULL)
922     {
923         ptr = filename;
924         f->dir = opendir(CURDIR);
925     }
926     else
927     {
928         *ptr = '\0';
929         f->dir = opendir(f->pattern);
930         memmove(f->pattern, ptr + 1, strlen(ptr + 1) + 1); // linux ver bug :bero
931     }
932 
933     return(_dos_findnext(f));
934 }
935 
936 
check_pattern_nocase(const char * x,const char * y)937 static int check_pattern_nocase(const char *x, const char *y)
938 {
939     if ((x == NULL) || (y == NULL))
940         return(0);  /* not a match. */
941 
942     while ((*x) && (*y))
943     {
944         if (*x == '*')
945             Error("Unexpected wildcard!");  /* FIXME? */
946 
947         else if (*x == '?')
948         {
949             if (*y == '\0')
950                 return(0);  /* anything but EOS is okay. */
951         }
952 
953         else
954         {
955             if (toupper((int) *x) != toupper((int) *y))
956                 return(0);  /* not a match. */
957         }
958 
959         x++;
960         y++;
961     }
962 
963     return(*x == *y);  /* it's a match (both should be EOS). */
964 }
965 
_dos_findnext(struct find_t * f)966 int _dos_findnext(struct find_t *f)
967 {
968     struct dirent *dent;
969 
970     if (f->dir == NULL)
971         return(1);  /* no such dir or we're just done searching. */
972 
973     while ((dent = readdir(f->dir)) != NULL)
974     {
975         if (check_pattern_nocase(f->pattern, dent->d_name))
976         {
977             if (strlen(dent->d_name) < sizeof (f->name))
978             {
979                 strcpy(f->name, dent->d_name);
980                 return(0);  /* match. */
981             }
982         }
983     }
984 
985     closedir(f->dir);
986     f->dir = NULL;
987     return(1);  /* no match in whole directory. */
988 }
989 #else
990 #error please define for your platform.
991 #endif
992 
993 
994 #if !PLATFORM_DOS
_dos_getdate(struct dosdate_t * date)995 void _dos_getdate(struct dosdate_t *date)
996 {
997 	time_t curtime = time(NULL);
998 	struct tm *tm;
999 
1000 	if (date == NULL) {
1001 		return;
1002 	}
1003 
1004 	memset(date, 0, sizeof(struct dosdate_t));
1005 
1006 	if ((tm = localtime(&curtime)) != NULL) {
1007 		date->day = tm->tm_mday;
1008 		date->month = tm->tm_mon + 1;
1009 		date->year = tm->tm_year + 1900;
1010 		date->dayofweek = tm->tm_wday + 1;
1011 	}
1012 }
1013 #endif
1014 
1015 
GetPathFromEnvironment(char * fullname,const char * envname,const char * filename)1016 void GetPathFromEnvironment( char *fullname, const char *envname, const char *filename )
1017    {
1018 
1019 #ifdef DOS
1020    char *path;
1021    path = getenv( envname );
1022 #else
1023    const char *path;
1024    path = envname;
1025 #endif
1026 
1027    if ( path != NULL )
1028       {
1029       strcpy( fullname, path );
1030       if ( fullname[ strlen( fullname ) - 1 ] != PATH_SEP_CHAR )
1031          {
1032          strcat( fullname, PATH_SEP_STR );
1033          }
1034       strcat( fullname, filename );
1035       }
1036    else
1037       {
1038       strcpy( fullname, filename );
1039       }
1040 
1041       FixFilePath(fullname);
1042    }
1043 
DefaultExtension(char * path,char * extension)1044 void DefaultExtension (char *path, char *extension)
1045 {
1046 	char	*src;
1047 //
1048 // if path doesn't have a .EXT, append extension
1049 // (extension should include the .)
1050 //
1051 	src = path + strlen(path) - 1;
1052 
1053 	while (*src != PATH_SEP_CHAR && src != path)
1054 	{
1055 		if (*src == '.')
1056 			return;			// it has an extension
1057 		src--;
1058 	}
1059 
1060 	strcat (path, extension);
1061 }
1062 
DefaultPath(char * path,char * basepath)1063 void DefaultPath (char *path, char *basepath)
1064 {
1065 	char	temp[128];
1066 
1067 	if (path[0] == PATH_SEP_CHAR)
1068 		return;							// absolute path location
1069 	strcpy (temp,path);
1070 	strcpy (path,basepath);
1071 	strcat (path,temp);
1072 }
1073 
1074 
ExtractFileBase(char * path,char * dest)1075 void ExtractFileBase (char *path, char *dest)
1076 {
1077 	char	*src;
1078 	int		length;
1079 
1080 	src = path + strlen(path) - 1;
1081 
1082 //
1083 // back up until a \ or the start
1084 //
1085 	while (src != path && *(src-1) != PATH_SEP_CHAR)
1086 		src--;
1087 
1088 //
1089 // copy up to eight characters
1090 //
1091 	memset (dest,0,8);
1092 	length = 0;
1093 	while (*src && *src != '.')
1094 	{
1095 		if (++length == 9)
1096 			Error ("Filename base of %s >8 chars",path);
1097 		*dest++ = toupper(*src++);
1098 	}
1099 }
1100 
1101 
1102 /*
1103 ==============
1104 =
1105 = ParseNum / ParseHex
1106 =
1107 ==============
1108 */
1109 
ParseHex(char * hex)1110 long ParseHex (char *hex)
1111 {
1112 	char	*str;
1113 	long	num;
1114 
1115 	num = 0;
1116 	str = hex;
1117 
1118 	while (*str)
1119 	{
1120 		num <<= 4;
1121 		if (*str >= '0' && *str <= '9')
1122 			num += *str-'0';
1123 		else if (*str >= 'a' && *str <= 'f')
1124 			num += 10 + *str-'a';
1125 		else if (*str >= 'A' && *str <= 'F')
1126 			num += 10 + *str-'A';
1127 		else
1128 			Error ("Bad hex number: %s",hex);
1129 		str++;
1130 	}
1131 
1132 	return num;
1133 }
1134 
1135 
ParseNum(char * str)1136 long ParseNum (char *str)
1137 {
1138 	if (str[0] == '$')
1139 		return ParseHex (str+1);
1140 	if (str[0] == '0' && str[1] == 'x')
1141 		return ParseHex (str+2);
1142 	return atol (str);
1143 }
1144 
1145 
1146 #if (BYTE_ORDER == LITTLE_ENDIAN)
1147 #define KeepShort IntelShort
1148 #define SwapShort MotoShort
1149 #define KeepLong IntelLong
1150 #define SwapLong MotoLong
1151 #else
1152 #define KeepShort MotoShort
1153 #define SwapShort IntelShort
1154 #define KeepLong MotoLong
1155 #define SwapLong IntelLong
1156 #endif
1157 
SwapShort(short l)1158 short	SwapShort (short l)
1159 {
1160 	byte	b1,b2;
1161 
1162 	b1 = l&255;
1163 	b2 = (l>>8)&255;
1164 
1165 	return (b1<<8) + b2;
1166 }
1167 
KeepShort(short l)1168 short	KeepShort (short l)
1169 {
1170 	return l;
1171 }
1172 
1173 
SwapLong(long l)1174 long	SwapLong (long l)
1175 {
1176 	byte	b1,b2,b3,b4;
1177 
1178 	b1 = l&255;
1179 	b2 = (l>>8)&255;
1180 	b3 = (l>>16)&255;
1181 	b4 = (l>>24)&255;
1182 
1183 	return ((long)b1<<24) + ((long)b2<<16) + ((long)b3<<8) + b4;
1184 }
1185 
KeepLong(long l)1186 long	KeepLong (long l)
1187 {
1188 	return l;
1189 }
1190 
1191 
1192 #undef KeepShort
1193 #undef KeepLong
1194 #undef SwapShort
1195 #undef SwapLong
1196 
SwapIntelLong(long * l)1197 void SwapIntelLong(long *l)
1198 {
1199     *l = IntelLong(*l);
1200 }
1201 
SwapIntelShort(short * s)1202 void SwapIntelShort(short *s)
1203 {
1204     *s = IntelShort(*s);
1205 }
1206 
SwapIntelLongArray(long * l,int num)1207 void SwapIntelLongArray(long *l, int num)
1208 {
1209     while (num--) {
1210         SwapIntelLong(l);
1211         l++;
1212     }
1213 }
1214 
SwapIntelShortArray(short * s,int num)1215 void SwapIntelShortArray(short *s, int num)
1216 {
1217     while (num--) {
1218         SwapIntelShort(s);
1219         s++;
1220     }
1221 }
1222 
1223 /*
1224 ============================================================================
1225 
1226 						BASIC GRAPHICS
1227 
1228 ============================================================================
1229 */
1230 
1231 /*
1232 ==============
1233 =
1234 = GetaPalette
1235 =
1236 = Return an 8 bit / color palette
1237 =
1238 ==============
1239 */
1240 
GetaPalette(byte * palette)1241 void GetaPalette (byte *palette)
1242 {
1243 #ifdef DOS
1244 	int	i;
1245 
1246 	OUTP (PEL_READ_ADR,0);
1247 	for (i=0 ; i<768 ; i++)
1248 		palette[i] = inp (PEL_DATA)<<2;
1249 #else
1250 	int i;
1251 	SDL_Palette *pal = SDL_GetVideoSurface()->format->palette;
1252 
1253 	for (i = 0; i < 256; i++) {
1254 		palette[0] = pal->colors[i].r;
1255 		palette[1] = pal->colors[i].g;
1256 		palette[2] = pal->colors[i].b;
1257 
1258 		palette += 3;
1259 	}
1260 #endif
1261 }
1262 
1263 /*
1264 ==============
1265 =
1266 = SetaPalette
1267 =
1268 = Sets an 8 bit / color palette
1269 =
1270 ==============
1271 */
1272 
SetaPalette(byte * pal)1273 void SetaPalette (byte *pal)
1274 {
1275 #ifdef DOS
1276 	int	i;
1277 
1278 	OUTP (PEL_WRITE_ADR,0);
1279 	for (i=0 ; i<768 ; i++)
1280 		OUTP (PEL_DATA, pal[i]>>2);
1281 #else
1282    SDL_Color cmap[256];
1283    int i;
1284 
1285    for (i = 0; i < 256; i++)
1286    {
1287 	   cmap[i].r = pal[i*3+0];
1288 	   cmap[i].g = pal[i*3+1];
1289 	   cmap[i].b = pal[i*3+2];
1290    }
1291 
1292    SDL_SetColors (SDL_GetVideoSurface (), cmap, 0, 256);
1293 #endif
1294 }
1295 
GetPalette(char * palette)1296 void GetPalette(char * palette)
1297 {
1298 #ifdef DOS
1299   int i;
1300 
1301   OUTP(0x03c7,0);
1302   for (i=0;i<256*3;i++)
1303      *(palette+(unsigned char)i)=inp(0x3c9)<<2;
1304 #else
1305 	int i;
1306 	SDL_Palette *pal = SDL_GetVideoSurface()->format->palette;
1307 
1308 	for (i = 0; i < 256; i++) {
1309 		palette[0] = pal->colors[i].r;
1310 		palette[1] = pal->colors[i].g;
1311 		palette[2] = pal->colors[i].b;
1312 
1313 		palette += 3;
1314 	}
1315 #endif
1316 }
1317 
SetPalette(char * pal)1318 void SetPalette ( char * pal )
1319 {
1320    VL_SetPalette (pal);
1321 }
1322 
1323 
1324 
1325 //******************************************************************************
1326 //
1327 // US_CheckParm() - checks to see if a string matches one of a set of
1328 //    strings. The check is case insensitive. The routine returns the
1329 //    index of the string that matched, or -1 if no matches were found
1330 //
1331 //******************************************************************************
1332 
US_CheckParm(char * parm,char ** strings)1333 int US_CheckParm (char *parm, char **strings)
1334 {
1335    char  cp,cs,
1336          *p,*s;
1337    int      i;
1338    int      length;
1339 
1340    length=strlen(parm);
1341    while ( (!isalpha(*parm)) && (length>0)) // Skip non-alphas
1342       {
1343       length--;
1344       parm++;
1345       }
1346 
1347    for (i = 0;*strings && **strings;i++)
1348    {
1349       for (s = *strings++,p = parm,cs = cp = 0;cs == cp;)
1350       {
1351          cs = *s++;
1352          if (!cs)
1353             return(i);
1354          cp = *p++;
1355 
1356          if (isupper(cs))
1357             cs = tolower(cs);
1358          if (isupper(cp))
1359             cp = tolower(cp);
1360       }
1361    }
1362    return(-1);
1363 }
1364 
1365 /*
1366 =============================================================================
1367 
1368                   PALETTE OPS
1369 
1370       To avoid snow, do a WaitVBL BEFORE calling these
1371 
1372 =============================================================================
1373 */
1374 
1375 
1376 /*
1377 =================
1378 =
1379 = VL_FillPalette
1380 =
1381 =================
1382 */
1383 
VL_FillPalette(int red,int green,int blue)1384 void VL_FillPalette (int red, int green, int blue)
1385 {
1386 #ifdef DOS
1387    int   i;
1388 
1389    OUTP (PEL_WRITE_ADR,0);
1390    for (i=0;i<256;i++)
1391    {
1392       OUTP (PEL_DATA,red);
1393       OUTP (PEL_DATA,green);
1394       OUTP (PEL_DATA,blue);
1395    }
1396 #else
1397    SDL_Color cmap[256];
1398    int i;
1399 
1400    for (i = 0; i < 256; i++)
1401    {
1402            cmap[i].r = red << 2;
1403            cmap[i].g = green << 2;
1404            cmap[i].b = blue << 2;
1405    }
1406 
1407    SDL_SetColors (SDL_GetVideoSurface (), cmap, 0, 256);
1408 #endif
1409 }
1410 
1411 //===========================================================================
1412 
1413 /*
1414 =================
1415 =
1416 = VL_SetColor
1417 =
1418 =================
1419 */
1420 
VL_SetColor(int color,int red,int green,int blue)1421 void VL_SetColor  (int color, int red, int green, int blue)
1422 {
1423 #ifdef DOS
1424    OUTP (PEL_WRITE_ADR,color);
1425    OUTP (PEL_DATA,red);
1426    OUTP (PEL_DATA,green);
1427    OUTP (PEL_DATA,blue);
1428 #else
1429 	STUB_FUNCTION;
1430 #endif
1431 }
1432 
1433 //===========================================================================
1434 
1435 /*
1436 =================
1437 =
1438 = VL_GetColor
1439 =
1440 =================
1441 */
1442 
VL_GetColor(int color,int * red,int * green,int * blue)1443 void VL_GetColor  (int color, int *red, int *green, int *blue)
1444 {
1445 #ifdef DOS
1446    OUTP (PEL_READ_ADR,color);
1447    *red   = inp (PEL_DATA);
1448    *green = inp (PEL_DATA);
1449    *blue  = inp (PEL_DATA);
1450 #else
1451 	STUB_FUNCTION;
1452 #endif
1453 }
1454 
1455 //===========================================================================
1456 
1457 /*
1458 =================
1459 =
1460 = VL_NormalizePalette
1461 =
1462 =================
1463 */
1464 
VL_NormalizePalette(byte * palette)1465 void VL_NormalizePalette (byte *palette)
1466 {
1467    int   i;
1468 
1469    for (i = 0; i < 768; i++)
1470       *(palette+i)=(*(palette+i))>>2;
1471 }
1472 
1473 
1474 /*
1475 =================
1476 =
1477 = VL_SetPalette
1478 =
1479 = If fast palette setting has been tested for, it is used
1480 = -some cards don't like outsb palette setting-
1481 =
1482 =================
1483 */
1484 
VL_SetPalette(byte * palette)1485 void VL_SetPalette (byte *palette)
1486 {
1487 #ifdef DOS
1488    int   i;
1489 
1490    OUTP (PEL_WRITE_ADR, 0);
1491 
1492    for (i = 0; i < 768; i++)
1493       {
1494       OUTP (PEL_DATA, gammatable[(gammaindex<<6)+(*palette++)]);
1495       }
1496 #else
1497    SDL_Color cmap[256];
1498    int i;
1499 
1500    for (i = 0; i < 256; i++)
1501    {
1502 	   cmap[i].r = gammatable[(gammaindex<<6)+(*palette++)] << 2;
1503 	   cmap[i].g = gammatable[(gammaindex<<6)+(*palette++)] << 2;
1504 	   cmap[i].b = gammatable[(gammaindex<<6)+(*palette++)] << 2;
1505    }
1506 
1507    SDL_SetColors (SDL_GetVideoSurface (), cmap, 0, 256);
1508 #endif
1509 }
1510 
1511 
1512 //===========================================================================
1513 
1514 /*
1515 =================
1516 =
1517 = VL_GetPalette
1518 =
1519 = This does not use the port string instructions,
1520 = due to some incompatabilities
1521 =
1522 =================
1523 */
1524 
VL_GetPalette(byte * palette)1525 void VL_GetPalette (byte *palette)
1526 {
1527 #ifdef DOS
1528    int   i;
1529 
1530    OUTP (PEL_READ_ADR, 0);
1531 
1532    for (i = 0; i < 768; i++)
1533       *palette++ = inp (PEL_DATA);
1534 #else
1535 	int i;
1536 	SDL_Palette *pal = SDL_GetVideoSurface()->format->palette;
1537 
1538 	for (i = 0; i < 256; i++) {
1539 		palette[0] = pal->colors[i].r >> 2;
1540 		palette[1] = pal->colors[i].g >> 2;
1541 		palette[2] = pal->colors[i].b >> 2;
1542 
1543 		palette += 3;
1544 	}
1545 #endif
1546 }
1547 
1548 
1549 /*
1550 =================
1551 =
1552 = UL_DisplayMemoryError ()
1553 =
1554 =================
1555 */
1556 
UL_DisplayMemoryError(int memneeded)1557 void UL_DisplayMemoryError ( int memneeded )
1558 {
1559 #ifdef DOS
1560    char buf[4000];
1561    int i;
1562 
1563    ShutDown ();
1564    TextMode ();
1565 
1566    for (i = 0; i < 19; i++)
1567       printf ("\n");
1568 
1569    memcpy (buf, &ROTT_ERR, 4000);
1570    memcpy ((byte *)0xB8000, &buf[160*7], 4000-(160*7));
1571 
1572    px = ERRORVERSIONCOL;
1573    py = ERRORVERSIONROW;
1574 #if (BETA == 1)
1575    UL_printf ("�");
1576 #else
1577    UL_printf (itoa(ROTTMAJORVERSION,&buf[0],10));
1578 #endif
1579    px++;
1580 
1581    UL_printf (itoa(ROTTMINORVERSION,&buf[0],10));
1582 
1583    px = LOWMEMORYCOL;
1584    py = LOWMEMORYROW;
1585    UL_printf ("You need ");
1586    UL_printf (itoa(memneeded,&buf[0],10));
1587    UL_printf (" bytes more memory");
1588    if ( SOUNDSETUP )
1589       {
1590       getch();
1591       }
1592 #else
1593 	STUB_FUNCTION;
1594 #endif
1595    exit (0);
1596 }
1597 
1598 
1599 /*
1600 =================
1601 =
1602 = UL_printf
1603 =
1604 =================
1605 */
1606 
UL_printf(byte * str)1607 void UL_printf (byte *str)
1608 {
1609 #ifdef DOS
1610    byte *s;
1611    byte *screen;
1612 
1613    s = str;
1614    screen = (byte *)(0xB8000 + (py*160) + (px<<1));
1615 
1616    while (*s)
1617    {
1618       *screen = *s;
1619       s++;
1620       screen += 2;
1621       px++;
1622 
1623       if ((*s < 32) && (*s > 0))
1624          s++;
1625    }
1626 #else
1627 #ifdef ANSIESC
1628    printf ("\x1b[%d;%dH%s",py,px,str);
1629 #else
1630    printf ("%s ",str);	// Hackish but works - DDOI
1631 #endif
1632 #endif
1633 }
1634 
1635 /*
1636 =================
1637 =
1638 = UL_ColorBox
1639 =
1640 =================
1641 */
1642 
UL_ColorBox(int x,int y,int w,int h,int color)1643 void UL_ColorBox (int x, int y, int w, int h, int color)
1644 {
1645 #ifdef DOS
1646    byte *screen;
1647    int i,j;
1648 
1649 
1650    for (j=0;j<h;j++)
1651       {
1652       screen = (byte *)(0xB8000 + ((y+j)*160) + (x<<1) + 1);
1653       for (i=0;i<w;i++)
1654          {
1655          *screen = (byte)color;
1656          screen+=2;
1657          }
1658       }
1659 #elif defined (ANSIESC)
1660    int i,j;
1661 
1662 
1663    for (j=0;j<h;j++)
1664       {
1665       for (i=0;i<w;i++)
1666          {
1667          printf ("\x1b[%d;%dH",y+j,x+i);
1668          put_dos2ansi(color);
1669          }
1670       }
1671 #endif
1672 }
1673 
1674 //******************************************************************************
1675 //
1676 // SideOfLine
1677 //
1678 //******************************************************************************
1679 
SideOfLine(int x1,int y1,int x2,int y2,int x3,int y3)1680 int SideOfLine(int x1, int y1, int x2, int y2, int x3, int y3)
1681 {
1682    int a1,b1,c1;
1683 
1684    /* Compute a1, b1, c1, where line joining points 1 and 2
1685     * is "a1 x  +  b1 y  +  c1  =  0".
1686     */
1687 
1688    a1 = y2 - y1;
1689    b1 = x1 - x2;
1690    c1 = FixedMulShift(x2,y1,16) - FixedMulShift(x1,y2,16);
1691 
1692    return SGN(FixedMulShift(a1,x3,16) + FixedMulShift(b1,y3,16) + c1);
1693 }
1694 
1695 
1696 
1697 //******************************************************************************
1698 //
1699 // HSORT - heap sort
1700 //
1701 //******************************************************************************
1702 
1703 typedef int (*PFI)();           /* pointer to a function returning int  */
1704 typedef void (*PFV)();           /* pointer to a function returning int  */
1705 static PFI Comp;                        /* pointer to comparison routine                */
1706 static PFV Switch;                        /* pointer to comparison routine                */
1707 static int Width;                       /* width of an object in bytes                  */
1708 static char *Base;                      /* pointer to element [-1] of array             */
1709 
1710 
newsift_down(L,U)1711 static void newsift_down(L,U) int L,U;
1712 {  int c;
1713 
1714    while(1)
1715       {c=L+L;
1716       if(c>U) break;
1717       if( (c+Width <= U) && ((*Comp)(Base+c+Width,Base+c)>0) ) c+= Width;
1718       if ((*Comp)(Base+L,Base+c)>=0) break;
1719       (*Switch)(Base+L, Base+c);
1720       L=c;
1721       }
1722 }
1723 
hsort(char * base,int nel,int width,int (* compare)(),void (* switcher)())1724 void hsort(char * base, int nel, int width, int (*compare)(), void (*switcher)())
1725 {
1726 static int i,n,stop;
1727         /*      Perform a heap sort on an array starting at base.  The array is
1728                 nel elements large and width is the size of a single element in
1729                 bytes.  Compare is a pointer to a comparison routine which will
1730                 be passed pointers to two elements of the array.  It should
1731                 return a negative number if the left-most argument is less than
1732                 the rightmost, 0 if the two arguments are equal, a positive
1733                 number if the left argument is greater than the right.  (That
1734                 is, it acts like a "subtract" operator.) If compare is 0 then
1735                 the default comparison routine, argvcmp (which sorts an
1736                 argv-like array of pointers to strings), is used.                                       */
1737 
1738    Width=width;
1739    Comp= compare;
1740    Switch= switcher;
1741    n=nel*Width;
1742    Base=base-Width;
1743    for (i=(n/Width/2)*Width; i>=Width; i-=Width) newsift_down(i,n);
1744    stop=Width+Width;
1745    for (i=n; i>=stop; )
1746       {
1747       (*Switch)(base, Base+i);
1748       newsift_down(Width,i-=Width);
1749       }
1750 
1751 }
1752 
1753 /*---------------------------------------------------------------------------*/
1754 
1755 //******************************************************************************
1756 //
1757 // UL_GetPath
1758 //
1759 // Purpose
1760 //    To parse the directory entered by the user to make the directory.
1761 //
1762 // Parms
1763 //    Path - the path to be parsed.
1764 //
1765 // Returns
1766 //    Pointer to next path
1767 //
1768 //******************************************************************************
1769 
UL_GetPath(char * path,char * dir)1770 char * UL_GetPath (char * path, char *dir)
1771 {
1772    boolean done      = 0;
1773    char *dr          = dir;
1774    int cnt           = 0;
1775 
1776    if (*path == SLASHES)
1777       path++;
1778 
1779    while (!done)
1780    {
1781       *dr = *path;
1782 
1783       cnt++;                  // make sure the number of characters in the dir
1784       if (cnt > MAXCHARS)     // name doesn't exceed acceptable limits.
1785          Error ("ERROR : Directory name can only be %d characters long.\n", MAXCHARS);
1786 
1787       path++;
1788       dr++;
1789 
1790       if ((*path == SLASHES) || (*path == 0))
1791          done = true;
1792    }
1793 
1794    *dr = 0;
1795    return (path);
1796 }
1797 
1798 
1799 //******************************************************************************
1800 //
1801 // UL_ChangeDirectory ()
1802 //
1803 // Purpose
1804 //    To change to a directory.  Checks for drive changes.
1805 //
1806 // Parms
1807 //    path - The path to change to.
1808 //
1809 // Returns
1810 //    TRUE  - If successful.
1811 //    FALSE - If unsuccessful.
1812 //
1813 //******************************************************************************
1814 
UL_ChangeDirectory(char * path)1815 boolean UL_ChangeDirectory (char *path)
1816 {
1817 #ifdef DOS
1818    char *p;
1819    char dir[9];
1820    char *d;
1821 
1822    d = &dir[0];
1823    p = path;
1824    memset (dir, 0, 9);
1825 
1826    // Check for a drive at the beginning of the path
1827    if (*(p+1) == ':')
1828    {
1829       *d++ = *p++;      // drive letter
1830       *d++ = *p++;      // colon
1831 
1832       if (UL_ChangeDrive (dir) == false)
1833          return (false);
1834    }
1835 
1836    if (*p == SLASHES)
1837    {
1838       chdir ("\\");
1839       p++;
1840    }
1841 
1842    d = &dir[0];
1843    while (*p)
1844    {
1845       p = UL_GetPath (p, d);
1846 
1847       if (chdir (d) == -1)
1848          return (false);
1849    }
1850 
1851    return (true);
1852 #else
1853 	STUB_FUNCTION;
1854 
1855 	return false;
1856 #endif
1857 }
1858 
1859 
1860 
1861 //******************************************************************************
1862 //
1863 // UL_ChangeDrive ()
1864 //
1865 // Purpose
1866 //    To change drives.
1867 //
1868 // Parms
1869 //    drive - The drive to change to.
1870 //
1871 // Returns
1872 //    TRUE  - If drive change successful.
1873 //    FALSE - If drive change unsuccessful.
1874 //
1875 //******************************************************************************
1876 
UL_ChangeDrive(char * drive)1877 boolean UL_ChangeDrive (char *drive)
1878 {
1879 #ifdef DOS
1880    unsigned d, total, tempd;
1881 
1882    d = toupper (*drive);
1883 
1884    d = d - 'A' + 1;
1885 
1886    _dos_setdrive (d, &total);
1887    _dos_getdrive (&tempd);
1888 
1889    if (d != tempd)
1890       return (false);
1891 
1892    return (true);
1893 #else
1894 	STUB_FUNCTION;
1895 
1896 	return false;
1897 #endif
1898 }
1899 
1900 
1901 /*
1902 =============
1903 =
1904 = AbortCheck
1905 =
1906 =============
1907 */
AbortCheck(char * abortstring)1908 void AbortCheck (char * abortstring)
1909 {
1910    // User abort check
1911 
1912    IN_UpdateKeyboard ();
1913 
1914    if (Keyboard[sc_Escape])
1915       Error("%s\n",abortstring);
1916 }
1917