Mac OS X work...lots of little changes that touch a lot of random places.

Still work to be done, but this at least matches the PowerPC Linux status
 now.

MacOS-specific directory (and XCode project) is gone...this now uses SDL,
 OpenAL, and the Unix Makefiles.

--ryan.
This commit is contained in:
Ryan C. Gordon 2005-11-26 07:46:21 +00:00
parent b20b86bbbe
commit 721b9a7d01
61 changed files with 877 additions and 22868 deletions

View File

@ -554,7 +554,7 @@ int PS_ReadName(script_t *script, token_t *token)
// Changes Globals: -
//============================================================================
void NumberValue(char *string, int subtype, unsigned long int *intvalue,
long double *floatvalue)
double *floatvalue)
{
unsigned long int dotfound = 0;
@ -573,13 +573,13 @@ void NumberValue(char *string, int subtype, unsigned long int *intvalue,
} //end if
if (dotfound)
{
*floatvalue = *floatvalue + (long double) (*string - '0') /
(long double) dotfound;
*floatvalue = *floatvalue + (double) (*string - '0') /
(double) dotfound;
dotfound *= 10;
} //end if
else
{
*floatvalue = *floatvalue * 10.0 + (long double) (*string - '0');
*floatvalue = *floatvalue * 10.0 + (double) (*string - '0');
} //end else
string++;
} //end while
@ -631,7 +631,7 @@ int PS_ReadNumber(script_t *script, token_t *token)
int octal, dot;
char c;
// unsigned long int intvalue = 0;
// long double floatvalue = 0;
// double floatvalue = 0;
token->type = TT_NUMBER;
//check for a hexadecimal number
@ -1148,15 +1148,15 @@ void StripSingleQuotes(char *string)
// Returns: -
// Changes Globals: -
//============================================================================
long double ReadSignedFloat(script_t *script)
double ReadSignedFloat(script_t *script)
{
token_t token;
long double sign = 1;
double sign = 1.0;
PS_ExpectAnyToken(script, &token);
if (!strcmp(token.string, "-"))
{
sign = -1;
sign = -1.0;
PS_ExpectTokenType(script, TT_NUMBER, 0, &token);
} //end if
else if (token.type != TT_NUMBER)

View File

@ -161,7 +161,7 @@ typedef struct token_s
int subtype; //last read token sub type
#ifdef NUMBERVALUE
unsigned long int intvalue; //integer value
long double floatvalue; //floating point value
double floatvalue; //floating point value
#endif //NUMBERVALUE
char *whitespace_p; //start of white space before token
char *endwhitespace_p; //start of white space before token
@ -218,7 +218,7 @@ void StripSingleQuotes(char *string);
//read a possible signed integer
signed long int ReadSignedInt(script_t *script);
//read a possible signed floating point number
long double ReadSignedFloat(script_t *script);
double ReadSignedFloat(script_t *script);
//set an array with punctuations, NULL restores default C/C++ set
void SetScriptPunctuations(script_t *script, punctuation_t *p);
//set script flags

View File

@ -28,14 +28,23 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "qal.h"
#if USE_OPENAL_DLOPEN
#if defined _WIN32
#if USE_SDL_VIDEO
#include "SDL.h"
#include "SDL_loadso.h"
#define OBJTYPE void *
#define OBJLOAD(x) SDL_LoadObject(x)
#define SYMLOAD(x,y) SDL_LoadFunction(x,y)
#define OBJFREE(x) SDL_UnloadObject(x)
#elif defined _WIN32
#include <windows.h>
#define OBJTYPE HMODULE
#define OBJLOAD(x) LoadLibrary(x)
#define SYMLOAD(x,y) GetProcAddress(x,y)
#define OBJFREE(x) FreeLibrary(x)
#elif defined __linux__ || defined __FreeBSD__
#elif defined __linux__ || defined __FreeBSD__ || defined MACOS_X
#include <unistd.h>
#include <sys/types.h>
#include <dlfcn.h>

View File

@ -32,8 +32,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define AL_NO_PROTOTYPES
#define ALC_NO_PROTOTYPES
#endif
#include <AL/al.h>
#include <AL/alc.h>
#include "../AL/al.h"
#include "../AL/alc.h"
#if USE_OPENAL_DLOPEN
extern LPALENABLE qalEnable;

View File

@ -42,7 +42,7 @@ static int FGetLittleLong( fileHandle_t f ) {
FGetLittleShort
=================
*/
static int FGetLittleShort( fileHandle_t f ) {
static short FGetLittleShort( fileHandle_t f ) {
short v;
FS_Read( &v, sizeof(v), f );

View File

@ -224,7 +224,8 @@ CHANNEL MIXING
===============================================================================
*/
static void S_PaintChannelFrom16( channel_t *ch, const sfx_t *sc, int count, int sampleOffset, int bufferOffset ) {
#if idppc_altivec
static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int count, int sampleOffset, int bufferOffset ) {
int data, aoff, boff;
int leftvol, rightvol;
int i, j;
@ -249,15 +250,12 @@ static void S_PaintChannelFrom16( channel_t *ch, const sfx_t *sc, int count, int
}
if (!ch->doppler || ch->dopplerScale==1.0f) {
#if idppc_altivec
vector signed short volume_vec;
vector unsigned int volume_shift;
int vectorCount, samplesLeft, chunkSamplesLeft;
#endif
leftvol = ch->leftvol*snd_vol;
rightvol = ch->rightvol*snd_vol;
samples = chunk->sndChunk;
#if idppc_altivec
((short *)&volume_vec)[0] = leftvol;
((short *)&volume_vec)[1] = leftvol;
((short *)&volume_vec)[4] = leftvol;
@ -297,14 +295,12 @@ static void S_PaintChannelFrom16( channel_t *ch, const sfx_t *sc, int count, int
{
vector unsigned char tmp;
vector short s0, s1, sampleData0, sampleData1;
vector short samples0, samples1;
vector signed int left0, right0;
vector signed int merge0, merge1;
vector signed int d0, d1, d2, d3;
vector unsigned char samplePermute0 =
(vector unsigned char){0, 1, 4, 5, 0, 1, 4, 5, 2, 3, 6, 7, 2, 3, 6, 7};
vector unsigned char samplePermute0 =
VECCONST_UINT8(0, 1, 4, 5, 0, 1, 4, 5, 2, 3, 6, 7, 2, 3, 6, 7);
vector unsigned char samplePermute1 =
(vector unsigned char){8, 9, 12, 13, 8, 9, 12, 13, 10, 11, 14, 15, 10, 11, 14, 15};
VECCONST_UINT8(8, 9, 12, 13, 8, 9, 12, 13, 10, 11, 14, 15, 10, 11, 14, 15);
vector unsigned char loadPermute0, loadPermute1;
// Rather than permute the vectors after we load them to do the sample
@ -365,7 +361,66 @@ static void S_PaintChannelFrom16( channel_t *ch, const sfx_t *sc, int count, int
}
}
}
#else
} else {
fleftvol = ch->leftvol*snd_vol;
frightvol = ch->rightvol*snd_vol;
ooff = sampleOffset;
samples = chunk->sndChunk;
for ( i=0 ; i<count ; i++ ) {
aoff = ooff;
ooff = ooff + ch->dopplerScale;
boff = ooff;
fdata = 0;
for (j=aoff; j<boff; j++) {
if (j == SND_CHUNK_SIZE) {
chunk = chunk->next;
if (!chunk) {
chunk = sc->soundData;
}
samples = chunk->sndChunk;
ooff -= SND_CHUNK_SIZE;
}
fdata += samples[j&(SND_CHUNK_SIZE-1)];
}
fdiv = 256 * (boff-aoff);
samp[i].left += (fdata * fleftvol)/fdiv;
samp[i].right += (fdata * frightvol)/fdiv;
}
}
}
#endif
static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int count, int sampleOffset, int bufferOffset ) {
int data, aoff, boff;
int leftvol, rightvol;
int i, j;
portable_samplepair_t *samp;
sndBuffer *chunk;
short *samples;
float ooff, fdata, fdiv, fleftvol, frightvol;
samp = &paintbuffer[ bufferOffset ];
if (ch->doppler) {
sampleOffset = sampleOffset*ch->oldDopplerScale;
}
chunk = sc->soundData;
while (sampleOffset>=SND_CHUNK_SIZE) {
chunk = chunk->next;
sampleOffset -= SND_CHUNK_SIZE;
if (!chunk) {
chunk = sc->soundData;
}
}
if (!ch->doppler || ch->dopplerScale==1.0f) {
leftvol = ch->leftvol*snd_vol;
rightvol = ch->rightvol*snd_vol;
samples = chunk->sndChunk;
for ( i=0 ; i<count ; i++ ) {
data = samples[sampleOffset++];
samp[i].left += (data * leftvol)>>8;
@ -377,7 +432,6 @@ static void S_PaintChannelFrom16( channel_t *ch, const sfx_t *sc, int count, int
sampleOffset = 0;
}
}
#endif
} else {
fleftvol = ch->leftvol*snd_vol;
frightvol = ch->rightvol*snd_vol;
@ -412,6 +466,18 @@ static void S_PaintChannelFrom16( channel_t *ch, const sfx_t *sc, int count, int
}
}
static void S_PaintChannelFrom16( channel_t *ch, const sfx_t *sc, int count, int sampleOffset, int bufferOffset ) {
#if idppc_altivec
extern cvar_t *com_altivec;
if (com_altivec->integer) {
// must be in a seperate function or G3 systems will crash.
S_PaintChannelFrom16_altivec( ch, sc, count, sampleOffset, bufferOffset );
return;
}
#endif
S_PaintChannelFrom16_scalar( ch, sc, count, sampleOffset, bufferOffset );
}
void S_PaintChannelFromWavelet( channel_t *ch, sfx_t *sc, int count, int sampleOffset, int bufferOffset ) {
int data;
int leftvol, rightvol;

Binary file not shown.

Binary file not shown.

View File

@ -1,17 +0,0 @@
#!/bin/zsh
APPNAME="Quake3"
PACKAGENAME= Quake3
(cd $OMNI_SOURCE_ROOT; ./Build Quake3 install)
rm -rf "/tmp/$APPNAME"
mkdir "/tmp/$APPNAME"
cp "Read Me.rtf" "/tmp/$APPNAME"
cd /Users/Shared/$USER/InstalledProducts
gnutar cf - FAKK2.app | (cd "/tmp/$APPNAME"; gnutar xf -)
cd "/tmp/$APPNAME"
sudo ~bungi/Unix/bin/files2image $PACKAGENAME ./*

View File

@ -1,27 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#import <ApplicationServices/ApplicationServices.h>
extern void CGFix_Initialize();
extern void CGFix_GetLastMouseDelta(CGMouseDelta *dx, CGMouseDelta *dy);

View File

@ -1,131 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#import "CGMouseDeltaFix.h"
#import "CGPrivateAPI.h"
#import <Foundation/Foundation.h>
#import <mach-o/dyld.h>
// We will try to automatically fall back to using the original CGGetLastMouseDelta when we are on a system new enough to have the fix. Any version of CoreGraphics past 1.93.0 will have the fixed version.
static BOOL originalVersionShouldWork = YES;
static CGMouseDelta CGFix_Mouse_DeltaX, CGFix_Mouse_DeltaY;
static void CGFix_NotificationCallback(CGSNotificationType note, CGSNotificationData data, CGSByteCount dataLength, CGSNotificationArg arg);
static CGSRegisterNotifyProcType registerNotifyProc = NULL;
void CGFix_Initialize()
{
NSAutoreleasePool *pool;
NSBundle *cgBundle;
NSString *version;
NSArray *components;
if (registerNotifyProc)
// We've already been called once and have registered our callbacks. If the original version works, this will be NULL, but we'll end up doing nothing (again, possibly).
return;
//NSLog(@"CGFix_Initialize\n");
pool = [[NSAutoreleasePool alloc] init];
cgBundle = [NSBundle bundleWithPath: @"/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework"];
if (!cgBundle) {
// If it's moved, it must be newer than what we know about and should work
//NSLog(@"No /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework\n");
goto done;
}
version = [[cgBundle infoDictionary] objectForKey: @"CFBundleShortVersionString"];
components = [version componentsSeparatedByString: @"."];
//NSLog(@"version = %@\n", version);
//NSLog(@"components = %@\n", components);
if ([components count] < 2)
// We don't understand this versioning scheme. Must have changed.
goto done;
if (![[components objectAtIndex: 0] isEqualToString: @"1"] || [[components objectAtIndex: 1] intValue] > 93)
// This version should be new enough to work
goto done;
// Look up the function pointer we need to register our callback.
if (!NSIsSymbolNameDefined("_CGSRegisterNotifyProc")) {
//NSLog(@"No _CGSRegisterNotifyProc\n");
goto done;
}
registerNotifyProc = NSAddressOfSymbol(NSLookupAndBindSymbol("_CGSRegisterNotifyProc"));
//NSLog(@"registerNotifyProc = 0x%08x", registerNotifyProc);
// Must not work if we got here
originalVersionShouldWork = NO;
// We want to catch all the events that could possible indicate mouse movement and sum them up
registerNotifyProc( CGFix_NotificationCallback, kCGSEventNotificationMouseMoved, NULL);
registerNotifyProc( CGFix_NotificationCallback, kCGSEventNotificationLeftMouseDragged, NULL);
registerNotifyProc( CGFix_NotificationCallback, kCGSEventNotificationRightMouseDragged, NULL);
registerNotifyProc( CGFix_NotificationCallback, kCGSEventNotificationNotificationOtherMouseDragged, NULL);
done:
[pool release];
}
void CGFix_GetLastMouseDelta(CGMouseDelta *dx, CGMouseDelta *dy)
{
if (originalVersionShouldWork) {
CGGetLastMouseDelta(dx, dy);
return;
}
*dx = CGFix_Mouse_DeltaX;
*dy = CGFix_Mouse_DeltaY;
CGFix_Mouse_DeltaX = CGFix_Mouse_DeltaY = 0;
}
static void CGFix_NotificationCallback(CGSNotificationType note, CGSNotificationData data, CGSByteCount dataLength, CGSNotificationArg arg)
{
CGSEventRecordPtr event;
//fprintf(stderr, "CGFix_NotificationCallback(note=%d, date=0x%08x, dataLength=%d, arg=0x%08x)\n", note, data, dataLength, arg);
#ifdef DEBUG
if ((note != kCGSEventNotificationMouseMoved &&
note != kCGSEventNotificationLeftMouseDragged &&
note != kCGSEventNotificationRightMouseDragged &&
note != kCGSEventNotificationNotificationOtherMouseDragged) ||
dataLength != sizeof (CGSEventRecord))
fprintf(stderr, "Unexpected arguments to callback function CGFix_NotificationCallback(note=%d, date=0x%08x, dataLength=%d, arg=0x%08x)\n", note, data, dataLength, arg);
abort();
}
#endif
event = (CGSEventRecordPtr)data;
CGFix_Mouse_DeltaX += event->data.move.deltaX;
CGFix_Mouse_DeltaY += event->data.move.deltaY;
//fprintf(stderr, " dx += %d, dy += %d\n", event->data.move.deltaX, event->data.move.deltaY);
}

View File

@ -1,185 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
typedef unsigned long CGSNotificationType;
typedef void * CGSNotificationData;
typedef void * CGSNotificationArg;
typedef void * CGSWindowID;
typedef void * CGSConnectionID;
typedef unsigned long long CGSUInt64;
typedef long long CGSInt64;
typedef unsigned long CGSUInt32;
typedef long CGSInt32;
typedef unsigned short CGSUInt16;
typedef short CGSInt16;
typedef unsigned char CGSUInt8;
typedef char CGSInt8;
typedef float CGSFloat32;
typedef CGSUInt32 CGSByteCount;
typedef CGSUInt16 CGSEventRecordVersion;
typedef unsigned long CGSEventType;
typedef CGSUInt64 CGSEventRecordTime; /* nanosecond timer */
typedef unsigned long CGSEventFlag;
typedef CGSUInt32 CGSError;
typedef union {
struct { /* For mouse events */
CGSUInt8 subx; /* sub-pixel position for x */
CGSUInt8 suby; /* sub-pixel position for y */
CGSInt16 eventNum; /* unique identifier for this button */
CGSInt32 click; /* click state of this event */
CGSUInt8 pressure; /* pressure value: 0=none, 255=full */
CGSInt8 _reserved1;
CGSInt16 _reserved2;
CGSInt16 deltaX;
CGSInt16 deltaY;
CGSInt32 _padding[8];
} mouse;
struct { /* For pointer movement events */
CGSInt16 _obsolete_deltaX; /* Revert to subX, subY, eventNum */
CGSInt16 _obsolete_deltaY; /* for Gonzo 1H */
CGSInt32 click; /* click state of this event */
CGSUInt8 pressure; /* pressure value: 0=none, 255=full */
CGSInt8 _reserved1;
CGSInt16 _reserved2;
CGSInt16 deltaX;
CGSInt16 deltaY;
CGSInt32 _padding[8];
} move;
struct { /* For key-down and key-up events */
CGSInt16 reserved;
CGSInt16 repeat; /* for key-down: nonzero if really a repeat */
CGSUInt16 charSet; /* character set code */
CGSUInt16 charCode; /* character code in that set */
CGSUInt16 keyCode; /* device-dependent virtual key code */
CGSInt16 keyData; /* device-dependent info */
CGSInt16 specialKey; /* CPSSpecialKeyID if kCGSFlagsMaskSpecialKey is set */
CGSInt16 _pad;
CGSInt32 _padding[8];
} key;
struct { /* For mouse-entered and mouse-exited events */
CGSInt16 reserved;
CGSInt16 eventNum; /* unique identifier from mouse down event */
CGSInt32 trackingNum; /* unique identifier from settrackingrect */
CGSInt32 userData; /* unCGSInt32erpreted CGSInt32eger from settrackingrect */
CGSInt32 _padding[9];
} tracking;
struct { /* For process-related events */
CGSUInt16 notifyCode; /* CPSNotificationCodes in CPSProcesses.h */
CGSUInt16 flags; /* CPSEventFlags in CPSProcesses.h */
CGSUInt32 targetHiPSN; /* hiword of PSN */
CGSUInt32 targetLoPSN; /* loword of PSN */
CGSInt32 status; /* operation result */
CGSInt32 _padding[8];
} process;
struct { /* For scroll wheel events */
CGSInt16 deltaAxis1;
CGSInt16 deltaAxis2;
CGSInt16 deltaAxis3;
CGSInt16 reserved1;
CGSInt32 reserved2;
CGSInt32 _padding[9];
} scrollWheel;
struct {
CGSInt32 x; /* absolute x coordinate in tablet space at full tablet resolution */
CGSInt32 y; /* absolute y coordinate in tablet space at full tablet resolution */
CGSInt32 z; /* absolute z coordinate in tablet space at full tablet resolution */
CGSUInt16 buttons; /* one bit per button - bit 0 is first button - 1 = closed */
CGSUInt16 pressure; /* scaled pressure value; MAXPRESSURE=(2^16)-1, MINPRESSURE=0 */
struct {
CGSInt16 x; /* scaled tilt x value; range is -((2^15)-1) to (2^15)-1 (-32767 to 32767) */
CGSInt16 y; /* scaled tilt y value; range is -((2^15)-1) to (2^15)-1 (-32767 to 32767) */
} tilt;
CGSUInt16 rotation; /* Fixed-point representation of device rotation in a 10.6 format */
CGSInt16 tangentialPressure; /* tangential pressure on the device; range same as tilt */
CGSUInt16 deviceID; /* system-assigned unique device ID - matches to deviceID field in proximity event */
CGSInt16 vendor1; /* vendor-defined signed 16-bit integer */
CGSInt16 vendor2; /* vendor-defined signed 16-bit integer */
CGSInt16 vendor3; /* vendor-defined signed 16-bit integer */
CGSInt32 _padding[4];
} tablet;
struct {
CGSUInt16 vendorID; /* vendor-defined ID - typically will be USB vendor ID */
CGSUInt16 tabletID; /* vendor-defined tablet ID - typically will be USB product ID for the tablet */
CGSUInt16 pointerID; /* vendor-defined ID of the specific pointing device */
CGSUInt16 deviceID; /* system-assigned unique device ID - matches to deviceID field in tablet event */
CGSUInt16 systemTabletID; /* system-assigned unique tablet ID */
CGSUInt16 vendorPointerType; /* vendor-defined pointer type */
CGSUInt32 pointerSerialNumber; /* vendor-defined serial number of the specific pointing device */
CGSUInt64 uniqueID; /* vendor-defined unique ID for this pointer */
CGSUInt32 capabilityMask; /* mask representing the capabilities of the device */
CGSUInt8 pointerType; /* type of pointing device - enum to be defined */
CGSUInt8 enterProximity; /* non-zero = entering; zero = leaving */
CGSInt16 reserved1;
CGSInt32 _padding[4];
} proximity;
struct { /* For AppKit-defined, sys-defined, and app-defined events */
CGSInt16 reserved;
CGSInt16 subtype; /* event subtype for compound events */
union {
CGSFloat32 F[11]; /* for use in compound events */
CGSInt32 L[11]; /* for use in compound events */
CGSInt16 S[22]; /* for use in compound events */
CGSInt8 C[44]; /* for use in compound events */
} misc;
} compound;
} CGSEventRecordData;
struct _CGSEventRecord {
CGSEventRecordVersion major;
CGSEventRecordVersion minor;
CGSByteCount length; /* Length of complete event record */
CGSEventType type; /* An event type from above */
CGPoint location; /* Base coordinates (global), from upper-left */
CGPoint windowLocation; /* Coordinates relative to window */
CGSEventRecordTime time; /* nanoseconds since startup */
CGSEventFlag flags; /* key state flags */
CGSWindowID window; /* window number of assigned window */
CGSConnectionID connection; /* connection the event came from */
CGSEventRecordData data; /* type-dependent data: 40 bytes */
};
typedef struct _CGSEventRecord CGSEventRecord;
typedef CGSEventRecord *CGSEventRecordPtr;
typedef void (*CGSNotifyProcPtr)(CGSNotificationType type,
CGSNotificationData data,
CGSByteCount dataLength,
CGSNotificationArg arg);
// Define a type for the 'CGSRegisterNotifyProc' call. Don't reference it explicitly since we don't want link errors if Apple removes this private function.
typedef CGSError (*CGSRegisterNotifyProcType)(CGSNotifyProcPtr proc,
CGSNotificationType type,
CGSNotificationArg arg);
#define kCGSEventNotificationMouseMoved (710 + 5)
#define kCGSEventNotificationLeftMouseDragged (710 + 6)
#define kCGSEventNotificationRightMouseDragged (710 + 7)
#define kCGSEventNotificationNotificationOtherMouseDragged (710 + 27)

View File

@ -1,146 +0,0 @@
#!/usr/bin/perl
open(INPUT_FILE, ">/tmp/input-$$.h") || die "$!";
print INPUT_FILE "#import <OpenGL/gl.h>\n";
close INPUT_FILE;
open(CPP, "cpp /tmp/input-$$.h|") || die "$!";
print "/**** This file is autogenerated. Run GenerateQGL.pl to update it ****/\n\n";
print "#ifdef QGL_LOG_GL_CALLS\n";
print "extern unsigned int QGLLogGLCalls;\n";
print "extern FILE *QGLDebugFile(void);\n";
print "#endif\n\n";
print "extern void QGLCheckError(const char *message);\n";
print "extern unsigned int QGLBeginStarted;\n\n";
print "// This has to be done to avoid infinite recursion between our glGetError wrapper and QGLCheckError()\n";
print "static inline GLenum _glGetError(void) {\n";
print " return glGetError();\n";
print "}\n\n";
@functionNames = ();
while (<CPP>) {
chop;
/^extern/ || next;
s/extern //;
print "// $_\n";
# This approach is necessary to deal with glGetString whos type isn't a single word
($type, $rest) = m/(.+)\s+(gl.*)/;
# print "type='$type'\n";
# print "rest='$rest'\n";
($name, $argString) = ($rest =~ m/(\w+).*\s*\((.*)\)/);
$isVoid = ($type =~ m/void/);
push(@functionNames, $name);
# print "name=$name\n";
# print "argString=$argString\n";
# print "argCount=$#args\n";
# Parse the argument list into two arrays, one of types and one of argument names
if ($argString =~ m/^void$/) {
@args = ();
} else {
@args = split(",", $argString);
}
@argTypes = ();
@argNames = ();
for $arg (@args) {
($argType, $argName) = ($arg =~ m/(.*[ \*])([_a-zA-Z0-9]+)/);
$argType =~ s/^ *//;
$argType =~ s/ *$//;
push(@argTypes, $argType);
push(@argNames, $argName);
# print "argType='$argType'\n";
# print "argName='$argName'\n";
}
print "static inline $type q$name($argString)\n";
print "{\n";
if (! $isVoid) {
print " $type returnValue;\n";
}
print "#if !defined(NDEBUG) && defined(QGL_LOG_GL_CALLS)\n";
print " if (QGLLogGLCalls)\n";
print " fprintf(QGLDebugFile(), \"$name(";
if ($#argTypes >= 0) {
for ($i = 0; $i <= $#argTypes; $i++) {
$argType = $argTypes[$i];
$argName = $argNames[$i];
$_ = $argType;
if (/^GLenum$/ || /^GLuint$/ || /^GLbitfield$/) {
print "$argName=%lu";
} elsif (/^GLsizei$/ || /^GLint$/) {
print "$argName=%ld";
} elsif (/^GLfloat$/ || /^GLdouble$/ || /^GLclampf$/ || /^GLclampd$/) {
print "$argName=%f";
} elsif (/^GLbyte$/) {
print "$argName=%d";
} elsif (/^GLubyte$/) {
print "$argName=%u";
} elsif (/^GLshort$/) {
print "$argName=%d";
} elsif (/^GLushort$/) {
print "$argName=%u";
} elsif (/^GLboolean$/) {
print "$argName=%u";
} elsif (/\*$/) {
# TJW -- Later we should look at the count specified in the function name, look at the basic type and print out an array. Or we could just special case them...
print "$argName=%p";
} else {
print STDERR "Unknown type '$argType'\n";
exit(1);
}
print ", " if ($i != $#argTypes);
}
} else {
print "void";
}
print ")\\n\"";
print ", " if $#argTypes >= 0;
print join(", ", @argNames);
print ");\n";
print "#endif\n";
if (! $isVoid) {
print " returnValue = ";
} else {
print " ";
}
print "$name(" . join(", ", @argNames) . ");\n";
print "#if !defined(NDEBUG) && defined(QGL_CHECK_GL_ERRORS)\n";
if ($name eq "glBegin") {
print " QGLBeginStarted++;\n";
}
if ($name eq "glEnd") {
print " QGLBeginStarted--;\n";
}
print " if (!QGLBeginStarted)\n";
print " QGLCheckError(\"$name\");\n";
print "#endif\n";
if (! $isVoid) {
print " return returnValue;\n";
}
print "}\n\n";
}
print "// Prevent calls to the 'normal' GL functions\n";
for $name (@functionNames) {
print "#define $name CALL_THE_QGL_VERSION_OF_$name\n";
}

View File

@ -1,114 +0,0 @@
{\rtf1\mac\ansicpg10000{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;\red255\green0\blue16;\red255\green0\blue16;}
\paperw14240\paperh14700
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f0\fs24 \cf0 \
\b +set timedemo 1 +demo die.dm3 +set s_initsound 0 +set r_enablerender 0 +set vm_cgame 0 +set vm_game 0\
4865 frames, 154.3 seconds: 31.5 fps\
\
\
+set timedemo 1 +demo die.dm3 +set s_initsound 0 +set r_enablerender 0 +set vm_cgame 2 +set vm_game 2\
4865 frames, 199.8 seconds: 24.4 fps\
\
\
+set timedemo 1 +demo demo001.dm3 +set s_initsound 0 +set r_enablerender 0 +set vm_cgame 0 +set vm_game 0\
1346 frames, 10.1 seconds: 133.0 fps\
\
\
+set timedemo 1 +demo demo001.dm3 +set s_initsound 0 +set r_enablerender 0 +set vm_cgame 2 +set vm_game 2\
1346 frames, 12.8 seconds: 105.4 fps\
\
\
\
Starting point\
\b0 4865 frames, 154.5 seconds: 31.5 fps\
[seconds spent locally, % of parent, % of total, # of samples]\
[133.623469 -- 60130560955, 100.00%, 100.00%, 4866] Root\
[126.853849 -- 57084231997, 94.93%, 94.93%, 4866] CL_Frame\
[125.895845 -- 56653130083, 99.24%, 94.22%, 4918] SCR_UpdateScreen\
[50.532841 -- 22739778533, 40.14%, 37.82%, 524036] RB_SurfaceMesh\
[46.583051 -- 20962372767, 92.18%, 34.86%, 524036] LerpMeshVertexes\
[8.465527 -- 3809487228, 18.17%, 6.34%, 455917] LerpMeshVertexes 1\
\b \cf2 [37.967433 -- 17085344910, 81.50%, 28.41%, 68119] LerpMeshVertexes 2\
\b0 \cf0 [0.32% spent locally]\
[7.82% spent locally]\
[59.86% spent locally]\
[0.76% spent locally]\
[5.07% spent locally]\
\
\b Minor cleanup of local variables\
\b0 [seconds spent locally, % of parent, % of total, # of samples]\
[133.121489 -- 59904670191, 100.00%, 100.00%, 4866] Root\
[126.329343 -- 56848204176, 94.90%, 94.90%, 4866] CL_Frame\
[125.402239 -- 56431007399, 99.27%, 94.20%, 4918] SCR_UpdateScreen\
[50.013076 -- 22505884288, 39.88%, 37.57%, 524036] RB_SurfaceMesh\
[46.085775 -- 20738598809, 92.15%, 34.62%, 524036] LerpMeshVertexes\
[8.427565 -- 3792404277, 18.29%, 6.33%, 455917] LerpMeshVertexes 1\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\b \cf3 [37.517092 -- 16882691281, 81.41%, 28.18%, 68119] LerpMeshVertexes 2\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\b0 \cf0 [0.31% spent locally]\
[7.85% spent locally]\
[60.12% spent locally]\
[0.73% spent locally]\
[5.10% spent locally]\
\
\
\b Split out normalization of LERPed normals (i.e., all the sqrt calls)\
\b0 [seconds spent locally, % of parent, % of total, # of samples]\
[133.110463 -- 59899708244, 100.00%, 100.00%, 4866] Root\
[126.357393 -- 56860826689, 94.93%, 94.93%, 4866] CL_Frame\
[125.364641 -- 56414088645, 99.21%, 94.18%, 4918] SCR_UpdateScreen\
[49.854816 -- 22434667309, 39.77%, 37.45%, 524036] RB_SurfaceMesh\
[45.981802 -- 20691810706, 92.23%, 34.54%, 524036] LerpMeshVertexes\
[8.407983 -- 3783592133, 18.29%, 6.32%, 455917] LerpMeshVertexes 1\
[37.432159 -- 16844471717, 81.41%, 28.12%, 68119] LerpMeshVertexes 2\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\b \cf3 [30.288000 -- 13629599780, 80.91%, 22.75%, 68119] VectorArrayNormalize\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\b0 \cf0 [19.09% spent locally]\
[0.31% spent locally]\
[7.77% spent locally]\
[60.23% spent locally]\
[0.79% spent locally]\
[5.07% spent locally]\
\
\b Rewrote VectorArrayNormalize to use PPC frsqrt instruction (with Newton-Rhapson refinement)\
\b0 4865 frames, 128.7 seconds: 37.8 fps\
[seconds spent locally, % of parent, % of total, # of samples]\
[103.972710 -- 46787719721, 100.00%, 100.00%, 4866] Root\
[97.153160 -- 43718922078, 93.44%, 93.44%, 4866] CL_Frame\
[96.219348 -- 43298706398, 99.04%, 92.54%, 4918] SCR_UpdateScreen\
[20.873944 -- 9393274747, 21.69%, 20.08%, 524036] RB_SurfaceMesh\
[17.053245 -- 7673960266, 81.70%, 16.40%, 524036] LerpMeshVertexes\
[8.356579 -- 3760460537, 49.00%, 8.04%, 455917] LerpMeshVertexes 1\
[8.560159 -- 3852071404, 50.20%, 8.23%, 68119] LerpMeshVertexes 2\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\b \cf3 [1.429376 -- 643219234, 16.70%, 1.37%, 68119] VectorArrayNormalize\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\b0 \cf0 [83.30% spent locally]\
[0.80% spent locally]\
[18.30% spent locally]\
[78.31% spent locally]\
[0.96% spent locally]\
[6.56% spent locally]\
\
\
}

View File

@ -1,40 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#import <AppKit/AppKit.h>
@interface Q3Controller : NSObject
{
IBOutlet NSPanel *bannerPanel;
}
#ifndef DEDICATED
- (IBAction)paste:(id)sender;
- (IBAction)requestTerminate:(id)sender;
- (void) showBanner;
#endif
- (void)quakeMain;
@end

View File

@ -1,435 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#import "Q3Controller.h"
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#include "client.h"
#include "macosx_local.h"
//#include "GameRanger SDK/gameranger.h"
#ifdef OMNI_TIMER
#import "macosx_timers.h"
#endif
#define MAX_ARGC 1024
static qboolean Sys_IsProcessingTerminationRequest = qfalse;
static void Sys_CreatePathToFile(NSString *path, NSDictionary *attributes);
@interface Q3Controller (Private)
- (void)quakeMain;
@end
@implementation Q3Controller
#ifndef DEDICATED
- (void)applicationDidFinishLaunching:(NSNotification *)notification;
{
NS_DURING {
[self quakeMain];
} NS_HANDLER {
Sys_Error("%@", [localException reason]);
} NS_ENDHANDLER;
Sys_Quit();
}
- (void)applicationDidUnhide:(NSNotification *)notification;
{
// Don't reactivate the game if we are asking whether to quit
if (Sys_IsProcessingTerminationRequest)
return;
if (!Sys_Unhide())
// Didn't work -- hide again so we should get another chance to unhide later
[NSApp hide: nil];
}
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
{
int choice;
if (!Sys_IsHidden) {
// We're terminating via -terminate:
return NSTerminateNow;
}
// Avoid reactivating GL when we unhide due to this panel
Sys_IsProcessingTerminationRequest = qtrue;
choice = NSRunAlertPanel(nil, @"Quit without saving?", @"Don't Quit", @"Quit", nil);
Sys_IsProcessingTerminationRequest = qfalse;
if (choice == NSAlertAlternateReturn)
return NSTerminateNow;
// Make sure we get re-hidden
[NSApp hide:nil];
return NSTerminateCancel;
}
// Actions
- (IBAction)paste:(id)sender;
{
int shiftWasDown, insertWasDown;
unsigned int currentTime;
currentTime = Sys_Milliseconds();
// Save the original keyboard state
shiftWasDown = keys[K_SHIFT].down;
insertWasDown = keys[K_INS].down;
// Fake a Shift-Insert keyboard event
keys[K_SHIFT].down = qtrue;
Sys_QueEvent(currentTime, SE_KEY, K_INS, qtrue, 0, NULL);
Sys_QueEvent(currentTime, SE_KEY, K_INS, qfalse, 0, NULL);
// Restore the original keyboard state
keys[K_SHIFT].down = shiftWasDown;
keys[K_INS].down = insertWasDown;
}
extern void CL_Quit_f(void);
- (IBAction)requestTerminate:(id)sender;
{
Com_Quit_f();
// UI_QuitMenu();
}
- (void)showBanner;
{
static BOOL hasShownBanner = NO;
if (!hasShownBanner) {
cvar_t *showBanner;
hasShownBanner = YES;
showBanner = Cvar_Get("cl_showBanner", "1", 0);
if (showBanner->integer != 0) {
NSPanel *splashPanel;
NSImage *bannerImage;
NSRect bannerRect;
NSImageView *bannerImageView;
bannerImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForImageResource:@"banner.jpg"]];
bannerRect = NSMakeRect(0.0, 0.0, [bannerImage size].width, [bannerImage size].height);
splashPanel = [[NSPanel alloc] initWithContentRect:bannerRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
bannerImageView = [[NSImageView alloc] initWithFrame:bannerRect];
[bannerImageView setImage:bannerImage];
[splashPanel setContentView:bannerImageView];
[bannerImageView release];
[splashPanel center];
[splashPanel setHasShadow:YES];
[splashPanel orderFront: nil];
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.5]];
[splashPanel close];
[bannerImage release];
}
}
}
// Services
- (void)connectToServer:(NSPasteboard *)pasteboard userData:(NSString *)data error:(NSString **)error;
{
NSArray *pasteboardTypes;
pasteboardTypes = [pasteboard types];
if ([pasteboardTypes containsObject:NSStringPboardType]) {
NSString *requestedServer;
requestedServer = [pasteboard stringForType:NSStringPboardType];
if (requestedServer) {
Cbuf_AddText(va("connect %s\n", [requestedServer cString]));
return;
}
}
*error = @"Unable to connect to server: could not find string on pasteboard";
}
- (void)performCommand:(NSPasteboard *)pasteboard userData:(NSString *)data error:(NSString **)error;
{
NSArray *pasteboardTypes;
pasteboardTypes = [pasteboard types];
if ([pasteboardTypes containsObject:NSStringPboardType]) {
NSString *requestedCommand;
requestedCommand = [pasteboard stringForType:NSStringPboardType];
if (requestedCommand) {
Cbuf_AddText(va("%s\n", [requestedCommand cString]));
return;
}
}
*error = @"Unable to perform command: could not find string on pasteboard";
}
#endif
- (void)quakeMain;
{
NSAutoreleasePool *pool;
int argc = 0;
const char *argv[MAX_ARGC];
NSProcessInfo *processInfo;
NSArray *arguments;
unsigned int argumentIndex, argumentCount;
NSFileManager *defaultManager;
unsigned int commandLineLength;
NSString *installationPathKey, *installationPath;
char *cmdline;
BOOL foundDirectory;
NSString *appName, *demoAppName, *selectButton;
int count = 0;
pool = [[NSAutoreleasePool alloc] init];
[NSApp setServicesProvider:self];
processInfo = [NSProcessInfo processInfo];
arguments = [processInfo arguments];
argumentCount = [arguments count];
for (argumentIndex = 0; argumentIndex < argumentCount; argumentIndex++) {
NSString *arg;
arg = [arguments objectAtIndex:argumentIndex];
// Don't pass the Process Serial Number command line arg that the Window Server/Finder invokes us with
if ([arg hasPrefix: @"-psn_"])
continue;
argv[argc++] = strdup([arg cString]);
}
// Figure out where the level data is stored.
installationPathKey = @"RetailInstallationPath";
installationPath = [[NSUserDefaults standardUserDefaults] objectForKey:installationPathKey];
if (!installationPath) {
// Default to the directory containing the executable (which is where most users will want to put it
installationPath = [[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent];
}
#if !defined(DEDICATED)
appName = [[[NSBundle mainBundle] infoDictionary] objectForKey: @"CFBundleName"];
#else
// We are hard coding the app name here since the dedicated server is a tool, not a app bundle and does not have access to the Info.plist that the client app does. Suck.
appName = @"Quake3";
#endif
demoAppName = appName;
while (YES) {
NSString *dataPath;
NSOpenPanel *openPanel;
int result;
foundDirectory = NO;
defaultManager = [NSFileManager defaultManager];
//NSLog(@"Candidate installation path = %@", installationPath);
dataPath = [installationPath stringByAppendingPathComponent: @"baseq3"];
if ([defaultManager fileExistsAtPath: dataPath]) {
// Check that the data directory contains at least one .pk3 file. We don't know what it will be named, so don't hard code a name (for example it might be named 'french.pk3' for a French release
NSArray *files;
unsigned int fileIndex;
files = [defaultManager directoryContentsAtPath: dataPath];
fileIndex = [files count];
while (fileIndex--) {
if ([[files objectAtIndex: fileIndex] hasSuffix: @"pk3"]) {
//NSLog(@"Found %@.", [files objectAtIndex: fileIndex]);
foundDirectory = YES;
break;
}
}
}
if (foundDirectory)
break;
#ifdef DEDICATED
break;
#warning TJW: We are hard coding the app name and default domain here since the dedicated server is a tool, not a app bundle and does not have access to the Info.plist that the client app does. Suck.
NSLog(@"Unable to determine installation directory. Please move the executable into the '%@' installation directory or add a '%@' key in the 'Q3DedicatedServer' defaults domain.", appName, installationPathKey, [[NSBundle mainBundle] bundleIdentifier]);
Sys_Quit();
exit(1);
#else
selectButton = @"Select Retail Installation...";
result = NSRunAlertPanel(demoAppName, @"You need to select the installation directory for %@ (not any directory inside of it -- the installation directory itself).", selectButton, @"Quit", nil, appName);
switch (result) {
case NSAlertDefaultReturn:
break;
default:
Sys_Quit();
break;
}
openPanel = [NSOpenPanel openPanel];
[openPanel setAllowsMultipleSelection:NO];
[openPanel setCanChooseDirectories:YES];
[openPanel setCanChooseFiles:NO];
result = [openPanel runModalForDirectory:nil file:nil];
if (result == NSOKButton) {
NSArray *filenames;
filenames = [openPanel filenames];
if ([filenames count] == 1) {
installationPath = [filenames objectAtIndex:0];
[[NSUserDefaults standardUserDefaults] setObject:installationPath forKey:installationPathKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
#endif
}
// Create the application support directory if it doesn't exist already
do {
NSArray *results;
NSString *libraryPath, *homePath, *filePath;
NSDictionary *attributes;
results = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
if (![results count])
break;
libraryPath = [results objectAtIndex: 0];
homePath = [libraryPath stringByAppendingPathComponent: @"Application Support"];
homePath = [homePath stringByAppendingPathComponent: appName];
filePath = [homePath stringByAppendingPathComponent: @"foo"];
attributes = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithUnsignedInt: 0750], NSFilePosixPermissions, nil];
NS_DURING {
Sys_CreatePathToFile(filePath, attributes);
Sys_SetDefaultHomePath([homePath fileSystemRepresentation]);
} NS_HANDLER {
NSLog(@"Exception: %@", localException);
#ifndef DEDICATED
NSRunAlertPanel(nil, @"Unable to create '%@'. Please make sure that you have permission to write to this folder and re-run the game.", @"OK", nil, nil, homePath);
#endif
Sys_Quit();
} NS_ENDHANDLER;
} while(0);
// Provoke the CD scanning code into looking up the CD.
Sys_CheckCD();
// Let the filesystem know where our local install is
Sys_SetDefaultInstallPath([installationPath cString]);
cmdline = NULL;
#if 0
if (GRCheckFileForCmd()) {
GRGetWaitingCmd();
if (GRHasProperty( 'Exec' )) {
NSString *cfgPath, *grCfg;
cfgPath = [[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent];
cfgPath = [cfgPath stringByAppendingPathComponent: [NSString stringWithCString: GRGetPropertyStr( 'Exec' )]];
grCfg = [NSString stringWithContentsOfFile: cfgPath];
cmdline = malloc(strlen([grCfg cString])+1);
[grCfg getCString: cmdline];
}
}
#endif
if (!cmdline) {
// merge the command line, this is kinda silly
for (commandLineLength = 1, argumentIndex = 1; argumentIndex < argc; argumentIndex++)
commandLineLength += strlen(argv[argumentIndex]) + 1;
cmdline = malloc(commandLineLength);
*cmdline = '\0';
for (argumentIndex = 1; argumentIndex < argc; argumentIndex++) {
if (argumentIndex > 1)
strcat(cmdline, " ");
strcat(cmdline, argv[argumentIndex]);
}
}
Com_Printf("command line: %s\n", cmdline);
Com_Init(cmdline);
#ifndef DEDICATED
[NSApp activateIgnoringOtherApps:YES];
#endif
while (1) {
Com_Frame();
if ((count & 15)==0) {
// We should think about doing this less frequently than every frame
[pool release];
pool = [[NSAutoreleasePool alloc] init];
}
}
[pool release];
}
@end
// Creates any directories needed to be able to create a file at the specified path. Raises an exception on failure.
static void Sys_CreatePathToFile(NSString *path, NSDictionary *attributes)
{
NSArray *pathComponents;
unsigned int dirIndex, dirCount;
unsigned int startingIndex;
NSFileManager *manager;
manager = [NSFileManager defaultManager];
pathComponents = [path pathComponents];
dirCount = [pathComponents count] - 1;
startingIndex = 0;
for (dirIndex = startingIndex; dirIndex < dirCount; dirIndex++) {
NSString *partialPath;
BOOL fileExists;
partialPath = [NSString pathWithComponents:[pathComponents subarrayWithRange:NSMakeRange(0, dirIndex + 1)]];
// Don't use the 'fileExistsAtPath:isDirectory:' version since it doesn't traverse symlinks
fileExists = [manager fileExistsAtPath:partialPath];
if (!fileExists) {
if (![manager createDirectoryAtPath:partialPath attributes:attributes]) {
[NSException raise:NSGenericException format:@"Unable to create a directory at path: %@", partialPath];
}
} else {
NSDictionary *attributes;
attributes = [manager fileAttributesAtPath:partialPath traverseLink:YES];
if (![[attributes objectForKey:NSFileType] isEqualToString: NSFileTypeDirectory]) {
[NSException raise:NSGenericException format:@"Unable to write to path \"%@\" because \"%@\" is not a directory",
path, partialPath];
}
}
}
}
#ifdef DEDICATED
void S_ClearSoundBuffer( void ) {
}
#endif

Binary file not shown.

View File

@ -1,18 +0,0 @@
{
IBClasses = (
{
ACTIONS = {showHelp = id; };
CLASS = FirstResponder;
LANGUAGE = ObjC;
SUPERCLASS = NSObject;
},
{
ACTIONS = {paste = id; requestTerminate = id; };
CLASS = Q3Controller;
LANGUAGE = ObjC;
OUTLETS = {bannerPanel = id; };
SUPERCLASS = NSObject;
}
);
IBVersion = 1;
}

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
<key>IBEditorPositions</key>
<dict>
<key>29</key>
<string>69 252 121 44 0 0 1152 746 </string>
</dict>
<key>IBFramework Version</key>
<string>248.0</string>
<key>IBOpenObjects</key>
<array>
<integer>29</integer>
</array>
<key>IBSystem Version</key>
<string>5V21</string>
</dict>
</plist>

Binary file not shown.

View File

@ -1,563 +0,0 @@
// !$*UTF8*$!
{
00F5ED38FEBA95B7C697A12F = {
activeExec = 0;
};
00F5ED90FEBA9615C697A12F = {
activeExec = 0;
};
016EAE0300B4BDD1C697A10E = {
activeExec = 0;
};
0170304B00B4885DC697A10E = {
activeExec = 0;
executables = (
1895FF35065E291B00F8B3F4,
);
};
0170311C00B49352C697A10E = {
activeExec = 0;
};
043627B100868916C697A10E = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1586, 6033}}";
sepNavSelRange = "{136, 0}";
sepNavVisRect = "{{0, 0}, {711, 428}}";
};
};
0654BA41FE8ECEE0C697A12F = {
activeBuildStyle = 07F3F50BFFE98E8EC697A10E;
activeExecutable = 1895FF30065E291B00F8B3F4;
activeTarget = 00F5ED90FEBA9615C697A12F;
codeSenseManager = 1895FF4C065E294000F8B3F4;
executables = (
1895FF2F065E291B00F8B3F4,
1895FF30065E291B00F8B3F4,
1895FF31065E291B00F8B3F4,
1895FF35065E291B00F8B3F4,
);
perUserDictionary = {
PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID;
PBXFileTableDataSourceColumnWidthsKey = (
22,
843.7974,
);
PBXFileTableDataSourceColumnsKey = (
PBXExecutablesDataSource_ActiveFlagID,
PBXExecutablesDataSource_NameID,
);
};
PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
550,
20,
99,
43,
43,
20,
);
PBXFileTableDataSourceColumnsKey = (
PBXFileDataSource_FiletypeID,
PBXFileDataSource_Filename_ColumnID,
PBXFileDataSource_Built_ColumnID,
PBXFileDataSource_ObjectSize_ColumnID,
PBXFileDataSource_Errors_ColumnID,
PBXFileDataSource_Warnings_ColumnID,
PBXFileDataSource_Target_ColumnID,
);
};
PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
467,
101,
20,
101,
43,
43,
);
PBXFileTableDataSourceColumnsKey = (
PBXFileDataSource_FiletypeID,
PBXFileDataSource_Filename_ColumnID,
PBXTargetDataSource_PrimaryAttribute,
PBXFileDataSource_Built_ColumnID,
PBXFileDataSource_ObjectSize_ColumnID,
PBXFileDataSource_Errors_ColumnID,
PBXFileDataSource_Warnings_ColumnID,
);
};
PBXPerProjectTemplateStateSaveDate = 106915007;
PBXPrepackagedSmartGroups_v2 = (
{
PBXTransientLocationAtTop = bottom;
absolutePathToBundle = "";
activationKey = OldTargetSmartGroup;
clz = PBXTargetSmartGroup;
description = "Displays all targets of the project.";
globalID = 1C37FABC04509CD000000102;
name = Targets;
preferences = {
image = Targets;
};
},
{
PBXTransientLocationAtTop = bottom;
absolutePathToBundle = "";
clz = PBXTargetSmartGroup2;
description = "Displays all targets of the project as well as nested build phases.";
globalID = 1C37FBAC04509CD000000102;
name = Targets;
preferences = {
image = Targets;
};
},
{
PBXTransientLocationAtTop = bottom;
absolutePathToBundle = "";
clz = PBXExecutablesSmartGroup;
description = "Displays all executables of the project.";
globalID = 1C37FAAC04509CD000000102;
name = Executables;
preferences = {
image = Executable;
};
},
{
" PBXTransientLocationAtTop " = bottom;
absolutePathToBundle = "";
clz = PBXErrorsWarningsSmartGroup;
description = "Displays files with errors or warnings.";
globalID = 1C08E77C0454961000C914BD;
name = "Errors and Warnings";
preferences = {
fnmatch = "";
image = WarningsErrors;
recursive = 1;
regex = "";
root = "<PROJECT>";
};
},
{
PBXTransientLocationAtTop = bottom;
absolutePathToBundle = "";
clz = PBXFilenameSmartGroup;
description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter.";
globalID = 1CC0EA4004350EF90044410B;
name = "Implementation Files";
preferences = {
canSave = 1;
fnmatch = "";
image = SmartFolder;
isLeaf = 0;
recursive = 1;
regex = "?*\\.[mcMC]";
root = "<PROJECT>";
};
},
{
PBXTransientLocationAtTop = bottom;
absolutePathToBundle = "";
clz = PBXFilenameSmartGroup;
description = "This group displays Interface Builder NIB Files.";
globalID = 1CC0EA4004350EF90041110B;
name = "NIB Files";
preferences = {
canSave = 1;
fnmatch = "*.nib";
image = SmartFolder;
isLeaf = 0;
recursive = 1;
regex = "";
root = "<PROJECT>";
};
},
{
PBXTransientLocationAtTop = no;
absolutePathToBundle = "";
clz = PBXFindSmartGroup;
description = "Displays Find Results.";
globalID = 1C37FABC05509CD000000102;
name = "Find Results";
preferences = {
image = spyglass;
};
},
{
PBXTransientLocationAtTop = no;
absolutePathToBundle = "";
clz = PBXBookmarksSmartGroup;
description = "Displays Project Bookmarks.";
globalID = 1C37FABC05539CD112110102;
name = Bookmarks;
preferences = {
image = Bookmarks;
};
},
{
PBXTransientLocationAtTop = bottom;
absolutePathToBundle = "";
clz = XCSCMSmartGroup;
description = "Displays files with interesting SCM status.";
globalID = E2644B35053B69B200211256;
name = SCM;
preferences = {
image = PBXRepository;
isLeaf = 0;
};
},
{
PBXTransientLocationAtTop = bottom;
absolutePathToBundle = "";
clz = PBXSymbolsSmartGroup;
description = "Displays all symbols for the project.";
globalID = 1C37FABC04509CD000100104;
name = "Project Symbols";
preferences = {
image = ProjectSymbols;
isLeaf = 1;
};
},
{
PBXTransientLocationAtTop = bottom;
absolutePathToBundle = "";
clz = PBXFilenameSmartGroup;
description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter.";
globalID = PBXTemplateMarker;
name = "Simple Filter SmartGroup";
preferences = {
canSave = 1;
fnmatch = "*.nib";
image = SmartFolder;
isLeaf = 0;
recursive = 1;
regex = "";
root = "<PROJECT>";
};
},
{
PBXTransientLocationAtTop = bottom;
absolutePathToBundle = "";
clz = PBXFilenameSmartGroup;
description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter.";
globalID = PBXTemplateMarker;
name = "Simple Regular Expression SmartGroup";
preferences = {
canSave = 1;
fnmatch = "";
image = SmartFolder;
isLeaf = 0;
recursive = 1;
regex = "?*\\.[mcMC]";
root = "<PROJECT>";
};
},
);
PBXWorkspaceContents = (
{
PBXProjectWorkspaceModule_StateKey_Rev39 = {
PBXProjectWorkspaceModule_DataSourceSelectionKey_Rev6 = {
BoundsStr = "{{0, 0}, {823, 735}}";
Rows = (
);
VisibleRectStr = "{{0, 0}, {823, 735}}";
};
PBXProjectWorkspaceModule_EditorOpen = false;
PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = {
PBXSplitModuleInNavigatorKey = {
SplitCount = 1;
};
};
PBXProjectWorkspaceModule_GeometryKey_Rev15 = {
PBXProjectWorkspaceModule_SGTM_Geometry = {
_collapsingFrameDimension = 0;
_indexOfCollapsedView = 0;
_percentageOfCollapsedView = 0;
sizes = (
"{{0, 0}, {210, 752}}",
"{{210, 0}, {838, 752}}",
);
};
};
PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {838, 752}}";
PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 0}, {750, 480}}";
PBXProjectWorkspaceModule_OldSuperviewFrame = "{{210, 0}, {838, 752}}";
PBXProjectWorkspaceModule_SGTM = {
PBXBottomSmartGroupGIDs = (
1C37FBAC04509CD000000102,
1C37FAAC04509CD000000102,
1C08E77C0454961000C914BD,
1CC0EA4004350EF90044410B,
1CC0EA4004350EF90041110B,
1C37FABC05509CD000000102,
1C37FABC05539CD112110102,
E2644B35053B69B200211256,
1C37FABC04509CD000100104,
);
PBXSmartGroupTreeModuleColumnData = {
PBXSmartGroupTreeModuleColumnWidthsKey = (
193,
);
PBXSmartGroupTreeModuleColumnsKey_v4 = (
MainColumn,
);
};
PBXSmartGroupTreeModuleOutlineStateKey_v7 = {
PBXSmartGroupTreeModuleOutlineStateExpansionKey = (
1C37FBAC04509CD000000102,
18A3D348065F659F006A719A,
18A3D35B065F6655006A719A,
);
PBXSmartGroupTreeModuleOutlineStateSelectionKey = (
(
2,
1,
),
);
PBXSmartGroupTreeModuleOutlineStateVisibleRectKey = "{{0, 0}, {193, 734}}";
};
PBXTopSmartGroupGIDs = (
);
};
};
},
);
"PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXBuildResultsModule" = {
};
"PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXCVSModule" = {
};
"PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugCLIModule" = {
};
"PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXNavigatorGroup" = {
PBXSplitModuleInNavigatorKey = {
SplitCount = 1;
};
};
"PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXProjectWorkspaceModule" = {
PBXProjectWorkspaceModule_StateKey_Rev39 = {
PBXProjectWorkspaceModule_DataSourceSelectionKey_Rev6 = {
BoundsStr = "{{0, 0}, {851, 4290}}";
Rows = (
0,
);
VisibleRectStr = "{{0, 0}, {851, 735}}";
};
PBXProjectWorkspaceModule_EditorOpen = false;
PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = {
PBXSplitModuleInNavigatorKey = {
SplitCount = 1;
};
};
PBXProjectWorkspaceModule_GeometryKey_Rev15 = {
PBXProjectWorkspaceModule_SGTM_Geometry = {
_collapsingFrameDimension = 0;
_indexOfCollapsedView = 0;
_percentageOfCollapsedView = 0;
sizes = (
"{{0, 0}, {182, 752}}",
"{{182, 0}, {866, 752}}",
);
};
};
PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {866, 752}}";
PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 0}, {750, 480}}";
PBXProjectWorkspaceModule_OldSuperviewFrame = "{{182, 0}, {866, 752}}";
PBXProjectWorkspaceModule_SGTM = {
PBXBottomSmartGroupGIDs = (
1C37FBAC04509CD000000102,
1C37FAAC04509CD000000102,
1C08E77C0454961000C914BD,
1CC0EA4004350EF90044410B,
1CC0EA4004350EF90041110B,
1C37FABC05509CD000000102,
1C37FABC05539CD112110102,
E2644B35053B69B200211256,
1C37FABC04509CD000100104,
);
PBXSmartGroupTreeModuleColumnData = {
PBXSmartGroupTreeModuleColumnWidthsKey = (
165,
);
PBXSmartGroupTreeModuleColumnsKey_v4 = (
MainColumn,
);
};
PBXSmartGroupTreeModuleOutlineStateKey_v7 = {
PBXSmartGroupTreeModuleOutlineStateExpansionKey = (
1C37FBAC04509CD000000102,
18A3D340065F651C006A719A,
18A3D341065F651D006A719A,
);
PBXSmartGroupTreeModuleOutlineStateSelectionKey = (
(
1,
),
);
PBXSmartGroupTreeModuleOutlineStateVisibleRectKey = "{{0, 0}, {165, 734}}";
};
PBXTopSmartGroupGIDs = (
);
};
};
};
PBXWorkspaceGeometries = (
{
Frame = "{{0, 0}, {1048, 752}}";
PBXProjectWorkspaceModule_GeometryKey_Rev15 = {
};
RubberWindowFrame = "17 182 1048 794 0 0 1680 1028 ";
},
);
"PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXBuildResultsModule" = {
Frame = "{{0, 0}, {755, 578}}";
PBXModuleWindowStatusBarHidden = YES;
RubberWindowFrame = "612 317 755 599 0 0 1680 1028 ";
};
"PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXCVSModule" = {
Frame = "{{0, 0}, {482, 276}}";
RubberWindowFrame = "590 449 482 318 0 0 1680 1028 ";
};
"PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugCLIModule" = {
Frame = "{{0, 0}, {400, 201}}";
PBXModuleWindowStatusBarHidden = YES;
RubberWindowFrame = "50 1000 400 222 0 0 1680 1028 ";
};
"PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXNavigatorGroup" = {
Frame = "{{0, 0}, {750, 460}}";
RubberWindowFrame = "428 357 750 502 0 0 1680 1028 ";
};
"PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXProjectWorkspaceModule" = {
Frame = "{{0, 0}, {1048, 752}}";
PBXProjectWorkspaceModule_GeometryKey_Rev15 = {
PBXProjectWorkspaceModule_BuildResultsWindowVisible = true;
};
RubberWindowFrame = "17 182 1048 794 0 0 1680 1028 ";
};
PBXWorkspaceStateSaveDate = 106915007;
};
sourceControlManager = 1895FF4B065E294000F8B3F4;
userBuildSettings = {
};
};
0654BA5CFE8ECEE0C697A12F = {
activeExec = 0;
executables = (
1895FF2F065E291B00F8B3F4,
);
};
1895FF2F065E291B00F8B3F4 = {
activeArgIndex = 2147483647;
activeArgIndices = (
);
argumentStrings = (
);
configStateDict = {
};
debuggerPlugin = GDBDebugging;
dylibVariantSuffix = "";
enableDebugStr = 1;
environmentEntries = (
);
isa = PBXExecutable;
name = "Quake3 (Application)";
shlibInfoDictList = (
);
sourceDirectories = (
);
};
1895FF30065E291B00F8B3F4 = {
activeArgIndex = 2147483647;
activeArgIndices = (
);
argumentStrings = (
);
configStateDict = {
};
debuggerPlugin = GDBDebugging;
enableDebugStr = 1;
environmentEntries = (
);
isa = PBXExecutable;
name = "Dedicated Server G4";
shlibInfoDictList = (
);
sourceDirectories = (
);
};
1895FF31065E291B00F8B3F4 = {
activeArgIndex = 2147483647;
activeArgIndices = (
);
argumentStrings = (
);
configStateDict = {
};
debuggerPlugin = GDBDebugging;
enableDebugStr = 1;
environmentEntries = (
);
isa = PBXExecutable;
name = "Quake3 G4 (Application)";
shlibInfoDictList = (
);
sourceDirectories = (
);
};
1895FF35065E291B00F8B3F4 = {
activeArgIndex = 2147483647;
activeArgIndices = (
);
argumentStrings = (
);
configStateDict = {
};
debuggerPlugin = GDBDebugging;
enableDebugStr = 1;
environmentEntries = (
);
isa = PBXExecutable;
name = "Dedicated Server";
shlibInfoDictList = (
);
sourceDirectories = (
);
};
1895FF4B065E294000F8B3F4 = {
isa = PBXSourceControlManager;
scmConfiguration = {
};
scmType = scm.cvs;
};
1895FF4C065E294000F8B3F4 = {
indexTemplatePath = "";
isa = PBXCodeSenseManager;
usesDefaults = 1;
wantsCodeCompletion = 1;
wantsCodeCompletionAutoPopup = 0;
wantsCodeCompletionAutoSuggestions = 0;
wantsCodeCompletionCaseSensitivity = 1;
wantsCodeCompletionOnlyMatchingItems = 1;
wantsCodeCompletionParametersIncluded = 1;
wantsCodeCompletionPlaceholdersInserted = 1;
wantsCodeCompletionTabCompletes = 1;
wantsIndex = 1;
};
4FF0904804896C0E00030DA8 = {
activeExec = 0;
executables = (
1895FF31065E291B00F8B3F4,
);
};
4FF0912704896C1600030DA8 = {
activeExec = 0;
executables = (
1895FF30065E291B00F8B3F4,
);
};
}

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +0,0 @@
#!/bin/zsh -x
/Local/Public/bungi/BuildOutput/Quake3.app/Contents/MacOS/Quake3 \
+set sv_pure 0 \
+set g_syncronousClients 1 \
+map q3dm6 \
+record foo

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

