/* Relay -- a tool to record and play Quake2 demos Copyright (C) 2000 Conor Davis 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. Conor Davis cedavis@planetquake.com */ #ifdef WIN32 #include // for kbhit() #include // for GetTickCount() #else #include #include // for gettimeofday(...) #include #endif #include #include #include #include "shared.h" #include "block.h" #include "mem.h" #include "pak.h" #include "utils.h" // // MISCELLANEOUS // // returns a (hopefully) millisecond-accurate timer size_t mstime() { #ifdef WIN32 return GetTickCount(); #else // FIXME: better way? struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec*1000 + tv.tv_usec/1000; #endif } void msleep(size_t msecs) { #ifdef WIN32 Sleep(msecs); #else usleep(msecs * 1000); #endif } const char *read_line() { static char buf[1024]; #ifdef WIN32 // there has to be a better way to poll for line input static qboolean reset; if (reset) { buf[0] = 0; reset = false; } while (_kbhit()) { int c = _getch(); int len = strlen(buf); if (c == 0 || c == 0xe0) { _getch(); continue; } if (c == 8) { if (len) { buf[len-1] = 0; printf("\r%*s\r%s", len, " ", buf); } } else { if (c == '\r') c = '\n'; putc(c, stdout); buf[len] = (char)c; buf[len+1] = 0; if (c == '\n' || len == sizeof(buf)-1) { reset = true; return buf; } } } return NULL; #else // !WIN32 struct pollfd ufd = {0, POLLIN, 0}; poll(&ufd, 1, 0); if (ufd.revents & POLLIN) return fgets(buf, sizeof(buf), stdin); return NULL; #endif // !WIN32 } char *GamePath(char *dest, char *basedir, char *gamedir) { if (basedir[0]) { strcpy(dest, basedir); strcat(dest, "/"); } if (gamedir[0]) strcat(dest, gamedir); else strcat(dest, "baseq2"); return dest; } qboolean FileExists(char *filename) { FILE *f; f = fopen(filename, "rb"); if (!f) return false; fclose(f); return true; } int LoadFile(char *path, block_t *block) { FILE *fd; size_t len; fd = fopen(path, "rb"); if (!fd) return -1; fseek(fd, 0, SEEK_END); len = ftell(fd); fseek(fd, 0, SEEK_SET); BlockInit(block, Z_Malloc(len), len); if (!fread(block->buffer, len, 1, fd)) { Z_Free(block->buffer); fclose(fd); return -1; } fclose(fd); block->writeoffset = len; return len; } int Pack_LoadFile(char *path, block_t *block) { PFILE *fd; size_t len; fd = pfopen(path, "pvrb"); if (!fd) return -1; pfseek(fd, 0, SEEK_END); len = pftell(fd); pfseek(fd, 0, SEEK_SET); BlockInit(block, Z_Malloc(len), len); if (!pfread(block->buffer, len, 1, fd)) { Z_Free(block->buffer); pfclose(fd); return -1; } pfclose(fd); block->writeoffset = len; return len; } int ExpandString(char *dest, int len, char *src, char format[256][32]) { char *o, *s; o = dest; while (*src && len) { if (*src == '%') { src++; s = format[(int)*src]; while (*s && len) { *o++ = *s++; len--; } src++; } else { *o++ = *src++; len--; } } if (len) { *o++ = 0; return o - dest; } return 0; } const char *PlayerName(const char *s) { static char buf[16]; int i; for (i = 0; i < sizeof(buf); i++) { if (!s[i] || s[i] == '\\') break; buf[i] = s[i]; } return buf; } char *strcatf(char *out, size_t size, const char *fmt, ...) { va_list argptr; char buffer[0x10000]; size_t len; len = strlen(out); va_start(argptr, fmt); len += vsprintf(buffer, fmt, argptr); va_end(argptr); if (len >= size) Com_Printf("strcatf: overflow of %u in %u\n", len, size); else strcat(out, buffer); return out; }