/* Copyright (C) 1994-1995 Apogee Software, Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "rt_def.h" #ifdef DOS #include #include #include #include #include #elif USE_SDL #include "SDL.h" #endif #include #include #include #include #include #include #include #include #include #include "watcom.h" #include "_rt_util.h" #include "rt_util.h" #include "isr.h" #include "z_zone.h" #include "rt_dr_a.h" #include "rt_in.h" #include "rt_main.h" #include "scriplib.h" #include "rt_menu.h" #include "rt_playr.h" #include "version.h" #include "develop.h" #include "rt_vid.h" #include "rt_view.h" #include "modexlib.h" #include "rt_cfg.h" //MED #include "memcheck.h" int egacolor[16]; byte * origpal; FILE * errout; FILE * debugout; FILE * mapdebugout; static boolean SoftErrorStarted=false; static boolean DebugStarted=false; static boolean MapDebugStarted=false; static unsigned char egargb[48]={ 0x00,0x00,0x00, 0x00,0x00,0xab, 0x00,0xab,0x00, 0x00,0xab,0xab, 0xab,0x00,0x00, 0xab,0x00,0xab, 0xab,0x57,0x00, 0xab,0xab,0xab, 0x57,0x57,0x57, 0x57,0x57,0xff, 0x57,0xff,0x57, 0x57,0xff,0xff, 0xff,0x57,0x57, 0xff,0x57,0xff, 0xff,0xff,0x57, 0xff,0xff,0xff}; extern const byte * ROTT_ERR; #if (DEVELOPMENT == 1) int TotalStaticMemory=0; #endif #define SWAP(a,b) \ { \ a=(a)^(b); \ b=(a)^(b); \ a=(a)^(b); \ } \ //****************************************************************************** // // FindDistance // //****************************************************************************** int FindDistance(int ix, int iy) { int t; ix= abs(ix); /* absolute values */ iy= abs(iy); if (ix>1); return (ix - (ix>>5) - (ix>>7) + (t>>2) + (t>>6)); } //****************************************************************************** // // Find_3D_Distance // //****************************************************************************** int Find_3D_Distance(int ix, int iy, int iz) { int t; ix= abs(ix); /* absolute values */ iy= abs(iy); iz= abs(iz); if (ix>4) + (t>>2) + (t>>3)); } //****************************************************************************** // // atan2_appx // //****************************************************************************** int atan2_appx(int dx, int dy) {int absdx, absdy; fixed angle; fixed ratio; if (!(dx||dy)) return 0; absdx = abs(dx); absdy = abs(dy); if (absdx >= absdy) ratio = FixedDiv2(absdy,absdx); else ratio = FixedDiv2(absdx,absdy); if (dx >= 0) {if (dy >= 0) {if (absdx >= absdy) angle = ratio; // 1st octant else angle = (2<<16) - ratio; // 2nd octant } else {if (absdx >= absdy) angle = (8<<16) - ratio; // 8th octant else angle = (6<<16) + ratio; // 7th octant } } else {if (dy >= 0) {if (absdx >= absdy) angle = (4<<16) - ratio; // 4th octant else angle = (2<<16) + ratio; // 3rd octant } else {if (absdx >= absdy) angle = (4<<16) + ratio; // 5th octant else angle = (6<<16) - ratio; // 6th octant } } return (((int)FixedMul(angle,ANGLESDIV8))&(FINEANGLES-1)); } //****************************************************************************** // // StringsNotEqual // //****************************************************************************** boolean StringsNotEqual (char * s1, char * s2, int length) { int i; for (i=0;i 1) abort(); SetTextMode (); #ifdef DOS memcpy ((byte *)0xB8000, &ROTT_ERR, 160*7); #elif defined (ANSIESC) DisplayTextSplash (&ROTT_ERR, 7); #endif memset (msgbuf, 0, 300); #ifdef DOS px = ERRORVERSIONCOL-1; py = ERRORVERSIONROW; #if (SHAREWARE == 1) UL_printf ("S"); #else UL_printf ("R"); #endif px = ERRORVERSIONCOL; py = ERRORVERSIONROW; #if (BETA == 1) UL_printf ("á"); #else UL_printf (itoa(ROTTMAJORVERSION,&buf[0],10)); #endif // Skip the dot px++; UL_printf (itoa(ROTTMINORVERSION,&buf[0],10)); #endif va_start (argptr, error); vsprintf (&msgbuf[0], error, argptr); va_end (argptr); scriptbuffer = &msgbuf[0]; size = strlen (msgbuf); sptr = script_p = scriptbuffer; scriptend_p = script_p + size; scriptline = 1; endofscript = false; tokenready = false; px = ERRORCOL; py = ERRORROW; GetToken (true); while (!endofscript) { if ((script_p - sptr) >= 60) { px = ERRORCOL; py++; sptr = script_p; } UL_printf (token); px++; //SPACE GetToken (true); } #ifdef ANSIESC for (i = 0; i < 8; i++) printf ("\n"); #endif if (player!=NULL) { printf ("Player X = %lx\n", (long int)player->x); printf ("Player Y = %lx\n", (long int)player->y); printf ("Player Angle = %lx\n\n", (long int)player->angle); } printf ("Episode = %ld\n", (long int)gamestate.episode); if (gamestate.episode > 1) level = (gamestate.mapon+1) - ((gamestate.episode-1) << 3); else level = gamestate.mapon+1; printf ("Area = %ld\n", (long int)level); ShutDown(); // DDOI - moved this so that it doesn't try to access player // which is freed by this function. #ifdef DOS GetPathFromEnvironment( filename, ApogeePath, ERRORFILE ); handle=SafeOpenAppend ( filename ); for (y=0;y<16;y++) { for (x=0;x<160;x+=2) SafeWrite(handle,(byte *)0xB8000+(y*160)+x,1); i=10; SafeWrite(handle,&i,1); i=13; SafeWrite(handle,&i,1); } close(handle); if ( SOUNDSETUP ) { getch(); } #endif #if USE_SDL SDL_Quit(); #endif exit (1); } //#if (SOFTERROR==1) /* ================= = = SoftwareError = ================= */ void SoftwareError (char *error, ...) { va_list argptr; if (SoftErrorStarted==false) return; va_start (argptr, error); vfprintf (errout, error, argptr); va_end (argptr); } //#endif //#if (DEBUG == 1) /* ================= = = DebugError = ================= */ void DebugError (char *error, ...) { va_list argptr; if (DebugStarted==false) return; va_start (argptr, error); vfprintf (debugout, error, argptr); va_end (argptr); } //#endif /* ================= = = OpenSoftError = ================= */ void OpenSoftError ( void ) { errout = fopen(SOFTERRORFILE,"wt+"); SoftErrorStarted=true; } /* ================= = = MapDebug = ================= */ void MapDebug (char *error, ...) { va_list argptr; if (MapDebugStarted==false) return; va_start (argptr, error); vfprintf (mapdebugout, error, argptr); va_end (argptr); } /* ================= = = OpenMapDebug = ================= */ void OpenMapDebug ( void ) { char filename[ 128 ]; if (MapDebugStarted==true) return; GetPathFromEnvironment( filename, ApogeePath, MAPDEBUGFILE ); mapdebugout = fopen(filename,"wt+"); MapDebugStarted=true; } /* ================= = = StartupSoftError = ================= */ void StartupSoftError ( void ) { #if (DEBUG == 1) if (DebugStarted==false) { debugout = fopen(DEBUGFILE,"wt+"); DebugStarted=true; } #endif #if (SOFTERROR == 1) if (SoftErrorStarted==false) OpenSoftError(); #endif } /* ================= = = ShutdownSoftError = ================= */ void ShutdownSoftError ( void ) { if (DebugStarted==true) { fclose(debugout); DebugStarted=false; } if (SoftErrorStarted==true) { fclose(errout); SoftErrorStarted=false; } if (MapDebugStarted==true) { fclose(mapdebugout); MapDebugStarted=false; } } /* ================= = = CheckParm = = Checks for the given parameter in the program's command line arguments = = Returns the argument number (1 to argc-1) or 0 if not present = ================= */ int CheckParm (char *check) { int i; char *parm; for (i = 1;i<_argc;i++) { parm = _argv[i]; if ( !isalpha(*parm) ) // skip - / \ etc.. in front of parm { parm++; if (!*parm) continue; // parm was only one char } if ( !_fstricmp(check,parm) ) return i; } return 0; } int SafeOpenAppend (char *_filename) { int handle; char filename[MAX_PATH]; strncpy(filename, _filename, sizeof (filename)); filename[sizeof (filename) - 1] = '\0'; FixFilePath(filename); handle = open(filename,O_RDWR | O_BINARY | O_CREAT | O_APPEND , S_IREAD | S_IWRITE); if (handle == -1) Error ("Error opening for append %s: %s",filename,strerror(errno)); return handle; } int SafeOpenWrite (char *_filename) { int handle; char filename[MAX_PATH]; strncpy(filename, _filename, sizeof (filename)); filename[sizeof (filename) - 1] = '\0'; FixFilePath(filename); handle = open(filename,O_RDWR | O_BINARY | O_CREAT | O_TRUNC , S_IREAD | S_IWRITE); if (handle == -1) Error ("Error opening %s: %s",filename,strerror(errno)); return handle; } int SafeOpenRead (char *_filename) { int handle; char filename[MAX_PATH]; strncpy(filename, _filename, sizeof (filename)); filename[sizeof (filename) - 1] = '\0'; FixFilePath(filename); handle = open(filename,O_RDONLY | O_BINARY); if (handle == -1) Error ("Error opening %s: %s",filename,strerror(errno)); return handle; } void SafeRead (int handle, void *buffer, long count) { unsigned iocount; while (count) { iocount = count > 0x8000 ? 0x8000 : count; if (read (handle,buffer,iocount) != (int)iocount) Error ("File read failure reading %ld bytes",count); buffer = (void *)( (byte *)buffer + iocount ); count -= iocount; } } void SafeWrite (int handle, void *buffer, long count) { unsigned iocount; while (count) { iocount = count > 0x8000 ? 0x8000 : count; if (write (handle,buffer,iocount) != (int)iocount) Error ("File write failure writing %ld bytes",count); buffer = (void *)( (byte *)buffer + iocount ); count -= iocount; } } void SafeWriteString (int handle, char * buffer) { unsigned iocount; iocount=strlen(buffer); if (write (handle,buffer,iocount) != (int)iocount) Error ("File write string failure writing %s\n",buffer); } void *SafeMalloc (long size) { void *ptr; if (zonememorystarted==false) Error("Called SafeMalloc without starting zone memory\n"); ptr = Z_Malloc (size,PU_STATIC,NULL); if (!ptr) Error ("SafeMalloc failure for %lu bytes",size); return ptr; } void *SafeLevelMalloc (long size) { void *ptr; if (zonememorystarted==false) Error("Called SafeLevelMalloc without starting zone memory\n"); ptr = Z_LevelMalloc (size,PU_STATIC,NULL); if (!ptr) Error ("SafeLevelMalloc failure for %lu bytes",size); return ptr; } void SafeFree (void * ptr) { if ( ptr == NULL ) Error ("SafeFree : Tried to free a freed pointer\n"); Z_Free (ptr); } /* ============== = = LoadFile = ============== */ long LoadFile (char *filename, void **bufferptr) { int handle; long length; handle = SafeOpenRead (filename); length = filelength (handle); *bufferptr = SafeMalloc (length); SafeRead (handle,*bufferptr, length); close (handle); return length; } /* ============== = = SaveFile = ============== */ void SaveFile (char *filename, void *buffer, long count) { int handle; handle = SafeOpenWrite (filename); SafeWrite (handle, buffer, count); close (handle); } void FixFilePath(char *filename) { #if PLATFORM_UNIX char *ptr; char *lastsep = filename; if ((!filename) || (*filename == '\0')) return; if (access(filename, F_OK) == 0) /* File exists; we're good to go. */ return; for (ptr = filename; 1; ptr++) { if (*ptr == '\\') *ptr = PATH_SEP_CHAR; if ((*ptr == PATH_SEP_CHAR) || (*ptr == '\0')) { char pch = *ptr; struct dirent *dent = NULL; DIR *dir; if ((pch == PATH_SEP_CHAR) && (*(ptr + 1) == '\0')) return; /* eos is pathsep; we're done. */ if (lastsep == ptr) continue; /* absolute path; skip to next one. */ *ptr = '\0'; if (lastsep == filename) { dir = opendir((*lastsep == PATH_SEP_CHAR) ? ROOTDIR : CURDIR); if (*lastsep == PATH_SEP_CHAR) { lastsep++; } } else { *lastsep = '\0'; dir = opendir(filename); *lastsep = PATH_SEP_CHAR; lastsep++; } if (dir == NULL) { *ptr = PATH_SEP_CHAR; return; /* maybe dir doesn't exist? give up. */ } while ((dent = readdir(dir)) != NULL) { if (strcasecmp(dent->d_name, lastsep) == 0) { /* found match; replace it. */ strcpy(lastsep, dent->d_name); break; } } closedir(dir); *ptr = pch; lastsep = ptr; if (dent == NULL) return; /* no match. oh well. */ if (pch == '\0') /* eos? */ return; } } #endif } #if PLATFORM_DOS /* no-op. */ #elif PLATFORM_WIN32 int _dos_findfirst(char *filename, int x, struct find_t *f) { long rc = _findfirst(filename, &f->data); f->handle = rc; if (rc != -1) { strncpy(f->name, f->data.name, sizeof (f->name) - 1); f->name[sizeof (f->name) - 1] = '\0'; return(0); } return(1); } int _dos_findnext(struct find_t *f) { int rc = 0; if (f->handle == -1) return(1); /* invalid handle. */ rc = _findnext(f->handle, &f->data); if (rc == -1) { _findclose(f->handle); f->handle = -1; return(1); } strncpy(f->name, f->data.name, sizeof (f->name) - 1); f->name[sizeof (f->name) - 1] = '\0'; return(0); } #elif PLATFORM_UNIX int _dos_findfirst(char *filename, int x, struct find_t *f) { char *ptr; if (strlen(filename) >= sizeof (f->pattern)) return(1); strcpy(f->pattern, filename); FixFilePath(f->pattern); ptr = strrchr(f->pattern, PATH_SEP_CHAR); if (ptr == NULL) { ptr = filename; f->dir = opendir(CURDIR); } else { *ptr = '\0'; f->dir = opendir(f->pattern); memmove(f->pattern, ptr + 1, strlen(ptr + 1) + 1); } return(_dos_findnext(f)); } static int check_pattern_nocase(const char *x, const char *y) { if ((x == NULL) || (y == NULL)) return(0); /* not a match. */ while ((*x) && (*y)) { if (*x == '*') Error("Unexpected wildcard!"); /* FIXME? */ else if (*x == '?') { if (*y == '\0') return(0); /* anything but EOS is okay. */ } else { if (toupper((int) *x) != toupper((int) *y)) return(0); /* not a match. */ } x++; y++; } return(*x == *y); /* it's a match (both should be EOS). */ } int _dos_findnext(struct find_t *f) { struct dirent *dent; if (f->dir == NULL) return(1); /* no such dir or we're just done searching. */ while ((dent = readdir(f->dir)) != NULL) { if (check_pattern_nocase(f->pattern, dent->d_name)) { if (strlen(dent->d_name) < sizeof (f->name)) { strcpy(f->name, dent->d_name); return(0); /* match. */ } } } closedir(f->dir); f->dir = NULL; return(1); /* no match in whole directory. */ } #else #error please define for your platform. #endif #if !PLATFORM_DOS void _dos_getdate(struct dosdate_t *date) { time_t curtime = time(NULL); struct tm *tm; if (date == NULL) { return; } memset(date, 0, sizeof(struct dosdate_t)); if ((tm = localtime(&curtime)) != NULL) { date->day = tm->tm_mday; date->month = tm->tm_mon + 1; date->year = tm->tm_year + 1900; date->dayofweek = tm->tm_wday + 1; } } #endif void GetPathFromEnvironment( char *fullname, const char *envname, const char *filename ) { #ifdef DOS char *path; path = getenv( envname ); #else const char *path; path = envname; #endif if ( path != NULL ) { strcpy( fullname, path ); if ( fullname[ strlen( fullname ) - 1 ] != PATH_SEP_CHAR ) { strcat( fullname, PATH_SEP_STR ); } strcat( fullname, filename ); } else { strcpy( fullname, filename ); } FixFilePath(fullname); } void DefaultExtension (char *path, char *extension) { char *src; // // if path doesn't have a .EXT, append extension // (extension should include the .) // src = path + strlen(path) - 1; while (*src != PATH_SEP_CHAR && src != path) { if (*src == '.') return; // it has an extension src--; } strcat (path, extension); } void DefaultPath (char *path, char *basepath) { char temp[128]; if (path[0] == PATH_SEP_CHAR) return; // absolute path location strcpy (temp,path); strcpy (path,basepath); strcat (path,temp); } void ExtractFileBase (char *path, char *dest) { char *src; int length; src = path + strlen(path) - 1; // // back up until a \ or the start // while (src != path && *(src-1) != PATH_SEP_CHAR) src--; // // copy up to eight characters // memset (dest,0,8); length = 0; while (*src && *src != '.') { if (++length == 9) Error ("Filename base of %s >8 chars",path); *dest++ = toupper(*src++); } } /* ============== = = ParseNum / ParseHex = ============== */ long ParseHex (char *hex) { char *str; long num; num = 0; str = hex; while (*str) { num <<= 4; if (*str >= '0' && *str <= '9') num += *str-'0'; else if (*str >= 'a' && *str <= 'f') num += 10 + *str-'a'; else if (*str >= 'A' && *str <= 'F') num += 10 + *str-'A'; else Error ("Bad hex number: %s",hex); str++; } return num; } long ParseNum (char *str) { if (str[0] == '$') return ParseHex (str+1); if (str[0] == '0' && str[1] == 'x') return ParseHex (str+2); return atol (str); } #if (BYTE_ORDER == LITTLE_ENDIAN) #define KeepShort IntelShort #define SwapShort MotoShort #define KeepLong IntelLong #define SwapLong MotoLong #else #define KeepShort MotoShort #define SwapShort IntelShort #define KeepLong MotoLong #define SwapLong IntelLong #endif short SwapShort (short l) { byte b1,b2; b1 = l&255; b2 = (l>>8)&255; return (b1<<8) + b2; } short KeepShort (short l) { return l; } int SwapLong (int l) { byte b1,b2,b3,b4; b1 = l&255; b2 = (l>>8)&255; b3 = (l>>16)&255; b4 = (l>>24)&255; return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; } int KeepLong (int l) { return l; } #undef KeepShort #undef KeepLong #undef SwapShort #undef SwapLong void SwapIntelLong(int *l) { *l = IntelLong(*l); } void SwapIntelShort(short *s) { *s = IntelShort(*s); } void SwapIntelLongArray(int *l, int num) { while (num--) { SwapIntelLong(l); l++; } } void SwapIntelShortArray(short *s, int num) { while (num--) { SwapIntelShort(s); s++; } } /* ============================================================================ BASIC GRAPHICS ============================================================================ */ /* ============== = = GetaPalette = = Return an 8 bit / color palette = ============== */ void GetaPalette (byte *palette) { #ifdef DOS int i; OUTP (PEL_READ_ADR,0); for (i=0 ; i<768 ; i++) palette[i] = inp (PEL_DATA)<<2; #else int i; SDL_Palette *pal = SDL_GetVideoSurface()->format->palette; for (i = 0; i < 256; i++) { palette[0] = pal->colors[i].r; palette[1] = pal->colors[i].g; palette[2] = pal->colors[i].b; palette += 3; } #endif } /* ============== = = SetaPalette = = Sets an 8 bit / color palette = ============== */ void SetaPalette (byte *pal) { #ifdef DOS int i; OUTP (PEL_WRITE_ADR,0); for (i=0 ; i<768 ; i++) OUTP (PEL_DATA, pal[i]>>2); #else SDL_Color cmap[256]; int i; for (i = 0; i < 256; i++) { cmap[i].r = pal[i*3+0]; cmap[i].g = pal[i*3+1]; cmap[i].b = pal[i*3+2]; } SDL_SetColors (SDL_GetVideoSurface (), cmap, 0, 256); #endif } void GetPalette(char * palette) { #ifdef DOS int i; OUTP(0x03c7,0); for (i=0;i<256*3;i++) *(palette+(unsigned char)i)=inp(0x3c9)<<2; #else int i; SDL_Palette *pal = SDL_GetVideoSurface()->format->palette; for (i = 0; i < 256; i++) { palette[0] = pal->colors[i].r; palette[1] = pal->colors[i].g; palette[2] = pal->colors[i].b; palette += 3; } #endif } void SetPalette ( char * pal ) { VL_SetPalette (pal); } //****************************************************************************** // // US_CheckParm() - checks to see if a string matches one of a set of // strings. The check is case insensitive. The routine returns the // index of the string that matched, or -1 if no matches were found // //****************************************************************************** int US_CheckParm (char *parm, char **strings) { char cp,cs, *p,*s; int i; int length; length=strlen(parm); while ( (!isalpha(*parm)) && (length>0)) // Skip non-alphas { length--; parm++; } for (i = 0;*strings && **strings;i++) { for (s = *strings++,p = parm,cs = cp = 0;cs == cp;) { cs = *s++; if (!cs) return(i); cp = *p++; if (isupper(cs)) cs = tolower(cs); if (isupper(cp)) cp = tolower(cp); } } return(-1); } /* ============================================================================= PALETTE OPS To avoid snow, do a WaitVBL BEFORE calling these ============================================================================= */ /* ================= = = VL_FillPalette = ================= */ void VL_FillPalette (int red, int green, int blue) { #ifdef DOS int i; OUTP (PEL_WRITE_ADR,0); for (i=0;i<256;i++) { OUTP (PEL_DATA,red); OUTP (PEL_DATA,green); OUTP (PEL_DATA,blue); } #else SDL_Color cmap[256]; int i; for (i = 0; i < 256; i++) { cmap[i].r = red << 2; cmap[i].g = green << 2; cmap[i].b = blue << 2; } SDL_SetColors (SDL_GetVideoSurface (), cmap, 0, 256); #endif } //=========================================================================== /* ================= = = VL_SetColor = ================= */ void VL_SetColor (int color, int red, int green, int blue) { #ifdef DOS OUTP (PEL_WRITE_ADR,color); OUTP (PEL_DATA,red); OUTP (PEL_DATA,green); OUTP (PEL_DATA,blue); #else STUB_FUNCTION; #endif } //=========================================================================== /* ================= = = VL_GetColor = ================= */ void VL_GetColor (int color, int *red, int *green, int *blue) { #ifdef DOS OUTP (PEL_READ_ADR,color); *red = inp (PEL_DATA); *green = inp (PEL_DATA); *blue = inp (PEL_DATA); #else STUB_FUNCTION; #endif } //=========================================================================== /* ================= = = VL_NormalizePalette = ================= */ void VL_NormalizePalette (byte *palette) { int i; for (i = 0; i < 768; i++) *(palette+i)=(*(palette+i))>>2; } /* ================= = = VL_SetPalette = = If fast palette setting has been tested for, it is used = -some cards don't like outsb palette setting- = ================= */ void VL_SetPalette (byte *palette) { #ifdef DOS int i; OUTP (PEL_WRITE_ADR, 0); for (i = 0; i < 768; i++) { OUTP (PEL_DATA, gammatable[(gammaindex<<6)+(*palette++)]); } #else SDL_Color cmap[256]; int i; for (i = 0; i < 256; i++) { cmap[i].r = gammatable[(gammaindex<<6)+(*palette++)] << 2; cmap[i].g = gammatable[(gammaindex<<6)+(*palette++)] << 2; cmap[i].b = gammatable[(gammaindex<<6)+(*palette++)] << 2; } SDL_SetColors (SDL_GetVideoSurface (), cmap, 0, 256); #endif } //=========================================================================== /* ================= = = VL_GetPalette = = This does not use the port string instructions, = due to some incompatabilities = ================= */ void VL_GetPalette (byte *palette) { #ifdef DOS int i; OUTP (PEL_READ_ADR, 0); for (i = 0; i < 768; i++) *palette++ = inp (PEL_DATA); #else int i; SDL_Palette *pal = SDL_GetVideoSurface()->format->palette; for (i = 0; i < 256; i++) { palette[0] = pal->colors[i].r >> 2; palette[1] = pal->colors[i].g >> 2; palette[2] = pal->colors[i].b >> 2; palette += 3; } #endif } /* ================= = = UL_DisplayMemoryError () = ================= */ void UL_DisplayMemoryError ( int memneeded ) { #ifdef DOS char buf[4000]; int i; ShutDown (); TextMode (); for (i = 0; i < 19; i++) printf ("\n"); memcpy (buf, &ROTT_ERR, 4000); memcpy ((byte *)0xB8000, &buf[160*7], 4000-(160*7)); px = ERRORVERSIONCOL; py = ERRORVERSIONROW; #if (BETA == 1) UL_printf ("á"); #else UL_printf (itoa(ROTTMAJORVERSION,&buf[0],10)); #endif px++; UL_printf (itoa(ROTTMINORVERSION,&buf[0],10)); px = LOWMEMORYCOL; py = LOWMEMORYROW; UL_printf ("You need "); UL_printf (itoa(memneeded,&buf[0],10)); UL_printf (" bytes more memory"); if ( SOUNDSETUP ) { getch(); } #else STUB_FUNCTION; #endif exit (0); } /* ================= = = UL_printf = ================= */ void UL_printf (byte *str) { #ifdef DOS byte *s; byte *screen; s = str; screen = (byte *)(0xB8000 + (py*160) + (px<<1)); while (*s) { *screen = *s; s++; screen += 2; px++; if ((*s < 32) && (*s > 0)) s++; } #else #ifdef ANSIESC printf ("\x1b[%d;%dH%s",py,px,str); #else printf ("%s ",str); // Hackish but works - DDOI #endif #endif } /* ================= = = UL_ColorBox = ================= */ void UL_ColorBox (int x, int y, int w, int h, int color) { #ifdef DOS byte *screen; int i,j; for (j=0;jU) break; if( (c+Width <= U) && ((*Comp)(Base+c+Width,Base+c)>0) ) c+= Width; if ((*Comp)(Base+L,Base+c)>=0) break; (*Switch)(Base+L, Base+c); L=c; } } void hsort(char * base, int nel, int width, int (*compare)(), void (*switcher)()) { static int i,n,stop; /* Perform a heap sort on an array starting at base. The array is nel elements large and width is the size of a single element in bytes. Compare is a pointer to a comparison routine which will be passed pointers to two elements of the array. It should return a negative number if the left-most argument is less than the rightmost, 0 if the two arguments are equal, a positive number if the left argument is greater than the right. (That is, it acts like a "subtract" operator.) If compare is 0 then the default comparison routine, argvcmp (which sorts an argv-like array of pointers to strings), is used. */ Width=width; Comp= compare; Switch= switcher; n=nel*Width; Base=base-Width; for (i=(n/Width/2)*Width; i>=Width; i-=Width) newsift_down(i,n); stop=Width+Width; for (i=n; i>=stop; ) { (*Switch)(base, Base+i); newsift_down(Width,i-=Width); } } /*---------------------------------------------------------------------------*/ //****************************************************************************** // // UL_GetPath // // Purpose // To parse the directory entered by the user to make the directory. // // Parms // Path - the path to be parsed. // // Returns // Pointer to next path // //****************************************************************************** char * UL_GetPath (char * path, char *dir) { boolean done = 0; char *dr = dir; int cnt = 0; if (*path == SLASHES) path++; while (!done) { *dr = *path; cnt++; // make sure the number of characters in the dir if (cnt > MAXCHARS) // name doesn't exceed acceptable limits. Error ("ERROR : Directory name can only be %d characters long.\n", MAXCHARS); path++; dr++; if ((*path == SLASHES) || (*path == 0)) done = true; } *dr = 0; return (path); } //****************************************************************************** // // UL_ChangeDirectory () // // Purpose // To change to a directory. Checks for drive changes. // // Parms // path - The path to change to. // // Returns // TRUE - If successful. // FALSE - If unsuccessful. // //****************************************************************************** boolean UL_ChangeDirectory (char *path) { #ifdef DOS char *p; char dir[9]; char *d; d = &dir[0]; p = path; memset (dir, 0, 9); // Check for a drive at the beginning of the path if (*(p+1) == ':') { *d++ = *p++; // drive letter *d++ = *p++; // colon if (UL_ChangeDrive (dir) == false) return (false); } if (*p == SLASHES) { chdir ("\\"); p++; } d = &dir[0]; while (*p) { p = UL_GetPath (p, d); if (chdir (d) == -1) return (false); } return (true); #else if (!*path) { return true; } if (chdir (path) == -1) { return (false); } return true; #endif } //****************************************************************************** // // UL_ChangeDrive () // // Purpose // To change drives. // // Parms // drive - The drive to change to. // // Returns // TRUE - If drive change successful. // FALSE - If drive change unsuccessful. // //****************************************************************************** boolean UL_ChangeDrive (char *drive) { #ifdef DOS unsigned d, total, tempd; d = toupper (*drive); d = d - 'A' + 1; _dos_setdrive (d, &total); _dos_getdrive (&tempd); if (d != tempd) return (false); return (true); #else STUB_FUNCTION; return false; #endif } /* ============= = = AbortCheck = ============= */ void AbortCheck (char * abortstring) { // User abort check IN_UpdateKeyboard (); if (Keyboard[sc_Escape]) Error("%s\n",abortstring); }