View File

@ -1,196 +0,0 @@
item team_redobelisk has modelindex 0item team_blueobelisk has modelindex 0item team_neutralobelisk has modelindex 0item item_botroam has modelindex 0entity worldspawn unknown item
entity target_delay unknown item
entity light unknown item
entity target_delay unknown item
entity target_speaker unknown item
entity trigger_multiple unknown item
entity target_speaker unknown item
entity trigger_multiple unknown item
entity target_speaker unknown item
entity trigger_multiple unknown item
entity target_speaker unknown item
entity trigger_multiple unknown item
entity target_speaker unknown item
entity trigger_multiple unknown item
entity target_speaker unknown item
entity trigger_multiple unknown item
entity misc_model unknown item
entity light unknown item
entity light unknown item
entity target_speaker unknown item
entity target_speaker unknown item
entity func_timer unknown item
entity target_speaker unknown item
entity target_speaker unknown item
entity target_position unknown item
entity info_player_intermission unknown item
entity target_speaker unknown item
entity func_timer unknown item
entity target_speaker unknown item
entity misc_model unknown item
entity light unknown item
entity misc_teleporter_dest unknown item
entity target_position unknown item
entity misc_portal_camera unknown item
entity light unknown item
entity light unknown item
entity target_position unknown item
entity light unknown item
entity info_player_deathmatch unknown item
entity light unknown item
entity light unknown item
entity info_null unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity target_position unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity info_player_deathmatch unknown item
entity info_player_deathmatch unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity misc_model unknown item
entity light unknown item
entity light unknown item
entity misc_model unknown item
entity info_player_deathmatch unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity trigger_multiple unknown item
entity func_timer unknown item
entity target_speaker unknown item
entity trigger_multiple unknown item
entity func_timer unknown item
entity target_speaker unknown item
entity target_speaker unknown item
entity trigger_teleport unknown item
entity misc_portal_surface unknown item
entity misc_portal_surface unknown item
entity info_player_deathmatch unknown item
entity misc_model unknown item
entity light unknown item
entity func_rotating unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity target_position unknown item
entity light unknown item
entity light unknown item
entity target_position unknown item
entity light unknown item
entity light unknown item
entity func_rotating unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity light unknown item
entity misc_model unknown item
entity misc_model unknown item
entity func_timer unknown item
entity target_speaker unknown item
entity target_speaker unknown item
entity func_timer unknown item
entity target_speaker unknown item
entity func_timer unknown item
entity target_speaker unknown item
entity func_door unknown item
entity func_door unknown item
entity light unknown item
entity light unknown item
entity misc_model unknown item
entity light unknown item
bots/crash_c.cskill 1073741824
{
0 Crash
1 female
2 0.366667
3 bots/crash_w.c
4 0.366667
5 180
6 4.166667
7 0.366667
8 0.366667
9 0.450000
10 0.450000
11 0.450000
12 0.450000
13 0.450000
14 0.450000
15 0.450000
16 0.366667
17 0.450000
18 0.450000
19 0.450000
20 0.450000
21 bots/crash_t.c
22 crash
23 400
24 0.400000
25 1.000000
26 1.000000
27 1.000000
28 1.000000
29 1.000000
30 1.000000
31 1.000000
32 1.000000
33 1.000000
34 1.000000
35 1.000000
36 0.000000
37 0.000000
38 0.000000
39 0.000000
40 bots/crash_i.c
41 0.233333
42 0.233333
43 0.233333
44 0.233333
45 0.000000
46 0.233333
47 0.333333
48 1.000000
}
item info 7 "weapon_gauntlet" has no fuzzy weight
item info 16 "weapon_grapplinghook" has no fuzzy weight
item info 49 "team_redobelisk" has no fuzzy weight
item info 50 "team_blueobelisk" has no fuzzy weight
item info 51 "team_neutralobelisk" has no fuzzy weight

