mirror of
https://github.com/ioquake/ioq3.git
synced 2024-11-10 07:11:46 +00:00
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:
parent
b20b86bbbe
commit
721b9a7d01
61 changed files with 877 additions and 22868 deletions
|
@ -554,7 +554,7 @@ int PS_ReadName(script_t *script, token_t *token)
|
||||||
// Changes Globals: -
|
// Changes Globals: -
|
||||||
//============================================================================
|
//============================================================================
|
||||||
void NumberValue(char *string, int subtype, unsigned long int *intvalue,
|
void NumberValue(char *string, int subtype, unsigned long int *intvalue,
|
||||||
long double *floatvalue)
|
double *floatvalue)
|
||||||
{
|
{
|
||||||
unsigned long int dotfound = 0;
|
unsigned long int dotfound = 0;
|
||||||
|
|
||||||
|
@ -573,13 +573,13 @@ void NumberValue(char *string, int subtype, unsigned long int *intvalue,
|
||||||
} //end if
|
} //end if
|
||||||
if (dotfound)
|
if (dotfound)
|
||||||
{
|
{
|
||||||
*floatvalue = *floatvalue + (long double) (*string - '0') /
|
*floatvalue = *floatvalue + (double) (*string - '0') /
|
||||||
(long double) dotfound;
|
(double) dotfound;
|
||||||
dotfound *= 10;
|
dotfound *= 10;
|
||||||
} //end if
|
} //end if
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*floatvalue = *floatvalue * 10.0 + (long double) (*string - '0');
|
*floatvalue = *floatvalue * 10.0 + (double) (*string - '0');
|
||||||
} //end else
|
} //end else
|
||||||
string++;
|
string++;
|
||||||
} //end while
|
} //end while
|
||||||
|
@ -631,7 +631,7 @@ int PS_ReadNumber(script_t *script, token_t *token)
|
||||||
int octal, dot;
|
int octal, dot;
|
||||||
char c;
|
char c;
|
||||||
// unsigned long int intvalue = 0;
|
// unsigned long int intvalue = 0;
|
||||||
// long double floatvalue = 0;
|
// double floatvalue = 0;
|
||||||
|
|
||||||
token->type = TT_NUMBER;
|
token->type = TT_NUMBER;
|
||||||
//check for a hexadecimal number
|
//check for a hexadecimal number
|
||||||
|
@ -1148,15 +1148,15 @@ void StripSingleQuotes(char *string)
|
||||||
// Returns: -
|
// Returns: -
|
||||||
// Changes Globals: -
|
// Changes Globals: -
|
||||||
//============================================================================
|
//============================================================================
|
||||||
long double ReadSignedFloat(script_t *script)
|
double ReadSignedFloat(script_t *script)
|
||||||
{
|
{
|
||||||
token_t token;
|
token_t token;
|
||||||
long double sign = 1;
|
double sign = 1.0;
|
||||||
|
|
||||||
PS_ExpectAnyToken(script, &token);
|
PS_ExpectAnyToken(script, &token);
|
||||||
if (!strcmp(token.string, "-"))
|
if (!strcmp(token.string, "-"))
|
||||||
{
|
{
|
||||||
sign = -1;
|
sign = -1.0;
|
||||||
PS_ExpectTokenType(script, TT_NUMBER, 0, &token);
|
PS_ExpectTokenType(script, TT_NUMBER, 0, &token);
|
||||||
} //end if
|
} //end if
|
||||||
else if (token.type != TT_NUMBER)
|
else if (token.type != TT_NUMBER)
|
||||||
|
|
|
@ -161,7 +161,7 @@ typedef struct token_s
|
||||||
int subtype; //last read token sub type
|
int subtype; //last read token sub type
|
||||||
#ifdef NUMBERVALUE
|
#ifdef NUMBERVALUE
|
||||||
unsigned long int intvalue; //integer value
|
unsigned long int intvalue; //integer value
|
||||||
long double floatvalue; //floating point value
|
double floatvalue; //floating point value
|
||||||
#endif //NUMBERVALUE
|
#endif //NUMBERVALUE
|
||||||
char *whitespace_p; //start of white space before token
|
char *whitespace_p; //start of white space before token
|
||||||
char *endwhitespace_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
|
//read a possible signed integer
|
||||||
signed long int ReadSignedInt(script_t *script);
|
signed long int ReadSignedInt(script_t *script);
|
||||||
//read a possible signed floating point number
|
//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
|
//set an array with punctuations, NULL restores default C/C++ set
|
||||||
void SetScriptPunctuations(script_t *script, punctuation_t *p);
|
void SetScriptPunctuations(script_t *script, punctuation_t *p);
|
||||||
//set script flags
|
//set script flags
|
||||||
|
|
|
@ -28,14 +28,23 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#include "qal.h"
|
#include "qal.h"
|
||||||
|
|
||||||
#if USE_OPENAL_DLOPEN
|
#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>
|
#include <windows.h>
|
||||||
#define OBJTYPE HMODULE
|
#define OBJTYPE HMODULE
|
||||||
#define OBJLOAD(x) LoadLibrary(x)
|
#define OBJLOAD(x) LoadLibrary(x)
|
||||||
#define SYMLOAD(x,y) GetProcAddress(x,y)
|
#define SYMLOAD(x,y) GetProcAddress(x,y)
|
||||||
#define OBJFREE(x) FreeLibrary(x)
|
#define OBJFREE(x) FreeLibrary(x)
|
||||||
|
|
||||||
#elif defined __linux__ || defined __FreeBSD__
|
#elif defined __linux__ || defined __FreeBSD__ || defined MACOS_X
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
|
@ -32,8 +32,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#define AL_NO_PROTOTYPES
|
#define AL_NO_PROTOTYPES
|
||||||
#define ALC_NO_PROTOTYPES
|
#define ALC_NO_PROTOTYPES
|
||||||
#endif
|
#endif
|
||||||
#include <AL/al.h>
|
#include "../AL/al.h"
|
||||||
#include <AL/alc.h>
|
#include "../AL/alc.h"
|
||||||
|
|
||||||
#if USE_OPENAL_DLOPEN
|
#if USE_OPENAL_DLOPEN
|
||||||
extern LPALENABLE qalEnable;
|
extern LPALENABLE qalEnable;
|
||||||
|
|
|
@ -42,7 +42,7 @@ static int FGetLittleLong( fileHandle_t f ) {
|
||||||
FGetLittleShort
|
FGetLittleShort
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
static int FGetLittleShort( fileHandle_t f ) {
|
static short FGetLittleShort( fileHandle_t f ) {
|
||||||
short v;
|
short v;
|
||||||
|
|
||||||
FS_Read( &v, sizeof(v), f );
|
FS_Read( &v, sizeof(v), f );
|
||||||
|
|
|
@ -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 data, aoff, boff;
|
||||||
int leftvol, rightvol;
|
int leftvol, rightvol;
|
||||||
int i, j;
|
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 (!ch->doppler || ch->dopplerScale==1.0f) {
|
||||||
#if idppc_altivec
|
|
||||||
vector signed short volume_vec;
|
vector signed short volume_vec;
|
||||||
vector unsigned int volume_shift;
|
vector unsigned int volume_shift;
|
||||||
int vectorCount, samplesLeft, chunkSamplesLeft;
|
int vectorCount, samplesLeft, chunkSamplesLeft;
|
||||||
#endif
|
|
||||||
leftvol = ch->leftvol*snd_vol;
|
leftvol = ch->leftvol*snd_vol;
|
||||||
rightvol = ch->rightvol*snd_vol;
|
rightvol = ch->rightvol*snd_vol;
|
||||||
samples = chunk->sndChunk;
|
samples = chunk->sndChunk;
|
||||||
#if idppc_altivec
|
|
||||||
((short *)&volume_vec)[0] = leftvol;
|
((short *)&volume_vec)[0] = leftvol;
|
||||||
((short *)&volume_vec)[1] = leftvol;
|
((short *)&volume_vec)[1] = leftvol;
|
||||||
((short *)&volume_vec)[4] = 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 unsigned char tmp;
|
||||||
vector short s0, s1, sampleData0, sampleData1;
|
vector short s0, s1, sampleData0, sampleData1;
|
||||||
vector short samples0, samples1;
|
|
||||||
vector signed int left0, right0;
|
|
||||||
vector signed int merge0, merge1;
|
vector signed int merge0, merge1;
|
||||||
vector signed int d0, d1, d2, d3;
|
vector signed int d0, d1, d2, d3;
|
||||||
vector unsigned char samplePermute0 =
|
vector unsigned char samplePermute0 =
|
||||||
(vector unsigned char){0, 1, 4, 5, 0, 1, 4, 5, 2, 3, 6, 7, 2, 3, 6, 7};
|
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 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;
|
vector unsigned char loadPermute0, loadPermute1;
|
||||||
|
|
||||||
// Rather than permute the vectors after we load them to do the sample
|
// 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++ ) {
|
for ( i=0 ; i<count ; i++ ) {
|
||||||
data = samples[sampleOffset++];
|
data = samples[sampleOffset++];
|
||||||
samp[i].left += (data * leftvol)>>8;
|
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;
|
sampleOffset = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
fleftvol = ch->leftvol*snd_vol;
|
fleftvol = ch->leftvol*snd_vol;
|
||||||
frightvol = ch->rightvol*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 ) {
|
void S_PaintChannelFromWavelet( channel_t *ch, sfx_t *sc, int count, int sampleOffset, int bufferOffset ) {
|
||||||
int data;
|
int data;
|
||||||
int leftvol, rightvol;
|
int leftvol, rightvol;
|
||||||
|
|
BIN
code/libs/macosx/libSDL-1.2.0.dylib
Executable file
BIN
code/libs/macosx/libSDL-1.2.0.dylib
Executable file
Binary file not shown.
BIN
code/libs/macosx/libSDLmain.a
Normal file
BIN
code/libs/macosx/libSDLmain.a
Normal file
Binary file not shown.
|
@ -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 ./*
|
|
||||||
|
|
|
@ -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);
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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)
|
|
||||||
|
|
||||||
|
|
|
@ -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";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -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]\
|
|
||||||
\
|
|
||||||
\
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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.
18
code/macosx/Quake3.nib/classes.nib
generated
18
code/macosx/Quake3.nib/classes.nib
generated
|
@ -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;
|
|
||||||
}
|
|
19
code/macosx/Quake3.nib/info.nib
generated
19
code/macosx/Quake3.nib/info.nib
generated
|
@ -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>
|
|
BIN
code/macosx/Quake3.nib/objects.nib
generated
BIN
code/macosx/Quake3.nib/objects.nib
generated
Binary file not shown.
|
@ -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
|
@ -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 |
|
@ -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
|
|
|
@ -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
|
|
|
@ -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();
|
|
||||||
|
|
|
@ -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");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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 )
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
@ -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) {
|
|
||||||
}
|
|
||||||
|
|
|
@ -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) {
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ cvar_t *com_fixedtime;
|
||||||
cvar_t *com_dropsim; // 0.0 to 1.0, simulated packet drops
|
cvar_t *com_dropsim; // 0.0 to 1.0, simulated packet drops
|
||||||
cvar_t *com_journal;
|
cvar_t *com_journal;
|
||||||
cvar_t *com_maxfps;
|
cvar_t *com_maxfps;
|
||||||
|
cvar_t *com_altivec;
|
||||||
cvar_t *com_timedemo;
|
cvar_t *com_timedemo;
|
||||||
cvar_t *com_sv_running;
|
cvar_t *com_sv_running;
|
||||||
cvar_t *com_cl_running;
|
cvar_t *com_cl_running;
|
||||||
|
@ -2425,6 +2426,7 @@ void Com_Init( char *commandLine ) {
|
||||||
//
|
//
|
||||||
// init commands and vars
|
// init commands and vars
|
||||||
//
|
//
|
||||||
|
com_altivec = Cvar_Get ("com_altivec", "1", CVAR_ARCHIVE);
|
||||||
com_maxfps = Cvar_Get ("com_maxfps", "85", CVAR_ARCHIVE);
|
com_maxfps = Cvar_Get ("com_maxfps", "85", CVAR_ARCHIVE);
|
||||||
com_blood = Cvar_Get ("com_blood", "1", 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");
|
Cvar_Set("ui_singlePlayerActive", "0");
|
||||||
|
|
||||||
com_fullyInitialized = qtrue;
|
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
//==================================================================
|
//==================================================================
|
||||||
|
|
|
@ -51,6 +51,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#define idppc_altivec 0
|
#define idppc_altivec 0
|
||||||
#endif
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef __ASM_I386__ // don't include the C bits if included from qasm.h
|
#ifndef __ASM_I386__ // don't include the C bits if included from qasm.h
|
||||||
|
|
|
@ -1820,7 +1820,7 @@ asm (
|
||||||
|
|
||||||
#if defined(MACOS_X) && defined(__OPTIMIZE__)
|
#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.
|
// 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
|
#else
|
||||||
// Mac OS X Server and unoptimized compiles include a GCC AsmCall frame
|
// Mac OS X Server and unoptimized compiles include a GCC AsmCall frame
|
||||||
asm (
|
asm (
|
||||||
|
|
|
@ -46,7 +46,22 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
#elif defined(MACOS_X)
|
#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__)
|
#elif defined( __linux__ ) || defined(__FreeBSD__)
|
||||||
|
|
||||||
|
@ -164,7 +179,7 @@ extern void ( APIENTRY * qglUnlockArraysEXT) (void);
|
||||||
|
|
||||||
#include "qgl_linked.h"
|
#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.
|
// 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"
|
#include "macosx_qgl.h"
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ static void MakeMeshNormals( int width, int height, drawVert_t ctrl[MAX_GRID_SIZ
|
||||||
int i, j, k, dist;
|
int i, j, k, dist;
|
||||||
vec3_t normal;
|
vec3_t normal;
|
||||||
vec3_t sum;
|
vec3_t sum;
|
||||||
int count;
|
int count = 0;
|
||||||
vec3_t base;
|
vec3_t base;
|
||||||
vec3_t delta;
|
vec3_t delta;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
|
@ -150,12 +150,15 @@ int max_polys;
|
||||||
cvar_t *r_maxpolyverts;
|
cvar_t *r_maxpolyverts;
|
||||||
int max_polyverts;
|
int max_polyverts;
|
||||||
|
|
||||||
|
/* !!! FIXME: Why are these here?! */
|
||||||
|
#if 0
|
||||||
void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t );
|
void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t );
|
||||||
void ( APIENTRY * qglActiveTextureARB )( GLenum texture );
|
void ( APIENTRY * qglActiveTextureARB )( GLenum texture );
|
||||||
void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
|
void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
|
||||||
|
|
||||||
void ( APIENTRY * qglLockArraysEXT)( GLint, GLint);
|
void ( APIENTRY * qglLockArraysEXT)( GLint, GLint);
|
||||||
void ( APIENTRY * qglUnlockArraysEXT) ( void );
|
void ( APIENTRY * qglUnlockArraysEXT) ( void );
|
||||||
|
#endif
|
||||||
|
|
||||||
static void AssertCvarRange( cvar_t *cv, float minVal, float maxVal, qboolean shouldBeIntegral )
|
static void AssertCvarRange( cvar_t *cv, float minVal, float maxVal, qboolean shouldBeIntegral )
|
||||||
{
|
{
|
||||||
|
|
|
@ -402,9 +402,9 @@ ProjectDlightTexture
|
||||||
Perform dynamic lighting with another rendering pass
|
Perform dynamic lighting with another rendering pass
|
||||||
===================
|
===================
|
||||||
*/
|
*/
|
||||||
static void ProjectDlightTexture( void ) {
|
|
||||||
int i, l;
|
|
||||||
#if idppc_altivec
|
#if idppc_altivec
|
||||||
|
static void ProjectDlightTexture_altivec( void ) {
|
||||||
|
int i, l;
|
||||||
vec_t origin0, origin1, origin2;
|
vec_t origin0, origin1, origin2;
|
||||||
float texCoords0, texCoords1;
|
float texCoords0, texCoords1;
|
||||||
vector float floatColorVec0, floatColorVec1;
|
vector float floatColorVec0, floatColorVec1;
|
||||||
|
@ -412,13 +412,10 @@ static void ProjectDlightTexture( void ) {
|
||||||
vector short colorShort;
|
vector short colorShort;
|
||||||
vector signed int colorInt;
|
vector signed int colorInt;
|
||||||
vector unsigned char floatColorVecPerm, modulatePerm, colorChar;
|
vector unsigned char floatColorVecPerm, modulatePerm, colorChar;
|
||||||
vector unsigned char vSel = (vector unsigned char){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,
|
0x00, 0x00, 0x00, 0xff,
|
||||||
0x00, 0x00, 0x00, 0xff};
|
0x00, 0x00, 0x00, 0xff);
|
||||||
#else
|
|
||||||
vec3_t origin;
|
|
||||||
#endif
|
|
||||||
float *texCoords;
|
float *texCoords;
|
||||||
byte *colors;
|
byte *colors;
|
||||||
byte clipBits[SHADER_MAX_VERTEXES];
|
byte clipBits[SHADER_MAX_VERTEXES];
|
||||||
|
@ -429,20 +426,18 @@ static void ProjectDlightTexture( void ) {
|
||||||
float scale;
|
float scale;
|
||||||
float radius;
|
float radius;
|
||||||
vec3_t floatColor;
|
vec3_t floatColor;
|
||||||
float modulate;
|
float modulate = 0.0f;
|
||||||
|
|
||||||
if ( !backEnd.refdef.num_dlights ) {
|
if ( !backEnd.refdef.num_dlights ) {
|
||||||
return;
|
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.
|
// and/or modulate are already 16-byte aligned.
|
||||||
floatColorVecPerm = vec_lvsl(0,(float *)floatColor);
|
floatColorVecPerm = vec_lvsl(0,(float *)floatColor);
|
||||||
modulatePerm = vec_lvsl(0,(float *)&modulate);
|
modulatePerm = vec_lvsl(0,(float *)&modulate);
|
||||||
modulatePerm = (vector unsigned char)vec_splat((vector unsigned int)modulatePerm,0);
|
modulatePerm = (vector unsigned char)vec_splat((vector unsigned int)modulatePerm,0);
|
||||||
zero = (vector float)vec_splat_s8(0);
|
zero = (vector float)vec_splat_s8(0);
|
||||||
#endif
|
|
||||||
|
|
||||||
for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) {
|
for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) {
|
||||||
dlight_t *dl;
|
dlight_t *dl;
|
||||||
|
@ -454,27 +449,20 @@ static void ProjectDlightTexture( void ) {
|
||||||
colors = colorArray[0];
|
colors = colorArray[0];
|
||||||
|
|
||||||
dl = &backEnd.refdef.dlights[l];
|
dl = &backEnd.refdef.dlights[l];
|
||||||
#if idppc_altivec
|
|
||||||
origin0 = dl->transformed[0];
|
origin0 = dl->transformed[0];
|
||||||
origin1 = dl->transformed[1];
|
origin1 = dl->transformed[1];
|
||||||
origin2 = dl->transformed[2];
|
origin2 = dl->transformed[2];
|
||||||
#else
|
|
||||||
VectorCopy( dl->transformed, origin );
|
|
||||||
#endif
|
|
||||||
radius = dl->radius;
|
radius = dl->radius;
|
||||||
scale = 1.0f / radius;
|
scale = 1.0f / radius;
|
||||||
|
|
||||||
floatColor[0] = dl->color[0] * 255.0f;
|
floatColor[0] = dl->color[0] * 255.0f;
|
||||||
floatColor[1] = dl->color[1] * 255.0f;
|
floatColor[1] = dl->color[1] * 255.0f;
|
||||||
floatColor[2] = dl->color[2] * 255.0f;
|
floatColor[2] = dl->color[2] * 255.0f;
|
||||||
#if idppc_altivec
|
|
||||||
floatColorVec0 = vec_ld(0, floatColor);
|
floatColorVec0 = vec_ld(0, floatColor);
|
||||||
floatColorVec1 = vec_ld(11, floatColor);
|
floatColorVec1 = vec_ld(11, floatColor);
|
||||||
floatColorVec0 = vec_perm(floatColorVec0,floatColorVec0,floatColorVecPerm);
|
floatColorVec0 = vec_perm(floatColorVec0,floatColorVec0,floatColorVecPerm);
|
||||||
#endif
|
|
||||||
for ( i = 0 ; i < tess.numVertexes ; i++, texCoords += 2, colors += 4 ) {
|
for ( i = 0 ; i < tess.numVertexes ; i++, texCoords += 2, colors += 4 ) {
|
||||||
int clip = 0;
|
int clip = 0;
|
||||||
#if idppc_altivec
|
|
||||||
#define DIST0 dist0
|
#define DIST0 dist0
|
||||||
#define DIST1 dist1
|
#define DIST1 dist1
|
||||||
#define DIST2 dist2
|
#define DIST2 dist2
|
||||||
|
@ -485,16 +473,6 @@ static void ProjectDlightTexture( void ) {
|
||||||
dist0 = origin0 - tess.xyz[i][0];
|
dist0 = origin0 - tess.xyz[i][0];
|
||||||
dist1 = origin1 - tess.xyz[i][1];
|
dist1 = origin1 - tess.xyz[i][1];
|
||||||
dist2 = origin2 - tess.xyz[i][2];
|
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++;
|
backEnd.pc.c_dlightVertexes++;
|
||||||
|
|
||||||
|
@ -539,7 +517,6 @@ static void ProjectDlightTexture( void ) {
|
||||||
}
|
}
|
||||||
clipBits[i] = clip;
|
clipBits[i] = clip;
|
||||||
|
|
||||||
#if idppc_altivec
|
|
||||||
modulateVec = vec_ld(0,(float *)&modulate);
|
modulateVec = vec_ld(0,(float *)&modulate);
|
||||||
modulateVec = vec_perm(modulateVec,modulateVec,modulatePerm);
|
modulateVec = vec_perm(modulateVec,modulateVec,modulatePerm);
|
||||||
colorVec = vec_madd(floatColorVec0,modulateVec,zero);
|
colorVec = vec_madd(floatColorVec0,modulateVec,zero);
|
||||||
|
@ -548,12 +525,6 @@ static void ProjectDlightTexture( void ) {
|
||||||
colorChar = vec_packsu(colorShort,colorShort); // RGBxRGBxRGBxRGBx
|
colorChar = vec_packsu(colorShort,colorShort); // RGBxRGBxRGBxRGBx
|
||||||
colorChar = vec_sel(colorChar,vSel,vSel); // RGBARGBARGBARGBA replace alpha with 255
|
colorChar = vec_sel(colorChar,vSel,vSel); // RGBARGBARGBARGBA replace alpha with 255
|
||||||
vec_ste((vector unsigned int)colorChar,0,(unsigned int *)colors); // store color
|
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 DIST0
|
||||||
#undef DIST1
|
#undef DIST1
|
||||||
|
@ -602,6 +573,162 @@ static void ProjectDlightTexture( void ) {
|
||||||
backEnd.pc.c_dlightIndexes += numIndexes;
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1097,22 +1097,19 @@ void RB_CalcSpecularAlpha( unsigned char *alphas ) {
|
||||||
**
|
**
|
||||||
** The basic vertex lighting calc
|
** 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 *v, *normal;
|
||||||
float incoming;
|
|
||||||
trRefEntity_t *ent;
|
trRefEntity_t *ent;
|
||||||
int ambientLightInt;
|
int ambientLightInt;
|
||||||
vec3_t ambientLight;
|
|
||||||
vec3_t lightDir;
|
vec3_t lightDir;
|
||||||
vec3_t directedLight;
|
|
||||||
int numVertexes;
|
int numVertexes;
|
||||||
#if idppc_altivec
|
vector unsigned char vSel = VECCONST_UINT8(0x00, 0x00, 0x00, 0xff,
|
||||||
vector unsigned char vSel = (vector unsigned char){0x00, 0x00, 0x00, 0xff,
|
0x00, 0x00, 0x00, 0xff,
|
||||||
0x00, 0x00, 0x00, 0xff,
|
0x00, 0x00, 0x00, 0xff,
|
||||||
0x00, 0x00, 0x00, 0xff,
|
0x00, 0x00, 0x00, 0xff);
|
||||||
0x00, 0x00, 0x00, 0xff};
|
|
||||||
vector float ambientLightVec;
|
vector float ambientLightVec;
|
||||||
vector float directedLightVec;
|
vector float directedLightVec;
|
||||||
vector float lightDirVec;
|
vector float lightDirVec;
|
||||||
|
@ -1122,10 +1119,8 @@ void RB_CalcDiffuseColor( unsigned char *colors )
|
||||||
vector signed int jVecInt;
|
vector signed int jVecInt;
|
||||||
vector signed short jVecShort;
|
vector signed short jVecShort;
|
||||||
vector unsigned char jVecChar, normalPerm;
|
vector unsigned char jVecChar, normalPerm;
|
||||||
#endif
|
|
||||||
ent = backEnd.currentEntity;
|
ent = backEnd.currentEntity;
|
||||||
ambientLightInt = ent->ambientLightInt;
|
ambientLightInt = ent->ambientLightInt;
|
||||||
#if idppc_altivec
|
|
||||||
// A lot of this could be simplified if we made sure
|
// A lot of this could be simplified if we made sure
|
||||||
// entities light info was 16-byte aligned.
|
// entities light info was 16-byte aligned.
|
||||||
jVecChar = vec_lvsl(0, ent->ambientLight);
|
jVecChar = vec_lvsl(0, ent->ambientLight);
|
||||||
|
@ -1145,21 +1140,13 @@ void RB_CalcDiffuseColor( unsigned char *colors )
|
||||||
|
|
||||||
zero = (vector float)vec_splat_s8(0);
|
zero = (vector float)vec_splat_s8(0);
|
||||||
VectorCopy( ent->lightDir, lightDir );
|
VectorCopy( ent->lightDir, lightDir );
|
||||||
#else
|
|
||||||
VectorCopy( ent->ambientLight, ambientLight );
|
|
||||||
VectorCopy( ent->directedLight, directedLight );
|
|
||||||
VectorCopy( ent->lightDir, lightDir );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
v = tess.xyz[0];
|
v = tess.xyz[0];
|
||||||
normal = tess.normal[0];
|
normal = tess.normal[0];
|
||||||
|
|
||||||
#if idppc_altivec
|
|
||||||
normalPerm = vec_lvsl(0,normal);
|
normalPerm = vec_lvsl(0,normal);
|
||||||
#endif
|
|
||||||
numVertexes = tess.numVertexes;
|
numVertexes = tess.numVertexes;
|
||||||
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
|
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
|
||||||
#if idppc_altivec
|
|
||||||
normalVec0 = vec_ld(0,(vector float *)normal);
|
normalVec0 = vec_ld(0,(vector float *)normal);
|
||||||
normalVec1 = vec_ld(11,(vector float *)normal);
|
normalVec1 = vec_ld(11,(vector float *)normal);
|
||||||
normalVec0 = vec_perm(normalVec0,normalVec1,normalPerm);
|
normalVec0 = vec_perm(normalVec0,normalVec1,normalPerm);
|
||||||
|
@ -1177,7 +1164,32 @@ void RB_CalcDiffuseColor( unsigned char *colors )
|
||||||
jVecChar = vec_packsu(jVecShort,jVecShort); // RGBxRGBxRGBxRGBx
|
jVecChar = vec_packsu(jVecShort,jVecShort); // RGBxRGBxRGBxRGBx
|
||||||
jVecChar = vec_sel(jVecChar,vSel,vSel); // RGBARGBARGBARGBA replace alpha with 255
|
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
|
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);
|
incoming = DotProduct (normal, lightDir);
|
||||||
if ( incoming <= 0 ) {
|
if ( incoming <= 0 ) {
|
||||||
*(int *)&colors[i*4] = ambientLightInt;
|
*(int *)&colors[i*4] = ambientLightInt;
|
||||||
|
@ -1202,7 +1214,19 @@ void RB_CalcDiffuseColor( unsigned char *colors )
|
||||||
colors[i*4+2] = j;
|
colors[i*4+2] = j;
|
||||||
|
|
||||||
colors[i*4+3] = 255;
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -610,7 +610,8 @@ static void VectorArrayNormalize(vec4_t *normals, unsigned int count)
|
||||||
/*
|
/*
|
||||||
** LerpMeshVertexes
|
** 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;
|
short *oldXyz, *newXyz, *oldNormals, *newNormals;
|
||||||
float *outXyz, *outNormal;
|
float *outXyz, *outNormal;
|
||||||
|
@ -633,7 +634,6 @@ static void LerpMeshVertexes (md3Surface_t *surf, float backlerp)
|
||||||
numVerts = surf->numVerts;
|
numVerts = surf->numVerts;
|
||||||
|
|
||||||
if ( backlerp == 0 ) {
|
if ( backlerp == 0 ) {
|
||||||
#if idppc_altivec
|
|
||||||
vector signed short newNormalsVec0;
|
vector signed short newNormalsVec0;
|
||||||
vector signed short newNormalsVec1;
|
vector signed short newNormalsVec1;
|
||||||
vector signed int newNormalsIntVec;
|
vector signed int newNormalsIntVec;
|
||||||
|
@ -687,34 +687,6 @@ static void LerpMeshVertexes (md3Surface_t *surf, float backlerp)
|
||||||
vec_ste(newNormalsFloatVec,4,outXyz);
|
vec_ste(newNormalsFloatVec,4,outXyz);
|
||||||
vec_ste(newNormalsFloatVec,8,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 {
|
} else {
|
||||||
//
|
//
|
||||||
// interpolate and copy the vertex and normal
|
// 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);
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
|
|
|
@ -218,6 +218,11 @@ typedef struct {
|
||||||
#define _3DFX_DRIVER_NAME "3dfxvgl"
|
#define _3DFX_DRIVER_NAME "3dfxvgl"
|
||||||
#define OPENGL_DRIVER_NAME "opengl32"
|
#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
|
#else
|
||||||
|
|
||||||
#define _3DFX_DRIVER_NAME "libMesaVoodooGL.so"
|
#define _3DFX_DRIVER_NAME "libMesaVoodooGL.so"
|
||||||
|
|
|
@ -16,6 +16,19 @@ endif
|
||||||
CC=gcc
|
CC=gcc
|
||||||
Q3ASM_CFLAGS=-O2 -Wall -Werror -fno-strict-aliasing
|
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
|
default: q3asm
|
||||||
|
|
||||||
q3asm: q3asm.c cmdlib.c
|
q3asm: q3asm.c cmdlib.c
|
||||||
|
|
|
@ -22,6 +22,19 @@ RMDIR=rmdir
|
||||||
BUILDDIR=build
|
BUILDDIR=build
|
||||||
BD=$(BUILDDIR)/
|
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)
|
ifeq ($(PLATFORM),SunOS)
|
||||||
INSTALL=ginstall
|
INSTALL=ginstall
|
||||||
else
|
else
|
||||||
|
|
|
@ -13,7 +13,17 @@
|
||||||
|
|
||||||
PLATFORM=$(shell uname|sed -e s/_.*//|tr A-Z a-z)
|
PLATFORM=$(shell uname|sed -e s/_.*//|tr A-Z a-z)
|
||||||
PLATFORM_RELEASE=$(shell uname -r)
|
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
|
DXSDK_DIR=C:/DXSDK
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifndef USE_CCACHE
|
||||||
|
USE_CCACHE=1
|
||||||
|
endif
|
||||||
|
export USE_CCACHE
|
||||||
|
|
||||||
ifndef USE_SDL
|
ifndef USE_SDL
|
||||||
USE_SDL=1
|
USE_SDL=1
|
||||||
endif
|
endif
|
||||||
|
@ -121,7 +136,10 @@ ifeq ($(PLATFORM),linux)
|
||||||
endif
|
endif
|
||||||
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)
|
ifeq ($(USE_OPENAL),1)
|
||||||
BASE_CFLAGS += -DUSE_OPENAL=1
|
BASE_CFLAGS += -DUSE_OPENAL=1
|
||||||
|
@ -153,6 +171,7 @@ ifeq ($(PLATFORM),linux)
|
||||||
HAVE_VM_COMPILED=true
|
HAVE_VM_COMPILED=true
|
||||||
else
|
else
|
||||||
ifeq ($(ARCH),ppc)
|
ifeq ($(ARCH),ppc)
|
||||||
|
BASE_CFLAGS += -maltivec
|
||||||
ifneq ($(VM_PPC),)
|
ifneq ($(VM_PPC),)
|
||||||
HAVE_VM_COMPILED=true
|
HAVE_VM_COMPILED=true
|
||||||
endif
|
endif
|
||||||
|
@ -181,8 +200,10 @@ ifeq ($(PLATFORM),linux)
|
||||||
CLIENT_LDFLAGS=-L/usr/X11R6/$(LIB) -lX11 -lXext -lXxf86dga -lXxf86vm
|
CLIENT_LDFLAGS=-L/usr/X11R6/$(LIB) -lX11 -lXext -lXxf86dga -lXxf86vm
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(USE_OPENAL_DLOPEN),1)
|
ifeq ($(USE_OPENAL),1)
|
||||||
CLIENT_LDFLAGS += -lopenal
|
ifneq ($(USE_OPENAL_DLOPEN),1)
|
||||||
|
CLIENT_LDFLAGS += -lopenal
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(ARCH),i386)
|
ifeq ($(ARCH),i386)
|
||||||
|
@ -216,6 +237,106 @@ ifeq ($(PLATFORM),linux)
|
||||||
|
|
||||||
else # ifeq 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
|
# SETUP AND BUILD -- MINGW32
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
@ -494,7 +615,6 @@ else # ifeq SunOS
|
||||||
#############################################################################
|
#############################################################################
|
||||||
# SETUP AND BUILD -- GENERIC
|
# SETUP AND BUILD -- GENERIC
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
CC=cc
|
CC=cc
|
||||||
BASE_CFLAGS=-DNO_VM_COMPILED
|
BASE_CFLAGS=-DNO_VM_COMPILED
|
||||||
DEBUG_CFLAGS=$(BASE_CFLAGS) -g
|
DEBUG_CFLAGS=$(BASE_CFLAGS) -g
|
||||||
|
@ -508,11 +628,17 @@ else # ifeq SunOS
|
||||||
$(B)/$(PLATFORM)q3ded
|
$(B)/$(PLATFORM)q3ded
|
||||||
|
|
||||||
endif #Linux
|
endif #Linux
|
||||||
|
endif #darwin
|
||||||
endif #mingw32
|
endif #mingw32
|
||||||
endif #FreeBSD
|
endif #FreeBSD
|
||||||
endif #IRIX
|
endif #IRIX
|
||||||
endif #SunOS
|
endif #SunOS
|
||||||
|
|
||||||
|
ifeq ($(USE_CCACHE),1)
|
||||||
|
CC := ccache $(CC)
|
||||||
|
CXX := ccache $(CXX)
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq ($(BUILD_SERVER),1)
|
ifneq ($(BUILD_SERVER),1)
|
||||||
TARGETS := $(subst $(B)/$(PLATFORM)q3ded,,$(TARGETS))
|
TARGETS := $(subst $(B)/$(PLATFORM)q3ded,,$(TARGETS))
|
||||||
endif
|
endif
|
||||||
|
@ -541,15 +667,15 @@ ifeq ($(GENERATE_DEPENDENCIES),1)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
DO_CC=$(CC) $(CFLAGS) -o $@ -c $<
|
DO_CC=$(CC) $(NOTSHLIBCFLAGS) $(CFLAGS) -o $@ -c $<
|
||||||
DO_CXX=$(CXX) $(CFLAGS) -o $@ -c $<
|
DO_CXX=$(CXX) $(NOTSHLIBCFLAGS) $(CFLAGS) -o $@ -c $<
|
||||||
DO_SMP_CC=$(CC) $(CFLAGS) -DSMP -o $@ -c $<
|
DO_SMP_CC=$(CC) $(NOTSHLIBCFLAGS) $(CFLAGS) -DSMP -o $@ -c $<
|
||||||
DO_BOT_CC=$(CC) $(CFLAGS) -DBOTLIB -o $@ -c $< # $(SHLIBCFLAGS) # bk001212
|
DO_BOT_CC=$(CC) $(NOTSHLIBCFLAGS) $(CFLAGS) -DBOTLIB -o $@ -c $< # $(SHLIBCFLAGS) # bk001212
|
||||||
DO_DEBUG_CC=$(CC) $(DEBUG_CFLAGS) -o $@ -c $<
|
DO_DEBUG_CC=$(CC) $(NOTSHLIBCFLAGS) $(DEBUG_CFLAGS) -o $@ -c $<
|
||||||
DO_SHLIB_CC=$(CC) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $<
|
DO_SHLIB_CC=$(CC) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $<
|
||||||
DO_SHLIB_DEBUG_CC=$(CC) $(DEBUG_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_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 $@
|
DO_WINDRES=$(WINDRES) -i $< -o $@
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
@ -864,6 +990,33 @@ else
|
||||||
Q3POBJ_SMP += $(B)/client/ftola.o $(B)/client/snapvectora.o
|
Q3POBJ_SMP += $(B)/client/ftola.o $(B)/client/snapvectora.o
|
||||||
endif
|
endif
|
||||||
endif #Linux-axp
|
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
|
else
|
||||||
ifeq ($(PLATFORM),SunOS)
|
ifeq ($(PLATFORM),SunOS)
|
||||||
Q3POBJ=\
|
Q3POBJ=\
|
||||||
|
@ -895,16 +1048,25 @@ ifeq ($(PLATFORM),SunOS)
|
||||||
|
|
||||||
endif #SunOS
|
endif #SunOS
|
||||||
endif #Linux
|
endif #Linux
|
||||||
|
endif #darwin
|
||||||
endif #mingw32
|
endif #mingw32
|
||||||
endif #IRIX
|
endif #IRIX
|
||||||
endif #FreeBSD
|
endif #FreeBSD
|
||||||
|
|
||||||
$(B)/$(PLATFORM)quake3$(BINEXT): $(Q3OBJ) $(Q3POBJ)
|
$(B)/$(PLATFORM)quake3$(BINEXT): $(Q3OBJ) $(Q3POBJ) $(LIBSDLMAIN)
|
||||||
$(CC) -o $@ $(Q3OBJ) $(Q3POBJ) $(CLIENT_LDFLAGS) $(LDFLAGS)
|
$(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) \
|
$(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_cgame.o : $(CDIR)/cl_cgame.c; $(DO_CC)
|
||||||
$(B)/client/cl_cin.o : $(CDIR)/cl_cin.c; $(DO_CC)
|
$(B)/client/cl_cin.o : $(CDIR)/cl_cin.c; $(DO_CC)
|
||||||
|
|
|
@ -1265,7 +1265,9 @@ static void GLW_InitExtensions( void )
|
||||||
|
|
||||||
if ( qglActiveTextureARB )
|
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 )
|
if ( glConfig.maxActiveTextures > 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,8 +45,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
//#endif
|
//#endif
|
||||||
//#include <GL/glx.h> // bk010216 - FIXME: all of the above redundant? renderer/qgl.h
|
//#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>
|
#include <dlfcn.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// bk001129 - from cvs1.17 (mkv)
|
// bk001129 - from cvs1.17 (mkv)
|
||||||
#if defined(__FX__)
|
#if defined(__FX__)
|
||||||
|
@ -60,12 +64,14 @@ void (*qfxMesaSwapBuffers)(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//GLX Functions
|
//GLX Functions
|
||||||
|
#if !defined(USE_SDL_VIDEO)
|
||||||
XVisualInfo * (*qglXChooseVisual)( Display *dpy, int screen, int *attribList );
|
XVisualInfo * (*qglXChooseVisual)( Display *dpy, int screen, int *attribList );
|
||||||
GLXContext (*qglXCreateContext)( Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct );
|
GLXContext (*qglXCreateContext)( Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct );
|
||||||
void (*qglXDestroyContext)( Display *dpy, GLXContext ctx );
|
void (*qglXDestroyContext)( Display *dpy, GLXContext ctx );
|
||||||
Bool (*qglXMakeCurrent)( Display *dpy, GLXDrawable drawable, GLXContext ctx);
|
Bool (*qglXMakeCurrent)( Display *dpy, GLXDrawable drawable, GLXContext ctx);
|
||||||
void (*qglXCopyContext)( Display *dpy, GLXContext src, GLXContext dst, GLuint mask );
|
void (*qglXCopyContext)( Display *dpy, GLXContext src, GLXContext dst, GLuint mask );
|
||||||
void (*qglXSwapBuffers)( Display *dpy, GLXDrawable drawable );
|
void (*qglXSwapBuffers)( Display *dpy, GLXDrawable drawable );
|
||||||
|
#endif
|
||||||
|
|
||||||
void ( APIENTRY * qglAccum )(GLenum op, GLfloat value);
|
void ( APIENTRY * qglAccum )(GLenum op, GLfloat value);
|
||||||
void ( APIENTRY * qglAlphaFunc )(GLenum func, GLclampf ref);
|
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 * qglActiveTextureARB )( GLenum texture );
|
||||||
void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
|
void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
|
||||||
|
|
||||||
void ( APIENTRY * qglLockArraysEXT)( int, int);
|
void ( APIENTRY * qglLockArraysEXT)( GLint, GLint);
|
||||||
void ( APIENTRY * qglUnlockArraysEXT) ( void );
|
void ( APIENTRY * qglUnlockArraysEXT) ( void );
|
||||||
|
|
||||||
void ( APIENTRY * qglPointParameterfEXT)( GLenum param, GLfloat value );
|
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)
|
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 );
|
dllAlphaFunc( func, ref );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,13 +787,13 @@ static void APIENTRY logArrayElement(GLint i)
|
||||||
|
|
||||||
static void APIENTRY logBegin(GLenum mode)
|
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 );
|
dllBegin( mode );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void APIENTRY logBindTexture(GLenum target, GLuint texture)
|
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 );
|
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)
|
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 );
|
dllBlendFunc( sfactor, dfactor );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void APIENTRY logCallList(GLuint list)
|
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 );
|
dllCallList( list );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1122,7 +1128,7 @@ static void APIENTRY logDepthRange(GLclampd zNear, GLclampd zFar)
|
||||||
|
|
||||||
static void APIENTRY logDisable(GLenum cap)
|
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 );
|
dllDisable( cap );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1176,7 +1182,7 @@ static void APIENTRY logEdgeFlagv(const GLboolean *flag)
|
||||||
|
|
||||||
static void APIENTRY logEnable(GLenum cap)
|
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 );
|
dllEnable( cap );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1504,7 +1510,7 @@ static void APIENTRY logGetTexParameteriv(GLenum target, GLenum pname, GLint *pa
|
||||||
|
|
||||||
static void APIENTRY logHint(GLenum target, GLenum mode)
|
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 );
|
dllHint( target, mode );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1923,7 +1929,7 @@ static void APIENTRY logPointSize(GLfloat size)
|
||||||
|
|
||||||
static void APIENTRY logPolygonMode(GLenum face, GLenum mode)
|
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 );
|
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)
|
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 );
|
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)
|
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 );
|
dllTexEnvi( target, pname, param );
|
||||||
}
|
}
|
||||||
static void APIENTRY logTexEnviv(GLenum target, GLenum pname, const GLint *params)
|
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)
|
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 );
|
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)
|
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 );
|
dllTexParameteri( target, pname, param );
|
||||||
}
|
}
|
||||||
static void APIENTRY logTexParameteriv(GLenum target, GLenum pname, const GLint *params)
|
static void APIENTRY logTexParameteriv(GLenum target, GLenum pname, const GLint *params)
|
||||||
|
@ -2669,12 +2675,14 @@ void QGL_Shutdown( void )
|
||||||
if( r_GLlibCoolDownMsec->integer )
|
if( r_GLlibCoolDownMsec->integer )
|
||||||
usleep( r_GLlibCoolDownMsec->integer * 1000 );
|
usleep( r_GLlibCoolDownMsec->integer * 1000 );
|
||||||
|
|
||||||
|
#if USE_SDL_VIDEO
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||||
|
#else
|
||||||
dlclose ( glw_state.OpenGLLib );
|
dlclose ( glw_state.OpenGLLib );
|
||||||
|
#endif
|
||||||
glw_state.OpenGLLib = NULL;
|
glw_state.OpenGLLib = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
glw_state.OpenGLLib = NULL;
|
|
||||||
|
|
||||||
qglAccum = NULL;
|
qglAccum = NULL;
|
||||||
qglAlphaFunc = NULL;
|
qglAlphaFunc = NULL;
|
||||||
qglAreTexturesResident = NULL;
|
qglAreTexturesResident = NULL;
|
||||||
|
@ -3022,15 +3030,22 @@ void QGL_Shutdown( void )
|
||||||
qfxMesaSwapBuffers = NULL;
|
qfxMesaSwapBuffers = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(USE_SDL_VIDEO)
|
||||||
qglXChooseVisual = NULL;
|
qglXChooseVisual = NULL;
|
||||||
qglXCreateContext = NULL;
|
qglXCreateContext = NULL;
|
||||||
qglXDestroyContext = NULL;
|
qglXDestroyContext = NULL;
|
||||||
qglXMakeCurrent = NULL;
|
qglXMakeCurrent = NULL;
|
||||||
qglXCopyContext = NULL;
|
qglXCopyContext = NULL;
|
||||||
qglXSwapBuffers = 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 )
|
#define GPA( a ) dlsym( glw_state.OpenGLLib, a )
|
||||||
|
#endif
|
||||||
|
|
||||||
void *qwglGetProcAddress(char *symbol)
|
void *qwglGetProcAddress(char *symbol)
|
||||||
{
|
{
|
||||||
|
@ -3039,6 +3054,8 @@ void *qwglGetProcAddress(char *symbol)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *do_dlerror(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** QGL_Init
|
** QGL_Init
|
||||||
**
|
**
|
||||||
|
@ -3052,23 +3069,39 @@ void *qwglGetProcAddress(char *symbol)
|
||||||
|
|
||||||
qboolean QGL_Init( const char *dllname )
|
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];
|
char fn[1024];
|
||||||
// FILE *fp; // bk001204 - unused
|
// FILE *fp; // bk001204 - unused
|
||||||
|
|
||||||
// if we are not setuid, try current directory
|
// if we are not setuid, try current directory
|
||||||
if (1) {
|
if (dllname != NULL) {
|
||||||
getcwd(fn, sizeof(fn));
|
getcwd(fn, sizeof(fn));
|
||||||
Q_strcat(fn, sizeof(fn), "/");
|
Q_strcat(fn, sizeof(fn), "/");
|
||||||
Q_strcat(fn, sizeof(fn), dllname);
|
Q_strcat(fn, sizeof(fn), dllname);
|
||||||
|
|
||||||
if ( ( glw_state.OpenGLLib = dlopen( fn, RTLD_LAZY ) ) == 0 ) {
|
#if USE_SDL_VIDEO
|
||||||
ri.Printf(PRINT_ALL, "QGL_Init: Can't load %s from /etc/ld.so.conf or current dir: %s\n", dllname, dlerror());
|
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;
|
return qfalse;
|
||||||
}
|
}
|
||||||
} else {
|
} 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;
|
return qfalse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3418,12 +3451,14 @@ qboolean QGL_Init( const char *dllname )
|
||||||
qfxMesaSwapBuffers = GPA("fxMesaSwapBuffers");
|
qfxMesaSwapBuffers = GPA("fxMesaSwapBuffers");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(USE_SDL_VIDEO)
|
||||||
qglXChooseVisual = GPA("glXChooseVisual");
|
qglXChooseVisual = GPA("glXChooseVisual");
|
||||||
qglXCreateContext = GPA("glXCreateContext");
|
qglXCreateContext = GPA("glXCreateContext");
|
||||||
qglXDestroyContext = GPA("glXDestroyContext");
|
qglXDestroyContext = GPA("glXDestroyContext");
|
||||||
qglXMakeCurrent = GPA("glXMakeCurrent");
|
qglXMakeCurrent = GPA("glXMakeCurrent");
|
||||||
qglXCopyContext = GPA("glXCopyContext");
|
qglXCopyContext = GPA("glXCopyContext");
|
||||||
qglXSwapBuffers = GPA("glXSwapBuffers");
|
qglXSwapBuffers = GPA("glXSwapBuffers");
|
||||||
|
#endif
|
||||||
|
|
||||||
qglLockArraysEXT = NULL;
|
qglLockArraysEXT = NULL;
|
||||||
qglUnlockArraysEXT = NULL;
|
qglUnlockArraysEXT = NULL;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
*
|
*
|
||||||
* I wrote such a beast originally for Loki's port of Heavy Metal: FAKK2,
|
* 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
|
* 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.
|
* GPL release of Quake 3.
|
||||||
*
|
*
|
||||||
* Written by Ryan C. Gordon (icculus@icculus.org). Please refer to
|
* 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_allowSoftwareGL; // don't abort out if the pixelformat claims software
|
||||||
cvar_t *r_previousglDriver;
|
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.
|
* Find the first occurrence of find in s.
|
||||||
*/
|
*/
|
||||||
|
@ -217,8 +234,12 @@ static const char *XLateKey(SDL_keysym *keysym, int *key)
|
||||||
default: break;
|
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;
|
char ch = (char) keysym->unicode;
|
||||||
if (ch == '~')
|
if (ch == '~')
|
||||||
*key = '~'; // console HACK
|
*key = '~'; // console HACK
|
||||||
|
@ -231,17 +252,25 @@ static const char *XLateKey(SDL_keysym *keysym, int *key)
|
||||||
// ch = ch - 'A' + 'a';
|
// ch = ch - 'A' + 'a';
|
||||||
|
|
||||||
buf[0] = ch;
|
buf[0] = ch;
|
||||||
}
|
}
|
||||||
else if(keysym->unicode == 8) // ctrl-h
|
else if(keysym->unicode == 8) // ctrl-h
|
||||||
buf[0] = 8;
|
buf[0] = 8;
|
||||||
|
}
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void install_grabs(void)
|
static void install_grabs(void)
|
||||||
{
|
{
|
||||||
SDL_ShowCursor(0);
|
|
||||||
SDL_WM_GrabInput(SDL_GRAB_ON);
|
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)
|
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 )
|
void GLimp_Shutdown( void )
|
||||||
{
|
{
|
||||||
IN_Shutdown();
|
IN_Shutdown();
|
||||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
|
||||||
screen = NULL;
|
screen = NULL;
|
||||||
|
|
||||||
memset( &glConfig, 0, sizeof( glConfig ) );
|
memset( &glConfig, 0, sizeof( glConfig ) );
|
||||||
|
@ -448,16 +476,8 @@ static qboolean GLW_StartDriverAndSetMode( const char *drivername,
|
||||||
{
|
{
|
||||||
rserr_t err;
|
rserr_t err;
|
||||||
|
|
||||||
if (!SDL_WasInit(SDL_INIT_VIDEO))
|
if (GLimp_sdl_init_video() == qfalse)
|
||||||
{
|
return qfalse;
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't ever bother going into fullscreen with a voodoo card
|
// don't ever bother going into fullscreen with a voodoo card
|
||||||
#if 1 // JDC: I reenabled this
|
#if 1 // JDC: I reenabled this
|
||||||
|
@ -714,17 +734,17 @@ static void GLW_InitExtensions( void )
|
||||||
qglClientActiveTextureARB = NULL;
|
qglClientActiveTextureARB = NULL;
|
||||||
if ( Q_stristr( glConfig.extensions_string, "GL_ARB_multitexture" ) )
|
if ( Q_stristr( glConfig.extensions_string, "GL_ARB_multitexture" ) )
|
||||||
{
|
{
|
||||||
// !!! FIXME: Use SDL_GL_GetProcAddress instead?
|
|
||||||
if ( r_ext_multitexture->value )
|
if ( r_ext_multitexture->value )
|
||||||
{
|
{
|
||||||
qglMultiTexCoord2fARB = ( PFNGLMULTITEXCOORD2FARBPROC ) dlsym( glw_state.OpenGLLib, "glMultiTexCoord2fARB" );
|
qglMultiTexCoord2fARB = ( PFNGLMULTITEXCOORD2FARBPROC ) SDL_GL_GetProcAddress( "glMultiTexCoord2fARB" );
|
||||||
qglActiveTextureARB = ( PFNGLACTIVETEXTUREARBPROC ) dlsym( glw_state.OpenGLLib, "glActiveTextureARB" );
|
qglActiveTextureARB = ( PFNGLACTIVETEXTUREARBPROC ) SDL_GL_GetProcAddress( "glActiveTextureARB" );
|
||||||
qglClientActiveTextureARB = ( PFNGLCLIENTACTIVETEXTUREARBPROC ) dlsym( glw_state.OpenGLLib, "glClientActiveTextureARB" );
|
qglClientActiveTextureARB = ( PFNGLCLIENTACTIVETEXTUREARBPROC ) SDL_GL_GetProcAddress( "glClientActiveTextureARB" );
|
||||||
|
|
||||||
if ( qglActiveTextureARB )
|
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 )
|
if ( glConfig.maxActiveTextures > 1 )
|
||||||
{
|
{
|
||||||
ri.Printf( PRINT_ALL, "...using GL_ARB_multitexture\n" );
|
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 )
|
if ( r_ext_compiled_vertex_array->value )
|
||||||
{
|
{
|
||||||
ri.Printf( PRINT_ALL, "...using GL_EXT_compiled_vertex_array\n" );
|
ri.Printf( PRINT_ALL, "...using GL_EXT_compiled_vertex_array\n" );
|
||||||
qglLockArraysEXT = ( void ( APIENTRY * )( int, int ) ) dlsym( glw_state.OpenGLLib, "glLockArraysEXT" );
|
qglLockArraysEXT = ( void ( APIENTRY * )( GLint, GLint ) ) SDL_GL_GetProcAddress( "glLockArraysEXT" );
|
||||||
qglUnlockArraysEXT = ( void ( APIENTRY * )( void ) ) dlsym( glw_state.OpenGLLib, "glUnlockArraysEXT" );
|
qglUnlockArraysEXT = ( void ( APIENTRY * )( void ) ) SDL_GL_GetProcAddress( "glUnlockArraysEXT" );
|
||||||
if (!qglLockArraysEXT || !qglUnlockArraysEXT)
|
if (!qglLockArraysEXT || !qglUnlockArraysEXT)
|
||||||
{
|
{
|
||||||
ri.Error (ERR_FATAL, "bad getprocaddress");
|
ri.Error (ERR_FATAL, "bad getprocaddress");
|
||||||
|
@ -783,7 +803,7 @@ static qboolean GLW_LoadOpenGL( const char *name )
|
||||||
{
|
{
|
||||||
qboolean fullscreen;
|
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
|
// disable the 3Dfx splash screen and set gamma
|
||||||
// we do this all the time, but it shouldn't hurt anything
|
// we do this all the time, but it shouldn't hurt anything
|
||||||
|
|
|
@ -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
|
<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)
|
void Snd_Memset (void* dest, const int val, const size_t count)
|
||||||
{
|
{
|
||||||
int *pDest;
|
int *pDest;
|
||||||
|
|
|
@ -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
|
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
|
#error You should include this file only on Linux/FreeBSD/Solaris platforms
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,17 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#ifdef __linux__ // rb010123
|
#ifdef __linux__ // rb010123
|
||||||
#include <mntent.h>
|
#include <mntent.h>
|
||||||
#endif
|
#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>
|
#include <dlfcn.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <fpu_control.h> // bk001213 - force dumps on divide by zero
|
#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
|
#include "linux_local.h" // bk001204
|
||||||
|
|
||||||
// Structure containing functions exported from refresh DLL
|
#if idppc_altivec
|
||||||
refexport_t re;
|
#ifdef MACOS_X
|
||||||
|
#include <Carbon/Carbon.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned sys_frame_time;
|
unsigned sys_frame_time;
|
||||||
|
|
||||||
|
@ -349,8 +362,33 @@ void Sys_Quit (void) {
|
||||||
Sys_Exit(0);
|
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)
|
void Sys_Init(void)
|
||||||
{
|
{
|
||||||
|
Sys_DetectAltivec();
|
||||||
|
|
||||||
Cmd_AddCommand ("in_restart", Sys_In_Restart_f);
|
Cmd_AddCommand ("in_restart", Sys_In_Restart_f);
|
||||||
|
|
||||||
Cvar_Set( "arch", OS_STRING " " ARCH_STRING );
|
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
|
Sys_UnloadDll
|
||||||
|
@ -651,16 +699,23 @@ Sys_UnloadDll
|
||||||
*/
|
*/
|
||||||
void Sys_UnloadDll( void *dllHandle ) {
|
void Sys_UnloadDll( void *dllHandle ) {
|
||||||
// bk001206 - verbose error reporting
|
// bk001206 - verbose error reporting
|
||||||
const char* err; // rb010123 - now const
|
|
||||||
if ( !dllHandle )
|
if ( !dllHandle )
|
||||||
{
|
{
|
||||||
Com_Printf("Sys_UnloadDll(NULL)\n");
|
Com_Printf("Sys_UnloadDll(NULL)\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_SDL_VIDEO
|
||||||
|
SDL_UnloadObject(dllHandle);
|
||||||
|
#else
|
||||||
dlclose( dllHandle );
|
dlclose( dllHandle );
|
||||||
err = dlerror();
|
{
|
||||||
if ( err != NULL )
|
const char* err; // rb010123 - now const
|
||||||
Com_Printf ( "Sys_UnloadGame failed on dlclose: \"%s\"!\n", err );
|
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 );
|
fn = FS_BuildOSPath( base, gamedir, fname );
|
||||||
Com_Printf( "Sys_LoadDll(%s)... \n", fn );
|
Com_Printf( "Sys_LoadDll(%s)... \n", fn );
|
||||||
|
|
||||||
|
#if USE_SDL_VIDEO
|
||||||
|
libHandle = SDL_LoadObject(fn);
|
||||||
|
#else
|
||||||
libHandle = dlopen( fn, Q_RTLD );
|
libHandle = dlopen( fn, Q_RTLD );
|
||||||
|
#endif
|
||||||
|
|
||||||
if(!libHandle) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,20 +811,31 @@ void *Sys_LoadDll( const char *name, char *fqpath ,
|
||||||
return NULL;
|
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" );
|
*entryPoint = dlsym( libHandle, "vmMain" );
|
||||||
|
#endif
|
||||||
|
|
||||||
if ( !*entryPoint || !dllEntry )
|
if ( !*entryPoint || !dllEntry )
|
||||||
{
|
{
|
||||||
err = dlerror();
|
err = do_dlerror();
|
||||||
#ifndef NDEBUG // bk001206 - in debug abort on failure
|
#ifndef NDEBUG // bk001206 - in debug abort on failure
|
||||||
Com_Error ( ERR_FATAL, "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err );
|
Com_Error ( ERR_FATAL, "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err );
|
||||||
#else
|
#else
|
||||||
Com_Printf ( "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err );
|
Com_Printf ( "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err );
|
||||||
#endif
|
#endif
|
||||||
|
#if USE_SDL_VIDEO
|
||||||
|
SDL_UnloadObject(libHandle);
|
||||||
|
#else
|
||||||
dlclose( libHandle );
|
dlclose( libHandle );
|
||||||
err = dlerror();
|
err = do_dlerror();
|
||||||
if ( err != NULL )
|
if ( err != NULL )
|
||||||
Com_Printf ( "Sys_LoadDll(%s) failed dlcose:\n\"%s\"\n", name, err );
|
Com_Printf ( "Sys_LoadDll(%s) failed dlcose:\n\"%s\"\n", name, err );
|
||||||
|
#endif
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Com_Printf ( "Sys_LoadDll(%s) found **vmMain** at %p \n", name, *entryPoint ); // bk001212
|
Com_Printf ( "Sys_LoadDll(%s) found **vmMain** at %p \n", name, *entryPoint ); // bk001212
|
||||||
|
@ -1322,4 +1393,7 @@ int main ( int argc, char* argv[] )
|
||||||
#endif
|
#endif
|
||||||
Com_Frame ();
|
Com_Frame ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue