#include #import #include "../qcommon/qcommon.h" int curtime; int sys_frame_time; void Sys_UnloadGame (void) { } void *GetGameAPI (void *import); void *Sys_GetGameAPI (void *parms) { // we are hard-linked in, so no need to load anything return GetGameAPI (parms); } void Sys_CopyProtect (void) { } char *Sys_GetClipboardData( void ) { return NULL; } //=========================================================================== int hunkcount; byte *membase; int hunkmaxsize; int cursize; //#define VIRTUAL_ALLOC void *Hunk_Begin (int maxsize) { // reserve a huge chunk of memory, but don't commit any yet cursize = 0; hunkmaxsize = maxsize; #ifdef VIRTUAL_ALLOC membase = VirtualAlloc (NULL, maxsize, MEM_RESERVE, PAGE_NOACCESS); #else membase = malloc (maxsize); memset (membase, 0, maxsize); #endif if (!membase) Sys_Error ("VirtualAlloc reserve failed"); return (void *)membase; } void *Hunk_Alloc (int size) { void *buf; // round to cacheline size = (size+31)&~31; #ifdef VIRTUAL_ALLOC // commit pages as needed // buf = VirtualAlloc (membase+cursize, size, MEM_COMMIT, PAGE_READWRITE); buf = VirtualAlloc (membase, cursize+size, MEM_COMMIT, PAGE_READWRITE); if (!buf) { FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buf, 0, NULL); Sys_Error ("VirtualAlloc commit failed.\n%s", buf); } #endif cursize += size; if (cursize > hunkmaxsize) Sys_Error ("Hunk_Alloc overflow"); return (void *)(membase+cursize-size); } int Hunk_End (void) { // free the remaining unused virtual memory #if 0 void *buf; // write protect it buf = VirtualAlloc (membase, cursize, MEM_COMMIT, PAGE_READONLY); if (!buf) Sys_Error ("VirtualAlloc commit failed"); #endif hunkcount++; //Com_Printf ("hunkcount: %i\n", hunkcount); return cursize; } void Hunk_Free (void *base) { if ( base ) #ifdef VIRTUAL_ALLOC VirtualFree (base, 0, MEM_RELEASE); #else free (base); #endif hunkcount--; } //=========================================================================== void Sys_Mkdir (char *path) { if (mkdir (path, 0777) != -1) return; if (errno != EEXIST) Com_Error (ERR_FATAL, "mkdir %s: %s",path, strerror(errno)); } char *Sys_FindFirst (char *path, unsigned musthave, unsigned canthave) { return NULL; } char *Sys_FindNext (unsigned musthave, unsigned canthave) { return NULL; } void Sys_FindClose (void) { } /* ================ Sys_Milliseconds ================ */ int Sys_Milliseconds (void) { struct timeval tp; struct timezone tzp; static int secbase; gettimeofday(&tp, &tzp); if (!secbase) { secbase = tp.tv_sec; return tp.tv_usec/1000; } curtime = (tp.tv_sec - secbase)*1000 + tp.tv_usec/1000; return curtime; } /* ================ Sys_Error ================ */ void Sys_Error (char *error, ...) { va_list argptr; char string[1024]; // change stdin to non blocking fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY); va_start (argptr,error); vsprintf (string,error,argptr); va_end (argptr); printf ("Fatal error: %s\n",string); if (!NSApp) { // appkit isn't running, so don't try to pop up a panel exit (1); } NSRunAlertPanel (@"Fatal error",[NSString stringWithCString: string] ,@"exit",NULL,NULL); [NSApp terminate: NULL]; exit(1); } /* ================ Sys_Printf ================ */ void Sys_ConsoleOutput (char *text) { char *t_p; int l, r; l = strlen(text); t_p = text; // make sure everything goes through, even though we are non-blocking while (l) { r = write (1, text, l); if (r != l) sleep (0); if (r > 0) { t_p += r; l -= r; } } } /* ================ Sys_Quit ================ */ void Sys_Quit (void) { // change stdin to blocking fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY); if (!NSApp) exit (0); // appkit isn't running [NSApp terminate:nil]; } /* ================ Sys_Init ================ */ void Sys_Init(void) { moncontrol(0); // turn off profiling except during real Quake work // change stdin to non blocking fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY); } extern NSWindow *vid_window_i; void Sys_AppActivate (void) { [vid_window_i makeKeyAndOrderFront: nil]; } /* ================ Sys_SendKeyEvents service any pending appkit events ================ */ void Sys_SendKeyEvents (void) { NSEvent *event; NSDate *date; date = [NSDate date]; do { event = [NSApp nextEventMatchingMask: 0xffffffff untilDate: date inMode: @"NSDefaultRunLoopMode" dequeue: YES]; if (event) [NSApp sendEvent: event]; } while (event); // grab frame time sys_frame_time = Sys_Milliseconds(); } /* ================ Sys_ConsoleInput Checks for a complete line of text typed in at the console, then forwards it to the host command processor ================ */ char *Sys_ConsoleInput (void) { static char text[256]; int len; len = read (0, text, sizeof(text)); if (len < 1) return NULL; text[len-1] = 0; // rip off the /n and terminate return text; } /* ============= main ============= */ void main (int argc, char **argv) { int frame; NSAutoreleasePool *pool; int oldtime, t; pool = [[NSAutoreleasePool alloc] init]; Qcommon_Init (argc, argv); [pool release]; oldtime = Sys_Milliseconds (); while (1) { pool =[[NSAutoreleasePool alloc] init]; if (++frame > 10) moncontrol(1);// profile only while we do each Quake frame t = Sys_Milliseconds (); Qcommon_Frame (t - oldtime); oldtime = t; moncontrol(0); [pool release]; } }