View File

@ -1,33 +0,0 @@
#if 0 // not used anymore
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include <unistd.h>
#include <string.h>
void Com_Memcpy (void* dest, const void* src, const size_t count) {
memcpy(dest, src, count);
}
void Com_Memset (void* dest, const int val, const size_t count) {
memset(dest, val, count);
}
#endif

View File

@ -1,38 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "tr_local.h"
#include "macosx_local.h"
@class NSDictionary;
extern NSDictionary *Sys_GetMatchingDisplayMode(qboolean allowStretchedModes);
extern void Sys_StoreGammaTables();
extern void Sys_GetGammaTable(glwgamma_t *table);
extern void Sys_SetScreenFade(glwgamma_t *table, float fraction);
extern void Sys_FadeScreens();
extern void Sys_FadeScreen(CGDirectDisplayID display);
extern void Sys_UnfadeScreens();
extern void Sys_UnfadeScreen(CGDirectDisplayID display, glwgamma_t *table);
extern void Sys_ReleaseAllDisplays();

View File

@ -1,369 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#import "macosx_display.h"
#include "tr_local.h"
#import "macosx_local.h"
#import <Foundation/Foundation.h>
#import <IOKit/graphics/IOGraphicsTypes.h> // for interpreting the kCGDisplayIOFlags element of the display mode
NSDictionary *Sys_GetMatchingDisplayMode(qboolean allowStretchedModes)
{
NSArray *displayModes;
NSDictionary *mode;
unsigned int modeIndex, modeCount, bestModeIndex;
int verbose;
cvar_t *cMinFreq, *cMaxFreq;
int minFreq, maxFreq;
unsigned int colorDepth;
verbose = r_verbose->integer;
colorDepth = r_colorbits->integer;
if (colorDepth < 16 || !r_fullscreen->integer)
colorDepth = [[glw_state.desktopMode objectForKey: (id)kCGDisplayBitsPerPixel] intValue];
cMinFreq = ri.Cvar_Get("r_minDisplayRefresh", "0", CVAR_ARCHIVE);
cMaxFreq = ri.Cvar_Get("r_maxDisplayRefresh", "0", CVAR_ARCHIVE);
if (cMinFreq && cMaxFreq && cMinFreq->integer && cMaxFreq->integer &&
cMinFreq->integer > cMaxFreq->integer) {
ri.Error(ERR_FATAL, "r_minDisplayRefresh must be less than or equal to r_maxDisplayRefresh");
}
minFreq = cMinFreq ? cMinFreq->integer : 0;
maxFreq = cMaxFreq ? cMaxFreq->integer : 0;
displayModes = (NSArray *)CGDisplayAvailableModes(glw_state.display);
if (!displayModes) {
ri.Error(ERR_FATAL, "CGDisplayAvailableModes returned NULL -- 0x%0x is an invalid display", glw_state.display);
}
modeCount = [displayModes count];
if (verbose) {
ri.Printf(PRINT_ALL, "%d modes avaliable\n", modeCount);
ri.Printf(PRINT_ALL, "Current mode is %s\n", [[(id)CGDisplayCurrentMode(glw_state.display) description] cString]);
}
// Default to the current desktop mode
bestModeIndex = 0xFFFFFFFF;
for ( modeIndex = 0; modeIndex < modeCount; ++modeIndex ) {
id object;
int refresh;
mode = [displayModes objectAtIndex: modeIndex];
if (verbose) {
ri.Printf(PRINT_ALL, " mode %d -- %s\n", modeIndex, [[mode description] cString]);
}
// Make sure we get the right size
object = [mode objectForKey: (id)kCGDisplayWidth];
if ([[mode objectForKey: (id)kCGDisplayWidth] intValue] != glConfig.vidWidth ||
[[mode objectForKey: (id)kCGDisplayHeight] intValue] != glConfig.vidHeight) {
if (verbose)
ri.Printf(PRINT_ALL, " -- bad size\n");
continue;
}
if (!allowStretchedModes) {
if ([[mode objectForKey: (id)kCGDisplayIOFlags] intValue] & kDisplayModeStretchedFlag) {
if (verbose)
ri.Printf(PRINT_ALL, " -- stretched modes disallowed\n");
continue;
}
}
// Make sure that our frequency restrictions are observed
refresh = [[mode objectForKey: (id)kCGDisplayRefreshRate] intValue];
if (minFreq && refresh < minFreq) {
if (verbose)
ri.Printf(PRINT_ALL, " -- refresh too low\n");
continue;
}
if (maxFreq && refresh > maxFreq) {
if (verbose)
ri.Printf(PRINT_ALL, " -- refresh too high\n");
continue;
}
if ([[mode objectForKey: (id)kCGDisplayBitsPerPixel] intValue] != colorDepth) {
if (verbose)
ri.Printf(PRINT_ALL, " -- bad depth\n");
continue;
}
bestModeIndex = modeIndex;
if (verbose)
ri.Printf(PRINT_ALL, " -- OK\n", bestModeIndex);
}
if (verbose)
ri.Printf(PRINT_ALL, " bestModeIndex = %d\n", bestModeIndex);
if (bestModeIndex == 0xFFFFFFFF) {
ri.Printf(PRINT_ALL, "No suitable display mode available.\n");
return nil;
}
return [displayModes objectAtIndex: bestModeIndex];
}
#define MAX_DISPLAYS 128
void Sys_GetGammaTable(glwgamma_t *table)
{
CGTableCount tableSize = 512;
CGDisplayErr err;
table->tableSize = tableSize;
if (table->red)
free(table->red);
table->red = malloc(tableSize * sizeof(*table->red));
if (table->green)
free(table->green);
table->green = malloc(tableSize * sizeof(*table->green));
if (table->blue)
free(table->blue);
table->blue = malloc(tableSize * sizeof(*table->blue));
// TJW: We _could_ loop here if we get back the same size as our table, increasing the table size.
err = CGGetDisplayTransferByTable(table->display, tableSize, table->red, table->green, table->blue,
&table->tableSize);
if (err != CGDisplayNoErr) {
Com_Printf("GLimp_Init: CGGetDisplayTransferByTable returned %d.\n", err);
table->tableSize = 0;
}
}
void Sys_SetGammaTable(glwgamma_t *table)
{
}
void Sys_StoreGammaTables()
{
// Store the original gamma for all monitors so that we can fade and unfade them all
CGDirectDisplayID displays[MAX_DISPLAYS];
CGDisplayCount displayIndex;
CGDisplayErr err;
err = CGGetActiveDisplayList(MAX_DISPLAYS, displays, &glw_state.displayCount);
if (err != CGDisplayNoErr)
Sys_Error("Cannot get display list -- CGGetActiveDisplayList returned %d.\n", err);
glw_state.originalDisplayGammaTables = calloc(glw_state.displayCount, sizeof(*glw_state.originalDisplayGammaTables));
for (displayIndex = 0; displayIndex < glw_state.displayCount; displayIndex++) {
glwgamma_t *table;
table = &glw_state.originalDisplayGammaTables[displayIndex];
table->display = displays[displayIndex];
Sys_GetGammaTable(table);
}
}
// This isn't a mathematically correct fade, but we don't care that much.
void Sys_SetScreenFade(glwgamma_t *table, float fraction)
{
CGTableCount tableSize;
CGGammaValue *red, *blue, *green;
CGTableCount gammaIndex;
if (!glConfig.deviceSupportsGamma)
return;
if (!(tableSize = table->tableSize))
// we couldn't get the table for this display for some reason
return;
// Com_Printf("0x%08x %f\n", table->display, fraction);
red = glw_state.tempTable.red;
green = glw_state.tempTable.green;
blue = glw_state.tempTable.blue;
if (glw_state.tempTable.tableSize < tableSize) {
glw_state.tempTable.tableSize = tableSize;
red = realloc(red, sizeof(*red) * tableSize);
green = realloc(green, sizeof(*green) * tableSize);
blue = realloc(blue, sizeof(*blue) * tableSize);
glw_state.tempTable.red = red;
glw_state.tempTable.green = green;
glw_state.tempTable.blue = blue;
}
for (gammaIndex = 0; gammaIndex < table->tableSize; gammaIndex++) {
red[gammaIndex] = table->red[gammaIndex] * fraction;
blue[gammaIndex] = table->blue[gammaIndex] * fraction;
green[gammaIndex] = table->green[gammaIndex] * fraction;
}
CGSetDisplayTransferByTable(table->display, table->tableSize, red, green, blue);
}
// Fades all the active displays at the same time.
#define FADE_DURATION 0.5
void Sys_FadeScreens()
{
CGDisplayCount displayIndex;
glwgamma_t *table;
NSTimeInterval start, current;
float time;
if (!glConfig.deviceSupportsGamma)
return;
Com_Printf("Fading all displays\n");
start = [NSDate timeIntervalSinceReferenceDate];
time = 0.0;
while (time != FADE_DURATION) {
current = [NSDate timeIntervalSinceReferenceDate];
time = current - start;
if (time > FADE_DURATION)
time = FADE_DURATION;
for (displayIndex = 0; displayIndex < glw_state.displayCount; displayIndex++) {
table = &glw_state.originalDisplayGammaTables[displayIndex];
Sys_SetScreenFade(table, 1.0 - time / FADE_DURATION);
}
}
}
void Sys_FadeScreen(CGDirectDisplayID display)
{
CGDisplayCount displayIndex;
glwgamma_t *table;
if (!glConfig.deviceSupportsGamma)
return;
Com_Printf("Fading display 0x%08x\n", display);
for (displayIndex = 0; displayIndex < glw_state.displayCount; displayIndex++) {
if (display == glw_state.originalDisplayGammaTables[displayIndex].display) {
NSTimeInterval start, current;
float time;
start = [NSDate timeIntervalSinceReferenceDate];
time = 0.0;
table = &glw_state.originalDisplayGammaTables[displayIndex];
while (time != FADE_DURATION) {
current = [NSDate timeIntervalSinceReferenceDate];
time = current - start;
if (time > FADE_DURATION)
time = FADE_DURATION;
Sys_SetScreenFade(table, 1.0 - time / FADE_DURATION);
}
return;
}
}
Com_Printf("Unable to find display to fade it\n");
}
void Sys_UnfadeScreens()
{
CGDisplayCount displayIndex;
glwgamma_t *table;
NSTimeInterval start, current;
float time;
if (!glConfig.deviceSupportsGamma)
return;
Com_Printf("Unfading all displays\n");
start = [NSDate timeIntervalSinceReferenceDate];
time = 0.0;
while (time != FADE_DURATION) {
current = [NSDate timeIntervalSinceReferenceDate];
time = current - start;
if (time > FADE_DURATION)
time = FADE_DURATION;
for (displayIndex = 0; displayIndex < glw_state.displayCount; displayIndex++) {
table = &glw_state.originalDisplayGammaTables[displayIndex];
Sys_SetScreenFade(table, time / FADE_DURATION);
}
}
}
void Sys_UnfadeScreen(CGDirectDisplayID display, glwgamma_t *table)
{
CGDisplayCount displayIndex;
if (!glConfig.deviceSupportsGamma)
return;
Com_Printf("Unfading display 0x%08x\n", display);
if (table) {
CGTableCount i;
Com_Printf("Given table:\n");
for (i = 0; i < table->tableSize; i++) {
Com_Printf(" %f %f %f\n", table->red[i], table->blue[i], table->green[i]);
}
}
// Search for the original gamma table for the display
if (!table) {
for (displayIndex = 0; displayIndex < glw_state.displayCount; displayIndex++) {
if (display == glw_state.originalDisplayGammaTables[displayIndex].display) {
table = &glw_state.originalDisplayGammaTables[displayIndex];
break;
}
}
}
if (table) {
NSTimeInterval start, current;
float time;
start = [NSDate timeIntervalSinceReferenceDate];
time = 0.0;
while (time != FADE_DURATION) {
current = [NSDate timeIntervalSinceReferenceDate];
time = current - start;
if (time > FADE_DURATION)
time = FADE_DURATION;
Sys_SetScreenFade(table, time / FADE_DURATION);
}
return;
}
Com_Printf("Unable to find display to unfade it\n");
}

View File

@ -1,37 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#ifndef GL_EXT_abgr
#include <OpenGL/glext.h>
#endif
// This can be defined to use the CGLMacro.h support which avoids looking up
// the current context.
//#define USE_CGLMACROS
#ifdef USE_CGLMACROS
#include "macosx_local.h"
#define cgl_ctx glw_state._cgl_ctx
#include <OpenGL/CGLMacro.h>
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,176 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#import "macosx_glimp.h"
#include "tr_local.h"
#import "macosx_local.h"
#import "macosx_display.h"
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#import <pthread.h>
//
// The main Q3 SMP API
//
static pthread_mutex_t smpMutex;
static pthread_cond_t mainThreadCondition;
static pthread_cond_t renderThreadCondition;
static volatile qboolean smpDataChanged;
static volatile void *smpData;
static void *GLimp_RenderThreadWrapper(void *arg)
{
Com_Printf("Render thread starting\n");
((void (*)())arg)();
#ifndef USE_CGLMACROS
// Unbind the context before we die
OSX_GLContextClearCurrent();
#endif
Com_Printf("Render thread terminating\n");
return arg;
}
qboolean GLimp_SpawnRenderThread( void (*function)( void ) )
{
pthread_t renderThread;
int rc;
pthread_mutex_init(&smpMutex, NULL);
pthread_cond_init(&mainThreadCondition, NULL);
pthread_cond_init(&renderThreadCondition, NULL);
rc = pthread_create(&renderThread, NULL, GLimp_RenderThreadWrapper, function);
if (rc) {
ri.Printf(PRINT_ALL, "pthread_create returned %d: %s", rc, strerror(rc));
return qfalse;
} else {
rc = pthread_detach(renderThread);
if (rc) {
ri.Printf(PRINT_ALL, "pthread_detach returned %d: %s", rc, strerror(rc));
}
}
return qtrue;
}
// Called in the rendering thread to wait until a command buffer is ready.
// The command buffer returned might be NULL, indicating that the rendering thread should exit.
void *GLimp_RendererSleep(void)
{
volatile void *data;
GLSTAMP("GLimp_RendererSleep start", 0);
#ifndef USE_CGLMACROS
// Clear the current context while we sleep so the main thread can access it
OSX_GLContextClearCurrent();
#endif
pthread_mutex_lock(&smpMutex); {
// Clear out any data we had and signal the main thread that we are no longer busy
smpData = NULL;
smpDataChanged = qfalse;
pthread_cond_signal(&mainThreadCondition);
// Wait until we get something new to work on
while (!smpDataChanged)
pthread_cond_wait(&renderThreadCondition, &smpMutex);
// Record the data (if any).
data = smpData;
} pthread_mutex_unlock(&smpMutex);
#ifndef USE_CGLMACROS
// We are going to render a frame... retake the context
OSX_GLContextSetCurrent();
#endif
GLSTAMP("GLimp_RendererSleep end", 0);
return (void *)data;
}
// Called from the main thread to wait until the rendering thread is done with the command buffer.
void GLimp_FrontEndSleep(void)
{
GLSTAMP("GLimp_FrontEndSleep start", 0);
pthread_mutex_lock(&smpMutex); {
while (smpData) {
#if 0
struct timespec ts;
int result;
ts.tv_sec = 1;
ts.tv_nsec = 0;
result = pthread_cond_timedwait_relative_np(&mainThreadCondition, &smpMutex, &ts);
if (result) {
Com_Printf("GLimp_FrontEndSleep timed out. Probably due to R_SyncRenderThread called due to Com_Error being called\n");
break;
}
#else
pthread_cond_wait(&mainThreadCondition, &smpMutex);
#endif
}
} pthread_mutex_unlock(&smpMutex);
#ifndef USE_CGLMACROS
// We are done waiting for the background thread, take the current context back.
OSX_GLContextSetCurrent();
#endif
GLSTAMP("GLimp_FrontEndSleep end", 0);
}
// This is called in the main thread to issue another command
// buffer to the rendering thread. This is always called AFTER
// GLimp_FrontEndSleep, so we know that there is no command
// pending in 'smpData'.
void GLimp_WakeRenderer( void *data )
{
GLSTAMP("GLimp_WakeRenderer start", data);
#ifndef USE_CGLMACROS
// We want the background thread to draw stuff. Give up the current context
OSX_GLContextClearCurrent();
#endif
pthread_mutex_lock(&smpMutex); {
// Store the new data pointer and wake up the rendering thread
assert(smpData == NULL);
smpData = data;
smpDataChanged = qtrue;
pthread_cond_signal(&renderThreadCondition);
} pthread_mutex_unlock(&smpMutex);
GLSTAMP("GLimp_WakeRenderer end", data);
}

View File

@ -1,46 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#import "macosx_glimp.h"
#include "tr_local.h"
#import "macosx_local.h"
qboolean GLimp_SpawnRenderThread( void (*function)( void ) )
{
return qfalse;
}
void *GLimp_RendererSleep(void)
{
return NULL;
}
void GLimp_FrontEndSleep(void)
{
}
void GLimp_WakeRenderer( void *data )
{
}

