/* sys_sun.c @description@ Copyright (C) 1996-1997 Id Software, Inc. 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: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA $Id$ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "errno.h" #include #include #include #include #include #include #include #include #include #include #include qboolean isDedicated; /* =============================================================================== FILE IO =============================================================================== */ #define MAX_HANDLES 10 typedef struct { QFile *hFile; char *pMap; int nLen; int nPos; } MEMFILE; MEMFILE sys_handles[MAX_HANDLES]; int findhandle (void) { int i; for (i = 1; i < MAX_HANDLES; i++) if (!sys_handles[i].hFile) return i; Sys_Error ("out of handles"); return -1; } /* ================ filelength ================ */ int filelength (QFile *f) { int pos; int end; pos = ftell (f); fseek (f, 0, SEEK_END); end = ftell (f); fseek (f, pos, SEEK_SET); return end; } int Sys_FileOpenRead (char *path, int *hndl) { QFile *f; int i; i = findhandle (); f = Qopen (path, "rb"); if (!f) { *hndl = -1; return -1; } sys_handles[i].hFile = f; sys_handles[i].nLen = filelength (f); sys_handles[i].nPos = 0; sys_handles[i].pMap = mmap (0, sys_handles[i].nLen, PROT_READ, MAP_SHARED, fileno (sys_handles[i].hFile), 0); if (!sys_handles[i].pMap || (sys_handles[i].pMap == (char *) -1)) { printf ("mmap %s failed!", path); sys_handles[i].pMap = NULL; } *hndl = i; return (sys_handles[i].nLen); } int Sys_FileOpenWrite (char *path) { QFile *f; int i; i = findhandle (); f = Qopen (path, "wb"); if (!f) Sys_Error ("Error opening %s: %s", path, strerror (errno)); sys_handles[i].hFile = f; sys_handles[i].nLen = 0; sys_handles[i].nPos = 0; sys_handles[i].pMap = NULL; return i; } void Sys_FileClose (int handle) { if (sys_handles[handle].pMap) if (munmap (sys_handles[handle].pMap, sys_handles[handle].nLen) != 0) printf ("failed to unmap handle %d\n", handle); Qclose (sys_handles[handle].hFile); sys_handles[handle].hFile = NULL; } void Sys_FileSeek (int handle, int position) { if (sys_handles[handle].pMap) { sys_handles[handle].nPos = position; } else fseek (sys_handles[handle].hFile, position, SEEK_SET); } int Sys_FileRead (int handle, void *dest, int count) { if (sys_handles[handle].pMap) { int nPos = sys_handles[handle].nPos; if (count < 0) count = 0; if (nPos + count > sys_handles[handle].nLen) count = sys_handles[handle].nLen - nPos; memcpy (dest, &sys_handles[handle].pMap[nPos], count); sys_handles[handle].nPos = nPos + count; return (count); } else return fread (dest, 1, count, sys_handles[handle].hFile); } int Sys_FileWrite (int handle, void *data, int count) { if (sys_handles[handle].pMap) Sys_Error ("Attempted to write to read-only file %d!\n", handle); return fwrite (data, 1, count, sys_handles[handle].hFile); } int Sys_FileTime (char *path) { QFile *f; f = Qopen (path, "rb"); if (f) { Qclose (f); return 1; } return -1; } void Sys_mkdir (char *path) { mkdir (path, 0777); } /* =============================================================================== SYSTEM IO =============================================================================== */ void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length) { int r; unsigned long addr; int psize = getpagesize (); addr = (startaddr & ~(psize - 1)) - psize; // fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr, // addr, startaddr+length, length); r = mprotect ((char *) addr, length + startaddr - addr + psize, 7); if (r < 0) Sys_Error ("Protection change failed\n"); } void Sys_Error (char *error, ...) { va_list argptr; printf ("Sys_Error: "); va_start (argptr, error); vprintf (error, argptr); va_end (argptr); printf ("\n"); Host_Shutdown (); exit (1); } void Sys_Printf (char *fmt, ...) { va_list argptr; va_start (argptr, fmt); vprintf (fmt, argptr); va_end (argptr); } void Sys_Quit (void) { Host_Shutdown (); exit (0); } double Sys_DoubleTime (void) { struct timeval tp; struct timezone tzp; static int secbase; gettimeofday (&tp, &tzp); if (!secbase) { secbase = tp.tv_sec; return tp.tv_usec / 1000000.0; } return (tp.tv_sec - secbase) + tp.tv_usec / 1000000.0; } char * Sys_ConsoleInput (void) { static char text[256]; int len; fd_set readfds; int ready; struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 0; FD_ZERO (&readfds); FD_SET (0, &readfds); ready = select (1, &readfds, 0, 0, &timeout); if (ready > 0) { len = read (0, text, sizeof (text)); if (len >= 1) { text[len - 1] = 0; // rip off the /n and terminate return text; } } return 0; } void Sys_Sleep (void) { } #ifndef USE_INTEL_ASM void Sys_HighFPPrecision (void) { } void Sys_LowFPPrecision (void) { } #endif void Sys_Init (void) { #ifdef USE_INTEL_ASM Sys_SetFPCW (); #endif } //============================================================================= int main (int argc, char **argv) { static quakeparms_t parms; float time, oldtime, newtime; parms.memsize = 16 * 1024 * 1024; parms.membase = malloc (parms.memsize); parms.basedir = "."; parms.cachedir = NULL; COM_InitArgv (argc, argv); parms.argc = com_argc; parms.argv = com_argv; printf ("Host_Init\n"); Host_Init (&parms); Sys_Init (); // unroll the simulation loop to give the video side a chance to see // _vid_default_mode Host_Frame (0.1); VID_SetDefaultMode (); oldtime = Sys_DoubleTime (); while (1) { newtime = Sys_DoubleTime (); Host_Frame (newtime - oldtime); oldtime = newtime; } return 0; }