View File

@ -1,425 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#import "macosx_glimp.h"
#include "tr_local.h"
#import "macosx_local.h"
#import "macosx_display.h"
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#import <mach/mach.h>
#import <mach/mach_error.h>
#warning Using Mach Ports SMP acceleration implementation
/*
===========================================================
SMP acceleration
===========================================================
*/
#import <pthread.h>
#define USE_MACH_PORTS 1
// This is a small cover layer that makes for easier calling
typedef struct _MsgPort {
#if USE_MACH_PORTS
mach_port_t port;
id nsPort;
#else
pthread_mutex_t mutex;
pthread_cond_t condition;
volatile unsigned int status;
unsigned int msgCode;
void *msgData;
#endif
} MsgPort;
static BOOL portsInited = NO;
static pthread_mutex_t logMutex;
static unsigned int renderMsgOutstanding;
static unsigned int rendererProcessingCommand;
static MsgPort rendererMsgPort;
static MsgPort frontEndMsgPort;
enum {
MsgNone,
MsgPending,
};
enum {
MsgCodeInvalid = 0,
RenderCommandMsg = 1,
RenderCompletedMsg = 2,
};
static /*ID_INLINE*/ void MsgPortInit(MsgPort *port)
{
#if USE_MACH_PORTS
port->nsPort = [[NSMachPort alloc] init];
port->port = [port->nsPort machPort];
//rc = mach_port_allocate(mach_task_self(), MACH_PORT_TYPE_SEND_RECEIVE, &port->port);
//if (rc) {
// fprintf(stderr, "MsgPortInit: mach_port_allocate returned: %d: %s \n",rc, mach_error_string(rc));
// }
#else
int rc;
rc = pthread_mutex_init(&port->mutex, NULL);
if (rc) {
ri.Printf(PRINT_ALL, "MsgPortInit: pthread_mutex_init returned: %d: %s\n", rc, strerror(rc));
}
rc = pthread_cond_init(&port->condition, NULL);
if (rc) {
ri.Printf(PRINT_ALL, "EventInit: pthread_cond_init returned %d: %s\n", rc, strerror(rc));
}
port->status = MsgNone;
port->msgCode = MsgCodeInvalid;
port->msgData = NULL;
#endif
}
static /*ID_INLINE*/ void _SendMsg(MsgPort *port, unsigned int msgCode, void *msgData,
const char *functionName, const char *portName, const char *msgName)
{
int rc;
#if USE_MACH_PORTS
mach_msg_header_t msg;
//printf("SendMsg: %s %s %s (%d %08lx)\n",functionName, portName, msgName, msgCode, msgData);
/*
typedef struct
{
mach_msg_bits_t msgh_bits;
mach_msg_size_t msgh_size;
mach_port_t msgh_remote_port;
mach_port_t msgh_local_port;
mach_msg_size_t msgh_reserved;
mach_msg_id_t msgh_id;
} mach_msg_header_t;
*/
msg.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,MACH_MSG_TYPE_MAKE_SEND_ONCE);
msg.msgh_size=sizeof(msg);
//msg.msg_type=MSG_TYPE_NORMAL;
msg.msgh_local_port=MACH_PORT_NULL;
msg.msgh_remote_port=port->port;
msg.msgh_reserved = 0;
msg.msgh_id=(mach_msg_id_t)msgData; // HACK
rc = mach_msg_send(&msg);
if(rc) {
fprintf(stderr,"SendMsg: mach_msg_send returned %d: %s\n", rc, mach_error_string(rc));
}
#else
//printf("SendMsg: %s %s %s (%d %08lx)\n",functionName, portName, msgName, msgCode, msgData);
rc = pthread_mutex_lock(&port->mutex);
if(rc) {
fprintf(stderr,"SendMsg: pthread_mutex_lock returned %d: %s\n", rc, strerror(rc));
}
/* Block until port is empty */
while(port->status != MsgNone) {
//fprintf(stderr, "SendMsg: %s blocking until port %s is empty\n", functionName, portName);
rc = pthread_cond_wait(&port->condition, &port->mutex);
if(rc) {
fprintf(stderr, "SendMsg: pthread_cond_wait returned %d: %s\n", rc, strerror(rc));
}
}
/* Queue msg */
port->msgCode = msgCode;
port->msgData = msgData;
port->status = MsgPending;
/* Unlock port */
rc = pthread_mutex_unlock(&port->mutex);
if(rc) {
fprintf(stderr, "SendMsg: pthread_mutex_unlock returned %d: %s\n", rc, strerror(rc));
}
/* Wake up any threads blocked waiting for a message */
rc = pthread_cond_broadcast(&port->condition);
if(rc) {
fprintf(stderr, "SendMsg: pthread_cond_broadcast returned %d: %s\n", rc, strerror(rc));
}
#endif
}
static /*ID_INLINE*/ void _WaitMsg(MsgPort *port, unsigned int *msgCode, void **msgData,
const char *functionName, const char *portName)
{
int rc;
#if USE_MACH_PORTS
mach_msg_empty_rcv_t msg;
//printf("WaitMsg: %s %s\n",functionName, portName);
msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,MACH_MSG_TYPE_MAKE_SEND_ONCE);
msg.header.msgh_size= sizeof(msg);
//msg.msg_type=MSG_TYPE_NORMAL;
msg.header.msgh_local_port=port->port;
msg.header.msgh_remote_port=MACH_PORT_NULL;
msg.header.msgh_reserved = 0;
msg.header.msgh_id=(mach_msg_id_t)msgData; // HACK
rc = mach_msg_receive(&msg.header);
if(rc) {
fprintf(stderr,"SendMsg: mach_msg_receive returned %d: %s\n", rc, mach_error_string(rc));
}
*msgData = (void *)msg.header.msgh_id;
//printf("WaitMsg: %s %s got %08lx\n",functionName, portName, *msgData);
#else
//printf("WaitMsg: %s %s\n",functionName, portName);
rc = pthread_mutex_lock(&port->mutex);
if(rc) {
fprintf(stderr, "WaitMsg: pthread_mutex_lock returned %d: %s\n", rc, strerror(rc));
}
/* Block until port is empty */
while(port->status != MsgPending) {
rc = pthread_cond_wait(&port->condition, &port->mutex);
if(rc) {
fprintf(stderr, "WaitMsg: pthread_cond_wait returned %d: %s\n", rc, strerror(rc));
}
}
/* Remove msg */
*msgCode = port->msgCode;
*msgData = port->msgData;
//printf("WaitMsg: %s %s got %d %08lx\n",functionName, portName, *msgCode, *msgData);
port->status = MsgNone;
port->msgCode = 0;
port->msgData = NULL;
rc = pthread_mutex_unlock(&port->mutex);
if(rc) {
fprintf(stderr, "WaitMsg: pthread_mutex_unlock returned %d: %s\n", rc, strerror(rc));
}
/* Wake up any threads blocked waiting for port to be empty. */
rc = pthread_cond_broadcast(&port->condition);
if(rc) {
fprintf(stderr, "SendMsg: pthread_cond_broadcast returned %d: %s\n", rc, strerror(rc));
}
#endif
}
#define SendMsg(p, c, d) _SendMsg(p, c, d, __PRETTY_FUNCTION__, #p, #c)
#define WaitMsg(p, c, d) _WaitMsg(p, c, d, __PRETTY_FUNCTION__, #p)
#if 0
static void _Log(const char *msg)
{
int rc;
rc = pthread_mutex_lock(&logMutex);
if (rc)
ri.Printf(PRINT_ALL, "_Log: pthread_mutex_lock returned %d: %s\n", rc, strerror(rc));
fputs(msg,stderr);
fflush(stderr);
rc = pthread_mutex_unlock(&logMutex);
if (rc)
ri.Printf(PRINT_ALL, "_Log: pthread_mutex_unlock returned %d: %s\n", rc, strerror(rc));
}
#endif
//
// The main Q3 SMP API
//
static void (*glimpRenderThread)( void ) = NULL;
static void *GLimp_RenderThreadWrapper(void *arg)
{
Com_Printf("Render thread starting\n");
glimpRenderThread();
#ifndef USE_CGLMACROS
// Unbind the context before we die
OSX_GLContextClearCurrent();
#endif
// Send one last message back to front end before we die...
// This is somewhat of a hack.. fixme.
if (rendererProcessingCommand) {
SendMsg(&frontEndMsgPort, RenderCompletedMsg, NULL);
rendererProcessingCommand = NO;
}
Com_Printf("Render thread terminating\n");
return arg;
}
qboolean GLimp_SpawnRenderThread( void (*function)( void ) )
{
pthread_t renderThread;
int rc;
if (!portsInited) {
portsInited = YES;
MsgPortInit(&rendererMsgPort);
MsgPortInit(&frontEndMsgPort);
renderMsgOutstanding = NO;
rendererProcessingCommand = NO;
pthread_mutex_init(&logMutex, NULL);
}
glimpRenderThread = function;
rc = pthread_create(&renderThread,
NULL, // attributes
GLimp_RenderThreadWrapper,
NULL); // argument
if (rc) {
ri.Printf(PRINT_ALL, "pthread_create returned %d: %s", rc, strerror(rc));
return qfalse;
} else {
rc = pthread_detach(renderThread);
if (rc) {
ri.Printf(PRINT_ALL, "pthread_detach returned %d: %s", rc, strerror(rc));
}
}
return qtrue;
}
static volatile void *smpData;
// TJW - This is calling in the rendering thread to wait until another
// command buffer is ready. The command buffer returned might be NULL,
// indicating that the rendering thread should exit.
void *GLimp_RendererSleep(void)
{
//_Log(__PRETTY_FUNCTION__ " entered");
unsigned int msgCode;
void *msgData;
GLSTAMP("GLimp_RendererSleep start", 0);
#ifndef USE_CGLMACROS
// Clear the current context while we sleep so the main thread can access it
OSX_GLContextClearCurrent();
#endif
// Let the main thread we are idle and that no work is queued
//_Log("rs0\n");
/* If we actually had some work to do, then tell the front end we completed it. */
if (rendererProcessingCommand) {
SendMsg(&frontEndMsgPort, RenderCompletedMsg, NULL);
rendererProcessingCommand = NO;
}
// Wait for new msg
for (;;) {
WaitMsg(&rendererMsgPort, &msgCode, &msgData);
if (1 || msgCode == RenderCommandMsg) {
smpData = msgData;
break;
} else {
printf("renderer received unknown message: %d\n",msgCode);
}
}
#ifndef USE_CGLMACROS
// We are going to render a frame... retake the context
OSX_GLContextSetCurrent();
#endif
rendererProcessingCommand = YES;
GLSTAMP("GLimp_RendererSleep end", 0);
return (void *)smpData;
}
// TJW - This is from the main thread to wait until the rendering thread
// has completed the command buffer that it has
void GLimp_FrontEndSleep(void)
{
unsigned int msgCode;
void *msgData;
GLSTAMP("GLimp_FrontEndSleep start", 1);
if (renderMsgOutstanding) {
for (;;) {
WaitMsg(&frontEndMsgPort, &msgCode, &msgData);
if(1 || msgCode == RenderCompletedMsg) {
break;
} else {
printf("front end received unknown message: %d\n",msgCode);
}
}
renderMsgOutstanding = NO;
}
#ifndef USE_CGLMACROS
// We are done waiting for the background thread, take the current context back.
OSX_GLContextSetCurrent();
#endif
GLSTAMP("GLimp_FrontEndSleep end", 1);
}
// TJW - This is called in the main thread to issue another command
// buffer to the rendering thread. This is always called AFTER
// GLimp_FrontEndSleep, so we know that there is no command
// pending in 'smpData'.
void GLimp_WakeRenderer( void *data )
{
GLSTAMP("GLimp_WakeRenderer start", 1);
#ifndef USE_CGLMACROS
// We want the background thread to draw stuff. Give up the current context
OSX_GLContextClearCurrent();
#endif
SendMsg(&rendererMsgPort, RenderCommandMsg, data);
// Don't set flag saying that the renderer is processing something if it's just
// being told to exit.
//if(data != NULL)
renderMsgOutstanding = YES;
GLSTAMP("GLimp_WakeRenderer end", 1);
}

View File

@ -1,916 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#include <ApplicationServices/ApplicationServices.h>
#import "../client/client.h"
#import "macosx_local.h"
#import "../renderer/tr_local.h"
#import "Q3Controller.h"
//#import "CGMouseDeltaFix.h"
#import "macosx_timers.h"
#import "macosx_display.h" // For Sys_SetScreenFade
#import <IOKit/hidsystem/event_status_driver.h>
#import <sys/types.h>
#import <sys/time.h>
#import <unistd.h>
static qboolean inputActive;
static NSDate *distantPast;
static cvar_t *in_nomouse;
static cvar_t *in_showevents;
static cvar_t *in_mouseLowEndSlope;
static cvar_t *in_mouseHighEndCutoff;
static cvar_t *in_disableOSMouseScaling;
static void Sys_StartMouseInput();
static void Sys_StopMouseInput();
static qboolean mouseactive = qfalse;
static BOOL inputRectValid = NO;
static CGRect inputRect;
static NXMouseScaling originalScaling;
static unsigned int currentModifierFlags;
static void Sys_PreventMouseMovement(CGPoint point)
{
CGEventErr err;
//Com_Printf("**** Calling CGAssociateMouseAndMouseCursorPosition(false)\n");
err = CGAssociateMouseAndMouseCursorPosition(false);
if (err != CGEventNoErr) {
Sys_Error("Could not disable mouse movement, CGAssociateMouseAndMouseCursorPosition returned %d\n", err);
}
// Put the mouse in the position we want to leave it at
err = CGWarpMouseCursorPosition(point);
if (err != CGEventNoErr) {
Sys_Error("Could not disable mouse movement, CGWarpMouseCursorPosition returned %d\n", err);
}
}
static void Sys_ReenableMouseMovement()
{
CGEventErr err;
//Com_Printf("**** Calling CGAssociateMouseAndMouseCursorPosition(true)\n");
err = CGAssociateMouseAndMouseCursorPosition(true);
if (err != CGEventNoErr) {
Sys_Error("Could not reenable mouse movement, CGAssociateMouseAndMouseCursorPosition returned %d\n", err);
}
// Leave the mouse where it was -- don't warp here.
}
void Sys_InitInput(void)
{
// no input with dedicated servers
if ( com_dedicated->integer ) {
return;
}
// The Cvars don't seem to work really early.
[(Q3Controller *)[NSApp delegate] showBanner];
Com_Printf( "------- Input Initialization -------\n" );
if (!distantPast)
distantPast = [[NSDate distantPast] retain];
// For hide support. If we don't do this, then the command key will get stuck on when we hide (since we won't get the flags changed event when it goes up).
currentModifierFlags = 0;
r_fullscreen = Cvar_Get( "r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH );
in_nomouse = Cvar_Get( "in_nomouse", "0", 0 );
in_showevents = Cvar_Get( "in_showevents", "0", 0 );
// these defaults were arrived at via emprical testing between a Windows box and a Mac OS X box
#define ACT_LIKE_WINDOWS
#ifdef ACT_LIKE_WINDOWS
in_mouseLowEndSlope = Cvar_Get("in_mouseLowEndSlope", "3.5", CVAR_ARCHIVE);
if (in_mouseLowEndSlope->value < 1) {
Cvar_Set("in_mouseLowEndSlope", "1");
}
#else
in_mouseLowEndSlope = Cvar_Get("in_mouseLowEndSlope", "1", CVAR_ARCHIVE);
if (in_mouseLowEndSlope->value < 1) {
Cvar_Set("in_mouseLowEndSlope", "1");
}
#endif
in_mouseHighEndCutoff = Cvar_Get("in_mouseHighEndCutoff", "20", CVAR_ARCHIVE);
if (in_mouseLowEndSlope->value < 1) {
Cvar_Set("in_mouseHighEndCutoff", "1");
}
in_disableOSMouseScaling = Cvar_Get("in_disableOSMouseScaling", "1", CVAR_ARCHIVE );
glw_state.display = Sys_DisplayToUse();
inputActive = qtrue;
if ( in_nomouse->integer == 0 )
Sys_StartMouseInput();
else
Com_Printf( " in_nomouse is set, skipping.\n" );
Com_Printf( "------------------------------------\n" );
}
void Sys_ShutdownInput(void)
{
// no input with dedicated servers
if ( !com_dedicated || com_dedicated->integer ) {
return;
}
Com_Printf( "------- Input Shutdown -------\n" );
if ( !inputActive ) {
return;
}
inputActive = qfalse;
if (mouseactive)
Sys_StopMouseInput();
Com_Printf( "------------------------------\n" );
}
static void Sys_LockMouseInInputRect(CGRect rect)
{
CGPoint center;
center.x = rect.origin.x + rect.size.width / 2.0;
center.y = rect.origin.y + rect.size.height / 2.0;
// Now, put the mouse in the middle of the input rect (anywhere over it would do)
// and don't allow it to move. This means that the user won't be able to accidentally
// select another application.
Sys_PreventMouseMovement(center);
}
extern void Sys_UpdateWindowMouseInputRect(void);
static void Sys_StartMouseInput()
{
NXEventHandle eventStatus;
CGMouseDelta dx, dy;
if (mouseactive) {
//Com_Printf("**** Attempted to start mouse input while already started\n");
return;
}
Com_Printf("Starting mouse input\n");
mouseactive = qtrue;
if (inputRectValid && !glConfig.isFullscreen)
// Make sure that if window moved we don't hose the user...
Sys_UpdateWindowMouseInputRect();
Sys_LockMouseInInputRect(inputRect);
// Grab any mouse delta information to reset the last delta buffer
CGGetLastMouseDelta(&dx, &dy);
// Turn off mouse scaling
if (in_disableOSMouseScaling->integer==0 && (eventStatus = NXOpenEventStatus())) {
NXMouseScaling newScaling;
NXGetMouseScaling(eventStatus, &originalScaling);
newScaling.numScaleLevels = 1;
newScaling.scaleThresholds[0] = 1;
newScaling.scaleFactors[0] = -1;
NXSetMouseScaling(eventStatus, &newScaling);
NXCloseEventStatus(eventStatus);
}
[NSCursor hide];
}
static void Sys_StopMouseInput()
{
NXEventHandle eventStatus;
if (!mouseactive) {
//Com_Printf("**** Attempted to stop mouse input while already stopped\n");
return;
}
Com_Printf("Stopping mouse input\n");
// Restore mouse scaling
if (in_disableOSMouseScaling->integer == 0 && (eventStatus = NXOpenEventStatus())) {
NXSetMouseScaling(eventStatus, &originalScaling);
NXCloseEventStatus(eventStatus);
}
mouseactive = qfalse;
Sys_ReenableMouseMovement();
[NSCursor unhide];
}
//===========================================================================
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
static char *Sys_ConsoleInput(void)
{
extern qboolean stdin_active;
static char text[256];
int len;
fd_set fdset;
struct timeval timeout;
if (!com_dedicated || !com_dedicated->integer)
return NULL;
if (!stdin_active)
return NULL;
FD_ZERO(&fdset);
FD_SET(fileno(stdin), &fdset);
timeout.tv_sec = 0;
timeout.tv_usec = 0;
if (select (1, &fdset, NULL, NULL, &timeout) == -1 || !FD_ISSET(fileno(stdin), &fdset))
return NULL;
len = read (fileno(stdin), text, sizeof(text));
if (len == 0) { // eof!
stdin_active = qfalse;
return NULL;
}
if (len < 1)
return NULL;
text[len-1] = 0; // rip off the /n and terminate
return text;
}
//===========================================================================
// Mouse input
//===========================================================================
#define MAX_DISPLAYS 128
CGDirectDisplayID Sys_DisplayToUse(void)
{
static BOOL gotDisplay = NO;
static CGDirectDisplayID displayToUse;
cvar_t *vid_screen;
CGDisplayErr err;
CGDirectDisplayID displays[MAX_DISPLAYS];
CGDisplayCount displayCount;
int displayIndex;
if (gotDisplay)
return displayToUse;
gotDisplay = YES;
err = CGGetActiveDisplayList(MAX_DISPLAYS, displays, &displayCount);
if (err != CGDisplayNoErr)
Sys_Error("Cannot get display list -- CGGetActiveDisplayList returned %d.\n", err);
// -1, the default, means to use the main screen
if ((vid_screen = Cvar_Get("vid_screen", "-1", CVAR_ARCHIVE)))
displayIndex = vid_screen->integer;
else
displayIndex = -1;
if (displayIndex < 0 || displayIndex >= displayCount)
// This is documented (in CGDirectDisplay.h) to be the main display. We want to
// return this instead of kCGDirectMainDisplay since this will allow us to compare
// display IDs.
displayToUse = displays[0];
else
displayToUse = displays[displayIndex];
return displayToUse;
}
void Sys_SetMouseInputRect(CGRect newRect)
{
inputRectValid = YES;
inputRect = newRect;
//Com_Printf("**** inputRect = (%f, %f, %f, %f)\n", newRect.origin.x, newRect.origin.y, newRect.size.width, newRect.size.height);
if (mouseactive)
Sys_LockMouseInInputRect(inputRect);
}
static void Sys_ProcessMouseMovedEvent(NSEvent *mouseMovedEvent, int currentTime)
{
float dx, dy;
if (!mouseactive)
return;
dx = [mouseMovedEvent deltaX];
dy = [mouseMovedEvent deltaY];
if (in_showevents->integer)
Com_Printf("MOUSE MOVED: %d, %d\n", dx, dy);
Sys_QueEvent(currentTime, SE_MOUSE, dx, dy, 0, NULL );
}
// If we are 'paused' (i.e., in any state that our normal key bindings aren't in effect), then interpret cmd-h and cmd-tab as hiding the application.
static qboolean maybeHide()
{
if ((currentModifierFlags & NSCommandKeyMask) == 0)
return qfalse;
return Sys_Hide();
}
static ID_INLINE void sendEventForCharacter(NSEvent *event, unichar character, qboolean keyDownFlag, int currentTime)
{
if (in_showevents->integer)
Com_Printf("CHARACTER: 0x%02x down=%d\n", character, keyDownFlag);
#ifdef OMNI_TIMER
if (character == NSF9FunctionKey && !keyDownFlag) {
// Log and reset the root timer. We should currently only have the root on the stack.
OTStackPopRoot();
OTStackReportResults(NULL);
OTStackReset();
OTStackPushRoot(rootNode);
}
#endif
switch (character) {
case 0x03:
Sys_QueEvent(currentTime, SE_KEY, K_KP_ENTER, keyDownFlag, 0, NULL);
break;
case '\b':
case '\177':
Sys_QueEvent(currentTime, SE_KEY, K_BACKSPACE, keyDownFlag, 0, NULL);
if (keyDownFlag) {
Sys_QueEvent(currentTime, SE_CHAR, '\b', 0, 0, NULL);
}
break;
case '\t':
if (maybeHide())
return;
Sys_QueEvent(currentTime, SE_KEY, K_TAB, keyDownFlag, 0, NULL);
if (keyDownFlag) {
Sys_QueEvent(currentTime, SE_CHAR, '\t', 0, 0, NULL);
}
break;
case '\r':
case '\n':
Sys_QueEvent(currentTime, SE_KEY, K_ENTER, keyDownFlag, 0, NULL);
if (keyDownFlag) {
Sys_QueEvent(currentTime, SE_CHAR, '\r', 0, 0, NULL);
}
break;
case '\033':
Sys_QueEvent(currentTime, SE_KEY, K_ESCAPE, keyDownFlag, 0, NULL);
break;
case ' ':
Sys_QueEvent(currentTime, SE_KEY, K_SPACE, keyDownFlag, 0, NULL);
if (keyDownFlag) {
Sys_QueEvent(currentTime, SE_CHAR, ' ', 0, 0, NULL);
}
break;
case NSUpArrowFunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_UPARROW, keyDownFlag, 0, NULL);
break;
case NSDownArrowFunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_DOWNARROW, keyDownFlag, 0, NULL);
break;
case NSLeftArrowFunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_LEFTARROW, keyDownFlag, 0, NULL);
break;
case NSRightArrowFunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_RIGHTARROW, keyDownFlag, 0, NULL);
break;
case NSF1FunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_F1, keyDownFlag, 0, NULL);
break;
case NSF2FunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_F2, keyDownFlag, 0, NULL);
break;
case NSF3FunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_F3, keyDownFlag, 0, NULL);
break;
case NSF4FunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_F4, keyDownFlag, 0, NULL);
break;
case NSF5FunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_F5, keyDownFlag, 0, NULL);
break;
case NSF6FunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_F6, keyDownFlag, 0, NULL);
break;
case NSF7FunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_F7, keyDownFlag, 0, NULL);
break;
case NSF8FunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_F8, keyDownFlag, 0, NULL);
break;
case NSF9FunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_F9, keyDownFlag, 0, NULL);
break;
case NSF10FunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_F10, keyDownFlag, 0, NULL);
break;
case NSF11FunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_F11, keyDownFlag, 0, NULL);
break;
case NSF12FunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_F12, keyDownFlag, 0, NULL);
break;
case NSF13FunctionKey:
Sys_QueEvent(currentTime, SE_KEY, '`', keyDownFlag, 0, NULL);
if (keyDownFlag) {
Sys_QueEvent(currentTime, SE_CHAR, '`', 0, 0, NULL);
}
break;
case NSInsertFunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_INS, keyDownFlag, 0, NULL);
break;
case NSDeleteFunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_DEL, keyDownFlag, 0, NULL);
break;
case NSPageDownFunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_PGDN, keyDownFlag, 0, NULL);
break;
case NSPageUpFunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_PGUP, keyDownFlag, 0, NULL);
break;
case NSHomeFunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_HOME, keyDownFlag, 0, NULL);
break;
case NSEndFunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_END, keyDownFlag, 0, NULL);
break;
case NSPauseFunctionKey:
Sys_QueEvent(currentTime, SE_KEY, K_PAUSE, keyDownFlag, 0, NULL);
break;
default:
if ([event modifierFlags] & NSNumericPadKeyMask) {
switch (character) {
case '0':
Sys_QueEvent(currentTime, SE_KEY, K_KP_INS, keyDownFlag, 0, NULL);
break;
case '1':
Sys_QueEvent(currentTime, SE_KEY, K_KP_END, keyDownFlag, 0, NULL);
break;
case '2':
Sys_QueEvent(currentTime, SE_KEY, K_KP_DOWNARROW, keyDownFlag, 0, NULL);
break;
case '3':
Sys_QueEvent(currentTime, SE_KEY, K_KP_PGDN, keyDownFlag, 0, NULL);
break;
case '4':
Sys_QueEvent(currentTime, SE_KEY, K_KP_LEFTARROW, keyDownFlag, 0, NULL);
break;
case '5':
Sys_QueEvent(currentTime, SE_KEY, K_KP_5, keyDownFlag, 0, NULL);
break;
case '6':
Sys_QueEvent(currentTime, SE_KEY, K_KP_RIGHTARROW, keyDownFlag, 0, NULL);
break;
case '7':
Sys_QueEvent(currentTime, SE_KEY, K_KP_HOME, keyDownFlag, 0, NULL);
break;
case '8':
Sys_QueEvent(currentTime, SE_KEY, K_KP_UPARROW, keyDownFlag, 0, NULL);
break;
case '9':
Sys_QueEvent(currentTime, SE_KEY, K_KP_PGUP, keyDownFlag, 0, NULL);
break;
case '.':
case ',':
Sys_QueEvent(currentTime, SE_KEY, K_KP_DEL, keyDownFlag, 0, NULL);
break;
case '+':
Sys_QueEvent(currentTime, SE_KEY, K_KP_PLUS, keyDownFlag, 0, NULL);
break;
case '-':
Sys_QueEvent(currentTime, SE_KEY, K_KP_MINUS, keyDownFlag, 0, NULL);
break;
case '*':
Sys_QueEvent(currentTime, SE_KEY, K_KP_STAR, keyDownFlag, 0, NULL);
break;
case '/':
Sys_QueEvent(currentTime, SE_KEY, K_KP_SLASH, keyDownFlag, 0, NULL);
break;
case '=':
Sys_QueEvent(currentTime, SE_KEY, K_KP_EQUALS, keyDownFlag, 0, NULL);
break;
default:
//NSLog(@"TODO: Implement character %d", (int)character);
break;
}
} else if (character >= 'a' && character <= 'z') {
if (character == 'h') {
if (maybeHide())
return;
}
Sys_QueEvent(currentTime, SE_KEY, character, keyDownFlag, 0, NULL);
if (keyDownFlag) {
Sys_QueEvent(currentTime, SE_CHAR, (char)character, 0, 0, NULL);
}
} else if (character >= 'A' && character <= 'Z') {
Sys_QueEvent(currentTime, SE_KEY, 'a' + (character - 'A'), keyDownFlag, 0, NULL);
if (keyDownFlag) {
Sys_QueEvent(currentTime, SE_CHAR, character, 0, 0, NULL);
}
} else if (character >= 32 && character < 127) {
Sys_QueEvent(currentTime, SE_KEY, character, keyDownFlag, 0, NULL);
if (keyDownFlag) {
Sys_QueEvent(currentTime, SE_CHAR, (char)character, 0, 0, NULL);
}
} else {
//NSLog(@"TODO: Implement character %d", (int)character);
}
break;
}
}
static ID_INLINE void processKeyEvent(NSEvent *keyEvent, qboolean keyDownFlag, int currentTime)
{
NSEventType eventType;
NSString *characters;
unsigned int characterIndex, characterCount;
eventType = [keyEvent type];
characters = [keyEvent charactersIgnoringModifiers];
characterCount = [characters length];
for (characterIndex = 0; characterIndex < characterCount; characterIndex++) {
sendEventForCharacter(keyEvent, [characters characterAtIndex:characterIndex], keyDownFlag, currentTime);
}
}
static ID_INLINE void sendEventForMaskChangeInFlags(int quakeKey, unsigned int modifierMask, unsigned int newModifierFlags, int currentTime)
{
BOOL oldHadModifier, newHasModifier;
oldHadModifier = (currentModifierFlags & modifierMask) != 0;
newHasModifier = (newModifierFlags & modifierMask) != 0;
if (oldHadModifier != newHasModifier) {
// NSLog(@"Key %d posted for modifier mask modifierMask", quakeKey);
Sys_QueEvent(currentTime, SE_KEY, quakeKey, newHasModifier, 0, NULL);
}
}
static ID_INLINE void processFlagsChangedEvent(NSEvent *flagsChangedEvent, int currentTime)
{
int newModifierFlags;
newModifierFlags = [flagsChangedEvent modifierFlags];
sendEventForMaskChangeInFlags(K_COMMAND, NSCommandKeyMask, newModifierFlags, currentTime);
sendEventForMaskChangeInFlags(K_CAPSLOCK, NSAlphaShiftKeyMask, newModifierFlags, currentTime);
sendEventForMaskChangeInFlags(K_ALT, NSAlternateKeyMask, newModifierFlags, currentTime);
sendEventForMaskChangeInFlags(K_CTRL, NSControlKeyMask, newModifierFlags, currentTime);
sendEventForMaskChangeInFlags(K_SHIFT, NSShiftKeyMask, newModifierFlags, currentTime);
currentModifierFlags = newModifierFlags;
}
static ID_INLINE void processSystemDefinedEvent(NSEvent *systemDefinedEvent, int currentTime)
{
static int oldButtons = 0;
int buttonsDelta;
int buttons;
int isDown;
if ([systemDefinedEvent subtype] == 7) {
if (!mouseactive)
return;
buttons = [systemDefinedEvent data2];
buttonsDelta = oldButtons ^ buttons;
//Com_Printf("uberbuttons: %08lx %08lx\n",buttonsDelta,buttons);
if (buttonsDelta & 1) {
isDown = buttons & 1;
Sys_QueEvent(currentTime, SE_KEY, K_MOUSE1, isDown, 0, NULL);
if (in_showevents->integer) {
Com_Printf("MOUSE2: %s\n", isDown ? "down" : "up");
}
}
if (buttonsDelta & 2) {
isDown = buttons & 2;
Sys_QueEvent(currentTime, SE_KEY, K_MOUSE2, isDown, 0, NULL);
if (in_showevents->integer) {
Com_Printf("MOUSE3: %s\n", isDown ? "down" : "up");
}
}
if (buttonsDelta & 4) {
isDown = buttons & 4;
Sys_QueEvent(currentTime, SE_KEY, K_MOUSE3, isDown, 0, NULL);
if (in_showevents->integer) {
Com_Printf("MOUSE1: %s\n", isDown ? "down" : "up");
}
}
if (buttonsDelta & 8) {
isDown = buttons & 8;
Sys_QueEvent(currentTime, SE_KEY, K_MOUSE4, isDown, 0, NULL);
if (in_showevents->integer) {
Com_Printf("MOUSE4: %s\n", isDown ? "down" : "up");
}
}
if (buttonsDelta & 16) {
isDown = buttons & 16;
Sys_QueEvent(currentTime, SE_KEY, K_MOUSE5, isDown, 0, NULL);
if (in_showevents->integer) {
Com_Printf("MOUSE5: %s\n", isDown ? "down" : "up");
}
}
oldButtons = buttons;
}
}
static ID_INLINE void processEvent(NSEvent *event, int currentTime)
{
NSEventType eventType;
if (!inputActive)
return;
eventType = [event type];
if (in_showevents->integer)
NSLog(@"event = %@", event);
switch (eventType) {
// These six event types are ignored since we do all of our mouse down/up process via the uber-mouse system defined event. We have to accept these events however since they get enqueued and the queue will fill up if we don't.
case NSLeftMouseDown:
//Sys_QueEvent(currentTime, SE_KEY, K_MOUSE1, qtrue, 0, NULL);
return;
case NSLeftMouseUp:
//Sys_QueEvent(currentTime, SE_KEY, K_MOUSE1, qfalse, 0, NULL);
return;
case NSRightMouseDown:
//Sys_QueEvent(currentTime, SE_KEY, K_MOUSE2, qtrue, 0, NULL);
return;
case NSRightMouseUp:
//Sys_QueEvent(currentTime, SE_KEY, K_MOUSE2, qfalse, 0, NULL);
return;
case 25: // other mouse down
return;
case 26: // other mouse up
return;
case NSMouseMoved:
case NSLeftMouseDragged:
case NSRightMouseDragged:
case 27: // other mouse dragged
Sys_ProcessMouseMovedEvent(event, currentTime);
return;
case NSKeyDown:
case NSKeyUp:
processKeyEvent(event, eventType == NSKeyDown, currentTime);
return;
case NSFlagsChanged:
processFlagsChangedEvent(event, currentTime);
return;
case NSSystemDefined:
processSystemDefinedEvent(event, currentTime);
return;
case NSScrollWheel:
if ([event deltaY] < 0.0) {
Sys_QueEvent(currentTime, SE_KEY, K_MWHEELDOWN, qtrue, 0, NULL );
Sys_QueEvent(currentTime, SE_KEY, K_MWHEELDOWN, qfalse, 0, NULL );
} else {
Sys_QueEvent(currentTime, SE_KEY, K_MWHEELUP, qtrue, 0, NULL );
Sys_QueEvent(currentTime, SE_KEY, K_MWHEELUP, qfalse, 0, NULL );
}
return;
default:
break;
}
[NSApp sendEvent:event];
}
static void Sys_SendKeyEvents(int currentTime)
{
#ifndef DEDICATED
NSEvent *event;
NSDate *timeout;
extern float SNDDMA_GetBufferDuration();
timeout = distantPast;
if (Sys_IsHidden)
timeout = [NSDate dateWithTimeIntervalSinceNow: 0.25 * SNDDMA_GetBufferDuration()];
// This gets call regardless of whether inputActive is true or not. This is important since we need to be poking the event queue in order for the unhide event to make its way through the system. This means that when we hide, we can just shut down the input system and reeanbled it when we unhide.
while ((event = [NSApp nextEventMatchingMask: NSAnyEventMask
untilDate: timeout
inMode: NSDefaultRunLoopMode
dequeue:YES])) {
if (Sys_IsHidden) {
// Just let NSApp handle events so that we'll get the app activation event
[NSApp sendEvent: event];
timeout = [NSDate dateWithTimeIntervalSinceNow: 0.1];
} else {
static int lastEventTime = 0;
static BOOL lastEventTimeValid = NO;
// Mac OS X 10.0.3 has a bug where the if the monitor goes to sleep in fullscreen GL mode, the gamma won't be restored. We'll restore the gamma if there is a pause while in the game of more than 10 seconds. We don't do this on the 'Sys_IsHidden' branch since unhiding will restore the monitor gamma.
if ((currentTime - lastEventTime > 1 * 1000) && lastEventTimeValid) {
//Com_Printf("Restoring monitor gamma after being idle for %f seconds.\n", (currentTime - lastEventTime) / 1000.0);
[NSCursor hide];
Sys_SetScreenFade(&glw_state.inGameTable, 1.0);
}
lastEventTime = [event timestamp] * 1000.0; //currentTime;
lastEventTimeValid = YES;
processEvent(event, lastEventTime);
}
}
#endif
}
/*
========================================================================
EVENT LOOP
========================================================================
*/
extern qboolean Sys_GetPacket ( netadr_t *net_from, msg_t *net_message );
#define MAX_QUED_EVENTS 256
#define MASK_QUED_EVENTS ( MAX_QUED_EVENTS - 1 )
static sysEvent_t eventQue[MAX_QUED_EVENTS];
static int eventHead, eventTail;
static byte sys_packetReceived[MAX_MSGLEN];
/*
================
Sys_QueEvent
A time of 0 will get the current time
Ptr should either be null, or point to a block of data that can
be freed by the game later.
================
*/
void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr ) {
sysEvent_t *ev;
int i,j;
#ifndef DEDICATED
if (in_showevents->integer)
NSLog(@"EVENT ENQUEUE: time=%d type=%d value=0x%08x value2=0x%08x\n", time, type, value, value2);
#endif
if ( eventHead - eventTail >= MAX_QUED_EVENTS ) {
Com_Printf("Sys_QueEvent: overflow\n");
}
if ( !time ) {
time = Sys_Milliseconds();
}
// insert it by time
for ( i = eventTail ; i < eventHead ; i++ ) {
ev = &eventQue[ i & MASK_QUED_EVENTS ];
if ( ev->evTime > time ) {
break;
}
}
// insert before i
for ( j = eventHead ; j > i ; j-- ) {
eventQue[ j & MASK_QUED_EVENTS ] = eventQue[ (j-1) & MASK_QUED_EVENTS ];
}
ev = &eventQue[ i & MASK_QUED_EVENTS ];
eventHead++;
ev->evTime = time;
ev->evType = type;
ev->evValue = value;
ev->evValue2 = value2;
ev->evPtrLength = ptrLength;
ev->evPtr = ptr;
}
/*
================
Sys_GetEvent
================
*/
sysEvent_t Sys_GetEvent( void )
{
sysEvent_t ev;
char *s;
msg_t netmsg;
netadr_t adr;
int currentTime;
// return if we have data
if (eventHead > eventTail) {
eventTail++;
return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ];
}
// The queue must be empty. Check all of the event sources. If the events are
// already in the queue, we can't imply any real ordering, so we'll avoid extra
// system calls and give them all the same time.
currentTime = Sys_Milliseconds();
// Check for mouse and keyboard events
Sys_SendKeyEvents(currentTime);
// check for console commands
s = Sys_ConsoleInput();
if ( s ) {
char *b;
int len;
len = strlen( s ) + 1;
b = Z_Malloc( len );
strcpy( b, s );
Sys_QueEvent( currentTime, SE_CONSOLE, 0, 0, len, b );
}
// During debugging it is sometimes usefull to be able to start/stop mouse input.
// Don't turn on the input when we've disabled it because we're hidden, however.
if (!com_dedicated->integer) {
if (in_nomouse->integer == mouseactive && !Sys_IsHidden) {
if (in_nomouse->integer)
Sys_StopMouseInput();
else
Sys_StartMouseInput();
}
}
// check for network packets
MSG_Init( &netmsg, sys_packetReceived, sizeof( sys_packetReceived ) );
if ( Sys_GetPacket ( &adr, &netmsg ) ) {
netadr_t *buf;
int len;
// copy out to a seperate buffer for qeueing
len = sizeof( netadr_t ) + netmsg.cursize;
buf = Z_Malloc( len );
*buf = adr;
memcpy( buf+1, netmsg.data, netmsg.cursize );
Sys_QueEvent( currentTime, SE_PACKET, 0, 0, len, buf );
}
// If we got an event, return it
if (eventHead > eventTail) {
eventTail++;
return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ];
}
// Otherwise, return an empty event to indicate that there are no events pending.
memset( &ev, 0, sizeof( ev ) );
ev.evTime = currentTime;
return ev;
}

View File

@ -1,129 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __macosx_local_h
#define __macosx_local_h
#include "qcommon.h"
#ifdef __cplusplus
typedef void NSDictionary;
typedef void NSOpenGLContext;
typedef void NSWindow;
extern "C" {
#else
#import <Foundation/NSGeometry.h>
@class NSEvent, NSOpenGLContext, NSWindow;
#endif
#include <ApplicationServices/ApplicationServices.h>
#include <OpenGL/CGLTypes.h>
// In macosx_input.m
extern void Sys_InitInput(void);
extern void Sys_ShutdownInput(void);
extern void Sys_SetMouseInputRect(CGRect newRect);
extern CGDirectDisplayID Sys_DisplayToUse(void);
// In macosx_sys.m
extern void Sys_QueEvent(int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr);
extern void Sys_AnnoyingBanner();
// In macosx_glimp.m
extern qboolean Sys_IsHidden;
extern qboolean Sys_Hide();
extern qboolean Sys_Unhide();
typedef struct {
CGDirectDisplayID display;
CGTableCount tableSize;
CGGammaValue *red;
CGGammaValue *blue;
CGGammaValue *green;
} glwgamma_t;
typedef struct
{
CGDirectDisplayID display;
NSDictionary *desktopMode;
NSDictionary *gameMode;
CGDisplayCount displayCount;
glwgamma_t *originalDisplayGammaTables;
glwgamma_t inGameTable;
glwgamma_t tempTable;
NSOpenGLContext *_ctx;
CGLContextObj _cgl_ctx;
qboolean _ctx_is_current;
NSWindow *window;
FILE *log_fp;
unsigned int bufferSwapCount;
unsigned int glPauseCount;
} glwstate_t;
extern glwstate_t glw_state;
#define OSX_SetGLContext(context) \
do { \
NSOpenGLContext *_context = (context); \
glw_state._ctx = _context; \
glw_state._cgl_ctx = [_context cglContext]; \
} while (0)
#define OSX_GetNSGLContext() glw_state._ctx
#define OSX_GetCGLContext() glw_state._cgl_ctx
#define OSX_GLContextIsCurrent() glw_state._ctx_is_current
#define OSX_GLContextSetCurrent() \
do { \
[glw_state._ctx makeCurrentContext]; \
glw_state._ctx_is_current = (glw_state._ctx != nil); \
} while (0)
#define OSX_GLContextClearCurrent() \
do { \
[NSOpenGLContext clearCurrentContext]; \
glw_state._ctx_is_current = NO; \
} while (0)
extern void Sys_PauseGL();
extern void Sys_ResumeGL();
#import "macosx_timers.h"
#ifdef OMNI_TIMER
extern OTStampList glThreadStampList;
#define GLSTAMP(name, data) OTStampListAddStamp(glThreadStampList, name, data)
#else
#define GLSTAMP(name, data)
#endif
#ifdef __cplusplus
}
#endif
#endif // __macosx_local_h

File diff suppressed because it is too large Load Diff

View File

@ -1,325 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// mac_snddma.c
// all other sound mixing is portable
#include "../client/snd_local.h"
#include <CoreServices/CoreServices.h>
#include <CoreAudio/AudioHardware.h>
#include <QuickTime/QuickTime.h>
// For 'ri'
#include "../renderer/tr_local.h"
#import <Foundation/NSData.h>
#import <Foundation/NSString.h>
static unsigned int submissionChunk;
static unsigned int maxMixedSamples;
static short *s_mixedSamples;
static int s_chunkCount; // number of chunks submitted
static qboolean s_isRunning;
static AudioDeviceID outputDeviceID;
static AudioStreamBasicDescription outputStreamBasicDescription;
/*
===============
audioDeviceIOProc
===============
*/
OSStatus audioDeviceIOProc(AudioDeviceID inDevice,
const AudioTimeStamp *inNow,
const AudioBufferList *inInputData,
const AudioTimeStamp *inInputTime,
AudioBufferList *outOutputData,
const AudioTimeStamp *inOutputTime,
void *inClientData)
{
int offset;
short *samples;
unsigned int sampleIndex;
float *outBuffer;
float scale, temp;
offset = ( s_chunkCount * submissionChunk ) % maxMixedSamples;
samples = s_mixedSamples + offset;
assert(outOutputData->mNumberBuffers == 1);
assert(outOutputData->mBuffers[0].mNumberChannels == 2);
//assert(outOutputData->mBuffers[0].mDataByteSize == (dma.submission_chunk * sizeof(float)));
outBuffer = (float *)outOutputData->mBuffers[0].mData;
// If we have run out of samples, return silence
if (s_chunkCount * submissionChunk > dma.channels * s_paintedtime) {
memset(outBuffer, 0, sizeof(*outBuffer) * dma.submission_chunk);
} else {
scale = (1.0f / SHRT_MAX);
if (outputStreamBasicDescription.mSampleRate == 44100 && dma.speed == 22050) {
for (sampleIndex = 0; sampleIndex < dma.submission_chunk; sampleIndex+=2) {
// Convert the samples from shorts to floats. Scale the floats to be [-1..1].
temp = samples[sampleIndex + 0] * scale;
outBuffer[(sampleIndex<<1)+0] = temp;
outBuffer[(sampleIndex<<1)+2] = temp;
temp = samples[sampleIndex + 1] * scale;
outBuffer[(sampleIndex<<1)+1] = temp;
outBuffer[(sampleIndex<<1)+3] = temp;
}
} else if (outputStreamBasicDescription.mSampleRate == 44100 && dma.speed == 11025) {
for (sampleIndex = 0; sampleIndex < dma.submission_chunk; sampleIndex+=4) {
// Convert the samples from shorts to floats. Scale the floats to be [-1..1].
temp = samples[sampleIndex + 0] * scale;
outBuffer[(sampleIndex<<1)+0] = temp;
outBuffer[(sampleIndex<<1)+2] = temp;
outBuffer[(sampleIndex<<1)+4] = temp;
outBuffer[(sampleIndex<<1)+6] = temp;
temp = samples[sampleIndex + 1] * scale;
outBuffer[(sampleIndex<<1)+1] = temp;
outBuffer[(sampleIndex<<1)+3] = temp;
outBuffer[(sampleIndex<<1)+5] = temp;
outBuffer[(sampleIndex<<1)+7] = temp;
}
} else {
for (sampleIndex = 0; sampleIndex < dma.submission_chunk; sampleIndex++) {
// Convert the samples from shorts to floats. Scale the floats to be [-1..1].
outBuffer[sampleIndex] = samples[sampleIndex] * scale;
}
}
}
s_chunkCount++; // this is the next buffer we will submit
return 0;
}
/*
===============
S_MakeTestPattern
===============
*/
void S_MakeTestPattern( void ) {
int i;
float v;
int sample;
for ( i = 0 ; i < dma.samples / 2 ; i ++ ) {
v = sin( M_PI * 2 * i / 64 );
sample = v * 0x4000;
((short *)dma.buffer)[i*2] = sample;
((short *)dma.buffer)[i*2+1] = sample;
}
}
/*
===============
SNDDMA_Init
===============
*/
qboolean SNDDMA_Init(void)
{
cvar_t *bufferSize;
cvar_t *chunkSize;
OSStatus status;
UInt32 propertySize, bufferByteCount;
if (s_isRunning)
return qtrue;
chunkSize = ri.Cvar_Get( "s_chunksize", "2048", CVAR_ARCHIVE );
bufferSize = ri.Cvar_Get( "s_buffersize", "16384", CVAR_ARCHIVE );
Com_Printf(" Chunk size = %d\n", chunkSize->integer);
Com_Printf("Buffer size = %d\n", bufferSize->integer);
if (!chunkSize->integer)
ri.Error(ERR_FATAL, "s_chunksize must be non-zero\n");
if (!bufferSize->integer)
ri.Error(ERR_FATAL, "s_buffersize must be non-zero\n");
if (chunkSize->integer >= bufferSize->integer)
ri.Error(ERR_FATAL, "s_chunksize must be less than s_buffersize\n");
if (bufferSize->integer % chunkSize->integer)
ri.Error(ERR_FATAL, "s_buffersize must be an even multiple of s_chunksize\n");
// Get the output device
propertySize = sizeof(outputDeviceID);
status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &propertySize, &outputDeviceID);
if (status) {
Com_Printf("AudioHardwareGetProperty returned %d\n", status);
return qfalse;
}
if (outputDeviceID == kAudioDeviceUnknown) {
Com_Printf("AudioHardwareGetProperty: outputDeviceID is kAudioDeviceUnknown\n");
return qfalse;
}
// Configure the output device
propertySize = sizeof(bufferByteCount);
bufferByteCount = chunkSize->integer * sizeof(float);
status = AudioDeviceSetProperty(outputDeviceID, NULL, 0, NO, kAudioDevicePropertyBufferSize, propertySize, &bufferByteCount);
if (status) {
Com_Printf("AudioDeviceSetProperty: returned %d when setting kAudioDevicePropertyBufferSize to %d\n", status, chunkSize->integer);
return qfalse;
}
propertySize = sizeof(bufferByteCount);
status = AudioDeviceGetProperty(outputDeviceID, 0, NO, kAudioDevicePropertyBufferSize, &propertySize, &bufferByteCount);
if (status) {
Com_Printf("AudioDeviceGetProperty: returned %d when setting kAudioDevicePropertyBufferSize\n", status);
return qfalse;
}
// Print out the device status
propertySize = sizeof(outputStreamBasicDescription);
status = AudioDeviceGetProperty(outputDeviceID, 0, NO, kAudioDevicePropertyStreamFormat, &propertySize, &outputStreamBasicDescription);
if (status) {
Com_Printf("AudioDeviceGetProperty: returned %d when getting kAudioDevicePropertyStreamFormat\n", status);
return qfalse;
}
Com_Printf("Hardware format:\n");
Com_Printf(" %f mSampleRate\n", outputStreamBasicDescription.mSampleRate);
Com_Printf(" %c%c%c%c mFormatID\n",
(outputStreamBasicDescription.mFormatID & 0xff000000) >> 24,
(outputStreamBasicDescription.mFormatID & 0x00ff0000) >> 16,
(outputStreamBasicDescription.mFormatID & 0x0000ff00) >> 8,
(outputStreamBasicDescription.mFormatID & 0x000000ff) >> 0);
Com_Printf(" %5d mBytesPerPacket\n", outputStreamBasicDescription.mBytesPerPacket);
Com_Printf(" %5d mFramesPerPacket\n", outputStreamBasicDescription.mFramesPerPacket);
Com_Printf(" %5d mBytesPerFrame\n", outputStreamBasicDescription.mBytesPerFrame);
Com_Printf(" %5d mChannelsPerFrame\n", outputStreamBasicDescription.mChannelsPerFrame);
Com_Printf(" %5d mBitsPerChannel\n", outputStreamBasicDescription.mBitsPerChannel);
if(outputStreamBasicDescription.mFormatID != kAudioFormatLinearPCM) {
Com_Printf("Default Audio Device doesn't support Linear PCM!");
return qfalse;
}
// Start sound running
status = AudioDeviceAddIOProc(outputDeviceID, audioDeviceIOProc, NULL);
if (status) {
Com_Printf("AudioDeviceAddIOProc: returned %d\n", status);
return qfalse;
}
submissionChunk = chunkSize->integer;
if (outputStreamBasicDescription.mSampleRate == 44100) {
submissionChunk = chunkSize->integer/2;
}
maxMixedSamples = bufferSize->integer;
s_mixedSamples = calloc(1, sizeof(*s_mixedSamples) * maxMixedSamples);
Com_Printf("Chunk Count = %d\n", (maxMixedSamples / submissionChunk));
// Tell the main app what we expect from it
dma.samples = maxMixedSamples;
dma.submission_chunk = submissionChunk;
dma.samplebits = 16;
dma.buffer = (byte *)s_mixedSamples;
dma.channels = outputStreamBasicDescription.mChannelsPerFrame;
dma.speed = 22050; //(unsigned long)outputStreamBasicDescription.mSampleRate;
// We haven't enqueued anything yet
s_chunkCount = 0;
status = AudioDeviceStart(outputDeviceID, audioDeviceIOProc);
if (status) {
Com_Printf("AudioDeviceStart: returned %d\n", status);
return qfalse;
}
s_isRunning = qtrue;
return qtrue;
}
/*
===============
SNDDMA_GetBufferDuration
===============
*/
float SNDDMA_GetBufferDuration(void)
{
return (float)dma.samples / (float)(dma.channels * dma.speed);
}
/*
===============
SNDDMA_GetDMAPos
===============
*/
int SNDDMA_GetDMAPos(void)
{
return s_chunkCount * dma.submission_chunk;
}
/*
===============
SNDDMA_Shutdown
===============
*/
void SNDDMA_Shutdown(void)
{
OSStatus status;
if (!s_isRunning)
return;
status = AudioDeviceStop(outputDeviceID, audioDeviceIOProc);
if (status) {
Com_Printf("AudioDeviceStop: returned %d\n", status);
return;
}
s_isRunning = qfalse;
status = AudioDeviceRemoveIOProc(outputDeviceID, audioDeviceIOProc);
if (status) {
Com_Printf("AudioDeviceRemoveIOProc: returned %d\n", status);
return;
}
free(s_mixedSamples);
s_mixedSamples = NULL;
dma.samples = NULL;
}
/*
===============
SNDDMA_BeginPainting
===============
*/
void SNDDMA_BeginPainting(void) {
}
/*
===============
SNDDMA_Submit
===============
*/
void SNDDMA_Submit(void) {
}

View File

@ -1,205 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// mac_snddma.c
// all other sound mixing is portable
#include "../client/snd_local.h"
#include <Carbon/Carbon.h>
// For 'ri'
#include "../renderer/tr_local.h"
#import <Foundation/NSZone.h>
// TJW - Different versions of SoundManager have different DMA buffer sizes. On MacOS X DP2,
// the buffer size is 8K. On MacOS 9 it is much smaller. The SoundManager guy at Apple says
// that the size of the buffer will be decreasing for final release to help get rid of latency.
//#define MAX_MIXED_SAMPLES (0x8000 * 64)
//#define SUBMISSION_CHUNK (0x100 * 64)
// Original MacOS 9 sizes
//#define MAX_MIXED_SAMPLES 0x8000
//#define SUBMISSION_CHUNK 0x100
static unsigned int submissionChunk;
static unsigned int maxMixedSamples;
static short *s_mixedSamples;
static int s_chunkCount; // number of chunks submitted
static SndChannel *s_sndChan;
static ExtSoundHeader s_sndHeader;
/*
===============
S_Callback
===============
*/
void S_Callback( SndChannel *sc, SndCommand *cmd )
{
SndCommand mySndCmd;
SndCommand mySndCmd2;
int offset;
offset = ( s_chunkCount * submissionChunk ) & (maxMixedSamples-1);
// queue up another sound buffer
memset( &s_sndHeader, 0, sizeof( s_sndHeader ) );
s_sndHeader.samplePtr = (void *)(s_mixedSamples + offset);
s_sndHeader.numChannels = 2;
s_sndHeader.sampleRate = rate22khz;
s_sndHeader.loopStart = 0;
s_sndHeader.loopEnd = 0;
s_sndHeader.encode = extSH;
s_sndHeader.baseFrequency = 1;
s_sndHeader.numFrames = submissionChunk / 2;
s_sndHeader.markerChunk = NULL;
s_sndHeader.instrumentChunks = NULL;
s_sndHeader.AESRecording = NULL;
s_sndHeader.sampleSize = 16;
mySndCmd.cmd = bufferCmd;
mySndCmd.param1 = 0;
mySndCmd.param2 = (int)&s_sndHeader;
SndDoCommand( sc, &mySndCmd, true );
// and another callback
mySndCmd2.cmd = callBackCmd;
mySndCmd2.param1 = 0;
mySndCmd2.param2 = 0;
SndDoCommand( sc, &mySndCmd2, true );
s_chunkCount++; // this is the next buffer we will submit
}
/*
===============
S_MakeTestPattern
===============
*/
void S_MakeTestPattern( void ) {
int i;
float v;
int sample;
for ( i = 0 ; i < dma.samples / 2 ; i ++ ) {
v = sin( M_PI * 2 * i / 64 );
sample = v * 0x4000;
((short *)dma.buffer)[i*2] = sample;
((short *)dma.buffer)[i*2+1] = sample;
}
}
/*
===============
SNDDMA_Init
===============
*/
qboolean SNDDMA_Init(void)
{
int err;
cvar_t *bufferSize;
cvar_t *chunkSize;
chunkSize = ri.Cvar_Get( "s_chunksize", "8192", CVAR_ARCHIVE );
bufferSize = ri.Cvar_Get( "s_buffersize", "65536", CVAR_ARCHIVE );
if (!chunkSize->integer) {
ri.Error(ERR_FATAL, "snd_chunkSize must be non-zero\n");
}
if (!bufferSize->integer) {
ri.Error(ERR_FATAL, "snd_bufferSize must be non-zero\n");
}
if (chunkSize->integer >= bufferSize->integer) {
ri.Error(ERR_FATAL, "snd_chunkSize must be less than snd_bufferSize\n");
}
if (bufferSize->integer % chunkSize->integer) {
ri.Error(ERR_FATAL, "snd_bufferSize must be an even multiple of snd_chunkSize\n");
}
// create a sound channel
s_sndChan = NULL;
err = SndNewChannel( &s_sndChan, sampledSynth, initStereo, NewSndCallBackProc(S_Callback) );
if ( err ) {
return false;
}
submissionChunk = chunkSize->integer;
maxMixedSamples = bufferSize->integer;
s_mixedSamples = NSZoneMalloc(NULL, sizeof(*s_mixedSamples) * maxMixedSamples);
dma.channels = 2;
dma.samples = maxMixedSamples;
dma.submission_chunk = submissionChunk;
dma.samplebits = 16;
dma.speed = 22050;
dma.buffer = (byte *)s_mixedSamples;
// que up the first submission-chunk sized buffer
s_chunkCount = 0;
S_Callback( s_sndChan, NULL );
return qtrue;
}
/*
===============
SNDDMA_GetDMAPos
===============
*/
int SNDDMA_GetDMAPos(void) {
return s_chunkCount * submissionChunk;
}
/*
===============
SNDDMA_Shutdown
===============
*/
void SNDDMA_Shutdown(void) {
if ( s_sndChan ) {
SndDisposeChannel( s_sndChan, true );
s_sndChan = NULL;
}
}
/*
===============
SNDDMA_BeginPainting
===============
*/
void SNDDMA_BeginPainting(void) {
}
/*
===============
SNDDMA_Submit
===============
*/
void SNDDMA_Submit(void) {
}

View File

@ -1,537 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#import "../client/client.h"
#import "macosx_local.h"
#import "dlfcn.h"
#import "Q3Controller.h"
#import <AppKit/AppKit.h>
#import <IOKit/IOKitLib.h>
#import <IOKit/IOBSD.h>
#import <IOKit/storage/IOCDMedia.h>
#import <mach/mach_error.h>
#import <sys/types.h>
#import <unistd.h>
#import <sys/param.h>
#import <sys/mount.h>
#import <sys/sysctl.h>
#ifdef OMNI_TIMER
#import "macosx_timers.h"
#endif
qboolean stdin_active = qfalse;
//===========================================================================
int main(int argc, const char *argv[]) {
#ifdef DEDICATED
Q3Controller *controller;
stdin_active = qtrue;
controller = [[Q3Controller alloc] init];
[controller quakeMain];
return 0;
#else
return NSApplicationMain(argc, argv);
#endif
}
//===========================================================================
/*
=================
Sys_UnloadDll
=================
*/
void Sys_UnloadDll( void *dllHandle ) {
if ( !dllHandle ) {
return;
}
dlclose( dllHandle );
}
/*
=================
Sys_LoadDll
Used to load a development dll instead of a virtual machine
=================
*/
extern char *FS_BuildOSPath( const char *base, const char *game, const char *qpath );
void * QDECL Sys_LoadDll( const char *name, char *fqpath , long (QDECL **entryPoint)(long, ...),
long (QDECL *systemcalls)(long, ...) ) {
void *libHandle;
void (*dllEntry)( long (*syscallptr)(long, ...) );
NSString *libraryPath;
const char *path;
// TTimo
// I don't understand the search strategy here. How can the Quake3 bundle know about the location
// of the other bundles? is that configured somewhere in XCode?
/*
bundlePath = [[NSBundle mainBundle] pathForResource: [NSString stringWithCString: name] ofType: @"bundle"];
libraryPath = [NSString stringWithFormat: @"%@/Contents/MacOS/%s", bundlePath, name];
*/
libraryPath = [NSString stringWithFormat: @"%s.bundle/Contents/MacOS/%s", name, name];
if (!libraryPath)
return NULL;
path = [libraryPath cString];
Com_Printf("Loading '%s'.\n", path);
libHandle = dlopen( [libraryPath cString], RTLD_LAZY );
if (!libHandle) {
libHandle = dlopen( name, RTLD_LAZY );
if (!libHandle) {
Com_Printf("Error loading dll: %s\n", dlerror());
return NULL;
}
}
dllEntry = dlsym( libHandle, "_dllEntry" );
if (!dllEntry) {
Com_Printf("Error loading dll: No dllEntry symbol.\n");
dlclose(libHandle);
return NULL;
}
*entryPoint = dlsym( libHandle, "_vmMain" );
if (!*entryPoint) {
Com_Printf("Error loading dll: No vmMain symbol.\n");
dlclose(libHandle);
return NULL;
}
dllEntry(systemcalls);
return libHandle;
}
//===========================================================================
char *Sys_GetClipboardData(void) // FIXME
{
NSPasteboard *pasteboard;
NSArray *pasteboardTypes;
pasteboard = [NSPasteboard generalPasteboard];
pasteboardTypes = [pasteboard types];
if ([pasteboardTypes containsObject:NSStringPboardType]) {
NSString *clipboardString;
clipboardString = [pasteboard stringForType:NSStringPboardType];
if (clipboardString && [clipboardString length] > 0) {
return strdup([clipboardString cString]);
}
}
return NULL;
}
char *Sys_GetWholeClipboard ( void )
{
return NULL;
}
void Sys_SetClipboard (const char *contents)
{
}
/*
==================
Sys_FunctionCheckSum
==================
*/
int Sys_FunctionCheckSum(void *f1) {
return 0;
}
/*
==================
Sys_MonkeyShouldBeSpanked
==================
*/
int Sys_MonkeyShouldBeSpanked( void ) {
return 0;
}
//===========================================================================
void Sys_BeginProfiling(void)
{
}
void Sys_EndProfiling(void)
{
}
//===========================================================================
/*
================
Sys_Init
The cvar and file system has been setup, so configurations are loaded
================
*/
void Sys_Init(void)
{
#ifdef OMNI_TIMER
InitializeTimers();
OTStackPushRoot(rootNode);
#endif
NET_Init();
Sys_InitInput();
}
/*
=================
Sys_Shutdown
=================
*/
void Sys_Shutdown(void)
{
Com_Printf( "----- Sys_Shutdown -----\n" );
Sys_EndProfiling();
Sys_ShutdownInput();
Com_Printf( "------------------------\n" );
}
void Sys_Error(const char *error, ...)
{
va_list argptr;
NSString *formattedString;
Sys_Shutdown();
va_start(argptr,error);
formattedString = [[NSString alloc] initWithFormat:[NSString stringWithCString:error] arguments:argptr];
va_end(argptr);
NSLog(@"Sys_Error: %@", formattedString);
NSRunAlertPanel(@"Quake 3 Error", formattedString, nil, nil, nil);
Sys_Quit();
}
void Sys_Quit(void)
{
Sys_Shutdown();
[NSApp terminate:nil];
}
/*
================
Sys_Print
This is called for all console output, even if the game is running
full screen and the dedicated console window is hidden.
================
*/
char *ansiColors[8] =
{ "\033[30m" , /* ANSI Black */
"\033[31m" , /* ANSI Red */
"\033[32m" , /* ANSI Green */
"\033[33m" , /* ANSI Yellow */
"\033[34m" , /* ANSI Blue */
"\033[36m" , /* ANSI Cyan */
"\033[35m" , /* ANSI Magenta */
"\033[37m" }; /* ANSI White */
void Sys_Print(const char *text)
{
#if 0
/* Okay, this is a stupid hack, but what the hell, I was bored. ;) */
const char *scan = text;
int index;
/* Make sure terminal mode is reset at the start of the line... */
fputs("\033[0m", stdout);
while(*scan) {
/* See if we have a color control code. If so, snarf the character,
print what we have so far, print the ANSI Terminal color code,
skip over the color control code and continue */
if(Q_IsColorString(scan)) {
index = ColorIndex(scan[1]);
/* Flush current message */
if(scan != text) {
fwrite(text, scan - text, 1, stdout);
}
/* Write ANSI color code */
fputs(ansiColors[index], stdout);
/* Reset search */
text = scan+2;
scan = text;
continue;
}
scan++;
}
/* Flush whatever's left */
fputs(text, stdout);
/* Make sure terminal mode is reset at the end of the line too... */
fputs("\033[0m", stdout);
#else
fputs(text, stdout);
#endif
}
/*
================
Sys_CheckCD
Return true if the proper CD is in the drive
================
*/
qboolean Sys_ObjectIsCDRomDevice(io_object_t object)
{
CFStringRef value;
kern_return_t krc;
CFMutableDictionaryRef properties;
qboolean isCDROM = qfalse;
io_iterator_t parentIterator;
io_object_t parent;
krc = IORegistryEntryCreateCFProperties(object, &properties, kCFAllocatorDefault, (IOOptionBits)0);
if (krc != KERN_SUCCESS) {
fprintf(stderr, "IORegistryEntryCreateCFProperties returned 0x%08x -- %s\n", krc, mach_error_string(krc));
return qfalse;
}
//NSLog(@"properties = %@", properties);
// See if this is a CD-ROM
value = CFDictionaryGetValue(properties, CFSTR(kIOCDMediaTypeKey));
if (value && CFStringCompare(value, CFSTR("CD-ROM"), 0) == kCFCompareEqualTo)
isCDROM = qtrue;
CFRelease(properties);
// If it isn't check each of its parents. It seems that the parent enumerator only returns the immediate parent. Maybe the plural indicates that an object can have multiple direct parents. So, we'll call ourselves recursively for each parent.
if (!isCDROM) {
krc = IORegistryEntryGetParentIterator(object, kIOServicePlane, &parentIterator);
if (krc != KERN_SUCCESS) {
fprintf(stderr, "IOServiceGetMatchingServices returned 0x%08x -- %s\n",
krc, mach_error_string(krc));
} else {
while (!isCDROM && (parent = IOIteratorNext(parentIterator))) {
if (Sys_ObjectIsCDRomDevice(parent))
isCDROM = qtrue;
IOObjectRelease(parent);
}
IOObjectRelease(parentIterator);
}
}
//NSLog(@"Sys_ObjectIsCDRomDevice -> %d", isCDROM);
return isCDROM;
}
qboolean Sys_IsCDROMDevice(const char *deviceName)
{
kern_return_t krc;
io_iterator_t deviceIterator;
mach_port_t masterPort;
io_object_t object;
qboolean isCDROM = qfalse;
krc = IOMasterPort(bootstrap_port, &masterPort);
if (krc != KERN_SUCCESS) {
fprintf(stderr, "IOMasterPort returned 0x%08x -- %s\n", krc, mach_error_string(krc));
return qfalse;
}
// Get an iterator for this BSD device. If it is a CD, it will likely only be one partition of the larger CD-ROM device.
krc = IOServiceGetMatchingServices(masterPort,
IOBSDNameMatching(masterPort, 0, deviceName),
&deviceIterator);
if (krc != KERN_SUCCESS) {
fprintf(stderr, "IOServiceGetMatchingServices returned 0x%08x -- %s\n",
krc, mach_error_string(krc));
return qfalse;
}
while (!isCDROM && (object = IOIteratorNext(deviceIterator))) {
if (Sys_ObjectIsCDRomDevice(object)) {
isCDROM = qtrue;
}
IOObjectRelease(object);
}
IOObjectRelease(deviceIterator);
//NSLog(@"Sys_IsCDROMDevice -> %d", isCDROM);
return isCDROM;
}
qboolean Sys_CheckCD( void )
{
// DO NOT just return success here if we have a library directory.
// Actually look for the CD.
// We'll look through the actual mount points rather than just looking
// for a particular directory since (a) the mount point may change
// between OS version (/foo in Public Beta, /Volumes/foo after Public Beta)
// and (b) this way someone can't just create a directory and warez the files.
unsigned int mountCount;
struct statfs *mounts;
mountCount = getmntinfo(&mounts, MNT_NOWAIT);
if (mountCount <= 0) {
perror("getmntinfo");
#if 1 // Q3:TA doesn't need a CD, but we still need to locate it to allow for partial installs
return qtrue;
#else
return qfalse;
#endif
}
while (mountCount--) {
const char *lastComponent;
if ((mounts[mountCount].f_flags & MNT_RDONLY) != MNT_RDONLY) {
// Should have been a read only CD... this isn't it
continue;
}
if ((mounts[mountCount].f_flags & MNT_LOCAL) != MNT_LOCAL) {
// Should have been a local filesystem
continue;
}
lastComponent = strrchr(mounts[mountCount].f_mntonname, '/');
if (!lastComponent) {
// No slash in the mount point! How is that possible?
continue;
}
// Skip the slash and look for the game name
lastComponent++;
if ((strcasecmp(lastComponent, "Quake3") != 0)) {
continue;
}
#if 0
fprintf(stderr, "f_bsize: %d\n", mounts[mountCount].f_bsize);
fprintf(stderr, "f_blocks: %d\n", mounts[mountCount].f_blocks);
fprintf(stderr, "type: %d\n", mounts[mountCount].f_type);
fprintf(stderr, "flags: %d\n", mounts[mountCount].f_flags);
fprintf(stderr, "fstype: %s\n", mounts[mountCount].f_fstypename);
fprintf(stderr, "f_mntonname: %s\n", mounts[mountCount].f_mntonname);
fprintf(stderr, "f_mntfromname: %s\n", mounts[mountCount].f_mntfromname);
fprintf(stderr, "\n\n");
#endif
lastComponent = strrchr(mounts[mountCount].f_mntfromname, '/');
if (!lastComponent) {
// No slash in the device name! How is that possible?
continue;
}
lastComponent++;
if (!Sys_IsCDROMDevice(lastComponent))
continue;
// This looks good
Sys_SetDefaultCDPath(mounts[mountCount].f_mntonname);
return qtrue;
}
#if 1 // Q3:TA doesn't need a CD, but we still need to locate it to allow for partial installs
return qtrue;
#else
return qfalse;
#endif
}
//===================================================================
void Sys_BeginStreamedFile( fileHandle_t f, int readAhead ) {
}
void Sys_EndStreamedFile( fileHandle_t f ) {
}
int Sys_StreamedRead( void *buffer, int size, int count, fileHandle_t f ) {
return FS_Read( buffer, size * count, f );
}
void Sys_StreamSeek( fileHandle_t f, int offset, int origin ) {
FS_Seek( f, offset, origin );
}
void OutputDebugString(char * s)
{
#ifdef DEBUG
fprintf(stderr, "%s", s);
#endif
}
/*
==================
Sys_LowPhysicalMemory()
==================
*/
#define MEM_THRESHOLD 96*1024*1024
qboolean Sys_LowPhysicalMemory()
{
return NSRealMemoryAvailable() <= MEM_THRESHOLD;
}
static unsigned int _Sys_ProcessorCount = 0;
unsigned int Sys_ProcessorCount()
{
if (!_Sys_ProcessorCount) {
int name[] = {CTL_HW, HW_NCPU};
size_t size;
size = sizeof(_Sys_ProcessorCount);
if (sysctl(name, 2, &_Sys_ProcessorCount, &size, NULL, 0) < 0) {
perror("sysctl");
_Sys_ProcessorCount = 1;
} else {
Com_Printf("System processor count is %d\n", _Sys_ProcessorCount);
}
}
return _Sys_ProcessorCount;
}

View File

@ -1,56 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifdef OMNI_TIMER
#import <OmniTimer/OmniTimer.h>
#define OTSTART(node) OTStackPush(node)
#define OTSTOP(node) OTStackPop()
extern OTStackNode *rootNode;
extern OTStackNode *markFragmentsNode1;
extern OTStackNode *markFragmentsNode2;
extern OTStackNode *markFragmentsGrid;
extern OTStackNode *markFragmentsNode4;
extern OTStackNode *addMarkFragmentsNode;
extern OTStackNode *chopPolyNode;
extern OTStackNode *boxTraceNode;
extern OTStackNode *boxOnPlaneSideNode;
extern OTStackNode *recursiveWorldNode;
extern OTStackNode *surfaceAnimNode;
extern OTStackNode *surfaceFaceNode;
extern OTStackNode *surfaceMeshNode;
extern OTStackNode *surfaceEndNode;
extern OTStackNode *shadowEndNode;
extern OTStackNode *stageIteratorGenericNode;
extern OTStackNode *computeColorAndTexNode;
extern OTStackNode *mp3DecodeNode;
extern void InitializeTimers();
#else
#define OTSTART(node)
#define OTSTOP(node)
#endif

View File

@ -1,75 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifdef OMNI_TIMER
#import "macosx_timers.h"
#import <Foundation/NSString.h>
#import <stdio.h>
OTStackNode *rootNode;
OTStackNode *markFragmentsNode1;
OTStackNode *markFragmentsNode2;
OTStackNode *markFragmentsGrid;
OTStackNode *markFragmentsNode4;
OTStackNode *addMarkFragmentsNode;
OTStackNode *chopPolyNode;
OTStackNode *boxTraceNode;
OTStackNode *boxOnPlaneSideNode;
OTStackNode *recursiveWorldNode;
OTStackNode *surfaceAnimNode;
OTStackNode *surfaceFaceNode;
OTStackNode *surfaceMeshNode;
OTStackNode *surfaceEndNode;
OTStackNode *shadowEndNode;
OTStackNode *stageIteratorGenericNode;
OTStackNode *computeColorAndTexNode;
OTStackNode *mp3DecodeNode;
void InitializeTimers()
{
const char *env;
OTSetup();
rootNode = OTStackNodeCreate("root");
markFragmentsNode1 = OTStackNodeCreate("R_MarkFragments 1");
markFragmentsNode2 = OTStackNodeCreate("R_MarkFragments 2");
markFragmentsGrid = OTStackNodeCreate("R_MarkFragmentsGrid");
markFragmentsNode4 = OTStackNodeCreate("R_MarkFragments 4");
addMarkFragmentsNode = OTStackNodeCreate("R_AddMarkFragments");
chopPolyNode = OTStackNodeCreate("R_ChopPolyBehindPlane");
boxTraceNode = OTStackNodeCreate("CM_BoxTrace");
boxOnPlaneSideNode = OTStackNodeCreate("BoxOnPlaneSide");
recursiveWorldNode = OTStackNodeCreate("R_RecursiveWorldNode");
surfaceAnimNode = OTStackNodeCreate("RB_SurfaceAnim");
surfaceFaceNode = OTStackNodeCreate("RB_SurfaceFace");
surfaceMeshNode = OTStackNodeCreate("RB_SurfaceMesh");
surfaceEndNode = OTStackNodeCreate("RB_EndSurface");
shadowEndNode = OTStackNodeCreate("RB_ShadowTessEnd");
stageIteratorGenericNode = OTStackNodeCreate("RB_StageIteratorGeneric");
computeColorAndTexNode = OTStackNodeCreate("ComputeColors & ComputeTexCoords");
mp3DecodeNode = OTStackNodeCreate("MP3Stream_Decode");
}
#endif // OMNI_TIMER

View File

@ -1,26 +0,0 @@
#!/bin/zsh
buildRoot=./build
executable=$buildRoot/Quake3.app/Contents/MacOS/Quake3
ls -l $executable
flags="$flags +set timedemo 1"
flags="$flags +set s_initsound 0"
flags="$flags +set vm_cgame 1"
flags="$flags +set vm_game 1"
flags="$flags +set r_texturebits 16"
flags="$flags +set r_depthbits 16"
flags="$flags +set r_colorbits 16"
flags="$flags +set stencilbits 8"
flags="$flags +set r_appleTransformHint 1"
echo flags=$flags
function demo {
echo Demo $*
$executable $flags +demo $* |& egrep "(seconds|VM)"
}
demo foo

View File

@ -66,6 +66,7 @@ cvar_t *com_fixedtime;
cvar_t *com_dropsim; // 0.0 to 1.0, simulated packet drops
cvar_t *com_journal;
cvar_t *com_maxfps;
cvar_t *com_altivec;
cvar_t *com_timedemo;
cvar_t *com_sv_running;
cvar_t *com_cl_running;
@ -2425,6 +2426,7 @@ void Com_Init( char *commandLine ) {
//
// init commands and vars
//
com_altivec = Cvar_Get ("com_altivec", "1", CVAR_ARCHIVE);
com_maxfps = Cvar_Get ("com_maxfps", "85", CVAR_ARCHIVE);
com_blood = Cvar_Get ("com_blood", "1", CVAR_ARCHIVE);
@ -2507,7 +2509,12 @@ void Com_Init( char *commandLine ) {
Cvar_Set("ui_singlePlayerActive", "0");
com_fullyInitialized = qtrue;
Com_Printf ("--- Common Initialization Complete ---\n");
#if idppc_altivec
Com_Printf ("Altivec support is %s\n", com_altivec->integer ? "enabled" : "disabled");
#endif
Com_Printf ("--- Common Initialization Complete ---\n");
}
//==================================================================

View File

@ -51,6 +51,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define idppc_altivec 0
#endif
#if (MACOS_X) // Apple's GCC does this differently than the FSF.
#define VECCONST_UINT8(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) (vector unsigned char) (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)
#else
#define VECCONST_UINT8(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) (vector unsigned char) {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p}
#endif
#endif
#ifndef __ASM_I386__ // don't include the C bits if included from qasm.h

View File

@ -1820,7 +1820,7 @@ asm (
#if defined(MACOS_X) && defined(__OPTIMIZE__)
// On Mac OS X, gcc doesn't push a frame when we are optimized, so trying to tear it down results in grave disorder.
#warning Mac OS X optimization on, not popping GCC AsmCall frame
//#warning Mac OS X optimization on, not popping GCC AsmCall frame
#else
// Mac OS X Server and unoptimized compiles include a GCC AsmCall frame
asm (

View File

@ -46,7 +46,22 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#elif defined(MACOS_X)
#include "macosx_glimp.h"
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#ifndef GL_EXT_abgr
#include <OpenGL/glext.h>
#endif
// This can be defined to use the CGLMacro.h support which avoids looking up
// the current context.
//#define USE_CGLMACROS
#ifdef USE_CGLMACROS
#include "macosx_local.h"
#define cgl_ctx glw_state._cgl_ctx
#include <OpenGL/CGLMacro.h>
#endif
#elif defined( __linux__ ) || defined(__FreeBSD__)
@ -164,7 +179,7 @@ extern void ( APIENTRY * qglUnlockArraysEXT) (void);
#include "qgl_linked.h"
#elif defined(MACOS_X)
#elif (defined(MACOS_X) && !defined(USE_SDL_VIDEO))
// This includes #ifdefs for optional logging and GL error checking after every GL call as well as #defines to prevent incorrect usage of the non-'qgl' versions of the GL API.
#include "macosx_qgl.h"

View File

@ -113,7 +113,7 @@ static void MakeMeshNormals( int width, int height, drawVert_t ctrl[MAX_GRID_SIZ
int i, j, k, dist;
vec3_t normal;
vec3_t sum;
int count;
int count = 0;
vec3_t base;
vec3_t delta;
int x, y;

View File

@ -150,12 +150,15 @@ int max_polys;
cvar_t *r_maxpolyverts;
int max_polyverts;
/* !!! FIXME: Why are these here?! */
#if 0
void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t );
void ( APIENTRY * qglActiveTextureARB )( GLenum texture );
void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
void ( APIENTRY * qglLockArraysEXT)( GLint, GLint);
void ( APIENTRY * qglUnlockArraysEXT) ( void );
#endif
static void AssertCvarRange( cvar_t *cv, float minVal, float maxVal, qboolean shouldBeIntegral )
{

View File

@ -402,9 +402,9 @@ ProjectDlightTexture
Perform dynamic lighting with another rendering pass
===================
*/
static void ProjectDlightTexture( void ) {
int i, l;
#if idppc_altivec
static void ProjectDlightTexture_altivec( void ) {
int i, l;
vec_t origin0, origin1, origin2;
float texCoords0, texCoords1;
vector float floatColorVec0, floatColorVec1;
@ -412,13 +412,10 @@ static void ProjectDlightTexture( void ) {
vector short colorShort;
vector signed int colorInt;
vector unsigned char floatColorVecPerm, modulatePerm, colorChar;
vector unsigned char vSel = (vector unsigned char){0x00, 0x00, 0x00, 0xff,
0x00, 0x00, 0x00, 0xff,
0x00, 0x00, 0x00, 0xff,
0x00, 0x00, 0x00, 0xff};
#else
vec3_t origin;
#endif
vector unsigned char vSel = VECCONST_UINT8(0x00, 0x00, 0x00, 0xff,
0x00, 0x00, 0x00, 0xff,
0x00, 0x00, 0x00, 0xff,
0x00, 0x00, 0x00, 0xff);
float *texCoords;
byte *colors;
byte clipBits[SHADER_MAX_VERTEXES];
@ -429,20 +426,18 @@ static void ProjectDlightTexture( void ) {
float scale;
float radius;
vec3_t floatColor;
float modulate;
float modulate = 0.0f;
if ( !backEnd.refdef.num_dlights ) {
return;
}
#if idppc_altivec
// There has to be a better way to do this so that floatColor
// There has to be a better way to do this so that floatColor
// and/or modulate are already 16-byte aligned.
floatColorVecPerm = vec_lvsl(0,(float *)floatColor);
modulatePerm = vec_lvsl(0,(float *)&modulate);
modulatePerm = (vector unsigned char)vec_splat((vector unsigned int)modulatePerm,0);
zero = (vector float)vec_splat_s8(0);
#endif
for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) {
dlight_t *dl;
@ -454,27 +449,20 @@ static void ProjectDlightTexture( void ) {
colors = colorArray[0];
dl = &backEnd.refdef.dlights[l];
#if idppc_altivec
origin0 = dl->transformed[0];
origin1 = dl->transformed[1];
origin2 = dl->transformed[2];
#else
VectorCopy( dl->transformed, origin );
#endif
radius = dl->radius;
scale = 1.0f / radius;
floatColor[0] = dl->color[0] * 255.0f;
floatColor[1] = dl->color[1] * 255.0f;
floatColor[2] = dl->color[2] * 255.0f;
#if idppc_altivec
floatColorVec0 = vec_ld(0, floatColor);
floatColorVec1 = vec_ld(11, floatColor);
floatColorVec0 = vec_perm(floatColorVec0,floatColorVec0,floatColorVecPerm);
#endif
for ( i = 0 ; i < tess.numVertexes ; i++, texCoords += 2, colors += 4 ) {
int clip = 0;
#if idppc_altivec
#define DIST0 dist0
#define DIST1 dist1
#define DIST2 dist2
@ -485,16 +473,6 @@ static void ProjectDlightTexture( void ) {
dist0 = origin0 - tess.xyz[i][0];
dist1 = origin1 - tess.xyz[i][1];
dist2 = origin2 - tess.xyz[i][2];
#else
#define DIST0 dist[0]
#define DIST1 dist[1]
#define DIST2 dist[2]
#define TEXCOORDS0 texCoords[0]
#define TEXCOORDS1 texCoords[1]
vec3_t dist;
VectorSubtract( origin, tess.xyz[i], dist );
#endif
backEnd.pc.c_dlightVertexes++;
@ -539,7 +517,6 @@ static void ProjectDlightTexture( void ) {
}
clipBits[i] = clip;
#if idppc_altivec
modulateVec = vec_ld(0,(float *)&modulate);
modulateVec = vec_perm(modulateVec,modulateVec,modulatePerm);
colorVec = vec_madd(floatColorVec0,modulateVec,zero);
@ -548,12 +525,6 @@ static void ProjectDlightTexture( void ) {
colorChar = vec_packsu(colorShort,colorShort); // RGBxRGBxRGBxRGBx
colorChar = vec_sel(colorChar,vSel,vSel); // RGBARGBARGBARGBA replace alpha with 255
vec_ste((vector unsigned int)colorChar,0,(unsigned int *)colors); // store color
#else
colors[0] = myftol(floatColor[0] * modulate);
colors[1] = myftol(floatColor[1] * modulate);
colors[2] = myftol(floatColor[2] * modulate);
colors[3] = 255;
#endif
}
#undef DIST0
#undef DIST1
@ -602,6 +573,162 @@ static void ProjectDlightTexture( void ) {
backEnd.pc.c_dlightIndexes += numIndexes;
}
}
#endif
static void ProjectDlightTexture_scalar( void ) {
int i, l;
vec3_t origin;
float *texCoords;
byte *colors;
byte clipBits[SHADER_MAX_VERTEXES];
float texCoordsArray[SHADER_MAX_VERTEXES][2];
byte colorArray[SHADER_MAX_VERTEXES][4];
unsigned hitIndexes[SHADER_MAX_INDEXES];
int numIndexes;
float scale;
float radius;
vec3_t floatColor;
float modulate = 0.0f;
if ( !backEnd.refdef.num_dlights ) {
return;
}
for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) {
dlight_t *dl;
if ( !( tess.dlightBits & ( 1 << l ) ) ) {
continue; // this surface definately doesn't have any of this light
}
texCoords = texCoordsArray[0];
colors = colorArray[0];
dl = &backEnd.refdef.dlights[l];
VectorCopy( dl->transformed, origin );
radius = dl->radius;
scale = 1.0f / radius;
floatColor[0] = dl->color[0] * 255.0f;
floatColor[1] = dl->color[1] * 255.0f;
floatColor[2] = dl->color[2] * 255.0f;
for ( i = 0 ; i < tess.numVertexes ; i++, texCoords += 2, colors += 4 ) {
int clip = 0;
#define DIST0 dist[0]
#define DIST1 dist[1]
#define DIST2 dist[2]
#define TEXCOORDS0 texCoords[0]
#define TEXCOORDS1 texCoords[1]
vec3_t dist;
VectorSubtract( origin, tess.xyz[i], dist );
backEnd.pc.c_dlightVertexes++;
TEXCOORDS0 = 0.5f + DIST0 * scale;
TEXCOORDS1 = 0.5f + DIST1 * scale;
if( !r_dlightBacks->integer &&
// dist . tess.normal[i]
( DIST0 * tess.normal[i][0] +
DIST1 * tess.normal[i][1] +
DIST2 * tess.normal[i][2] ) < 0.0f ) {
clip = 63;
} else {
if ( TEXCOORDS0 < 0.0f ) {
clip |= 1;
} else if ( TEXCOORDS0 > 1.0f ) {
clip |= 2;
}
if ( TEXCOORDS1 < 0.0f ) {
clip |= 4;
} else if ( TEXCOORDS1 > 1.0f ) {
clip |= 8;
}
texCoords[0] = TEXCOORDS0;
texCoords[1] = TEXCOORDS1;
// modulate the strength based on the height and color
if ( DIST2 > radius ) {
clip |= 16;
modulate = 0.0f;
} else if ( DIST2 < -radius ) {
clip |= 32;
modulate = 0.0f;
} else {
DIST2 = Q_fabs(DIST2);
if ( DIST2 < radius * 0.5f ) {
modulate = 1.0f;
} else {
modulate = 2.0f * (radius - DIST2) * scale;
}
}
}
clipBits[i] = clip;
colors[0] = myftol(floatColor[0] * modulate);
colors[1] = myftol(floatColor[1] * modulate);
colors[2] = myftol(floatColor[2] * modulate);
colors[3] = 255;
}
#undef DIST0
#undef DIST1
#undef DIST2
#undef TEXCOORDS0
#undef TEXCOORDS1
// build a list of triangles that need light
numIndexes = 0;
for ( i = 0 ; i < tess.numIndexes ; i += 3 ) {
int a, b, c;
a = tess.indexes[i];
b = tess.indexes[i+1];
c = tess.indexes[i+2];
if ( clipBits[a] & clipBits[b] & clipBits[c] ) {
continue; // not lighted
}
hitIndexes[numIndexes] = a;
hitIndexes[numIndexes+1] = b;
hitIndexes[numIndexes+2] = c;
numIndexes += 3;
}
if ( !numIndexes ) {
continue;
}
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
qglTexCoordPointer( 2, GL_FLOAT, 0, texCoordsArray[0] );
qglEnableClientState( GL_COLOR_ARRAY );
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorArray );
GL_Bind( tr.dlightImage );
// include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light
// where they aren't rendered
if ( dl->additive ) {
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
}
else {
GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
}
R_DrawElements( numIndexes, hitIndexes );
backEnd.pc.c_totalIndexes += numIndexes;
backEnd.pc.c_dlightIndexes += numIndexes;
}
}
static void ProjectDlightTexture( void ) {
#if idppc_altivec
extern cvar_t *com_altivec;
if (com_altivec->integer) {
// must be in a seperate function or G3 systems will crash.
ProjectDlightTexture_altivec();
return;
}
#endif
ProjectDlightTexture_scalar();
}
/*

View File

@ -1097,22 +1097,19 @@ void RB_CalcSpecularAlpha( unsigned char *alphas ) {
**
** The basic vertex lighting calc
*/
void RB_CalcDiffuseColor( unsigned char *colors )
#if idppc_altivec
static void RB_CalcDiffuseColor_altivec( unsigned char *colors )
{
int i, j;
int i;
float *v, *normal;
float incoming;
trRefEntity_t *ent;
int ambientLightInt;
vec3_t ambientLight;
vec3_t lightDir;
vec3_t directedLight;
int numVertexes;
#if idppc_altivec
vector unsigned char vSel = (vector unsigned char){0x00, 0x00, 0x00, 0xff,
0x00, 0x00, 0x00, 0xff,
0x00, 0x00, 0x00, 0xff,
0x00, 0x00, 0x00, 0xff};
vector unsigned char vSel = VECCONST_UINT8(0x00, 0x00, 0x00, 0xff,
0x00, 0x00, 0x00, 0xff,
0x00, 0x00, 0x00, 0xff,
0x00, 0x00, 0x00, 0xff);
vector float ambientLightVec;
vector float directedLightVec;
vector float lightDirVec;
@ -1122,10 +1119,8 @@ void RB_CalcDiffuseColor( unsigned char *colors )
vector signed int jVecInt;
vector signed short jVecShort;
vector unsigned char jVecChar, normalPerm;
#endif
ent = backEnd.currentEntity;
ambientLightInt = ent->ambientLightInt;
#if idppc_altivec
// A lot of this could be simplified if we made sure
// entities light info was 16-byte aligned.
jVecChar = vec_lvsl(0, ent->ambientLight);
@ -1145,21 +1140,13 @@ void RB_CalcDiffuseColor( unsigned char *colors )
zero = (vector float)vec_splat_s8(0);
VectorCopy( ent->lightDir, lightDir );
#else
VectorCopy( ent->ambientLight, ambientLight );
VectorCopy( ent->directedLight, directedLight );
VectorCopy( ent->lightDir, lightDir );
#endif
v = tess.xyz[0];
normal = tess.normal[0];
#if idppc_altivec
normalPerm = vec_lvsl(0,normal);
#endif
numVertexes = tess.numVertexes;
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
#if idppc_altivec
normalVec0 = vec_ld(0,(vector float *)normal);
normalVec1 = vec_ld(11,(vector float *)normal);
normalVec0 = vec_perm(normalVec0,normalVec1,normalPerm);
@ -1177,7 +1164,32 @@ void RB_CalcDiffuseColor( unsigned char *colors )
jVecChar = vec_packsu(jVecShort,jVecShort); // RGBxRGBxRGBxRGBx
jVecChar = vec_sel(jVecChar,vSel,vSel); // RGBARGBARGBARGBA replace alpha with 255
vec_ste((vector unsigned int)jVecChar,0,(unsigned int *)&colors[i*4]); // store color
#else
}
}
#endif
static void RB_CalcDiffuseColor_scalar( unsigned char *colors )
{
int i, j;
float *v, *normal;
float incoming;
trRefEntity_t *ent;
int ambientLightInt;
vec3_t ambientLight;
vec3_t lightDir;
vec3_t directedLight;
int numVertexes;
ent = backEnd.currentEntity;
ambientLightInt = ent->ambientLightInt;
VectorCopy( ent->ambientLight, ambientLight );
VectorCopy( ent->directedLight, directedLight );
VectorCopy( ent->lightDir, lightDir );
v = tess.xyz[0];
normal = tess.normal[0];
numVertexes = tess.numVertexes;
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
incoming = DotProduct (normal, lightDir);
if ( incoming <= 0 ) {
*(int *)&colors[i*4] = ambientLightInt;
@ -1202,7 +1214,19 @@ void RB_CalcDiffuseColor( unsigned char *colors )
colors[i*4+2] = j;
colors[i*4+3] = 255;
#endif
}
}
void RB_CalcDiffuseColor( unsigned char *colors )
{
#if idppc_altivec
extern cvar_t *com_altivec;
if (com_altivec->integer) {
// must be in a seperate function or G3 systems will crash.
RB_CalcDiffuseColor_altivec( colors );
return;
}
#endif
RB_CalcDiffuseColor_scalar( colors );
}

View File

@ -610,7 +610,8 @@ static void VectorArrayNormalize(vec4_t *normals, unsigned int count)
/*
** LerpMeshVertexes
*/
static void LerpMeshVertexes (md3Surface_t *surf, float backlerp)
#if idppc_altivec
static void LerpMeshVertexes_altivec(md3Surface_t *surf, float backlerp)
{
short *oldXyz, *newXyz, *oldNormals, *newNormals;
float *outXyz, *outNormal;
@ -633,7 +634,6 @@ static void LerpMeshVertexes (md3Surface_t *surf, float backlerp)
numVerts = surf->numVerts;
if ( backlerp == 0 ) {
#if idppc_altivec
vector signed short newNormalsVec0;
vector signed short newNormalsVec1;
vector signed int newNormalsIntVec;
@ -687,34 +687,6 @@ static void LerpMeshVertexes (md3Surface_t *surf, float backlerp)
vec_ste(newNormalsFloatVec,4,outXyz);
vec_ste(newNormalsFloatVec,8,outXyz);
}
#else
//
// just copy the vertexes
//
for (vertNum=0 ; vertNum < numVerts ; vertNum++,
newXyz += 4, newNormals += 4,
outXyz += 4, outNormal += 4)
{
outXyz[0] = newXyz[0] * newXyzScale;
outXyz[1] = newXyz[1] * newXyzScale;
outXyz[2] = newXyz[2] * newXyzScale;
lat = ( newNormals[0] >> 8 ) & 0xff;
lng = ( newNormals[0] & 0xff );
lat *= (FUNCTABLE_SIZE/256);
lng *= (FUNCTABLE_SIZE/256);
// decode X as cos( lat ) * sin( long )
// decode Y as sin( lat ) * sin( long )
// decode Z as cos( long )
outNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
outNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
outNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
}
#endif
} else {
//
// interpolate and copy the vertex and normal
@ -764,6 +736,132 @@ static void LerpMeshVertexes (md3Surface_t *surf, float backlerp)
VectorArrayNormalize((vec4_t *)tess.normal[tess.numVertexes], numVerts);
}
}
#endif
static void LerpMeshVertexes_scalar(md3Surface_t *surf, float backlerp)
{
short *oldXyz, *newXyz, *oldNormals, *newNormals;
float *outXyz, *outNormal;
float oldXyzScale, newXyzScale;
float oldNormalScale, newNormalScale;
int vertNum;
unsigned lat, lng;
int numVerts;
outXyz = tess.xyz[tess.numVertexes];
outNormal = tess.normal[tess.numVertexes];
newXyz = (short *)((byte *)surf + surf->ofsXyzNormals)
+ (backEnd.currentEntity->e.frame * surf->numVerts * 4);
newNormals = newXyz + 3;
newXyzScale = MD3_XYZ_SCALE * (1.0 - backlerp);
newNormalScale = 1.0 - backlerp;
numVerts = surf->numVerts;
if ( backlerp == 0 ) {
//
// just copy the vertexes
//
for (vertNum=0 ; vertNum < numVerts ; vertNum++,
newXyz += 4, newNormals += 4,
outXyz += 4, outNormal += 4)
{
outXyz[0] = newXyz[0] * newXyzScale;
outXyz[1] = newXyz[1] * newXyzScale;
outXyz[2] = newXyz[2] * newXyzScale;
lat = ( newNormals[0] >> 8 ) & 0xff;
lng = ( newNormals[0] & 0xff );
lat *= (FUNCTABLE_SIZE/256);
lng *= (FUNCTABLE_SIZE/256);
// decode X as cos( lat ) * sin( long )
// decode Y as sin( lat ) * sin( long )
// decode Z as cos( long )
outNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
outNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
outNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
}
} else {
//
// interpolate and copy the vertex and normal
//
oldXyz = (short *)((byte *)surf + surf->ofsXyzNormals)
+ (backEnd.currentEntity->e.oldframe * surf->numVerts * 4);
oldNormals = oldXyz + 3;
oldXyzScale = MD3_XYZ_SCALE * backlerp;
oldNormalScale = backlerp;
for (vertNum=0 ; vertNum < numVerts ; vertNum++,
oldXyz += 4, newXyz += 4, oldNormals += 4, newNormals += 4,
outXyz += 4, outNormal += 4)
{
vec3_t uncompressedOldNormal, uncompressedNewNormal;
// interpolate the xyz
outXyz[0] = oldXyz[0] * oldXyzScale + newXyz[0] * newXyzScale;
outXyz[1] = oldXyz[1] * oldXyzScale + newXyz[1] * newXyzScale;
outXyz[2] = oldXyz[2] * oldXyzScale + newXyz[2] * newXyzScale;
// FIXME: interpolate lat/long instead?
lat = ( newNormals[0] >> 8 ) & 0xff;
lng = ( newNormals[0] & 0xff );
lat *= 4;
lng *= 4;
uncompressedNewNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
uncompressedNewNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
uncompressedNewNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
lat = ( oldNormals[0] >> 8 ) & 0xff;
lng = ( oldNormals[0] & 0xff );
lat *= 4;
lng *= 4;
uncompressedOldNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
uncompressedOldNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
uncompressedOldNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
outNormal[0] = uncompressedOldNormal[0] * oldNormalScale + uncompressedNewNormal[0] * newNormalScale;
outNormal[1] = uncompressedOldNormal[1] * oldNormalScale + uncompressedNewNormal[1] * newNormalScale;
outNormal[2] = uncompressedOldNormal[2] * oldNormalScale + uncompressedNewNormal[2] * newNormalScale;
// VectorNormalize (outNormal);
}
VectorArrayNormalize((vec4_t *)tess.normal[tess.numVertexes], numVerts);
}
}
static void LerpMeshVertexes(md3Surface_t *surf, float backlerp)
{
#if idppc_altivec
// !!! FIXME: figure out what's broken and remove this.
#ifndef NDEBUG
static int already_complained = 0;
if (!already_complained)
{
already_complained = 1;
Com_Printf("WARNING! FIXME! Altivec mesh lerping broken in debug builds!\n");
}
#else
extern cvar_t *com_altivec;
if (com_altivec->integer) {
// must be in a seperate function or G3 systems will crash.
LerpMeshVertexes_altivec( surf, backlerp );
return;
}
#endif
#endif // idppc_altivec
LerpMeshVertexes_scalar( surf, backlerp );
}
/*
=============

View File

@ -218,6 +218,11 @@ typedef struct {
#define _3DFX_DRIVER_NAME "3dfxvgl"
#define OPENGL_DRIVER_NAME "opengl32"
#elif defined(MACOS_X)
#define _3DFX_DRIVER_NAME "libMesaVoodooGL.dylib"
#define OPENGL_DRIVER_NAME "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"
#else
#define _3DFX_DRIVER_NAME "libMesaVoodooGL.so"

View File

@ -16,6 +16,19 @@ endif
CC=gcc
Q3ASM_CFLAGS=-O2 -Wall -Werror -fno-strict-aliasing
ifeq ($(PLATFORM),darwin)
LCC_CFLAGS += -DMACOS_X=1
endif
ifndef USE_CCACHE
USE_CCACHE=0
endif
ifeq ($(USE_CCACHE),1)
CC := ccache $(CC)
CXX := ccache $(CXX)
endif
default: q3asm
q3asm: q3asm.c cmdlib.c

View File

@ -22,6 +22,19 @@ RMDIR=rmdir
BUILDDIR=build
BD=$(BUILDDIR)/
ifeq ($(PLATFORM),darwin)
LCC_CFLAGS += -DMACOS_X=1
endif
ifndef USE_CCACHE
USE_CCACHE=0
endif
ifeq ($(USE_CCACHE),1)
CC := ccache $(CC)
CXX := ccache $(CXX)
endif
ifeq ($(PLATFORM),SunOS)
INSTALL=ginstall
else

View File

@ -13,7 +13,17 @@
PLATFORM=$(shell uname|sed -e s/_.*//|tr A-Z a-z)
PLATFORM_RELEASE=$(shell uname -r)
ARCH:=$(shell uname -m | sed -e s/i.86/i386/)
# Apple does some things a little differently...
ifeq ($(PLATFORM),darwin)
ARCH:= $(shell uname -p | sed -e s/i.86/i386/)
else
ARCH:=$(shell uname -m | sed -e s/i.86/i386/)
endif
ifeq ($(ARCH),powerpc)
ARCH:=ppc
endif
#############################################################################
#
@ -43,6 +53,11 @@ ifndef DXSDK_DIR
DXSDK_DIR=C:/DXSDK
endif
ifndef USE_CCACHE
USE_CCACHE=1
endif
export USE_CCACHE
ifndef USE_SDL
USE_SDL=1
endif
@ -121,7 +136,10 @@ ifeq ($(PLATFORM),linux)
endif
endif
BASE_CFLAGS = -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes
BASE_CFLAGS = -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes -pipe
# Always include debug symbols...you can strip the binary later...
BASE_CFLAGS += -gfull
ifeq ($(USE_OPENAL),1)
BASE_CFLAGS += -DUSE_OPENAL=1
@ -153,6 +171,7 @@ ifeq ($(PLATFORM),linux)
HAVE_VM_COMPILED=true
else
ifeq ($(ARCH),ppc)
BASE_CFLAGS += -maltivec
ifneq ($(VM_PPC),)
HAVE_VM_COMPILED=true
endif
@ -181,8 +200,10 @@ ifeq ($(PLATFORM),linux)
CLIENT_LDFLAGS=-L/usr/X11R6/$(LIB) -lX11 -lXext -lXxf86dga -lXxf86vm
endif
ifneq ($(USE_OPENAL_DLOPEN),1)
CLIENT_LDFLAGS += -lopenal
ifeq ($(USE_OPENAL),1)
ifneq ($(USE_OPENAL_DLOPEN),1)
CLIENT_LDFLAGS += -lopenal
endif
endif
ifeq ($(ARCH),i386)
@ -216,6 +237,106 @@ ifeq ($(PLATFORM),linux)
else # ifeq Linux
#############################################################################
# SETUP AND BUILD -- MAC OS X
#############################################################################
ifeq ($(PLATFORM),darwin)
GLIBC=
CC=gcc
CXX=g++
VM_PPC=vm_ppc_new
BASE_CFLAGS = -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes
BASE_CFLAGS += -DMACOS_X=1 -fno-common -pipe
# Always include debug symbols...you can strip the binary later...
BASE_CFLAGS += -gfull
ifeq ($(USE_OPENAL),1)
BASE_CFLAGS += -DUSE_OPENAL=1
ifeq ($(USE_OPENAL_DLOPEN),1)
BASE_CFLAGS += -DUSE_OPENAL_DLOPEN=1
endif
endif
ifeq ($(USE_SDL),1)
BASE_CFLAGS += -DUSE_SDL_VIDEO=1 -DUSE_SDL_SOUND=1 -D_THREAD_SAFE=1 -I../SDL12/include
GL_CFLAGS =
endif
OPTIMIZE = -O3 -ffast-math -fomit-frame-pointer -falign-loops=16
ifeq ($(ARCH),ppc)
BASE_CFLAGS += -faltivec
ifneq ($(VM_PPC),)
HAVE_VM_COMPILED=true
endif
endif
ifeq ($(ARCH),i386)
# !!! FIXME: x86-specific flags here...
endif
ifneq ($(HAVE_VM_COMPILED),true)
BASE_CFLAGS += -DNO_VM_COMPILED
endif
DEBUG_CFLAGS = $(BASE_CFLAGS) -g -O0
RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG $(OPTIMIZE)
SHLIBEXT=dylib
SHLIBCFLAGS=-fPIC -fno-common
SHLIBLDFLAGS=-dynamiclib $(LDFLAGS)
NOTSHLIBCFLAGS=-mdynamic-no-pic
#THREAD_LDFLAGS=-lpthread
#LDFLAGS=-ldl -lm
LDFLAGS += -framework Carbon
ifeq ($(USE_SDL),1)
# We copy sdlmain before ranlib'ing it so that subversion doesn't think
# the file has been modified by each build.
LIBSDLMAIN=$(B)/libSDLmain.a
LIBSDLMAINSRC=../libs/macosx/libSDLmain.a
CLIENT_LDFLAGS=-framework Cocoa -framework OpenGL ../libs/macosx/libSDL-1.2.0.dylib
else
# !!! FIXME: frameworks: OpenGL, Carbon, etc...
#CLIENT_LDFLAGS=-L/usr/X11R6/$(LIB) -lX11 -lXext -lXxf86dga -lXxf86vm
endif
# -framework OpenAL requires 10.4 or later...for builds shipping to the
# public, you'll want to use USE_OPENAL_DLOPEN and ship your own OpenAL
# library (http://openal.org/ or http://icculus.org/al_osx/)
ifeq ($(USE_OPENAL),1)
ifneq ($(USE_OPENAL_DLOPEN),1)
CLIENT_LDFLAGS += -framework OpenAL
endif
endif
TARGETS=\
$(B)/$(PLATFORM)quake3 \
$(B)/$(PLATFORM)q3ded \
$(B)/baseq3/cgame$(ARCH).$(SHLIBEXT) \
$(B)/baseq3/qagame$(ARCH).$(SHLIBEXT) \
$(B)/baseq3/ui$(ARCH).$(SHLIBEXT) \
$(B)/missionpack/cgame$(ARCH).$(SHLIBEXT) \
$(B)/missionpack/qagame$(ARCH).$(SHLIBEXT) \
$(B)/missionpack/ui$(ARCH).$(SHLIBEXT) \
$(B)/baseq3/vm/cgame.qvm \
$(B)/baseq3/vm/qagame.qvm \
$(B)/baseq3/vm/ui.qvm \
$(B)/missionpack/vm/qagame.qvm \
$(B)/missionpack/vm/cgame.qvm \
$(B)/missionpack/vm/ui.qvm
# $(B)/$(PLATFORM)quake3-smp \
else # ifeq darwin
#############################################################################
# SETUP AND BUILD -- MINGW32
#############################################################################
@ -494,7 +615,6 @@ else # ifeq SunOS
#############################################################################
# SETUP AND BUILD -- GENERIC
#############################################################################
CC=cc
BASE_CFLAGS=-DNO_VM_COMPILED
DEBUG_CFLAGS=$(BASE_CFLAGS) -g
@ -508,11 +628,17 @@ else # ifeq SunOS
$(B)/$(PLATFORM)q3ded
endif #Linux
endif #darwin
endif #mingw32
endif #FreeBSD
endif #IRIX
endif #SunOS
ifeq ($(USE_CCACHE),1)
CC := ccache $(CC)
CXX := ccache $(CXX)
endif
ifneq ($(BUILD_SERVER),1)
TARGETS := $(subst $(B)/$(PLATFORM)q3ded,,$(TARGETS))
endif
@ -541,15 +667,15 @@ ifeq ($(GENERATE_DEPENDENCIES),1)
endif
endif
DO_CC=$(CC) $(CFLAGS) -o $@ -c $<
DO_CXX=$(CXX) $(CFLAGS) -o $@ -c $<
DO_SMP_CC=$(CC) $(CFLAGS) -DSMP -o $@ -c $<
DO_BOT_CC=$(CC) $(CFLAGS) -DBOTLIB -o $@ -c $< # $(SHLIBCFLAGS) # bk001212
DO_DEBUG_CC=$(CC) $(DEBUG_CFLAGS) -o $@ -c $<
DO_CC=$(CC) $(NOTSHLIBCFLAGS) $(CFLAGS) -o $@ -c $<
DO_CXX=$(CXX) $(NOTSHLIBCFLAGS) $(CFLAGS) -o $@ -c $<
DO_SMP_CC=$(CC) $(NOTSHLIBCFLAGS) $(CFLAGS) -DSMP -o $@ -c $<
DO_BOT_CC=$(CC) $(NOTSHLIBCFLAGS) $(CFLAGS) -DBOTLIB -o $@ -c $< # $(SHLIBCFLAGS) # bk001212
DO_DEBUG_CC=$(CC) $(NOTSHLIBCFLAGS) $(DEBUG_CFLAGS) -o $@ -c $<
DO_SHLIB_CC=$(CC) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $<
DO_SHLIB_DEBUG_CC=$(CC) $(DEBUG_CFLAGS) $(SHLIBCFLAGS) -o $@ -c $<
DO_AS=$(CC) $(CFLAGS) -DELF -x assembler-with-cpp -o $@ -c $<
DO_DED_CC=$(CC) -DDEDICATED $(CFLAGS) -o $@ -c $<
DO_DED_CC=$(CC) $(NOTSHLIBCFLAGS) -DDEDICATED $(CFLAGS) -o $@ -c $<
DO_WINDRES=$(WINDRES) -i $< -o $@
#############################################################################
@ -864,6 +990,33 @@ else
Q3POBJ_SMP += $(B)/client/ftola.o $(B)/client/snapvectora.o
endif
endif #Linux-axp
else
ifeq ($(PLATFORM),darwin)
Q3POBJ=\
$(B)/client/unix_main.o \
$(B)/client/unix_net.o \
$(B)/client/unix_shared.o \
$(B)/client/linux_signals.o \
$(B)/client/linux_common.o \
$(B)/client/linux_qgl.o \
$(B)/client/linux_glimp.o \
$(B)/client/sdl_glimp.o \
$(B)/client/linux_joystick.o \
$(B)/client/linux_snd.o \
$(B)/client/sdl_snd.o \
ifeq ($(ARCH),i386)
I386OBJS := \
$(B)/client/ftola.o \
$(B)/client/snapvectora.o \
$(B)/client/snd_mixa.o \
$(B)/client/matha.o \
Q3POBJ += $(I386OBJS)
Q3POBJ_SMP += $(I386OBJS)
endif
else
ifeq ($(PLATFORM),SunOS)
Q3POBJ=\
@ -895,16 +1048,25 @@ ifeq ($(PLATFORM),SunOS)
endif #SunOS
endif #Linux
endif #darwin
endif #mingw32
endif #IRIX
endif #FreeBSD
$(B)/$(PLATFORM)quake3$(BINEXT): $(Q3OBJ) $(Q3POBJ)
$(CC) -o $@ $(Q3OBJ) $(Q3POBJ) $(CLIENT_LDFLAGS) $(LDFLAGS)
$(B)/$(PLATFORM)quake3$(BINEXT): $(Q3OBJ) $(Q3POBJ) $(LIBSDLMAIN)
$(CC) -o $@ $(Q3OBJ) $(Q3POBJ) $(CLIENT_LDFLAGS) $(LDFLAGS) $(LIBSDLMAIN)
$(B)/$(PLATFORM)quake3-smp$(BINEXT): $(Q3OBJ) $(Q3POBJ_SMP)
$(B)/$(PLATFORM)quake3-smp$(BINEXT): $(Q3OBJ) $(Q3POBJ_SMP) $(LIBSDLMAIN)
$(CC) -o $@ $(Q3OBJ) $(Q3POBJ_SMP) $(CLIENT_LDFLAGS) \
$(THREAD_LDFLAGS) $(LDFLAGS)
$(THREAD_LDFLAGS) $(LDFLAGS) $(LIBSDLMAIN)
ifneq ($(strip $(LIBSDLMAIN)),)
ifneq ($(strip $(LIBSDLMAINSRC)),)
$(LIBSDLMAIN) : $(LIBSDLMAINSRC)
cp $< $@
ranlib $@
endif
endif
$(B)/client/cl_cgame.o : $(CDIR)/cl_cgame.c; $(DO_CC)
$(B)/client/cl_cin.o : $(CDIR)/cl_cin.c; $(DO_CC)

View File

@ -1265,7 +1265,9 @@ static void GLW_InitExtensions( void )
if ( qglActiveTextureARB )
{
qglGetIntegerv( GL_MAX_ACTIVE_TEXTURES_ARB, &glConfig.maxActiveTextures );
GLint glint = 0;
qglGetIntegerv( GL_MAX_ACTIVE_TEXTURES_ARB, &glint );
glConfig.maxActiveTextures = (int) glint;
if ( glConfig.maxActiveTextures > 1 )
{

View File

@ -45,8 +45,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//#endif
//#include <GL/glx.h> // bk010216 - FIXME: all of the above redundant? renderer/qgl.h
#if defined(USE_SDL_VIDEO)
#include "SDL.h"
#include "SDL_loadso.h"
#else
#include <dlfcn.h>
#endif
// bk001129 - from cvs1.17 (mkv)
#if defined(__FX__)
@ -60,12 +64,14 @@ void (*qfxMesaSwapBuffers)(void);
#endif
//GLX Functions
#if !defined(USE_SDL_VIDEO)
XVisualInfo * (*qglXChooseVisual)( Display *dpy, int screen, int *attribList );
GLXContext (*qglXCreateContext)( Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct );
void (*qglXDestroyContext)( Display *dpy, GLXContext ctx );
Bool (*qglXMakeCurrent)( Display *dpy, GLXDrawable drawable, GLXContext ctx);
void (*qglXCopyContext)( Display *dpy, GLXContext src, GLXContext dst, GLuint mask );
void (*qglXSwapBuffers)( Display *dpy, GLXDrawable drawable );
#endif
void ( APIENTRY * qglAccum )(GLenum op, GLfloat value);
void ( APIENTRY * qglAlphaFunc )(GLenum func, GLclampf ref);
@ -408,7 +414,7 @@ void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t
void ( APIENTRY * qglActiveTextureARB )( GLenum texture );
void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
void ( APIENTRY * qglLockArraysEXT)( int, int);
void ( APIENTRY * qglLockArraysEXT)( GLint, GLint);
void ( APIENTRY * qglUnlockArraysEXT) ( void );
void ( APIENTRY * qglPointParameterfEXT)( GLenum param, GLfloat value );
@ -763,7 +769,7 @@ static void APIENTRY logAccum(GLenum op, GLfloat value)
static void APIENTRY logAlphaFunc(GLenum func, GLclampf ref)
{
fprintf( glw_state.log_fp, "glAlphaFunc( 0x%x, %f )\n", func, ref );
fprintf( glw_state.log_fp, "glAlphaFunc( 0x%x, %f )\n", (unsigned int) func, ref );
dllAlphaFunc( func, ref );
}
@ -781,13 +787,13 @@ static void APIENTRY logArrayElement(GLint i)
static void APIENTRY logBegin(GLenum mode)
{
fprintf( glw_state.log_fp, "glBegin( 0x%x )\n", mode );
fprintf( glw_state.log_fp, "glBegin( 0x%x )\n", (unsigned int) mode );
dllBegin( mode );
}
static void APIENTRY logBindTexture(GLenum target, GLuint texture)
{
fprintf( glw_state.log_fp, "glBindTexture( 0x%x, %u )\n", target, texture );
fprintf( glw_state.log_fp, "glBindTexture( 0x%x, %u )\n", (unsigned int) target, (unsigned int) texture );
dllBindTexture( target, texture );
}
@ -799,13 +805,13 @@ static void APIENTRY logBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLf
static void APIENTRY logBlendFunc(GLenum sfactor, GLenum dfactor)
{
fprintf( glw_state.log_fp, "glBlendFunc( 0x%x, 0x%x )\n", sfactor, dfactor );
fprintf( glw_state.log_fp, "glBlendFunc( 0x%x, 0x%x )\n", (unsigned int) sfactor, (unsigned int) dfactor );
dllBlendFunc( sfactor, dfactor );
}
static void APIENTRY logCallList(GLuint list)
{
fprintf( glw_state.log_fp, "glCallList( %u )\n", list );
fprintf( glw_state.log_fp, "glCallList( %u )\n", (unsigned int) list );
dllCallList( list );
}
@ -1122,7 +1128,7 @@ static void APIENTRY logDepthRange(GLclampd zNear, GLclampd zFar)
static void APIENTRY logDisable(GLenum cap)
{
fprintf( glw_state.log_fp, "glDisable( 0x%x )\n", cap );
fprintf( glw_state.log_fp, "glDisable( 0x%x )\n", (unsigned int) cap );
dllDisable( cap );
}
@ -1176,7 +1182,7 @@ static void APIENTRY logEdgeFlagv(const GLboolean *flag)
static void APIENTRY logEnable(GLenum cap)
{
fprintf( glw_state.log_fp, "glEnable( 0x%x )\n", cap );
fprintf( glw_state.log_fp, "glEnable( 0x%x )\n", (unsigned int) cap );
dllEnable( cap );
}
@ -1504,7 +1510,7 @@ static void APIENTRY logGetTexParameteriv(GLenum target, GLenum pname, GLint *pa
static void APIENTRY logHint(GLenum target, GLenum mode)
{
fprintf( glw_state.log_fp, "glHint( 0x%x, 0x%x )\n", target, mode );
fprintf( glw_state.log_fp, "glHint( 0x%x, 0x%x )\n", (unsigned int) target, (unsigned int) mode );
dllHint( target, mode );
}
@ -1923,7 +1929,7 @@ static void APIENTRY logPointSize(GLfloat size)
static void APIENTRY logPolygonMode(GLenum face, GLenum mode)
{
fprintf( glw_state.log_fp, "glPolygonMode( 0x%x, 0x%x )\n", face, mode );
fprintf( glw_state.log_fp, "glPolygonMode( 0x%x, 0x%x )\n", (unsigned int) face, (unsigned int) mode );
dllPolygonMode( face, mode );
}
@ -2403,7 +2409,7 @@ static void APIENTRY logTexCoordPointer(GLint size, GLenum type, GLsizei stride,
static void APIENTRY logTexEnvf(GLenum target, GLenum pname, GLfloat param)
{
fprintf( glw_state.log_fp, "glTexEnvf( 0x%x, 0x%x, %f )\n", target, pname, param );
fprintf( glw_state.log_fp, "glTexEnvf( 0x%x, 0x%x, %f )\n", (unsigned int) target, (unsigned int) pname, param );
dllTexEnvf( target, pname, param );
}
@ -2415,7 +2421,7 @@ static void APIENTRY logTexEnvfv(GLenum target, GLenum pname, const GLfloat *par
static void APIENTRY logTexEnvi(GLenum target, GLenum pname, GLint param)
{
fprintf( glw_state.log_fp, "glTexEnvi( 0x%x, 0x%x, 0x%x )\n", target, pname, param );
fprintf( glw_state.log_fp, "glTexEnvi( 0x%x, 0x%x, 0x%x )\n", (unsigned int) target, (unsigned int) pname, (unsigned int) param );
dllTexEnvi( target, pname, param );
}
static void APIENTRY logTexEnviv(GLenum target, GLenum pname, const GLint *params)
@ -2469,7 +2475,7 @@ static void APIENTRY logTexImage2D(GLenum target, GLint level, GLint internalfor
static void APIENTRY logTexParameterf(GLenum target, GLenum pname, GLfloat param)
{
fprintf( glw_state.log_fp, "glTexParameterf( 0x%x, 0x%x, %f )\n", target, pname, param );
fprintf( glw_state.log_fp, "glTexParameterf( 0x%x, 0x%x, %f )\n", (unsigned int) target, (unsigned int) pname, param );
dllTexParameterf( target, pname, param );
}
@ -2480,7 +2486,7 @@ static void APIENTRY logTexParameterfv(GLenum target, GLenum pname, const GLfloa
}
static void APIENTRY logTexParameteri(GLenum target, GLenum pname, GLint param)
{
fprintf( glw_state.log_fp, "glTexParameteri( 0x%x, 0x%x, 0x%x )\n", target, pname, param );
fprintf( glw_state.log_fp, "glTexParameteri( 0x%x, 0x%x, 0x%x )\n", (unsigned int) target, (unsigned int) pname, (unsigned int) param );
dllTexParameteri( target, pname, param );
}
static void APIENTRY logTexParameteriv(GLenum target, GLenum pname, const GLint *params)
@ -2669,12 +2675,14 @@ void QGL_Shutdown( void )
if( r_GLlibCoolDownMsec->integer )
usleep( r_GLlibCoolDownMsec->integer * 1000 );
#if USE_SDL_VIDEO
SDL_QuitSubSystem(SDL_INIT_VIDEO);
#else
dlclose ( glw_state.OpenGLLib );
#endif
glw_state.OpenGLLib = NULL;
}
glw_state.OpenGLLib = NULL;
qglAccum = NULL;
qglAlphaFunc = NULL;
qglAreTexturesResident = NULL;
@ -3022,15 +3030,22 @@ void QGL_Shutdown( void )
qfxMesaSwapBuffers = NULL;
#endif
#if !defined(USE_SDL_VIDEO)
qglXChooseVisual = NULL;
qglXCreateContext = NULL;
qglXDestroyContext = NULL;
qglXMakeCurrent = NULL;
qglXCopyContext = NULL;
qglXSwapBuffers = NULL;
#endif
}
#if USE_SDL_VIDEO
#define GPA( a ) SDL_GL_GetProcAddress( a )
qboolean GLimp_sdl_init_video(void);
#else
#define GPA( a ) dlsym( glw_state.OpenGLLib, a )
#endif
void *qwglGetProcAddress(char *symbol)
{
@ -3039,6 +3054,8 @@ void *qwglGetProcAddress(char *symbol)
return NULL;
}
char *do_dlerror(void);
/*
** QGL_Init
**
@ -3052,23 +3069,39 @@ void *qwglGetProcAddress(char *symbol)
qboolean QGL_Init( const char *dllname )
{
if ( ( glw_state.OpenGLLib = dlopen( dllname, RTLD_LAZY|RTLD_GLOBAL ) ) == 0 )
if (glw_state.OpenGLLib == 0)
{
#if USE_SDL_VIDEO
if (GLimp_sdl_init_video() == qfalse)
return qfalse;
glw_state.OpenGLLib = (void*) ((SDL_GL_LoadLibrary(dllname) == -1) ? 0 : 1);
#else
glw_state.OpenGLLib = dlopen( dllname, RTLD_LAZY|RTLD_GLOBAL );
#endif
}
if (glw_state.OpenGLLib == 0)
{
char fn[1024];
// FILE *fp; // bk001204 - unused
// if we are not setuid, try current directory
if (1) {
if (dllname != NULL) {
getcwd(fn, sizeof(fn));
Q_strcat(fn, sizeof(fn), "/");
Q_strcat(fn, sizeof(fn), dllname);
if ( ( glw_state.OpenGLLib = dlopen( fn, RTLD_LAZY ) ) == 0 ) {
ri.Printf(PRINT_ALL, "QGL_Init: Can't load %s from /etc/ld.so.conf or current dir: %s\n", dllname, dlerror());
#if USE_SDL_VIDEO
glw_state.OpenGLLib = (void*) ((SDL_GL_LoadLibrary(fn) == -1) ? 0 : 1);
#else
glw_state.OpenGLLib = dlopen( fn, RTLD_LAZY );
#endif
if ( glw_state.OpenGLLib == 0 ) {
ri.Printf(PRINT_ALL, "QGL_Init: Can't load %s from /etc/ld.so.conf or current dir: %s\n", dllname, do_dlerror());
return qfalse;
}
} else {
ri.Printf(PRINT_ALL, "QGL_Init: Can't load %s from /etc/ld.so.conf: %s\n", dllname, dlerror());
ri.Printf(PRINT_ALL, "QGL_Init: Can't load %s from /etc/ld.so.conf: %s\n", dllname, do_dlerror());
return qfalse;
}
}
@ -3418,12 +3451,14 @@ qboolean QGL_Init( const char *dllname )
qfxMesaSwapBuffers = GPA("fxMesaSwapBuffers");
#endif
#if !defined(USE_SDL_VIDEO)
qglXChooseVisual = GPA("glXChooseVisual");
qglXCreateContext = GPA("glXCreateContext");
qglXDestroyContext = GPA("glXDestroyContext");
qglXMakeCurrent = GPA("glXMakeCurrent");
qglXCopyContext = GPA("glXCopyContext");
qglXSwapBuffers = GPA("glXSwapBuffers");
#endif
qglLockArraysEXT = NULL;
qglUnlockArraysEXT = NULL;

View File

@ -6,7 +6,7 @@
*
* I wrote such a beast originally for Loki's port of Heavy Metal: FAKK2,
* and then wrote it again for the Linux client of Medal of Honor: Allied
* Assault. Third times a charm, so I'm rewriting this once more for the
* Assault. Third time's a charm, so I'm rewriting this once more for the
* GPL release of Quake 3.
*
* Written by Ryan C. Gordon (icculus@icculus.org). Please refer to
@ -107,6 +107,23 @@ cvar_t *joy_threshold = NULL;
cvar_t *r_allowSoftwareGL; // don't abort out if the pixelformat claims software
cvar_t *r_previousglDriver;
qboolean GLimp_sdl_init_video(void)
{
if (!SDL_WasInit(SDL_INIT_VIDEO))
{
ri.Printf( PRINT_ALL, "Calling SDL_Init(SDL_INIT_VIDEO)...\n");
if (SDL_Init(SDL_INIT_VIDEO) == -1)
{
ri.Printf( PRINT_ALL, "SDL_Init(SDL_INIT_VIDEO) failed: %s\n", SDL_GetError());
return qfalse;
}
ri.Printf( PRINT_ALL, "SDL_Init(SDL_INIT_VIDEO) passed.\n");
}
return qtrue;
}
/*
* Find the first occurrence of find in s.
*/
@ -217,8 +234,12 @@ static const char *XLateKey(SDL_keysym *keysym, int *key)
default: break;
}
if (keysym->unicode <= 255 && keysym->unicode >= 20) // maps to ASCII?
if (*key == K_BACKSPACE)
buf[0] = 8;
else
{
if (keysym->unicode <= 255 && keysym->unicode >= 20) // maps to ASCII?
{
char ch = (char) keysym->unicode;
if (ch == '~')
*key = '~'; // console HACK
@ -231,17 +252,25 @@ static const char *XLateKey(SDL_keysym *keysym, int *key)
// ch = ch - 'A' + 'a';
buf[0] = ch;
}
else if(keysym->unicode == 8) // ctrl-h
}
else if(keysym->unicode == 8) // ctrl-h
buf[0] = 8;
}
return buf;
}
static void install_grabs(void)
{
SDL_ShowCursor(0);
SDL_WM_GrabInput(SDL_GRAB_ON);
SDL_ShowCursor(0);
// This is a bug in the current SDL/macosx...have to toggle it a few
// times to get the cursor to hide.
#if defined(MACOS_X)
SDL_ShowCursor(1);
SDL_ShowCursor(0);
#endif
}
static void uninstall_grabs(void)
@ -417,7 +446,6 @@ void GLimp_SetGamma( unsigned char red[256], unsigned char green[256], unsigned
void GLimp_Shutdown( void )
{
IN_Shutdown();
SDL_QuitSubSystem(SDL_INIT_VIDEO);
screen = NULL;
memset( &glConfig, 0, sizeof( glConfig ) );
@ -448,16 +476,8 @@ static qboolean GLW_StartDriverAndSetMode( const char *drivername,
{
rserr_t err;
if (!SDL_WasInit(SDL_INIT_VIDEO))
{
ri.Printf( PRINT_ALL, "Calling SDL_Init(SDL_INIT_VIDEO)...\n");
if (SDL_Init(SDL_INIT_VIDEO) == -1)
{
ri.Printf( PRINT_ALL, "SDL_Init(SDL_INIT_VIDEO) failed: %s\n", SDL_GetError());
return qfalse;
}
ri.Printf( PRINT_ALL, "SDL_Init(SDL_INIT_VIDEO) passed.\n");
}
if (GLimp_sdl_init_video() == qfalse)
return qfalse;
// don't ever bother going into fullscreen with a voodoo card
#if 1 // JDC: I reenabled this
@ -714,17 +734,17 @@ static void GLW_InitExtensions( void )
qglClientActiveTextureARB = NULL;
if ( Q_stristr( glConfig.extensions_string, "GL_ARB_multitexture" ) )
{
// !!! FIXME: Use SDL_GL_GetProcAddress instead?
if ( r_ext_multitexture->value )
{
qglMultiTexCoord2fARB = ( PFNGLMULTITEXCOORD2FARBPROC ) dlsym( glw_state.OpenGLLib, "glMultiTexCoord2fARB" );
qglActiveTextureARB = ( PFNGLACTIVETEXTUREARBPROC ) dlsym( glw_state.OpenGLLib, "glActiveTextureARB" );
qglClientActiveTextureARB = ( PFNGLCLIENTACTIVETEXTUREARBPROC ) dlsym( glw_state.OpenGLLib, "glClientActiveTextureARB" );
qglMultiTexCoord2fARB = ( PFNGLMULTITEXCOORD2FARBPROC ) SDL_GL_GetProcAddress( "glMultiTexCoord2fARB" );
qglActiveTextureARB = ( PFNGLACTIVETEXTUREARBPROC ) SDL_GL_GetProcAddress( "glActiveTextureARB" );
qglClientActiveTextureARB = ( PFNGLCLIENTACTIVETEXTUREARBPROC ) SDL_GL_GetProcAddress( "glClientActiveTextureARB" );
if ( qglActiveTextureARB )
{
qglGetIntegerv( GL_MAX_ACTIVE_TEXTURES_ARB, &glConfig.maxActiveTextures );
GLint glint = 0;
qglGetIntegerv( GL_MAX_ACTIVE_TEXTURES_ARB, &glint );
glConfig.maxActiveTextures = (int) glint;
if ( glConfig.maxActiveTextures > 1 )
{
ri.Printf( PRINT_ALL, "...using GL_ARB_multitexture\n" );
@ -751,8 +771,8 @@ static void GLW_InitExtensions( void )
if ( r_ext_compiled_vertex_array->value )
{
ri.Printf( PRINT_ALL, "...using GL_EXT_compiled_vertex_array\n" );
qglLockArraysEXT = ( void ( APIENTRY * )( int, int ) ) dlsym( glw_state.OpenGLLib, "glLockArraysEXT" );
qglUnlockArraysEXT = ( void ( APIENTRY * )( void ) ) dlsym( glw_state.OpenGLLib, "glUnlockArraysEXT" );
qglLockArraysEXT = ( void ( APIENTRY * )( GLint, GLint ) ) SDL_GL_GetProcAddress( "glLockArraysEXT" );
qglUnlockArraysEXT = ( void ( APIENTRY * )( void ) ) SDL_GL_GetProcAddress( "glUnlockArraysEXT" );
if (!qglLockArraysEXT || !qglUnlockArraysEXT)
{
ri.Error (ERR_FATAL, "bad getprocaddress");
@ -783,7 +803,7 @@ static qboolean GLW_LoadOpenGL( const char *name )
{
qboolean fullscreen;
ri.Printf( PRINT_ALL, "...loading %s: ", name );
ri.Printf( PRINT_ALL, "...loading %s:\n", name );
// disable the 3Dfx splash screen and set gamma
// we do this all the time, but it shouldn't hurt anything

View File

@ -81,6 +81,10 @@ https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=371
<TTimo> and use my own copy instead of the glibc crap
===============
*/
#ifdef Snd_Memset
#undef Snd_Memset
#endif
void Snd_Memset (void* dest, const int val, const size_t count)
{
int *pDest;

View File

@ -19,7 +19,7 @@ along with Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#if !( defined __linux__ || defined __FreeBSD__ || defined __sun)
#if !( defined __linux__ || defined __FreeBSD__ || defined __sun || defined MACOS_X )
#error You should include this file only on Linux/FreeBSD/Solaris platforms
#endif

View File

@ -41,7 +41,17 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#ifdef __linux__ // rb010123
#include <mntent.h>
#endif
#if (defined(DEDICATED) && defined(USE_SDL_VIDEO))
#undef USE_SDL_VIDEO
#endif
#if USE_SDL_VIDEO
#include "SDL.h"
#include "SDL_loadso.h"
#else
#include <dlfcn.h>
#endif
#ifdef __linux__
#include <fpu_control.h> // bk001213 - force dumps on divide by zero
@ -60,8 +70,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "linux_local.h" // bk001204
// Structure containing functions exported from refresh DLL
refexport_t re;
#if idppc_altivec
#ifdef MACOS_X
#include <Carbon/Carbon.h>
#endif
#endif
unsigned sys_frame_time;
@ -349,8 +362,33 @@ void Sys_Quit (void) {
Sys_Exit(0);
}
static void Sys_DetectAltivec(void)
{
extern cvar_t *com_altivec;
// Only detect if user hasn't forcibly disabled it.
if (com_altivec->integer) {
#if idppc_altivec
#if MACOS_X
{
long feat = 0;
OSErr err = Gestalt(gestaltPowerPCProcessorFeatures, &feat);
if ((err==noErr) && ((1 << gestaltPowerPCHasVectorInstructions) & feat))
com_altivec->integer = 1;
}
#else // !!! FIXME: PowerPC Linux, etc: how to detect?
com_altivec->integer = 1;
#endif
#else
com_altivec->integer = 0; // not an Altivec system, so never use it.
#endif
}
}
void Sys_Init(void)
{
Sys_DetectAltivec();
Cmd_AddCommand ("in_restart", Sys_In_Restart_f);
Cvar_Set( "arch", OS_STRING " " ARCH_STRING );
@ -643,6 +681,16 @@ char *Sys_ConsoleInput(void)
/*****************************************************************************/
char *do_dlerror(void)
{
#if USE_SDL_VIDEO
return SDL_GetError();
#else
return dlerror();
#endif
}
/*
=================
Sys_UnloadDll
@ -651,16 +699,23 @@ Sys_UnloadDll
*/
void Sys_UnloadDll( void *dllHandle ) {
// bk001206 - verbose error reporting
const char* err; // rb010123 - now const
if ( !dllHandle )
{
Com_Printf("Sys_UnloadDll(NULL)\n");
return;
}
#if USE_SDL_VIDEO
SDL_UnloadObject(dllHandle);
#else
dlclose( dllHandle );
err = dlerror();
if ( err != NULL )
Com_Printf ( "Sys_UnloadGame failed on dlclose: \"%s\"!\n", err );
{
const char* err; // rb010123 - now const
err = dlerror();
if ( err != NULL )
Com_Printf ( "Sys_UnloadGame failed on dlclose: \"%s\"!\n", err );
}
#endif
}
@ -689,10 +744,15 @@ static void* try_dlopen(const char* base, const char* gamedir, const char* fname
fn = FS_BuildOSPath( base, gamedir, fname );
Com_Printf( "Sys_LoadDll(%s)... \n", fn );
#if USE_SDL_VIDEO
libHandle = SDL_LoadObject(fn);
#else
libHandle = dlopen( fn, Q_RTLD );
#endif
if(!libHandle) {
Com_Printf( "Sys_LoadDll(%s) failed:\n\"%s\"\n", fn, dlerror() );
Com_Printf( "Sys_LoadDll(%s) failed:\n\"%s\"\n", fn, do_dlerror() );
return NULL;
}
@ -751,20 +811,31 @@ void *Sys_LoadDll( const char *name, char *fqpath ,
return NULL;
}
dllEntry = dlsym( libHandle, "dllEntry" );
#if USE_SDL_VIDEO
dllEntry = SDL_LoadFunction( libHandle, "dllEntry" );
*entryPoint = SDL_LoadFunction( libHandle, "vmMain" );
#else
dllEntry = dlsym( libHandle, "dllEntry" );
*entryPoint = dlsym( libHandle, "vmMain" );
#endif
if ( !*entryPoint || !dllEntry )
{
err = dlerror();
err = do_dlerror();
#ifndef NDEBUG // bk001206 - in debug abort on failure
Com_Error ( ERR_FATAL, "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err );
#else
Com_Printf ( "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err );
#endif
#if USE_SDL_VIDEO
SDL_UnloadObject(libHandle);
#else
dlclose( libHandle );
err = dlerror();
err = do_dlerror();
if ( err != NULL )
Com_Printf ( "Sys_LoadDll(%s) failed dlcose:\n\"%s\"\n", name, err );
#endif
return NULL;
}
Com_Printf ( "Sys_LoadDll(%s) found **vmMain** at %p \n", name, *entryPoint ); // bk001212
@ -1322,4 +1393,7 @@ int main ( int argc, char* argv[] )
#endif
Com_Frame ();
}
return 0;
}