Move cocoa-merge (GUSTO) to trunk
git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@289 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
parent
04dee7fe04
commit
1264b83cf0
148
Doc/FAQ.TXT
Normal file
148
Doc/FAQ.TXT
Normal file
@ -0,0 +1,148 @@
|
||||
Oolite-Linux Frequently Asked Questions
|
||||
=======================================
|
||||
|
||||
Note: Long answers to questions about installing and gameplay can be
|
||||
found in README.TXT and PLAYING.TXT respectively.
|
||||
|
||||
General questions about Oolite for any platform
|
||||
-----------------------------------------------
|
||||
1. What's the point of the game?
|
||||
To fly from planet to planet, buying and selling goods, shooting pirates
|
||||
or committing acts of piracy. There's no goal other than perhaps to achieve
|
||||
the rank of ELITE.
|
||||
|
||||
1.1. I'm still confused, how do I play?
|
||||
Have a look at Ian Bell's Flight Training Manual for the original BBC Elite,
|
||||
some of Oolite's control keys are different from the original, so be sure
|
||||
to read it alongside the Oolite PLAYING.TXT file..
|
||||
( http://www.iancgbell.clara.net/elite/ )
|
||||
|
||||
1.2. What do the various colors represent on the radar?
|
||||
White - unpowered items that can't mass-lock the in-system drive.
|
||||
Green/Yellow - navigation buoys.
|
||||
Yellow - powered craft.
|
||||
Red - powered craft identified as hostile.
|
||||
Green - space stations.
|
||||
Green/Red - thargoids
|
||||
Purple - police
|
||||
Blue/Red - police on intercept
|
||||
Red/Yellow - active mine (about to detonate)
|
||||
|
||||
1.3. Why are the ships so slow? It takes up to half-an-hour to get to the
|
||||
spacestation when you enter a system!
|
||||
Oolite is a simulation game — one based on a game design that comes from
|
||||
a time before 'twitch' gaming. That said, there are plenty of ways to speed
|
||||
up your game and cut that journey time dramatically. For the full story
|
||||
read this post on the Oolite Bulletin Board.
|
||||
( http://aegidian.org/bb/viewtopic.php?t=301 )
|
||||
|
||||
1.4. My keyboard doesn't have a particular key used by Oolite, what can
|
||||
I do to change the keys?
|
||||
Oolite reads a key configuration file called keyconfig.plist that (from v1.40)
|
||||
you can find at /AddOns/Config/keyconfig.plist (previous versions of
|
||||
Oolite can also read this file but you have to create it first). You
|
||||
can open this file in any text editor and change the ASCII values of
|
||||
the keys used to suit your own preferences.
|
||||
|
||||
2. Does it work on Mac OS X 10.2 (Jaguar)?
|
||||
Yes, from version 1.20 to version 1.51 Oolite works with Mac OS X 10.2.8.
|
||||
There are still has some problems with Speech Synthesis and handling
|
||||
events in full-screen mode though, so you're advised not to use those
|
||||
options.
|
||||
Keeping Oolite compatible with 10.2.8 has been a task with diminishing
|
||||
returns for me, and from v1.52 I will only be supporting Mac OS X 10.3
|
||||
and higher.
|
||||
|
||||
3. Is there a port for the PC or Linux?
|
||||
Yes. Some people are working on this, porting my code to GNUStep and SDL.
|
||||
You can find links to their work under 'Ports' in the nav-bar to the left
|
||||
|
||||
4. I have a question not answered here, where can I get help?
|
||||
At the Oolite Bulletin Boards, the Elite Bulletin Board System, or by
|
||||
emailing the author.
|
||||
Oolite BBS: http://aegidian.org/bb
|
||||
Elite BBS: http://www.alioth.net/cgi-bin/bbs.pl?siteId=1&action=show
|
||||
Author: <oolite@aegidian.org>
|
||||
Linux port: <dyls@alioth.net> / <dajt@...>
|
||||
|
||||
|
||||
Linux Specific Questions
|
||||
------------------------
|
||||
1. Why does Oolite use GNUstep?
|
||||
Oolite was written for the Macintosh and was at 'production level' for about
|
||||
a year before the Linux port was started. Mac OS X is essentially what
|
||||
NeXTstep/OpenStep became when Apple bought NeXT. Oolite was written in
|
||||
Objective-C using Cocoa (the Macintosh Objective-C libraries). GNUstep
|
||||
provide the same Objective-C classes that are used by Mac OS X for building
|
||||
utilities and applications.
|
||||
To not need GNUstep, Oolite would have to be totally rewritten from scratch.
|
||||
There was a project early on to make a Win32 port by converting objc to C++
|
||||
automatically, but the project seems to have vanished. It is likely that
|
||||
the mechanical conversion of objc to C++ would be the easy bit - then
|
||||
you still have to re-implement Cocoa/GNUstep as C++ classes; a task
|
||||
of truly epic proportions.
|
||||
Even if it was practical, it would mean that any new features implemented
|
||||
for a C++ version of the game would have to be backported into the ObjC
|
||||
version of the game on the Mac, a much more troublesome task than the
|
||||
simple code merges that are possible now, as the GNUstep code and
|
||||
Mac OS X code are 99% the same.
|
||||
|
||||
2. What are the positives of using GNUstep?
|
||||
A well developed object oriented library for Objective-C, plus the just mentioned commonality with the OS X code base which forms the
|
||||
root of Oolite.
|
||||
Oolite probably also has the distinction of being the only proper
|
||||
GNUstep OpenGL game :-)
|
||||
|
||||
3. What are the downsides of using GNUstep?
|
||||
Most Linux users don't have GNUstep installed. This is easily solved with
|
||||
the dependency pack that comes with this Oolite binary installer, but it
|
||||
does mean Oolite uses a bit more memory than you'd expect if the game
|
||||
was written just with C and SDL/OpenGL, and the performance probably
|
||||
takes a bit of a hit because Objective-C uses more 'real' message passing
|
||||
than languages like C++. However, I do have a 5 year old laptop I do
|
||||
tests on, and it runs fine on that.
|
||||
|
||||
4. What distros will Oolite run on?
|
||||
Hopefully any distro that came out within the last couple of years
|
||||
with a 2.4 or 2.6 kernel.
|
||||
The package you have now is known to run on:
|
||||
- Gentoo
|
||||
- Fedora Core 2
|
||||
- CentOS 4.1
|
||||
- Ubuntu 5.04
|
||||
- Debian Sid (Sept 2005)
|
||||
- Knoppix 3.7 (with the 2.4 kernel)
|
||||
|
||||
5. What dependencies do I need?
|
||||
Aside from X, you'll need accelerated OpenGL. The game plays well with
|
||||
relatively modest accelerated 3D hardware - the frame rate is acceptable
|
||||
on thte Radeon Mobility M6 on older laptops, and I've found it playable
|
||||
on HP/Compaq 'business' PCs such as the d510 which has cheap integrated
|
||||
onboard Intel graphics. Of course it plays VERY well on my development
|
||||
system with is a P4 with a GeForce 4 Ti 4200.
|
||||
Aside from that, you shouldn't need any additional software dependencies
|
||||
since most of the libraries are part of the dependencies pack that's
|
||||
included with this package.
|
||||
|
||||
6. Where can I get the source code for the game?
|
||||
You can get the full game source from the following two places:
|
||||
FTP: ftp://ftp.alioth.net/oolite (look for the 'src' tarballs)
|
||||
HTTP: http://oolite-linux.berlios.de
|
||||
|
||||
You can also get the latest source by anonymous SVN - see
|
||||
http://oolite-linux.berlios.de for more details.
|
||||
|
||||
Source code (mainly tarballs) for the dependency pack can be found
|
||||
at ftp.alioth.net/oolite-depends-source
|
||||
|
||||
7. What about other (non x86) architectures?
|
||||
Sadly, I don't have any non-x86 architecture systems I can install Linux on
|
||||
to build the game. However, binaries for other architectures are always
|
||||
welcome - please contact <dyls@alioth.net> if you've successfully built
|
||||
and run the game on non-x86 platforms. You shouldn't run into endian-ness
|
||||
problems as it already runs on macppc under OS X, but I've heard the odd
|
||||
report that building GNUstep on 64-bit archs failed - but if you have
|
||||
an amd64 system - please try and build it and let me know the results!
|
||||
(Additionally, last time I tried to build GNUstep on Fedora Core 4 it failed
|
||||
due to an internal compiler error in gcc 4)
|
||||
|
33
Doc/LICENSE.TXT
Normal file
33
Doc/LICENSE.TXT
Normal file
@ -0,0 +1,33 @@
|
||||
Copyright (c) 2004, Giles C Williams
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons
|
||||
Attribution-NonCommercial-ShareAlike License.
|
||||
To view a copy of this license, visit
|
||||
http://creativecommons.org/licenses/by-nc-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford,
|
||||
California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Noncommercial. You may not use this work for commercial purposes.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical
|
||||
to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the
|
||||
license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the
|
||||
copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
106
Doc/PORTING.TXT
Normal file
106
Doc/PORTING.TXT
Normal file
@ -0,0 +1,106 @@
|
||||
Porting Oolite
|
||||
==============
|
||||
|
||||
Oolite is portable to any platform that supports SDL and GNUstep. It is
|
||||
known to run on Linux, FreeBSD 5 and 6 and SGI IRIX. (The OS X version
|
||||
is the 'canonical' version - Oolite appeared on Mac OS X first and was
|
||||
later ported). It is also known to run under Windows, however the
|
||||
Windows port is currently at alpha test level (GNUstep on Windows isn't
|
||||
as complete as it is on Unix).
|
||||
|
||||
Oolite doesn't care about the endian-ness of the architecture - so far,
|
||||
it is known to have run on PowerPC, Intel/amd x86, amd x86_64 (and
|
||||
presumably Intel's emt64 when it's available) and 64-bit MIPS.
|
||||
|
||||
Oolite uses the BSD strl* string functions. These aren't included in
|
||||
GNU's libc, so make sure that src/BSDCompat files are included in your
|
||||
build if you are using a libc that doesn't have the strl* functions.
|
||||
|
||||
Making binary packages for your platform
|
||||
========================================
|
||||
There is a tarball installer system. To generate a tarball installer
|
||||
for your platform, run 'tools/mktarballs'. The result is deposited in
|
||||
TarballPackages off the root of this repository.
|
||||
|
||||
There should be a directory 'deps/OPSYS-CPU-deps', where OPSYS is
|
||||
the OS reported by 'uname' with no flags, and CPU is the result of
|
||||
'uname -p' (for i686 etc. this is converted to x86). If you are making
|
||||
a new dependency bundle for your platform, deps/OPSYS-CPU-deps should
|
||||
contain the following:
|
||||
|
||||
In the root:
|
||||
|
||||
install A shell script that installs Oolite on the user's computer
|
||||
oolite.src A shell script fragment that is used to make the shell
|
||||
script 'oolite' that runs the game.
|
||||
oolite-update.src A shell script fragment that can rsync updates.
|
||||
PLAYING.TXT Brief players guid
|
||||
README.TXT Readme for your platform
|
||||
|
||||
Subdirectories:
|
||||
oolite-deps
|
||||
GNUstep A minimalist set of GNUstep run time files
|
||||
lib Shared libraries that support the game
|
||||
|
||||
If your platform does not yet have this dependencies directory, you can
|
||||
model yours on the Linux-x86-deps directory. Most things will be the
|
||||
same. (The reason PLAYING.TXT is here is that it may vary slightly from
|
||||
platform to platform).
|
||||
|
||||
Issues you may encounter when building Oolite on a new platform
|
||||
===============================================================
|
||||
|
||||
Symptom:
|
||||
Altitude bar drawn right across the screen, time under the scanner
|
||||
showing stupid value (it should be something like NNNNNNN:NN:NN:NN),
|
||||
probably no rotating Cobra showing on startup (and no view out of the
|
||||
window when you launch your ship)
|
||||
|
||||
Cause:
|
||||
Bad maths.
|
||||
floor(), part of the standard C math library, is returning funny values
|
||||
or your int type is not at least 32 bits wide.
|
||||
Make sure #include <math.h> is done in all applicable files; for Linux
|
||||
this was put in oolite-linux.h which is included by every file.
|
||||
|
||||
Check that floor() returns a sensible value by writing a short program that
|
||||
does:
|
||||
|
||||
int result;
|
||||
double thing=180058016009.741669;
|
||||
result=floor(thing / 86400.0);
|
||||
printf("Result is %d and thing is %f\n", result, thing);
|
||||
|
||||
Result should equal 2084004. Try it including math.h and not including
|
||||
math.h and note any differences. If it gives the right result with math.h
|
||||
but the wrong result without, then you've not included math.h
|
||||
|
||||
In the case that your int type is only 16 bits, this will probably work:
|
||||
#define int long
|
||||
|
||||
and put it in your equivalent of oolite-linux.h.
|
||||
|
||||
Additional info: see the manpage for floor().
|
||||
|
||||
TODO: Include an assertion on startup that causes the game to exit
|
||||
immediately with an error message describing the problem if floor()
|
||||
doesn't return the correct value. I'll only bother if this problem
|
||||
keeps cropping up. An error message that can be reported is much
|
||||
better than a vague description of these symptoms by some guy who
|
||||
just wants to play the game.
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Symptom: Floating point exceptions
|
||||
|
||||
Cause: Some rhs of / and % expressions are turning out to be zero (I
|
||||
assume this isn't the case on OS X). In some instances, the simple
|
||||
fix of doing an if(rhs_of_expression)... before the div or mod
|
||||
operation is appropriate. It's probably best to look for the root
|
||||
cause of why the rhs is zero in the first place to check that it's not
|
||||
harmless and you're not going to hide a new problem or hide the root
|
||||
cause by doing this test.
|
||||
|
||||
The location of the exception is easily found by doing 'make debug=yes'
|
||||
and doing 'debugapp oolite.debug' and then looking at the line of code
|
||||
it crashes in.
|
||||
|
10
GNUmakefile
10
GNUmakefile
@ -1,14 +1,18 @@
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
CP = cp
|
||||
vpath %.m src/SDL:src/Core
|
||||
vpath %.h src/SDL:src/Core
|
||||
vpath %.c src/SDL:src/Core:src/BSDCompat
|
||||
ADDITIONAL_INCLUDE_DIRS = -Isrc/SDL -Isrc/Core -Isrc/BSDCompat
|
||||
GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_USER_ROOT)
|
||||
ADDITIONAL_GUI_LIBS = -lGLU -lGL -lSDL -lpthread -lSDL_mixer -lSDL_image -lSDL_gfx
|
||||
ADDITIONAL_CFLAGS = -DLINUX `sdl-config --cflags`
|
||||
ADDITIONAL_CFLAGS = -DLINUX -DNEED_STRLCPY `sdl-config --cflags`
|
||||
ADDITIONAL_OBJCFLAGS = -DLOADSAVEGUI -DLINUX -DHAVE_SOUND -Wno-import `sdl-config --cflags`
|
||||
APP_NAME = oolite
|
||||
oolite_LIB_DIRS += -L/usr/X11R6/lib/
|
||||
|
||||
oolite_C_FILES = vector.c legacy_random.c
|
||||
oolite_OBJC_FILES = Comparison.m AI.m DustEntity.m Entity.m GameController.m GuiDisplayGen.m HeadUpDisplay.m main.m MyOpenGLView.m OpenGLSprite.m ParticleEntity.m PlanetEntity.m PlayerEntity_Additions.m PlayerEntity_contracts.m PlayerEntity.m ResourceManager.m RingEntity.m ShipEntity_AI.m ShipEntity.m SkyEntity.m StationEntity.m TextureStore.m Universe.m OOSound.m OOMusic.m SDLImage.m LoadSave.m OOFileManager.m JoystickHandler.m PlayerEntity_StickMapper.m OOTrumble.m WormholeEntity.m ScannerExtension.m
|
||||
oolite_C_FILES = vector.c legacy_random.c strlcpy.c
|
||||
oolite_OBJC_FILES = Comparison.m AI.m DustEntity.m Entity.m GameController.m GuiDisplayGen.m HeadUpDisplay.m main.m MyOpenGLView.m OpenGLSprite.m ParticleEntity.m PlanetEntity.m PlayerEntity_Additions.m PlayerEntity_contracts.m PlayerEntity_Controls.m PlayerEntity_Sound.m PlayerEntity.m ResourceManager.m RingEntity.m ShipEntity_AI.m ShipEntity.m SkyEntity.m StationEntity.m TextureStore.m Universe.m OOSound.m OOMusic.m SDLImage.m LoadSave.m OOFileManager.m JoystickHandler.m PlayerEntity_StickMapper.m OOBasicSoundReferencePoint.m OOBasicSoundSource.m OOCharacter.m OOTrumble.m WormholeEntity.m ScannerExtension.m OOXMLExtensions.m MutableDictionaryExtension.m Geometry.m Octree.m CollisionRegion.m
|
||||
|
||||
include $(GNUSTEP_MAKEFILES)/application.make
|
||||
include GNUmakefile.postamble
|
||||
|
@ -11,5 +11,5 @@ after-all::
|
||||
rm -rf $(CONTENTDIR)
|
||||
$(MKDIRS) $(CONTENTDIR)
|
||||
$(CP) -r Resources $(CONTENTDIR)/Resources
|
||||
$(CP) Resources/Info-Oolite.plist $(GNUSTEP_OW)
|
||||
$(CP) src/Cocoa/Info-Oolite.plist $(GNUSTEP_OW)
|
||||
|
||||
|
113
OOAlsaSound.h
113
OOAlsaSound.h
@ -1,113 +0,0 @@
|
||||
//
|
||||
// OOALSASound.h: Interface for oolite to the Advanced Linux Sound
|
||||
// Achitecture.
|
||||
// Implements methods from NSSound which are used by oolite.
|
||||
//
|
||||
// It is a bit of a stopgap measure since the base NSSound is fine,
|
||||
// well, except the gnustep_sndd (sound daemon) crashes each time
|
||||
// it plays a sound, and it probably uses OSS instead of ALSA.
|
||||
// We also don't want a dependency on gnustep_sndd for statically-linked
|
||||
// versions of oolite.
|
||||
//
|
||||
// Dylan Smith, 2005-04-22
|
||||
//
|
||||
|
||||
#import <AppKit/NSSound.h>
|
||||
#import <Foundation/NSLock.h>
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
@interface OOSound : NSSound
|
||||
{
|
||||
BOOL isPlaying;
|
||||
}
|
||||
|
||||
- (BOOL) pause;
|
||||
- (BOOL) isPlaying;
|
||||
- (BOOL) play;
|
||||
- (BOOL) stop;
|
||||
- (BOOL) resume;
|
||||
|
||||
// we only do 44.1kHz so resample anything that's not. This makes
|
||||
// the mixer much simpler. TODO: make the mixer better.
|
||||
- (void) resample;
|
||||
|
||||
// accessor methods. Only OOAlsaSoundThread should be calling these.
|
||||
- (NSData *)getData;
|
||||
- (float)getSampleRate;
|
||||
- (float)getFrameSize;
|
||||
- (long)getDataSize;
|
||||
- (long)getFrameCount;
|
||||
- (int)getChannelCount;
|
||||
- (const unsigned char *)getBufferEnd;
|
||||
|
||||
// call startup when starting to play a sound, and resetState when
|
||||
// finishing. The two methods set the pointers right to do stuff.
|
||||
- (void)resetState;
|
||||
- (void)startup;
|
||||
|
||||
@end
|
||||
|
||||
// Some constants. (We normalize anything sent to us to these values)
|
||||
#define PERIODS 2
|
||||
#define PERIODSIZE 8192
|
||||
#define MIXBUFSIZE 2048
|
||||
#define SAMPLERATE 44100
|
||||
#define CHANNELS 2
|
||||
#define MAXTRACKS 6
|
||||
#define FRAMESIZE 4
|
||||
|
||||
// Instances of this class control a per-PCM thread that is responsible
|
||||
// for controlling access to the hardware.
|
||||
|
||||
typedef unsigned long Frame;
|
||||
typedef short Sample;
|
||||
#ifndef BYTE
|
||||
typedef unsigned char BYTE;
|
||||
#endif
|
||||
|
||||
typedef struct _soundChunk
|
||||
{
|
||||
Frame *buf;
|
||||
Frame *bufEnd;
|
||||
} SoundChunk;
|
||||
|
||||
@interface OOAlsaSoundThread : NSObject
|
||||
{
|
||||
snd_pcm_t *pcm_handle;
|
||||
snd_pcm_hw_params_t *hwparams;
|
||||
unsigned long bufsz;
|
||||
|
||||
// sounds to play
|
||||
OOSound *track[MAXTRACKS];
|
||||
SoundChunk trackBuffer[MAXTRACKS];
|
||||
Frame *chunkBuf;
|
||||
}
|
||||
|
||||
// init creates the thread and returns self.
|
||||
- (id) init;
|
||||
|
||||
// soundThread is a single thread per ALSA PCM device. It should only
|
||||
// ever be called once per PCM device.
|
||||
- (void) soundThread: (id)obj;
|
||||
- (void) stopTrack: (OOSound *)trackToStop;
|
||||
|
||||
// playBuffer sets up the buffer to be played and posts the semaphore
|
||||
// to crank it up.
|
||||
- (void) playBuffer: (OOSound *)sound;
|
||||
|
||||
// initAlsa sets up the device.
|
||||
- (BOOL) initAlsa;
|
||||
|
||||
// Quite a lot of nasty stuff is done here. The implementation almost
|
||||
// certainly can be improved, but I think it'll take reading the
|
||||
// ALSA library code to figure out a better way to do this.
|
||||
// If you think this code is bizarre or at best baroque I quite agree!
|
||||
- (BOOL)mixChunks;
|
||||
|
||||
@end
|
||||
|
||||
static OOAlsaSoundThread *soundThread;
|
||||
|
||||
// a bet to self: this class is still in use 2 years from now...
|
||||
|
460
OOAlsaSound.m
460
OOAlsaSound.m
@ -1,460 +0,0 @@
|
||||
//
|
||||
// OOALSASound.m: Interface for oolite to the Advanced Linux Sound
|
||||
// Achitecture.
|
||||
// Implements methods from NSSound which are used by oolite.
|
||||
//
|
||||
// Note: this only implements as much as oolite needs from NSSound.
|
||||
// It's also a bit of a stopgap measure since GNUstep NSSound doesn't
|
||||
// yet support ALSA and the sound server crashes all the time.
|
||||
//
|
||||
// Dylan Smith, 2005-04-22
|
||||
//
|
||||
#import <Foundation/NSData.h>
|
||||
#import <Foundation/NSThread.h>
|
||||
#import <Foundation/NSLock.h>
|
||||
#import "OOAlsaSound.h"
|
||||
#include <math.h>
|
||||
|
||||
@implementation OOSound
|
||||
|
||||
- (BOOL) pause
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (BOOL) isPlaying
|
||||
{
|
||||
return isPlaying;
|
||||
}
|
||||
|
||||
- (BOOL) play
|
||||
{
|
||||
if(!soundThread)
|
||||
{
|
||||
soundThread = [[OOAlsaSoundThread alloc] init];
|
||||
}
|
||||
|
||||
// do we need to upsample?
|
||||
if(_samplingRate < SAMPLERATE)
|
||||
{
|
||||
NSLog(@"sampleRate was %f; resampling", _samplingRate);
|
||||
[self resample];
|
||||
}
|
||||
[soundThread playBuffer: self];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL) stop
|
||||
{
|
||||
[soundThread stopTrack: self];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL) resume
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[soundThread stopTrack: self];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) resample
|
||||
{
|
||||
int i;
|
||||
int stretchSample=SAMPLERATE / _samplingRate;
|
||||
long newDataSize=_dataSize * stretchSample;
|
||||
Frame *newBuf=(Frame *)malloc(newDataSize);
|
||||
Frame *newBufPtr=newBuf;
|
||||
const Frame *oldBuf=(const Frame *)[_data bytes];
|
||||
const Frame *oldBufPtr;
|
||||
const Frame *oldBufEnd=oldBuf+(_dataSize / sizeof(Frame));
|
||||
|
||||
Sample lastChana;
|
||||
Sample lastChanb;
|
||||
Sample thisChana=0;
|
||||
Sample thisChanb=0;
|
||||
|
||||
for(oldBufPtr=oldBuf; oldBufPtr < oldBufEnd; oldBufPtr ++)
|
||||
{
|
||||
// Keep the last sample value and split out the ones
|
||||
// we are looking at (or use zero if we're at the first
|
||||
// frame of the buffer). Then make a simple straight line
|
||||
// between the two to antialise the sound that's being
|
||||
// resampled.
|
||||
lastChana=thisChana;
|
||||
lastChanb=thisChanb;
|
||||
|
||||
thisChana=(*oldBufPtr & 0xFFFF0000) >> 16;
|
||||
thisChanb=*oldBufPtr & 0x0000FFFF;
|
||||
|
||||
short stepChana=(thisChana-lastChana) / stretchSample;
|
||||
short stepChanb=(thisChanb-lastChanb) / stretchSample;
|
||||
|
||||
// we'll increment chana and chanb by the step as we
|
||||
// write them.
|
||||
short chana=lastChana;
|
||||
short chanb=lastChanb;
|
||||
|
||||
for(i=0; i < stretchSample; i++)
|
||||
{
|
||||
*newBufPtr=chana;
|
||||
*newBufPtr <<= 16;
|
||||
|
||||
// see later comment about shorts being aligned on longword
|
||||
// boundaries.
|
||||
*newBufPtr |= (chanb & 0x0000FFFF);
|
||||
chana+=stepChana;
|
||||
chanb+=stepChanb;
|
||||
newBufPtr++;
|
||||
}
|
||||
}
|
||||
[_data release];
|
||||
_data=[NSData dataWithBytes: newBuf length: newDataSize];
|
||||
[_data retain];
|
||||
_samplingRate=SAMPLERATE;
|
||||
_dataSize=newDataSize;
|
||||
_frameCount=newDataSize >> 2;
|
||||
}
|
||||
|
||||
// These methods reveal the internals of the NSSound.
|
||||
- (NSData *)getData
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
// Float!? Surely an integer Mr. Stallman!
|
||||
- (float)getSampleRate
|
||||
{
|
||||
return _samplingRate;
|
||||
}
|
||||
|
||||
- (float)getFrameSize
|
||||
{
|
||||
return _frameSize;
|
||||
}
|
||||
|
||||
- (long)getDataSize
|
||||
{
|
||||
return _dataSize;
|
||||
}
|
||||
|
||||
- (long)getFrameCount
|
||||
{
|
||||
return _frameCount;
|
||||
}
|
||||
|
||||
- (int)getChannelCount
|
||||
{
|
||||
return _channelCount;
|
||||
}
|
||||
|
||||
- (void)resetState
|
||||
{
|
||||
isPlaying=NO;
|
||||
}
|
||||
|
||||
- (void)startup
|
||||
{
|
||||
isPlaying=YES;
|
||||
}
|
||||
|
||||
- (const unsigned char *)getBufferEnd;
|
||||
{
|
||||
const unsigned char *buf=[_data bytes];
|
||||
buf+=_dataSize;
|
||||
return buf;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// Now here comes the really yucky stuff.
|
||||
// Some of this may not be strictly necesary, but the ALSA documentation
|
||||
// is truly abysmal. If you know ALSA better and can make a better
|
||||
// implementation of this I won't feel insulted, trust me :-) In fact
|
||||
// I think I might be a little bit relieved.
|
||||
@implementation OOAlsaSoundThread
|
||||
|
||||
- (id)init
|
||||
{
|
||||
// Crank up the player thread.
|
||||
[NSThread detachNewThreadSelector:@selector(soundThread:)
|
||||
toTarget:self
|
||||
withObject: nil];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)soundThread: (id)obj
|
||||
{
|
||||
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
|
||||
if(![self initAlsa])
|
||||
{
|
||||
NSLog(@"initAlsa returned NO, sound thread aborting");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
unsigned short int silence[1024];
|
||||
memset(silence, 0, sizeof(silence));
|
||||
|
||||
// Prepare/reset the PCM device for playback.
|
||||
// According to ALSA docs, just opening the device
|
||||
// implicitly prepares it, but it can't hurt to make
|
||||
// sure, especially knowing ALSA consistency...
|
||||
|
||||
snd_pcm_prepare(pcm_handle);
|
||||
|
||||
// do this forever
|
||||
// Note we have to play silence instead of stopping, it seems
|
||||
// to prevent problems with stalls/buffer underruns with some
|
||||
// hardware. It apparently uses more CPU to actually stop than
|
||||
// keep continously feeding the sound card.
|
||||
while(1)
|
||||
{
|
||||
int res;
|
||||
// play it one chunk at a time.
|
||||
if([self mixChunks])
|
||||
{
|
||||
res = snd_pcm_writei(pcm_handle, chunkBuf, bufsz);
|
||||
}
|
||||
else // Nothing to play? Play silence so we don't get an underrun.
|
||||
{
|
||||
res = snd_pcm_writei(pcm_handle, silence, sizeof(silence) / 4);
|
||||
}
|
||||
// Check for errors/problems
|
||||
if (res < 0)
|
||||
{
|
||||
NSLog(@"ALSA: error during snd_pcm_writei() (%s), resetting stream.",
|
||||
snd_strerror(res));
|
||||
snd_pcm_prepare(pcm_handle);
|
||||
}
|
||||
}
|
||||
|
||||
[pool release];
|
||||
}
|
||||
|
||||
// do all the initialization. The ALSA website doesn't document this
|
||||
// very well but the function calls are in the main self explanatory.
|
||||
- (BOOL) initAlsa
|
||||
{
|
||||
int dir;
|
||||
int periods = PERIODS;
|
||||
snd_pcm_uframes_t periodsize = PERIODSIZE;
|
||||
bufsz=MIXBUFSIZE;
|
||||
|
||||
int i;
|
||||
|
||||
// init track pointers.
|
||||
for(i=0; i < MAXTRACKS; i++)
|
||||
{
|
||||
trackBuffer[i].buf=NULL;
|
||||
trackBuffer[i].bufEnd=NULL;
|
||||
}
|
||||
|
||||
snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
|
||||
|
||||
// init the PCM name. TODO: perhaps load this from a config plist?
|
||||
// wanna get it working first...
|
||||
char *pcm_name=strdup("default");
|
||||
snd_pcm_hw_params_alloca(&hwparams);
|
||||
|
||||
// open it up
|
||||
if(snd_pcm_open(&pcm_handle, pcm_name, stream, 0) < 0)
|
||||
{
|
||||
NSLog(@"ALSA failed to initialize %s", pcm_name);
|
||||
return NO;
|
||||
}
|
||||
|
||||
if(snd_pcm_hw_params_any(pcm_handle, hwparams) < 0)
|
||||
{
|
||||
NSLog(@"ALSA cannot configure PCM device");
|
||||
return NO;
|
||||
}
|
||||
|
||||
// TODO: investigate mmaped access
|
||||
if(snd_pcm_hw_params_set_access(pcm_handle, hwparams,
|
||||
SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
|
||||
{
|
||||
NSLog(@"ALSA failed to set access");
|
||||
return NO;
|
||||
}
|
||||
|
||||
// assumption...
|
||||
if(snd_pcm_hw_params_set_format(pcm_handle, hwparams,
|
||||
SND_PCM_FORMAT_S16_LE) < 0)
|
||||
{
|
||||
NSLog(@"ALSA failed to set the format");
|
||||
return NO;
|
||||
}
|
||||
|
||||
// set sample rate and channels
|
||||
int exact_rate=SAMPLERATE;
|
||||
if(snd_pcm_hw_params_set_rate_near
|
||||
(pcm_handle, hwparams, &exact_rate, &dir))
|
||||
{
|
||||
NSLog(@"ALSA can't set the rate %d", exact_rate);
|
||||
return NO;
|
||||
}
|
||||
|
||||
if(snd_pcm_hw_params_set_channels(pcm_handle, hwparams, CHANNELS) < 0)
|
||||
{
|
||||
NSLog(@"ALSA can't set channels to %d", CHANNELS);
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
// TODO: find out exactly what periods are useful for.
|
||||
snd_pcm_uframes_t origPeriods=periods;
|
||||
int periodDir=0;
|
||||
if(snd_pcm_hw_params_set_periods_near
|
||||
(pcm_handle, hwparams, &periods, &periodDir) < 0)
|
||||
{
|
||||
NSLog(@"ALSA could not set periods");
|
||||
return NO;
|
||||
}
|
||||
|
||||
// http://www.suse.de/~mana/alsa090_howto.html
|
||||
// bufsz is the size in frames not bytes
|
||||
unsigned long hwbufsz=(periods * periodsize) >> 2;
|
||||
unsigned long origbufsz=hwbufsz;
|
||||
|
||||
if(origPeriods != periods)
|
||||
{
|
||||
NSLog(@"Tried to set %d periods but ended up with %d",
|
||||
origPeriods, periods);
|
||||
}
|
||||
|
||||
// bufsz = buffer size in frames. fpp = frames per period.
|
||||
// We try to allocate a buffer of the number of frames per
|
||||
// period but it might not happen.
|
||||
if(snd_pcm_hw_params_set_buffer_size_near
|
||||
(pcm_handle, hwparams, &hwbufsz) < 0)
|
||||
{
|
||||
NSLog(@"ALSA could not set the buffer size to %d", hwbufsz);
|
||||
return NO;
|
||||
}
|
||||
|
||||
if(hwbufsz != origbufsz)
|
||||
{
|
||||
NSLog(@"Sound card can't take a buffer of %d - using %d instead",
|
||||
origbufsz, hwbufsz);
|
||||
|
||||
// If the hwbufsz is smaller than our default bufsz, downsize
|
||||
// bufsz.
|
||||
if(hwbufsz < bufsz)
|
||||
bufsz=hwbufsz;
|
||||
}
|
||||
|
||||
// convert bufsz to bytes and allocate our mixer buffer.
|
||||
chunkBuf=(Frame *)malloc(bufsz * FRAMESIZE);
|
||||
|
||||
if(snd_pcm_hw_params(pcm_handle, hwparams) < 0)
|
||||
{
|
||||
NSLog(@"ALSA could not set HW params");
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
// playBuffer doesn't actually do the playing - it merely adds the
|
||||
// sound to the list of tracks the player thread should mix.
|
||||
- (void) playBuffer: (OOSound *)sound
|
||||
{
|
||||
NSLock *addlock=[[NSLock alloc] init];
|
||||
[addlock lock];
|
||||
int i;
|
||||
int slot=0;
|
||||
BOOL slotAssigned=NO;
|
||||
for(i=0; i < MAXTRACKS; i++)
|
||||
{
|
||||
if(!track[i] && !slotAssigned)
|
||||
{
|
||||
slot=i;
|
||||
slotAssigned=YES;
|
||||
}
|
||||
}
|
||||
if(!slotAssigned)
|
||||
{
|
||||
NSLog(@"No free tracks");
|
||||
return;
|
||||
}
|
||||
|
||||
[sound retain]; // we don't want it unexpectedly disappearing
|
||||
track[slot]=sound;
|
||||
trackBuffer[slot].buf=(Frame *)[[sound getData] bytes];
|
||||
trackBuffer[slot].bufEnd=(Frame *)[sound getBufferEnd];
|
||||
[sound startup];
|
||||
[addlock unlock];
|
||||
}
|
||||
|
||||
- (BOOL) mixChunks
|
||||
{
|
||||
int i;
|
||||
Frame *current;
|
||||
|
||||
// Check there's something to mix.
|
||||
for(i=0; i < MAXTRACKS; i++)
|
||||
{
|
||||
if(track[i])
|
||||
break;
|
||||
}
|
||||
if(i == MAXTRACKS)
|
||||
{
|
||||
// No tracks to do, exit now.
|
||||
return NO;
|
||||
}
|
||||
|
||||
for(current=chunkBuf; current < chunkBuf + bufsz; current++)
|
||||
{
|
||||
long sumChanA=0;
|
||||
long sumChanB=0;
|
||||
for(i=0; i < MAXTRACKS; i++)
|
||||
{
|
||||
if(!trackBuffer[i].buf) continue;
|
||||
if(trackBuffer[i].buf >= trackBuffer[i].bufEnd) continue;
|
||||
sumChanA += (long)*trackBuffer[i].buf >> 16;
|
||||
sumChanB += (long)(*trackBuffer[i].buf << 16) >> 16;
|
||||
trackBuffer[i].buf++;
|
||||
}
|
||||
|
||||
if(sumChanA > 32767) sumChanA=32767;
|
||||
else if(sumChanA < -32768) sumChanA=-32768;
|
||||
if(sumChanB > 32767) sumChanB=32767;
|
||||
else if(sumChanB < -32768) sumChanB=-32768;
|
||||
|
||||
*current = (sumChanA << 16) | (sumChanB & 0xffff);
|
||||
}
|
||||
|
||||
// drop tracks we don't want any more
|
||||
for(i=0; i < MAXTRACKS; i++)
|
||||
{
|
||||
if(trackBuffer[i].buf && trackBuffer[i].buf == trackBuffer[i].bufEnd)
|
||||
{
|
||||
[track[i] resetState];
|
||||
[track[i] release];
|
||||
track[i]=nil;
|
||||
trackBuffer[i].buf=NULL;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) stopTrack: (OOSound *)trackToStop
|
||||
{
|
||||
int i;
|
||||
for(i=0; i < MAXTRACKS; i++)
|
||||
{
|
||||
if(trackToStop == track[i])
|
||||
{
|
||||
track[i]=nil;
|
||||
trackBuffer[i].buf=NULL;
|
||||
[trackToStop resetState];
|
||||
[trackToStop release];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
140
OOCharacter.m
140
OOCharacter.m
@ -1,140 +0,0 @@
|
||||
//
|
||||
// OOCharacter.m
|
||||
// Oolite
|
||||
/*
|
||||
*
|
||||
* Oolite
|
||||
*
|
||||
* Created by Giles Williams on Thu Nov 03 2004.
|
||||
* Copyright (c) 2004 for aegidian.org. All rights reserved.
|
||||
*
|
||||
|
||||
Copyright (c) 2004, Giles C Williams
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Noncommercial. You may not use this work for commercial purposes.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOCharacter.h"
|
||||
|
||||
|
||||
@implementation OOCharacter
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (name)
|
||||
[name release];
|
||||
if (shortDescription)
|
||||
[shortDescription release];
|
||||
if (longDescription)
|
||||
[longDescription release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id) initWithGenSeed:(Random_Seed) g_seed andOriginalSystemSeed:(Random_Seed) s_seed
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
// do Pilot set-up
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithRole:(NSString*) role andOriginalSystemSeed:(Random_Seed) s_seed
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
// do Pilot set-up
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString*) name
|
||||
{
|
||||
return name;
|
||||
}
|
||||
- (NSString*) shortDescription
|
||||
{
|
||||
return shortDescription;
|
||||
}
|
||||
- (NSString*) longDescription
|
||||
{
|
||||
return longDescription;
|
||||
}
|
||||
- (Random_Seed) originSystemSeed
|
||||
{
|
||||
return originSystemSeed;
|
||||
}
|
||||
- (Random_Seed) genSeed
|
||||
{
|
||||
return genSeed;
|
||||
}
|
||||
- (int) legalStatus
|
||||
{
|
||||
return legalStatus;
|
||||
}
|
||||
- (int) insuranceCredits
|
||||
{
|
||||
return insuranceCredits;
|
||||
}
|
||||
|
||||
- setName: (NSString*) value
|
||||
{
|
||||
if (name)
|
||||
[name autorelease];
|
||||
name = [value retain];
|
||||
}
|
||||
- setShortDescription: (NSString*) value
|
||||
{
|
||||
if (shortDescription)
|
||||
[shortDescription autorelease];
|
||||
shortDescription = [value retain];
|
||||
}
|
||||
- setLongDescription: (NSString*) value
|
||||
{
|
||||
if (longDescription)
|
||||
[longDescription autorelease];
|
||||
longDescription = [value retain];
|
||||
}
|
||||
- setOriginSystemSeed: (Random_Seed) value
|
||||
{
|
||||
originSystemSeed = value;
|
||||
}
|
||||
- setGenSeed: (Random_Seed) value
|
||||
{
|
||||
genSeed = value;
|
||||
}
|
||||
- setLegalStatus: (int) value
|
||||
{
|
||||
legalStatus = value;
|
||||
}
|
||||
- setInsuranceCredits: (int) value
|
||||
{
|
||||
insuranceCredits = value;
|
||||
}
|
||||
|
||||
|
||||
@end
|
11
OOMusic.h
11
OOMusic.h
@ -1,11 +0,0 @@
|
||||
// OOMusic.h: Selects the appropriate music class source file
|
||||
// depending on the operating system defined.
|
||||
//
|
||||
// Add new OS imports here. The -DOS_NAME flag in the GNUmakefile
|
||||
// will select which one gets compiled.
|
||||
//
|
||||
// David Taylor, 2005-05-04
|
||||
|
||||
#ifdef LINUX
|
||||
#import "SDLMusic.h"
|
||||
#endif
|
1865
Oolite.xcodeproj/project.pbxproj
Normal file
1865
Oolite.xcodeproj/project.pbxproj
Normal file
File diff suppressed because it is too large
Load Diff
79
PORTING.TXT
79
PORTING.TXT
@ -1,79 +0,0 @@
|
||||
Stuff Fixed during Porting
|
||||
==========================
|
||||
|
||||
The purpose of this file is to list the things I came up against,
|
||||
how I fixed them, and what caused them so if you're porting to
|
||||
another platform and see something similar, you know where to start
|
||||
looking (rather than groping in the dark). It is grouped into 'Symptom'
|
||||
and 'Cause'. The cause discussion includes possible solutions.
|
||||
|
||||
If you are porting to another platform, and you encounter weird difficulties
|
||||
that you overcome please add them to this file and either send it to me,
|
||||
or if you have svn commit access to the repo, commit it.
|
||||
|
||||
Dylan Smith <dyls@alioth.net>
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
Symptom:
|
||||
Altitude bar drawn right across the screen, time under the scanner
|
||||
showing stupid value (it should be something like NNNNNNN:NN:NN:NN),
|
||||
probably no rotating Cobra showing on startup (and no view out of the
|
||||
window when you launch your ship)
|
||||
|
||||
Cause:
|
||||
Bad maths.
|
||||
floor(), part of the standard C math library, is returning funny values
|
||||
or your int type is not at least 32 bits wide.
|
||||
Make sure #include <math.h> is done in all applicable files; for Linux
|
||||
this was put in oolite-linux.h which is included by every file.
|
||||
|
||||
Check that floor() returns a sensible value by writing a short program that
|
||||
does:
|
||||
|
||||
int result;
|
||||
double thing=180058016009.741669;
|
||||
result=floor(thing / 86400.0);
|
||||
printf("Result is %d and thing is %f\n", result, thing);
|
||||
|
||||
Result should equal 2084004. Try it including math.h and not including
|
||||
math.h and note any differences. If it gives the right result with math.h
|
||||
but the wrong result without, then you've not included math.h
|
||||
|
||||
In the case that your int type is only 16 bits, this will probably work:
|
||||
#define int long
|
||||
|
||||
and put it in your equivalent of oolite-linux.h.
|
||||
|
||||
Additional info: see the manpage for floor().
|
||||
|
||||
TODO: Include an assertion on startup that causes the game to exit
|
||||
immediately with an error message describing the problem if floor()
|
||||
doesn't return the correct value. I'll only bother if this problem
|
||||
keeps cropping up. An error message that can be reported is much
|
||||
better than a vague description of these symptoms by some guy who
|
||||
just wants to play the game.
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Symptom: Floating point exceptions
|
||||
|
||||
Cause: Some rhs of / and % expressions are turning out to be zero (I
|
||||
assume this isn't the case on OS X). In some instances, the simple
|
||||
fix of doing an if(rhs_of_expression)... before the div or mod
|
||||
operation is appropriate. It's probably best to look for the root
|
||||
cause of why the rhs is zero in the first place to check that it's not
|
||||
harmless and you're not going to hide a new problem or hide the root
|
||||
cause by doing this test.
|
||||
|
||||
The location of the exception is easily found by doing 'make debug=yes'
|
||||
and doing 'debugapp oolite.debug' and then looking at the line of code
|
||||
it crashes in.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Sound in general: gnustep_sndd crashes
|
||||
|
||||
Cause: Don't know, assume it's a bug in GNUstep.
|
||||
|
||||
This has been fixed by subclassing NSSound (since the AIFF loader is
|
||||
fine) and replacing the actual sound output/mixer by using SDL.
|
||||
|
648
PlayerEntity.h
648
PlayerEntity.h
@ -1,648 +0,0 @@
|
||||
//
|
||||
// PlayerEntity.h
|
||||
/*
|
||||
*
|
||||
* Oolite
|
||||
*
|
||||
* Created by Giles Williams on Sat Apr 03 2004.
|
||||
* Copyright (c) 2004 for aegidian.org. All rights reserved.
|
||||
*
|
||||
|
||||
Copyright (c) 2004, Giles C Williams
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Noncommercial. You may not use this work for commercial purposes.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#ifndef GNUSTEP
|
||||
#import <QuickTime/Movies.h>
|
||||
#else
|
||||
#include "OOMusic.h"
|
||||
#endif
|
||||
|
||||
#import "ShipEntity.h"
|
||||
|
||||
@class GuiDisplayGen, OOTrumble, MyOpenGLView, HeadUpDisplay, ShipEntity, JoystickHandler;
|
||||
#ifndef GNUSTEP
|
||||
@class OOSound;
|
||||
#endif
|
||||
|
||||
#define SCRIPT_TIMER_INTERVAL 10.0
|
||||
|
||||
#define GUI_SCREEN_MAIN 000
|
||||
#define GUI_SCREEN_INTRO1 001
|
||||
#define GUI_SCREEN_INTRO2 002
|
||||
#define GUI_SCREEN_STATUS 101
|
||||
#define GUI_SCREEN_MANIFEST 111
|
||||
#define GUI_SCREEN_EQUIP_SHIP 102
|
||||
#define GUI_SCREEN_SHIPYARD 112
|
||||
#define GUI_SCREEN_LONG_RANGE_CHART 103
|
||||
#define GUI_SCREEN_SHORT_RANGE_CHART 113
|
||||
#define GUI_SCREEN_SYSTEM_DATA 105
|
||||
#define GUI_SCREEN_MARKET 106
|
||||
#define GUI_SCREEN_CONTRACTS 116
|
||||
#define GUI_SCREEN_INVENTORY 107
|
||||
#define GUI_SCREEN_OPTIONS 108
|
||||
#define GUI_SCREEN_LOAD 118
|
||||
#define GUI_SCREEN_SAVE 128
|
||||
#define GUI_SCREEN_SAVE_OVERWRITE 129
|
||||
#define GUI_SCREEN_STICKMAPPER 138
|
||||
#define GUI_SCREEN_MISSION 201
|
||||
#define GUI_SCREEN_REPORT 301
|
||||
|
||||
#define GUI_ROW_OPTIONS_QUICKSAVE 5
|
||||
#define GUI_ROW_OPTIONS_SAVE 6
|
||||
#define GUI_ROW_OPTIONS_LOAD 7
|
||||
#define GUI_ROW_OPTIONS_BEGIN_NEW 8
|
||||
#define GUI_ROW_OPTIONS_OPTIONS 9
|
||||
#define GUI_ROW_OPTIONS_DISPLAY 10
|
||||
|
||||
#ifdef GNUSTEP
|
||||
//#define GUI_ROW_OPTIONS_OOTUNES 12
|
||||
#define GUI_ROW_OPTIONS_DISPLAYSTYLE 11
|
||||
#define GUI_ROW_OPTIONS_VOLUME 12
|
||||
#define GUI_ROW_OPTIONS_DETAIL 13
|
||||
#define GUI_ROW_OPTIONS_STRICT 14
|
||||
#define GUI_ROW_OPTIONS_STICKMAPPER 15
|
||||
#define GUI_ROW_OPTIONS_QUIT 16
|
||||
#else
|
||||
#define GUI_ROW_OPTIONS_SPEECH 11
|
||||
#define GUI_ROW_OPTIONS_VOLUME 12
|
||||
#define GUI_ROW_OPTIONS_OOTUNES 13
|
||||
#define GUI_ROW_OPTIONS_DETAIL 14
|
||||
#define GUI_ROW_OPTIONS_STICKMAPPER 15
|
||||
#define GUI_ROW_OPTIONS_STRICT 16
|
||||
#endif
|
||||
|
||||
#define GUI_ROW_EQUIPMENT_START 3
|
||||
#define GUI_MAX_ROWS_EQUIPMENT 12
|
||||
#define GUI_ROW_EQUIPMENT_DETAIL GUI_ROW_EQUIPMENT_START+GUI_MAX_ROWS_EQUIPMENT+1
|
||||
#define GUI_ROW_EQUIPMENT_CASH 1
|
||||
#define GUI_ROW_MARKET_KEY 1
|
||||
#define GUI_ROW_MARKET_START 2
|
||||
#define GUI_ROW_MARKET_CASH 20
|
||||
|
||||
#define WEAPON_COOLING_FACTOR 6.0
|
||||
#define ENERGY_RECHARGE_FACTOR energy_recharge_rate
|
||||
#define SHIELD_RECHARGE_FACTOR (2.0 + shield_enhancer)
|
||||
#define ECM_ENERGY_DRAIN_FACTOR 20.0
|
||||
#define ECM_DURATION 2.5
|
||||
|
||||
#define ROLL_DAMPING_FACTOR 1.0
|
||||
#define PITCH_DAMPING_FACTOR 1.0
|
||||
|
||||
#define PLAYER_MAX_FORWARD_SHIELD (128.0 * (shield_booster + shield_enhancer))
|
||||
#define PLAYER_MAX_AFT_SHIELD (128.0 * (shield_booster + shield_enhancer))
|
||||
#define PLAYER_MAX_WEAPON_TEMP 256.0
|
||||
#define PLAYER_MAX_CABIN_TEMP 256.0
|
||||
#define PLAYER_MIN_CABIN_TEMP 60.0
|
||||
#define PLAYER_MAX_FUEL 70.0
|
||||
#define PLAYER_MAX_MISSILES 4
|
||||
#define PLAYER_STARTING_MISSILES 3
|
||||
#define PLAYER_DIAL_MAX_ALTITUDE 40000.0
|
||||
#define PLAYER_SUPER_ALTITUDE2 10000000000.0
|
||||
|
||||
#define PLAYER_MAX_TRUMBLES 24
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~ = 40km
|
||||
|
||||
#define ALERT_CONDITION_DOCKED 0
|
||||
#define ALERT_CONDITION_GREEN 1
|
||||
#define ALERT_CONDITION_YELLOW 2
|
||||
#define ALERT_CONDITION_RED 3
|
||||
|
||||
#define SHOT_RELOAD 0.25
|
||||
|
||||
#define HYPERSPEED_FACTOR 32.0
|
||||
|
||||
#define PLAYER_SHIP_DESC @"cobra3-player"
|
||||
#define PLAYER_MODEL @"cobra3_redux.dat"
|
||||
|
||||
#define KEY_DOCKING_MUSIC @"docking_music"
|
||||
|
||||
#define ESCAPE_SEQUENCE_TIME 10.0
|
||||
|
||||
#define AI_DOCKING_COMPUTER @"dockingAI.plist"
|
||||
|
||||
#define MS_WITCHSPACE_SF @"[witch-to-@-in-f-seconds]"
|
||||
#define MS_GAL_WITCHSPACE_F @"[witch-galactic-in-f-seconds]"
|
||||
|
||||
#define MISSILE_STATUS_SAFE 0
|
||||
#define MISSILE_STATUS_ARMED 1
|
||||
#define MISSILE_STATUS_TARGET_LOCKED 2
|
||||
|
||||
#define WEAPON_FACING_NONE 0
|
||||
#define WEAPON_FACING_FORWARD 1
|
||||
#define WEAPON_FACING_AFT 2
|
||||
#define WEAPON_FACING_PORT 4
|
||||
#define WEAPON_FACING_STARBOARD 8
|
||||
|
||||
#define WEAPON_OFFSET_DOWN 20
|
||||
|
||||
#define FORWARD_FACING_STRING @"\tForward "
|
||||
#define AFT_FACING_STRING @"\tAft "
|
||||
#define PORT_FACING_STRING @"\tPort "
|
||||
#define STARBOARD_FACING_STRING @"\tStarboard "
|
||||
|
||||
#define ENERGY_UNIT_NONE 0
|
||||
#define ENERGY_UNIT_NORMAL 15
|
||||
#define ENERGY_UNIT_NAVAL 20
|
||||
|
||||
#define ALERT_FLAG_DOCKED 0x010
|
||||
#define ALERT_FLAG_MASS_LOCK 0x020
|
||||
#define ALERT_FLAG_YELLOW_LIMIT 0x03f
|
||||
#define ALERT_FLAG_TEMP 0x040
|
||||
#define ALERT_FLAG_ALT 0x080
|
||||
#define ALERT_FLAG_ENERGY 0x100
|
||||
#define ALERT_FLAG_HOSTILES 0x200
|
||||
|
||||
#define KEY_REPEAT_INTERVAL 0.20
|
||||
|
||||
#define OOTUNES_ON ootunes_on
|
||||
|
||||
#define CABIN_COOLING_FACTOR 1.0
|
||||
#define CABIN_INSULATION_FACTOR 0.00175
|
||||
|
||||
#define SUN_TEMPERATURE 1250.0
|
||||
|
||||
#define PLAYER_SHIP_CLOCK_START 2084004 * 86400.0
|
||||
|
||||
#define CONTRACTS_GOOD_KEY @"contracts_fulfilled"
|
||||
#define CONTRACTS_BAD_KEY @"contracts_expired"
|
||||
#define CONTRACTS_UNKNOWN_KEY @"contracts_unknown"
|
||||
#define PASSAGE_GOOD_KEY @"passage_fulfilled"
|
||||
#define PASSAGE_BAD_KEY @"passage_expired"
|
||||
#define PASSAGE_UNKNOWN_KEY @"passage_unknown"
|
||||
|
||||
#define COMPASS_MODE_BASIC 0
|
||||
#define COMPASS_MODE_PLANET 1
|
||||
#define COMPASS_MODE_STATION 2
|
||||
#define COMPASS_MODE_SUN 3
|
||||
#define COMPASS_MODE_TARGET 4
|
||||
#define COMPASS_MODE_BEACONS 6
|
||||
#define COMPASS_MODE_ADVANCED_OKAY ((compass_mode >= 1)&&(compass_mode <= 10))
|
||||
|
||||
#define SCANNER_ZOOM_RATE_UP 2.0
|
||||
#define SCANNER_ZOOM_RATE_DOWN -8.0
|
||||
|
||||
#define PLAYER_INTERNAL_DAMAGE_FACTOR 31
|
||||
|
||||
@interface PlayerEntity : ShipEntity
|
||||
{
|
||||
@public
|
||||
|
||||
Random_Seed system_seed;
|
||||
Random_Seed target_system_seed;
|
||||
|
||||
BOOL show_info_flag;
|
||||
|
||||
@protected
|
||||
|
||||
NSString *ship_desc;
|
||||
int ship_trade_in_factor;
|
||||
|
||||
NSDictionary *script;
|
||||
NSMutableDictionary *mission_variables;
|
||||
int missionTextRow;
|
||||
ShipEntity *script_target;
|
||||
NSString *missionChoice;
|
||||
|
||||
NSString* specialCargo;
|
||||
|
||||
NSMutableArray* comm_log;
|
||||
|
||||
NSImage *missionBackgroundImage;
|
||||
|
||||
NSMutableDictionary *extra_equipment;
|
||||
BOOL found_equipment;
|
||||
|
||||
NSMutableDictionary *reputation;
|
||||
|
||||
int max_passengers;
|
||||
NSMutableArray *passengers;
|
||||
NSMutableDictionary *passenger_record;
|
||||
|
||||
NSMutableArray *contracts;
|
||||
NSMutableDictionary *contract_record;
|
||||
|
||||
NSMutableDictionary *shipyard_record;
|
||||
|
||||
double script_time;
|
||||
double script_time_check;
|
||||
double script_time_interval;
|
||||
NSString *lastTextKey;
|
||||
|
||||
double ship_clock;
|
||||
double ship_clock_adjust;
|
||||
|
||||
double fps_check_time;
|
||||
int fps_counter;
|
||||
|
||||
NSString *planetSearchString;
|
||||
|
||||
#ifdef LOADSAVEGUI
|
||||
// For GUI/SDL based save screen
|
||||
NSString *commanderNameString;
|
||||
NSMutableArray *cdrDetailArray;
|
||||
int currentPage;
|
||||
BOOL pollControls;
|
||||
#endif
|
||||
|
||||
StationEntity *docked_station;
|
||||
|
||||
HeadUpDisplay *hud;
|
||||
|
||||
BOOL showDemoShips;
|
||||
|
||||
BOOL rolling, pitching;
|
||||
BOOL using_mining_laser;
|
||||
|
||||
BOOL mouse_control_on;
|
||||
|
||||
BOOL speech_on;
|
||||
BOOL ootunes_on;
|
||||
|
||||
BOOL docking_music_on;
|
||||
|
||||
double roll_delta, pitch_delta;
|
||||
|
||||
double forward_shield, aft_shield;
|
||||
double weapon_temp;
|
||||
double forward_weapon_temp, aft_weapon_temp, port_weapon_temp, starboard_weapon_temp;
|
||||
double weapon_energy_per_shot, weapon_heat_increment_per_shot, weapon_reload_time;
|
||||
double cabin_temp;
|
||||
|
||||
int chosen_weapon_facing; // for purchasing weapons
|
||||
|
||||
BOOL game_over;
|
||||
BOOL docked;
|
||||
BOOL finished;
|
||||
BOOL bomb_detonated;
|
||||
BOOL autopilot_engaged;
|
||||
|
||||
BOOL afterburner_engaged;
|
||||
BOOL afterburnerSoundLooping;
|
||||
|
||||
BOOL hyperspeed_engaged;
|
||||
BOOL travelling_at_hyperspeed;
|
||||
BOOL hyperspeed_locked;
|
||||
|
||||
BOOL ident_engaged;
|
||||
|
||||
BOOL ecm_in_operation;
|
||||
double ecm_start_time;
|
||||
|
||||
#ifndef GNUSTEP
|
||||
NSMovie* themeMusic;
|
||||
NSMovie* missionMusic;
|
||||
NSMovie* dockingMusic;
|
||||
#else
|
||||
OOMusic* themeMusic;
|
||||
OOMusic* missionMusic;
|
||||
OOMusic* dockingMusic;
|
||||
#endif
|
||||
|
||||
NSSound* beepSound;
|
||||
NSSound* boopSound;
|
||||
NSSound* weaponSound;
|
||||
NSSound* weaponHitSound;
|
||||
NSSound* missileSound;
|
||||
NSSound* damageSound;
|
||||
NSSound* scrapeDamageSound;
|
||||
NSSound* destructionSound;
|
||||
NSSound* breakPatternSound;
|
||||
NSSound* ecmSound;
|
||||
NSSound* buySound;
|
||||
NSSound* sellSound;
|
||||
NSSound* warningSound;
|
||||
NSSound* afterburner1Sound;
|
||||
NSSound* afterburner2Sound;
|
||||
NSSound* witchAbortSound;
|
||||
|
||||
int gui_screen;
|
||||
int alert_flags;
|
||||
int alert_condition;
|
||||
int missile_status;
|
||||
int active_missile;
|
||||
|
||||
int current_cargo;
|
||||
|
||||
NSPoint cursor_coordinates;
|
||||
double witchspaceCountdown;
|
||||
|
||||
// player commander data
|
||||
//
|
||||
NSString* player_name;
|
||||
NSPoint galaxy_coordinates;
|
||||
|
||||
Random_Seed galaxy_seed;
|
||||
|
||||
int credits;
|
||||
int galaxy_number;
|
||||
int forward_weapon;
|
||||
int aft_weapon;
|
||||
int port_weapon;
|
||||
int starboard_weapon;
|
||||
|
||||
NSMutableArray* shipCommodityData;
|
||||
|
||||
BOOL has_energy_unit;
|
||||
int energy_unit;
|
||||
int shield_booster, shield_enhancer;
|
||||
BOOL has_docking_computer;
|
||||
BOOL has_galactic_hyperdrive;
|
||||
|
||||
int max_missiles; // int - no. of missile pylons
|
||||
ShipEntity* missile_entity[SHIPENTITY_MAX_MISSILES]; // holds the actual missile entities or equivalents
|
||||
|
||||
int legal_status;
|
||||
int market_rnd;
|
||||
int ship_kills;
|
||||
BOOL saved;
|
||||
|
||||
int compass_mode;
|
||||
|
||||
double fuel_leak_rate;
|
||||
|
||||
// keys!
|
||||
int key_roll_left;
|
||||
int key_roll_right;
|
||||
int key_pitch_forward;
|
||||
int key_pitch_back;
|
||||
int key_increase_speed;
|
||||
int key_decrease_speed;
|
||||
//
|
||||
int key_inject_fuel;
|
||||
//
|
||||
int key_fire_lasers;
|
||||
int key_target_missile;
|
||||
int key_untarget_missile;
|
||||
int key_launch_missile;
|
||||
int key_ecm;
|
||||
int key_launch_escapepod;
|
||||
int key_energy_bomb;
|
||||
int key_galactic_hyperspace;
|
||||
int key_hyperspace;
|
||||
int key_jumpdrive;
|
||||
int key_dump_cargo;
|
||||
int key_autopilot;
|
||||
int key_autopilot_target;
|
||||
int key_autodock;
|
||||
int key_snapshot;
|
||||
int key_docking_music;
|
||||
int key_scanner_zoom;
|
||||
//
|
||||
int key_map_dump;
|
||||
int key_map_home;
|
||||
int key_map_info;
|
||||
//
|
||||
int key_pausebutton;
|
||||
int key_show_fps;
|
||||
int key_mouse_control;
|
||||
//
|
||||
int key_emergency_hyperdrive;
|
||||
//
|
||||
int key_next_missile;
|
||||
int key_ident_system;
|
||||
//
|
||||
int key_comms_log;
|
||||
//
|
||||
int key_next_compass_mode;
|
||||
//
|
||||
int key_cloaking_device;
|
||||
//
|
||||
int key_contract_info;
|
||||
|
||||
// save-file
|
||||
NSString* save_path;
|
||||
|
||||
// position of viewports
|
||||
Vector forwardViewOffset, aftViewOffset, portViewOffset, starboardViewOffset;
|
||||
|
||||
// DEBUG
|
||||
ParticleEntity* drawDebugParticle;
|
||||
int debugShipID;
|
||||
|
||||
// trumbles
|
||||
int n_trumbles;
|
||||
OOTrumble* trumble[PLAYER_MAX_TRUMBLES];
|
||||
|
||||
// smart zoom
|
||||
double scanner_zoom_rate;
|
||||
|
||||
// Keeping track of joysticks
|
||||
int numSticks;
|
||||
JoystickHandler *stickHandler;
|
||||
BOOL keyboardRollPitchOverride;
|
||||
|
||||
// For PlayerEntity (StickMapper)
|
||||
int selFunctionIdx;
|
||||
BOOL waitingForStickCallback;
|
||||
NSArray *stickFunctions;
|
||||
}
|
||||
|
||||
- (void) init_keys;
|
||||
- (void) warnAboutHostiles;
|
||||
|
||||
- (void) unloadCargoPods;
|
||||
- (void) loadCargoPods;
|
||||
|
||||
- (int) random_factor;
|
||||
- (Random_Seed) galaxy_seed;
|
||||
- (NSPoint) galaxy_coordinates;
|
||||
- (NSPoint) cursor_coordinates;
|
||||
|
||||
- (Random_Seed) system_seed;
|
||||
- (void) setSystem_seed:(Random_Seed) s_seed;
|
||||
- (Random_Seed) target_system_seed;
|
||||
|
||||
- (NSDictionary *) commanderDataDictionary;
|
||||
- (void) setCommanderDataFromDictionary:(NSDictionary *) dict;
|
||||
|
||||
- (void) set_up;
|
||||
|
||||
- (void) doBookkeeping:(double) delta_t;
|
||||
|
||||
- (BOOL) massLocked;
|
||||
- (BOOL) atHyperspeed;
|
||||
- (Vector) velocityVector;
|
||||
|
||||
- (NSString *) ship_desc;
|
||||
|
||||
- (StationEntity *) docked_station;
|
||||
|
||||
- (HeadUpDisplay *) hud;
|
||||
|
||||
- (void) setShowDemoShips:(BOOL) value;
|
||||
- (BOOL) showDemoShips;
|
||||
|
||||
- (double) dial_roll;
|
||||
- (double) dial_pitch;
|
||||
- (double) dial_speed;
|
||||
- (double) dial_hyper_speed;
|
||||
|
||||
- (double) dial_forward_shield;
|
||||
- (double) dial_aft_shield;
|
||||
|
||||
- (double) dial_energy;
|
||||
- (double) dial_max_energy;
|
||||
|
||||
- (double) dial_fuel;
|
||||
- (double) dial_hyper_range;
|
||||
|
||||
- (double) dial_cabin_temp;
|
||||
- (double) dial_weapon_temp;
|
||||
- (double) dial_altitude;
|
||||
|
||||
- (int) dial_missiles;
|
||||
- (int) calc_missiles;
|
||||
- (int) dial_missile_status;
|
||||
|
||||
- (NSString*) dial_clock;
|
||||
- (NSString*) dial_clock_adjusted;
|
||||
- (NSString*) dial_fpsinfo;
|
||||
- (NSString*) dial_objinfo;
|
||||
|
||||
- (NSMutableArray*) comm_log;
|
||||
|
||||
- (int) compass_mode;
|
||||
- (void) setCompass_mode:(int) value;
|
||||
- (void) setNextCompassMode;
|
||||
|
||||
- (int) active_missile;
|
||||
- (void) setActive_missile: (int) value;
|
||||
- (int) dial_max_missiles;
|
||||
- (BOOL) dial_ident_engaged;
|
||||
- (NSString *) dial_target_name;
|
||||
- (ShipEntity *) missile_for_station: (int) value;
|
||||
- (void) sort_missiles;
|
||||
- (void) safe_all_missiles;
|
||||
- (void) select_next_missile;
|
||||
- (void) tidyMissilePylons;
|
||||
|
||||
- (void) clearAlert_flags;
|
||||
- (void) setAlert_flag:(int) flag :(BOOL) value;
|
||||
- (int) alert_condition;
|
||||
|
||||
- (void) pollControls:(double) delta_t;
|
||||
- (void) pollApplicationControls;
|
||||
- (void) pollFlightControls:(double) delta_t;
|
||||
- (void) pollFlightArrowKeyControls:(double) delta_t;
|
||||
- (void) pollGuiArrowKeyControls:(double) delta_t;
|
||||
- (BOOL) handleGUIUpDownArrowKeys:(GuiDisplayGen *)gui
|
||||
:(MyOpenGLView *)gameView;
|
||||
- (void) pollViewControls;
|
||||
- (void) pollGuiScreenControls;
|
||||
- (void) pollGameOverControls:(double) delta_t;
|
||||
- (void) pollAutopilotControls:(double) delta_t;
|
||||
- (void) pollDockedControls:(double) delta_t;
|
||||
- (void) pollDemoControls:(double) delta_t;
|
||||
|
||||
- (BOOL) mountMissile: (ShipEntity *)missile;
|
||||
|
||||
- (BOOL) fireEnergyBomb;
|
||||
- (BOOL) launchMine:(ShipEntity*) mine;
|
||||
|
||||
- (BOOL) fireMainWeapon;
|
||||
- (int) weaponForView:(int) view;
|
||||
|
||||
- (void) enterGalacticWitchspace;
|
||||
- (void) enterWormhole:(WormholeEntity*) w_hole;
|
||||
|
||||
- (void) interpretAIMessage:(NSString *)ms;
|
||||
|
||||
- (void) takeInternalDamage;
|
||||
- (NSDictionary*) damageInformation;
|
||||
- (void) getDestroyed;
|
||||
|
||||
- (void) loseTargetStatus;
|
||||
|
||||
- (void) docked;
|
||||
|
||||
- (void) quicksavePlayer;
|
||||
- (void) savePlayer;
|
||||
- (void) loadPlayer;
|
||||
- (void) loadPlayerFromFile:(NSString *)fileToOpen;
|
||||
- (void) changePlayerName;
|
||||
|
||||
- (void) setGuiToStatusScreen;
|
||||
- (int) getRatingFromKills: (int)shipKills;
|
||||
- (NSArray *) equipmentList;
|
||||
- (NSArray *) cargoList;
|
||||
- (void) setGuiToSystemDataScreen;
|
||||
- (NSArray *) markedDestinations;
|
||||
- (void) setGuiToLongRangeChartScreen;
|
||||
- (void) starChartDump;
|
||||
- (void) setGuiToShortRangeChartScreen;
|
||||
- (void) setGuiToLoadSaveScreen;
|
||||
- (void) setGuiToEquipShipScreen:(int) skip :(int) itemForSelectFacing;
|
||||
- (void) showInformationForSelectedUpgrade;
|
||||
- (void) setGuiToMarketScreen;
|
||||
|
||||
- (void) setGuiToIntro1Screen;
|
||||
- (void) setGuiToIntro2Screen;
|
||||
|
||||
- (int) gui_screen;
|
||||
|
||||
- (void) buySelectedItem;
|
||||
- (BOOL) tryBuyingItem:(int) index;
|
||||
- (BOOL) marketFlooded:(int) index;
|
||||
- (BOOL) tryBuyingCommodity:(int) index;
|
||||
- (BOOL) trySellingCommodity:(int) index;
|
||||
|
||||
- (BOOL) speech_on;
|
||||
|
||||
- (BOOL) has_extra_equipment:(NSString *) eq_key;
|
||||
- (void) add_extra_equipment:(NSString *) eq_key;
|
||||
- (void) remove_extra_equipment:(NSString *) eq_key;
|
||||
- (void) set_extra_equipment_from_flags;
|
||||
- (void) set_flags_from_extra_equipment;
|
||||
|
||||
- (void) loopAfterburnerSound;
|
||||
- (void) stopAfterburnerSound;
|
||||
|
||||
- (void) setScript_target:(ShipEntity *)ship;
|
||||
- (ShipEntity*) script_target;
|
||||
|
||||
- (void) getFined;
|
||||
|
||||
- (void) setDefaultViewOffsets;
|
||||
- (Vector) viewOffset;
|
||||
|
||||
- (void) setUpTrumbles;
|
||||
- (void) addTrumble:(OOTrumble*) papaTrumble;
|
||||
- (void) removeTrumble:(OOTrumble*) deadTrumble;
|
||||
- (OOTrumble**) trumbleArray;
|
||||
- (int) n_trumbles;
|
||||
// loading and saving n_trummbles
|
||||
- (NSObject*) trumbleValue;
|
||||
- (void) setTrumbleValueFrom:(NSObject*) trumbleValue;
|
||||
|
||||
- (void) munge_checksum_with_NSString:(NSString*) str;
|
||||
|
||||
@end
|
74
README.txt
Normal file
74
README.txt
Normal file
@ -0,0 +1,74 @@
|
||||
Grand Unified Source Tree for Oolite
|
||||
====================================
|
||||
|
||||
Oolite for all platforms can be built from this repository.
|
||||
Here is a quick guide to the source tree.
|
||||
|
||||
1. Guidelines
|
||||
-------------
|
||||
Nothing except makefiles/xcode projects, directories, and this readme
|
||||
file should appear in the top level directory.
|
||||
The deps directory should contain dependencies that are useful to carry
|
||||
along to build binary packages. The dependencies directory should
|
||||
be named:
|
||||
Opsys-cpuarch-deps
|
||||
Opsys should be exactly as reported by 'uname' with no flags (case
|
||||
sensitive!). The cpuarch should be the cpu architecture reported by
|
||||
'uname -p' (except i686, i586 etc should be translated to x86).
|
||||
This allows build scripts to automatically package up the right
|
||||
dependency tree in tarball installers.
|
||||
|
||||
2. Contents
|
||||
-----------
|
||||
autopackage Directory for the apspec file for the Linux autopackage
|
||||
Asset Source Files used to create the various PNG and sound files
|
||||
deps Dependencies for all plaforms:
|
||||
Cocoa-deps Dependencies for Mac OS X (macppc and macintel platforms)
|
||||
Linux-x86-deps Dependencies for Linux on x86 processors
|
||||
scripts Scripts and script fragments for tarball/autopackage
|
||||
Doc Documentation (including user guides)
|
||||
FreeDesktop Files for GNOME/KDE desktop launchers
|
||||
Oolite-importer (OS X) The oolite importer
|
||||
Oolite.xcodeproj The OS X Xcode project to build Oolite
|
||||
OSX-SDL Project files for the SDL version of Oolite on OS X
|
||||
(*very* seldom used, more of a curiosity)
|
||||
Resources Files that live in the application bundle's
|
||||
Contents/Resources directory (AI, config, textures etc).
|
||||
src Objective-C and C sources, incuding header files:
|
||||
Core Files that are compiled on all platforms
|
||||
SDL Files that are only compiled for platforms that use SDL
|
||||
Cocoa Files that are only compiled on Mac OS X without SDL
|
||||
BSDCompat Support for BSDisms that gnu libc doesn't have (strl*)
|
||||
tools Various tools for preparing files, builds, releases etc.
|
||||
|
||||
3. Building
|
||||
-----------
|
||||
On Mac OS X, you will need the latest version of Xcode and OS X 10.4 (Tiger).
|
||||
You will also need all the relevant frameworks (they come with Xcode).
|
||||
If you don't yet have Xcode you can get it from the Apple Developer
|
||||
Connection (see the Apple web site) - ADC membership to get Xcode is
|
||||
free, and it's a rather nice IDE.
|
||||
Then double click on the Xcode project in the Finder, and hit Build.
|
||||
|
||||
On Linux, BSD and other Unix platforms, you will need to get GNUstep and
|
||||
SDL development libraries in addition to what is usually installed by
|
||||
default if you choose to install the development headers/libraries etc.
|
||||
when initially installing the OS. For most Linux distros, GNUstep and SDL
|
||||
development libraries come prepackaged - just apt-get/yum install the
|
||||
relevant files. On others you may need to build them from source.
|
||||
In particular, you need the SDL_image and SDL_Mixer libraries; these
|
||||
don't always come with the base SDL development kit.
|
||||
Then just type 'make'.
|
||||
|
||||
If you want to make the Linux autopackage, after getting the Autopackage
|
||||
development kit, just type 'makeinstaller', and a package file will be
|
||||
deposited in the top level.
|
||||
|
||||
[Nic, please put some build instructions for Windows here!]
|
||||
|
||||
4. Running
|
||||
----------
|
||||
On OS X, you can run from Xcode by clicking on the appropriate icon
|
||||
(or choosing 'Build and Run').
|
||||
On Linux/BSD/Unix, in a terminal, type 'openapp oolite'
|
||||
|
@ -1,8 +1,14 @@
|
||||
{
|
||||
GLOBAL = {
|
||||
ENTER = ("setSpeedTo: 0.0", requestDockingCoordinates, "setStateTo: AWAIT_COORDS");
|
||||
EXIT = ();
|
||||
UPDATE = ();
|
||||
};
|
||||
"AWAIT_COORDS" = {
|
||||
"APPROACH_START" = ("setStateTo: GO_TO_START");
|
||||
"APPROACH" = ("setStateTo: APPROACH");
|
||||
"APPROACH_COORDINATES" = ("setStateTo: GO_TO_COORDS");
|
||||
"HOLD_POSITION" = (performIdle, "pauseAI: 10.0", "setStateTo: GLOBAL");
|
||||
"BACK_OFF" = ("setStateTo: RETREAT");
|
||||
"HOLD_POSITION" = ("setStateTo: STATIONKEEPING");
|
||||
"DOCKING_ABORTED" = ("setStateTo: ABORT");
|
||||
"TRY_AGAIN_LATER" = ("pauseAI: 30.0", "setStateTo: ABORT");
|
||||
"COLLISION" = ("setStateTo: ABORT");
|
||||
@ -12,48 +18,32 @@
|
||||
EXIT = ();
|
||||
UPDATE = ();
|
||||
};
|
||||
"EXIT_SYSTEM" = {ENTER = (performDocking, exitAI); EXIT = (); UPDATE = (); };
|
||||
ABORT = {
|
||||
ENTER = (abortDocking, "setSpeedFactorTo: 0.0", setDestinationToDockingAbort, "setDesiredRangeTo: 500.0", performFaceDestination);
|
||||
"FACING_DESTINATION" = ("setSpeedFactorTo: 1.0", "setDesiredRangeTo: 500.0", performFlyToRangeFromDestination);
|
||||
STATIONKEEPING = {
|
||||
ENTER = (performIdle, "setSpeedTo: 0.0", "pauseAI: 10.0");
|
||||
EXIT = ();
|
||||
"RESTART_DOCKING" = ("setStateTo: GLOBAL");
|
||||
"REACHED_SAFETY" = (performIdle, "setStateTo: GLOBAL");
|
||||
"DESIRED_RANGE_ACHIEVED" = (performIdle, "setStateTo: GLOBAL");
|
||||
UPDATE = ();
|
||||
UPDATE = (requestDockingCoordinates, "setStateTo: AWAIT_COORDS");
|
||||
};
|
||||
GLOBAL = {
|
||||
ENTER = ("setSpeedTo: 0.0", "setDesiredRangeTo: 5.0", requestDockingCoordinates, "setStateTo: AWAIT_COORDS");
|
||||
EXIT = ();
|
||||
UPDATE = ();
|
||||
};
|
||||
"GO_TO_WAYPOINT" = {
|
||||
ENTER = ("setDesiredRangeTo: 50.0", checkCourseToDestination);
|
||||
"COURSE_OK" = ("setSpeedFactorTo: 0.85", performFlyToRangeFromDestination);
|
||||
"WAYPOINT_SET" = ("setDesiredRangeTo: 50.0", checkCourseToDestination);
|
||||
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: GO_TO_STATION");
|
||||
EXIT = ();
|
||||
UPDATE = ();
|
||||
};
|
||||
"GO_TO_START" = {
|
||||
ENTER = (
|
||||
"setSpeedFactorTo: 0.05",
|
||||
setDestinationFromCoordinates,
|
||||
checkCourseToDestination
|
||||
);
|
||||
"WAYPOINT_SET" = ("setStateTo: GO_TO_WAYPOINT");
|
||||
"COURSE_OK" = ("setSpeedFactorTo: 0.25", performFaceDestination);
|
||||
"FACING_DESTINATION" = ("setDesiredRangeTo: 50.0", "setSpeedFactorTo: 0.85", performFlyToRangeFromDestination);
|
||||
APPROACH = {
|
||||
ENTER = (recallDockingInstructions, setTargetToStation, setDestinationToTarget, "setDesiredRangeTo: 10000.0", "setSpeedFactorTo: 1.0", performFlyToRangeFromDestination);
|
||||
"DESIRED_RANGE_ACHIEVED" = (requestDockingCoordinates, "setStateTo: AWAIT_COORDS");
|
||||
"DOCKING_ABORTED" = ("setStateTo: ABORT");
|
||||
"COLLISION" = ("setStateTo: ABORT");
|
||||
"RESTART_DOCKING" = ("setStateTo: GLOBAL");
|
||||
EXIT = ();
|
||||
UPDATE = ();
|
||||
};
|
||||
UPDATE = ();
|
||||
};
|
||||
RETREAT = {
|
||||
ENTER = (recallDockingInstructions, setTargetToStation, setDestinationToTarget, "setSpeedFactorTo: 0.5", "setDesiredRangeTo: 5000.0", performFlyToRangeFromDestination);
|
||||
"DESIRED_RANGE_ACHIEVED" = (requestDockingCoordinates, "setStateTo: AWAIT_COORDS");
|
||||
"DOCKING_ABORTED" = ("setStateTo: ABORT");
|
||||
"COLLISION" = ("setStateTo: ABORT");
|
||||
"RESTART_DOCKING" = ("setStateTo: GLOBAL");
|
||||
EXIT = ();
|
||||
UPDATE = ();
|
||||
};
|
||||
"GO_TO_COORDS" = {
|
||||
ENTER = (performFaceDestination);
|
||||
FRUSTRATED = (performIdle, "pauseAI: 5.0", performFaceDestination);
|
||||
FRUSTRATED = ("setSpeedTo: 0.0", performFaceDestination);
|
||||
"FACING_DESTINATION" = (recallDockingInstructions, performFlyToRangeFromDestination);
|
||||
"DESIRED_RANGE_ACHIEVED" = (requestDockingCoordinates, "setStateTo: AWAIT_COORDS");
|
||||
"DOCKING_ABORTED" = ("setStateTo: ABORT");
|
||||
@ -62,4 +52,14 @@
|
||||
EXIT = ();
|
||||
UPDATE = ();
|
||||
};
|
||||
}
|
||||
ABORT = {
|
||||
ENTER = (abortDocking, "setSpeedTo: 0.0", setDestinationToDockingAbort, "setDesiredRangeTo: 500.0", performFaceDestination);
|
||||
"FACING_DESTINATION" = ("setSpeedFactorTo: 1.0", "setDesiredRangeTo: 500.0", performFlyToRangeFromDestination);
|
||||
EXIT = ();
|
||||
"RESTART_DOCKING" = ("setStateTo: GLOBAL");
|
||||
"REACHED_SAFETY" = (performIdle, "setStateTo: GLOBAL");
|
||||
"DESIRED_RANGE_ACHIEVED" = (performIdle, "setStateTo: GLOBAL");
|
||||
UPDATE = ();
|
||||
};
|
||||
"EXIT_SYSTEM" = {ENTER = (performDocking, exitAI); EXIT = (); UPDATE = (); };
|
||||
}
|
@ -1,14 +1,15 @@
|
||||
{
|
||||
GLOBAL = {ENTER = ("setStateTo: CHECK_HOLD"); EXIT = (); UPDATE = (); };
|
||||
"CHECK_HOLD" = {
|
||||
ENTER = (checkForFullHold, "switchStateTo: STILL_HUNGRY");
|
||||
ENTER = (checkForFullHold);
|
||||
"HOLD_FULL" = ("switchAITo: enteringTraderAI.plist");
|
||||
EXIT = ();
|
||||
UPDATE = ();
|
||||
UPDATE = ("setStateTo: STILL_HUNGRY");
|
||||
};
|
||||
"STILL_HUNGRY" = {
|
||||
ENTER = ();
|
||||
EXIT = ();
|
||||
"HOLD_FULL" = ("switchAITo: enteringTraderAI.plist");
|
||||
UPDATE = ("switchAITo: pirateAI.plist");
|
||||
};
|
||||
}
|
@ -9,20 +9,27 @@
|
||||
"NOT_ESCORTING" = ("setStateTo: LOOK_FOR_BUSINESS");
|
||||
"TARGET_LOST" = ("setStateTo: LOOK_FOR_BUSINESS");
|
||||
"TARGET_DESTROYED" = ("setStateTo: LOOK_FOR_BUSINESS");
|
||||
"ENTER WORMHOLE" = ("setStateTo: ENTER_WORMHOLE");
|
||||
EXIT = ();
|
||||
UPDATE = (escortCheckMother, "pauseAI: 15");
|
||||
};
|
||||
"BEGIN_BUSINESS" = {
|
||||
"LAUNCHED OKAY" = ("setStateTo: CLEAR_STATION");
|
||||
ATTACKED = (setTargetToPrimaryAggressor, "setAITo: interceptAI.plist");
|
||||
ENTER = (escortCheckMother);
|
||||
EXIT = ();
|
||||
ESCORTING = ("setDesiredRangeTo: 0.0", performEscort);
|
||||
"NOT_ESCORTING" = ("setStateTo: LOOK_FOR_BUSINESS");
|
||||
"LAUNCHED_OKAY" = ("setStateTo: CLEAR_STATION");
|
||||
UPDATE = ();
|
||||
};
|
||||
"ENTER_WORMHOLE" = {
|
||||
ENTER = (setDestinationToTarget, "setDesiredRangeTo: 1.0", "setSpeedFactorTo: 1.0", performFlyToRangeFromDestination);
|
||||
"PLAYER WITCHSPACE" = (enterTargetWormhole);
|
||||
UPDATE = ();
|
||||
EXIT = ();
|
||||
};
|
||||
"CLEAR_STATION" = {
|
||||
ENTER = (setTargetToStation, "setDesiredRangeTo: 5000.0", "setSpeedFactorTo: 0.5", performFlyToRangeFromDestination);
|
||||
ENTER = (setTargetToStation, setDestinationWithinTarget, "setDesiredRangeTo: 8000.0", "setSpeedFactorTo: 0.5", performFlyToRangeFromDestination);
|
||||
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: LOOK_FOR_BUSINESS");
|
||||
UPDATE = (scanForFormationLeader, "pauseAI: 15.0");
|
||||
"TARGET_FOUND" = (setTargetToFoundTarget, suggestEscort);
|
||||
@ -30,14 +37,15 @@
|
||||
EXIT = ();
|
||||
};
|
||||
"LOOK_FOR_BUSINESS" = {
|
||||
"LAUNCHED OKAY" = ("setStateTo: CLEAR_STATION");
|
||||
ATTACKED = (setTargetToPrimaryAggressor, "setAITo: interceptAI.plist");
|
||||
RESTARTED = ("setStateTo: BEGIN_BUSINESS");
|
||||
ENTER = ("setSpeedTo: 0.0", performIdle);
|
||||
ENTER = (scanForFormationLeader);
|
||||
EXIT = ();
|
||||
ESCORTING = ("setDesiredRangeTo: 0.0", "setStateTo: FLYING_ESCORT");
|
||||
"TARGET_FOUND" = (setTargetToFoundTarget, suggestEscort);
|
||||
"NOTHING_FOUND" = ("setStateMachine: route1patrolAI.plist");
|
||||
UPDATE = (scanForFormationLeader, "pauseAI: 15.0");
|
||||
UPDATE = ("pauseAI: 7.5", scanForFormationLeader);
|
||||
};
|
||||
GLOBAL = {ENTER = ("setStateTo: BEGIN_BUSINESS"); EXIT = (); UPDATE = (); };
|
||||
}
|
@ -12,6 +12,9 @@
|
||||
ENTER = ();
|
||||
EXIT = ();
|
||||
UPDATE = (performHyperSpaceExit);
|
||||
"WITCHSPACE OKAY" = (wormholeEscorts);
|
||||
"WITCHSPACE BLOCKED" = (setTargetToFoundTarget, setDestinationWithinTarget, "setDesiredRangeTo: 10000.0", performFlyToRangeFromDestination);
|
||||
"WITCHSPACE UNAVAILABLE" = ("setAITo: route1traderAI.plist");
|
||||
};
|
||||
FLEE = {
|
||||
ATTACKED = (fightOrFleeHostiles);
|
||||
@ -27,12 +30,12 @@
|
||||
};
|
||||
"HEAD_AWAY_FROM_PLANET" = {
|
||||
ENTER = (getWitchspaceEntryCoordinates, setDestinationFromCoordinates, "setDesiredRangeTo: 100.0", "setSpeedFactorTo: 0.75", performFlyToRangeFromDestination);
|
||||
"DESIRED_RANGE_ACHIEVED" = (dockEscorts, "setSpeedFactorTo: 1.0", "pauseAI: 15.0", "setStateTo: EXIT_SYSTEM");
|
||||
"DESIRED_RANGE_ACHIEVED" = ("setSpeedFactorTo: 1.0", "pauseAI: 15.0", "setStateTo: EXIT_SYSTEM");
|
||||
ATTACKED = (fightOrFleeHostiles);
|
||||
FIGHTING = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
|
||||
FLEEING = (setTargetToPrimaryAggressor, "setStateTo: FLEE");
|
||||
"INCOMING_MISSILE" = (fightOrFleeMissile, "setStateTo: FLEE");
|
||||
"EXITED WITCHSPACE" = ("setAITo: route1traderAI.plist");
|
||||
"EXITED WITCHSPACE" = ("switchAITo: enteringTraderAI.plist");
|
||||
EXIT = ();
|
||||
UPDATE = ();
|
||||
};
|
||||
|
@ -4,7 +4,8 @@
|
||||
"COURSE_OK" = ("setSpeedFactorTo: 1.0", performFlyToRangeFromDestination);
|
||||
"WAYPOINT_SET" = ("setDesiredRangeTo: 50.0", checkCourseToDestination);
|
||||
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: GLOBAL");
|
||||
ATTACKED = (setTargetToPrimaryAggressor, broadcastDistressMessage, "setStateTo: FLEE");
|
||||
ATTACKED = (setTargetToPrimaryAggressor, broadcastDistressMessage, "setStateTo: FLEE");
|
||||
"APPROACHING_SURFACE" = (landOnPlanet);
|
||||
"INCOMING_MISSILE" = (fightOrFleeMissile, "setStateTo: FLEE");
|
||||
EXIT = ();
|
||||
UPDATE = ();
|
||||
@ -13,11 +14,12 @@
|
||||
ENTER = (setCourseToPlanet, checkCourseToDestination);
|
||||
"COURSE_OK" = ("setSpeedFactorTo: 1.0", performFlyToRangeFromDestination);
|
||||
"WAYPOINT_SET" = ("setStateTo: GO_TO_WAYPOINT");
|
||||
"APPROACHING_SURFACE" = (landOnPlanet);
|
||||
"DESIRED_RANGE_ACHIEVED" = (landOnPlanet);
|
||||
EXIT = ();
|
||||
ATTACKED = (setTargetToPrimaryAggressor, broadcastDistressMessage, "setStateTo: FLEE");
|
||||
"INCOMING_MISSILE" = (fightOrFleeMissile, "setStateTo: FLEE");
|
||||
UPDATE = (checkCourseToDestination, "pauseAI: 10.0");
|
||||
UPDATE = ("setDesiredRangeTo: 50.0", checkCourseToDestination, "pauseAI: 10.0");
|
||||
};
|
||||
GLOBAL = {ENTER = ("setSpeedFactorTo: 0.25", "setStateTo: FLY_HOME"); EXIT = (); UPDATE = (); };
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
"TARGET_DESTROYED" = ("setStateTo: EXPLODE");
|
||||
"TARGET_LOST" = ("setStateTo: EXPLODE");
|
||||
"GONE_BEYOND_RANGE" = ("setStateTo: EXPLODE");
|
||||
"ECM" = ("setStateTo: CHECK_EXPLOSION");
|
||||
UPDATE = ("setDesiredRangeTo: 30000.0", checkDistanceTravelled, "setDesiredRangeTo: 25.0", "pauseAI: 5.0");
|
||||
};
|
||||
DETONATE = {
|
||||
@ -18,6 +19,13 @@
|
||||
EXIT = ();
|
||||
UPDATE = ();
|
||||
};
|
||||
"CHECK_EXPLOSION" = {
|
||||
ENTER = ("rollD: 20");
|
||||
"ROLL_1" = ("setStateTo: DETONATE");
|
||||
"ROLL_2" = ("setStateTo: EXPLODE");
|
||||
EXIT = ();
|
||||
UPDATE = ("setStateTo: ATTACK_SHIP");
|
||||
};
|
||||
GLOBAL = {
|
||||
ENTER = ("setSpeedFactorTo: 1.0", "setStateTo: ATTACK_SHIP");
|
||||
EXIT = ();
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
GLOBAL = {
|
||||
"DESIRED_RANGE_ACHIEVED" = (landOnPlanet);
|
||||
ENTER = (setCourseToPlanet, performFlyToRangeFromDestination);
|
||||
ENTER = ();
|
||||
EXIT = ();
|
||||
UPDATE = ();
|
||||
UPDATE = (setCourseToPlanet, "setSpeedFactorTo: 1.0", performFlyToRangeFromDestination);
|
||||
"DESIRED_RANGE_ACHIEVED" = (landOnPlanet);
|
||||
};
|
||||
}
|
@ -56,4 +56,4 @@
|
||||
UPDATE = ();
|
||||
};
|
||||
GLOBAL = {ENTER = ("setSpeedFactorTo: 0.1", "setStateTo: LOOK_FOR_SPLINTERS"); EXIT = (); UPDATE = (); };
|
||||
}
|
||||
}
|
@ -93,8 +93,9 @@
|
||||
};
|
||||
"DOCK_WITH_STATION" = {
|
||||
ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
|
||||
ENTER = (setTargetToStation, "setDesiredRangeTo: 5000.0", performIntercept);
|
||||
"DESIRED_RANGE_ACHIEVED" = ("setAITo: dockingAI.plist");
|
||||
ENTER = (checkForMotherStation);
|
||||
"NOTHING_FOUND" = ("setAITo: route1traderAI.plist");
|
||||
"STATION_FOUND" = ("setAITo: dockingAI.plist");
|
||||
EXIT = ();
|
||||
"INCOMING_MISSILE" = (fightOrFleeMissile, "setStateTo: FLEE");
|
||||
UPDATE = ();
|
||||
|
@ -18,6 +18,7 @@
|
||||
EXIT = ();
|
||||
UPDATE = ();
|
||||
ATTACKED = (setTargetToPrimaryAggressor, "setAITo: interceptAI.plist");
|
||||
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", "sendTargetCommsMessage: [police-attack-warning]", "setAITo: interceptAI.plist");
|
||||
};
|
||||
"GO_TO_COORDS" = {
|
||||
ENTER = (
|
||||
@ -37,6 +38,7 @@
|
||||
"TARGET_OFFENDER" = ("sendTargetCommsMessage: [police-attack-warning]", "setAITo: interceptAI.plist");
|
||||
"TARGET_FUGITIVE" = ("setAITo: interceptAI.plist");
|
||||
ATTACKED = (setTargetToPrimaryAggressor, "setAITo: interceptAI.plist");
|
||||
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", "sendTargetCommsMessage: [police-attack-warning]", "setAITo: interceptAI.plist");
|
||||
};
|
||||
"EXIT_SYSTEM" = {ENTER = (performDocking, exitAI); EXIT = (); UPDATE = (); };
|
||||
}
|
||||
}
|
@ -6,16 +6,18 @@
|
||||
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
|
||||
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, groupAttackTarget);
|
||||
"TARGET_FOUND" = (setTargetToFoundTarget, groupAttackTarget);
|
||||
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", launchDefenseShip, groupAttackTarget);
|
||||
EXIT = ();
|
||||
UPDATE = (scanForHostiles, "pauseAI: 10.0");
|
||||
};
|
||||
"DOCKING_WITCHPOINT" = {
|
||||
ENTER = ("setSpeedFactorTo: 0.0", performIdle);
|
||||
"DOCKING_COMPLETE" = ("setStateTo: HEAD_FOR_WITCHPOINT");
|
||||
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setStateTo: ATTACK_TARGET");
|
||||
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget);
|
||||
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
|
||||
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, launchDefenseShip, groupAttackTarget, "setStateTo: ATTACK_TARGET");
|
||||
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, launchDefenseShip, groupAttackTarget);
|
||||
"TARGET_FOUND" = (setTargetToFoundTarget, launchDefenseShip, groupAttackTarget);
|
||||
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", launchDefenseShip, groupAttackTarget);
|
||||
EXIT = ();
|
||||
UPDATE = (scanForHostiles, "pauseAI: 10.0");
|
||||
};
|
||||
@ -30,6 +32,7 @@
|
||||
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, deployEscorts, groupAttackTarget, "setAITo: interceptAI.plist");
|
||||
"TARGET_FOUND" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
|
||||
"ACCEPT_DISTRESS_CALL" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
|
||||
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", deployEscorts, groupAttackTarget);
|
||||
EXIT = ();
|
||||
UPDATE = (scanForOffenders, "pauseAI: 10.0");
|
||||
RESTARTED = ("setStateTo: INBOUND_LOOT");
|
||||
@ -41,6 +44,7 @@
|
||||
"WAYPOINT_SET" = ("setDesiredRangeTo: 50.0", checkCourseToDestination);
|
||||
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: HEAD_FOR_PLANET");
|
||||
"ACCEPT_DISTRESS_CALL" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
|
||||
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", deployEscorts, groupAttackTarget);
|
||||
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: interceptAI.plist");
|
||||
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
|
||||
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, deployEscorts, groupAttackTarget, "setAITo: interceptAI.plist", "setStateTo: INBOUND_LOOT");
|
||||
@ -59,6 +63,7 @@
|
||||
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, deployEscorts, groupAttackTarget, "setAITo: interceptAI.plist", "setStateTo: OUTBOUND_LOOT");
|
||||
"TARGET_FOUND" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
|
||||
"ACCEPT_DISTRESS_CALL" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
|
||||
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", deployEscorts, groupAttackTarget);
|
||||
FRUSTRATED = ("setStateTo: HEAD_FOR_WITCHPOINT");
|
||||
EXIT = ();
|
||||
UPDATE = (scanForOffenders, "pauseAI: 10.0");
|
||||
@ -72,6 +77,7 @@
|
||||
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: HEAD_FOR_WITCHPOINT");
|
||||
"ACCEPT_DISTRESS_CALL" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
|
||||
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: interceptAI.plist");
|
||||
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", deployEscorts, groupAttackTarget);
|
||||
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
|
||||
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, deployEscorts, groupAttackTarget, "setAITo: interceptAI.plist", "setStateTo: OUTBOUND_LOOT");
|
||||
EXIT = ();
|
||||
@ -103,6 +109,7 @@
|
||||
"INBOUND_CHECK" = {
|
||||
ENTER = (scanForOffenders, checkForNormalSpace);
|
||||
EXIT = ();
|
||||
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", deployEscorts, groupAttackTarget);
|
||||
"TARGET_FOUND" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
|
||||
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: interceptAI.plist");
|
||||
RESTARTED = ("setStateTo: INBOUND_LOOT");
|
||||
@ -113,6 +120,7 @@
|
||||
"OUTBOUND_CHECK" = {
|
||||
ENTER = (scanForOffenders, checkForNormalSpace);
|
||||
EXIT = ();
|
||||
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", deployEscorts, groupAttackTarget);
|
||||
"TARGET_FOUND" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
|
||||
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: interceptAI.plist");
|
||||
RESTARTED = ("setStateTo: OUTBOUND_LOOT");
|
||||
@ -122,4 +130,4 @@
|
||||
};
|
||||
"HYPER_OUT" = {ENTER = (); EXIT = (); UPDATE = (performHyperSpaceExit); };
|
||||
GLOBAL = {ENTER = ("setStateTo: HEAD_FOR_WITCHPOINT"); EXIT = (); UPDATE = (); };
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@
|
||||
"TARGET_FOUND" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
|
||||
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: interceptAI.plist");
|
||||
"ACCEPT_DISTRESS_CALL" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
|
||||
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", deployEscorts, groupAttackTarget);
|
||||
EXIT = ();
|
||||
UPDATE = (scanForOffenders, "pauseAI: 10.0");
|
||||
RESTARTED = ("setStateTo: INBOUND_LOOT");
|
||||
@ -22,6 +23,7 @@
|
||||
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, deployEscorts, groupAttackTarget, "setAITo: interceptAI.plist", "setStateTo: INBOUND_LOOT");
|
||||
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: interceptAI.plist");
|
||||
"ACCEPT_DISTRESS_CALL" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
|
||||
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", deployEscorts, groupAttackTarget);
|
||||
EXIT = ();
|
||||
UPDATE = ();
|
||||
RESTARTED = ("setStateTo: INBOUND_LOOT");
|
||||
@ -37,6 +39,7 @@
|
||||
"TARGET_FOUND" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
|
||||
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: interceptAI.plist");
|
||||
"ACCEPT_DISTRESS_CALL" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
|
||||
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", deployEscorts, groupAttackTarget);
|
||||
EXIT = ();
|
||||
UPDATE = (scanForOffenders, "pauseAI: 10.0");
|
||||
RESTARTED = ("setStateTo: OUTBOUND_LOOT");
|
||||
@ -48,6 +51,7 @@
|
||||
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: HEAD_FOR_SUN");
|
||||
"ACCEPT_DISTRESS_CALL" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
|
||||
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: interceptAI.plist");
|
||||
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", deployEscorts, groupAttackTarget);
|
||||
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
|
||||
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, deployEscorts, groupAttackTarget, "setAITo: interceptAI.plist", "setStateTo: OUTBOUND_LOOT");
|
||||
EXIT = ();
|
||||
|
@ -28,15 +28,16 @@
|
||||
};
|
||||
GLOBAL = {ENTER = ("setSpeedFactorTo: 1.0", "setStateTo: LOOK_FOR_STUFF"); EXIT = (); UPDATE = (); };
|
||||
"COLLECT_STUFF" = {
|
||||
ATTACKED = (setTargetToPrimaryAggressor, broadcastDistressMessage, "setStateTo: FLEE");
|
||||
ENTER = (performCollect);
|
||||
FRUSTRATED = ("setSpeedTo: 0.0", setDestinationToTarget, "setDesiredRangeTo: 2.0", performFaceDestination);
|
||||
"FACING_DESTINATION" = (performCollect);
|
||||
"CARGO_SCOOPED" = (checkForFullHold, "setStateTo: LOOK_FOR_STUFF");
|
||||
FRUSTRATED = ("setStateTo: LOOK_FOR_STUFF");
|
||||
ATTACKED = (setTargetToPrimaryAggressor, broadcastDistressMessage, "setStateTo: FLEE");
|
||||
"TARGET_LOST" = ("setStateTo: LOOK_FOR_STUFF");
|
||||
"COLLISION" = ("setStateTo: LOOK_FOR_STUFF");
|
||||
ENTER = (performCollect);
|
||||
EXIT = ();
|
||||
"HOLD_FULL" = ("setStateTo: DOCK_WITH_STATION");
|
||||
"INCOMING_MISSILE" = (fightOrFleeMissile, "setStateTo: FLEE");
|
||||
UPDATE = ();
|
||||
};
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@
|
||||
"TARGET_OFFENDER" = (increaseAlertLevel);
|
||||
"TARGET_FUGITIVE" = (increaseAlertLevel);
|
||||
"ENERGY_FULL" = ("pauseAI: 20.0", "setStateTo: IDLE");
|
||||
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 15", launchDefenseShip, increaseAlertLevel);
|
||||
"TARGET_DESTROYED" = ("pauseAI: 20.0", "setStateTo: IDLE");
|
||||
"TARGET_LOST" = ("pauseAI: 20.0", "setStateTo: IDLE");
|
||||
"NO_TARGET" = ("pauseAI: 20.0", "setStateTo: IDLE");
|
||||
@ -28,6 +29,7 @@
|
||||
GLOBAL = {ENTER = ("setStateTo: IDLE"); EXIT = (); UPDATE = (); };
|
||||
IDLE = {
|
||||
ATTACKED = (setTargetToPrimaryAggressor, increaseAlertLevel, "setStateTo: DEFENSE_MODE");
|
||||
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 15", launchDefenseShip, increaseAlertLevel);
|
||||
ENTER = ();
|
||||
EXIT = ();
|
||||
"INCOMING_MISSILE" = (fireECM, increaseAlertLevel);
|
||||
|
@ -509,10 +509,31 @@
|
||||
<array>
|
||||
<string>%@ ejected.</string>
|
||||
</array>
|
||||
<key>@-ready-to-eject</key>
|
||||
<array>
|
||||
<string>Ready to eject %@.</string>
|
||||
</array>
|
||||
<key>ready-to-eject-@</key>
|
||||
<array>
|
||||
<string>Ready to eject %@.</string>
|
||||
</array>
|
||||
<key>@-scooped</key>
|
||||
<array>
|
||||
<string>%@ scooped.</string>
|
||||
</array>
|
||||
<key>fuel-scoop-active</key>
|
||||
<array>
|
||||
<string>Fuel scoop active.</string>
|
||||
</array>
|
||||
<key>hold-locked</key>
|
||||
<array>
|
||||
<string>Cargo ejection system offline (speed too high).</string>
|
||||
</array>
|
||||
<!-- holds full -->
|
||||
<key>hold-full</key>
|
||||
<array>
|
||||
<string>Cargo holds full.</string>
|
||||
</array>
|
||||
<!-- cloaking device .. -->
|
||||
<key>cloak-on</key>
|
||||
<array>
|
||||
@ -526,11 +547,6 @@
|
||||
<array>
|
||||
<string>Not enough energy to activate cloaking device.</string>
|
||||
</array>
|
||||
<!-- holds full -->
|
||||
<key>hold-full</key>
|
||||
<array>
|
||||
<string>Cargo holds full.</string>
|
||||
</array>
|
||||
<!-- Assorted messages sent out by ships etc.. -->
|
||||
<!-- %H - homeworld
|
||||
%I - homeworld+ian
|
||||
@ -667,7 +683,7 @@
|
||||
<key>fined</key>
|
||||
<array>
|
||||
<string>You have been fined %d credits.</string>
|
||||
<string>You have been fined %d credits, and made to pick up litter in the main hanger deck.</string>
|
||||
<string>You have been fined %d credits, and made to pick up litter in the main hangar deck.</string>
|
||||
<string>You have been fined %d credits, and are forced to clean up after the [6]oids.</string>
|
||||
<string>You have been fined %d credits, and sent for 'attitude adjustment'.</string>
|
||||
</array>
|
||||
@ -682,6 +698,10 @@
|
||||
<string>Trumbles have eaten a cargopod of %@.</string>
|
||||
</array>
|
||||
<!-- internal damage -->
|
||||
<key>@-damaged</key>
|
||||
<array>
|
||||
<string>%@ damaged.</string>
|
||||
</array>
|
||||
<key>@-destroyed</key>
|
||||
<array>
|
||||
<string>%@ destroyed.</string>
|
||||
|
@ -21,7 +21,7 @@
|
||||
<integer>4000</integer>
|
||||
<string>Large Cargo Bay</string>
|
||||
<string>EQ_CARGO_BAY</string>
|
||||
<string>Retro-fitted hull extensions permit the enclosure of an extra fifteen tons of cargo capacity.</string>
|
||||
<string>Retro-fitted hull extensions permit the enclosure of a few extra tons of cargo capacity.</string>
|
||||
</array>
|
||||
<array>
|
||||
<integer>2</integer>
|
||||
@ -209,6 +209,14 @@
|
||||
<string>EQ_WEAPON_TWIN_PLASMA_CANNON</string>
|
||||
<string>Basic cannon delivering charged plasma bursts at sublight speed.</string>
|
||||
</array>
|
||||
<!-- new items -->
|
||||
<array>
|
||||
<integer>4</integer>
|
||||
<integer>15000</integer>
|
||||
<string>External Heat Shielding</string>
|
||||
<string>EQ_HEAT_SHIELD</string>
|
||||
<string>Additional ceramid-fibre blanketing and tiles, no armour value but provides extra solar insulation.</string>
|
||||
</array>
|
||||
<!-- renovation -->
|
||||
<array>
|
||||
<integer>6</integer>
|
||||
|
@ -16,11 +16,13 @@
|
||||
<key>selector</key>
|
||||
<string>drawAegis:</string>
|
||||
<key>x</key>
|
||||
<integer>-108</integer>
|
||||
<integer>-116</integer>
|
||||
<key>y</key>
|
||||
<integer>-222</integer>
|
||||
<integer>-228</integer>
|
||||
<key>width</key>
|
||||
<integer>8</integer>
|
||||
<integer>16</integer>
|
||||
<key>height</key>
|
||||
<integer>16</integer>
|
||||
</dict>
|
||||
<dict><!-- scanner -->
|
||||
<key>alpha</key>
|
||||
|
@ -30,7 +30,7 @@
|
||||
<real>0</real>
|
||||
</array>
|
||||
</dict>
|
||||
<dict><!-- scanner zoom indicator, uses Images/zoom.png to provide 5 levels -->
|
||||
<dict><!-- scanner zoom indicator -->
|
||||
<key>alpha</key>
|
||||
<real>1</real>
|
||||
<key>selector</key>
|
||||
@ -40,7 +40,7 @@
|
||||
<key>y</key>
|
||||
<integer>-216</integer>
|
||||
</dict>
|
||||
<dict><!-- compass, uses Images/compass.png as background and Images/reddot.png and Images/greendot.png -->
|
||||
<dict><!-- compass -->
|
||||
<key>alpha</key>
|
||||
<real>1</real>
|
||||
<key>selector</key>
|
||||
@ -50,7 +50,7 @@
|
||||
<key>y</key>
|
||||
<integer>-216</integer>
|
||||
</dict>
|
||||
<dict><!-- station aegis, uses Images/aegis.png as indicator -->
|
||||
<dict><!-- station aegis -->
|
||||
<key>alpha</key>
|
||||
<real>1</real>
|
||||
<key>selector</key>
|
||||
@ -60,6 +60,16 @@
|
||||
<key>y</key>
|
||||
<integer>-216</integer>
|
||||
</dict>
|
||||
<dict><!-- fuel scoop status -->
|
||||
<key>alpha</key>
|
||||
<real>0.75</real>
|
||||
<key>selector</key>
|
||||
<string>drawScoopStatus:</string>
|
||||
<key>x</key>
|
||||
<integer>-132</integer>
|
||||
<key>y</key>
|
||||
<integer>-152</integer>
|
||||
</dict>
|
||||
<dict><!-- speed bar, can draw a surround 2 units out from the dial size specified -->
|
||||
<key>draw_surround</key>
|
||||
<true/>
|
||||
@ -383,4 +393,4 @@
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
</plist>
|
@ -44,6 +44,8 @@
|
||||
<integer>106</integer>
|
||||
<key>key_dump_cargo</key>
|
||||
<integer>100</integer>
|
||||
<key>key_rotate_cargo</key>
|
||||
<integer>82</integer>
|
||||
<key>key_autopilot</key>
|
||||
<integer>99</integer>
|
||||
<key>key_autodock</key>
|
||||
|
@ -57,7 +57,7 @@
|
||||
<!-- /Nova -->
|
||||
<!-- trumbles -->
|
||||
<key>trumble_offer</key>
|
||||
<string>Commander,\n\nYou look like a man who could use a Trumble!\n\nThis one's yours for only 30 credits.</string>
|
||||
<string>Commander [commander_name],\n\nYou look like someone who could use a Trumble on your [commander_shipname]!\n\nThis is yours for only 30 credits.</string>
|
||||
<key>trumble_offer_yesno</key>
|
||||
<dict>
|
||||
<key>NO</key>
|
||||
|
@ -238,6 +238,14 @@
|
||||
}
|
||||
);
|
||||
nova = (
|
||||
{
|
||||
conditions = ("status_string equal STATUS_IN_FLIGHT", "sunGoneNova_bool equal YES");
|
||||
do = (sendAllShipsAway);
|
||||
},
|
||||
{
|
||||
conditions = ("status_string equal STATUS_IN_FLIGHT", "sunWillGoNova_bool equal YES");
|
||||
do = (sendAllShipsAway);
|
||||
},
|
||||
{
|
||||
conditions = ("galaxy_number equal 3", "mission_novacount undefined");
|
||||
do = ("set: mission_novacount 0");
|
||||
@ -264,11 +272,8 @@
|
||||
);
|
||||
},
|
||||
{
|
||||
conditions = ("mission_nova equal 2HRS_TO_ZERO", "status_string equal STATUS_IN_FLIGHT");
|
||||
do = (
|
||||
{conditions = ("sunWillGoNova_bool equal NO"); do = ("reset: mission_nova"); },
|
||||
{conditions = ("sunWillGoNova_bool equal YES"); do = (sendAllShipsAway); }
|
||||
);
|
||||
conditions = ("mission_nova equal 2HRS_TO_ZERO", "status_string equal STATUS_IN_FLIGHT", "sunWillGoNova_bool equal NO");
|
||||
do = (sendAllShipsAway);
|
||||
},
|
||||
{
|
||||
conditions = (
|
||||
@ -293,6 +298,7 @@
|
||||
"useSpecialCargo: A hold full of %I refugees.",
|
||||
"setMissionDescription: nova_missiondesc",
|
||||
launchFromStation,
|
||||
blowUpStation,
|
||||
"set: mission_nova NOVA_ESCAPE_HERO",
|
||||
"setSunNovaIn: 30"
|
||||
);
|
||||
@ -365,12 +371,12 @@
|
||||
"missionChoice_string undefined"
|
||||
);
|
||||
do = (
|
||||
setGuiToMissionScreen,
|
||||
"showShipModel: none",
|
||||
"setMissionImage: none",
|
||||
"set: mission_trumbles OFFER_MADE",
|
||||
"setMissionImage: trumblebox.png",
|
||||
setGuiToMissionScreen,
|
||||
"addMissionText: trumble_offer",
|
||||
"setMissionChoices: trumble_offer_yesno"
|
||||
"setMissionChoices: trumble_offer_yesno",
|
||||
"set: mission_trumbles OFFER_MADE"
|
||||
);
|
||||
},
|
||||
{
|
||||
@ -381,6 +387,7 @@
|
||||
);
|
||||
do = (
|
||||
setGuiToStatusScreen,
|
||||
"setMissionImage: none",
|
||||
"set: mission_trumbles TRUMBLE_BOUGHT",
|
||||
"awardCredits: -30",
|
||||
"awardEquipment: EQ_TRUMBLE"
|
||||
@ -394,6 +401,7 @@
|
||||
);
|
||||
do = (
|
||||
setGuiToStatusScreen,
|
||||
"setMissionImage: none",
|
||||
"set: mission_trumbles NOT_NOW",
|
||||
resetMissionChoice
|
||||
);
|
||||
|
@ -619,7 +619,7 @@
|
||||
<key>name</key>
|
||||
<string>Cargo container</string>
|
||||
<key>roles</key>
|
||||
<string>cargopod</string>
|
||||
<string>cargopod 1t-cargopod</string>
|
||||
<key>thrust</key>
|
||||
<real>0.0</real>
|
||||
<key>weapon_energy</key>
|
||||
@ -2431,7 +2431,7 @@
|
||||
<key>thrust</key>
|
||||
<real>250</real>
|
||||
<key>weapon_energy</key>
|
||||
<real>12500</real>
|
||||
<real>4500</real>
|
||||
<key>weapon_offset_x</key>
|
||||
<real>0.0</real>
|
||||
</dict>
|
||||
@ -3961,7 +3961,7 @@
|
||||
<key>thrust</key>
|
||||
<real>250</real>
|
||||
<key>weapon_energy</key>
|
||||
<real>12500</real>
|
||||
<real>4500</real>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -30,7 +30,9 @@
|
||||
<key>standard_equipment</key>
|
||||
<dict>
|
||||
<key>extras</key>
|
||||
<array/>
|
||||
<array>
|
||||
<string>EQ_HEAT_SHIELD</string>
|
||||
</array>
|
||||
<key>forward_weapon_type</key>
|
||||
<string>EQ_WEAPON_PULSE_LASER</string>
|
||||
<key>missiles</key>
|
||||
@ -65,6 +67,7 @@
|
||||
<string>EQ_GAL_DRIVE</string>
|
||||
<string>EQ_ADVANCED_COMPASS</string>
|
||||
<string>EQ_SHIELD_BOOSTER</string>
|
||||
<string>EQ_HEAT_SHIELD</string>
|
||||
</array>
|
||||
<key>price</key>
|
||||
<integer>650000</integer>
|
||||
@ -102,6 +105,7 @@
|
||||
<string>EQ_ADVANCED_COMPASS</string>
|
||||
<string>EQ_SHIELD_BOOSTER</string>
|
||||
<string>EQ_NAVAL_SHIELD_BOOSTER</string>
|
||||
<string>EQ_HEAT_SHIELD</string>
|
||||
</array>
|
||||
<key>price</key>
|
||||
<integer>375000</integer>
|
||||
@ -146,6 +150,7 @@
|
||||
<string>EQ_GAL_DRIVE</string>
|
||||
<string>EQ_ADVANCED_COMPASS</string>
|
||||
<string>EQ_SHIELD_BOOSTER</string>
|
||||
<string>EQ_HEAT_SHIELD</string>
|
||||
</array>
|
||||
<key>price</key>
|
||||
<integer>450000</integer>
|
||||
@ -188,6 +193,7 @@
|
||||
<string>EQ_ADVANCED_COMPASS</string>
|
||||
<string>EQ_SHIELD_BOOSTER</string>
|
||||
<string>EQ_NAVAL_SHIELD_BOOSTER</string>
|
||||
<string>EQ_HEAT_SHIELD</string>
|
||||
</array>
|
||||
<key>price</key>
|
||||
<integer>495000</integer>
|
||||
@ -231,6 +237,7 @@
|
||||
<string>EQ_ADVANCED_COMPASS</string>
|
||||
<string>EQ_SHIELD_BOOSTER</string>
|
||||
<string>EQ_NAVAL_SHIELD_BOOSTER</string>
|
||||
<string>EQ_HEAT_SHIELD</string>
|
||||
</array>
|
||||
<key>price</key>
|
||||
<integer>150000</integer>
|
||||
@ -271,6 +278,7 @@
|
||||
<string>EQ_MULTI_TARGET</string>
|
||||
<string>EQ_GAL_DRIVE</string>
|
||||
<string>EQ_SHIELD_BOOSTER</string>
|
||||
<string>EQ_HEAT_SHIELD</string>
|
||||
</array>
|
||||
<key>price</key>
|
||||
<integer>100000</integer>
|
||||
@ -303,6 +311,7 @@
|
||||
<string>EQ_WEAPON_MILITARY_LASER</string>
|
||||
<string>EQ_GAL_DRIVE</string>
|
||||
<string>EQ_NAVAL_SHIELD_BOOSTER</string>
|
||||
<string>EQ_HEAT_SHIELD</string>
|
||||
</array>
|
||||
<key>price</key>
|
||||
<integer>485000</integer>
|
||||
@ -363,7 +372,9 @@
|
||||
<key>standard_equipment</key>
|
||||
<dict>
|
||||
<key>extras</key>
|
||||
<array/>
|
||||
<array>
|
||||
<string>EQ_HEAT_SHIELD</string>
|
||||
</array>
|
||||
<key>forward_weapon_type</key>
|
||||
<string>EQ_WEAPON_PULSE_LASER</string>
|
||||
<key>missiles</key>
|
||||
@ -405,7 +416,9 @@
|
||||
<key>standard_equipment</key>
|
||||
<dict>
|
||||
<key>extras</key>
|
||||
<array/>
|
||||
<array>
|
||||
<string>EQ_HEAT_SHIELD</string>
|
||||
</array>
|
||||
<key>forward_weapon_type</key>
|
||||
<string>EQ_WEAPON_NONE</string>
|
||||
<key>missiles</key>
|
||||
@ -440,6 +453,7 @@
|
||||
<string>EQ_MULTI_TARGET</string>
|
||||
<string>EQ_GAL_DRIVE</string>
|
||||
<string>EQ_SHIELD_BOOSTER</string>
|
||||
<string>EQ_HEAT_SHIELD</string>
|
||||
</array>
|
||||
<key>price</key>
|
||||
<integer>200000</integer>
|
||||
|
Binary file not shown.
BIN
Resources/oolite-document.icns
Normal file
BIN
Resources/oolite-document.icns
Normal file
Binary file not shown.
BIN
Resources/oolite-expansion-document.icns
Normal file
BIN
Resources/oolite-expansion-document.icns
Normal file
Binary file not shown.
BIN
Resources/oolite-icon.icns
Normal file
BIN
Resources/oolite-icon.icns
Normal file
Binary file not shown.
28
deps/Cocoa-deps/Ogg Vorbis/COPYING
vendored
Normal file
28
deps/Cocoa-deps/Ogg Vorbis/COPYING
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
Copyright (c) 2002, Xiph.org Foundation
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
481
deps/Cocoa-deps/Ogg Vorbis/Ogg.xcodeproj/project.pbxproj
vendored
Normal file
481
deps/Cocoa-deps/Ogg Vorbis/Ogg.xcodeproj/project.pbxproj
vendored
Normal file
@ -0,0 +1,481 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 42;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1ADE32B1097580A900961AE2 /* framing.c in Sources */ = {isa = PBXBuildFile; fileRef = 730F236209181A8D00AB638C /* framing.c */; };
|
||||
1ADE32B2097580AA00961AE2 /* bitwise.c in Sources */ = {isa = PBXBuildFile; fileRef = 730F236109181A8D00AB638C /* bitwise.c */; };
|
||||
730F236309181A8D00AB638C /* bitwise.c in Sources */ = {isa = PBXBuildFile; fileRef = 730F236109181A8D00AB638C /* bitwise.c */; };
|
||||
730F236409181A8D00AB638C /* framing.c in Sources */ = {isa = PBXBuildFile; fileRef = 730F236209181A8D00AB638C /* framing.c */; };
|
||||
730F236709181ABE00AB638C /* ogg.h in Headers */ = {isa = PBXBuildFile; fileRef = 730F236509181ABE00AB638C /* ogg.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
730F236809181ABE00AB638C /* os_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 730F236609181ABE00AB638C /* os_types.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8D07F2BE0486CC7A007CD1D0 /* Ogg_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 32BAE0B70371A74B00C91783 /* Ogg_Prefix.pch */; };
|
||||
8D07F2C00486CC7A007CD1D0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXBuildStyle section */
|
||||
4F0BB7EC011F40E904CA0E50 /* Development */ = {
|
||||
isa = PBXBuildStyle;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
ZERO_LINK = YES;
|
||||
};
|
||||
name = Development;
|
||||
};
|
||||
4F0BB7ED011F40E904CA0E50 /* Deployment */ = {
|
||||
isa = PBXBuildStyle;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = YES;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Deployment;
|
||||
};
|
||||
/* End PBXBuildStyle section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
1ADE32A40975807900961AE2 /* libOgg.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libOgg.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
32BAE0B70371A74B00C91783 /* Ogg_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Ogg_Prefix.pch; sourceTree = "<group>"; };
|
||||
730F236109181A8D00AB638C /* bitwise.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = bitwise.c; path = ../src/bitwise.c; sourceTree = SOURCE_ROOT; };
|
||||
730F236209181A8D00AB638C /* framing.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = framing.c; path = ../src/framing.c; sourceTree = SOURCE_ROOT; };
|
||||
730F236509181ABE00AB638C /* ogg.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ogg.h; path = ../include/ogg/ogg.h; sourceTree = SOURCE_ROOT; };
|
||||
730F236609181ABE00AB638C /* os_types.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = os_types.h; path = ../include/ogg/os_types.h; sourceTree = SOURCE_ROOT; };
|
||||
8D07F2C70486CC7A007CD1D0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||
8D07F2C80486CC7A007CD1D0 /* Ogg.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Ogg.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
1ADE32A20975807900961AE2 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
8D07F2C30486CC7A007CD1D0 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
034768DDFF38A45A11DB9C8B /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8D07F2C80486CC7A007CD1D0 /* Ogg.framework */,
|
||||
1ADE32A40975807900961AE2 /* libOgg.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0867D691FE84028FC02AAC07 /* Ogg */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
730F235F09181A3E00AB638C /* Headers */,
|
||||
08FB77ACFE841707C02AAC07 /* Source */,
|
||||
089C1665FE841158C02AAC07 /* Resources */,
|
||||
0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */,
|
||||
034768DDFF38A45A11DB9C8B /* Products */,
|
||||
);
|
||||
name = Ogg;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
);
|
||||
name = "External Frameworks and Libraries";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
089C1665FE841158C02AAC07 /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8D07F2C70486CC7A007CD1D0 /* Info.plist */,
|
||||
089C1666FE841158C02AAC07 /* InfoPlist.strings */,
|
||||
);
|
||||
name = Resources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
08FB77ACFE841707C02AAC07 /* Source */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
730F236109181A8D00AB638C /* bitwise.c */,
|
||||
730F236209181A8D00AB638C /* framing.c */,
|
||||
32BAE0B70371A74B00C91783 /* Ogg_Prefix.pch */,
|
||||
);
|
||||
name = Source;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
730F235F09181A3E00AB638C /* Headers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
730F236509181ABE00AB638C /* ogg.h */,
|
||||
730F236609181ABE00AB638C /* os_types.h */,
|
||||
);
|
||||
name = Headers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
1ADE32A00975807900961AE2 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
8D07F2BD0486CC7A007CD1D0 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8D07F2BE0486CC7A007CD1D0 /* Ogg_Prefix.pch in Headers */,
|
||||
730F236709181ABE00AB638C /* ogg.h in Headers */,
|
||||
730F236809181ABE00AB638C /* os_types.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
1ADE32A30975807900961AE2 /* LibOgg */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 1ADE32B7097580C800961AE2 /* Build configuration list for PBXNativeTarget "LibOgg" */;
|
||||
buildPhases = (
|
||||
1ADE32A00975807900961AE2 /* Headers */,
|
||||
1ADE32A10975807900961AE2 /* Sources */,
|
||||
1ADE32A20975807900961AE2 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
buildSettings = {
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
INSTALL_PATH = /usr/local/lib;
|
||||
PREBINDING = NO;
|
||||
PRODUCT_NAME = LibOgg;
|
||||
ZERO_LINK = YES;
|
||||
};
|
||||
dependencies = (
|
||||
);
|
||||
name = LibOgg;
|
||||
productName = LibOgg;
|
||||
productReference = 1ADE32A40975807900961AE2 /* libOgg.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
8D07F2BC0486CC7A007CD1D0 /* Ogg */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 730F235409181A3A00AB638C /* Build configuration list for PBXNativeTarget "Ogg" */;
|
||||
buildPhases = (
|
||||
8D07F2BD0486CC7A007CD1D0 /* Headers */,
|
||||
8D07F2BF0486CC7A007CD1D0 /* Resources */,
|
||||
8D07F2C10486CC7A007CD1D0 /* Sources */,
|
||||
8D07F2C30486CC7A007CD1D0 /* Frameworks */,
|
||||
8D07F2C50486CC7A007CD1D0 /* Rez */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
buildSettings = {
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = Ogg_Prefix.pch;
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = "$(HOME)/Library/Frameworks";
|
||||
LIBRARY_STYLE = DYNAMIC;
|
||||
PRODUCT_NAME = Ogg;
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
dependencies = (
|
||||
);
|
||||
name = Ogg;
|
||||
productInstallPath = "$(HOME)/Library/Frameworks";
|
||||
productName = Ogg;
|
||||
productReference = 8D07F2C80486CC7A007CD1D0 /* Ogg.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
0867D690FE84028FC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
buildConfigurationList = 730F235809181A3A00AB638C /* Build configuration list for PBXProject "Ogg" */;
|
||||
buildSettings = {
|
||||
};
|
||||
buildStyles = (
|
||||
4F0BB7EC011F40E904CA0E50 /* Development */,
|
||||
4F0BB7ED011F40E904CA0E50 /* Deployment */,
|
||||
);
|
||||
hasScannedForEncodings = 1;
|
||||
mainGroup = 0867D691FE84028FC02AAC07 /* Ogg */;
|
||||
productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */;
|
||||
projectDirPath = "";
|
||||
targets = (
|
||||
8D07F2BC0486CC7A007CD1D0 /* Ogg */,
|
||||
1ADE32A30975807900961AE2 /* LibOgg */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
8D07F2BF0486CC7A007CD1D0 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8D07F2C00486CC7A007CD1D0 /* InfoPlist.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXRezBuildPhase section */
|
||||
8D07F2C50486CC7A007CD1D0 /* Rez */ = {
|
||||
isa = PBXRezBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXRezBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
1ADE32A10975807900961AE2 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1ADE32B1097580A900961AE2 /* framing.c in Sources */,
|
||||
1ADE32B2097580AA00961AE2 /* bitwise.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
8D07F2C10486CC7A007CD1D0 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
730F236309181A8D00AB638C /* bitwise.c in Sources */,
|
||||
730F236409181A8D00AB638C /* framing.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
089C1666FE841158C02AAC07 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
089C1667FE841158C02AAC07 /* English */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
1ADE32B8097580C800961AE2 /* Development */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
INSTALL_PATH = /usr/local/lib;
|
||||
PREBINDING = NO;
|
||||
PRODUCT_NAME = LibOgg;
|
||||
ZERO_LINK = YES;
|
||||
};
|
||||
name = Development;
|
||||
};
|
||||
1ADE32B9097580C800961AE2 /* Deployment */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = (
|
||||
ppc,
|
||||
i386,
|
||||
);
|
||||
COPY_PHASE_STRIP = YES;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
INSTALL_PATH = /usr/local/lib;
|
||||
MACOSX_DEPLOYMENT_TARGET = "";
|
||||
PREBINDING = NO;
|
||||
PRODUCT_NAME = Ogg;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Deployment;
|
||||
};
|
||||
1ADE32BA097580C800961AE2 /* Default */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
INSTALL_PATH = /usr/local/lib;
|
||||
PREBINDING = NO;
|
||||
PRODUCT_NAME = LibOgg;
|
||||
ZERO_LINK = YES;
|
||||
};
|
||||
name = Default;
|
||||
};
|
||||
730F235509181A3A00AB638C /* Development */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = (
|
||||
ppc,
|
||||
i386,
|
||||
);
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = Ogg_Prefix.pch;
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = /Library/Frameworks;
|
||||
LIBRARY_STYLE = DYNAMIC;
|
||||
MACH_O_TYPE = mh_dylib;
|
||||
PRODUCT_NAME = Ogg;
|
||||
WRAPPER_EXTENSION = framework;
|
||||
ZERO_LINK = YES;
|
||||
};
|
||||
name = Development;
|
||||
};
|
||||
730F235609181A3A00AB638C /* Deployment */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = (
|
||||
ppc,
|
||||
i386,
|
||||
);
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = Ogg_Prefix.pch;
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = "@executable_path/../Frameworks";
|
||||
LIBRARY_STYLE = DYNAMIC;
|
||||
MACH_O_TYPE = mh_dylib;
|
||||
MACOSX_DEPLOYMENT_TARGET = "";
|
||||
OTHER_LDFLAGS = (
|
||||
"-Xlinker",
|
||||
"-image_base",
|
||||
"-Xlinker",
|
||||
650000,
|
||||
);
|
||||
PRODUCT_NAME = Ogg;
|
||||
STRIP_STYLE = "non-global";
|
||||
WRAPPER_EXTENSION = framework;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Deployment;
|
||||
};
|
||||
730F235709181A3A00AB638C /* Default */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = (
|
||||
ppc,
|
||||
i386,
|
||||
);
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = Ogg_Prefix.pch;
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = /Library/Frameworks;
|
||||
LIBRARY_STYLE = DYNAMIC;
|
||||
MACH_O_TYPE = mh_dylib;
|
||||
PRODUCT_NAME = Ogg;
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
name = Default;
|
||||
};
|
||||
730F235909181A3A00AB638C /* Development */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_PREPROCESSOR_DEFINITIONS = __MACOSX__;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.4;
|
||||
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
|
||||
};
|
||||
name = Development;
|
||||
};
|
||||
730F235A09181A3A00AB638C /* Deployment */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_PREPROCESSOR_DEFINITIONS = __MACOSX__;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.4;
|
||||
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
|
||||
};
|
||||
name = Deployment;
|
||||
};
|
||||
730F235B09181A3A00AB638C /* Default */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_PREPROCESSOR_DEFINITIONS = __MACOSX__;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.4;
|
||||
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
|
||||
};
|
||||
name = Default;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
1ADE32B7097580C800961AE2 /* Build configuration list for PBXNativeTarget "LibOgg" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1ADE32B8097580C800961AE2 /* Development */,
|
||||
1ADE32B9097580C800961AE2 /* Deployment */,
|
||||
1ADE32BA097580C800961AE2 /* Default */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Default;
|
||||
};
|
||||
730F235409181A3A00AB638C /* Build configuration list for PBXNativeTarget "Ogg" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
730F235509181A3A00AB638C /* Development */,
|
||||
730F235609181A3A00AB638C /* Deployment */,
|
||||
730F235709181A3A00AB638C /* Default */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Default;
|
||||
};
|
||||
730F235809181A3A00AB638C /* Build configuration list for PBXProject "Ogg" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
730F235909181A3A00AB638C /* Development */,
|
||||
730F235A09181A3A00AB638C /* Deployment */,
|
||||
730F235B09181A3A00AB638C /* Default */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Default;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
|
||||
}
|
859
deps/Cocoa-deps/Ogg Vorbis/Vorbis.xcodeproj/project.pbxproj
vendored
Normal file
859
deps/Cocoa-deps/Ogg Vorbis/Vorbis.xcodeproj/project.pbxproj
vendored
Normal file
@ -0,0 +1,859 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 42;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1ADE327809757FCF00961AE2 /* analysis.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F60A03389C830112CE8F /* analysis.c */; };
|
||||
1ADE327A09757FD200961AE2 /* bitrate.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F60D03389C830112CE8F /* bitrate.c */; };
|
||||
1ADE327B09757FD500961AE2 /* block.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F60F03389C830112CE8F /* block.c */; };
|
||||
1ADE327C09757FD500961AE2 /* codebook.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F62303389C830112CE8F /* codebook.c */; };
|
||||
1ADE32880975800000961AE2 /* envelope.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F62603389C830112CE8F /* envelope.c */; };
|
||||
1ADE32890975800000961AE2 /* floor0.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F62803389C830112CE8F /* floor0.c */; };
|
||||
1ADE328A0975800100961AE2 /* floor1.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F62903389C830112CE8F /* floor1.c */; };
|
||||
1ADE328B0975800100961AE2 /* info.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F62B03389C830112CE8F /* info.c */; };
|
||||
1ADE328C0975800200961AE2 /* lookup.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F62C03389C830112CE8F /* lookup.c */; };
|
||||
1ADE328D0975800200961AE2 /* lpc.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F63003389C830112CE8F /* lpc.c */; };
|
||||
1ADE328E0975800300961AE2 /* lsp.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F63203389C830112CE8F /* lsp.c */; };
|
||||
1ADE328F0975800400961AE2 /* mapping0.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F63603389C830112CE8F /* mapping0.c */; };
|
||||
1ADE32900975800500961AE2 /* mdct.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F63803389C830112CE8F /* mdct.c */; };
|
||||
1ADE32910975800700961AE2 /* psy.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F65203389C830112CE8F /* psy.c */; };
|
||||
1ADE32930975800800961AE2 /* registry.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F65503389C830112CE8F /* registry.c */; };
|
||||
1ADE32940975800900961AE2 /* res0.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F65703389C830112CE8F /* res0.c */; };
|
||||
1ADE32950975800A00961AE2 /* sharedbook.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F65903389C830112CE8F /* sharedbook.c */; };
|
||||
1ADE32960975800A00961AE2 /* smallft.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F65A03389C830112CE8F /* smallft.c */; };
|
||||
1ADE32970975800B00961AE2 /* synthesis.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F65C03389C830112CE8F /* synthesis.c */; };
|
||||
1ADE32990975800C00961AE2 /* vorbisenc.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F65E03389C830112CE8F /* vorbisenc.c */; };
|
||||
1ADE329A0975800E00961AE2 /* vorbisfile.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F65F03389C830112CE8F /* vorbisfile.c */; };
|
||||
1ADE329B0975800E00961AE2 /* window.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F66003389C830112CE8F /* window.c */; };
|
||||
730F23A3091827B100AB638C /* codec.h in Headers */ = {isa = PBXBuildFile; fileRef = F58520B90191D12B01A802FE /* codec.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
730F23A4091827B100AB638C /* vorbisenc.h in Headers */ = {isa = PBXBuildFile; fileRef = F58520BA0191D12B01A802FE /* vorbisenc.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
730F23A5091827B100AB638C /* vorbisfile.h in Headers */ = {isa = PBXBuildFile; fileRef = F58520BB0191D12B01A802FE /* vorbisfile.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
730F23A6091827B100AB638C /* backends.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F60B03389C830112CE8F /* backends.h */; };
|
||||
730F23A7091827B100AB638C /* bitrate.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F60E03389C830112CE8F /* bitrate.h */; };
|
||||
730F23A8091827B100AB638C /* res_books_stereo.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F61603389C830112CE8F /* res_books_stereo.h */; };
|
||||
730F23A9091827B100AB638C /* floor_books.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F61903389C830112CE8F /* floor_books.h */; };
|
||||
730F23AA091827B100AB638C /* res_books_uncoupled.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F62203389C830112CE8F /* res_books_uncoupled.h */; };
|
||||
730F23AB091827B100AB638C /* codebook.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F62403389C830112CE8F /* codebook.h */; };
|
||||
730F23AC091827B100AB638C /* codec_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F62503389C830112CE8F /* codec_internal.h */; };
|
||||
730F23AD091827B100AB638C /* envelope.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F62703389C830112CE8F /* envelope.h */; };
|
||||
730F23AE091827B100AB638C /* highlevel.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F62A03389C830112CE8F /* highlevel.h */; };
|
||||
730F23AF091827B100AB638C /* lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F62D03389C830112CE8F /* lookup.h */; };
|
||||
730F23B0091827B100AB638C /* lookup_data.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F62E03389C830112CE8F /* lookup_data.h */; };
|
||||
730F23B1091827B100AB638C /* lpc.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F63103389C830112CE8F /* lpc.h */; };
|
||||
730F23B2091827B100AB638C /* lsp.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F63303389C830112CE8F /* lsp.h */; };
|
||||
730F23B3091827B100AB638C /* masking.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F63703389C830112CE8F /* masking.h */; };
|
||||
730F23B4091827B100AB638C /* mdct.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F63903389C830112CE8F /* mdct.h */; };
|
||||
730F23B5091827B100AB638C /* misc.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F63B03389C830112CE8F /* misc.h */; };
|
||||
730F23B6091827B100AB638C /* floor_all.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F63E03389C830112CE8F /* floor_all.h */; };
|
||||
730F23B7091827B100AB638C /* psych_11.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F64103389C830112CE8F /* psych_11.h */; };
|
||||
730F23B8091827B100AB638C /* psych_16.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F64203389C830112CE8F /* psych_16.h */; };
|
||||
730F23B9091827B100AB638C /* psych_44.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F64303389C830112CE8F /* psych_44.h */; };
|
||||
730F23BA091827B100AB638C /* psych_8.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F64403389C830112CE8F /* psych_8.h */; };
|
||||
730F23BB091827B100AB638C /* residue_16.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F64503389C830112CE8F /* residue_16.h */; };
|
||||
730F23BC091827B100AB638C /* residue_44.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F64603389C830112CE8F /* residue_44.h */; };
|
||||
730F23BD091827B100AB638C /* residue_44u.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F64703389C830112CE8F /* residue_44u.h */; };
|
||||
730F23BE091827B100AB638C /* residue_8.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F64803389C830112CE8F /* residue_8.h */; };
|
||||
730F23BF091827B100AB638C /* setup_11.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F64903389C830112CE8F /* setup_11.h */; };
|
||||
730F23C0091827B100AB638C /* setup_16.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F64A03389C830112CE8F /* setup_16.h */; };
|
||||
730F23C1091827B100AB638C /* setup_22.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F64B03389C830112CE8F /* setup_22.h */; };
|
||||
730F23C2091827B100AB638C /* setup_32.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F64C03389C830112CE8F /* setup_32.h */; };
|
||||
730F23C3091827B100AB638C /* setup_44.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F64D03389C830112CE8F /* setup_44.h */; };
|
||||
730F23C4091827B100AB638C /* setup_44u.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F64E03389C830112CE8F /* setup_44u.h */; };
|
||||
730F23C5091827B100AB638C /* setup_8.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F64F03389C830112CE8F /* setup_8.h */; };
|
||||
730F23C6091827B100AB638C /* setup_X.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F65003389C830112CE8F /* setup_X.h */; };
|
||||
730F23C7091827B100AB638C /* os.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F65103389C830112CE8F /* os.h */; };
|
||||
730F23C8091827B100AB638C /* psy.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F65303389C830112CE8F /* psy.h */; };
|
||||
730F23C9091827B100AB638C /* registry.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F65603389C830112CE8F /* registry.h */; };
|
||||
730F23CA091827B100AB638C /* scales.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F65803389C830112CE8F /* scales.h */; };
|
||||
730F23CB091827B100AB638C /* smallft.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F65B03389C830112CE8F /* smallft.h */; };
|
||||
730F23CC091827B100AB638C /* window.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D8F66103389C830112CE8F /* window.h */; };
|
||||
730F23CE091827B100AB638C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; };
|
||||
730F23D3091827B100AB638C /* analysis.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F60A03389C830112CE8F /* analysis.c */; };
|
||||
730F23D4091827B100AB638C /* bitrate.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F60D03389C830112CE8F /* bitrate.c */; };
|
||||
730F23D5091827B100AB638C /* block.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F60F03389C830112CE8F /* block.c */; };
|
||||
730F23D6091827B100AB638C /* codebook.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F62303389C830112CE8F /* codebook.c */; };
|
||||
730F23D7091827B100AB638C /* envelope.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F62603389C830112CE8F /* envelope.c */; };
|
||||
730F23D8091827B100AB638C /* floor0.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F62803389C830112CE8F /* floor0.c */; };
|
||||
730F23D9091827B100AB638C /* floor1.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F62903389C830112CE8F /* floor1.c */; };
|
||||
730F23DA091827B100AB638C /* info.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F62B03389C830112CE8F /* info.c */; };
|
||||
730F23DB091827B100AB638C /* lookup.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F62C03389C830112CE8F /* lookup.c */; };
|
||||
730F23DC091827B100AB638C /* lpc.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F63003389C830112CE8F /* lpc.c */; };
|
||||
730F23DD091827B100AB638C /* lsp.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F63203389C830112CE8F /* lsp.c */; };
|
||||
730F23DE091827B100AB638C /* mapping0.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F63603389C830112CE8F /* mapping0.c */; };
|
||||
730F23DF091827B100AB638C /* mdct.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F63803389C830112CE8F /* mdct.c */; };
|
||||
730F23E0091827B100AB638C /* psy.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F65203389C830112CE8F /* psy.c */; };
|
||||
730F23E1091827B100AB638C /* registry.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F65503389C830112CE8F /* registry.c */; };
|
||||
730F23E2091827B100AB638C /* res0.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F65703389C830112CE8F /* res0.c */; };
|
||||
730F23E3091827B100AB638C /* sharedbook.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F65903389C830112CE8F /* sharedbook.c */; };
|
||||
730F23E4091827B100AB638C /* smallft.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F65A03389C830112CE8F /* smallft.c */; };
|
||||
730F23E5091827B100AB638C /* synthesis.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F65C03389C830112CE8F /* synthesis.c */; };
|
||||
730F23E6091827B100AB638C /* vorbisenc.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F65E03389C830112CE8F /* vorbisenc.c */; };
|
||||
730F23E7091827B100AB638C /* vorbisfile.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F65F03389C830112CE8F /* vorbisfile.c */; };
|
||||
730F23E8091827B100AB638C /* window.c in Sources */ = {isa = PBXBuildFile; fileRef = F5D8F66003389C830112CE8F /* window.c */; };
|
||||
730F23FB0918281100AB638C /* Ogg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 730F23FA0918281100AB638C /* Ogg.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXBuildStyle section */
|
||||
014CEA440018CDF011CA2923 /* Development */ = {
|
||||
isa = PBXBuildStyle;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
OPTIMIZATION_CFLAGS = "-O0";
|
||||
ZERO_LINK = YES;
|
||||
};
|
||||
name = Development;
|
||||
};
|
||||
014CEA450018CDF011CA2923 /* Deployment */ = {
|
||||
isa = PBXBuildStyle;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = YES;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Deployment;
|
||||
};
|
||||
/* End PBXBuildStyle section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
1ADE327709757FBE00961AE2 /* libVorbisAll.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libVorbisAll.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
730F23F0091827B100AB638C /* Info.plist */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = Info.plist; sourceTree = "<group>"; };
|
||||
730F23F1091827B100AB638C /* Vorbis.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Vorbis.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
730F23FA0918281100AB638C /* Ogg.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Ogg.framework; path = /Library/Frameworks/Ogg.framework; sourceTree = "<absolute>"; };
|
||||
F58520B90191D12B01A802FE /* codec.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = codec.h; sourceTree = "<group>"; };
|
||||
F58520BA0191D12B01A802FE /* vorbisenc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = vorbisenc.h; sourceTree = "<group>"; };
|
||||
F58520BB0191D12B01A802FE /* vorbisfile.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = vorbisfile.h; sourceTree = "<group>"; };
|
||||
F5D8F60A03389C830112CE8F /* analysis.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = analysis.c; sourceTree = "<group>"; };
|
||||
F5D8F60B03389C830112CE8F /* backends.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = backends.h; sourceTree = "<group>"; };
|
||||
F5D8F60C03389C830112CE8F /* barkmel.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = barkmel.c; sourceTree = "<group>"; };
|
||||
F5D8F60D03389C830112CE8F /* bitrate.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bitrate.c; sourceTree = "<group>"; };
|
||||
F5D8F60E03389C830112CE8F /* bitrate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bitrate.h; sourceTree = "<group>"; };
|
||||
F5D8F60F03389C830112CE8F /* block.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = block.c; sourceTree = "<group>"; };
|
||||
F5D8F61603389C830112CE8F /* res_books_stereo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = res_books_stereo.h; sourceTree = "<group>"; };
|
||||
F5D8F61903389C830112CE8F /* floor_books.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = floor_books.h; sourceTree = "<group>"; };
|
||||
F5D8F62203389C830112CE8F /* res_books_uncoupled.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = res_books_uncoupled.h; sourceTree = "<group>"; };
|
||||
F5D8F62303389C830112CE8F /* codebook.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = codebook.c; sourceTree = "<group>"; };
|
||||
F5D8F62403389C830112CE8F /* codebook.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = codebook.h; sourceTree = "<group>"; };
|
||||
F5D8F62503389C830112CE8F /* codec_internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = codec_internal.h; sourceTree = "<group>"; };
|
||||
F5D8F62603389C830112CE8F /* envelope.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = envelope.c; sourceTree = "<group>"; };
|
||||
F5D8F62703389C830112CE8F /* envelope.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = envelope.h; sourceTree = "<group>"; };
|
||||
F5D8F62803389C830112CE8F /* floor0.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = floor0.c; sourceTree = "<group>"; };
|
||||
F5D8F62903389C830112CE8F /* floor1.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = floor1.c; sourceTree = "<group>"; };
|
||||
F5D8F62A03389C830112CE8F /* highlevel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = highlevel.h; sourceTree = "<group>"; };
|
||||
F5D8F62B03389C830112CE8F /* info.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = info.c; sourceTree = "<group>"; };
|
||||
F5D8F62C03389C830112CE8F /* lookup.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = lookup.c; sourceTree = "<group>"; };
|
||||
F5D8F62D03389C830112CE8F /* lookup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = lookup.h; sourceTree = "<group>"; };
|
||||
F5D8F62E03389C830112CE8F /* lookup_data.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = lookup_data.h; sourceTree = "<group>"; };
|
||||
F5D8F63003389C830112CE8F /* lpc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = lpc.c; sourceTree = "<group>"; };
|
||||
F5D8F63103389C830112CE8F /* lpc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = lpc.h; sourceTree = "<group>"; };
|
||||
F5D8F63203389C830112CE8F /* lsp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = lsp.c; sourceTree = "<group>"; };
|
||||
F5D8F63303389C830112CE8F /* lsp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = lsp.h; sourceTree = "<group>"; };
|
||||
F5D8F63603389C830112CE8F /* mapping0.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mapping0.c; sourceTree = "<group>"; };
|
||||
F5D8F63703389C830112CE8F /* masking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = masking.h; sourceTree = "<group>"; };
|
||||
F5D8F63803389C830112CE8F /* mdct.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mdct.c; sourceTree = "<group>"; };
|
||||
F5D8F63903389C830112CE8F /* mdct.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mdct.h; sourceTree = "<group>"; };
|
||||
F5D8F63A03389C830112CE8F /* misc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = misc.c; sourceTree = "<group>"; };
|
||||
F5D8F63B03389C830112CE8F /* misc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = misc.h; sourceTree = "<group>"; };
|
||||
F5D8F63E03389C830112CE8F /* floor_all.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = floor_all.h; sourceTree = "<group>"; };
|
||||
F5D8F64103389C830112CE8F /* psych_11.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = psych_11.h; sourceTree = "<group>"; };
|
||||
F5D8F64203389C830112CE8F /* psych_16.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = psych_16.h; sourceTree = "<group>"; };
|
||||
F5D8F64303389C830112CE8F /* psych_44.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = psych_44.h; sourceTree = "<group>"; };
|
||||
F5D8F64403389C830112CE8F /* psych_8.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = psych_8.h; sourceTree = "<group>"; };
|
||||
F5D8F64503389C830112CE8F /* residue_16.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = residue_16.h; sourceTree = "<group>"; };
|
||||
F5D8F64603389C830112CE8F /* residue_44.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = residue_44.h; sourceTree = "<group>"; };
|
||||
F5D8F64703389C830112CE8F /* residue_44u.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = residue_44u.h; sourceTree = "<group>"; };
|
||||
F5D8F64803389C830112CE8F /* residue_8.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = residue_8.h; sourceTree = "<group>"; };
|
||||
F5D8F64903389C830112CE8F /* setup_11.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = setup_11.h; sourceTree = "<group>"; };
|
||||
F5D8F64A03389C830112CE8F /* setup_16.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = setup_16.h; sourceTree = "<group>"; };
|
||||
F5D8F64B03389C830112CE8F /* setup_22.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = setup_22.h; sourceTree = "<group>"; };
|
||||
F5D8F64C03389C830112CE8F /* setup_32.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = setup_32.h; sourceTree = "<group>"; };
|
||||
F5D8F64D03389C830112CE8F /* setup_44.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = setup_44.h; sourceTree = "<group>"; };
|
||||
F5D8F64E03389C830112CE8F /* setup_44u.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = setup_44u.h; sourceTree = "<group>"; };
|
||||
F5D8F64F03389C830112CE8F /* setup_8.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = setup_8.h; sourceTree = "<group>"; };
|
||||
F5D8F65003389C830112CE8F /* setup_X.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = setup_X.h; sourceTree = "<group>"; };
|
||||
F5D8F65103389C830112CE8F /* os.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = os.h; sourceTree = "<group>"; };
|
||||
F5D8F65203389C830112CE8F /* psy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = psy.c; sourceTree = "<group>"; };
|
||||
F5D8F65303389C830112CE8F /* psy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = psy.h; sourceTree = "<group>"; };
|
||||
F5D8F65403389C830112CE8F /* psytune.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = psytune.c; sourceTree = "<group>"; };
|
||||
F5D8F65503389C830112CE8F /* registry.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = registry.c; sourceTree = "<group>"; };
|
||||
F5D8F65603389C830112CE8F /* registry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = registry.h; sourceTree = "<group>"; };
|
||||
F5D8F65703389C830112CE8F /* res0.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = res0.c; sourceTree = "<group>"; };
|
||||
F5D8F65803389C830112CE8F /* scales.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = scales.h; sourceTree = "<group>"; };
|
||||
F5D8F65903389C830112CE8F /* sharedbook.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = sharedbook.c; sourceTree = "<group>"; };
|
||||
F5D8F65A03389C830112CE8F /* smallft.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = smallft.c; sourceTree = "<group>"; };
|
||||
F5D8F65B03389C830112CE8F /* smallft.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = smallft.h; sourceTree = "<group>"; };
|
||||
F5D8F65C03389C830112CE8F /* synthesis.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = synthesis.c; sourceTree = "<group>"; };
|
||||
F5D8F65D03389C830112CE8F /* tone.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = tone.c; sourceTree = "<group>"; };
|
||||
F5D8F65E03389C830112CE8F /* vorbisenc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = vorbisenc.c; sourceTree = "<group>"; };
|
||||
F5D8F65F03389C830112CE8F /* vorbisfile.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = vorbisfile.c; sourceTree = "<group>"; };
|
||||
F5D8F66003389C830112CE8F /* window.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = window.c; sourceTree = "<group>"; };
|
||||
F5D8F66103389C830112CE8F /* window.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = window.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
1ADE327509757FBE00961AE2 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
730F23E9091827B100AB638C /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
730F23FB0918281100AB638C /* Ogg.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
034768DFFF38A50411DB9C8B /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
730F23F1091827B100AB638C /* Vorbis.framework */,
|
||||
1ADE327709757FBE00961AE2 /* libVorbisAll.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0867D691FE84028FC02AAC07 /* vorbis */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F58520B70191D12B01A802FE /* Headers */,
|
||||
F5D8F60803389C830112CE8F /* lib */,
|
||||
089C1665FE841158C02AAC07 /* Resources */,
|
||||
0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */,
|
||||
034768DFFF38A50411DB9C8B /* Products */,
|
||||
);
|
||||
name = vorbis;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
730F23FA0918281100AB638C /* Ogg.framework */,
|
||||
);
|
||||
name = "External Frameworks and Libraries";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
089C1665FE841158C02AAC07 /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
730F23F0091827B100AB638C /* Info.plist */,
|
||||
089C1666FE841158C02AAC07 /* InfoPlist.strings */,
|
||||
);
|
||||
name = Resources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F58520B70191D12B01A802FE /* Headers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F58520B90191D12B01A802FE /* codec.h */,
|
||||
F58520BA0191D12B01A802FE /* vorbisenc.h */,
|
||||
F58520BB0191D12B01A802FE /* vorbisfile.h */,
|
||||
);
|
||||
name = Headers;
|
||||
path = ../include/vorbis;
|
||||
sourceTree = SOURCE_ROOT;
|
||||
};
|
||||
F5D8F60803389C830112CE8F /* lib */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F5D8F60A03389C830112CE8F /* analysis.c */,
|
||||
F5D8F60B03389C830112CE8F /* backends.h */,
|
||||
F5D8F60C03389C830112CE8F /* barkmel.c */,
|
||||
F5D8F60D03389C830112CE8F /* bitrate.c */,
|
||||
F5D8F60E03389C830112CE8F /* bitrate.h */,
|
||||
F5D8F60F03389C830112CE8F /* block.c */,
|
||||
F5D8F61003389C830112CE8F /* books */,
|
||||
F5D8F62303389C830112CE8F /* codebook.c */,
|
||||
F5D8F62403389C830112CE8F /* codebook.h */,
|
||||
F5D8F62503389C830112CE8F /* codec_internal.h */,
|
||||
F5D8F62603389C830112CE8F /* envelope.c */,
|
||||
F5D8F62703389C830112CE8F /* envelope.h */,
|
||||
F5D8F62803389C830112CE8F /* floor0.c */,
|
||||
F5D8F62903389C830112CE8F /* floor1.c */,
|
||||
F5D8F62A03389C830112CE8F /* highlevel.h */,
|
||||
F5D8F62B03389C830112CE8F /* info.c */,
|
||||
F5D8F62C03389C830112CE8F /* lookup.c */,
|
||||
F5D8F62D03389C830112CE8F /* lookup.h */,
|
||||
F5D8F62E03389C830112CE8F /* lookup_data.h */,
|
||||
F5D8F63003389C830112CE8F /* lpc.c */,
|
||||
F5D8F63103389C830112CE8F /* lpc.h */,
|
||||
F5D8F63203389C830112CE8F /* lsp.c */,
|
||||
F5D8F63303389C830112CE8F /* lsp.h */,
|
||||
F5D8F63603389C830112CE8F /* mapping0.c */,
|
||||
F5D8F63703389C830112CE8F /* masking.h */,
|
||||
F5D8F63803389C830112CE8F /* mdct.c */,
|
||||
F5D8F63903389C830112CE8F /* mdct.h */,
|
||||
F5D8F63A03389C830112CE8F /* misc.c */,
|
||||
F5D8F63B03389C830112CE8F /* misc.h */,
|
||||
F5D8F63C03389C830112CE8F /* modes */,
|
||||
F5D8F65103389C830112CE8F /* os.h */,
|
||||
F5D8F65203389C830112CE8F /* psy.c */,
|
||||
F5D8F65303389C830112CE8F /* psy.h */,
|
||||
F5D8F65403389C830112CE8F /* psytune.c */,
|
||||
F5D8F65503389C830112CE8F /* registry.c */,
|
||||
F5D8F65603389C830112CE8F /* registry.h */,
|
||||
F5D8F65703389C830112CE8F /* res0.c */,
|
||||
F5D8F65803389C830112CE8F /* scales.h */,
|
||||
F5D8F65903389C830112CE8F /* sharedbook.c */,
|
||||
F5D8F65A03389C830112CE8F /* smallft.c */,
|
||||
F5D8F65B03389C830112CE8F /* smallft.h */,
|
||||
F5D8F65C03389C830112CE8F /* synthesis.c */,
|
||||
F5D8F65D03389C830112CE8F /* tone.c */,
|
||||
F5D8F65E03389C830112CE8F /* vorbisenc.c */,
|
||||
F5D8F65F03389C830112CE8F /* vorbisfile.c */,
|
||||
F5D8F66003389C830112CE8F /* window.c */,
|
||||
F5D8F66103389C830112CE8F /* window.h */,
|
||||
);
|
||||
name = lib;
|
||||
path = ../lib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F5D8F61003389C830112CE8F /* books */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F5D8F61203389C830112CE8F /* coupled */,
|
||||
F5D8F61703389C830112CE8F /* floor */,
|
||||
F5D8F61E03389C830112CE8F /* uncoupled */,
|
||||
);
|
||||
path = books;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F5D8F61203389C830112CE8F /* coupled */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F5D8F61603389C830112CE8F /* res_books_stereo.h */,
|
||||
);
|
||||
path = coupled;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F5D8F61703389C830112CE8F /* floor */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F5D8F61903389C830112CE8F /* floor_books.h */,
|
||||
);
|
||||
path = floor;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F5D8F61E03389C830112CE8F /* uncoupled */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F5D8F62203389C830112CE8F /* res_books_uncoupled.h */,
|
||||
);
|
||||
path = uncoupled;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F5D8F63C03389C830112CE8F /* modes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F5D8F63E03389C830112CE8F /* floor_all.h */,
|
||||
F5D8F64103389C830112CE8F /* psych_11.h */,
|
||||
F5D8F64203389C830112CE8F /* psych_16.h */,
|
||||
F5D8F64303389C830112CE8F /* psych_44.h */,
|
||||
F5D8F64403389C830112CE8F /* psych_8.h */,
|
||||
F5D8F64503389C830112CE8F /* residue_16.h */,
|
||||
F5D8F64603389C830112CE8F /* residue_44.h */,
|
||||
F5D8F64703389C830112CE8F /* residue_44u.h */,
|
||||
F5D8F64803389C830112CE8F /* residue_8.h */,
|
||||
F5D8F64903389C830112CE8F /* setup_11.h */,
|
||||
F5D8F64A03389C830112CE8F /* setup_16.h */,
|
||||
F5D8F64B03389C830112CE8F /* setup_22.h */,
|
||||
F5D8F64C03389C830112CE8F /* setup_32.h */,
|
||||
F5D8F64D03389C830112CE8F /* setup_44.h */,
|
||||
F5D8F64E03389C830112CE8F /* setup_44u.h */,
|
||||
F5D8F64F03389C830112CE8F /* setup_8.h */,
|
||||
F5D8F65003389C830112CE8F /* setup_X.h */,
|
||||
);
|
||||
path = modes;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
1ADE327309757FBE00961AE2 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
730F23A2091827B100AB638C /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
730F23A3091827B100AB638C /* codec.h in Headers */,
|
||||
730F23A4091827B100AB638C /* vorbisenc.h in Headers */,
|
||||
730F23A5091827B100AB638C /* vorbisfile.h in Headers */,
|
||||
730F23A6091827B100AB638C /* backends.h in Headers */,
|
||||
730F23A7091827B100AB638C /* bitrate.h in Headers */,
|
||||
730F23A8091827B100AB638C /* res_books_stereo.h in Headers */,
|
||||
730F23A9091827B100AB638C /* floor_books.h in Headers */,
|
||||
730F23AA091827B100AB638C /* res_books_uncoupled.h in Headers */,
|
||||
730F23AB091827B100AB638C /* codebook.h in Headers */,
|
||||
730F23AC091827B100AB638C /* codec_internal.h in Headers */,
|
||||
730F23AD091827B100AB638C /* envelope.h in Headers */,
|
||||
730F23AE091827B100AB638C /* highlevel.h in Headers */,
|
||||
730F23AF091827B100AB638C /* lookup.h in Headers */,
|
||||
730F23B0091827B100AB638C /* lookup_data.h in Headers */,
|
||||
730F23B1091827B100AB638C /* lpc.h in Headers */,
|
||||
730F23B2091827B100AB638C /* lsp.h in Headers */,
|
||||
730F23B3091827B100AB638C /* masking.h in Headers */,
|
||||
730F23B4091827B100AB638C /* mdct.h in Headers */,
|
||||
730F23B5091827B100AB638C /* misc.h in Headers */,
|
||||
730F23B6091827B100AB638C /* floor_all.h in Headers */,
|
||||
730F23B7091827B100AB638C /* psych_11.h in Headers */,
|
||||
730F23B8091827B100AB638C /* psych_16.h in Headers */,
|
||||
730F23B9091827B100AB638C /* psych_44.h in Headers */,
|
||||
730F23BA091827B100AB638C /* psych_8.h in Headers */,
|
||||
730F23BB091827B100AB638C /* residue_16.h in Headers */,
|
||||
730F23BC091827B100AB638C /* residue_44.h in Headers */,
|
||||
730F23BD091827B100AB638C /* residue_44u.h in Headers */,
|
||||
730F23BE091827B100AB638C /* residue_8.h in Headers */,
|
||||
730F23BF091827B100AB638C /* setup_11.h in Headers */,
|
||||
730F23C0091827B100AB638C /* setup_16.h in Headers */,
|
||||
730F23C1091827B100AB638C /* setup_22.h in Headers */,
|
||||
730F23C2091827B100AB638C /* setup_32.h in Headers */,
|
||||
730F23C3091827B100AB638C /* setup_44.h in Headers */,
|
||||
730F23C4091827B100AB638C /* setup_44u.h in Headers */,
|
||||
730F23C5091827B100AB638C /* setup_8.h in Headers */,
|
||||
730F23C6091827B100AB638C /* setup_X.h in Headers */,
|
||||
730F23C7091827B100AB638C /* os.h in Headers */,
|
||||
730F23C8091827B100AB638C /* psy.h in Headers */,
|
||||
730F23C9091827B100AB638C /* registry.h in Headers */,
|
||||
730F23CA091827B100AB638C /* scales.h in Headers */,
|
||||
730F23CB091827B100AB638C /* smallft.h in Headers */,
|
||||
730F23CC091827B100AB638C /* window.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
1ADE327609757FBE00961AE2 /* LibVorbis */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 1ADE328009757FEC00961AE2 /* Build configuration list for PBXNativeTarget "LibVorbis" */;
|
||||
buildPhases = (
|
||||
1ADE327309757FBE00961AE2 /* Headers */,
|
||||
1ADE327409757FBE00961AE2 /* Sources */,
|
||||
1ADE327509757FBE00961AE2 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
buildSettings = {
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
INSTALL_PATH = /usr/local/lib;
|
||||
PREBINDING = NO;
|
||||
PRODUCT_NAME = LibVorbis;
|
||||
ZERO_LINK = YES;
|
||||
};
|
||||
dependencies = (
|
||||
);
|
||||
name = LibVorbis;
|
||||
productName = LibVorbis;
|
||||
productReference = 1ADE327709757FBE00961AE2 /* libVorbisAll.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
730F23A1091827B100AB638C /* Vorbis */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 730F23EC091827B100AB638C /* Build configuration list for PBXNativeTarget "Vorbis" */;
|
||||
buildPhases = (
|
||||
730F23A2091827B100AB638C /* Headers */,
|
||||
730F23CD091827B100AB638C /* Resources */,
|
||||
730F23D2091827B100AB638C /* Sources */,
|
||||
730F23E9091827B100AB638C /* Frameworks */,
|
||||
730F23EB091827B100AB638C /* Rez */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
buildSettings = {
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
/Library/Frameworks,
|
||||
../../ogg/macosx/build,
|
||||
);
|
||||
FRAMEWORK_VERSION = A;
|
||||
HEADER_SEARCH_PATHS = "";
|
||||
INSTALL_PATH = /Library/Frameworks;
|
||||
LIBRARY_SEARCH_PATHS = "";
|
||||
OTHER_CFLAGS = "-D__MACOSX__";
|
||||
OTHER_LDFLAGS = "";
|
||||
PRODUCT_NAME = Vorbis;
|
||||
SECTORDER_FLAGS = "";
|
||||
WARNING_CFLAGS = (
|
||||
"-Wmost",
|
||||
"-Wno-four-char-constants",
|
||||
"-Wno-unknown-pragmas",
|
||||
);
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
dependencies = (
|
||||
);
|
||||
name = Vorbis;
|
||||
productInstallPath = /Library/Frameworks;
|
||||
productName = vorbis;
|
||||
productReference = 730F23F1091827B100AB638C /* Vorbis.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
0867D690FE84028FC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
buildConfigurationList = 730F23F3091827B200AB638C /* Build configuration list for PBXProject "Vorbis" */;
|
||||
buildSettings = {
|
||||
};
|
||||
buildStyles = (
|
||||
014CEA440018CDF011CA2923 /* Development */,
|
||||
014CEA450018CDF011CA2923 /* Deployment */,
|
||||
);
|
||||
hasScannedForEncodings = 0;
|
||||
mainGroup = 0867D691FE84028FC02AAC07 /* vorbis */;
|
||||
productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
|
||||
projectDirPath = "";
|
||||
targets = (
|
||||
730F23A1091827B100AB638C /* Vorbis */,
|
||||
1ADE327609757FBE00961AE2 /* LibVorbis */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
730F23CD091827B100AB638C /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
730F23CE091827B100AB638C /* InfoPlist.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXRezBuildPhase section */
|
||||
730F23EB091827B100AB638C /* Rez */ = {
|
||||
isa = PBXRezBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXRezBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
1ADE327409757FBE00961AE2 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1ADE327809757FCF00961AE2 /* analysis.c in Sources */,
|
||||
1ADE327A09757FD200961AE2 /* bitrate.c in Sources */,
|
||||
1ADE327B09757FD500961AE2 /* block.c in Sources */,
|
||||
1ADE327C09757FD500961AE2 /* codebook.c in Sources */,
|
||||
1ADE32880975800000961AE2 /* envelope.c in Sources */,
|
||||
1ADE32890975800000961AE2 /* floor0.c in Sources */,
|
||||
1ADE328A0975800100961AE2 /* floor1.c in Sources */,
|
||||
1ADE328B0975800100961AE2 /* info.c in Sources */,
|
||||
1ADE328C0975800200961AE2 /* lookup.c in Sources */,
|
||||
1ADE328D0975800200961AE2 /* lpc.c in Sources */,
|
||||
1ADE328E0975800300961AE2 /* lsp.c in Sources */,
|
||||
1ADE328F0975800400961AE2 /* mapping0.c in Sources */,
|
||||
1ADE32900975800500961AE2 /* mdct.c in Sources */,
|
||||
1ADE32910975800700961AE2 /* psy.c in Sources */,
|
||||
1ADE32930975800800961AE2 /* registry.c in Sources */,
|
||||
1ADE32940975800900961AE2 /* res0.c in Sources */,
|
||||
1ADE32950975800A00961AE2 /* sharedbook.c in Sources */,
|
||||
1ADE32960975800A00961AE2 /* smallft.c in Sources */,
|
||||
1ADE32970975800B00961AE2 /* synthesis.c in Sources */,
|
||||
1ADE32990975800C00961AE2 /* vorbisenc.c in Sources */,
|
||||
1ADE329A0975800E00961AE2 /* vorbisfile.c in Sources */,
|
||||
1ADE329B0975800E00961AE2 /* window.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
730F23D2091827B100AB638C /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
730F23D3091827B100AB638C /* analysis.c in Sources */,
|
||||
730F23D4091827B100AB638C /* bitrate.c in Sources */,
|
||||
730F23D5091827B100AB638C /* block.c in Sources */,
|
||||
730F23D6091827B100AB638C /* codebook.c in Sources */,
|
||||
730F23D7091827B100AB638C /* envelope.c in Sources */,
|
||||
730F23D8091827B100AB638C /* floor0.c in Sources */,
|
||||
730F23D9091827B100AB638C /* floor1.c in Sources */,
|
||||
730F23DA091827B100AB638C /* info.c in Sources */,
|
||||
730F23DB091827B100AB638C /* lookup.c in Sources */,
|
||||
730F23DC091827B100AB638C /* lpc.c in Sources */,
|
||||
730F23DD091827B100AB638C /* lsp.c in Sources */,
|
||||
730F23DE091827B100AB638C /* mapping0.c in Sources */,
|
||||
730F23DF091827B100AB638C /* mdct.c in Sources */,
|
||||
730F23E0091827B100AB638C /* psy.c in Sources */,
|
||||
730F23E1091827B100AB638C /* registry.c in Sources */,
|
||||
730F23E2091827B100AB638C /* res0.c in Sources */,
|
||||
730F23E3091827B100AB638C /* sharedbook.c in Sources */,
|
||||
730F23E4091827B100AB638C /* smallft.c in Sources */,
|
||||
730F23E5091827B100AB638C /* synthesis.c in Sources */,
|
||||
730F23E6091827B100AB638C /* vorbisenc.c in Sources */,
|
||||
730F23E7091827B100AB638C /* vorbisfile.c in Sources */,
|
||||
730F23E8091827B100AB638C /* window.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
089C1666FE841158C02AAC07 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
089C1667FE841158C02AAC07 /* English */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
1ADE328109757FEC00961AE2 /* Development */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
INSTALL_PATH = /usr/local/lib;
|
||||
PREBINDING = NO;
|
||||
PRODUCT_NAME = LibVorbis;
|
||||
ZERO_LINK = YES;
|
||||
};
|
||||
name = Development;
|
||||
};
|
||||
1ADE328209757FEC00961AE2 /* Deployment */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = (
|
||||
ppc,
|
||||
i386,
|
||||
);
|
||||
COPY_PHASE_STRIP = YES;
|
||||
GCC_DYNAMIC_NO_PIC = YES;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../lib,
|
||||
"../../libogg-1.1.3/include",
|
||||
);
|
||||
INSTALL_PATH = /usr/local/lib;
|
||||
MACOSX_DEPLOYMENT_TARGET = "";
|
||||
PREBINDING = NO;
|
||||
PRODUCT_NAME = VorbisAll;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Deployment;
|
||||
};
|
||||
1ADE328309757FEC00961AE2 /* Default */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
INSTALL_PATH = /usr/local/lib;
|
||||
PREBINDING = NO;
|
||||
PRODUCT_NAME = LibVorbis;
|
||||
ZERO_LINK = YES;
|
||||
};
|
||||
name = Default;
|
||||
};
|
||||
730F23ED091827B100AB638C /* Development */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_SEARCH_PATHS = /Library/Frameworks;
|
||||
FRAMEWORK_VERSION = A;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../lib,
|
||||
"../../libogg-1.1.3/include",
|
||||
);
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = /Library/Frameworks;
|
||||
LIBRARY_SEARCH_PATHS = "";
|
||||
MACOSX_DEPLOYMENT_TARGET = "";
|
||||
OTHER_CFLAGS = "";
|
||||
OTHER_LDFLAGS = "";
|
||||
PRODUCT_NAME = Vorbis;
|
||||
SECTORDER_FLAGS = "";
|
||||
STRIP_STYLE = "non-global";
|
||||
WARNING_CFLAGS = (
|
||||
"-Wmost",
|
||||
"-Wno-four-char-constants",
|
||||
"-Wno-unknown-pragmas",
|
||||
);
|
||||
WRAPPER_EXTENSION = framework;
|
||||
ZERO_LINK = YES;
|
||||
};
|
||||
name = Development;
|
||||
};
|
||||
730F23EE091827B100AB638C /* Deployment */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_SEARCH_PATHS = /Library/Frameworks;
|
||||
FRAMEWORK_VERSION = A;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../lib,
|
||||
"../../libogg-1.1.3/include",
|
||||
);
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = "@executable_path/../Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = "";
|
||||
MACOSX_DEPLOYMENT_TARGET = "";
|
||||
OTHER_CFLAGS = "";
|
||||
OTHER_LDFLAGS = (
|
||||
"-Xlinker",
|
||||
"-image_base",
|
||||
"-Xlinker",
|
||||
600000,
|
||||
);
|
||||
PRODUCT_NAME = Vorbis;
|
||||
SECTORDER_FLAGS = "";
|
||||
STRIP_STYLE = "non-global";
|
||||
WARNING_CFLAGS = (
|
||||
"-Wmost",
|
||||
"-Wno-four-char-constants",
|
||||
"-Wno-unknown-pragmas",
|
||||
);
|
||||
WRAPPER_EXTENSION = framework;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Deployment;
|
||||
};
|
||||
730F23EF091827B100AB638C /* Default */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_SEARCH_PATHS = /Library/Frameworks;
|
||||
FRAMEWORK_VERSION = A;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../lib,
|
||||
"../../libogg-1.1.3/include",
|
||||
);
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = /Library/Frameworks;
|
||||
LIBRARY_SEARCH_PATHS = "";
|
||||
MACOSX_DEPLOYMENT_TARGET = "";
|
||||
OTHER_CFLAGS = "";
|
||||
OTHER_LDFLAGS = "";
|
||||
PRODUCT_NAME = Vorbis;
|
||||
SECTORDER_FLAGS = "";
|
||||
STRIP_STYLE = "non-global";
|
||||
WARNING_CFLAGS = (
|
||||
"-Wmost",
|
||||
"-Wno-four-char-constants",
|
||||
"-Wno-unknown-pragmas",
|
||||
);
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
name = Default;
|
||||
};
|
||||
730F23F4091827B200AB638C /* Development */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = (
|
||||
ppc,
|
||||
i386,
|
||||
);
|
||||
GCC_PREPROCESSOR_DEFINITIONS = __MACOSX__;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.4;
|
||||
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
|
||||
};
|
||||
name = Development;
|
||||
};
|
||||
730F23F5091827B200AB638C /* Deployment */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = (
|
||||
ppc,
|
||||
i386,
|
||||
);
|
||||
GCC_PREPROCESSOR_DEFINITIONS = __MACOSX__;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.4;
|
||||
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
|
||||
};
|
||||
name = Deployment;
|
||||
};
|
||||
730F23F6091827B200AB638C /* Default */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = (
|
||||
ppc,
|
||||
i386,
|
||||
);
|
||||
GCC_PREPROCESSOR_DEFINITIONS = __MACOSX__;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.4;
|
||||
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
|
||||
};
|
||||
name = Default;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
1ADE328009757FEC00961AE2 /* Build configuration list for PBXNativeTarget "LibVorbis" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1ADE328109757FEC00961AE2 /* Development */,
|
||||
1ADE328209757FEC00961AE2 /* Deployment */,
|
||||
1ADE328309757FEC00961AE2 /* Default */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Default;
|
||||
};
|
||||
730F23EC091827B100AB638C /* Build configuration list for PBXNativeTarget "Vorbis" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
730F23ED091827B100AB638C /* Development */,
|
||||
730F23EE091827B100AB638C /* Deployment */,
|
||||
730F23EF091827B100AB638C /* Default */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Default;
|
||||
};
|
||||
730F23F3091827B200AB638C /* Build configuration list for PBXProject "Vorbis" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
730F23F4091827B200AB638C /* Development */,
|
||||
730F23F5091827B200AB638C /* Deployment */,
|
||||
730F23F6091827B200AB638C /* Default */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Default;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
#define Boolean unsigned char
|
||||
#define Byte unsigned char
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
@ -1,26 +0,0 @@
|
||||
#ifndef OOLITE_LINUX
|
||||
#define OOLITE_LINUX
|
||||
/*
|
||||
*
|
||||
* oolite-linux.h: Includes, definitions and pathnames for Linux
|
||||
* systems.
|
||||
*
|
||||
* Dylan Smith, 2005-04-19
|
||||
*
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDL_opengl.h"
|
||||
#include "SDL_mixer.h"
|
||||
#include "SDL_syswm.h"
|
||||
|
||||
#define MAX_CHANNELS 16
|
||||
|
||||
// Macintosh compatibility defines
|
||||
#define kCGDisplayWidth (@"Width")
|
||||
#define kCGDisplayHeight (@"Height")
|
||||
#define kCGDisplayRefreshRate (@"RefreshRate")
|
||||
|
||||
#endif /* OOLITE_LINUX */
|
7
src/BSDCompat/bsd_string.h
Normal file
7
src/BSDCompat/bsd_string.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef BSD_STRING_H
|
||||
#define BSD_STRING_H
|
||||
#ifdef NEED_STRLCPY
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
#endif
|
||||
#endif
|
||||
|
56
src/BSDCompat/strlcpy.c
Normal file
56
src/BSDCompat/strlcpy.c
Normal file
@ -0,0 +1,56 @@
|
||||
/* $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef NEED_STRLCPY
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include "bsd_string.h" /* DJS for Oolite on Linux/win32 */
|
||||
|
||||
/*
|
||||
* Copy src to string dst of size siz. At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz == 0).
|
||||
* Returns strlen(src); if retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcpy(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
size_t n = siz;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0 && --n != 0) {
|
||||
do {
|
||||
if ((*d++ = *s++) == 0)
|
||||
break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0) {
|
||||
if (siz != 0)
|
||||
*d = '\0'; /* NUL-terminate dst */
|
||||
while (*s++)
|
||||
;
|
||||
}
|
||||
|
||||
return(s - src - 1); /* count does not include NUL */
|
||||
}
|
||||
#endif
|
||||
|
48
src/Cocoa/Groolite.h
Normal file
48
src/Cocoa/Groolite.h
Normal file
@ -0,0 +1,48 @@
|
||||
//
|
||||
// Groolite.h
|
||||
//
|
||||
// Growl integration module for Oolite
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Growl/Growl.h>
|
||||
|
||||
@class GameController;
|
||||
|
||||
|
||||
@interface Groolite: NSObject
|
||||
{
|
||||
NSConnection *connection;
|
||||
IBOutlet GameController *gameController;
|
||||
}
|
||||
|
||||
+ (NSString*) priorityDescription: (int) min_priority;
|
||||
|
||||
@end
|
282
src/Cocoa/Groolite.m
Normal file
282
src/Cocoa/Groolite.m
Normal file
@ -0,0 +1,282 @@
|
||||
//
|
||||
// Groolite.m
|
||||
// Oolite
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "Groolite.h"
|
||||
#import <Growl/Growl.h>
|
||||
#import "GameController.h"
|
||||
#import "GuiDisplayGen.h"
|
||||
#import "Universe.h"
|
||||
#import "PlayerEntity.h"
|
||||
|
||||
// #define GROOLITE_DEBUG
|
||||
#ifdef GROOLITE_DEBUG
|
||||
#define DEBUGMSG NSLog
|
||||
#else
|
||||
#define DEBUGMSG (void)
|
||||
#endif
|
||||
|
||||
|
||||
@protocol GrowlNotificationObserver
|
||||
- (oneway void) notifyWithDictionary:(bycopy NSDictionary *)dict;
|
||||
@end
|
||||
|
||||
|
||||
@protocol GrowlNotificationCenterProtocol
|
||||
|
||||
- (oneway void) addObserver:(byref id<GrowlNotificationObserver>)observer;
|
||||
- (oneway void) removeObserver:(byref id<GrowlNotificationObserver>)observer;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface Groolite (Private) <GrowlNotificationObserver>
|
||||
|
||||
- (void)connectToGrowl:unused;
|
||||
- (void)disconnectFromGrowl:unused;
|
||||
- (void)connectionDied:unused;
|
||||
- (void)displayGrowlNotificiationWithTitle:(NSString *)inTitle andMessage:(NSString *)inMessage fromApp:(NSString *) inAppname;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation Groolite
|
||||
|
||||
- (void)displayGrowlNotificiationWithTitle:(NSString *)inTitle andMessage:(NSString *)inMessage fromApp:(NSString *) inAppname
|
||||
{
|
||||
Universe *universe;
|
||||
PlayerEntity *player;
|
||||
NSString *notificationString;
|
||||
NSString *displayString;
|
||||
|
||||
universe = [gameController universe];
|
||||
player = (PlayerEntity *)[universe entityZero];
|
||||
|
||||
if (!inTitle)
|
||||
return; // catch blank messages
|
||||
|
||||
if (!inAppname)
|
||||
{
|
||||
// standard response
|
||||
notificationString = @"Growl";
|
||||
}
|
||||
else
|
||||
{
|
||||
// response if we're told which application is sending the message
|
||||
notificationString = inAppname;
|
||||
}
|
||||
|
||||
if (nil == inMessage)
|
||||
{
|
||||
// Terse mode
|
||||
displayString = [NSString stringWithFormat:@"%@: %@", notificationString, inTitle];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Standard 'verbose' mode
|
||||
displayString = [NSString stringWithFormat:@"%@: %@\n%@", notificationString, inTitle, inMessage];
|
||||
}
|
||||
|
||||
[player commsMessage: displayString];
|
||||
|
||||
if ([player speech_on])
|
||||
{
|
||||
if ([universe isSpeaking]) [universe stopSpeaking];
|
||||
[universe startSpeakingString:[NSString stringWithFormat:@"%@ message: %@", notificationString, inTitle]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (id)init
|
||||
{
|
||||
NSDistributedNotificationCenter *dnc;
|
||||
|
||||
self = [super init];
|
||||
if (nil != self)
|
||||
{
|
||||
/*
|
||||
Subscribe to GROWL_IS_READY notifications.
|
||||
This is necessary in case GrowlHelperApp currently isn't running, and in case
|
||||
it is restarted.
|
||||
*/
|
||||
dnc = [NSDistributedNotificationCenter defaultCenter];
|
||||
[dnc addObserver:self selector:@selector(connectToGrowl:) name:GROWL_IS_READY object:nil];
|
||||
|
||||
// Also, try to connect on the off chance it’s running now.
|
||||
[self connectToGrowl:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self disconnectFromGrowl:nil];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
- (void)connectToGrowl:unused
|
||||
{
|
||||
NSConnection *theConnection;
|
||||
NSNotificationCenter *nc;
|
||||
id<GrowlNotificationCenterProtocol> growlNC;
|
||||
|
||||
NS_DURING
|
||||
theConnection = [NSConnection connectionWithRegisteredName:@"GrowlNotificationCenter" host:nil];
|
||||
if (nil != theConnection)
|
||||
{
|
||||
growlNC = (id<GrowlNotificationCenterProtocol>)[theConnection rootProxy];
|
||||
[growlNC addObserver:self];
|
||||
|
||||
// Subscribe to connection-died and application-quit notifications, so we can unregister appropriately.
|
||||
nc = [NSNotificationCenter defaultCenter];
|
||||
[nc addObserver:self selector:@selector(connectionDied:) name:NSConnectionDidDieNotification object:theConnection];
|
||||
[nc addObserver:self selector:@selector(disconnectFromGrowl:) name:NSApplicationWillTerminateNotification object:nil];
|
||||
|
||||
connection = [theConnection retain];
|
||||
}
|
||||
NS_HANDLER
|
||||
// DEBUGMSG(@"DEBUG GROOLITE exception : %@ : %@", [localException name], [localException reason]);
|
||||
NS_ENDHANDLER
|
||||
}
|
||||
|
||||
|
||||
- (void)disconnectFromGrowl:unused
|
||||
{
|
||||
NSNotificationCenter *nc;
|
||||
id<GrowlNotificationCenterProtocol> growlNC;
|
||||
|
||||
if (nil != connection)
|
||||
{
|
||||
NS_DURING
|
||||
growlNC = (id<GrowlNotificationCenterProtocol>)[connection rootProxy];
|
||||
[growlNC removeObserver:self];
|
||||
[connection release];
|
||||
connection = nil;
|
||||
|
||||
nc = [NSNotificationCenter defaultCenter];
|
||||
[nc removeObserver:self];
|
||||
NS_HANDLER
|
||||
// DEBUGMSG(@"DEBUG GROOLITE exception : %@ : %@", [localException name], [localException reason]);
|
||||
NS_ENDHANDLER
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)connectionDied:unused
|
||||
{
|
||||
NSNotificationCenter *nc;
|
||||
|
||||
if (nil != connection)
|
||||
{
|
||||
NS_DURING
|
||||
[connection release];
|
||||
connection = nil;
|
||||
|
||||
nc = [NSNotificationCenter defaultCenter];
|
||||
[nc removeObserver:self];
|
||||
NS_HANDLER
|
||||
// DEBUGMSG(@"DEBUG GROOLITE exception : %@ : %@", [localException name], [localException reason]);
|
||||
NS_ENDHANDLER
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (oneway void) notifyWithDictionary:(bycopy NSDictionary *)inDict
|
||||
{
|
||||
NSUserDefaults *prefs;
|
||||
int priority;
|
||||
NSString *title;
|
||||
NSString *message;
|
||||
NSString *appname;
|
||||
|
||||
prefs = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
// Ignore if we're in a window
|
||||
#ifndef GROOLITE_DEBUG
|
||||
if (![gameController inFullScreenMode])
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Ignore if we're paused
|
||||
if ([gameController game_is_paused])
|
||||
return;
|
||||
|
||||
// Check that priority is not below our threshold
|
||||
priority = [[inDict objectForKey:GROWL_NOTIFICATION_PRIORITY] intValue];
|
||||
#ifndef GROOLITE_DEBUG
|
||||
if (priority < [prefs integerForKey:@"groolite-min-priority"])
|
||||
return;
|
||||
#endif
|
||||
|
||||
// If we get here, we need to handle the message
|
||||
title = [inDict objectForKey:GROWL_NOTIFICATION_TITLE];
|
||||
message = [inDict objectForKey:GROWL_NOTIFICATION_DESCRIPTION];
|
||||
appname = [inDict objectForKey:GROWL_APP_NAME];
|
||||
|
||||
// DEBUGMSG(@"DEBUG Groolite: inDict\n%@\n\n", inDict);
|
||||
// DEBUGMSG(@"Groolite: priority = %d appname = \"%@\" title = \"%@\", message = \"%@\"", priority, appname, title, message);
|
||||
|
||||
if (nil == title || [@"" isEqual:title])
|
||||
{
|
||||
title = message;
|
||||
message = nil;
|
||||
}
|
||||
|
||||
[self displayGrowlNotificiationWithTitle:title andMessage:message fromApp:appname];
|
||||
}
|
||||
|
||||
+ (NSString*) priorityDescription: (int) min_priority
|
||||
{
|
||||
NSString* result;
|
||||
switch (min_priority)
|
||||
{
|
||||
case -2:
|
||||
result = @"ON (for all messages)"; break;
|
||||
case -1:
|
||||
result = @"ON (for low priority messages)"; break;
|
||||
case 0:
|
||||
result = @"ON (for medium priority messages)"; break;
|
||||
case 1:
|
||||
result = @"ON (for high priority messages)"; break;
|
||||
case 2:
|
||||
result = @"ON (for highest priority messages)"; break;
|
||||
case 3:
|
||||
result = @"OFF (for all messages)"; break;
|
||||
default:
|
||||
result = @"Bad Value";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
@ -48,7 +48,7 @@
|
||||
<key>CFBundleSignature</key>
|
||||
<string>Ool8</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.60</string>
|
||||
<string>1.64</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
96
src/Cocoa/Info-OoliteDev.plist
Normal file
96
src/Cocoa/Info-OoliteDev.plist
Normal file
@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>oolite-save</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>oolite-document</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Oolite Saved Game</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>oxp</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>oolite-expansion-document</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Oolite Expansion Pack</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>OoliteDev</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>oolite-icon</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.aegidian.oolite</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>OoliteDev</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>Ool8</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.64</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>OoliteApp</string>
|
||||
<key>UTExportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.aegidian.oolite.save</string>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Oolite Saved Game</string>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
<string>public.content</string>
|
||||
</array>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>oolite-save</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.aegidian.oolite.oxp</string>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Oolite Expansion Pack</string>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
<string>com.apple.package</string>
|
||||
</array>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>oxp</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
96
src/Cocoa/Info-OoliteUB.plist
Normal file
96
src/Cocoa/Info-OoliteUB.plist
Normal file
@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>oolite-save</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>oolite-document</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Oolite Saved Game</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>oxp</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>oolite-expansion-document</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Oolite Expansion Pack</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>OoliteUB</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>oolite-icon</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.aegidian.oolite</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>OoliteUB</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>Ool8</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.64</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>OoliteApp</string>
|
||||
<key>UTExportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.aegidian.oolite.save</string>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Oolite Saved Game</string>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
<string>public.content</string>
|
||||
</array>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>oolite-save</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.aegidian.oolite.oxp</string>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Oolite Expansion Pack</string>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
<string>com.apple.package</string>
|
||||
</array>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>oxp</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
@ -15,16 +15,16 @@ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, Californi
|
||||
|
||||
You are free:
|
||||
|
||||
¥ to copy, distribute, display, and perform the work
|
||||
¥ to make derivative works
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
¥ Attribution. You must give the original author credit.
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
¥ Noncommercial. You may not use this work for commercial purposes.
|
||||
• Noncommercial. You may not use this work for commercial purposes.
|
||||
|
||||
¥ Share Alike. If you alter, transform, or build upon this work,
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
@ -34,18 +34,12 @@ Any of these conditions can be waived if you get permission from the copyright h
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
#ifdef GNUSTEP
|
||||
#import <Foundation/Foundation.h>
|
||||
#else
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
|
||||
#ifdef LINUX
|
||||
#include "oolite-linux.h"
|
||||
#else
|
||||
#import <OpenGL/OpenGL.h>
|
||||
#import <OpenGL/gl.h>
|
||||
#import <OpenGL/glext.h>
|
||||
#import "OOCocoa.h"
|
||||
#import "OOOpenGL.h"
|
||||
|
||||
#ifdef GNUSTEP
|
||||
#include <SDL/SDL.h>
|
||||
#endif
|
||||
|
||||
#define MAX_CLEAR_DEPTH 100000000.0
|
||||
@ -55,7 +49,14 @@ Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
#define MOUSE_DOUBLE_CLICK_INTERVAL 0.40
|
||||
|
||||
@class Entity, GameController, OpenGLSprite, JoystickHandler;
|
||||
@class Entity, GameController, OpenGLSprite;
|
||||
|
||||
#ifdef GNUSTEP
|
||||
@class JoystickHandler;
|
||||
#define OpenGLViewSuperClass NSObject
|
||||
#else
|
||||
#define OpenGLViewSuperClass NSOpenGLView
|
||||
#endif
|
||||
|
||||
enum GameViewKeys
|
||||
{
|
||||
@ -98,53 +99,50 @@ enum StringInput
|
||||
|
||||
extern int debug;
|
||||
|
||||
@interface MyOpenGLView : NSObject
|
||||
@interface MyOpenGLView : OpenGLViewSuperClass
|
||||
{
|
||||
GameController *gameController;
|
||||
GameController *gameController;
|
||||
#ifndef GNUSTEP
|
||||
OpenGLSprite* splashSprite;
|
||||
OpenGLSprite *splashSprite;
|
||||
#endif
|
||||
BOOL keys[NUM_KEYS];
|
||||
BOOL supressKeys; // DJS
|
||||
BOOL keys[NUM_KEYS];
|
||||
BOOL supressKeys; // DJS
|
||||
|
||||
BOOL opt, ctrl, command, shift;
|
||||
BOOL allowingStringInput;
|
||||
BOOL isAlphabetKeyDown;
|
||||
BOOL opt, ctrl, command, shift;
|
||||
BOOL allowingStringInput;
|
||||
BOOL isAlphabetKeyDown;
|
||||
|
||||
int keycodetrans[255];
|
||||
int keycodetrans[255];
|
||||
|
||||
BOOL m_glContextInitialized;
|
||||
NSPoint mouseDragStartPoint;
|
||||
double squareX,squareY;
|
||||
BOOL m_glContextInitialized;
|
||||
NSPoint mouseDragStartPoint;
|
||||
|
||||
NSTimeInterval timeIntervalAtLastClick;
|
||||
BOOL doubleClick;
|
||||
NSTimeInterval timeIntervalAtLastClick;
|
||||
BOOL doubleClick;
|
||||
|
||||
NSMutableString *typedString;
|
||||
NSRect bounds;
|
||||
NSSize viewSize;
|
||||
GLfloat display_z;
|
||||
NSMutableString *typedString;
|
||||
|
||||
NSPoint virtualJoystickPosition;
|
||||
|
||||
NSSize viewSize;
|
||||
GLfloat display_z;
|
||||
|
||||
#ifdef GNUSTEP
|
||||
double squareX,squareY;
|
||||
NSRect bounds;
|
||||
|
||||
NSPoint virtualJoystickPosition;
|
||||
|
||||
// Full screen sizes
|
||||
NSMutableArray *screenSizes;
|
||||
int currentSize;
|
||||
BOOL fullScreen;
|
||||
|
||||
// Windowed mode
|
||||
NSSize currentWindowSize;
|
||||
|
||||
NSMutableArray *screenSizes;
|
||||
int currentSize;
|
||||
BOOL fullScreen;
|
||||
|
||||
// Windowed mode
|
||||
NSSize currentWindowSize;
|
||||
SDL_Surface* surface;
|
||||
|
||||
JoystickHandler *stickHandler;
|
||||
JoystickHandler *stickHandler;
|
||||
#endif
|
||||
}
|
||||
|
||||
+ (NSMutableDictionary *) getNativeSize;
|
||||
|
||||
// override
|
||||
- (id) init;
|
||||
- (void) dealloc;
|
||||
|
||||
- (void) setStringInput: (enum StringInput) value;
|
||||
- (void) allowStringInput: (BOOL) value;
|
||||
@ -153,7 +151,6 @@ extern int debug;
|
||||
- (void) resetTypedString;
|
||||
- (void) setTypedString:(NSString*) value;
|
||||
|
||||
- (NSRect) bounds;
|
||||
- (NSSize) viewSize;
|
||||
- (GLfloat) display_z;
|
||||
|
||||
@ -163,13 +160,19 @@ extern int debug;
|
||||
- (void) initialiseGLWithSize:(NSSize) v_size;
|
||||
|
||||
- (void)drawRect:(NSRect)rect;
|
||||
- (void) display;
|
||||
|
||||
- (void) snapShot;
|
||||
|
||||
- (BOOL) inFullScreenMode;
|
||||
#ifdef GNUSTEP
|
||||
#ifndef GNUSTEP
|
||||
- (void)mouseDown:(NSEvent *)theEvent;
|
||||
- (void)mouseUp:(NSEvent *)theEvent;
|
||||
#else
|
||||
- (NSRect) bounds;
|
||||
- (void) display;
|
||||
+ (NSMutableDictionary *) getNativeSize;
|
||||
|
||||
- (void) setFullScreenMode:(BOOL)fsm;
|
||||
- (BOOL) inFullScreenMode;
|
||||
- (void) toggleScreenMode;
|
||||
- (void) setDisplayMode:(int)mode fullScreen:(BOOL)fsm;
|
||||
|
||||
@ -183,15 +186,13 @@ extern int debug;
|
||||
- (int) loadFullscreenSettings;
|
||||
- (int) findDisplayModeForWidth: (unsigned int) d_width Height:(unsigned int) d_height
|
||||
Refresh: (unsigned int)d_refresh;
|
||||
- (NSSize) currentScreenSize;
|
||||
- (NSSize) currentScreenSize;
|
||||
|
||||
- (void) pollControls: (id)sender;
|
||||
- (void) handleStringInput: (SDL_KeyboardEvent *) kbd_event; // DJS
|
||||
- (JoystickHandler *)getStickHandler; // DJS
|
||||
#endif
|
||||
|
||||
/*
|
||||
// These are standard methods in NSView.
|
||||
- (void)mouseDown:(NSEvent *)theEvent;
|
||||
- (void)mouseUp:(NSEvent *)theEvent;
|
||||
- (void)mouseDragged:(NSEvent *)theEvent;
|
||||
*/
|
||||
- (void) setVirtualJoystick:(double) vmx :(double) vmy;
|
||||
- (NSPoint) virtualJoystickPosition;
|
||||
|
||||
@ -205,8 +206,4 @@ extern int debug;
|
||||
- (BOOL) isCommandDown;
|
||||
- (BOOL) isShiftDown;
|
||||
- (int) numKeys;
|
||||
|
||||
- (void) pollControls: (id)sender;
|
||||
- (void) handleStringInput: (SDL_KeyboardEvent *) kbd_event; // DJS
|
||||
- (JoystickHandler *)getStickHandler; // DJS
|
||||
@end
|
663
src/Cocoa/MyOpenGLView.m
Normal file
663
src/Cocoa/MyOpenGLView.m
Normal file
@ -0,0 +1,663 @@
|
||||
/*
|
||||
*
|
||||
* Oolite
|
||||
*
|
||||
* Created by Giles Williams on Sat Apr 03 2004.
|
||||
* Copyright (c) 2004 for aegidian.org. All rights reserved.
|
||||
*
|
||||
|
||||
Copyright (c) 2004, Giles C Williams
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
¥ to copy, distribute, display, and perform the work
|
||||
¥ to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
¥ Attribution. You must give the original author credit.
|
||||
|
||||
¥ Noncommercial. You may not use this work for commercial purposes.
|
||||
|
||||
¥ Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "MyOpenGLView.h"
|
||||
|
||||
#import "GameController.h"
|
||||
#import "Universe.h"
|
||||
#import "TextureStore.h"
|
||||
#import "Entity.h"
|
||||
#import "PlanetEntity.h"
|
||||
#import "OpenGLSprite.h"
|
||||
#import "ResourceManager.h"
|
||||
|
||||
@interface MyOpenGLView(Internal)
|
||||
|
||||
- (int) translateKeyCode: (int) input;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation MyOpenGLView
|
||||
|
||||
- (id) initWithFrame:(NSRect)frameRect
|
||||
{
|
||||
//NSLog(@"-- initWithFrame MyOpenGLView");
|
||||
|
||||
// Pixel Format Attributes for the View-based (non-FullScreen) NSOpenGLContext
|
||||
NSOpenGLPixelFormatAttribute attrs[] = {
|
||||
|
||||
// // Specify that we want a full-screen OpenGL context.
|
||||
// NSOpenGLPFAFullScreen,
|
||||
// and that we want a windowed OpenGL context.
|
||||
NSOpenGLPFAWindow,
|
||||
|
||||
// We may be on a multi-display system (and each screen may be driven by a different renderer), so we need to specify which screen we want to take over.
|
||||
// For this demo, we'll specify the main screen.
|
||||
NSOpenGLPFAScreenMask, CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay),
|
||||
|
||||
// Specifying "NoRecovery" gives us a context that cannot fall back to the software renderer.
|
||||
//This makes the View-based context a compatible with the fullscreen context, enabling us to use the "shareContext"
|
||||
// feature to share textures, display lists, and other OpenGL objects between the two.
|
||||
NSOpenGLPFANoRecovery,
|
||||
|
||||
// Attributes Common to FullScreen and non-FullScreen
|
||||
NSOpenGLPFACompliant,
|
||||
|
||||
NSOpenGLPFAColorSize, 32,
|
||||
NSOpenGLPFADepthSize, 32,
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
NSOpenGLPFAAccelerated,
|
||||
0
|
||||
};
|
||||
long rendererID;
|
||||
|
||||
// Create our non-FullScreen pixel format.
|
||||
NSOpenGLPixelFormat* pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
|
||||
|
||||
// Just as a diagnostic, report the renderer ID that this pixel format binds to. CGLRenderers.h contains a list of known renderers
|
||||
// and their corresponding RendererID codes.
|
||||
[pixelFormat getValues:&rendererID forAttribute:NSOpenGLPFARendererID forVirtualScreen:0];
|
||||
//NSLog(@" init! NSOpenGLView pixelFormat RendererID = %08x", (unsigned)rendererID);
|
||||
|
||||
self = [super initWithFrame:frameRect pixelFormat:pixelFormat];
|
||||
|
||||
virtualJoystickPosition = NSMakePoint(0.0,0.0);
|
||||
|
||||
typedString = [[NSMutableString alloc] initWithString:@""];
|
||||
allowingStringInput = gvStringInputNo;
|
||||
isAlphabetKeyDown = NO;
|
||||
|
||||
timeIntervalAtLastClick = [NSDate timeIntervalSinceReferenceDate];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (typedString)
|
||||
[typedString release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) setStringInput: (enum StringInput) value
|
||||
{
|
||||
allowingStringInput = value;
|
||||
}
|
||||
|
||||
- (void) allowStringInput: (BOOL) value
|
||||
{
|
||||
if (value)
|
||||
allowingStringInput = gvStringInputAlpha;
|
||||
else
|
||||
allowingStringInput = gvStringInputNo;
|
||||
}
|
||||
|
||||
-(enum StringInput) allowingStringInput
|
||||
{
|
||||
return allowingStringInput;
|
||||
}
|
||||
|
||||
- (NSString *) typedString
|
||||
{
|
||||
return typedString;
|
||||
}
|
||||
|
||||
- (void) resetTypedString
|
||||
{
|
||||
[typedString setString:@""];
|
||||
}
|
||||
|
||||
- (void) setTypedString:(NSString*) value
|
||||
{
|
||||
// NSLog(@"DEBUG setTypedString:%@",value);
|
||||
[typedString setString:value];
|
||||
}
|
||||
|
||||
|
||||
- (NSSize) viewSize
|
||||
{
|
||||
return viewSize;
|
||||
}
|
||||
|
||||
- (GLfloat) display_z
|
||||
{
|
||||
return display_z;
|
||||
}
|
||||
|
||||
|
||||
- (GameController *) gameController
|
||||
{
|
||||
return gameController;
|
||||
}
|
||||
|
||||
- (void) setGameController:(GameController *) controller
|
||||
{
|
||||
gameController = controller;
|
||||
}
|
||||
|
||||
- (void)drawRect:(NSRect)rect
|
||||
{
|
||||
// AppDelegate *deleg = (AppDelegate *)[NSApp delegate];
|
||||
|
||||
if ((viewSize.width != [self frame].size.width)||(viewSize.height != [self frame].size.height)) // resized
|
||||
{
|
||||
m_glContextInitialized = NO;
|
||||
viewSize = [self frame].size;
|
||||
|
||||
//NSLog(@"DEBUG resized to %.0f x %.0f", viewSize.width, viewSize.height);
|
||||
}
|
||||
|
||||
if (!m_glContextInitialized)
|
||||
[self initialiseGLWithSize:viewSize];
|
||||
|
||||
// do all the drawing!
|
||||
//
|
||||
if ([gameController universe])
|
||||
[[gameController universe] drawFromEntity:0];
|
||||
else
|
||||
{
|
||||
// not set up yet, draw a black screen
|
||||
glClearColor( 0.0, 0.0, 0.0, 0.0);
|
||||
glClear( GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
//
|
||||
////
|
||||
|
||||
[[self openGLContext] flushBuffer];
|
||||
}
|
||||
|
||||
- (void) initialiseGLWithSize:(NSSize) v_size
|
||||
{
|
||||
GLfloat sun_ambient[] = {0.0, 0.0, 0.0, 1.0};
|
||||
GLfloat sun_diffuse[] = {1.0, 1.0, 1.0, 1.0};
|
||||
GLfloat sun_specular[] = {1.0, 1.0, 1.0, 1.0};
|
||||
GLfloat sun_center_position[] = {4000000.0, 0.0, 0.0, 1.0};
|
||||
GLfloat stars_ambient[] = {0.25, 0.2, 0.25, 1.0};
|
||||
|
||||
viewSize = v_size;
|
||||
if (viewSize.width/viewSize.height > 4.0/3.0)
|
||||
display_z = 480.0 * viewSize.width/viewSize.height;
|
||||
else
|
||||
display_z = 640.0;
|
||||
|
||||
// NSLog(@">>>>> display_z = %.1f", display_z);
|
||||
|
||||
float ratio = 0.5;
|
||||
float aspect = viewSize.height/viewSize.width;
|
||||
|
||||
glShadeModel(GL_FLAT);
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
[[self openGLContext] flushBuffer];
|
||||
|
||||
glClearDepth(MAX_CLEAR_DEPTH);
|
||||
glViewport( 0, 0, viewSize.width, viewSize.height);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity(); // reset matrix
|
||||
glFrustum( -ratio, ratio, -aspect*ratio, aspect*ratio, 1.0, MAX_CLEAR_DEPTH); // set projection matrix
|
||||
|
||||
glMatrixMode( GL_MODELVIEW);
|
||||
|
||||
glEnable( GL_DEPTH_TEST); // depth buffer
|
||||
glDepthFunc( GL_LESS); // depth buffer
|
||||
|
||||
glFrontFace( GL_CCW); // face culling - front faces are AntiClockwise!
|
||||
glCullFace( GL_BACK); // face culling
|
||||
glEnable( GL_CULL_FACE); // face culling
|
||||
|
||||
glEnable( GL_BLEND); // alpha blending
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha blending
|
||||
|
||||
if ([gameController universe])
|
||||
{
|
||||
Entity* the_sun = [[gameController universe] sun];
|
||||
Vector sun_pos = (the_sun)? the_sun->position : make_vector( 0.0f, 0.0f, 0.0f);
|
||||
sun_center_position[0] = sun_pos.x;
|
||||
sun_center_position[1] = sun_pos.y;
|
||||
sun_center_position[2] = sun_pos.z;
|
||||
[[gameController universe] setLighting];
|
||||
}
|
||||
else
|
||||
{
|
||||
glLightfv(GL_LIGHT1, GL_AMBIENT, sun_ambient);
|
||||
glLightfv(GL_LIGHT1, GL_SPECULAR, sun_specular);
|
||||
glLightfv(GL_LIGHT1, GL_DIFFUSE, sun_diffuse);
|
||||
glLightfv(GL_LIGHT1, GL_POSITION, sun_center_position);
|
||||
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, stars_ambient);
|
||||
//
|
||||
// light for demo ships display..
|
||||
GLfloat white[] = { 1.0, 1.0, 1.0, 1.0}; // white light
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, white);
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, white);
|
||||
glLightfv(GL_LIGHT0, GL_SPECULAR, white);
|
||||
}
|
||||
|
||||
glEnable(GL_LIGHT1); // lighting
|
||||
glEnable(GL_LIGHT0); // lighting
|
||||
glEnable(GL_LIGHTING); // lighting
|
||||
|
||||
// world's simplest OpenGL optimisations...
|
||||
glHint(GL_TRANSFORM_HINT_APPLE, GL_FASTEST);
|
||||
glDisable(GL_NORMALIZE);
|
||||
glDisable(GL_RESCALE_NORMAL);
|
||||
|
||||
m_glContextInitialized = YES;
|
||||
}
|
||||
|
||||
- (void) snapShot
|
||||
{
|
||||
//NSRect boundsRect = [self bounds];
|
||||
int w = viewSize.width;
|
||||
int h = viewSize.height;
|
||||
|
||||
if (w & 3)
|
||||
w = w + 4 - (w & 3);
|
||||
|
||||
long nPixels = w * h + 1;
|
||||
|
||||
unsigned char *red = (unsigned char *) malloc( nPixels);
|
||||
unsigned char *green = (unsigned char *) malloc( nPixels);
|
||||
unsigned char *blue = (unsigned char *) malloc( nPixels);
|
||||
|
||||
NSString *filepath = [[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent];
|
||||
int imageNo = 1;
|
||||
NSString *pathToPic = [filepath stringByAppendingPathComponent:[NSString stringWithFormat:@"oolite-%03d.png",imageNo]];
|
||||
|
||||
while ([[NSFileManager defaultManager] fileExistsAtPath:pathToPic])
|
||||
{
|
||||
imageNo++;
|
||||
pathToPic = [filepath stringByAppendingPathComponent:[NSString stringWithFormat:@"oolite-%03d.png",imageNo]];
|
||||
}
|
||||
|
||||
NSString *pathToPng = [[pathToPic stringByDeletingPathExtension] stringByAppendingPathExtension:@"png"];
|
||||
|
||||
NSLog(@">>>>> Snapshot %d x %d file path chosen = %@", w, h, pathToPic);
|
||||
|
||||
NSBitmapImageRep* bitmapRep =
|
||||
[[NSBitmapImageRep alloc]
|
||||
initWithBitmapDataPlanes: nil // --> let the class allocate it
|
||||
pixelsWide: w
|
||||
pixelsHigh: h
|
||||
bitsPerSample: 8 // each component is 8 bits (1 byte)
|
||||
samplesPerPixel: 3 // number of components (R, G, B)
|
||||
hasAlpha: NO // no transparency
|
||||
isPlanar: NO // data integrated into single plane
|
||||
colorSpaceName: NSDeviceRGBColorSpace
|
||||
bytesPerRow: 3*w // can no longer let the class figure it out
|
||||
bitsPerPixel: 24 // can no longer let the class figure it out
|
||||
];
|
||||
|
||||
unsigned char *pixels = [bitmapRep bitmapData];
|
||||
|
||||
glReadPixels(0,0, w,h, GL_RED, GL_UNSIGNED_BYTE, red);
|
||||
glReadPixels(0,0, w,h, GL_GREEN, GL_UNSIGNED_BYTE, green);
|
||||
glReadPixels(0,0, w,h, GL_BLUE, GL_UNSIGNED_BYTE, blue);
|
||||
|
||||
int x,y;
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
long index = (h - y - 1)*w;
|
||||
for (x = 0; x < w; x++) // set bitmap pixels
|
||||
{
|
||||
*pixels++ = red[index];
|
||||
*pixels++ = green[index];
|
||||
*pixels++ = blue[index++];
|
||||
}
|
||||
}
|
||||
|
||||
[[bitmapRep representationUsingType:NSPNGFileType properties:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSImageInterlaced, NULL]]
|
||||
writeToFile:pathToPng atomically:YES]; // save PNG representation of Image
|
||||
|
||||
// free allocated objects and memory
|
||||
[bitmapRep release];
|
||||
free(red);
|
||||
free(green);
|
||||
free(blue);
|
||||
|
||||
}
|
||||
|
||||
- (BOOL) acceptsFirstResponder
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (void) keyUp:(NSEvent *)theEvent
|
||||
{
|
||||
int key = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
|
||||
int keycode = [theEvent keyCode] & 255;
|
||||
supressKeys=NO;
|
||||
|
||||
// NSLog(@"DEBUG keyUp [theEvent charactersIgnoringModifiers] = %@ keyCode = %d",[theEvent charactersIgnoringModifiers],[theEvent keyCode]);
|
||||
|
||||
key = keycodetrans[keycode]; // retrieve the character we got for pressing the hardware at key location 'keycode'
|
||||
|
||||
isAlphabetKeyDown = NO;
|
||||
if ((key >= 0)&&(key < [self numKeys])&&(keys[key]))
|
||||
{
|
||||
keys[key] = NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (key > [self numKeys])
|
||||
NSLog(@"***** translated key: %d out of range\n", key);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) keyDown:(NSEvent *)theEvent
|
||||
{
|
||||
int key = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
|
||||
int keycode = [theEvent keyCode] & 255;
|
||||
|
||||
// NSLog(@"DEBUG keyDown [theEvent charactersIgnoringModifiers] = %@ keyCode = %d",[theEvent charactersIgnoringModifiers],[theEvent keyCode]);
|
||||
|
||||
key = [self translateKeyCode: key];
|
||||
|
||||
keycodetrans[keycode] = key; // record the chracter we got for pressing the hardware at key location 'keycode'
|
||||
|
||||
if ((key >= 0)&&(key < [self numKeys])&&(!keys[key]))
|
||||
{
|
||||
//NSLog( @"key : %d", key );
|
||||
keys[key] = YES;
|
||||
|
||||
if (allowingStringInput)
|
||||
{
|
||||
// limited input for planet find screen
|
||||
if (allowingStringInput == gvStringInputAlpha)
|
||||
{
|
||||
if (((key > 64)&&(key < 91))||((key > 96)&&(key < 123)))
|
||||
{
|
||||
// alphanumeric
|
||||
isAlphabetKeyDown = YES;
|
||||
// convert to lowercase
|
||||
[typedString appendFormat:@"%c", (key | 64)];
|
||||
//NSLog(@"accumulated string '%@'",typedString);
|
||||
}
|
||||
else
|
||||
isAlphabetKeyDown = NO;
|
||||
if (key == NSDeleteCharacter)
|
||||
{
|
||||
//delete
|
||||
[typedString setString:@""];
|
||||
}
|
||||
}
|
||||
|
||||
// full input for load-save screen
|
||||
if (allowingStringInput == gvStringInputAll)
|
||||
{
|
||||
if ((key > 31)&&(key < 123))
|
||||
{
|
||||
// alphanumeric
|
||||
isAlphabetKeyDown = YES;
|
||||
// convert to lowercase
|
||||
[typedString appendFormat:@"%c", key];
|
||||
//NSLog(@"accumulated string '%@'",typedString);
|
||||
}
|
||||
else
|
||||
isAlphabetKeyDown = NO;
|
||||
if ((key == NSDeleteCharacter) && [typedString length])
|
||||
{
|
||||
//delete
|
||||
[typedString deleteCharactersInRange:NSMakeRange([typedString length] - 1, 1)];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (key > [self numKeys])
|
||||
NSLog(@"***** translated key: %d out of range\n", key);
|
||||
}
|
||||
}
|
||||
|
||||
/* Capture shift, ctrl, opt and command press & release */
|
||||
- (void)flagsChanged:(NSEvent *)theEvent
|
||||
{
|
||||
int flags = [theEvent modifierFlags];
|
||||
opt = (flags & NSAlternateKeyMask) ? YES : NO;
|
||||
ctrl = (flags & NSControlKeyMask) ? YES : NO;
|
||||
command = (flags & NSCommandKeyMask) ? YES : NO;
|
||||
shift = ( flags & NSShiftKeyMask ) ? YES : NO;
|
||||
|
||||
}
|
||||
|
||||
- (void)mouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
if (doubleClick)
|
||||
{
|
||||
doubleClick = NO;
|
||||
keys[gvMouseDoubleClick] = NO;
|
||||
}
|
||||
keys[gvMouseLeftButton] = YES; // 'a' down
|
||||
}
|
||||
|
||||
- (void)mouseUp:(NSEvent *)theEvent
|
||||
{
|
||||
NSTimeInterval timeBetweenClicks = [NSDate timeIntervalSinceReferenceDate] - timeIntervalAtLastClick;
|
||||
timeIntervalAtLastClick += timeBetweenClicks;
|
||||
|
||||
if (!doubleClick)
|
||||
{
|
||||
doubleClick = (timeBetweenClicks < MOUSE_DOUBLE_CLICK_INTERVAL); // One fifth of a second
|
||||
keys[gvMouseDoubleClick] = doubleClick;
|
||||
// if (doubleClick)
|
||||
// NSLog(@"DEBUG registering a double-click!");
|
||||
}
|
||||
|
||||
keys[gvMouseLeftButton] = NO; // 'a' up
|
||||
}
|
||||
|
||||
|
||||
- (void)mouseMoved:(NSEvent *)theEvent
|
||||
{
|
||||
double mx = [theEvent locationInWindow].x - viewSize.width/2.0;
|
||||
double my = [theEvent locationInWindow].y - viewSize.height/2.0;
|
||||
|
||||
if (display_z > 640.0)
|
||||
{
|
||||
mx /= viewSize.width * MAIN_GUI_PIXEL_WIDTH / display_z;
|
||||
my /= viewSize.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
mx /= MAIN_GUI_PIXEL_WIDTH * viewSize.width / 640.0;
|
||||
my /= MAIN_GUI_PIXEL_HEIGHT * viewSize.width / 640.0;
|
||||
}
|
||||
|
||||
[self setVirtualJoystick:mx :-my];
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
/* Turn the Cocoa ArrowKeys into our arrow key constants. */
|
||||
- (int) translateKeyCode: (int) input
|
||||
{
|
||||
int key = input;
|
||||
switch ( input )
|
||||
{
|
||||
case NSUpArrowFunctionKey:
|
||||
key = gvArrowKeyUp;
|
||||
break;
|
||||
|
||||
case NSDownArrowFunctionKey:
|
||||
key = gvArrowKeyDown;
|
||||
break;
|
||||
|
||||
case NSLeftArrowFunctionKey:
|
||||
key = gvArrowKeyLeft;
|
||||
break;
|
||||
|
||||
case NSRightArrowFunctionKey:
|
||||
key = gvArrowKeyRight;
|
||||
break;
|
||||
|
||||
case NSF1FunctionKey:
|
||||
key = gvFunctionKey1;
|
||||
break;
|
||||
|
||||
case NSF2FunctionKey:
|
||||
key = gvFunctionKey2;
|
||||
break;
|
||||
|
||||
case NSF3FunctionKey:
|
||||
key = gvFunctionKey3;
|
||||
break;
|
||||
|
||||
case NSF4FunctionKey:
|
||||
key = gvFunctionKey4;
|
||||
break;
|
||||
|
||||
case NSF5FunctionKey:
|
||||
key = gvFunctionKey5;
|
||||
break;
|
||||
|
||||
case NSF6FunctionKey:
|
||||
key = gvFunctionKey6;
|
||||
break;
|
||||
|
||||
case NSF7FunctionKey:
|
||||
key = gvFunctionKey7;
|
||||
break;
|
||||
|
||||
case NSF8FunctionKey:
|
||||
key = gvFunctionKey8;
|
||||
break;
|
||||
|
||||
case NSF9FunctionKey:
|
||||
key = gvFunctionKey9;
|
||||
break;
|
||||
|
||||
case NSF10FunctionKey:
|
||||
key = gvFunctionKey10;
|
||||
break;
|
||||
|
||||
case NSF11FunctionKey:
|
||||
key = gvFunctionKey11;
|
||||
break;
|
||||
|
||||
case NSHomeFunctionKey:
|
||||
key = gvHomeKey;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
- (void) setVirtualJoystick:(double) vmx :(double) vmy
|
||||
{
|
||||
virtualJoystickPosition.x = vmx;
|
||||
virtualJoystickPosition.y = vmy;
|
||||
}
|
||||
|
||||
- (NSPoint) virtualJoystickPosition
|
||||
{
|
||||
return virtualJoystickPosition;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
- (void) clearKeys
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < [self numKeys]; i++)
|
||||
keys[i] = NO;
|
||||
}
|
||||
|
||||
- (void) clearMouse
|
||||
{
|
||||
keys[gvMouseDoubleClick] = NO;
|
||||
keys[gvMouseLeftButton] = NO;
|
||||
doubleClick = NO;
|
||||
}
|
||||
|
||||
- (BOOL) isAlphabetKeyDown
|
||||
{
|
||||
return isAlphabetKeyDown = NO;;
|
||||
}
|
||||
|
||||
// DJS: When entering submenus in the gui, it is not helpful if the
|
||||
// key down that brought you into the submenu is still registered
|
||||
// as down when we're in. This makes isDown return NO until a key up
|
||||
// event has been received from SDL.
|
||||
- (void) supressKeysUntilKeyUp
|
||||
{
|
||||
supressKeys = YES;
|
||||
[self clearKeys];
|
||||
}
|
||||
|
||||
- (BOOL) isDown: (int) key
|
||||
{
|
||||
if( supressKeys )
|
||||
return NO;
|
||||
if ( key < 0 )
|
||||
return NO;
|
||||
if ( key >= [self numKeys] )
|
||||
return NO;
|
||||
return keys[key];
|
||||
}
|
||||
|
||||
- (BOOL) isOptDown
|
||||
{
|
||||
return opt;
|
||||
}
|
||||
|
||||
- (BOOL) isCtrlDown
|
||||
{
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
- (BOOL) isCommandDown
|
||||
{
|
||||
return command;
|
||||
}
|
||||
|
||||
- (BOOL) isShiftDown
|
||||
{
|
||||
return shift;
|
||||
}
|
||||
|
||||
- (int) numKeys
|
||||
{
|
||||
return NUM_KEYS;
|
||||
}
|
||||
|
||||
@end
|
48
src/Cocoa/OOCABufferedSound.h
Normal file
48
src/Cocoa/OOCABufferedSound.h
Normal file
@ -0,0 +1,48 @@
|
||||
//
|
||||
// OOCABufferedSound.h
|
||||
// CoreAudio sound implementation for Oolite
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "OOCASound.h"
|
||||
|
||||
|
||||
@interface OOCABufferedSound: OOSound
|
||||
{
|
||||
float *_buffer;
|
||||
size_t _size;
|
||||
Float64 _sampleRate;
|
||||
NSString *_name;
|
||||
}
|
||||
|
||||
- (BOOL)bufferSound:(NSString *)inPath;
|
||||
|
||||
@end
|
177
src/Cocoa/OOCABufferedSound.m
Normal file
177
src/Cocoa/OOCABufferedSound.m
Normal file
@ -0,0 +1,177 @@
|
||||
//
|
||||
// OOCABufferedSound.m
|
||||
// CoreAudio sound implementation for Oolite
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOCASoundInternal.h"
|
||||
|
||||
|
||||
@implementation OOCABufferedSound
|
||||
|
||||
|
||||
- (id)initWithContentsOfFile:(NSString *)inPath
|
||||
{
|
||||
BOOL OK = YES;
|
||||
|
||||
if (!gOOSoundSetUp) [OOSound setUp];
|
||||
if (gOOSoundBroken) OK = NO;
|
||||
|
||||
if (OK)
|
||||
{
|
||||
self = [super init];
|
||||
if (nil != self)
|
||||
{
|
||||
if (![self bufferSound:inPath]) OK = NO;
|
||||
}
|
||||
}
|
||||
|
||||
if (!OK)
|
||||
{
|
||||
[self release];
|
||||
self = nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)bufferSound:(NSString *)inPath
|
||||
{
|
||||
OOCASoundDecoder *decoder;
|
||||
BOOL OK = YES;
|
||||
|
||||
decoder = [[OOCASoundDecoder alloc] initWithPath:inPath];
|
||||
if (nil == decoder) OK = NO;
|
||||
else
|
||||
{
|
||||
_name = [[decoder name] retain];
|
||||
_sampleRate = [decoder sampleRate];
|
||||
OK = [decoder readMonoCreatingBuffer:&_buffer withFrameCount:&_size];
|
||||
}
|
||||
|
||||
[decoder release];
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (_buffer) free(_buffer);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
- (NSString *)name
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
|
||||
- (void)play
|
||||
{
|
||||
[[OOCASoundMixer mixer] playSound:self];
|
||||
/*
|
||||
OOSoundSource *source = [[OOSoundSource alloc] init];
|
||||
[source playSound:self];
|
||||
[source release];
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)getAudioStreamBasicDescription:(AudioStreamBasicDescription *)outFormat
|
||||
{
|
||||
assert(NULL != outFormat);
|
||||
|
||||
outFormat->mSampleRate = _sampleRate;
|
||||
outFormat->mFormatID = kAudioFormatLinearPCM;
|
||||
outFormat->mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved;
|
||||
outFormat->mBytesPerPacket = sizeof (float);
|
||||
outFormat->mFramesPerPacket = 1;
|
||||
outFormat->mBytesPerFrame = sizeof (float);
|
||||
outFormat->mChannelsPerFrame = 2;
|
||||
outFormat->mBitsPerChannel = sizeof (float) * 8;
|
||||
outFormat->mReserved = 0;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (OSStatus)renderWithFlags:(AudioUnitRenderActionFlags *)ioFlags frames:(UInt32)inNumFrames context:(OOCASoundRenderContext *)ioContext data:(AudioBufferList *)ioData
|
||||
{
|
||||
size_t toCopy, remaining, underflow, offset;
|
||||
unsigned i, count;
|
||||
|
||||
offset = *ioContext;
|
||||
count = ioData->mNumberBuffers;
|
||||
|
||||
if (offset < _size)
|
||||
{
|
||||
remaining = _size - offset;
|
||||
if (remaining < inNumFrames)
|
||||
{
|
||||
toCopy = remaining;
|
||||
underflow = inNumFrames - remaining;
|
||||
}
|
||||
else
|
||||
{
|
||||
toCopy = inNumFrames;
|
||||
underflow = 0;
|
||||
}
|
||||
|
||||
*ioContext += toCopy;
|
||||
|
||||
toCopy *= sizeof (float);
|
||||
|
||||
for (i = 0; i != count; ++i)
|
||||
{
|
||||
bcopy(_buffer + offset, ioData->mBuffers[i].mData, toCopy);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
toCopy = 0;
|
||||
underflow = inNumFrames;
|
||||
*ioFlags |= kAudioUnitRenderAction_OutputIsSilence;
|
||||
}
|
||||
|
||||
if (underflow)
|
||||
{
|
||||
underflow *= sizeof (float);
|
||||
for (i = 0; i != count; ++i)
|
||||
{
|
||||
bzero(ioData->mBuffers[i].mData + toCopy, underflow);
|
||||
}
|
||||
}
|
||||
|
||||
return underflow ? endOfDataReached : noErr;
|
||||
}
|
||||
|
||||
@end
|
53
src/Cocoa/OOCAMusic.h
Normal file
53
src/Cocoa/OOCAMusic.h
Normal file
@ -0,0 +1,53 @@
|
||||
//
|
||||
// OOCAMusic.h
|
||||
// CoreAudio sound implementation for Oolite
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "OOSound.h"
|
||||
|
||||
@class OOCASoundDecoder;
|
||||
@class VirtualRingBuffer;
|
||||
|
||||
|
||||
@interface OOMusic: OOSound
|
||||
{
|
||||
OOCASoundDecoder *_decoder;
|
||||
VirtualRingBuffer *_bufferL, *_bufferR;
|
||||
BOOL _loop, _atEnd;
|
||||
}
|
||||
|
||||
- (id) initWithContentsOfFile:(NSString *)path;
|
||||
|
||||
- (void) setLoop:(BOOL)inLoop;
|
||||
- (BOOL) loop;
|
||||
|
||||
@end
|
328
src/Cocoa/OOCAMusic.m
Normal file
328
src/Cocoa/OOCAMusic.m
Normal file
@ -0,0 +1,328 @@
|
||||
//
|
||||
// OOCAMusic.m
|
||||
// CoreAudio sound implementation for Oolite
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOCASoundInternal.h"
|
||||
#import "VirtualRingBuffer.h"
|
||||
|
||||
static BOOL sFeederThreadActive = NO;
|
||||
static NSMachPort *sFeederPort = NULL;
|
||||
|
||||
|
||||
@interface OOMusic (Internal)
|
||||
|
||||
+ (void)feederThread:ignored;
|
||||
- (BOOL)setUpAudioUnit;
|
||||
- (void)fillBuffers;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
// Port messages
|
||||
kMsgFillBuffers = 1UL
|
||||
};
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
kStreamBufferCount = 100000, // Number of frames in buffer
|
||||
kStreamBufferRefillThreshold = kStreamBufferCount / 3, // When to request refill
|
||||
kStreamBufferSize = kStreamBufferCount * sizeof (float)
|
||||
};
|
||||
|
||||
|
||||
@implementation OOMusic
|
||||
|
||||
- (id)initWithContentsOfFile:(NSString *)inPath
|
||||
{
|
||||
BOOL OK = YES;
|
||||
|
||||
if (!gOOSoundSetUp) [OOSound setUp];
|
||||
if (gOOSoundBroken) OK = NO;
|
||||
|
||||
if (OK)
|
||||
{
|
||||
self = [super init];
|
||||
if (nil != self)
|
||||
{
|
||||
_decoder = [[OOCASoundDecoder codecWithPath:inPath] retain];
|
||||
if (nil == _decoder) OK = NO;
|
||||
}
|
||||
}
|
||||
|
||||
if (!OK)
|
||||
{
|
||||
[self release];
|
||||
self = nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if ([self isPlaying]) [self stop];
|
||||
[_decoder release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)play
|
||||
{
|
||||
[[OOCASoundMixer mixer] playMusic:self];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)stop
|
||||
{
|
||||
[[OOCASoundMixer mixer] stopMusic:self];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isPaused
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isPlaying
|
||||
{
|
||||
return [[OOCASoundMixer mixer] currentMusic] == self;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)pause
|
||||
{
|
||||
NSLog(@"[OOMusic pause] called but ignored - please report.");
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)resume
|
||||
{
|
||||
NSLog(@"[OOMusic resume] called but ignored - please report.");
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)prepareToPlayWithContext:(OOCASoundRenderContext *)outContext
|
||||
{
|
||||
BOOL OK = YES;
|
||||
|
||||
if (OK)
|
||||
{
|
||||
if (!_bufferL) _bufferL = [[VirtualRingBuffer alloc] initWithLength:kStreamBufferSize];
|
||||
if (!_bufferR) _bufferR = [[VirtualRingBuffer alloc] initWithLength:kStreamBufferSize];
|
||||
if (!_bufferL || !_bufferR)
|
||||
{
|
||||
NSLog(@"DEBUG OOMUSIC: failed to create ring buffers.");
|
||||
OK = NO;
|
||||
}
|
||||
}
|
||||
|
||||
if (OK && !sFeederThreadActive) [NSThread detachNewThreadSelector:@selector(feederThread:) toTarget:[OOMusic class] withObject:nil];
|
||||
|
||||
[self fillBuffers];
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
- (void)finishStoppingWithContext:(OOCASoundRenderContext *)outContext
|
||||
{
|
||||
[_bufferL release];
|
||||
_bufferL = nil;
|
||||
[_bufferR release];
|
||||
_bufferR = nil;
|
||||
[_decoder rewindToBeginning];
|
||||
}
|
||||
|
||||
|
||||
+ (void)feederThread:ignored
|
||||
{
|
||||
NSRunLoop *runLoop;
|
||||
|
||||
sFeederPort = [[NSMachPort alloc] init];
|
||||
if (nil == sFeederPort) return;
|
||||
|
||||
sFeederThreadActive = YES;
|
||||
|
||||
[sFeederPort setDelegate:[self class]];
|
||||
runLoop = [NSRunLoop currentRunLoop];
|
||||
[runLoop addPort:sFeederPort forMode:NSDefaultRunLoopMode];
|
||||
[[NSRunLoop currentRunLoop] run];
|
||||
}
|
||||
|
||||
|
||||
+ (void)handlePortMessage:(NSPortMessage *)inMessage
|
||||
{
|
||||
NSData *data;
|
||||
OOMusic *music;
|
||||
|
||||
switch ([inMessage msgid])
|
||||
{
|
||||
case kMsgFillBuffers:
|
||||
data = [[inMessage components] objectAtIndex:0];
|
||||
if ([data length] == sizeof music)
|
||||
{
|
||||
music = *(OOMusic **)[data bytes];
|
||||
[music fillBuffers];
|
||||
[music release];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)fillBuffers
|
||||
{
|
||||
size_t spaceL, spaceR;
|
||||
void *ptrL, *ptrR;
|
||||
|
||||
[gOOCASoundSyncLock lock];
|
||||
spaceL = [_bufferL lengthAvailableToWriteReturningPointer:&ptrL];
|
||||
spaceR = [_bufferR lengthAvailableToWriteReturningPointer:&ptrR];
|
||||
|
||||
if (spaceR < spaceL) spaceL = spaceR;
|
||||
spaceL /= sizeof (float);
|
||||
|
||||
if (0 != spaceL)
|
||||
{
|
||||
spaceL = [_decoder readStereoToBufferL:(float *)ptrL bufferR:(float *)ptrR maxFrames:(size_t)spaceL];
|
||||
[_bufferL didWriteLength:spaceL * sizeof (float)];
|
||||
[_bufferR didWriteLength:spaceL * sizeof (float)];
|
||||
|
||||
if ([_decoder atEnd])
|
||||
{
|
||||
if (_loop) [_decoder rewindToBeginning];
|
||||
else _atEnd = YES;
|
||||
}
|
||||
}
|
||||
[gOOCASoundSyncLock unlock];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)getAudioStreamBasicDescription:(AudioStreamBasicDescription *)outFormat
|
||||
{
|
||||
assert(NULL != outFormat);
|
||||
|
||||
outFormat->mSampleRate = [_decoder sampleRate];
|
||||
outFormat->mFormatID = kAudioFormatLinearPCM;
|
||||
outFormat->mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved;
|
||||
outFormat->mBytesPerPacket = sizeof (float);
|
||||
outFormat->mFramesPerPacket = 1;
|
||||
outFormat->mBytesPerFrame = sizeof (float);
|
||||
outFormat->mChannelsPerFrame = 2;
|
||||
outFormat->mBitsPerChannel = sizeof (float) * 8;
|
||||
outFormat->mReserved = 0;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (OSStatus)renderWithFlags:(AudioUnitRenderActionFlags *)ioFlags frames:(UInt32)inNumFrames context:(OOCASoundRenderContext *)ioContext data:(AudioBufferList *)ioData
|
||||
{
|
||||
size_t availL, availR, remaining, underflow;
|
||||
size_t numBytes;
|
||||
void *ptrL, *ptrR;
|
||||
|
||||
assert(2 == ioData->mNumberBuffers);
|
||||
|
||||
availL = [_bufferL lengthAvailableToReadReturningPointer:&ptrL];
|
||||
availR = [_bufferR lengthAvailableToReadReturningPointer:&ptrR];
|
||||
|
||||
numBytes = inNumFrames * sizeof (float);
|
||||
|
||||
if (availR < availL) availL = availR;
|
||||
remaining = availL;
|
||||
if (numBytes < availL) availL = numBytes;
|
||||
|
||||
bcopy(ptrL, ioData->mBuffers[0].mData, availL);
|
||||
bcopy(ptrR, ioData->mBuffers[1].mData, availL);
|
||||
|
||||
[_bufferL didReadLength:availL];
|
||||
[_bufferR didReadLength:availL];
|
||||
|
||||
if (availL < numBytes)
|
||||
{
|
||||
// Buffer underflow! Fill with silence.
|
||||
underflow = numBytes - availL;
|
||||
|
||||
if (0 == availL) *ioFlags |= kAudioUnitRenderAction_OutputIsSilence;
|
||||
|
||||
bzero(ioData->mBuffers[0].mData + availL, underflow);
|
||||
bzero(ioData->mBuffers[0].mData + availL, underflow);
|
||||
if (_atEnd && !_loop) [self stop];
|
||||
}
|
||||
|
||||
remaining -= availL;
|
||||
if (!_atEnd && remaining < kStreamBufferRefillThreshold * sizeof (float) && nil != sFeederPort)
|
||||
{
|
||||
// Queue self for refilling
|
||||
// Supposedly this is more efficient than, say, MPQueues. Huh?
|
||||
NSAutoreleasePool *pool;
|
||||
NSPortMessage *msg;
|
||||
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
[self retain];
|
||||
msg = [[NSPortMessage alloc] initWithSendPort:sFeederPort receivePort:nil components:[NSArray arrayWithObject:[NSData dataWithBytes:&self length: sizeof self]]];
|
||||
[msg setMsgid:kMsgFillBuffers];
|
||||
[msg sendBeforeDate:[NSDate date]];
|
||||
[pool release];
|
||||
}
|
||||
|
||||
return _atEnd ? endOfDataReached : noErr;
|
||||
}
|
||||
|
||||
|
||||
- (void)setLoop:(BOOL)inLoop
|
||||
{
|
||||
_loop = !!inLoop;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)loop
|
||||
{
|
||||
return _loop;
|
||||
}
|
||||
|
||||
|
||||
- (NSString *)name
|
||||
{
|
||||
return [_decoder name];
|
||||
}
|
||||
|
||||
@end
|
58
src/Cocoa/OOCASound.h
Normal file
58
src/Cocoa/OOCASound.h
Normal file
@ -0,0 +1,58 @@
|
||||
//
|
||||
// OOCASound.h
|
||||
// CoreAudio sound implementation for Oolite
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
¥ to copy, distribute, display, and perform the work
|
||||
¥ to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
¥ Attribution. You must give the original author credit.
|
||||
|
||||
¥ Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#ifndef HAVE_SOUND
|
||||
#define HAVE_SOUND
|
||||
#endif
|
||||
|
||||
|
||||
@interface OOSound: NSObject
|
||||
|
||||
+ (void) setUp;
|
||||
+ (void) tearDown;
|
||||
+ (void) update;
|
||||
|
||||
+ (void) setMasterVolume:(float) fraction;
|
||||
+ (float) masterVolume;
|
||||
|
||||
- (id) initWithContentsOfFile:(NSString *)path;
|
||||
|
||||
- (BOOL) isPlaying;
|
||||
- (BOOL) play;
|
||||
- (BOOL) stop;
|
||||
|
||||
- (NSString *)name;
|
||||
|
||||
@end
|
205
src/Cocoa/OOCASound.m
Normal file
205
src/Cocoa/OOCASound.m
Normal file
@ -0,0 +1,205 @@
|
||||
//
|
||||
// OOCASound.m
|
||||
// CoreAudio sound implementation for Oolite
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOCASoundInternal.h"
|
||||
#import <CoreAudio/CoreAudio.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
#define KEY_VOLUME_CONTROL @"volume_control"
|
||||
|
||||
|
||||
static float sNominalVolume = 1.0f;
|
||||
BOOL gOOSoundSetUp = NO;
|
||||
BOOL gOOSoundBroken = NO;
|
||||
NSLock *gOOCASoundSyncLock = NULL; // Used to ensure thread-safety of play and stop, specifically because stop may be called from the CoreAudio thread.
|
||||
|
||||
|
||||
@implementation OOSound
|
||||
|
||||
+ (void) setUp
|
||||
{
|
||||
if (!gOOSoundSetUp)
|
||||
{
|
||||
gOOCASoundSyncLock = [[NSRecursiveLock alloc] init];
|
||||
if (nil == gOOCASoundSyncLock)
|
||||
{
|
||||
NSLog(@"Failed to set up sound (lock allocation failed). No sound will be played.");
|
||||
gOOSoundBroken = YES;
|
||||
}
|
||||
if (!gOOSoundBroken)
|
||||
{
|
||||
if (![OOCASoundChannel setUp])
|
||||
gOOSoundBroken = YES;
|
||||
}
|
||||
|
||||
gOOSoundSetUp = YES;
|
||||
|
||||
if ([[NSUserDefaults standardUserDefaults] objectForKey:KEY_VOLUME_CONTROL])
|
||||
sNominalVolume = [[NSUserDefaults standardUserDefaults] floatForKey:KEY_VOLUME_CONTROL];
|
||||
else
|
||||
sNominalVolume = 0.75; // default setting at 75% system volume
|
||||
[[OOCASoundMixer mixer] setMasterVolume:sNominalVolume];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+ (void) tearDown
|
||||
{
|
||||
if (gOOSoundSetUp)
|
||||
{
|
||||
[gOOCASoundSyncLock release];
|
||||
gOOCASoundSyncLock = nil;
|
||||
[OOCASoundMixer destroy];
|
||||
}
|
||||
[OOCASoundChannel tearDown];
|
||||
gOOSoundSetUp = NO;
|
||||
gOOSoundBroken = NO;
|
||||
}
|
||||
|
||||
|
||||
+ (void) update
|
||||
{
|
||||
[[OOCASoundMixer mixer] update];
|
||||
}
|
||||
|
||||
|
||||
+ (void) setMasterVolume:(float)fraction
|
||||
{
|
||||
if (fraction != sNominalVolume)
|
||||
{
|
||||
[[OOCASoundMixer mixer] setMasterVolume:fraction];
|
||||
|
||||
sNominalVolume = fraction;
|
||||
[[NSUserDefaults standardUserDefaults] setFloat:fraction forKey:KEY_VOLUME_CONTROL];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+ (float) masterVolume
|
||||
{
|
||||
return sNominalVolume;
|
||||
}
|
||||
|
||||
|
||||
- (id) initWithContentsOfFile:(NSString *)inPath
|
||||
{
|
||||
[self release];
|
||||
return [[OOCABufferedSound alloc] initWithContentsOfFile:inPath];
|
||||
}
|
||||
|
||||
|
||||
- (OSStatus)renderWithFlags:(AudioUnitRenderActionFlags *)ioFlags frames:(UInt32)inNumFrames context:(OOCASoundRenderContext *)ioContext data:(AudioBufferList *)ioData
|
||||
{
|
||||
NSLog(@"%s shouldn't be called - subclass responsibility.", __PRETTY_FUNCTION__);
|
||||
return unimpErr;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) isPlaying
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) isPaused
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) play
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)stop
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)pause
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)resume
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)prepareToPlayWithContext:(OOCASoundRenderContext *)outContext
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (void)finishStoppingWithContext:(OOCASoundRenderContext)inContext
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)doPlay
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)doStop
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"<%@ %p>{\"%@\"}", [self className], self, [self name]];
|
||||
}
|
||||
|
||||
|
||||
- (NSString *)name
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)getAudioStreamBasicDescription:(AudioStreamBasicDescription *)outFormat
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
88
src/Cocoa/OOCASoundChannel.h
Normal file
88
src/Cocoa/OOCASoundChannel.h
Normal file
@ -0,0 +1,88 @@
|
||||
//
|
||||
// OOCASoundChannel.h
|
||||
// CoreAudio sound implementation for Oolite
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
@class OOSound;
|
||||
|
||||
|
||||
typedef uintptr_t OOCASoundRenderContext;
|
||||
typedef OSStatus (*OOCASoundChannel_RenderIMP)(id inSelf, SEL inSelector, AudioUnitRenderActionFlags *ioFlags, UInt32 inNumFrames, OOCASoundRenderContext *ioContext, AudioBufferList *ioData);
|
||||
|
||||
|
||||
@interface OOCASoundChannel: NSObject
|
||||
{
|
||||
OOCASoundChannel *_next;
|
||||
id _delegate;
|
||||
AUNode _subGraphNode;
|
||||
AUGraph _subGraph;
|
||||
AUNode _node;
|
||||
AudioUnit _au;
|
||||
OOSound *_sound;
|
||||
OOCASoundRenderContext _context;
|
||||
OOCASoundChannel_RenderIMP Render;
|
||||
uint8_t _state,
|
||||
_id,
|
||||
_stopReq;
|
||||
}
|
||||
|
||||
+ (BOOL)setUp;
|
||||
+ (void)tearDown;
|
||||
|
||||
- (id)initWithID:(uint32_t)inID auGraph:(AUGraph)inGraph;
|
||||
|
||||
- (void)setDelegate:(id)inDelegate;
|
||||
|
||||
- (uint32_t)ID;
|
||||
|
||||
- (AUNode)auSubGraphNode;
|
||||
|
||||
// Unretained pointer used to maintain simple stack
|
||||
- (OOCASoundChannel *)next;
|
||||
- (void)setNext:(OOCASoundChannel *)inNext;
|
||||
|
||||
- (BOOL)playSound:(OOSound *)inSound;
|
||||
- (void)stop;
|
||||
|
||||
- (OOSound *)sound;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface NSObject(OOCASoundChannelDelegate)
|
||||
|
||||
// Note: this will be called in a separate thread.
|
||||
- (void)channel:(OOCASoundChannel *)inChannel didFinishPlayingSound:(OOSound *)inSound;
|
||||
|
||||
@end
|
592
src/Cocoa/OOCASoundChannel.m
Normal file
592
src/Cocoa/OOCASoundChannel.m
Normal file
@ -0,0 +1,592 @@
|
||||
//
|
||||
// OOCASoundChannel.m
|
||||
// CoreAudio sound implementation for Oolite
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOCASoundChannel.h"
|
||||
#import "OOCASoundInternal.h"
|
||||
#import <mach/mach.h>
|
||||
|
||||
|
||||
static mach_port_t sReapPort = MACH_PORT_NULL;
|
||||
static mach_port_t sStatusPort = MACH_PORT_NULL;
|
||||
static BOOL sReaperRunning = NO;
|
||||
static OOCASoundChannel_RenderIMP SoundChannelRender = NULL;
|
||||
|
||||
static SInt32 sDebugUnexpectedNullCount = 0;
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
kState_Stopped,
|
||||
kState_Playing,
|
||||
kState_Ended
|
||||
};
|
||||
|
||||
|
||||
#define kAURenderSelector @selector(renderWithFlags:frames:context:data:)
|
||||
|
||||
|
||||
@interface OOCASoundChannel(Private)
|
||||
|
||||
+ (void)reaperThread:junk;
|
||||
- (void)cleanUp;
|
||||
|
||||
- (OSStatus)renderWithFlags:(AudioUnitRenderActionFlags *)ioFlags frames:(UInt32)inNumFrames context:(OOCASoundRenderContext *)ioContext data:(AudioBufferList *)ioData;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
// Port messages
|
||||
kMsgRecycleChannel = 1UL,
|
||||
kMsgThreadUp,
|
||||
kMsgDie,
|
||||
kMsgThreadDied
|
||||
};
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uintptr_t tag;
|
||||
void *value;
|
||||
} PortMessage;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mach_msg_header_t header;
|
||||
mach_msg_size_t descCount;
|
||||
mach_msg_descriptor_t descriptor;
|
||||
PortMessage message;
|
||||
} PortSendMsgBody;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mach_msg_header_t header;
|
||||
mach_msg_size_t descCount;
|
||||
mach_msg_descriptor_t descriptor;
|
||||
PortMessage message;
|
||||
mach_msg_trailer_t trailer;
|
||||
} PortWaitMsgBody;
|
||||
|
||||
|
||||
static OSStatus ChannelRenderProc(void *inRefCon, AudioUnitRenderActionFlags *ioFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumFrames, AudioBufferList *ioData);
|
||||
|
||||
static mach_port_t CreatePort(void);
|
||||
static void PortSend(mach_port_t inPort, PortMessage inMessage);
|
||||
static BOOL PortWait(mach_port_t inPort, PortMessage *outMessage);
|
||||
|
||||
|
||||
@implementation OOCASoundChannel
|
||||
|
||||
+ (BOOL)setUp
|
||||
{
|
||||
BOOL OK = YES;
|
||||
PortMessage message;
|
||||
|
||||
if (sReaperRunning) return YES;
|
||||
|
||||
SoundChannelRender = (OOCASoundChannel_RenderIMP)[OOCASoundChannel instanceMethodForSelector:kAURenderSelector];
|
||||
if (NULL == SoundChannelRender) OK = NO;
|
||||
|
||||
if (OK)
|
||||
{
|
||||
sReapPort = CreatePort();
|
||||
if (MACH_PORT_NULL == sReapPort) OK = NO;
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
sStatusPort = CreatePort();
|
||||
if (MACH_PORT_NULL == sStatusPort) OK = NO;
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
[NSThread detachNewThreadSelector:@selector(reaperThread:) toTarget:self withObject:nil];
|
||||
OK = PortWait(sStatusPort, &message);
|
||||
if (OK)
|
||||
{
|
||||
if (kMsgThreadUp != message.tag) OK = NO;
|
||||
}
|
||||
}
|
||||
|
||||
if (!OK)
|
||||
{
|
||||
NSLog(@"Failed to set up sound (channel release queue allocation failed). No sound will be played.");
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
+ (void)tearDown
|
||||
{
|
||||
ipc_space_t task;
|
||||
PortMessage message = { kMsgDie, NULL };
|
||||
|
||||
if (sReaperRunning)
|
||||
{
|
||||
PortSend(sReapPort, message);
|
||||
PortWait(sStatusPort, &message);
|
||||
}
|
||||
|
||||
task = mach_task_self();
|
||||
if (MACH_PORT_NULL != sReapPort) mach_port_destroy(task, sReapPort);
|
||||
if (MACH_PORT_NULL != sStatusPort) mach_port_destroy(task, sStatusPort);
|
||||
}
|
||||
|
||||
|
||||
+ (void)reaperThread:junk
|
||||
{
|
||||
PortMessage message = { kMsgThreadUp, NULL };
|
||||
OOCASoundChannel *chan;
|
||||
|
||||
sReaperRunning = YES;
|
||||
PortSend(sStatusPort, message);
|
||||
|
||||
[NSThread setThreadPriority:0.5];
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (PortWait(sReapPort, &message))
|
||||
{
|
||||
if (kMsgRecycleChannel == message.tag)
|
||||
{
|
||||
chan = message.value;
|
||||
[chan cleanUp];
|
||||
}
|
||||
else if (kMsgDie == message.tag)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
message.tag = kMsgThreadDied;
|
||||
message.value = NULL;
|
||||
sReaperRunning = NO;
|
||||
PortSend(sStatusPort, message);
|
||||
}
|
||||
|
||||
|
||||
- (id)init
|
||||
{
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
- (id)initWithID:(uint32_t)inID auGraph:(AUGraph)inGraph
|
||||
{
|
||||
OSStatus err = noErr;
|
||||
ComponentDescription desc;
|
||||
AURenderCallbackStruct input;
|
||||
|
||||
assert(sReaperRunning);
|
||||
|
||||
self = [super init];
|
||||
if (nil != self)
|
||||
{
|
||||
_id = inID;
|
||||
|
||||
// Create a subgraph (since we can’t have multiple output units otherwise)
|
||||
err = AUGraphNewNodeSubGraph(inGraph, &_subGraphNode);
|
||||
if (!err) err = AUGraphGetNodeInfoSubGraph(inGraph, _subGraphNode, &_subGraph);
|
||||
|
||||
// Create an output unit
|
||||
desc.componentType = kAudioUnitType_Output;
|
||||
desc.componentSubType = kAudioUnitSubType_GenericOutput;
|
||||
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
desc.componentFlags = 0;
|
||||
desc.componentFlagsMask = 0;
|
||||
if (!err) err = AUGraphNewNode(_subGraph, &desc, 0, NULL, &_node);
|
||||
if (!err) err = AUGraphGetNodeInfo(_subGraph, _node, NULL, NULL, NULL, &_au);
|
||||
|
||||
// Set render callback
|
||||
input.inputProc = ChannelRenderProc;
|
||||
input.inputProcRefCon = self;
|
||||
if (!err) err = AudioUnitSetProperty(_au, kAudioUnitProperty_SetRenderCallback,
|
||||
kAudioUnitScope_Input, 0, &input, sizeof input);
|
||||
|
||||
// Init & check errors
|
||||
if (!err) err = AudioUnitInitialize(_au);
|
||||
|
||||
if (err)
|
||||
{
|
||||
NSLog(@"AudioUnit setup error %@.", AudioErrorNSString(err));
|
||||
|
||||
[self release];
|
||||
self = nil;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self stop];
|
||||
if (NULL != _au) CloseComponent(_au);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
- (void)setDelegate:(id)inDelegate
|
||||
{
|
||||
_delegate = inDelegate;
|
||||
}
|
||||
|
||||
|
||||
- (uint32_t)ID
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
|
||||
- (AUNode)auSubGraphNode
|
||||
{
|
||||
return _subGraphNode;
|
||||
}
|
||||
|
||||
|
||||
- (OOCASoundChannel *)next
|
||||
{
|
||||
return _next;
|
||||
}
|
||||
|
||||
|
||||
- (void)setNext:(OOCASoundChannel *)inNext
|
||||
{
|
||||
_next = inNext;
|
||||
}
|
||||
|
||||
|
||||
- (OOSound *)sound
|
||||
{
|
||||
return _sound;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)playSound:(OOSound *)inSound
|
||||
{
|
||||
BOOL OK = YES;
|
||||
OSStatus err = noErr;
|
||||
AudioStreamBasicDescription format;
|
||||
OOSound *temp;
|
||||
SInt32 unexpectedNulls;
|
||||
|
||||
unexpectedNulls = sDebugUnexpectedNullCount;
|
||||
if (0 != unexpectedNulls)
|
||||
{
|
||||
OTAtomicAdd32(-unexpectedNulls, &sDebugUnexpectedNullCount);
|
||||
if (1 == unexpectedNulls)
|
||||
{
|
||||
NSLog(@"A NULL Render() or nil _sound error has occured.");
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"%i NULL Render() or nil _sound errors have occured.", (int)unexpectedNulls);
|
||||
}
|
||||
}
|
||||
|
||||
if (nil != inSound)
|
||||
{
|
||||
[gOOCASoundSyncLock lock];
|
||||
if (kState_Stopped != _state)
|
||||
{
|
||||
NSLog(@"Channel %@ reused while playing.", self);
|
||||
|
||||
[[OOCASoundMixer mixer] disconnectChannel:self];
|
||||
if (_sound)
|
||||
{
|
||||
Render = NULL;
|
||||
temp = _sound;
|
||||
_sound = nil;
|
||||
[temp finishStoppingWithContext:_context];
|
||||
_context = 0;
|
||||
[temp release];
|
||||
}
|
||||
_stopReq = NO;
|
||||
_state = kState_Stopped;
|
||||
}
|
||||
|
||||
Render = (OOCASoundChannel_RenderIMP)[inSound methodForSelector:kAURenderSelector];
|
||||
OK = (NULL != Render);
|
||||
|
||||
if (OK) OK = [inSound getAudioStreamBasicDescription:&format];
|
||||
if (OK) OK = [inSound prepareToPlayWithContext:&_context];
|
||||
|
||||
if (!OK)
|
||||
{
|
||||
NSLog(@"OOCASoundChannel: Failed to play sound %@ - set-up issues.", inSound);
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
_sound = inSound;
|
||||
|
||||
err = AudioUnitSetProperty(_au, kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input, 0, &format, sizeof format);
|
||||
|
||||
if (err) NSLog(@"OOCASoundChannel: Failed to play %@ (error %@)", inSound, AudioErrorNSString(err));
|
||||
OK = !err;
|
||||
}
|
||||
|
||||
if (OK) OK = [[OOCASoundMixer mixer] connectChannel:self];
|
||||
|
||||
if (OK)
|
||||
{
|
||||
[_sound retain];
|
||||
_state = kState_Playing;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sound = nil;
|
||||
// if (!err) NSLog(@"OOCASoundChannel: Failed to play %@", inSound);
|
||||
}
|
||||
[gOOCASoundSyncLock unlock];
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
- (void)stop
|
||||
{
|
||||
if (kState_Playing == _state)
|
||||
{
|
||||
_stopReq = YES;
|
||||
}
|
||||
|
||||
if (kState_Ended == _state) [self cleanUp];
|
||||
}
|
||||
|
||||
|
||||
- (void)cleanUp
|
||||
{
|
||||
OOSound *sound;
|
||||
|
||||
[gOOCASoundSyncLock lock];
|
||||
|
||||
if (kState_Ended == _state)
|
||||
{
|
||||
Render = NULL;
|
||||
sound = _sound;
|
||||
_sound = nil;
|
||||
[sound finishStoppingWithContext:_context];
|
||||
_context = 0;
|
||||
|
||||
_state = kState_Stopped;
|
||||
_stopReq = NO;
|
||||
|
||||
if (nil != _delegate && [_delegate respondsToSelector:@selector(channel:didFinishPlayingSound:)])
|
||||
{
|
||||
[_delegate channel:self didFinishPlayingSound:sound];
|
||||
}
|
||||
[sound release];
|
||||
}
|
||||
[gOOCASoundSyncLock unlock];
|
||||
}
|
||||
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
NSString *result, *stateString;
|
||||
|
||||
[gOOCASoundSyncLock lock];
|
||||
switch (_state)
|
||||
{
|
||||
case kState_Stopped:
|
||||
stateString = @"stopped";
|
||||
break;
|
||||
|
||||
case kState_Playing:
|
||||
stateString = @"playing";
|
||||
break;
|
||||
|
||||
case kState_Ended:
|
||||
stateString = @"ended";
|
||||
break;
|
||||
|
||||
default:
|
||||
stateString = [NSString stringWithFormat:@"unknown (%u)", _state];
|
||||
}
|
||||
|
||||
result = [NSString stringWithFormat:@"<%@ %p>{ID=%u, state=%@, sound=%@}", [self className], self, _id, stateString, _sound];
|
||||
[gOOCASoundSyncLock unlock];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
- (OSStatus)renderWithFlags:(AudioUnitRenderActionFlags *)ioFlags frames:(UInt32)inNumFrames context:(OOCASoundRenderContext *)ioContext data:(AudioBufferList *)ioData
|
||||
{
|
||||
OSStatus err;
|
||||
PortMessage message;
|
||||
|
||||
if (__builtin_expect(_stopReq, 0)) err = endOfDataReached;
|
||||
else
|
||||
{
|
||||
if (NULL != Render && nil != _sound)
|
||||
{
|
||||
err = Render(_sound, kAURenderSelector, ioFlags, inNumFrames, &_context, ioData);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned i, count;
|
||||
|
||||
err = endOfDataReached;
|
||||
count = ioData->mNumberBuffers;
|
||||
|
||||
// Logging in real-time thread _baaaaaad_.
|
||||
if (NULL == Render)
|
||||
{
|
||||
OTAtomicAdd32(1, &sDebugUnexpectedNullCount);
|
||||
// NSLog(@"NULL Render()! Zeroing output (%u channels).", count);
|
||||
}
|
||||
else if (nil == _sound)
|
||||
{
|
||||
OTAtomicAdd32(1, &sDebugUnexpectedNullCount);
|
||||
// NSLog(@"nil _sound! Zeroing output (%u channels).", count);
|
||||
}
|
||||
|
||||
for (i = 0; i != count; ++count)
|
||||
{
|
||||
bzero(ioData->mBuffers[i].mData, ioData->mBuffers[i].mDataByteSize);
|
||||
}
|
||||
*ioFlags |= kAudioUnitRenderAction_OutputIsSilence;
|
||||
}
|
||||
}
|
||||
|
||||
if (endOfDataReached == err)
|
||||
{
|
||||
err = noErr;
|
||||
|
||||
[[OOCASoundMixer mixer] disconnectChannel:self];
|
||||
_state = kState_Ended;
|
||||
|
||||
message.tag = kMsgRecycleChannel;
|
||||
message.value = self;
|
||||
PortSend(sReapPort, message);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
static OSStatus ChannelRenderProc(void *inRefCon, AudioUnitRenderActionFlags *ioFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumFrames, AudioBufferList *ioData)
|
||||
{
|
||||
return SoundChannelRender((id)inRefCon, kAURenderSelector, ioFlags, inNumFrames, 0, ioData);
|
||||
}
|
||||
|
||||
|
||||
static mach_port_t CreatePort(void)
|
||||
{
|
||||
kern_return_t err;
|
||||
mach_port_t result;
|
||||
ipc_space_t task;
|
||||
mach_msg_type_name_t type;
|
||||
mach_port_t sendRight;
|
||||
|
||||
task = mach_task_self();
|
||||
err = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &result);
|
||||
if (KERN_SUCCESS == err) err = mach_port_insert_right(task, result, result, MACH_MSG_TYPE_MAKE_SEND);
|
||||
if (KERN_SUCCESS == err) err = mach_port_extract_right(task, result, MACH_MSG_TYPE_MAKE_SEND, &sendRight, &type);
|
||||
|
||||
if (KERN_SUCCESS != err)
|
||||
{
|
||||
NSLog(@"Mach port creation failure: %@", KernelResultNSString(err));
|
||||
result = MACH_PORT_NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void PortSend(mach_port_t inPort, PortMessage inMessage)
|
||||
{
|
||||
PortSendMsgBody message;
|
||||
mach_msg_return_t result;
|
||||
|
||||
bzero(&message, sizeof message);
|
||||
|
||||
message.header.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_MAKE_SEND);
|
||||
message.header.msgh_size = sizeof message;
|
||||
message.header.msgh_remote_port = inPort;
|
||||
message.header.msgh_local_port = MACH_PORT_NULL;
|
||||
|
||||
message.descCount = 1;
|
||||
|
||||
message.message = inMessage;
|
||||
|
||||
result = mach_msg(&message.header, MACH_SEND_MSG | MACH_SEND_TIMEOUT, sizeof message, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL);
|
||||
if (MACH_MSG_SUCCESS != result)
|
||||
{
|
||||
NSLog(@"Mach port transient send failure: %@", KernelResultNSString(result));
|
||||
result = mach_msg(&message.header, MACH_SEND_MSG, sizeof message, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL);
|
||||
if (MACH_MSG_SUCCESS != result)
|
||||
{
|
||||
NSLog(@"Mach port send failure: %@", KernelResultNSString(result));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static BOOL PortWait(mach_port_t inPort, PortMessage *outMessage)
|
||||
{
|
||||
PortWaitMsgBody message;
|
||||
mach_msg_return_t result;
|
||||
|
||||
bzero(&message, sizeof message);
|
||||
|
||||
message.header.msgh_bits = MACH_MSGH_BITS_LOCAL(MACH_MSG_TYPE_COPY_RECEIVE);
|
||||
message.header.msgh_size = sizeof message;
|
||||
message.header.msgh_local_port = inPort;
|
||||
|
||||
result = mach_msg_receive(&message.header);
|
||||
if (MACH_MSG_SUCCESS == result)
|
||||
{
|
||||
if (NULL != outMessage) *outMessage = message.message;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MACH_RCV_TIMED_OUT != result) NSLog(@"Mach port receive failure: %@", KernelResultNSString(result));
|
||||
}
|
||||
|
||||
return MACH_MSG_SUCCESS == result;
|
||||
}
|
54
src/Cocoa/OOCASoundDecoder.h
Normal file
54
src/Cocoa/OOCASoundDecoder.h
Normal file
@ -0,0 +1,54 @@
|
||||
//
|
||||
// OOCASoundDecoder.h
|
||||
// CoreAudio sound implementation for Oolite
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface OOCASoundDecoder: NSObject
|
||||
|
||||
- (id)initWithPath:(NSString *)inPath;
|
||||
+ (OOCASoundDecoder *)codecWithPath:(NSString *)inPath;
|
||||
|
||||
// This will always provide two channels (as non-interleaved PCM), discarding extra channels or doubling mono as necessary.
|
||||
- (size_t)readStereoToBufferL:(float *)ioBufferL bufferR:(float *)ioBufferR maxFrames:(size_t)inMax;
|
||||
|
||||
// This will always provide one channel, mixing down stereo and discarding extra channels.
|
||||
- (BOOL)readMonoCreatingBuffer:(float **)outBuffer withFrameCount:(size_t *)outSize;
|
||||
|
||||
- (Float64)sampleRate;
|
||||
- (BOOL)atEnd;
|
||||
- (void)rewindToBeginning;
|
||||
|
||||
- (NSString *)name;
|
||||
|
||||
@end
|
376
src/Cocoa/OOCASoundDecoder.m
Normal file
376
src/Cocoa/OOCASoundDecoder.m
Normal file
@ -0,0 +1,376 @@
|
||||
//
|
||||
// OOCASoundDecoder.m
|
||||
// CoreAudio sound implementation for Oolite
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOCASoundDecoder.h"
|
||||
#import <stdio.h>
|
||||
#import <vorbis/vorbisfile.h>
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
kMaxDecodeSize = 1 << 20 // 2^20 frames = four megs of data
|
||||
};
|
||||
|
||||
|
||||
static void MixDown(float *inChan1, float *inChan2, float *outMix, size_t inCount);
|
||||
|
||||
|
||||
@interface OOSoundCAVorbisCodec: OOCASoundDecoder
|
||||
{
|
||||
OggVorbis_File _vf;
|
||||
NSString *_name;
|
||||
BOOL _atEnd;
|
||||
}
|
||||
|
||||
- (NSDictionary *)comments;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation OOCASoundDecoder
|
||||
|
||||
#ifndef NDEBUG
|
||||
- (id)init
|
||||
{
|
||||
NSLog(@"Invalid call of %s.", __PRETTY_FUNCTION__);
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
- (id)initWithPath:(NSString *)inPath
|
||||
{
|
||||
[self release];
|
||||
self = nil;
|
||||
|
||||
if ([[inPath pathExtension] isEqual:@"ogg"])
|
||||
{
|
||||
self = [[OOSoundCAVorbisCodec alloc] initWithPath:inPath];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
+ (OOCASoundDecoder *)codecWithPath:(NSString *)inPath
|
||||
{
|
||||
if ([[inPath pathExtension] isEqual:@"ogg"])
|
||||
{
|
||||
return [[[OOSoundCAVorbisCodec alloc] initWithPath:inPath] autorelease];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
- (size_t)readStereoToBufferL:(float *)ioBufferL bufferR:(float *)ioBufferR maxFrames:(size_t)inMax
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)readMonoCreatingBuffer:(float **)outBuffer withFrameCount:(size_t *)outSize
|
||||
{
|
||||
if (NULL != outBuffer) *outBuffer = NULL;
|
||||
if (NULL != outSize) *outSize = 0;
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
- (double)sampleRate
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)atEnd
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (void)rewindToBeginning
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (NSString *)name
|
||||
{
|
||||
return @"";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation OOSoundCAVorbisCodec
|
||||
|
||||
- (id)initWithPath:(NSString *)inPath
|
||||
{
|
||||
BOOL OK = NO;
|
||||
int err;
|
||||
FILE *file;
|
||||
|
||||
_name = [[inPath lastPathComponent] retain];
|
||||
|
||||
if (nil != inPath)
|
||||
{
|
||||
file = fopen([inPath UTF8String], "rb");
|
||||
if (NULL != file)
|
||||
{
|
||||
err = ov_open(file, &_vf, NULL, 0);
|
||||
if (0 == err)
|
||||
{
|
||||
OK = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!OK)
|
||||
{
|
||||
[self release];
|
||||
self = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_name release];
|
||||
ov_clear(&_vf);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
- (NSDictionary *)comments
|
||||
{
|
||||
vorbis_comment *comments;
|
||||
unsigned i, count;
|
||||
NSMutableDictionary *result = nil;
|
||||
NSString *comment, *key, *value;
|
||||
NSRange range;
|
||||
|
||||
comments = ov_comment(&_vf, -1);
|
||||
if (NULL != comments)
|
||||
{
|
||||
count = comments->comments;
|
||||
if (0 != count)
|
||||
{
|
||||
result = [NSMutableDictionary dictionaryWithCapacity:count];
|
||||
for (i = 0; i != count; ++i)
|
||||
{
|
||||
comment = [[NSString alloc] initWithBytesNoCopy:comments->user_comments[i] length:comments->comment_lengths[i] encoding:NSUTF8StringEncoding freeWhenDone:NO];
|
||||
range = [comment rangeOfString:@"="];
|
||||
if (0 != range.length)
|
||||
{
|
||||
key = [comment substringToIndex:range.location];
|
||||
value = [comment substringFromIndex:range.location + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
key = comment;
|
||||
value = @"";
|
||||
}
|
||||
[result setObject:value forKey:key];
|
||||
|
||||
[comment release];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
- (size_t)readStereoToBufferL:(float *)ioBufferL bufferR:(float *)ioBufferR maxFrames:(size_t)inMax
|
||||
{
|
||||
float **src;
|
||||
unsigned chanCount;
|
||||
unsigned framesRead, size;
|
||||
size_t remaining;
|
||||
unsigned rightChan;
|
||||
|
||||
// Note: for our purposes, a frame is a set of one sample for each channel.
|
||||
if (NULL == ioBufferL || NULL == ioBufferR || 0 == inMax) return 0;
|
||||
if (_atEnd) return inMax;
|
||||
|
||||
remaining = inMax;
|
||||
do
|
||||
{
|
||||
chanCount = ov_info(&_vf, -1)->channels;
|
||||
framesRead = ov_read_float(&_vf, &src, remaining, NULL);
|
||||
if (framesRead <= 0)
|
||||
{
|
||||
if (OV_HOLE == framesRead) continue;
|
||||
//else:
|
||||
_atEnd = YES;
|
||||
break;
|
||||
}
|
||||
|
||||
size = sizeof (float) * framesRead;
|
||||
|
||||
rightChan = (1 == chanCount) ? 0 : 1;
|
||||
bcopy(src[0], ioBufferL, size);
|
||||
bcopy(src[rightChan], ioBufferR, size);
|
||||
|
||||
remaining -= framesRead;
|
||||
ioBufferL += framesRead;
|
||||
ioBufferR += framesRead;
|
||||
} while (0 != remaining);
|
||||
|
||||
return inMax - remaining;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)readMonoCreatingBuffer:(float **)outBuffer withFrameCount:(size_t *)outSize
|
||||
{
|
||||
float *buffer, *dst, **src;
|
||||
size_t sizeInFrames, remaining;
|
||||
unsigned chanCount;
|
||||
unsigned framesRead;
|
||||
ogg_int64_t totalSizeInFrames;
|
||||
BOOL OK = YES;
|
||||
|
||||
if (NULL != outBuffer) *outBuffer = NULL;
|
||||
if (NULL != outSize) *outSize = 0;
|
||||
if (NULL == outBuffer || NULL == outSize) OK = NO;
|
||||
|
||||
if (OK)
|
||||
{
|
||||
totalSizeInFrames = ov_pcm_total(&_vf, -1);
|
||||
if (kMaxDecodeSize < totalSizeInFrames)
|
||||
{
|
||||
NSLog(@"Refusing to load %@ because its uncompressed size is over %u bytes.", [self name], kMaxDecodeSize * sizeof (float));
|
||||
OK = NO;
|
||||
}
|
||||
sizeInFrames = totalSizeInFrames;
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
buffer = malloc(sizeof (float) * sizeInFrames);
|
||||
if (!buffer) OK = NO;
|
||||
}
|
||||
|
||||
if (OK && sizeInFrames)
|
||||
{
|
||||
remaining = sizeInFrames;
|
||||
dst = buffer;
|
||||
|
||||
do
|
||||
{
|
||||
chanCount = ov_info(&_vf, -1)->channels;
|
||||
framesRead = ov_read_float(&_vf, &src, remaining, NULL);
|
||||
if (framesRead <= 0)
|
||||
{
|
||||
if (OV_HOLE == framesRead) continue;
|
||||
//else:
|
||||
break;
|
||||
}
|
||||
|
||||
if (1 == chanCount) bcopy(src[0], dst, sizeof (float) * framesRead);
|
||||
else MixDown(src[0], src[1], dst, framesRead);
|
||||
|
||||
remaining -= framesRead;
|
||||
dst += framesRead;
|
||||
} while (0 != remaining);
|
||||
|
||||
sizeInFrames -= remaining; // In case we stopped at an error
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
*outBuffer = buffer;
|
||||
*outSize = sizeInFrames;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"<%@ %p>{\"%@\", comments=%@}", [self className], self, _name, [self comments]];
|
||||
}
|
||||
|
||||
|
||||
- (Float64)sampleRate
|
||||
{
|
||||
return ov_info(&_vf, -1)->rate;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)atEnd
|
||||
{
|
||||
return _atEnd;
|
||||
}
|
||||
|
||||
|
||||
- (void)rewindToBeginning
|
||||
{
|
||||
if (!ov_pcm_seek(&_vf, 0)) _atEnd = NO;
|
||||
}
|
||||
|
||||
|
||||
- (NSString *)name
|
||||
{
|
||||
NSDictionary *comments;
|
||||
NSString *result = nil;
|
||||
|
||||
comments = [self comments];
|
||||
if (nil != comments)
|
||||
{
|
||||
result = [comments objectForKey:@"TITLE"];
|
||||
if (nil == result) result = [comments objectForKey:@"NAME"];
|
||||
}
|
||||
|
||||
if (nil == result) result = [[_name retain] autorelease];
|
||||
if (nil == result) result = [super name];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// TODO: optimise, vectorise
|
||||
static void MixDown(float *inChan1, float *inChan2, float *outMix, size_t inCount)
|
||||
{
|
||||
while (inCount--)
|
||||
{
|
||||
*outMix++ = (*inChan1++ + *inChan2++) * 0.5f;
|
||||
}
|
||||
}
|
68
src/Cocoa/OOCASoundInternal.h
Normal file
68
src/Cocoa/OOCASoundInternal.h
Normal file
@ -0,0 +1,68 @@
|
||||
//
|
||||
// OOCASoundInternal.h
|
||||
// CoreAudio sound implementation for Oolite
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOCASound.h"
|
||||
#import "OOCAMusic.h"
|
||||
#import "OOCASoundDecoder.h"
|
||||
#import "OOCASoundMixer.h"
|
||||
#import "OOCASoundChannel.h"
|
||||
#import "OOCABufferedSound.h"
|
||||
#import <CoreAudio/CoreAudio.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
#import "OOErrorDescription.h"
|
||||
#import "OOCASoundSource.h"
|
||||
|
||||
|
||||
@interface OOSound (Internal)
|
||||
|
||||
- (OSStatus)renderWithFlags:(AudioUnitRenderActionFlags *)ioFlags frames:(UInt32)inNumFrames context:(OOCASoundRenderContext *)ioContext data:(AudioBufferList *)ioData;
|
||||
|
||||
// Called by -play and -stop only if in appropriate state
|
||||
- (BOOL)prepareToPlayWithContext:(OOCASoundRenderContext *)outContext;
|
||||
- (void)finishStoppingWithContext:(OOCASoundRenderContext)inContext;
|
||||
|
||||
- (BOOL)getAudioStreamBasicDescription:(AudioStreamBasicDescription *)outFormat;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface OOCASoundMixer (Internal)
|
||||
|
||||
- (BOOL)connectChannel:(OOCASoundChannel *)inChannel;
|
||||
- (void)disconnectChannel:(OOCASoundChannel *)inChannel;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
extern BOOL gOOSoundSetUp, gOOSoundBroken;
|
||||
extern NSLock *gOOCASoundSyncLock;
|
89
src/Cocoa/OOCASoundMixer.h
Normal file
89
src/Cocoa/OOCASoundMixer.h
Normal file
@ -0,0 +1,89 @@
|
||||
//
|
||||
// OOCASoundMixer.h
|
||||
// CoreAudio sound implementation for Oolite
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <mach/port.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
@class OOMusic, OOCASoundChannel, OOSoundSource;
|
||||
|
||||
|
||||
#define kMixerGeneralChannels 32
|
||||
#define SUPPORT_SOUND_INSPECTOR 0
|
||||
|
||||
|
||||
@interface OOCASoundMixer: NSObject
|
||||
{
|
||||
OOCASoundChannel *_channels[kMixerGeneralChannels];
|
||||
OOCASoundChannel *_freeList;
|
||||
NSLock *_listLock;
|
||||
|
||||
AUGraph _graph;
|
||||
AUNode _mixerNode;
|
||||
AUNode _outputNode;
|
||||
AudioUnit _mixerUnit;
|
||||
|
||||
OOSoundSource *_musicSource;
|
||||
OOMusic *_music;
|
||||
|
||||
uint32_t _activeChannels;
|
||||
uint32_t _maxChannels;
|
||||
uint32_t _playMask;
|
||||
|
||||
#if SUPPORT_SOUND_INSPECTOR
|
||||
IBOutlet NSMatrix *checkBoxes;
|
||||
IBOutlet NSTextField *currentField;
|
||||
IBOutlet NSTextField *maxField;
|
||||
IBOutlet NSTextField *loadField;
|
||||
IBOutlet NSProgressIndicator *loadBar;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Singleton accessor
|
||||
+ (OOCASoundMixer *)mixer;
|
||||
+ (void)destroy; // releases singleton
|
||||
|
||||
- (void)playMusic:(OOMusic *)inMusic;
|
||||
- (void)stopMusic:(OOMusic *)inMusic;
|
||||
- (OOMusic *)currentMusic;
|
||||
|
||||
- (void)playSound:(OOSound *)inSound;
|
||||
|
||||
- (void)update;
|
||||
|
||||
- (void)setMasterVolume:(float)inVolume;
|
||||
|
||||
- (OOCASoundChannel *)popChannel;
|
||||
- (void)pushChannel:(OOCASoundChannel *)inChannel;
|
||||
|
||||
@end
|
390
src/Cocoa/OOCASoundMixer.m
Normal file
390
src/Cocoa/OOCASoundMixer.m
Normal file
@ -0,0 +1,390 @@
|
||||
//
|
||||
// OOCASoundMixer.m
|
||||
// CoreAudio sound implementation for Oolite
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOCASoundInternal.h"
|
||||
#import "OOCASoundChannel.h"
|
||||
|
||||
@interface OOCASoundMixer(Private)
|
||||
|
||||
- (void)reallyRelease;
|
||||
- (void)channelSoundEnded:(OOCASoundChannel *)inChannel;
|
||||
|
||||
- (void)pushChannel:(OOCASoundChannel *)inChannel;
|
||||
- (OOCASoundChannel *)popChannel;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
static OOCASoundMixer *sSingleton = nil;
|
||||
|
||||
|
||||
@implementation OOCASoundMixer
|
||||
|
||||
+ (OOCASoundMixer *)mixer
|
||||
{
|
||||
if (nil == sSingleton)
|
||||
{
|
||||
sSingleton = [[self alloc] init];
|
||||
}
|
||||
return sSingleton;
|
||||
}
|
||||
|
||||
|
||||
- (id)init
|
||||
{
|
||||
OSStatus err = noErr;
|
||||
BOOL OK;
|
||||
uint32_t idx = 0, count = kMixerGeneralChannels;
|
||||
OOCASoundChannel *temp;
|
||||
ComponentDescription desc;
|
||||
|
||||
if (!gOOSoundSetUp) [OOSound setUp];
|
||||
|
||||
if (nil != sSingleton)
|
||||
{
|
||||
[super release];
|
||||
}
|
||||
else
|
||||
{
|
||||
self = [super init];
|
||||
if (nil != self)
|
||||
{
|
||||
_listLock = [[NSLock alloc] init];
|
||||
OK = nil != _listLock;
|
||||
|
||||
if (OK)
|
||||
{
|
||||
// Create audio graph
|
||||
err = NewAUGraph(&_graph);
|
||||
|
||||
// Add output node
|
||||
desc.componentType = kAudioUnitType_Output;
|
||||
desc.componentSubType = kAudioUnitSubType_DefaultOutput;
|
||||
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
desc.componentFlags = 0;
|
||||
desc.componentFlagsMask = 0;
|
||||
if (!err) err = AUGraphNewNode(_graph, &desc, 0, NULL, &_outputNode);
|
||||
|
||||
// Add mixer node
|
||||
desc.componentType = kAudioUnitType_Mixer;
|
||||
desc.componentSubType = kAudioUnitSubType_StereoMixer;
|
||||
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
desc.componentFlags = 0;
|
||||
desc.componentFlagsMask = 0;
|
||||
if (!err) err = AUGraphNewNode(_graph, &desc, 0, NULL, &_mixerNode);
|
||||
|
||||
// Connect mixer to output
|
||||
if (!err) err = AUGraphConnectNodeInput(_graph, _mixerNode, 0, _outputNode, 0);
|
||||
|
||||
// Open the graph (turn it into concrete AUs) and extract mixer AU
|
||||
if (!err) err = AUGraphOpen(_graph);
|
||||
if (!err) err = AUGraphGetNodeInfo(_graph, _mixerNode, NULL, NULL, NULL, &_mixerUnit);
|
||||
|
||||
if (err) OK = NO;
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
// Allocate channels
|
||||
do
|
||||
{
|
||||
temp = [[OOCASoundChannel alloc] initWithID:count auGraph:_graph];
|
||||
if (nil != temp)
|
||||
{
|
||||
_channels[idx++] = temp;
|
||||
[temp setNext:_freeList];
|
||||
_freeList = temp;
|
||||
}
|
||||
} while (--count);
|
||||
|
||||
if (noErr != AUGraphInitialize(_graph)) OK = NO;
|
||||
}
|
||||
|
||||
if (OK) _musicSource = [[OOSoundSource alloc] init];
|
||||
|
||||
if (!OK)
|
||||
{
|
||||
[self reallyRelease];
|
||||
self = nil;
|
||||
}
|
||||
|
||||
#if SUPPORT_SOUND_INSPECTOR
|
||||
if (![NSBundle loadNibNamed:@"SoundInspector" owner:self])
|
||||
{
|
||||
NSLog(@"Failed to load sound inspector panel.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
sSingleton = self;
|
||||
}
|
||||
|
||||
return sSingleton;
|
||||
}
|
||||
|
||||
|
||||
- (id)retain
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void)release
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)reallyRelease
|
||||
{
|
||||
[super release];
|
||||
}
|
||||
|
||||
|
||||
- (id)autorelease
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
+ (void)destroy
|
||||
{
|
||||
if (nil != sSingleton)
|
||||
{
|
||||
[sSingleton reallyRelease];
|
||||
sSingleton = nil;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
uint32_t idx;
|
||||
|
||||
if (NULL != _graph)
|
||||
{
|
||||
AUGraphStop(_graph);
|
||||
AUGraphUninitialize(_graph);
|
||||
AUGraphClose(_graph);
|
||||
DisposeAUGraph(_graph);
|
||||
}
|
||||
for (idx = 0; idx != kMixerGeneralChannels; ++idx)
|
||||
{
|
||||
[_channels[idx] release];
|
||||
}
|
||||
[_musicSource release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
- (void)playMusic:(OOMusic *)inMusic
|
||||
{
|
||||
if (_music != inMusic)
|
||||
{
|
||||
_music = [inMusic retain];
|
||||
[_musicSource playSound:inMusic];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)stopMusic:(OOMusic *)inMusic
|
||||
{
|
||||
if (_music == inMusic)
|
||||
{
|
||||
[_musicSource stop];
|
||||
[_music autorelease];
|
||||
_music = nil;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (OOMusic *)currentMusic
|
||||
{
|
||||
return _music;
|
||||
}
|
||||
|
||||
|
||||
- (void)playSound:(OOSound *)inSound
|
||||
{
|
||||
BOOL OK = YES;
|
||||
OOCASoundChannel *chan;
|
||||
|
||||
if (nil == inSound) return;
|
||||
|
||||
chan = [self popChannel];
|
||||
|
||||
if (nil != chan)
|
||||
{
|
||||
[chan setDelegate:self];
|
||||
OK = [chan playSound:inSound];
|
||||
|
||||
if (OK) [self retain];
|
||||
else
|
||||
{
|
||||
[self pushChannel:chan];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"Out of sound channels! Pretend you're hearing %@", [inSound name]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)channel:(OOCASoundChannel *)inChannel didFinishPlayingSound:(OOSound *)inSound
|
||||
{
|
||||
[self pushChannel:inChannel];
|
||||
}
|
||||
|
||||
|
||||
- (void)update
|
||||
{
|
||||
#if SUPPORT_SOUND_INSPECTOR
|
||||
uint32_t i;
|
||||
Float32 load;
|
||||
|
||||
for (i = 0; i != kMixerGeneralChannels && i != 32; ++i)
|
||||
{
|
||||
[[checkBoxes cellWithTag:i] setIntValue:_playMask & (1 << i)];
|
||||
}
|
||||
|
||||
if (_maxChannels < _activeChannels)
|
||||
{
|
||||
_maxChannels = _activeChannels;
|
||||
[maxField setIntValue:_maxChannels];
|
||||
}
|
||||
[currentField setIntValue:_activeChannels];
|
||||
|
||||
if (!AUGraphGetCPULoad(_graph, &load))
|
||||
{
|
||||
[loadBar setDoubleValue:load];
|
||||
[loadField setObjectValue:[NSString stringWithFormat:@"%.2g%%", load * 100.0]];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if SUPPORT_SOUND_INSPECTOR
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if (nil != checkBoxes)
|
||||
{
|
||||
for (i = 0; i != kMixerGeneralChannels; ++i)
|
||||
{
|
||||
[[checkBoxes cellWithTag:i] setIntValue:0];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
- (void)setMasterVolume:(float)inVolume
|
||||
{
|
||||
AudioUnitSetParameter(_mixerUnit, kStereoMixerParam_Volume, kAudioUnitScope_Output, 0, inVolume, 0);
|
||||
}
|
||||
|
||||
|
||||
- (void)pushChannel:(OOCASoundChannel *)inChannel
|
||||
{
|
||||
uint32_t ID;
|
||||
|
||||
assert(nil != inChannel);
|
||||
|
||||
[_listLock lock];
|
||||
|
||||
[inChannel setNext:_freeList];
|
||||
_freeList = inChannel;
|
||||
|
||||
if (0 == --_activeChannels)
|
||||
{
|
||||
AUGraphStop(_graph);
|
||||
}
|
||||
ID = [inChannel ID] - 1;
|
||||
if (ID < 32) _playMask &= ~(1 << ID);
|
||||
[_listLock unlock];
|
||||
}
|
||||
|
||||
|
||||
- (OOCASoundChannel *)popChannel
|
||||
{
|
||||
OOCASoundChannel *result;
|
||||
uint32_t ID;
|
||||
|
||||
[_listLock lock];
|
||||
result = _freeList;
|
||||
_freeList = [result next];
|
||||
|
||||
if (nil != result)
|
||||
{
|
||||
if (0 == _activeChannels++)
|
||||
{
|
||||
AUGraphStart(_graph);
|
||||
}
|
||||
|
||||
ID = [result ID] - 1;
|
||||
if (ID < 32) _playMask |= (1 << ID);
|
||||
}
|
||||
[_listLock unlock];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)connectChannel:(OOCASoundChannel *)inChannel
|
||||
{
|
||||
AUNode node;
|
||||
OSStatus err;
|
||||
|
||||
assert(nil != inChannel);
|
||||
|
||||
node = [inChannel auSubGraphNode];
|
||||
err = AUGraphConnectNodeInput(_graph, node, 0, _mixerNode, [inChannel ID]);
|
||||
if (!err) err = AUGraphUpdate(_graph, NULL);
|
||||
|
||||
if (err) NSLog(@"OOCASoundMixer: failed to connect channel %@, error = %@.", inChannel, AudioErrorNSString(err));
|
||||
|
||||
return !err;
|
||||
}
|
||||
|
||||
|
||||
- (void)disconnectChannel:(OOCASoundChannel *)inChannel
|
||||
{
|
||||
assert(nil != inChannel);
|
||||
|
||||
AUGraphDisconnectNodeInput(_graph, _mixerNode, [inChannel ID]);
|
||||
AUGraphUpdate(_graph, NULL);
|
||||
}
|
||||
|
||||
@end
|
45
src/Cocoa/OOCASoundReferencePoint.h
Normal file
45
src/Cocoa/OOCASoundReferencePoint.h
Normal file
@ -0,0 +1,45 @@
|
||||
//
|
||||
// OOCASoundReferencePoint.h
|
||||
// CoreAudio sound implementation for Oolite
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "vector.h"
|
||||
|
||||
|
||||
@interface OOSoundReferencePoint: NSObject
|
||||
|
||||
// Positional audio attributes are ignored in this implementation
|
||||
- (void)setPosition:(Vector)inPosition;
|
||||
- (void)setVelocity:(Vector)inVelocity;
|
||||
- (void)setOrientation:(Vector)inOrientation;
|
||||
|
||||
@end
|
56
src/Cocoa/OOCASoundReferencePoint.m
Normal file
56
src/Cocoa/OOCASoundReferencePoint.m
Normal file
@ -0,0 +1,56 @@
|
||||
//
|
||||
// OOCASoundReferencePoint.m
|
||||
// CoreAudio sound implementation for Oolite
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOCASoundReferencePoint.h"
|
||||
|
||||
|
||||
@implementation OOSoundReferencePoint
|
||||
|
||||
- (void)setPosition:(Vector)inPosition
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)setVelocity:(Vector)inVelocity
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)setOrientation:(Vector)inOrientation
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@end
|
67
src/Cocoa/OOCASoundSource.h
Normal file
67
src/Cocoa/OOCASoundSource.h
Normal file
@ -0,0 +1,67 @@
|
||||
//
|
||||
// OOCASoundSource.h
|
||||
// CoreAudio sound implementation for Oolite
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "vector.h"
|
||||
#import "OOCASoundReferencePoint.h"
|
||||
|
||||
@class OOSound, OOCASoundChannel;
|
||||
|
||||
|
||||
@interface OOSoundSource: NSObject
|
||||
{
|
||||
OOCASoundChannel *_channel;
|
||||
BOOL _playing, _loop;
|
||||
uint8_t _playCount;
|
||||
}
|
||||
|
||||
// Positional audio attributes are ignored in this implementation
|
||||
- (void)setPositional:(BOOL)inPositional;
|
||||
- (void)setPosition:(Vector)inPosition;
|
||||
- (void)setVelocity:(Vector)inVelocity;
|
||||
- (void)setOrientation:(Vector)inOrientation;
|
||||
- (void)setConeAngle:(float)inAngle;
|
||||
- (void)setGainInsideCone:(float)inInside outsideCone:(float)inOutside;
|
||||
- (void)positionRelativeTo:(OOSoundReferencePoint *)inPoint;
|
||||
|
||||
- (void)setLoop:(BOOL)inLoop;
|
||||
|
||||
- (void)playSound:(OOSound *)inSound;
|
||||
// repeatCount lets a sound be played a fixed number of times. If looping is on, it will play the specified number of times after looping is switched off.
|
||||
- (void)playSound:(OOSound *)inSound repeatCount:(uint8_t)inCount;
|
||||
// -playOrRepeatSound will increment the repeat count if the sound is already playing.
|
||||
- (void)playOrRepeatSound:(OOSound *)inSound;
|
||||
- (void)stop;
|
||||
- (BOOL)isPlaying;
|
||||
|
||||
@end
|
236
src/Cocoa/OOCASoundSource.m
Normal file
236
src/Cocoa/OOCASoundSource.m
Normal file
@ -0,0 +1,236 @@
|
||||
//
|
||||
// OOCASoundSource.m
|
||||
// CoreAudio sound implementation for Oolite
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOCASoundInternal.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
kFreeListMax = 16
|
||||
};
|
||||
|
||||
|
||||
static uint32_t sFreeListCount = 0;
|
||||
static OOSoundSource *sFreeList = nil;
|
||||
|
||||
|
||||
@implementation OOSoundSource
|
||||
|
||||
+ (id)alloc
|
||||
{
|
||||
OOSoundSource *result = nil;
|
||||
|
||||
[gOOCASoundSyncLock lock];
|
||||
if (nil != sFreeList)
|
||||
{
|
||||
result = sFreeList;
|
||||
sFreeList = (OOSoundSource *)result->_channel;
|
||||
result->_channel = nil;
|
||||
}
|
||||
[gOOCASoundSyncLock unlock];
|
||||
|
||||
if (nil == result)
|
||||
{
|
||||
result = [super alloc];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (nil != _channel) [self stop];
|
||||
|
||||
if (sFreeListCount < kFreeListMax)
|
||||
{
|
||||
// It’s OK to do locking after test since the count doesn’t need to be precise.
|
||||
[gOOCASoundSyncLock lock];
|
||||
_channel = (OOCASoundChannel *)sFreeList;
|
||||
sFreeList = self;
|
||||
_loop = NO;
|
||||
[gOOCASoundSyncLock unlock];
|
||||
return;
|
||||
}
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
- (void)positionRelativeTo:(OOSoundReferencePoint *)inPoint
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)setPositional:(BOOL)inPositional
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)setPosition:(Vector)inPosition
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)setVelocity:(Vector)inVelocity
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)setOrientation:(Vector)inOrientation
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)setConeAngle:(float)inAngle
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)setGainInsideCone:(float)inInside outsideCone:(float)inOutside
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)setLoop:(BOOL)inLoop
|
||||
{
|
||||
_loop = inLoop;
|
||||
}
|
||||
|
||||
|
||||
- (void)playSound:(OOSound *)inSound
|
||||
{
|
||||
[self playSound:inSound repeatCount:1];
|
||||
}
|
||||
|
||||
|
||||
- (void)playSound:(OOSound *)inSound repeatCount:(uint8_t)inCount
|
||||
{
|
||||
if (nil == inSound || 0 == inCount) return;
|
||||
|
||||
[gOOCASoundSyncLock lock];
|
||||
|
||||
if (nil != _channel)
|
||||
{
|
||||
[self stop];
|
||||
}
|
||||
|
||||
_channel = [[OOCASoundMixer mixer] popChannel];
|
||||
if (nil != _channel)
|
||||
{
|
||||
_playCount = inCount;
|
||||
_playing = YES;
|
||||
[_channel setDelegate:self];
|
||||
[_channel playSound:inSound];
|
||||
[self retain];
|
||||
}
|
||||
[gOOCASoundSyncLock unlock];
|
||||
}
|
||||
|
||||
|
||||
- (void)playOrRepeatSound:(OOSound *)inSound
|
||||
{
|
||||
if (nil == inSound) return;
|
||||
|
||||
[gOOCASoundSyncLock lock];
|
||||
if ([_channel sound] == inSound)
|
||||
{
|
||||
++_playCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
[self playSound:inSound repeatCount:1];
|
||||
}
|
||||
[gOOCASoundSyncLock unlock];
|
||||
}
|
||||
|
||||
|
||||
- (void)stop
|
||||
{
|
||||
[gOOCASoundSyncLock lock];
|
||||
if (nil != _channel)
|
||||
{
|
||||
[_channel setDelegate:[self class]];
|
||||
[_channel stop];
|
||||
_channel = nil;
|
||||
[self release];
|
||||
_playCount = 0;
|
||||
}
|
||||
|
||||
_playing = NO;
|
||||
[gOOCASoundSyncLock unlock];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isPlaying
|
||||
{
|
||||
return _playing;
|
||||
}
|
||||
|
||||
|
||||
- (void)channel:(OOCASoundChannel *)inChannel didFinishPlayingSound:(OOSound *)inSound
|
||||
{
|
||||
assert(_channel == inChannel);
|
||||
|
||||
[gOOCASoundSyncLock lock];
|
||||
if (_loop && _playing) ++_playCount;
|
||||
|
||||
if (--_playCount)
|
||||
{
|
||||
[_channel playSound:inSound];
|
||||
}
|
||||
else
|
||||
{
|
||||
[_channel setDelegate:nil];
|
||||
[[OOCASoundMixer mixer] pushChannel:_channel];
|
||||
_channel = nil;
|
||||
_playing = NO;
|
||||
[self release];
|
||||
}
|
||||
[gOOCASoundSyncLock unlock];
|
||||
}
|
||||
|
||||
|
||||
+ (void)channel:(OOCASoundChannel *)inChannel didFinishPlayingSound:(OOSound *)inSound
|
||||
{
|
||||
[[OOCASoundMixer mixer] pushChannel:inChannel];
|
||||
}
|
||||
|
||||
|
||||
@end
|
40
src/Cocoa/OOErrorDescription.h
Normal file
40
src/Cocoa/OOErrorDescription.h
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// OOErrorDescription.h
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
// Provide descriptions of various Mac-specific error codes
|
||||
NSString *OSStatusErrorNSString(OSStatus inCode);
|
||||
NSString *AudioErrorNSString(ComponentResult inCode);
|
||||
NSString *KernelResultNSString(kern_return_t inCode);
|
||||
NSString *FourCharCodeToNSString(FourCharCode inCode);
|
263
src/Cocoa/OOErrorDescription.m
Normal file
263
src/Cocoa/OOErrorDescription.m
Normal file
@ -0,0 +1,263 @@
|
||||
//
|
||||
// OOErrorDescription.m
|
||||
//
|
||||
/*
|
||||
|
||||
Copyright © 2005, Jens Ayton
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOErrorDescription.h"
|
||||
#import <CoreAudio/CoreAudio.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
|
||||
#define CASE(foo) case foo: return @#foo
|
||||
#define CASE2(foo, bar) case foo: return @ #foo"/"#bar
|
||||
#define CASE3(foo, bar, baz) case foo: return @ #foo"/"#bar"/"#baz
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
static NSString *GetGenericOSStatusString(OSStatus inCode);
|
||||
#endif
|
||||
|
||||
|
||||
NSString *OSStatusErrorNSString(OSStatus inCode)
|
||||
{
|
||||
NSString *result = nil;
|
||||
|
||||
#ifndef NDEBUG
|
||||
result = GetGenericOSStatusString(inCode);
|
||||
#else
|
||||
if (noErr == inCode) result = @"no error";
|
||||
#endif
|
||||
|
||||
if (nil == result) result = [NSString stringWithFormat:@"%i", (int)inCode];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
NSString *AudioErrorNSString(ComponentResult inCode)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
switch (inCode)
|
||||
{
|
||||
CASE(kAudioConverterErr_FormatNotSupported);
|
||||
CASE(kAudioConverterErr_OperationNotSupported);
|
||||
CASE(kAudioConverterErr_PropertyNotSupported);
|
||||
CASE(kAudioConverterErr_InvalidInputSize);
|
||||
CASE(kAudioConverterErr_InvalidOutputSize);
|
||||
CASE2(kAudioConverterErr_UnspecifiedError, kAudioCodecUnspecifiedError);
|
||||
CASE2(kAudioConverterErr_BadPropertySizeError, kAudioCodecBadPropertySizeError);
|
||||
CASE(kAudioConverterErr_RequiresPacketDescriptionsError);
|
||||
CASE(kAudioConverterErr_InputSampleRateOutOfRange);
|
||||
CASE(kAudioConverterErr_OutputSampleRateOutOfRange);
|
||||
|
||||
CASE(kAudioCodecUnknownPropertyError);
|
||||
CASE(kAudioCodecIllegalOperationError);
|
||||
CASE(kAudioCodecUnsupportedFormatError);
|
||||
CASE(kAudioCodecStateError);
|
||||
CASE(kAudioCodecNotEnoughBufferSpaceError);
|
||||
|
||||
CASE(kAudioUnitErr_InvalidProperty);
|
||||
CASE(kAudioUnitErr_InvalidParameter);
|
||||
CASE(kAudioUnitErr_InvalidElement);
|
||||
CASE(kAudioUnitErr_NoConnection);
|
||||
CASE(kAudioUnitErr_FailedInitialization);
|
||||
CASE(kAudioUnitErr_TooManyFramesToProcess);
|
||||
CASE(kAudioUnitErr_IllegalInstrument);
|
||||
CASE(kAudioUnitErr_InstrumentTypeNotFound);
|
||||
CASE(kAudioUnitErr_InvalidFile);
|
||||
CASE(kAudioUnitErr_UnknownFileType);
|
||||
CASE(kAudioUnitErr_FileNotSpecified);
|
||||
CASE(kAudioUnitErr_FormatNotSupported);
|
||||
CASE(kAudioUnitErr_Uninitialized);
|
||||
CASE(kAudioUnitErr_InvalidScope);
|
||||
CASE(kAudioUnitErr_PropertyNotWritable);
|
||||
CASE3(kAudioUnitErr_CannotDoInCurrentContext, kAUGraphErr_CannotDoInCurrentContext, kAUGraphErr_CannotDoInCurrentContext);
|
||||
CASE(kAudioUnitErr_InvalidPropertyValue);
|
||||
CASE(kAudioUnitErr_PropertyNotInUse);
|
||||
CASE(kAudioUnitErr_Initialized);
|
||||
CASE(kAudioUnitErr_InvalidOfflineRender);
|
||||
CASE(kAudioUnitErr_Unauthorized);
|
||||
|
||||
CASE(kAUGraphErr_NodeNotFound);
|
||||
CASE(kAUGraphErr_InvalidConnection);
|
||||
CASE(kAUGraphErr_OutputNodeErr);
|
||||
CASE(kAUGraphErr_InvalidAudioUnit);
|
||||
|
||||
default:
|
||||
{
|
||||
NSString *result = GetGenericOSStatusString(inCode);
|
||||
if (nil != result) return result;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (noErr == inCode) return @"no error";
|
||||
#endif
|
||||
|
||||
int high = inCode >> 24;
|
||||
if (high && ! (high & 0xFF))
|
||||
{
|
||||
// Assume a four-char code
|
||||
return [NSString stringWithFormat:@"\'%@\' (%i)", FourCharCodeToNSString(inCode), inCode];
|
||||
}
|
||||
else
|
||||
{
|
||||
return [NSString stringWithFormat:@"%i", (int)inCode];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NSString *KernelResultNSString(kern_return_t inCode)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
switch (inCode)
|
||||
{
|
||||
CASE(KERN_INVALID_ADDRESS);
|
||||
CASE(KERN_PROTECTION_FAILURE);
|
||||
CASE(KERN_NO_SPACE);
|
||||
CASE(KERN_INVALID_ARGUMENT);
|
||||
CASE(KERN_FAILURE);
|
||||
CASE(KERN_RESOURCE_SHORTAGE);
|
||||
CASE(KERN_NOT_RECEIVER);
|
||||
CASE(KERN_NO_ACCESS);
|
||||
CASE(KERN_MEMORY_FAILURE);
|
||||
CASE(KERN_MEMORY_ERROR);
|
||||
CASE(KERN_ALREADY_IN_SET);
|
||||
CASE(KERN_NOT_IN_SET);
|
||||
CASE(KERN_NAME_EXISTS);
|
||||
CASE(KERN_ABORTED);
|
||||
CASE(KERN_INVALID_NAME);
|
||||
CASE(KERN_INVALID_TASK);
|
||||
CASE(KERN_INVALID_RIGHT);
|
||||
CASE(KERN_INVALID_VALUE);
|
||||
CASE(KERN_UREFS_OVERFLOW);
|
||||
CASE(KERN_INVALID_CAPABILITY);
|
||||
CASE(KERN_RIGHT_EXISTS);
|
||||
CASE(KERN_INVALID_HOST);
|
||||
CASE(KERN_MEMORY_PRESENT);
|
||||
CASE(KERN_MEMORY_DATA_MOVED);
|
||||
CASE(KERN_MEMORY_RESTART_COPY);
|
||||
CASE(KERN_INVALID_PROCESSOR_SET);
|
||||
CASE(KERN_POLICY_LIMIT);
|
||||
CASE(KERN_INVALID_POLICY);
|
||||
CASE(KERN_INVALID_OBJECT);
|
||||
CASE(KERN_ALREADY_WAITING);
|
||||
CASE(KERN_DEFAULT_SET);
|
||||
CASE(KERN_EXCEPTION_PROTECTED);
|
||||
CASE(KERN_INVALID_LEDGER);
|
||||
CASE(KERN_INVALID_MEMORY_CONTROL);
|
||||
CASE(KERN_INVALID_SECURITY);
|
||||
CASE(KERN_NOT_DEPRESSED);
|
||||
CASE(KERN_TERMINATED);
|
||||
CASE(KERN_LOCK_SET_DESTROYED);
|
||||
CASE(KERN_LOCK_UNSTABLE);
|
||||
CASE(KERN_LOCK_OWNED);
|
||||
CASE(KERN_LOCK_OWNED_SELF);
|
||||
CASE(KERN_SEMAPHORE_DESTROYED);
|
||||
CASE(KERN_RPC_SERVER_TERMINATED);
|
||||
CASE(KERN_RPC_TERMINATE_ORPHAN);
|
||||
CASE(KERN_RPC_CONTINUE_ORPHAN);
|
||||
CASE(KERN_NOT_SUPPORTED);
|
||||
CASE(KERN_NODE_DOWN);
|
||||
CASE(KERN_NOT_WAITING);
|
||||
CASE(KERN_OPERATION_TIMED_OUT);
|
||||
CASE(MACH_MSG_IPC_SPACE);
|
||||
CASE(MACH_MSG_VM_SPACE);
|
||||
CASE(MACH_MSG_IPC_KERNEL);
|
||||
CASE(MACH_MSG_VM_KERNEL);
|
||||
CASE(MACH_SEND_IN_PROGRESS);
|
||||
CASE(MACH_SEND_INVALID_DATA);
|
||||
CASE(MACH_SEND_INVALID_DEST);
|
||||
CASE(MACH_SEND_TIMED_OUT);
|
||||
CASE(MACH_SEND_INTERRUPTED);
|
||||
CASE(MACH_SEND_MSG_TOO_SMALL);
|
||||
CASE(MACH_SEND_INVALID_REPLY);
|
||||
CASE(MACH_SEND_INVALID_RIGHT);
|
||||
CASE(MACH_SEND_INVALID_NOTIFY);
|
||||
CASE(MACH_SEND_INVALID_MEMORY);
|
||||
CASE(MACH_SEND_NO_BUFFER);
|
||||
CASE(MACH_SEND_TOO_LARGE);
|
||||
CASE(MACH_SEND_INVALID_TYPE);
|
||||
CASE(MACH_SEND_INVALID_HEADER);
|
||||
CASE(MACH_SEND_INVALID_TRAILER);
|
||||
CASE(MACH_SEND_INVALID_RT_OOL_SIZE);
|
||||
CASE(MACH_RCV_IN_PROGRESS);
|
||||
CASE(MACH_RCV_INVALID_NAME);
|
||||
CASE(MACH_RCV_TIMED_OUT);
|
||||
CASE(MACH_RCV_TOO_LARGE);
|
||||
CASE(MACH_RCV_INTERRUPTED);
|
||||
CASE(MACH_RCV_PORT_CHANGED);
|
||||
CASE(MACH_RCV_INVALID_NOTIFY);
|
||||
CASE(MACH_RCV_INVALID_DATA);
|
||||
CASE(MACH_RCV_PORT_DIED);
|
||||
CASE(MACH_RCV_IN_SET);
|
||||
CASE(MACH_RCV_HEADER_ERROR);
|
||||
CASE(MACH_RCV_BODY_ERROR);
|
||||
CASE(MACH_RCV_INVALID_TYPE);
|
||||
CASE(MACH_RCV_SCATTER_SMALL);
|
||||
CASE(MACH_RCV_INVALID_TRAILER);
|
||||
CASE(MACH_RCV_IN_PROGRESS_TIMED);
|
||||
|
||||
case 0: return @"no error";
|
||||
}
|
||||
#else
|
||||
if (0 == inCode) return @"no error";
|
||||
#endif
|
||||
|
||||
return [NSString stringWithFormat:@"0x%.8X", (unsigned)inCode];
|
||||
}
|
||||
|
||||
|
||||
NSString *FourCharCodeToNSString(FourCharCode inCode)
|
||||
{
|
||||
return [[[NSString alloc] initWithBytes:&inCode length:4 encoding:NSMacOSRomanStringEncoding] autorelease];
|
||||
}
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
static NSString *GetGenericOSStatusString(OSStatus inCode)
|
||||
{
|
||||
switch (inCode)
|
||||
{
|
||||
case noErr: return @"no error";
|
||||
|
||||
CASE(paramErr);
|
||||
CASE(memFullErr);
|
||||
CASE(unimpErr);
|
||||
CASE(userCanceledErr);
|
||||
CASE(dskFulErr);
|
||||
CASE(fnfErr);
|
||||
CASE(errFSBadFSRef);
|
||||
CASE(gestaltUnknownErr);
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
#endif
|
46
src/Cocoa/OoliteApp.h
Normal file
46
src/Cocoa/OoliteApp.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
|
||||
Oolite
|
||||
|
||||
OoliteApp.h
|
||||
|
||||
Created by Giles Williams on 01/05/2005.
|
||||
|
||||
|
||||
Copyright (c) 2005, Giles C Williams
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Noncommercial. You may not use this work for commercial purposes.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOCocoa.h"
|
||||
|
||||
|
||||
@interface OoliteApp : NSApplication {
|
||||
|
||||
}
|
||||
|
||||
@end
|
73
src/Cocoa/OoliteApp.m
Normal file
73
src/Cocoa/OoliteApp.m
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
|
||||
Oolite
|
||||
|
||||
OoliteApp.m
|
||||
|
||||
Created by Giles Williams on 01/05/2005.
|
||||
|
||||
|
||||
Copyright (c) 2005, Giles C Williams
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Noncommercial. You may not use this work for commercial purposes.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "OoliteApp.h"
|
||||
#import "GameController.h"
|
||||
#import "MyOpenGLView.h"
|
||||
|
||||
/*--
|
||||
This is a subclass of NSApplication for Oolite.
|
||||
|
||||
It gets around problems with the system intercepting certain events (NSKeyDown and NSKeyUp)
|
||||
before MyOpenGLView gets to see them, it does this by sending those events to MyOpenGLView
|
||||
regardless of any other processing NSApplication will do with them.
|
||||
--*/
|
||||
|
||||
@implementation OoliteApp
|
||||
|
||||
- (void)sendEvent:(NSEvent *)theEvent
|
||||
{
|
||||
NSEventType etype = [theEvent type];
|
||||
GameController* gameController = (GameController*)[self delegate];
|
||||
MyOpenGLView* gameView = (MyOpenGLView*)[gameController gameView];
|
||||
switch (etype)
|
||||
{
|
||||
case NSKeyDown:
|
||||
[gameView keyDown:theEvent]; // ensure this gets called at least once
|
||||
break;
|
||||
case NSKeyUp:
|
||||
[gameView keyUp:theEvent]; // ensure this gets called at least once
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
[super sendEvent:theEvent]; // perform the default event behaviour
|
||||
}
|
||||
|
||||
|
||||
@end
|
18
src/Cocoa/SoundInspector.nib/classes.nib
generated
Normal file
18
src/Cocoa/SoundInspector.nib/classes.nib
generated
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
IBClasses = (
|
||||
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{
|
||||
CLASS = OOCASoundMixer;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {
|
||||
checkBoxes = NSMatrix;
|
||||
currentField = NSTextField;
|
||||
loadBar = NSProgressIndicator;
|
||||
loadField = NSTextField;
|
||||
maxField = NSTextField;
|
||||
};
|
||||
SUPERCLASS = NSObject;
|
||||
}
|
||||
);
|
||||
IBVersion = 1;
|
||||
}
|
20
src/Cocoa/SoundInspector.nib/info.nib
generated
Normal file
20
src/Cocoa/SoundInspector.nib/info.nib
generated
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>677 140 356 240 0 0 1440 878 </string>
|
||||
<key>IBFramework Version</key>
|
||||
<string>443.0</string>
|
||||
<key>IBLockedObjects</key>
|
||||
<array>
|
||||
<integer>46</integer>
|
||||
</array>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>46</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>8F46</string>
|
||||
</dict>
|
||||
</plist>
|
BIN
src/Cocoa/SoundInspector.nib/keyedobjects.nib
generated
Normal file
BIN
src/Cocoa/SoundInspector.nib/keyedobjects.nib
generated
Normal file
Binary file not shown.
86
src/Cocoa/VirtualRingBuffer.h
Normal file
86
src/Cocoa/VirtualRingBuffer.h
Normal file
@ -0,0 +1,86 @@
|
||||
//
|
||||
// VirtualRingBuffer.h
|
||||
// PlayBufferedSoundFile
|
||||
//
|
||||
/*
|
||||
Copyright (c) 2002, Kurt Revis. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Snoize nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//
|
||||
// VirtualRingBuffer implements a classic ring buffer (or circular buffer), with a couple of twists.
|
||||
//
|
||||
// * It allows reads and writes to happen in different threads, with no explicit locking,
|
||||
// so readers and writers will never block. This is useful if either thread uses the
|
||||
// time-constraint scheduling policy, since it is bad for such threads to block for
|
||||
// indefinite amounts of time.
|
||||
//
|
||||
// * It uses a virtual memory trick to allow the client to read or write using just one
|
||||
// operation, even if the data involved wraps around the end of the buffer. We allocate
|
||||
// our buffer normally, and then place a VM region immediately after it in the address
|
||||
// space which maps back to the "real" buffer. So reads and writes into both sections
|
||||
// are transparently translated into the same physical memory.
|
||||
// This makes the API much simpler to use, and saves us from doing some math to
|
||||
// calculate the wraparound points.
|
||||
// The tradeoff is that we use twice as much address space for the buffer than we would
|
||||
// otherwise. Address space is not typically constrained for most applications, though,
|
||||
// so this isn't a big problem.
|
||||
// The idea for this trick came from <http://phil.ipal.org/freeware/vrb/> (via sweetcode.org),
|
||||
// although none of that code is used here. (We use the Mach VM API directly.)
|
||||
//
|
||||
|
||||
// Threading note:
|
||||
// It is expected that this object will be shared between exactly two threads; one will
|
||||
// always read and the other will always write. In that situation, the implementation is
|
||||
// thread-safe, and this object will never block or yield.
|
||||
// It will also work in one thread, of course (although I don't know why you'd bother).
|
||||
// However, if you have multiple reader or writer threads, all bets are off!
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
@interface VirtualRingBuffer : NSObject
|
||||
{
|
||||
void *buffer;
|
||||
void *bufferEnd;
|
||||
UInt32 bufferLength;
|
||||
// buffer is the start of the ring buffer's address space.
|
||||
// bufferEnd is the end of the "real" buffer (always buffer + bufferLength).
|
||||
// Note that the "virtual" portion of the buffer extends from bufferEnd to bufferEnd+bufferLength.
|
||||
|
||||
void *readPointer;
|
||||
void *writePointer;
|
||||
}
|
||||
|
||||
- (id)initWithLength:(UInt32)length;
|
||||
// Note: The specified length will be rounded up to an integral number of VM pages.
|
||||
|
||||
// Empties the buffer. It is NOT safe to do this while anyone is reading from or writing to the buffer.
|
||||
- (void)empty;
|
||||
// Checks if the buffer is empty or not. This is safe in any thread.
|
||||
- (BOOL)isEmpty;
|
||||
|
||||
// Read operations:
|
||||
|
||||
// The reading thread must call this method first.
|
||||
- (UInt32)lengthAvailableToReadReturningPointer:(void **)returnedReadPointer;
|
||||
// Iff a value > 0 is returned, the reading thread may go on to read that much data from the returned pointer.
|
||||
// Afterwards, the reading thread must call didReadLength:.
|
||||
- (void)didReadLength:(UInt32)length;
|
||||
|
||||
// Write operations:
|
||||
|
||||
// The writing thread must call this method first.
|
||||
- (UInt32)lengthAvailableToWriteReturningPointer:(void **)returnedWritePointer;
|
||||
// Iff a value > 0 is returned, the writing thread may then write that much data into the returned pointer.
|
||||
// Afterwards, the writing thread must call didWriteLength:.
|
||||
- (void)didWriteLength:(UInt32)length;
|
||||
|
||||
@end
|
315
src/Cocoa/VirtualRingBuffer.m
Normal file
315
src/Cocoa/VirtualRingBuffer.m
Normal file
@ -0,0 +1,315 @@
|
||||
//
|
||||
// VirtualRingBuffer.m
|
||||
// PlayBufferedSoundFile
|
||||
//
|
||||
/*
|
||||
Copyright (c) 2002, Kurt Revis. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Snoize nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "VirtualRingBuffer.h"
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_error.h>
|
||||
|
||||
|
||||
@implementation VirtualRingBuffer
|
||||
|
||||
static void *allocateVirtualBuffer(UInt32 bufferLength);
|
||||
static void deallocateVirtualBuffer(void *buffer, UInt32 bufferLength);
|
||||
|
||||
|
||||
- (id)initWithLength:(UInt32)length
|
||||
{
|
||||
if (![super init])
|
||||
return nil;
|
||||
|
||||
// We need to allocate entire VM pages, so round the specified length up to the next page if necessary.
|
||||
bufferLength = round_page(length);
|
||||
|
||||
buffer = allocateVirtualBuffer(bufferLength);
|
||||
if (buffer) {
|
||||
bufferEnd = buffer + bufferLength;
|
||||
} else {
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
|
||||
readPointer = NULL;
|
||||
writePointer = NULL;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (buffer)
|
||||
deallocateVirtualBuffer(buffer, bufferLength);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)empty
|
||||
{
|
||||
// Assumption:
|
||||
// No one is reading or writing from the buffer, in any thread, when this method is called.
|
||||
|
||||
readPointer = NULL;
|
||||
writePointer = NULL;
|
||||
}
|
||||
|
||||
- (BOOL)isEmpty
|
||||
{
|
||||
return (readPointer != NULL && writePointer != NULL);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Theory of operation:
|
||||
//
|
||||
// This class keeps a pointer to the next byte to be read (readPointer) and a pointer to the next byte to be written (writePointer).
|
||||
// readPointer is only advanced in the reading thread (except for one case: when the buffer first has data written to it).
|
||||
// writePointer is only advanced in the writing thread.
|
||||
//
|
||||
// Since loading and storing word length data is atomic, each pointer can safely be modified in one thread while the other thread
|
||||
// uses it, IF each thread is careful to make a local copy of the "opposite" pointer when necessary.
|
||||
//
|
||||
|
||||
//
|
||||
// Read operations
|
||||
//
|
||||
|
||||
- (UInt32)lengthAvailableToReadReturningPointer:(void **)returnedReadPointer
|
||||
{
|
||||
// Assumptions:
|
||||
// returnedReadPointer != NULL
|
||||
|
||||
UInt32 length;
|
||||
// Read this pointer exactly once, so we're safe in case it is changed in another thread
|
||||
void *localWritePointer = writePointer;
|
||||
|
||||
// Depending on out-of-order execution and memory storage, either one of these may be NULL when the buffer is empty. So we must check both.
|
||||
if (!readPointer || !localWritePointer) {
|
||||
// The buffer is empty
|
||||
length = 0;
|
||||
} else if (localWritePointer > readPointer) {
|
||||
// Write is ahead of read in the buffer
|
||||
length = localWritePointer - readPointer;
|
||||
} else {
|
||||
// Write has wrapped around past read, OR write == read (the buffer is full)
|
||||
length = bufferLength - (readPointer - localWritePointer);
|
||||
}
|
||||
|
||||
*returnedReadPointer = readPointer;
|
||||
return length;
|
||||
}
|
||||
|
||||
- (void)didReadLength:(UInt32)length
|
||||
{
|
||||
// Assumptions:
|
||||
// [self lengthAvailableToReadReturningPointer:] currently returns a value >= length
|
||||
// length > 0
|
||||
|
||||
void *newReadPointer;
|
||||
|
||||
newReadPointer = readPointer + length;
|
||||
if (newReadPointer >= bufferEnd)
|
||||
newReadPointer -= bufferLength;
|
||||
|
||||
if (newReadPointer == writePointer) {
|
||||
// We just read the last data out of the buffer, so it is now empty.
|
||||
newReadPointer = NULL;
|
||||
}
|
||||
|
||||
// Store the new read pointer. This is the only place this happens in the read thread.
|
||||
readPointer = newReadPointer;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Write operations
|
||||
//
|
||||
|
||||
- (UInt32)lengthAvailableToWriteReturningPointer:(void **)returnedWritePointer
|
||||
{
|
||||
// Assumptions:
|
||||
// returnedWritePointer != NULL
|
||||
|
||||
UInt32 length;
|
||||
// Read this pointer exactly once, so we're safe in case it is changed in another thread
|
||||
void *localReadPointer = readPointer;
|
||||
|
||||
// Either one of these may be NULL when the buffer is empty. So we must check both.
|
||||
if (!localReadPointer || !writePointer) {
|
||||
// The buffer is empty. Set it up to be written into.
|
||||
// This is one of the two places the write pointer can change; both are in the write thread.
|
||||
writePointer = buffer;
|
||||
length = bufferLength;
|
||||
} else if (writePointer <= localReadPointer) {
|
||||
// Write is before read in the buffer, OR write == read (meaning that the buffer is full).
|
||||
length = localReadPointer - writePointer;
|
||||
} else {
|
||||
// Write is behind read in the buffer. The available space wraps around.
|
||||
length = (bufferEnd - writePointer) + (localReadPointer - buffer);
|
||||
}
|
||||
|
||||
*returnedWritePointer = writePointer;
|
||||
return length;
|
||||
}
|
||||
|
||||
- (void)didWriteLength:(UInt32)length
|
||||
{
|
||||
// Assumptions:
|
||||
// [self lengthAvailableToWriteReturningPointer:] currently returns a value >= length
|
||||
// length > 0
|
||||
|
||||
void *oldWritePointer = writePointer;
|
||||
void *newWritePointer;
|
||||
|
||||
// Advance the write pointer, wrapping around if necessary.
|
||||
newWritePointer = writePointer + length;
|
||||
if (newWritePointer >= bufferEnd)
|
||||
newWritePointer -= bufferLength;
|
||||
|
||||
// This is one of the two places the write pointer can change; both are in the write thread.
|
||||
writePointer = newWritePointer;
|
||||
|
||||
// Also, if the read pointer is NULL, then we just wrote into a previously empty buffer, so set the read pointer.
|
||||
// This is the only place the read pointer is changed in the write thread.
|
||||
// The read thread should never change the read pointer when it is NULL, so this is safe.
|
||||
if (!readPointer)
|
||||
readPointer = oldWritePointer;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
void *allocateVirtualBuffer(UInt32 bufferLength)
|
||||
{
|
||||
kern_return_t error;
|
||||
vm_address_t originalAddress = 0;
|
||||
vm_address_t realAddress = 0;
|
||||
mach_port_t memoryEntry;
|
||||
vm_size_t memoryEntryLength;
|
||||
vm_address_t virtualAddress = 0;
|
||||
|
||||
// We want to find where we can get 2 * bufferLength bytes of contiguous address space.
|
||||
// So let's just allocate that space, remember its address, and deallocate it.
|
||||
// (This doesn't actually have to touch all of that memory so it's not terribly expensive.)
|
||||
error = vm_allocate(mach_task_self(), &originalAddress, 2 * bufferLength, TRUE);
|
||||
if (error) {
|
||||
#if DEBUG
|
||||
mach_error("vm_allocate initial chunk", error);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
error = vm_deallocate(mach_task_self(), originalAddress, 2 * bufferLength);
|
||||
if (error) {
|
||||
#if DEBUG
|
||||
mach_error("vm_deallocate initial chunk", error);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Then allocate a "real" block of memory at the same address, but with the normal bufferLength.
|
||||
realAddress = originalAddress;
|
||||
error = vm_allocate(mach_task_self(), &realAddress, bufferLength, FALSE);
|
||||
if (error) {
|
||||
#if DEBUG
|
||||
mach_error("vm_allocate real chunk", error);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
if (realAddress != originalAddress) {
|
||||
#if DEBUG
|
||||
NSLog(@"allocateVirtualBuffer: vm_allocate 2nd time didn't return same address (%p vs %p)", originalAddress, realAddress);
|
||||
#endif
|
||||
goto errorReturn;
|
||||
}
|
||||
|
||||
// Then make a memory entry for the area we just allocated.
|
||||
memoryEntryLength = bufferLength;
|
||||
error = mach_make_memory_entry(mach_task_self(), &memoryEntryLength, realAddress, VM_PROT_READ | VM_PROT_WRITE, &memoryEntry, 0);
|
||||
if (error) {
|
||||
#if DEBUG
|
||||
mach_error("mach_make_memory_entry", error);
|
||||
#endif
|
||||
goto errorReturn;
|
||||
}
|
||||
if (!memoryEntry) {
|
||||
#if DEBUG
|
||||
NSLog(@"mach_make_memory_entry: returned memoryEntry of NULL");
|
||||
#endif
|
||||
goto errorReturn;
|
||||
}
|
||||
if (memoryEntryLength != bufferLength) {
|
||||
#if DEBUG
|
||||
NSLog(@"mach_make_memory_entry: size changed (from %0x to %0x)", bufferLength, memoryEntryLength);
|
||||
#endif
|
||||
goto errorReturn;
|
||||
}
|
||||
|
||||
// And map the area immediately after the first block, with length bufferLength, to that memory entry.
|
||||
virtualAddress = realAddress + bufferLength;
|
||||
error = vm_map(mach_task_self(), &virtualAddress, bufferLength, 0, FALSE, memoryEntry, 0, FALSE, VM_PROT_READ | VM_PROT_WRITE, VM_PROT_READ | VM_PROT_WRITE, VM_INHERIT_DEFAULT);
|
||||
if (error) {
|
||||
#if DEBUG
|
||||
mach_error("vm_map", error);
|
||||
#endif
|
||||
// TODO Retry from the beginning, instead of failing completely. There is a tiny (but > 0) probability that someone
|
||||
// will allocate this space out from under us.
|
||||
virtualAddress = 0;
|
||||
goto errorReturn;
|
||||
}
|
||||
if (virtualAddress != realAddress + bufferLength) {
|
||||
#if DEBUG
|
||||
NSLog(@"vm_map: didn't return correct address (%p vs %p)", realAddress + bufferLength, virtualAddress);
|
||||
#endif
|
||||
goto errorReturn;
|
||||
}
|
||||
|
||||
// Success!
|
||||
return (void *)realAddress;
|
||||
|
||||
#if DEBUG
|
||||
// Here's a little test...
|
||||
*realAddress = '?';
|
||||
if (*virtualAddress != '?')
|
||||
NSLog(@"VirtualRingBuffer: Test 1: vm magic failed");
|
||||
|
||||
*(virtualAddress + 1) = '!';
|
||||
if (*(realAddress + 1) != '!')
|
||||
NSLog(@"VirtualRingBuffer: Test 2: vm magic failed");
|
||||
#endif
|
||||
|
||||
errorReturn:
|
||||
if (realAddress)
|
||||
vm_deallocate(mach_task_self(), realAddress, bufferLength);
|
||||
if (virtualAddress)
|
||||
vm_deallocate(mach_task_self(), virtualAddress, bufferLength);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void deallocateVirtualBuffer(void *buffer, UInt32 bufferLength)
|
||||
{
|
||||
kern_return_t error;
|
||||
|
||||
// We can conveniently deallocate both the vm_allocated memory and
|
||||
// the vm_mapped region at the same time.
|
||||
error = vm_deallocate(mach_task_self(), (vm_address_t)buffer, bufferLength * 2);
|
||||
if (error) {
|
||||
#if DEBUG
|
||||
mach_error("vm_deallocate in dealloc", error);
|
||||
#endif
|
||||
}
|
||||
}
|
10
src/Cocoa/main.m
Normal file
10
src/Cocoa/main.m
Normal file
@ -0,0 +1,10 @@
|
||||
//#import <Foundation/Foundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
BOOL debug = NO;
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
return NSApplicationMain(argc, argv);
|
||||
}
|
||||
|
@ -63,6 +63,8 @@ extern int debug;
|
||||
|
||||
}
|
||||
|
||||
- (id) prepare;
|
||||
|
||||
- (id) initWithStateMachine:(NSString *) smName andState:(NSString *) stateName;
|
||||
|
||||
- (void) setOwner:(ShipEntity *)ship;
|
@ -44,23 +44,31 @@ Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
@implementation AI
|
||||
|
||||
- (id) init
|
||||
{
|
||||
self = [super init];
|
||||
//
|
||||
ai_stack = [[NSMutableArray alloc] initWithCapacity:8];
|
||||
//
|
||||
pendingMessages = [[NSMutableArray alloc] initWithCapacity:16]; // alloc retains
|
||||
//
|
||||
nextThinkTime = 0.0;
|
||||
//
|
||||
- (id) prepare
|
||||
{
|
||||
aiLock = [[NSLock alloc] init];
|
||||
//
|
||||
[aiLock lock]; // protect from asynchronous access
|
||||
//
|
||||
ai_stack = [[NSMutableArray alloc] init]; // retained
|
||||
//
|
||||
pendingMessages = [[NSMutableArray alloc] init]; // retained
|
||||
//
|
||||
nextThinkTime = [[NSDate distantFuture] timeIntervalSinceNow]; // don't think for a while
|
||||
//
|
||||
thinkTimeInterval = AI_THINK_INTERVAL;
|
||||
//
|
||||
stateMachine = nil;
|
||||
stateMachine = nil; // no initial brain
|
||||
//
|
||||
return self;
|
||||
[aiLock unlock]; // okay now we're ready...
|
||||
//
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
self = [super init];
|
||||
return [self prepare];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
@ -84,13 +92,13 @@ Your fair use and other rights are in no way affected by the above.
|
||||
{
|
||||
self = [super init];
|
||||
//
|
||||
pendingMessages = [[NSMutableArray alloc] initWithCapacity:16]; // alloc retains
|
||||
[self prepare];
|
||||
//
|
||||
aiLock = [[NSLock alloc] init];
|
||||
if (smName)
|
||||
[self setStateMachine:smName];
|
||||
//
|
||||
[self setStateMachine:smName];
|
||||
//
|
||||
currentState = [stateName retain];
|
||||
if (stateName)
|
||||
currentState = [stateName retain];
|
||||
//
|
||||
return self;
|
||||
}
|
||||
@ -104,14 +112,30 @@ Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
- (void) preserveCurrentStateMachine
|
||||
{
|
||||
if (!stateMachine)
|
||||
return;
|
||||
|
||||
NSMutableDictionary *pickledMachine = [NSMutableDictionary dictionaryWithCapacity:3];
|
||||
[pickledMachine setObject:stateMachine forKey:@"stateMachine"];
|
||||
[pickledMachine setObject:currentState forKey:@"currentState"];
|
||||
[pickledMachine setObject:pendingMessages forKey:@"pendingMessages"];
|
||||
|
||||
// use copies because the currently referenced objects might change
|
||||
[pickledMachine setObject:[NSDictionary dictionaryWithDictionary: stateMachine] forKey:@"stateMachine"];
|
||||
[pickledMachine setObject:[NSString stringWithString: currentState] forKey:@"currentState"];
|
||||
[pickledMachine setObject:[NSArray arrayWithArray: pendingMessages] forKey:@"pendingMessages"];
|
||||
|
||||
if (!ai_stack)
|
||||
ai_stack = [[NSMutableArray alloc] initWithCapacity:8];
|
||||
|
||||
if ([ai_stack count] > 32)
|
||||
{
|
||||
NSLog(@"***** ERROR: AI stack overflow for %@ stack:\n%@", owner, ai_stack);
|
||||
NSException *myException = [NSException
|
||||
exceptionWithName:@"OoliteException"
|
||||
reason:[NSString stringWithFormat:@"AI stack overflow for %@", owner]
|
||||
userInfo:nil];
|
||||
[myException raise];
|
||||
return;
|
||||
}
|
||||
|
||||
[ai_stack insertObject:pickledMachine atIndex:0]; // PUSH
|
||||
}
|
||||
|
||||
@ -151,19 +175,25 @@ Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
- (void) setStateMachine:(NSString *) smName
|
||||
{
|
||||
//
|
||||
//
|
||||
[aiLock lock];
|
||||
//
|
||||
if (stateMachine)
|
||||
NSDictionary* newSM = [ResourceManager dictionaryFromFilesNamed:smName inFolder:@"AIs" andMerge:NO];
|
||||
//
|
||||
if (newSM)
|
||||
{
|
||||
[self preserveCurrentStateMachine];
|
||||
[stateMachine release];
|
||||
}
|
||||
stateMachine = [[ResourceManager dictionaryFromFilesNamed:smName inFolder:@"AIs" andMerge:NO] retain];
|
||||
if (stateMachine)
|
||||
[stateMachine release]; // release old state machine
|
||||
stateMachine = [newSM retain];
|
||||
nextThinkTime = 0.0; // think at next tick
|
||||
}
|
||||
//
|
||||
[aiLock unlock];
|
||||
//
|
||||
[self setState:@"GLOBAL"];
|
||||
if (currentState) [currentState release];
|
||||
currentState = [[NSString stringWithString:@"GLOBAL"] retain];
|
||||
[self reactToMessage:@"ENTER"];
|
||||
//
|
||||
//NSLog(@"AI Loaded:\n%@",[stateMachine description]);
|
||||
//
|
||||
@ -201,10 +231,18 @@ Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
if (!message)
|
||||
return;
|
||||
|
||||
//
|
||||
if (!owner)
|
||||
return;
|
||||
//
|
||||
if ([owner universal_id] == NO_TARGET) // don't think until launched
|
||||
return;
|
||||
//
|
||||
if (!stateMachine)
|
||||
return;
|
||||
//
|
||||
if (![stateMachine objectForKey:currentState])
|
||||
return;
|
||||
|
||||
[aiLock lock];
|
||||
//
|
||||
@ -235,7 +273,6 @@ Your fair use and other rights are in no way affected by the above.
|
||||
if ([owner respondsToSelector:_interpretAIMessageSel])
|
||||
[owner performSelector:_interpretAIMessageSel withObject:message];
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -258,7 +295,6 @@ Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
if ([tokens count] > 1)
|
||||
{
|
||||
// dataString = (NSString *)[tokens objectAtIndex:1];
|
||||
dataString = [[tokens subarrayWithRange:NSMakeRange(1, [tokens count] - 1)] componentsJoinedByString:@" "];
|
||||
}
|
||||
|
||||
@ -295,15 +331,21 @@ Your fair use and other rights are in no way affected by the above.
|
||||
return;
|
||||
//
|
||||
|
||||
if (!stateMachine) // don't think until launched
|
||||
return;
|
||||
//
|
||||
|
||||
[self reactToMessage:@"UPDATE"];
|
||||
|
||||
[aiLock lock];
|
||||
if (pendingMessages)
|
||||
if ([pendingMessages retain])
|
||||
{
|
||||
//NSLog(@"debug1");
|
||||
ms_list = [NSArray arrayWithArray:pendingMessages];
|
||||
if ([pendingMessages count] > 0)
|
||||
ms_list = [NSArray arrayWithArray:pendingMessages];
|
||||
//NSLog(@"debug2");
|
||||
[pendingMessages removeAllObjects];
|
||||
[pendingMessages release];
|
||||
}
|
||||
[aiLock unlock];
|
||||
|
||||
@ -332,6 +374,9 @@ Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
- (double) nextThinkTime
|
||||
{
|
||||
if (!stateMachine)
|
||||
return [[NSDate distantFuture] timeIntervalSinceNow];
|
||||
|
||||
return nextThinkTime;
|
||||
}
|
||||
|
94
src/Core/CollisionRegion.h
Normal file
94
src/Core/CollisionRegion.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
|
||||
Oolite
|
||||
|
||||
CollisionRegion.h
|
||||
|
||||
Created by Giles Williams on 01/03/2006.
|
||||
|
||||
|
||||
Copyright (c) 2005, Giles C Williams
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Noncommercial. You may not use this work for commercial purposes.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOCocoa.h"
|
||||
#import "vector.h"
|
||||
|
||||
#define COLLISION_REGION_BORDER_RADIUS 32000.0f
|
||||
#define COLLISION_MAX_ENTITIES 128
|
||||
|
||||
@class Entity, Universe;
|
||||
|
||||
@interface CollisionRegion : NSObject {
|
||||
|
||||
@public
|
||||
|
||||
BOOL isUniverse; // if YES location is origin and radius is 0.0f
|
||||
|
||||
Vector location; // center of the region
|
||||
GLfloat radius; // inner radius of the region
|
||||
GLfloat border_radius; // additiønal, border radius of the region (typically 32km or some value > the scanner range)
|
||||
|
||||
NSMutableArray* subregions;
|
||||
|
||||
@protected
|
||||
|
||||
Entity** entity_array; // entities within the region
|
||||
int n_entities; // number of entities
|
||||
int max_entities; // so storage can be expanded
|
||||
|
||||
CollisionRegion* parentRegion;
|
||||
|
||||
}
|
||||
|
||||
- (id) initAsUniverse;
|
||||
- (id) initAtLocation:(Vector) locn withRadius:(GLfloat) rad withinRegion:(CollisionRegion*) otherRegion;
|
||||
|
||||
- (void) clearSubregions;
|
||||
- (void) addSubregionAtPosition:(Vector) pos withRadius:(GLfloat) rad;
|
||||
|
||||
// update routines to check if a position is within the radius or within it's borders
|
||||
//
|
||||
BOOL positionIsWithinRegion( Vector position, CollisionRegion* region);
|
||||
BOOL sphereIsWithinRegion( Vector position, GLfloat rad, CollisionRegion* region);
|
||||
BOOL positionIsWithinBorders( Vector position, CollisionRegion* region);
|
||||
BOOL positionIsOnBorders( Vector position, CollisionRegion* region);
|
||||
NSArray* subregionsContainingPosition( Vector position, CollisionRegion* region);
|
||||
|
||||
// collision checking
|
||||
//
|
||||
- (void) clearEntityList;
|
||||
- (void) addEntity:(Entity*) ent;
|
||||
//
|
||||
- (BOOL) checkEntity:(Entity*) ent;
|
||||
//
|
||||
- (void) findCollisionsInUniverse:(Universe*) universe;
|
||||
|
||||
- (NSString*) debugOut;
|
||||
|
||||
@end
|
402
src/Core/CollisionRegion.m
Normal file
402
src/Core/CollisionRegion.m
Normal file
@ -0,0 +1,402 @@
|
||||
/*
|
||||
|
||||
Oolite
|
||||
|
||||
CollisionRegion.m
|
||||
|
||||
Created by Giles Williams on 01/03/2006.
|
||||
|
||||
|
||||
Copyright (c) 2005, Giles C Williams
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Noncommercial. You may not use this work for commercial purposes.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "CollisionRegion.h"
|
||||
#import "vector.h"
|
||||
#import "Universe.h"
|
||||
#import "Entity.h"
|
||||
|
||||
|
||||
@implementation CollisionRegion
|
||||
|
||||
- (NSString*) description
|
||||
{
|
||||
int n_subs = [subregions count];
|
||||
NSMutableString* result = [[NSMutableString alloc] initWithFormat:@"<CollisionRegion containing %d subregions and %d entities:", n_subs, n_entities];
|
||||
int i;
|
||||
for (i = 0; i < n_subs; i++)
|
||||
[result appendFormat:@" %@", [subregions objectAtIndex:i]];
|
||||
[result appendString:@" >"];
|
||||
return [result autorelease];
|
||||
}
|
||||
|
||||
// basic alloc/ dealloc routines
|
||||
//
|
||||
- (id) initAsUniverse
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
location = make_vector( 0.0f, 0.0f, 0.0f);
|
||||
radius = 0.0f;
|
||||
border_radius = 0.0f;
|
||||
isUniverse = YES;
|
||||
|
||||
max_entities = COLLISION_MAX_ENTITIES;
|
||||
n_entities = 0;
|
||||
entity_array = (Entity**) malloc( max_entities * sizeof(Entity*));
|
||||
|
||||
subregions = [[NSMutableArray alloc] initWithCapacity: 32]; // retained
|
||||
|
||||
parentRegion = nil;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initAtLocation:(Vector) locn withRadius:(GLfloat) rad withinRegion:(CollisionRegion*) otherRegion
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
location = locn;
|
||||
radius = rad;
|
||||
border_radius = COLLISION_REGION_BORDER_RADIUS;
|
||||
isUniverse = NO;
|
||||
|
||||
max_entities = COLLISION_MAX_ENTITIES;
|
||||
n_entities = 0;
|
||||
entity_array = (Entity**) malloc( max_entities * sizeof(Entity*));
|
||||
|
||||
subregions = [[NSMutableArray alloc] initWithCapacity: 32]; // retained
|
||||
|
||||
if (otherRegion)
|
||||
parentRegion = otherRegion;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (entity_array)
|
||||
free((void *)entity_array); // free up the allocated space
|
||||
if (subregions)
|
||||
[subregions release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) clearSubregions
|
||||
{
|
||||
int i;
|
||||
int n_subs = [subregions count];
|
||||
for (i = 0; i < n_subs; i++)
|
||||
[(CollisionRegion*)[subregions objectAtIndex: i] clearSubregions];
|
||||
[subregions removeAllObjects];
|
||||
}
|
||||
|
||||
- (void) addSubregionAtPosition:(Vector) pos withRadius:(GLfloat) rad
|
||||
{
|
||||
// check if this can be fitted within any of the subregions
|
||||
//
|
||||
int i;
|
||||
int n_subs = [subregions count];
|
||||
for (i = 0; i < n_subs; i++)
|
||||
{
|
||||
CollisionRegion* sub = (CollisionRegion*)[subregions objectAtIndex: i];
|
||||
if (sphereIsWithinRegion( pos, rad, sub))
|
||||
{
|
||||
// if it fits, put it in!
|
||||
[sub addSubregionAtPosition: pos withRadius: rad];
|
||||
return;
|
||||
}
|
||||
if (positionIsWithinRegion( pos, sub))
|
||||
{
|
||||
// crosses the border of this region already - leave it out
|
||||
return;
|
||||
}
|
||||
}
|
||||
// no subregion fit - move on...
|
||||
//
|
||||
CollisionRegion* sub = [[CollisionRegion alloc] initAtLocation: pos withRadius: rad withinRegion: self];
|
||||
[subregions addObject:sub];
|
||||
[sub release];
|
||||
}
|
||||
|
||||
|
||||
// update routines to check if a position is within the radius or within it's borders
|
||||
//
|
||||
BOOL positionIsWithinRegion( Vector position, CollisionRegion* region)
|
||||
{
|
||||
if (!region)
|
||||
return NO;
|
||||
|
||||
if (region->isUniverse)
|
||||
return YES;
|
||||
|
||||
Vector loc = region->location;
|
||||
GLfloat r1 = region->radius;
|
||||
|
||||
if ((position.x < loc.x - r1)||(position.x > loc.x + r1)||
|
||||
(position.y < loc.y - r1)||(position.y > loc.y + r1)||
|
||||
(position.z < loc.z - r1)||(position.z > loc.z + r1))
|
||||
return NO;
|
||||
|
||||
// return (magnitude2(vector_between( position, loc)) < r1 * r1);
|
||||
return YES;
|
||||
}
|
||||
|
||||
BOOL sphereIsWithinRegion( Vector position, GLfloat rad, CollisionRegion* region)
|
||||
{
|
||||
if (!region)
|
||||
return NO;
|
||||
|
||||
if (region->isUniverse)
|
||||
return YES;
|
||||
|
||||
Vector loc = region->location;
|
||||
GLfloat r1 = region->radius;
|
||||
|
||||
if ((position.x - rad < loc.x - r1)||(position.x + rad > loc.x + r1)||
|
||||
(position.y - rad < loc.y - r1)||(position.y + rad > loc.y + r1)||
|
||||
(position.z - rad < loc.z - r1)||(position.z + rad > loc.z + r1))
|
||||
return NO;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
BOOL positionIsWithinBorders( Vector position, CollisionRegion* region)
|
||||
{
|
||||
if (!region)
|
||||
return NO;
|
||||
|
||||
if (region->isUniverse)
|
||||
return YES;
|
||||
|
||||
Vector loc = region->location;
|
||||
GLfloat r1 = region->radius + region->border_radius;
|
||||
|
||||
if ((position.x < loc.x - r1)||(position.x > loc.x + r1)||
|
||||
(position.y < loc.y - r1)||(position.y > loc.y + r1)||
|
||||
(position.z < loc.z - r1)||(position.z > loc.z + r1))
|
||||
return NO;
|
||||
|
||||
// return (magnitude2(vector_between( position, loc)) < r1 * r1);
|
||||
return YES;
|
||||
}
|
||||
|
||||
BOOL positionIsOnBorders( Vector position, CollisionRegion* region)
|
||||
{
|
||||
if (!region)
|
||||
return NO;
|
||||
|
||||
if (region->isUniverse)
|
||||
return NO;
|
||||
|
||||
Vector loc = region->location;
|
||||
// GLfloat r1 = region->radius;
|
||||
GLfloat r2 = region->radius + region->border_radius;
|
||||
|
||||
if ((position.x < loc.x - r2)||(position.x > loc.x + r2)||
|
||||
(position.y < loc.y - r2)||(position.y > loc.y + r2)||
|
||||
(position.z < loc.z - r2)||(position.z > loc.z + r2))
|
||||
return NO;
|
||||
|
||||
// GLfloat d2 = magnitude2(vector_between( position, loc));
|
||||
//
|
||||
// return ((d2 > r1 * r1)&&(d2 < r2 * r2));
|
||||
return (!positionIsWithinRegion( position, region));
|
||||
}
|
||||
|
||||
NSArray* subregionsContainingPosition( Vector position, CollisionRegion* region)
|
||||
{
|
||||
NSArray* subs = region->subregions;
|
||||
NSMutableArray* result = [NSMutableArray array]; // autoreleased
|
||||
|
||||
if (!subs)
|
||||
return result; // empty array
|
||||
|
||||
int i;
|
||||
int n_subs = [subs count];
|
||||
for (i = 0; i < n_subs; i++)
|
||||
if (positionIsWithinBorders( position, (CollisionRegion*)[subs objectAtIndex: i]))
|
||||
[result addObject: [subs objectAtIndex: i]];
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// collision checking
|
||||
//
|
||||
- (void) clearEntityList
|
||||
{
|
||||
n_entities = 0;
|
||||
int i;
|
||||
int n_subs = [subregions count];
|
||||
for (i = 0; i < n_subs; i++)
|
||||
[(CollisionRegion*)[subregions objectAtIndex: i] clearEntityList];
|
||||
}
|
||||
|
||||
- (void) addEntity:(Entity*) ent
|
||||
{
|
||||
// expand if necessary
|
||||
//
|
||||
if (n_entities == max_entities)
|
||||
{
|
||||
max_entities = 1 + max_entities * 2;
|
||||
Entity** new_store = (Entity**) malloc( max_entities * sizeof(Entity*));
|
||||
int i;
|
||||
for (i = 0; i < n_entities; i++)
|
||||
new_store[i] = entity_array[i];
|
||||
free( (void*)entity_array);
|
||||
entity_array = new_store;
|
||||
}
|
||||
|
||||
entity_array[n_entities++] = ent;
|
||||
}
|
||||
|
||||
- (BOOL) checkEntity:(Entity*) ent
|
||||
{
|
||||
Vector position = ent->position;
|
||||
|
||||
// check subregions
|
||||
BOOL foundRegion = NO;
|
||||
int n_subs = [subregions count];
|
||||
int i;
|
||||
for (i = 0; i < n_subs; i++)
|
||||
{
|
||||
CollisionRegion* sub = (CollisionRegion*)[subregions objectAtIndex:i];
|
||||
if (positionIsWithinBorders( position, sub))
|
||||
foundRegion |= [sub checkEntity:ent];
|
||||
}
|
||||
if (foundRegion)
|
||||
return YES; // it's in a subregion so no further action is neccesary
|
||||
|
||||
if (!positionIsWithinBorders( position, self))
|
||||
return NO;
|
||||
|
||||
[self addEntity: ent];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (void) findCollisionsInUniverse:(Universe*) universe
|
||||
{
|
||||
//
|
||||
// According to Shark, when this was in Universe this was where Oolite spent most time!
|
||||
//
|
||||
Entity *e1,*e2;
|
||||
Vector p1, p2;
|
||||
double dist2, r1, r2, r0, min_dist2;
|
||||
int i,j;
|
||||
//
|
||||
|
||||
// reject trivial cases
|
||||
//
|
||||
if (n_entities < 2)
|
||||
return;
|
||||
|
||||
// clear collision variables
|
||||
//
|
||||
for (i = 0; i < n_entities; i++)
|
||||
{
|
||||
e1 = entity_array[i];
|
||||
if (e1->has_collided)
|
||||
[[e1 collisionArray] removeAllObjects];
|
||||
e1->has_collided = NO;
|
||||
if (e1->isShip)
|
||||
[(ShipEntity*)e1 setProximity_alert:nil];
|
||||
e1->collider = nil;
|
||||
}
|
||||
|
||||
// test for collisions in each subregion
|
||||
//
|
||||
int n_subs = [subregions count];
|
||||
for (i = 0; i < n_subs; i++)
|
||||
[(CollisionRegion*)[subregions objectAtIndex: i] findCollisionsInUniverse: universe];
|
||||
//
|
||||
|
||||
// test each entity in this region against the others
|
||||
//
|
||||
for (i = 0; i < n_entities; i++)
|
||||
{
|
||||
e1 = entity_array[i];
|
||||
p1 = e1->position;
|
||||
r1 = e1->collision_radius;
|
||||
for (j = i + 1; j < n_entities; j++)
|
||||
{
|
||||
e2 = entity_array[j];
|
||||
p2 = e2->position;
|
||||
r2 = e2->collision_radius;
|
||||
r0 = r1 + r2;
|
||||
p2.x -= p1.x; p2.y -= p1.y; p2.z -= p1.z;
|
||||
if ((p2.x > r0)||(p2.x < -r0)) // test for simple x distance
|
||||
continue; // next j
|
||||
if ((p2.y > r0)||(p2.y < -r0)) // test for simple y distance
|
||||
continue; // next j
|
||||
if ((p2.z > r0)||(p2.z < -r0)) // test for simple z distance
|
||||
continue; // next j
|
||||
dist2 = p2.x*p2.x + p2.y*p2.y + p2.z*p2.z;
|
||||
min_dist2 = r0 * r0;
|
||||
if (dist2 < PROXIMITY_WARN_DISTANCE2 * min_dist2)
|
||||
{
|
||||
if ((e1->isShip) && (e2->isShip))
|
||||
{
|
||||
if (dist2 < PROXIMITY_WARN_DISTANCE2 * r2 * r2) [(ShipEntity*)e1 setProximity_alert:(ShipEntity*)e2];
|
||||
if (dist2 < PROXIMITY_WARN_DISTANCE2 * r1 * r1) [(ShipEntity*)e2 setProximity_alert:(ShipEntity*)e1];
|
||||
}
|
||||
if (dist2 < min_dist2)
|
||||
{
|
||||
BOOL coll1 = [e1 checkCloseCollisionWith:e2];
|
||||
BOOL coll2 = [e2 checkCloseCollisionWith:e1];
|
||||
if ( coll1 && coll2 )
|
||||
{
|
||||
if (e1->collider)
|
||||
[[e1 collisionArray] addObject:e1->collider];
|
||||
else
|
||||
[[e1 collisionArray] addObject:e2];
|
||||
e1->has_collided = YES;
|
||||
//
|
||||
if (e2->collider)
|
||||
[[e2 collisionArray] addObject:e2->collider];
|
||||
else
|
||||
[[e2 collisionArray] addObject:e1];
|
||||
e2->has_collided = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString*) debugOut
|
||||
{
|
||||
int i;
|
||||
int n_subs = [subregions count];
|
||||
NSMutableString* result = [[NSMutableString alloc] initWithFormat:@"%d:", n_entities];
|
||||
for (i = 0; i < n_subs; i++)
|
||||
[result appendString:[(CollisionRegion*)[subregions objectAtIndex:i] debugOut]];
|
||||
return [result autorelease];
|
||||
}
|
||||
|
||||
@end
|
@ -168,7 +168,6 @@ Your fair use and other rights are in no way affected by the above.
|
||||
glFogf(GL_FOG_END, half_scale);
|
||||
//
|
||||
// disapply lighting and texture
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
//
|
||||
if (player->isSunlit)
|
||||
@ -202,13 +201,9 @@ Your fair use and other rights are in no way affected by the above.
|
||||
Vector vh = make_vector(vertices[vi].x-warp_vector.x/HYPERSPEED_FACTOR, vertices[vi].y-warp_vector.y/HYPERSPEED_FACTOR, vertices[vi].z-warp_vector.z/HYPERSPEED_FACTOR);
|
||||
glVertex3f( vh.x, vh.y, vh.z);
|
||||
}
|
||||
// //
|
||||
// checkGLErrors(@"DustEntity after p1"); // NOTA BENE: YOU CANNOT CHECK FOR GL_ERRORs BETWEEN GL_BEGIN AND GL_END
|
||||
// //
|
||||
}
|
||||
glEnd();
|
||||
// reapply lighting etc.
|
||||
glEnable(GL_LIGHTING);
|
||||
// reapply normal conditions
|
||||
glDisable(GL_FOG);
|
||||
}
|
||||
//
|
@ -67,6 +67,7 @@ Your fair use and other rights are in no way affected by the above.
|
||||
#define STATUS_EXITING_WITCHSPACE 412
|
||||
#define STATUS_ESCAPE_SEQUENCE 500
|
||||
#define STATUS_IN_HOLD 600
|
||||
#define STATUS_BEING_SCOOPED 700
|
||||
#define STATUS_HANDLING_ERROR 999
|
||||
|
||||
#define CLASS_NOT_SET -1
|
||||
@ -90,20 +91,16 @@ Your fair use and other rights are in no way affected by the above.
|
||||
#define SCANNER_MAX_RANGE 25600.0
|
||||
#define SCANNER_MAX_RANGE2 655360000.0
|
||||
|
||||
#define CLOSE_COLLISION_CHECK_MAX_RANGE2 1000000000.0
|
||||
|
||||
|
||||
#define MODEL_FILE @"CORIOLIS.DAT"
|
||||
|
||||
#ifdef GNUSTEP
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
#import "gnustep-oolite.h"
|
||||
#else
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
#import "OOCocoa.h"
|
||||
#include "vector.h"
|
||||
#include "legacy_random.h"
|
||||
|
||||
@class Universe;
|
||||
@class Universe, Geometry, CollisionRegion;
|
||||
|
||||
|
||||
struct face
|
||||
@ -118,7 +115,8 @@ struct face
|
||||
|
||||
GLint vertex[MAX_VERTICES_PER_FACE];
|
||||
|
||||
NSString *textureFile;
|
||||
Str255 textureFileStr255;
|
||||
// NSString *textureFile;
|
||||
GLuint texName;
|
||||
GLfloat s[MAX_VERTICES_PER_FACE];
|
||||
GLfloat t[MAX_VERTICES_PER_FACE];
|
||||
@ -133,7 +131,7 @@ typedef struct
|
||||
GLfloat texture_uv_array[ 3 * MAX_FACES_PER_ENTITY * 2];
|
||||
Vector vertex_array[3 * MAX_FACES_PER_ENTITY];
|
||||
Vector normal_array[3 * MAX_FACES_PER_ENTITY];
|
||||
NSString *textureFile;
|
||||
|
||||
GLuint texName;
|
||||
|
||||
int n_triangles;
|
||||
@ -203,7 +201,10 @@ extern int debug;
|
||||
//
|
||||
Entity* collider;
|
||||
//
|
||||
int universal_id; // used to reference the entity
|
||||
int universal_id; // used to reference the entity
|
||||
//
|
||||
CollisionRegion* collision_region; // initially nil - then maintained
|
||||
|
||||
@protected
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
@ -255,7 +256,8 @@ extern int debug;
|
||||
int n_textures;
|
||||
EntityData entityData;
|
||||
NSRange triangle_range[MAX_TEXTURES_PER_ENTITY];
|
||||
NSString* texture_file[MAX_TEXTURES_PER_ENTITY];
|
||||
// NSString* texture_file[MAX_TEXTURES_PER_ENTITY];
|
||||
Str255 texture_file[MAX_TEXTURES_PER_ENTITY];
|
||||
GLuint texture_name[MAX_TEXTURES_PER_ENTITY];
|
||||
|
||||
BOOL throw_sparks;
|
||||
@ -308,11 +310,13 @@ extern int debug;
|
||||
- (void) setPosition:(GLfloat) x:(GLfloat) y:(GLfloat) z;
|
||||
- (Vector) getPosition;
|
||||
- (Vector) getViewpointPosition;
|
||||
- (Vector) getViewpointOffset;
|
||||
|
||||
- (double) getZeroDistance;
|
||||
- (Vector) relative_position;
|
||||
- (NSComparisonResult) compareZeroDistance:(Entity *)otherEntity;
|
||||
|
||||
- (Geometry*) getGeometry;
|
||||
- (BoundingBox) getBoundingBox;
|
||||
|
||||
- (GLfloat) mass;
|
||||
@ -341,6 +345,7 @@ extern int debug;
|
||||
- (void) moveForward:(double) amount;
|
||||
|
||||
- (GLfloat *) rotationMatrix;
|
||||
- (GLfloat *) drawRotationMatrix;
|
||||
|
||||
- (BOOL) canCollide;
|
||||
- (double) collisionRadius;
|
@ -40,6 +40,7 @@ Your fair use and other rights are in no way affected by the above.
|
||||
#import "Entity.h"
|
||||
|
||||
#import "vector.h"
|
||||
#import "Geometry.h"
|
||||
#import "Universe.h"
|
||||
#import "GameController.h"
|
||||
#import "TextureStore.h"
|
||||
@ -238,7 +239,7 @@ static Universe *data_store_universe;
|
||||
quaternion_set_identity(&q_rotation);
|
||||
quaternion_into_gl_matrix(q_rotation, rotMatrix);
|
||||
//
|
||||
position = make_vector( 0.0, 0.0, 0.0);
|
||||
position = make_vector( 0.0f, 0.0f, 0.0f);
|
||||
//
|
||||
zero_distance = 0.0; // 10 km
|
||||
no_draw_distance = 100000.0; // 10 km
|
||||
@ -282,12 +283,14 @@ static Universe *data_store_universe;
|
||||
isSunlit = YES;
|
||||
shadingEntityID = NO_TARGET;
|
||||
//
|
||||
collision_region = nil;
|
||||
//
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (universe) [universe release];
|
||||
// universe is a mere reference. It is neither retained nor released.
|
||||
if (basefile) [basefile release];
|
||||
if (collidingEntities) [collidingEntities release];
|
||||
if (trackLock) [trackLock release];
|
||||
@ -307,16 +310,7 @@ static Universe *data_store_universe;
|
||||
|
||||
- (void) setUniverse:(Universe *)univ
|
||||
{
|
||||
if (univ)
|
||||
{
|
||||
if (universe) [universe release];
|
||||
universe = [univ retain];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (universe) [universe release];
|
||||
universe = nil;
|
||||
}
|
||||
universe = univ;
|
||||
}
|
||||
|
||||
- (void) setUniversal_id:(int)uid
|
||||
@ -356,17 +350,18 @@ static Universe *data_store_universe;
|
||||
- (void) setOwner:(Entity *) ent
|
||||
{
|
||||
int owner_id = [ent universal_id];
|
||||
if (universe)
|
||||
if (!universe)
|
||||
{
|
||||
[self setUniverse:[ent universe]];
|
||||
owner = owner_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([universe entityForUniversalID:owner_id] == ent) // check to make sure it's kosher
|
||||
owner = owner_id;
|
||||
else
|
||||
owner = NO_TARGET;
|
||||
}
|
||||
else
|
||||
{
|
||||
owner = owner_id; // if the universe hasn't been initialised yet, trust the sender
|
||||
}
|
||||
}
|
||||
|
||||
- (Entity *) owner
|
||||
@ -374,6 +369,7 @@ static Universe *data_store_universe;
|
||||
return [universe entityForUniversalID:owner];
|
||||
}
|
||||
|
||||
|
||||
- (void) setModel:(NSString *) modelName
|
||||
{
|
||||
// use our own pool to save big memory
|
||||
@ -434,6 +430,21 @@ static Universe *data_store_universe;
|
||||
return NSOrderedDescending;
|
||||
}
|
||||
|
||||
- (Geometry*) getGeometry
|
||||
{
|
||||
Geometry* result = [[Geometry alloc] initWithCapacity: n_faces];
|
||||
int i;
|
||||
for (i = 0; i < n_faces; i++)
|
||||
{
|
||||
Triangle tri;
|
||||
tri.v[0] = vertices[faces[i].vertex[0]];
|
||||
tri.v[1] = vertices[faces[i].vertex[1]];
|
||||
tri.v[2] = vertices[faces[i].vertex[2]];
|
||||
[result addTriangle: tri];
|
||||
}
|
||||
return [result autorelease];
|
||||
}
|
||||
|
||||
- (BoundingBox) getBoundingBox
|
||||
{
|
||||
return boundingBox;
|
||||
@ -557,6 +568,11 @@ static Universe *data_store_universe;
|
||||
return rotMatrix;
|
||||
}
|
||||
|
||||
- (GLfloat *) drawRotationMatrix
|
||||
{
|
||||
return rotMatrix;
|
||||
}
|
||||
|
||||
- (Vector) getPosition
|
||||
{
|
||||
return position;
|
||||
@ -567,6 +583,10 @@ static Universe *data_store_universe;
|
||||
return position;
|
||||
}
|
||||
|
||||
- (Vector) getViewpointOffset
|
||||
{
|
||||
return make_vector( 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
- (BOOL) canCollide
|
||||
{
|
||||
@ -733,14 +753,14 @@ static Universe *data_store_universe;
|
||||
{
|
||||
Vector abspos = position; // STATUS_ACTIVE means it is in control of it's own orientation
|
||||
Entity* father = my_owner;
|
||||
GLfloat* r_mat = [father rotationMatrix];
|
||||
GLfloat* r_mat = [father drawRotationMatrix];
|
||||
while (father)
|
||||
{
|
||||
mult_vector_gl_matrix(&abspos, r_mat);
|
||||
Vector pos = father->position;
|
||||
abspos.x += pos.x; abspos.y += pos.y; abspos.z += pos.z;
|
||||
father = [father owner];
|
||||
r_mat = [father rotationMatrix];
|
||||
r_mat = [father drawRotationMatrix];
|
||||
}
|
||||
glPopMatrix(); // one down
|
||||
glPushMatrix();
|
||||
@ -765,13 +785,16 @@ static Universe *data_store_universe;
|
||||
for (fi = 0; fi < n_faces; fi++)
|
||||
{
|
||||
// texture
|
||||
if ((faces[fi].texName == 0)&&(faces[fi].textureFile))
|
||||
NSString* texture = [NSString stringWithUTF8String:(char*)faces[fi].textureFileStr255];
|
||||
// if ((faces[fi].texName == 0)&&(faces[fi].textureFile))
|
||||
if ((faces[fi].texName == 0)&&(texture))
|
||||
{
|
||||
// load texture into Universe texturestore
|
||||
// NSLog(@"Off to load %@",faces[fi].textureFile);
|
||||
if (universe)
|
||||
{
|
||||
faces[fi].texName = [[universe textureStore] getTextureNameFor:faces[fi].textureFile];
|
||||
// faces[fi].texName = [[universe textureStore] getTextureNameFor:faces[fi].textureFile];
|
||||
faces[fi].texName = [[universe textureStore] getTextureNameFor: texture];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -780,7 +803,8 @@ static Universe *data_store_universe;
|
||||
{
|
||||
if (!texture_name[ti])
|
||||
{
|
||||
texture_name[ti] = [[universe textureStore] getTextureNameFor:texture_file[ti]];
|
||||
// texture_name[ti] = [[universe textureStore] getTextureNameFor: texture_file[ti]];
|
||||
texture_name[ti] = [[universe textureStore] getTextureNameFor: [NSString stringWithUTF8String: (char*)texture_file[ti]]];
|
||||
// NSLog(@"DEBUG (initialiseTextures) Processed textureFile : %@ to texName : %d", entityData[ti].textureFile, entityData[ti].texName);
|
||||
}
|
||||
}
|
||||
@ -1032,7 +1056,7 @@ static Universe *data_store_universe;
|
||||
NSData* vdata = (NSData*)[dict objectForKey:@"vertices"];
|
||||
NSData* ndata = (NSData*)[dict objectForKey:@"normals"];
|
||||
NSData* fdata = (NSData*)[dict objectForKey:@"faces"];
|
||||
if (vdata && ndata && fdata)
|
||||
if ((vdata) && (ndata) && (fdata))
|
||||
{
|
||||
Vector* vbytes = (Vector*)[vdata bytes];
|
||||
Vector* nbytes = (Vector*)[ndata bytes];
|
||||
@ -1050,7 +1074,7 @@ static Universe *data_store_universe;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"ERROR setModelFromData: %@ FAILED", dict);
|
||||
NSLog(@"ERROR setModelFromData: FAILED");
|
||||
// should throw an oolite-fatal-exception here
|
||||
NSException* myException = [NSException
|
||||
exceptionWithName: OOLITE_EXCEPTION_FATAL
|
||||
@ -1319,7 +1343,9 @@ static Universe *data_store_universe;
|
||||
}
|
||||
else
|
||||
{
|
||||
faces[j].textureFile = [texfile retain];
|
||||
// faces[j].textureFile = [texfile retain];
|
||||
strlcpy( (char*)faces[j].textureFileStr255, [texfile UTF8String], 256);
|
||||
// NSLog(@"DEBUG TEST strlcpy of '%@' result = '%s'", texfile, faces[j].textureFileStr255);
|
||||
}
|
||||
faces[j].texName = 0;
|
||||
|
||||
@ -1475,7 +1501,7 @@ static Universe *data_store_universe;
|
||||
}
|
||||
for (i = 0; i < n_vertices; i++)
|
||||
{
|
||||
Vector normal_sum = make_vector( 0, 0, 0);
|
||||
Vector normal_sum = make_vector( 0.0f, 0.0f, 0.0f);
|
||||
for (j = 0; j < n_faces; j++)
|
||||
{
|
||||
BOOL is_shared = ((faces[j].vertex[0] == i)||(faces[j].vertex[1] == i)||(faces[j].vertex[2] == i));
|
||||
@ -1503,20 +1529,20 @@ static Universe *data_store_universe;
|
||||
int tri_index = 0;
|
||||
int uv_index = 0;
|
||||
int vertex_index = 0;
|
||||
// int normal_index = 0;
|
||||
entityData.textureFile = nil;
|
||||
entityData.texName = 0;
|
||||
|
||||
texi = 1; // index of first texture
|
||||
|
||||
for (face = 0; face < n_faces; face++)
|
||||
{
|
||||
NSString* tex_string = faces[face].textureFile;
|
||||
// NSString* tex_string = faces[face].textureFile;
|
||||
NSString* tex_string = [NSString stringWithUTF8String: (char*)faces[face].textureFileStr255];
|
||||
if (![texturesProcessed objectForKey:tex_string])
|
||||
{
|
||||
// do this texture
|
||||
triangle_range[texi].location = tri_index;
|
||||
texture_file[texi] = tex_string;
|
||||
// texture_file[texi] = tex_string;
|
||||
strlcpy( (char*)texture_file[texi], (char*)faces[face].textureFileStr255, 256);
|
||||
texture_name[texi] = faces[face].texName;
|
||||
|
||||
for (fi = 0; fi < n_faces; fi++)
|
||||
@ -1525,7 +1551,9 @@ static Universe *data_store_universe;
|
||||
int v;
|
||||
if (!is_smooth_shaded)
|
||||
normal = faces[fi].normal;
|
||||
if ([faces[fi].textureFile isEqual:tex_string])
|
||||
// if ([faces[fi].textureFile isEqual:tex_string])
|
||||
// if ([[NSString stringWithUTF8String: faces[fi].textureFileStr255] isEqual:tex_string])
|
||||
if (strcmp( (char*)faces[fi].textureFileStr255, (char*)faces[face].textureFileStr255) == 0)
|
||||
{
|
||||
for (vi = 0; vi < 3; vi++)
|
||||
{
|
||||
@ -1579,22 +1607,22 @@ static Universe *data_store_universe;
|
||||
bounding_box_add_vector(&boundingBox,vertices[i]);
|
||||
}
|
||||
|
||||
length_longest_axis = boundingBox.max_x - boundingBox.min_x;
|
||||
if (boundingBox.max_y - boundingBox.min_y > length_longest_axis)
|
||||
length_longest_axis = boundingBox.max_y - boundingBox.min_y;
|
||||
if (boundingBox.max_z - boundingBox.min_z > length_longest_axis)
|
||||
length_longest_axis = boundingBox.max_z - boundingBox.min_z;
|
||||
length_longest_axis = boundingBox.max.x - boundingBox.min.x;
|
||||
if (boundingBox.max.y - boundingBox.min.y > length_longest_axis)
|
||||
length_longest_axis = boundingBox.max.y - boundingBox.min.y;
|
||||
if (boundingBox.max.z - boundingBox.min.z > length_longest_axis)
|
||||
length_longest_axis = boundingBox.max.z - boundingBox.min.z;
|
||||
|
||||
length_shortest_axis = boundingBox.max_x - boundingBox.min_x;
|
||||
if (boundingBox.max_y - boundingBox.min_y < length_shortest_axis)
|
||||
length_shortest_axis = boundingBox.max_y - boundingBox.min_y;
|
||||
if (boundingBox.max_z - boundingBox.min_z < length_shortest_axis)
|
||||
length_shortest_axis = boundingBox.max_z - boundingBox.min_z;
|
||||
length_shortest_axis = boundingBox.max.x - boundingBox.min.x;
|
||||
if (boundingBox.max.y - boundingBox.min.y < length_shortest_axis)
|
||||
length_shortest_axis = boundingBox.max.y - boundingBox.min.y;
|
||||
if (boundingBox.max.z - boundingBox.min.z < length_shortest_axis)
|
||||
length_shortest_axis = boundingBox.max.z - boundingBox.min.z;
|
||||
|
||||
d_squared = (length_longest_axis + length_shortest_axis) * (length_longest_axis + length_shortest_axis) * 0.25; // square of average length
|
||||
no_draw_distance = d_squared * NO_DRAW_DISTANCE_FACTOR * NO_DRAW_DISTANCE_FACTOR; // no longer based on the collision radius
|
||||
|
||||
mass = (boundingBox.max_x - boundingBox.min_x) * (boundingBox.max_y - boundingBox.min_y) * (boundingBox.max_z - boundingBox.min_z);
|
||||
mass = (boundingBox.max.x - boundingBox.min.x) * (boundingBox.max.y - boundingBox.min.y) * (boundingBox.max.z - boundingBox.min.z);
|
||||
|
||||
return sqrt(result);
|
||||
}
|
||||
@ -1602,6 +1630,8 @@ static Universe *data_store_universe;
|
||||
|
||||
- (BoundingBox) findBoundingBoxRelativeTo:(Entity *)other InVectors:(Vector) _i :(Vector) _j :(Vector) _k
|
||||
{
|
||||
NSLog(@"DEBUG ** DEPRECATED [Entity findBoundingBoxRelativeTo:(Entity *)other InVectors:(Vector) _i :(Vector) _j :(Vector) _k] CALLED **");
|
||||
|
||||
Vector pv, rv;
|
||||
Vector rpos = position;
|
||||
Vector opv = (other)? other->position : rpos;
|
||||
@ -1627,6 +1657,8 @@ static Universe *data_store_universe;
|
||||
|
||||
- (BoundingBox) findBoundingBoxRelativeToPosition:(Vector)opv InVectors:(Vector) _i :(Vector) _j :(Vector) _k
|
||||
{
|
||||
NSLog(@"DEBUG ** DEPRECATED [Entity findBoundingBoxRelativeToPosition:(Vector)opv InVectors:(Vector) _i :(Vector) _j :(Vector) _k] CALLED **");
|
||||
|
||||
Vector pv, rv;
|
||||
Vector rpos = position;
|
||||
rpos.x -= opv.x; rpos.y -= opv.y; rpos.z -= opv.z;
|
||||
@ -1695,8 +1727,11 @@ static Universe *data_store_universe;
|
||||
result = [NSString stringWithFormat:@"%@\nTEXTURES\n", result];
|
||||
for (j = 0; j < n_faces; j++)
|
||||
{
|
||||
NSSize texSize = [[universe textureStore] getSizeOfTexture:faces[j].textureFile];
|
||||
result = [NSString stringWithFormat:@"%@%@\t%d %d", result, faces[j].textureFile, (int)texSize.width, (int)texSize.height];
|
||||
// NSSize texSize = [[universe textureStore] getSizeOfTexture:faces[j].textureFile];
|
||||
// result = [NSString stringWithFormat:@"%@%@\t%d %d", result, faces[j].textureFile, (int)texSize.width, (int)texSize.height];
|
||||
NSString* texture = [NSString stringWithUTF8String: (char*)faces[j].textureFileStr255];
|
||||
NSSize texSize = [[universe textureStore] getSizeOfTexture: texture];
|
||||
result = [NSString stringWithFormat:@"%@%@\t%d %d", result, texture, (int)texSize.width, (int)texSize.height];
|
||||
for (i = 0; i < faces[j].n_verts; i++)
|
||||
{
|
||||
int s = (int)(faces[j].s[i] * texSize.width);
|
||||
@ -1767,7 +1802,9 @@ static Universe *data_store_universe;
|
||||
{
|
||||
i = fi[j];
|
||||
//fa[i] = faces[i];
|
||||
fa[i].textureFile = [NSString stringWithFormat:@"top_%@", textureFile];
|
||||
// fa[i].textureFile = [NSString stringWithFormat:@"top_%@", textureFile];
|
||||
// strlcpy( (char*)fa[i].textureFileStr255, [fa[i].textureFile UTF8String], 256);
|
||||
strlcpy( (char*)fa[i].textureFileStr255, [[NSString stringWithFormat:@"top_%@", textureFile] UTF8String], 256);
|
||||
for (k = 0; k < faces[i].n_verts; k++)
|
||||
{
|
||||
float s, t;
|
||||
@ -1815,7 +1852,9 @@ static Universe *data_store_universe;
|
||||
{
|
||||
i = fi[j];
|
||||
//fa[i] = faces[i];
|
||||
fa[i].textureFile = [NSString stringWithFormat:@"bottom_%@", textureFile];
|
||||
// fa[i].textureFile = [NSString stringWithFormat:@"bottom_%@", textureFile];
|
||||
// strlcpy( (char*)fa[i].textureFileStr255, [fa[i].textureFile UTF8String], 256);
|
||||
strlcpy( (char*)fa[i].textureFileStr255, [[NSString stringWithFormat:@"bottom_%@", textureFile] UTF8String], 256);
|
||||
for (k = 0; k < faces[i].n_verts; k++)
|
||||
{
|
||||
float s, t;
|
||||
@ -1856,7 +1895,9 @@ static Universe *data_store_universe;
|
||||
{
|
||||
i = fi[j];
|
||||
//fa[i] = faces[i];
|
||||
fa[i].textureFile = [NSString stringWithFormat:@"right_%@", textureFile];
|
||||
// fa[i].textureFile = [NSString stringWithFormat:@"right_%@", textureFile];
|
||||
// strlcpy( (char*)fa[i].textureFileStr255, [fa[i].textureFile UTF8String], 256);
|
||||
strlcpy( (char*)fa[i].textureFileStr255, [[NSString stringWithFormat:@"right_%@", textureFile] UTF8String], 256);
|
||||
for (k = 0; k < faces[i].n_verts; k++)
|
||||
{
|
||||
float s, t;
|
||||
@ -1897,7 +1938,9 @@ static Universe *data_store_universe;
|
||||
{
|
||||
i = fi[j];
|
||||
//fa[i] = faces[i];
|
||||
fa[i].textureFile = [NSString stringWithFormat:@"left_%@", textureFile];
|
||||
// fa[i].textureFile = [NSString stringWithFormat:@"left_%@", textureFile];
|
||||
// strlcpy( (char*)fa[i].textureFileStr255, [fa[i].textureFile UTF8String], 256);
|
||||
strlcpy( (char*)fa[i].textureFileStr255, [[NSString stringWithFormat:@"left_%@", textureFile] UTF8String], 256);
|
||||
for (k = 0; k < faces[i].n_verts; k++)
|
||||
{
|
||||
float s, t;
|
||||
@ -1938,7 +1981,9 @@ static Universe *data_store_universe;
|
||||
{
|
||||
i = fi[j];
|
||||
//fa[i] = faces[i];
|
||||
fa[i].textureFile = [NSString stringWithFormat:@"front_%@", textureFile];
|
||||
// fa[i].textureFile = [NSString stringWithFormat:@"front_%@", textureFile];
|
||||
// strlcpy( (char*)fa[i].textureFileStr255, [fa[i].textureFile UTF8String], 256);
|
||||
strlcpy( (char*)fa[i].textureFileStr255, [[NSString stringWithFormat:@"front_%@", textureFile] UTF8String], 256);
|
||||
for (k = 0; k < faces[i].n_verts; k++)
|
||||
{
|
||||
float s, t;
|
||||
@ -1979,7 +2024,9 @@ static Universe *data_store_universe;
|
||||
{
|
||||
i = fi[j];
|
||||
//fa[i] = faces[i];
|
||||
fa[i].textureFile = [NSString stringWithFormat:@"back_%@", textureFile];
|
||||
// fa[i].textureFile = [NSString stringWithFormat:@"back_%@", textureFile];
|
||||
// strlcpy( (char*)fa[i].textureFileStr255, [fa[i].textureFile UTF8String], 256);
|
||||
strlcpy( (char*)fa[i].textureFileStr255, [[NSString stringWithFormat:@"back_%@", textureFile] UTF8String], 256);
|
||||
for (k = 0; k < faces[i].n_verts; k++)
|
||||
{
|
||||
float s, t;
|
||||
@ -1995,7 +2042,8 @@ static Universe *data_store_universe;
|
||||
for (i = 0; i < n_faces; i++)
|
||||
{
|
||||
NSString *result;
|
||||
faces[i].textureFile = [fa[i].textureFile retain];
|
||||
// faces[i].textureFile = [fa[i].textureFile retain];
|
||||
strlcpy( (char*)faces[i].textureFileStr255, (char*)fa[i].textureFileStr255, 256);
|
||||
faces[i].texName = 0;
|
||||
for (j = 0; j < faces[i].n_verts; j++)
|
||||
{
|
||||
@ -2005,7 +2053,8 @@ static Universe *data_store_universe;
|
||||
faces[i].s[j] = fa[i].s[j] / maxSize.width;
|
||||
faces[i].t[j] = fa[i].t[j] / maxSize.height;
|
||||
}
|
||||
result = [NSString stringWithFormat:@"%@\t%d %d", faces[i].textureFile, (int)maxSize.width, (int)maxSize.height];
|
||||
// result = [NSString stringWithFormat:@"%@\t%d %d", faces[i].textureFile, (int)maxSize.width, (int)maxSize.height];
|
||||
result = [NSString stringWithFormat:@"%s\t%d %d", faces[i].textureFileStr255, (int)maxSize.width, (int)maxSize.height];
|
||||
//NSLog(@"face[%d] : %@", i, result);
|
||||
}
|
||||
|
@ -36,21 +36,20 @@ Your fair use and other rights are in no way affected by the above.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef GNUSTEP
|
||||
#import <Foundation/Foundation.h>
|
||||
//#import <AppKit/AppKit.h>
|
||||
//#import <AppKit/NSOpenGL.h>
|
||||
//#include <X11/Xlib.h>
|
||||
#else
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
#import "OOCocoa.h"
|
||||
|
||||
#define MODE_WINDOWED 100
|
||||
#define MODE_FULL_SCREEN 200
|
||||
|
||||
#define DISPLAY_MIN_COLOURS 32
|
||||
#define DISPLAY_MIN_WIDTH 800
|
||||
#ifndef GNUSTEP
|
||||
#define DISPLAY_MIN_WIDTH 640
|
||||
#define DISPLAY_MIN_HEIGHT 480
|
||||
#else
|
||||
// *** Is there a reason for this difference? -- Jens
|
||||
#define DISPLAY_MIN_WIDTH 800
|
||||
#define DISPLAY_MIN_HEIGHT 600
|
||||
#endif
|
||||
#define DISPLAY_MAX_WIDTH 2400
|
||||
#define DISPLAY_MAX_HEIGHT 1800
|
||||
|
||||
@ -60,85 +59,71 @@ Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
@class Universe, MyOpenGLView, TextureStore;
|
||||
|
||||
// dajt: is defined as BOOL in main.m
|
||||
extern int debug;
|
||||
|
||||
#ifdef GNUSTEP
|
||||
#define IBOutlet /**/
|
||||
#define IBAction void
|
||||
#endif
|
||||
|
||||
@interface GameController : NSObject
|
||||
{
|
||||
#ifndef GNUSTEP
|
||||
IBOutlet NSTextField *splashProgressTextField;
|
||||
IBOutlet NSTextField *splashProgressTextField;
|
||||
IBOutlet NSView *splashView;
|
||||
IBOutlet NSWindow *gameWindow;
|
||||
IBOutlet NSWindow *fsGameWindow;
|
||||
#else
|
||||
NSRect fsGeometry;
|
||||
MyOpenGLView *switchView;
|
||||
#endif
|
||||
IBOutlet MyOpenGLView *gameView;
|
||||
|
||||
NSRect fsGeometry;
|
||||
Universe *universe;
|
||||
|
||||
IBOutlet MyOpenGLView *gameView;
|
||||
IBOutlet MyOpenGLView *switchView;
|
||||
NSTimeInterval last_timeInterval;
|
||||
double delta_t;
|
||||
|
||||
Universe *universe;
|
||||
int my_mouse_x, my_mouse_y;
|
||||
|
||||
NSTimeInterval last_timeInterval;
|
||||
double delta_t;
|
||||
|
||||
int my_mouse_x, my_mouse_y;
|
||||
NSString *playerFileDirectory;
|
||||
NSString *playerFileToLoad;
|
||||
NSMutableArray *expansionPathsToInclude;
|
||||
|
||||
NSTimer *timer;
|
||||
|
||||
#ifdef GNUSTEP
|
||||
// TODO: What should go here?
|
||||
// dajt: CGMouseDelta is just an integer - we can use a Cocoa compat header file to define it
|
||||
#else
|
||||
CGMouseDelta mouse_dx, mouse_dy;
|
||||
#endif
|
||||
|
||||
NSString *playerFileDirectory;
|
||||
NSString *playerFileToLoad;
|
||||
NSMutableArray* expansionPathsToInclude;
|
||||
|
||||
NSTimer *timer;
|
||||
|
||||
/* GDC example code */
|
||||
|
||||
NSMutableArray *displayModes;
|
||||
|
||||
unsigned int width, height;
|
||||
unsigned int colorBits;
|
||||
unsigned int depthBits;
|
||||
unsigned int refresh;
|
||||
BOOL fullscreen;
|
||||
NSDictionary *originalDisplayMode;
|
||||
NSDictionary *fullscreenDisplayMode;
|
||||
NSMutableArray *displayModes;
|
||||
|
||||
unsigned int width, height;
|
||||
unsigned int refresh;
|
||||
BOOL fullscreen;
|
||||
NSDictionary *originalDisplayMode;
|
||||
NSDictionary *fullscreenDisplayMode;
|
||||
|
||||
#ifndef GNUSTEP
|
||||
NSOpenGLContext *fullScreenContext;
|
||||
NSOpenGLContext *fullScreenContext;
|
||||
#endif
|
||||
BOOL stayInFullScreenMode;
|
||||
|
||||
BOOL stayInFullScreenMode;
|
||||
|
||||
/* end of GDC */
|
||||
|
||||
TextureStore *oldTextureStore;
|
||||
|
||||
SEL pauseSelector;
|
||||
NSObject* pauseTarget;
|
||||
|
||||
BOOL game_is_paused;
|
||||
|
||||
|
||||
TextureStore *oldTextureStore;
|
||||
|
||||
SEL pauseSelector;
|
||||
NSObject *pauseTarget;
|
||||
|
||||
BOOL game_is_paused;
|
||||
}
|
||||
|
||||
- (void) applicationDidFinishLaunching: (NSNotification *)notification;
|
||||
- (BOOL) game_is_paused;
|
||||
- (void) pause_game;
|
||||
- (void) unpause_game;
|
||||
|
||||
#ifndef GNUSTEP
|
||||
- (IBAction) goFullscreen:(id) sender;
|
||||
- (void) exitFullScreenMode;
|
||||
- (BOOL) inFullScreenMode;
|
||||
#ifdef GNUSTEP
|
||||
#else
|
||||
- (void) setFullScreenMode:(BOOL)fsm;
|
||||
#endif
|
||||
- (void) exitFullScreenMode;
|
||||
- (BOOL) inFullScreenMode;
|
||||
|
||||
- (void) pauseFullScreenModeToPerform:(SEL) selector onTarget:(id) target;
|
||||
- (void) exitApp;
|
||||
@ -153,9 +138,6 @@ extern int debug;
|
||||
- (NSString *) playerFileToLoad;
|
||||
- (void) setPlayerFileToLoad:(NSString *)filename;
|
||||
|
||||
// dajt: added to make things a bit neater
|
||||
- (void) applicationDidFinishLaunching: (NSNotification*) notification;
|
||||
|
||||
- (NSString *) playerFileDirectory;
|
||||
- (void) setPlayerFileDirectory:(NSString *)filename;
|
||||
|
@ -41,12 +41,8 @@ Your fair use and other rights are in no way affected by the above.
|
||||
#import "ResourceManager.h"
|
||||
#import "MyOpenGLView.h"
|
||||
#import "TextureStore.h"
|
||||
|
||||
#ifdef LINUX
|
||||
#include "oolite-linux.h"
|
||||
#else
|
||||
#import <OpenGL/OpenGL.h>
|
||||
#endif
|
||||
#import "OOSound.h"
|
||||
#import "OOOpenGL.h"
|
||||
|
||||
@implementation GameController
|
||||
|
||||
@ -317,10 +313,9 @@ static int _compareModes(id arg1, id arg2, void *context)
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef GNUSTEP
|
||||
- (void) applicationDidFinishLaunching: (NSNotification*) notification
|
||||
{
|
||||
#ifdef GNUSTEP
|
||||
// A bunch of things get allocated while this method runs and an autorelease pool
|
||||
// is required. The one from main had to be released already because we never go
|
||||
// back there under GNUstep.
|
||||
@ -328,7 +323,6 @@ static int _compareModes(id arg1, id arg2, void *context)
|
||||
gameView = [MyOpenGLView alloc];
|
||||
[gameView init];
|
||||
[gameView setGameController: self];
|
||||
#endif
|
||||
|
||||
//
|
||||
// ensure the gameView is drawn to, so OpenGL is initialised and so textures can initialse.
|
||||
@ -371,27 +365,95 @@ static int _compareModes(id arg1, id arg2, void *context)
|
||||
// get the run loop and add the call to doStuff
|
||||
//
|
||||
NSTimeInterval ti = 0.01;
|
||||
#ifdef GNUSTEP
|
||||
timer = [[NSTimer timerWithTimeInterval:ti target:gameView selector:@selector(pollControls:) userInfo:self repeats:YES] retain];
|
||||
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
|
||||
#else
|
||||
timer = [[NSTimer timerWithTimeInterval:ti target:self selector:@selector(doStuff:) userInfo:self repeats:YES] retain];
|
||||
|
||||
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
|
||||
|
||||
|
||||
// set up the window to accept mouseMoved events
|
||||
[gameWindow setAcceptsMouseMovedEvents:YES];
|
||||
#endif
|
||||
//
|
||||
[self endSplashScreen];
|
||||
|
||||
#ifdef GNUSTEP
|
||||
// Release anything allocated above that is not required.
|
||||
[pool release];
|
||||
[[NSRunLoop currentRunLoop] run];
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
- (void) applicationDidFinishLaunching: (NSNotification*) notification
|
||||
{
|
||||
//
|
||||
// ensure the gameView is drawn to, so OpenGL is initialised and so textures can initialse.
|
||||
//
|
||||
[gameView drawRect:[gameView bounds]];
|
||||
|
||||
[self beginSplashScreen];
|
||||
[self logProgress:@"initialising..."];
|
||||
//
|
||||
// check user defaults
|
||||
//
|
||||
width = 640; // standard screen is 640x480 pixels, 32 bit color, 32 bit z-buffer, refresh rate 75Hz
|
||||
height = 480;
|
||||
refresh = 75;
|
||||
//
|
||||
//NSLog(@"--- loading userdefaults");
|
||||
//
|
||||
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
|
||||
//
|
||||
if ([userDefaults objectForKey:@"display_width"])
|
||||
width = [userDefaults integerForKey:@"display_width"];
|
||||
if ([userDefaults objectForKey:@"display_height"])
|
||||
height = [userDefaults integerForKey:@"display_height"];
|
||||
if ([userDefaults objectForKey:@"display_refresh"])
|
||||
refresh = [userDefaults integerForKey:@"display_refresh"];
|
||||
|
||||
/* GDC example code */
|
||||
|
||||
[self logProgress:@"getting display modes..."];
|
||||
[self getDisplayModes];
|
||||
|
||||
/* end GDC */
|
||||
|
||||
fullscreenDisplayMode = [self findDisplayModeForWidth:width Height:height Refresh:refresh];
|
||||
if (fullscreenDisplayMode == nil)
|
||||
{
|
||||
// set full screen mode to first available mode
|
||||
fullscreenDisplayMode = [displayModes objectAtIndex:0];
|
||||
width = [[fullscreenDisplayMode objectForKey: (NSString *)kCGDisplayWidth] intValue];
|
||||
height = [[fullscreenDisplayMode objectForKey: (NSString *)kCGDisplayHeight] intValue];
|
||||
refresh = [[fullscreenDisplayMode objectForKey: (NSString *)kCGDisplayRefreshRate] intValue];
|
||||
}
|
||||
|
||||
// moved to before the Universe is created
|
||||
[self logProgress:@"loading selected expansion packs..."];
|
||||
if (expansionPathsToInclude)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < [expansionPathsToInclude count]; i++)
|
||||
[ResourceManager addExternalPath: (NSString*)[expansionPathsToInclude objectAtIndex: i]];
|
||||
}
|
||||
|
||||
// moved here to try to avoid initialising this before having an Open GL context
|
||||
[self logProgress:@"initialising universe..."];
|
||||
universe = [[Universe alloc] init];
|
||||
|
||||
[universe setGameView:gameView];
|
||||
|
||||
[self logProgress:@"loading player..."];
|
||||
[self loadPlayerIfRequired];
|
||||
|
||||
//
|
||||
// get the run loop and add the call to doStuff
|
||||
//
|
||||
NSTimeInterval ti = 0.01;
|
||||
|
||||
timer = [[NSTimer timerWithTimeInterval:ti target:self selector:@selector(doStuff:) userInfo:self repeats:YES] retain];
|
||||
|
||||
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
|
||||
|
||||
|
||||
// set up the window to accept mouseMoved events
|
||||
[gameWindow setAcceptsMouseMovedEvents:YES];
|
||||
|
||||
//
|
||||
[self endSplashScreen];
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void) loadPlayerIfRequired
|
||||
{
|
||||
@ -470,6 +532,7 @@ static int _compareModes(id arg1, id arg2, void *context)
|
||||
}
|
||||
#endif
|
||||
//
|
||||
[OOSound update];
|
||||
}
|
||||
|
||||
- (void) startAnimationTimer
|
||||
@ -505,12 +568,13 @@ static int _compareModes(id arg1, id arg2, void *context)
|
||||
CGDisplayErr err;
|
||||
long oldSwapInterval;
|
||||
long newSwapInterval;
|
||||
CGMouseDelta mouse_dx, mouse_dy;
|
||||
|
||||
// empty the event queue and strip all keys - stop problems with hangover keys
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSEvent *event;
|
||||
while (event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES]);
|
||||
while ((event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES]));
|
||||
[pool release];
|
||||
[gameView clearKeys];
|
||||
}
|
||||
@ -542,12 +606,21 @@ static int _compareModes(id arg1, id arg2, void *context)
|
||||
|
||||
// Specify that we want a full-screen OpenGL context.
|
||||
NSOpenGLPFAFullScreen,
|
||||
// // and that we want a windowed OpenGL context.
|
||||
// NSOpenGLPFAWindow,
|
||||
|
||||
// We may be on a multi-display system (and each screen may be driven by a different renderer), so we need to specify which screen we want to take over.
|
||||
// For this demo, we'll specify the main screen.
|
||||
NSOpenGLPFAScreenMask, CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay),
|
||||
|
||||
// Specifying "NoRecovery" gives us a context that cannot fall back to the software renderer.
|
||||
//This makes the View-based context a compatible with the fullscreen context, enabling us to use the "shareContext"
|
||||
// feature to share textures, display lists, and other OpenGL objects between the two.
|
||||
NSOpenGLPFANoRecovery,
|
||||
|
||||
// Attributes Common to FullScreen and non-FullScreen
|
||||
NSOpenGLPFACompliant,
|
||||
|
||||
NSOpenGLPFAColorSize, 32,
|
||||
NSOpenGLPFADepthSize, 32,
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
@ -629,7 +702,7 @@ static int _compareModes(id arg1, id arg2, void *context)
|
||||
|
||||
// Check for and process input events.
|
||||
NSEvent *event;
|
||||
while (event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES])
|
||||
while ((event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES]))
|
||||
{
|
||||
switch ([event type])
|
||||
{
|
||||
@ -648,6 +721,9 @@ static int _compareModes(id arg1, id arg2, void *context)
|
||||
break;
|
||||
|
||||
case NSMouseMoved:
|
||||
case NSLeftMouseDragged:
|
||||
// case NSRightMouseDragged: // avoid conflict with NSRightMouseDown
|
||||
case NSOtherMouseDragged:
|
||||
CGGetLastMouseDelta(&mouse_dx, &mouse_dy);
|
||||
if (past_first_mouse_delta)
|
||||
{
|
76
src/Core/Geometry.h
Normal file
76
src/Core/Geometry.h
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
|
||||
Oolite
|
||||
|
||||
Geometry.h
|
||||
|
||||
Created by Giles Williams on 30/01/2006.
|
||||
|
||||
|
||||
Copyright (c) 2005, Giles C Williams
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Noncommercial. You may not use this work for commercial purposes.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOCocoa.h"
|
||||
|
||||
#import "vector.h"
|
||||
|
||||
@class ShipEntity, Octree;
|
||||
|
||||
@interface Geometry : NSObject
|
||||
{
|
||||
// a geometry essentially consists of a whole bunch of Triangles.
|
||||
int n_triangles; // how many triangles in the geometry
|
||||
int max_triangles; // how many triangles are allowed in the geometry before expansion
|
||||
Triangle* triangles; // pointer to an array of triangles which we'll grow as necessary...
|
||||
BOOL isConvex; // set at initialisation to NO
|
||||
}
|
||||
|
||||
- (id) initWithCapacity:(int) amount;
|
||||
|
||||
- (BOOL) isConvex;
|
||||
- (void) setConvex:(BOOL) value;
|
||||
|
||||
- (void) addTriangle:(Triangle) tri;
|
||||
|
||||
- (BOOL) testHasGeometry;
|
||||
- (BOOL) testIsConvex;
|
||||
- (BOOL) testCornersWithinGeometry:(GLfloat) corner;
|
||||
- (GLfloat) findMaxDimensionFromOrigin;
|
||||
|
||||
- (Octree*) findOctreeToDepth: (int) depth;
|
||||
- (NSObject*) octreeWithinRadius:(GLfloat) octreeRadius toDepth: (int) depth;
|
||||
|
||||
- (void) translate:(Vector) offset;
|
||||
- (void) scale:(GLfloat) scalar;
|
||||
|
||||
- (void) x_axisSplitBetween:(Geometry*) g_plus :(Geometry*) g_minus :(GLfloat) x;
|
||||
- (void) y_axisSplitBetween:(Geometry*) g_plus :(Geometry*) g_minus :(GLfloat) y;
|
||||
- (void) z_axisSplitBetween:(Geometry*) g_plus :(Geometry*) g_minus :(GLfloat) z;
|
||||
|
||||
@end
|
752
src/Core/Geometry.m
Normal file
752
src/Core/Geometry.m
Normal file
@ -0,0 +1,752 @@
|
||||
/*
|
||||
|
||||
Oolite
|
||||
|
||||
Geometry.m
|
||||
|
||||
Created by Giles Williams on 30/01/2006.
|
||||
|
||||
|
||||
Copyright (c) 2005, Giles C Williams
|
||||
All rights reserved.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/
|
||||
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
|
||||
You are free:
|
||||
|
||||
• to copy, distribute, display, and perform the work
|
||||
• to make derivative works
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
• Attribution. You must give the original author credit.
|
||||
|
||||
• Noncommercial. You may not use this work for commercial purposes.
|
||||
|
||||
• Share Alike. If you alter, transform, or build upon this work,
|
||||
you may distribute the resulting work only under a license identical to this one.
|
||||
|
||||
For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
|
||||
Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#import "Geometry.h"
|
||||
|
||||
#import "vector.h"
|
||||
#import "Octree.h"
|
||||
#import "ShipEntity.h"
|
||||
|
||||
|
||||
@implementation Geometry
|
||||
|
||||
- (NSString*) description
|
||||
{
|
||||
NSString* result = [[NSString alloc] initWithFormat:@"<Geometry with %d triangles currently %@.>", n_triangles, [self testIsConvex]? @"Convex":@"not convex"];
|
||||
return [result autorelease];
|
||||
}
|
||||
|
||||
- (id) initWithCapacity:(int) amount
|
||||
{
|
||||
if (amount < 1)
|
||||
return nil;
|
||||
self = [super init];
|
||||
|
||||
max_triangles = amount;
|
||||
triangles = (Triangle*) malloc( max_triangles * sizeof(Triangle)); // allocate the required space
|
||||
n_triangles = 0;
|
||||
isConvex = NO;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
free((void *)triangles); // free up the allocated space
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (BOOL) isConvex
|
||||
{
|
||||
return isConvex;
|
||||
}
|
||||
|
||||
- (void) setConvex:(BOOL) value
|
||||
{
|
||||
isConvex = value;
|
||||
}
|
||||
|
||||
- (void) addTriangle:(Triangle) tri
|
||||
{
|
||||
// check for degenerate triangles
|
||||
if ((tri.v[0].x == tri.v[1].x)&&(tri.v[0].y == tri.v[1].y)&&(tri.v[0].z == tri.v[1].z)) // v0 == v1 -> return
|
||||
return;
|
||||
if ((tri.v[1].x == tri.v[2].x)&&(tri.v[1].y == tri.v[2].y)&&(tri.v[1].z == tri.v[2].z)) // v1 == v2 -> return
|
||||
return;
|
||||
if ((tri.v[2].x == tri.v[0].x)&&(tri.v[2].y == tri.v[0].y)&&(tri.v[2].z == tri.v[0].z)) // v2 == v0 -> return
|
||||
return;
|
||||
// clear!
|
||||
//
|
||||
// check for no-more-room
|
||||
if (n_triangles == max_triangles)
|
||||
{
|
||||
// create more space by doubling the capacity of this geometry...
|
||||
int i;
|
||||
max_triangles = 1 + max_triangles * 2;
|
||||
Triangle* old_triangles = triangles;
|
||||
Triangle* new_triangles = (Triangle *) malloc( max_triangles * sizeof(Triangle));
|
||||
|
||||
if (!new_triangles) // couldn't allocate space
|
||||
{
|
||||
NSLog(@" --- ran out of memory to allocate more geometry!");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
for (i = 0; i < n_triangles; i++)
|
||||
new_triangles[i] = old_triangles[i]; // copy old->new
|
||||
triangles = new_triangles;
|
||||
free((void *) old_triangles); // free up previous memory
|
||||
}
|
||||
triangles[n_triangles++] = tri;
|
||||
}
|
||||
|
||||
- (BOOL) testHasGeometry
|
||||
{
|
||||
return (n_triangles > 0);
|
||||
}
|
||||
|
||||
- (BOOL) testIsConvex
|
||||
{
|
||||
// enumerate over triangles
|
||||
// calculate normal for each one
|
||||
// then enumerate over vertices relative to a vertex on the triangle
|
||||
// and check if they are on the forwardside or coplanar with the triangle
|
||||
// if a vertex is on the backside of any triangle then return NO;
|
||||
int i, j;
|
||||
for (i = 0; i < n_triangles; i++)
|
||||
{
|
||||
Vector v0 = triangles[i].v[0];
|
||||
Vector vn = calculateNormalForTriangle(&triangles[i]);
|
||||
//
|
||||
for (j = 0; j < n_triangles; j++)
|
||||
{
|
||||
if (j != i)
|
||||
{
|
||||
if ((dot_product( vector_between( v0, triangles[j].v[0]), vn) < -0.001)||
|
||||
(dot_product( vector_between( v0, triangles[j].v[1]), vn) < -0.001)||
|
||||
(dot_product( vector_between( v0, triangles[j].v[2]), vn) < -0.001)) // within 1mm tolerance
|
||||
{
|
||||
isConvex = NO;
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
isConvex = YES;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL) testCornersWithinGeometry:(GLfloat) corner;
|
||||
{
|
||||
// enumerate over triangles
|
||||
// calculate normal for each one
|
||||
// then enumerate over corners relative to a vertex on the triangle
|
||||
// and check if they are on the forwardside or coplanar with the triangle
|
||||
// if a corner is on the backside of any triangle then return NO;
|
||||
int i, x, y, z;
|
||||
for (i = 0; i < n_triangles; i++)
|
||||
{
|
||||
Vector v0 = triangles[i].v[0];
|
||||
Vector vn = calculateNormalForTriangle(&triangles[i]);
|
||||
//
|
||||
for (z = -1; z < 2; z += 2) for (y = -1; y < 2; y += 2) for (x = -1; x < 2; x += 2)
|
||||
{
|
||||
Vector vc = make_vector( corner * x, corner * y, corner * z);
|
||||
if (dot_product( vector_between( v0, vc), vn) < -0.001)
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (GLfloat) findMaxDimensionFromOrigin
|
||||
{
|
||||
// enumerate over triangles
|
||||
GLfloat result = 0;
|
||||
int i, j;
|
||||
for (i = 0; i < n_triangles; i++) for (j = 0; j < 3; j++)
|
||||
{
|
||||
Vector v = triangles[i].v[j];
|
||||
if (fabs(v.x) > result)
|
||||
result = fabs(v.x);
|
||||
if (fabs(v.y) > result)
|
||||
result = fabs(v.y);
|
||||
if (fabs(v.z) > result)
|
||||
result = fabs(v.z);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int leafcount;
|
||||
static float volumecount;
|
||||
- (Octree*) findOctreeToDepth: (int) depth
|
||||
{
|
||||
//
|
||||
leafcount = 0;
|
||||
volumecount = 0.0;
|
||||
//
|
||||
GLfloat foundRadius = 0.5 + [self findMaxDimensionFromOrigin]; // pad out from geometry by a half meter
|
||||
//
|
||||
NSObject* foundOctree = [self octreeWithinRadius:foundRadius toDepth:depth];
|
||||
//
|
||||
// NSLog(@"octree found has %d leafs - object has volume %.2f mass %.2f", leafcount, volumecount, volumecount * 8.0);
|
||||
//
|
||||
Octree* octreeRepresentation = [[Octree alloc] initWithRepresentationOfOctree:foundRadius :foundOctree :leafcount];
|
||||
//
|
||||
return [octreeRepresentation autorelease];
|
||||
}
|
||||
|
||||
- (NSObject*) octreeWithinRadius:(GLfloat) octreeRadius toDepth: (int) depth;
|
||||
{
|
||||
//
|
||||
GLfloat offset = 0.5 * octreeRadius;
|
||||
//
|
||||
if (![self testHasGeometry])
|
||||
{
|
||||
leafcount++; // nil or zero or 0
|
||||
return [NSNumber numberWithBool:NO]; // empty octree
|
||||
}
|
||||
// there is geometry!
|
||||
//
|
||||
if ((octreeRadius <= OCTREE_MIN_RADIUS)||(depth <= 0)) // maximum resolution
|
||||
{
|
||||
leafcount++; // partially full or -1
|
||||
volumecount += octreeRadius * octreeRadius * octreeRadius * 0.5;
|
||||
return [NSNumber numberWithBool:YES]; // at least partially full octree
|
||||
}
|
||||
//
|
||||
if (!isConvex)
|
||||
[self testIsConvex]; // check!
|
||||
//
|
||||
if (isConvex) // we're convex!
|
||||
{
|
||||
if ([self testCornersWithinGeometry: octreeRadius]) // all eight corners inside or on!
|
||||
{
|
||||
leafcount++; // full or -1
|
||||
volumecount += octreeRadius * octreeRadius * octreeRadius;
|
||||
return [NSNumber numberWithBool:YES]; // full octree
|
||||
}
|
||||
}
|
||||
//
|
||||
Geometry* g_000 = [[Geometry alloc] initWithCapacity:n_triangles];
|
||||
Geometry* g_001 = [[Geometry alloc] initWithCapacity:n_triangles];
|
||||
Geometry* g_010 = [[Geometry alloc] initWithCapacity:n_triangles];
|
||||
Geometry* g_011 = [[Geometry alloc] initWithCapacity:n_triangles];
|
||||
Geometry* g_100 = [[Geometry alloc] initWithCapacity:n_triangles];
|
||||
Geometry* g_101 = [[Geometry alloc] initWithCapacity:n_triangles];
|
||||
Geometry* g_110 = [[Geometry alloc] initWithCapacity:n_triangles];
|
||||
Geometry* g_111 = [[Geometry alloc] initWithCapacity:n_triangles];
|
||||
//
|
||||
Geometry* g_xx1 = [[Geometry alloc] initWithCapacity:n_triangles];
|
||||
Geometry* g_xx0 = [[Geometry alloc] initWithCapacity:n_triangles];
|
||||
//
|
||||
[self z_axisSplitBetween:g_xx1 :g_xx0 : offset];
|
||||
if ([g_xx0 testHasGeometry])
|
||||
{
|
||||
Geometry* g_x00 = [[Geometry alloc] initWithCapacity:n_triangles];
|
||||
Geometry* g_x10 = [[Geometry alloc] initWithCapacity:n_triangles];
|
||||
//
|
||||
[g_xx0 y_axisSplitBetween: g_x10 : g_x00 : offset];
|
||||
if ([g_x00 testHasGeometry])
|
||||
{
|
||||
[g_x00 x_axisSplitBetween:g_100 :g_000 : offset];
|
||||
[g_000 setConvex: isConvex];
|
||||
[g_100 setConvex: isConvex];
|
||||
}
|
||||
if ([g_x10 testHasGeometry])
|
||||
{
|
||||
[g_x10 x_axisSplitBetween:g_110 :g_010 : offset];
|
||||
[g_010 setConvex: isConvex];
|
||||
[g_110 setConvex: isConvex];
|
||||
}
|
||||
[g_x00 release];
|
||||
[g_x10 release];
|
||||
}
|
||||
if ([g_xx1 testHasGeometry])
|
||||
{
|
||||
Geometry* g_x01 = [[Geometry alloc] initWithCapacity:n_triangles];
|
||||
Geometry* g_x11 = [[Geometry alloc] initWithCapacity:n_triangles];
|
||||
//
|
||||
[g_xx1 y_axisSplitBetween: g_x11 : g_x01 :offset];
|
||||
if ([g_x01 testHasGeometry])
|
||||
{
|
||||
[g_x01 x_axisSplitBetween:g_101 :g_001 :offset];
|
||||
[g_001 setConvex: isConvex];
|
||||
[g_101 setConvex: isConvex];
|
||||
}
|
||||
if ([g_x11 testHasGeometry])
|
||||
{
|
||||
[g_x11 x_axisSplitBetween:g_111 :g_011 :offset];
|
||||
[g_011 setConvex: isConvex];
|
||||
[g_111 setConvex: isConvex];
|
||||
}
|
||||
[g_x01 release];
|
||||
[g_x11 release];
|
||||
}
|
||||
[g_xx0 release];
|
||||
[g_xx1 release];
|
||||
|
||||
leafcount++; // pointer to array
|
||||
NSObject* result = [NSArray arrayWithObjects:
|
||||
[g_000 octreeWithinRadius: offset toDepth:depth - 1],
|
||||
[g_001 octreeWithinRadius: offset toDepth:depth - 1],
|
||||
[g_010 octreeWithinRadius: offset toDepth:depth - 1],
|
||||
[g_011 octreeWithinRadius: offset toDepth:depth - 1],
|
||||
[g_100 octreeWithinRadius: offset toDepth:depth - 1],
|
||||
[g_101 octreeWithinRadius: offset toDepth:depth - 1],
|
||||
[g_110 octreeWithinRadius: offset toDepth:depth - 1],
|
||||
[g_111 octreeWithinRadius: offset toDepth:depth - 1],
|
||||
nil];
|
||||
[g_000 release];
|
||||
[g_001 release];
|
||||
[g_010 release];
|
||||
[g_011 release];
|
||||
[g_100 release];
|
||||
[g_101 release];
|
||||
[g_110 release];
|
||||
[g_111 release];
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void) translate:(Vector) offset
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n_triangles; i++)
|
||||
{
|
||||
triangles[i].v[0].x += offset.x;
|
||||
triangles[i].v[1].x += offset.x;
|
||||
triangles[i].v[2].x += offset.x;
|
||||
|
||||
triangles[i].v[0].y += offset.y;
|
||||
triangles[i].v[1].y += offset.y;
|
||||
triangles[i].v[2].y += offset.y;
|
||||
|
||||
triangles[i].v[0].z += offset.z;
|
||||
triangles[i].v[1].z += offset.z;
|
||||
triangles[i].v[2].z += offset.z;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) scale:(GLfloat) scalar
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n_triangles; i++)
|
||||
{
|
||||
triangles[i].v[0].x *= scalar;
|
||||
triangles[i].v[1].x *= scalar;
|
||||
triangles[i].v[2].x *= scalar;
|
||||
triangles[i].v[0].y *= scalar;
|
||||
triangles[i].v[1].y *= scalar;
|
||||
triangles[i].v[2].y *= scalar;
|
||||
triangles[i].v[0].z *= scalar;
|
||||
triangles[i].v[1].z *= scalar;
|
||||
triangles[i].v[2].z *= scalar;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) x_axisSplitBetween:(Geometry*) g_plus :(Geometry*) g_minus :(GLfloat) x;
|
||||
{
|
||||
// test each triangle splitting against x == 0.0
|
||||
//
|
||||
int i;
|
||||
for (i = 0; i < n_triangles; i++)
|
||||
{
|
||||
BOOL done_tri = NO;
|
||||
Vector v0 = triangles[i].v[0];
|
||||
Vector v1 = triangles[i].v[1];
|
||||
Vector v2 = triangles[i].v[2];
|
||||
|
||||
if ((v0.x >= 0.0)&&(v1.x >= 0.0)&&(v2.x >= 0.0))
|
||||
{
|
||||
[g_plus addTriangle: triangles[i]];
|
||||
done_tri = YES;
|
||||
}
|
||||
if ((v0.x <= 0.0)&&(v1.x <= 0.0)&&(v2.x <= 0.0))
|
||||
{
|
||||
[g_minus addTriangle: triangles[i]];
|
||||
done_tri = YES;
|
||||
}
|
||||
if (!done_tri) // triangle must cross y == 0.0
|
||||
{
|
||||
GLfloat i01, i12, i20;
|
||||
if (v0.x == v1.x)
|
||||
i01 = -1.0;
|
||||
else
|
||||
i01 = v0.x / (v0.x - v1.x);
|
||||
if (v1.x == v2.x)
|
||||
i12 = -1.0;
|
||||
else
|
||||
i12 = v1.x / (v1.x - v2.x);
|
||||
if (v2.x == v0.x)
|
||||
i20 = -1.0;
|
||||
else
|
||||
i20 = v2.x / (v2.x - v0.x);
|
||||
Vector v01 = make_vector( 0.0, i01 * (v1.y - v0.y) + v0.y, i01 * (v1.z - v0.z) + v0.z);
|
||||
Vector v12 = make_vector( 0.0, i12 * (v2.y - v1.y) + v1.y, i12 * (v2.z - v1.z) + v1.z);
|
||||
Vector v20 = make_vector( 0.0, i20 * (v0.y - v2.y) + v2.y, i20 * (v0.z - v2.z) + v2.z);
|
||||
|
||||
// cases where a vertex is on the split..
|
||||
if (v0.x == 0.0)
|
||||
{
|
||||
if (v1.x > 0)
|
||||
{
|
||||
[g_plus addTriangle:make_triangle(v0, v1, v12)];
|
||||
[g_minus addTriangle:make_triangle(v0, v12, v2)];
|
||||
}
|
||||
else
|
||||
{
|
||||
[g_minus addTriangle:make_triangle(v0, v1, v12)];
|
||||
[g_plus addTriangle:make_triangle(v0, v12, v2)];
|
||||
}
|
||||
}
|
||||
if (v1.x == 0.0)
|
||||
{
|
||||
if (v2.x > 0)
|
||||
{
|
||||
[g_plus addTriangle:make_triangle(v1, v2, v20)];
|
||||
[g_minus addTriangle:make_triangle(v1, v20, v0)];
|
||||
}
|
||||
else
|
||||
{
|
||||
[g_minus addTriangle:make_triangle(v1, v2, v20)];
|
||||
[g_plus addTriangle:make_triangle(v1, v20, v0)];
|
||||
}
|
||||
}
|
||||
if (v2.x == 0.0)
|
||||
{
|
||||
if (v0.x > 0)
|
||||
{
|
||||
[g_plus addTriangle:make_triangle(v2, v0, v01)];
|
||||
[g_minus addTriangle:make_triangle(v2, v01, v1)];
|
||||
}
|
||||
else
|
||||
{
|
||||
[g_minus addTriangle:make_triangle(v2, v0, v01)];
|
||||
[g_plus addTriangle:make_triangle(v2, v01, v1)];
|
||||
}
|
||||
}
|
||||
|
||||
if ((v0.x > 0.0)&&(v1.x > 0.0)&&(v2.x < 0.0))
|
||||
{
|
||||
[g_plus addTriangle:make_triangle( v0, v12, v20)];
|
||||
[g_plus addTriangle:make_triangle( v0, v1, v12)];
|
||||
[g_minus addTriangle:make_triangle( v20, v12, v2)];
|
||||
}
|
||||
|
||||
if ((v0.x > 0.0)&&(v1.x < 0.0)&&(v2.x > 0.0))
|
||||
{
|
||||
[g_plus addTriangle:make_triangle( v2, v01, v12)];
|
||||
[g_plus addTriangle:make_triangle( v2, v0, v01)];
|
||||
[g_minus addTriangle:make_triangle( v12, v01, v1)];
|
||||
}
|
||||
|
||||
if ((v0.x > 0.0)&&(v1.x < 0.0)&&(v2.x < 0.0))
|
||||
{
|
||||
[g_plus addTriangle:make_triangle( v20, v0, v01)];
|
||||
[g_minus addTriangle:make_triangle( v2, v20, v1)];
|
||||
[g_minus addTriangle:make_triangle( v20, v01, v1)];
|
||||
}
|
||||
|
||||
if ((v0.x < 0.0)&&(v1.x > 0.0)&&(v2.x > 0.0))
|
||||
{
|
||||
[g_minus addTriangle:make_triangle( v01, v20, v0)];
|
||||
[g_plus addTriangle:make_triangle( v1, v20, v01)];
|
||||
[g_plus addTriangle:make_triangle( v1, v2, v20)];
|
||||
}
|
||||
|
||||
if ((v0.x < 0.0)&&(v1.x > 0.0)&&(v2.x < 0.0))
|
||||
{
|
||||
[g_plus addTriangle:make_triangle( v01, v1, v12)];
|
||||
[g_minus addTriangle:make_triangle( v0, v01, v2)];
|
||||
[g_minus addTriangle:make_triangle( v01, v12, v2)];
|
||||
}
|
||||
|
||||
if ((v0.x < 0.0)&&(v1.x < 0.0)&&(v2.x > 0.0))
|
||||
{
|
||||
[g_plus addTriangle:make_triangle( v12, v2, v20)];
|
||||
[g_minus addTriangle:make_triangle( v1, v12, v0)];
|
||||
[g_minus addTriangle:make_triangle( v12, v20, v0)];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
[g_plus translate: make_vector( -x, 0.0, 0.0)];
|
||||
[g_minus translate: make_vector( x, 0.0, 0.0)];
|
||||
}
|
||||
|
||||
- (void) y_axisSplitBetween:(Geometry*) g_plus :(Geometry*) g_minus :(GLfloat) y;
|
||||
{
|
||||
// test each triangle splitting against y == 0.0
|
||||
//
|
||||
int i;
|
||||
for (i = 0; i < n_triangles; i++)
|
||||
{
|
||||
BOOL done_tri = NO;
|
||||
Vector v0 = triangles[i].v[0];
|
||||
Vector v1 = triangles[i].v[1];
|
||||
Vector v2 = triangles[i].v[2];
|
||||
|
||||
if ((v0.y >= 0.0)&&(v1.y >= 0.0)&&(v2.y >= 0.0))
|
||||
{
|
||||
[g_plus addTriangle: triangles[i]];
|
||||
done_tri = YES;
|
||||
}
|
||||
if ((v0.y <= 0.0)&&(v1.y <= 0.0)&&(v2.y <= 0.0))
|
||||
{
|
||||
[g_minus addTriangle: triangles[i]];
|
||||
done_tri = YES;
|
||||
}
|
||||
if (!done_tri) // triangle must cross y == 0.0
|
||||
{
|
||||
GLfloat i01, i12, i20;
|
||||
if (v0.y == v1.y)
|
||||
i01 = -1.0;
|
||||
else
|
||||
i01 = v0.y / (v0.y - v1.y);
|
||||
if (v1.y == v2.y)
|
||||
i12 = -1.0;
|
||||
else
|
||||
i12 = v1.y / (v1.y - v2.y);
|
||||
if (v2.y == v0.y)
|
||||
i20 = -1.0;
|
||||
else
|
||||
i20 = v2.y / (v2.y - v0.y);
|
||||
Vector v01 = make_vector( i01 * (v1.x - v0.x) + v0.x, 0.0, i01 * (v1.z - v0.z) + v0.z);
|
||||
Vector v12 = make_vector( i12 * (v2.x - v1.x) + v1.x, 0.0, i12 * (v2.z - v1.z) + v1.z);
|
||||
Vector v20 = make_vector( i20 * (v0.x - v2.x) + v2.x, 0.0, i20 * (v0.z - v2.z) + v2.z);
|
||||
|
||||
// cases where a vertex is on the split..
|
||||
if (v0.y == 0.0)
|
||||
{
|
||||
if (v1.y > 0)
|
||||
{
|
||||
[g_plus addTriangle:make_triangle(v0, v1, v12)];
|
||||
[g_minus addTriangle:make_triangle(v0, v12, v2)];
|
||||
}
|
||||
else
|
||||
{
|
||||
[g_minus addTriangle:make_triangle(v0, v1, v12)];
|
||||
[g_plus addTriangle:make_triangle(v0, v12, v2)];
|
||||
}
|
||||
}
|
||||
if (v1.y == 0.0)
|
||||
{
|
||||
if (v2.y > 0)
|
||||
{
|
||||
[g_plus addTriangle:make_triangle(v1, v2, v20)];
|
||||
[g_minus addTriangle:make_triangle(v1, v20, v0)];
|
||||
}
|
||||
else
|
||||
{
|
||||
[g_minus addTriangle:make_triangle(v1, v2, v20)];
|
||||
[g_plus addTriangle:make_triangle(v1, v20, v0)];
|
||||
}
|
||||
}
|
||||
if (v2.y == 0.0)
|
||||
{
|
||||
if (v0.y > 0)
|
||||
{
|
||||
[g_plus addTriangle:make_triangle(v2, v0, v01)];
|
||||
[g_minus addTriangle:make_triangle(v2, v01, v1)];
|
||||
}
|
||||
else
|
||||
{
|
||||
[g_minus addTriangle:make_triangle(v2, v0, v01)];
|
||||
[g_plus addTriangle:make_triangle(v2, v01, v1)];
|
||||
}
|
||||
}
|
||||
|
||||
if ((v0.y > 0.0)&&(v1.y > 0.0)&&(v2.y < 0.0))
|
||||
{
|
||||
[g_plus addTriangle:make_triangle( v0, v12, v20)];
|
||||
[g_plus addTriangle:make_triangle( v0, v1, v12)];
|
||||
[g_minus addTriangle:make_triangle( v20, v12, v2)];
|
||||
}
|
||||
|
||||
if ((v0.y > 0.0)&&(v1.y < 0.0)&&(v2.y > 0.0))
|
||||
{
|
||||
[g_plus addTriangle:make_triangle( v2, v01, v12)];
|
||||
[g_plus addTriangle:make_triangle( v2, v0, v01)];
|
||||
[g_minus addTriangle:make_triangle( v12, v01, v1)];
|
||||
}
|
||||
|
||||
if ((v0.y > 0.0)&&(v1.y < 0.0)&&(v2.y < 0.0))
|
||||
{
|
||||
[g_plus addTriangle:make_triangle( v20, v0, v01)];
|
||||
[g_minus addTriangle:make_triangle( v2, v20, v1)];
|
||||
[g_minus addTriangle:make_triangle( v20, v01, v1)];
|
||||
}
|
||||
|
||||
if ((v0.y < 0.0)&&(v1.y > 0.0)&&(v2.y > 0.0))
|
||||
{
|
||||
[g_minus addTriangle:make_triangle( v01, v20, v0)];
|
||||
[g_plus addTriangle:make_triangle( v1, v20, v01)];
|
||||
[g_plus addTriangle:make_triangle( v1, v2, v20)];
|
||||
}
|
||||
|
||||
if ((v0.y < 0.0)&&(v1.y > 0.0)&&(v2.y < 0.0))
|
||||
{
|
||||
[g_plus addTriangle:make_triangle( v01, v1, v12)];
|
||||
[g_minus addTriangle:make_triangle( v0, v01, v2)];
|
||||
[g_minus addTriangle:make_triangle( v01, v12, v2)];
|
||||
}
|
||||
|
||||
if ((v0.y < 0.0)&&(v1.y < 0.0)&&(v2.y > 0.0))
|
||||
{
|
||||
[g_plus addTriangle:make_triangle( v12, v2, v20)];
|
||||
[g_minus addTriangle:make_triangle( v1, v12, v0)];
|
||||
[g_minus addTriangle:make_triangle( v12, v20, v0)];
|
||||
}
|
||||
}
|
||||
}
|
||||
[g_plus translate: make_vector( 0.0, -y, 0.0)];
|
||||
[g_minus translate: make_vector( 0.0, y, 0.0)];
|
||||
}
|
||||
|
||||
- (void) z_axisSplitBetween:(Geometry*) g_plus :(Geometry*) g_minus :(GLfloat) z
|
||||
{
|
||||
// test each triangle splitting against z == 0.0
|
||||
//
|
||||
int i;
|
||||
for (i = 0; i < n_triangles; i++)
|
||||
{
|
||||
BOOL done_tri = NO;
|
||||
Vector v0 = triangles[i].v[0];
|
||||
Vector v1 = triangles[i].v[1];
|
||||
Vector v2 = triangles[i].v[2];
|
||||
|
||||
if ((v0.z >= 0.0)&&(v1.z >= 0.0)&&(v2.z >= 0.0))
|
||||
{
|
||||
[g_plus addTriangle: triangles[i]];
|
||||
done_tri = YES;
|
||||
}
|
||||
if ((v0.z <= 0.0)&&(v1.z <= 0.0)&&(v2.z <= 0.0))
|
||||
{
|
||||
[g_minus addTriangle: triangles[i]];
|
||||
done_tri = YES;
|
||||
}
|
||||
if (!done_tri) // triangle must cross y == 0.0
|
||||
{
|
||||
GLfloat i01, i12, i20;
|
||||
if (v0.z == v1.z)
|
||||
i01 = -1.0;
|
||||
else
|
||||
i01 = v0.z / (v0.z - v1.z);
|
||||
if (v1.z == v2.z)
|
||||
i12 = -1.0;
|
||||
else
|
||||
i12 = v1.z / (v1.z - v2.z);
|
||||
if (v2.z == v0.z)
|
||||
i20 = -1.0;
|
||||
else
|
||||
i20 = v2.z / (v2.z - v0.z);
|
||||
Vector v01 = make_vector( i01 * (v1.x - v0.x) + v0.x, i01 * (v1.y - v0.y) + v0.y, 0.0);
|
||||
Vector v12 = make_vector( i12 * (v2.x - v1.x) + v1.x, i12 * (v2.y - v1.y) + v1.y, 0.0);
|
||||
Vector v20 = make_vector( i20 * (v0.x - v2.x) + v2.x, i20 * (v0.y - v2.y) + v2.y, 0.0);
|
||||
|
||||
// cases where a vertex is on the split..
|
||||
if (v0.z == 0.0)
|
||||
{
|
||||
if (v1.z > 0)
|
||||
{
|
||||
[g_plus addTriangle:make_triangle(v0, v1, v12)];
|
||||
[g_minus addTriangle:make_triangle(v0, v12, v2)];
|
||||
}
|
||||
else
|
||||
{
|
||||
[g_minus addTriangle:make_triangle(v0, v1, v12)];
|
||||
[g_plus addTriangle:make_triangle(v0, v12, v2)];
|
||||
}
|
||||
}
|
||||
if (v1.z == 0.0)
|
||||
{
|
||||
if (v2.z > 0)
|
||||
{
|
||||
[g_plus addTriangle:make_triangle(v1, v2, v20)];
|
||||
[g_minus addTriangle:make_triangle(v1, v20, v0)];
|
||||
}
|
||||
else
|
||||
{
|
||||
[g_minus addTriangle:make_triangle(v1, v2, v20)];
|
||||
[g_plus addTriangle:make_triangle(v1, v20, v0)];
|
||||
}
|
||||
}
|
||||
if (v2.z == 0.0)
|
||||
{
|
||||
if (v0.z > 0)
|
||||
{
|
||||
[g_plus addTriangle:make_triangle(v2, v0, v01)];
|
||||
[g_minus addTriangle:make_triangle(v2, v01, v1)];
|
||||
}
|
||||
else
|
||||
{
|
||||
[g_minus addTriangle:make_triangle(v2, v0, v01)];
|
||||
[g_plus addTriangle:make_triangle(v2, v01, v1)];
|
||||
}
|
||||
}
|
||||
|
||||
if ((v0.z > 0.0)&&(v1.z > 0.0)&&(v2.z < 0.0))
|
||||
{
|
||||
[g_plus addTriangle:make_triangle( v0, v12, v20)];
|
||||
[g_plus addTriangle:make_triangle( v0, v1, v12)];
|
||||
[g_minus addTriangle:make_triangle( v20, v12, v2)];
|
||||
}
|
||||
|
||||
if ((v0.z > 0.0)&&(v1.z < 0.0)&&(v2.z > 0.0))
|
||||
{
|
||||
[g_plus addTriangle:make_triangle( v2, v01, v12)];
|
||||
[g_plus addTriangle:make_triangle( v2, v0, v01)];
|
||||
[g_minus addTriangle:make_triangle( v12, v01, v1)];
|
||||
}
|
||||
|
||||
if ((v0.z > 0.0)&&(v1.z < 0.0)&&(v2.z < 0.0))
|
||||
{
|
||||
[g_plus addTriangle:make_triangle( v20, v0, v01)];
|
||||
[g_minus addTriangle:make_triangle( v2, v20, v1)];
|
||||
[g_minus addTriangle:make_triangle( v20, v01, v1)];
|
||||
}
|
||||
|
||||
if ((v0.z < 0.0)&&(v1.z > 0.0)&&(v2.z > 0.0))
|
||||
{
|
||||
[g_minus addTriangle:make_triangle( v01, v20, v0)];
|
||||
[g_plus addTriangle:make_triangle( v1, v20, v01)];
|
||||
[g_plus addTriangle:make_triangle( v1, v2, v20)];
|
||||
}
|
||||
|
||||
if ((v0.z < 0.0)&&(v1.z > 0.0)&&(v2.z < 0.0))
|
||||
{
|
||||
[g_plus addTriangle:make_triangle( v01, v1, v12)];
|
||||
[g_minus addTriangle:make_triangle( v0, v01, v2)];
|
||||
[g_minus addTriangle:make_triangle( v01, v12, v2)];
|
||||
}
|
||||
|
||||
if ((v0.z < 0.0)&&(v1.z < 0.0)&&(v2.z > 0.0))
|
||||
{
|
||||
[g_plus addTriangle:make_triangle( v12, v2, v20)];
|
||||
[g_minus addTriangle:make_triangle( v1, v12, v0)];
|
||||
[g_minus addTriangle:make_triangle( v12, v20, v0)];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
[g_plus translate: make_vector( 0.0, 0.0, -z)];
|
||||
[g_minus translate: make_vector( 0.0, 0.0, z)];
|
||||
}
|
||||
|
||||
@end
|
@ -37,12 +37,7 @@ Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef GNUSTEP
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
#else
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
#import "OOCocoa.h"
|
||||
|
||||
#define GUI_MAX_ROWS 64
|
||||
#define GUI_MAX_COLUMNS 40
|
||||
@ -62,7 +57,7 @@ Your fair use and other rights are in no way affected by the above.
|
||||
#import "OpenGLSprite.h"
|
||||
#import "HeadUpDisplay.h"
|
||||
|
||||
@class Universe;
|
||||
@class Universe, OOSound;
|
||||
|
||||
extern int debug;
|
||||
|
||||
@ -79,7 +74,7 @@ extern int debug;
|
||||
BOOL has_title;
|
||||
NSSize pixel_title_size;
|
||||
|
||||
NSSound *guiclick;
|
||||
OOSound *guiclick;
|
||||
|
||||
NSImage *backgroundImage;
|
||||
NSColor *backgroundColor;
|
@ -41,6 +41,8 @@ Your fair use and other rights are in no way affected by the above.
|
||||
#import "Universe.h"
|
||||
#import "OpenGLSprite.h"
|
||||
#import "ResourceManager.h"
|
||||
#import "OOSound.h"
|
||||
|
||||
|
||||
@implementation GuiDisplayGen
|
||||
|
||||
@ -89,7 +91,7 @@ Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
title = @"Test Page";
|
||||
|
||||
guiclick = [[ResourceManager soundNamed:@"guiclick.ogg" inFolder:@"Sounds"] retain];
|
||||
guiclick = [[ResourceManager ooSoundNamed:@"guiclick.ogg" inFolder:@"Sounds"] retain];
|
||||
|
||||
backgroundImage = nil;
|
||||
backgroundColor = nil;
|
||||
@ -137,7 +139,7 @@ Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
title = [gui_title retain];
|
||||
|
||||
guiclick = [[ResourceManager soundNamed:@"guiclick.ogg" inFolder:@"Sounds"] retain];
|
||||
guiclick = [[ResourceManager ooSoundNamed:@"guiclick.ogg" inFolder:@"Sounds"] retain];
|
||||
|
||||
backgroundImage = nil;
|
||||
backgroundColor = nil;
|
||||
@ -1000,7 +1002,7 @@ Your fair use and other rights are in no way affected by the above.
|
||||
star.x = g_seed.d * hscale + hoffset;
|
||||
star.y = g_seed.b * vscale + voffset;
|
||||
|
||||
double sz = (4.0 + 0.5 * (0x03 | g_seed.f & 0x0f)) / 7.0;
|
||||
double sz = (4.0 + 0.5 * (0x03 | (g_seed.f & 0x0f))) / 7.0;
|
||||
|
||||
glVertex3f( x + star.x, y + star.y + sz, z);
|
||||
glVertex3f( x + star.x + sz, y + star.y, z);
|
@ -38,16 +38,9 @@ Any of these conditions can be waived if you get permission from the copyright h
|
||||
Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
*/
|
||||
//
|
||||
|
||||
#ifdef LINUX
|
||||
#include "oolite-linux.h"
|
||||
#else
|
||||
#import <OpenGL/gl.h>
|
||||
#import <OpenGL/glu.h>
|
||||
#endif
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "OOOpenGL.h"
|
||||
|
||||
#import "vector.h"
|
||||
#import "MyOpenGLView.h"
|
||||
@ -63,13 +56,15 @@ Your fair use and other rights are in no way affected by the above.
|
||||
#define SCANNER_ZOOM_LEVELS 5
|
||||
#define ZOOM_INDICATOR_CENTRE_X 108
|
||||
#define ZOOM_INDICATOR_CENTRE_Y -216
|
||||
#define ZOOM_INDICATOR_WIDTH 11.0f
|
||||
#define ZOOM_INDICATOR_HEIGHT 14.0f
|
||||
#define ZOOM_LEVELS_IMAGE @"zoom.png"
|
||||
|
||||
#define COMPASS_IMAGE @"compass.png"
|
||||
#define COMPASS_CENTRE_X 132
|
||||
#define COMPASS_CENTRE_Y -216
|
||||
#define COMPASS_SIZE 64
|
||||
#define COMPASS_HALF_SIZE 32
|
||||
#define COMPASS_SIZE 56
|
||||
#define COMPASS_HALF_SIZE 28
|
||||
#define COMPASS_REDDOT_IMAGE @"reddot.png"
|
||||
#define COMPASS_GREENDOT_IMAGE @"greendot.png"
|
||||
#define COMPASS_DOT_SIZE 16
|
||||
@ -78,6 +73,8 @@ Your fair use and other rights are in no way affected by the above.
|
||||
#define AEGIS_IMAGE @"aegis.png"
|
||||
#define AEGIS_CENTRE_X -132
|
||||
#define AEGIS_CENTRE_Y -216
|
||||
#define AEGIS_WIDTH 24
|
||||
#define AEGIS_HEIGHT 24
|
||||
|
||||
#define SPEED_BAR_CENTRE_X 200
|
||||
#define SPEED_BAR_CENTRE_Y -145
|
||||
@ -158,6 +155,11 @@ Your fair use and other rights are in no way affected by the above.
|
||||
#define HIT_INDICATOR_CENTRE_X 200
|
||||
#define HIT_INDICATOR_CENTRE_Y 0
|
||||
|
||||
#define SCOOPSTATUS_CENTRE_X -132
|
||||
#define SCOOPSTATUS_CENTRE_Y -152
|
||||
#define SCOOPSTATUS_WIDTH 16.0
|
||||
#define SCOOPSTATUS_HEIGHT 16.0
|
||||
|
||||
#define DIALS_KEY @"dials"
|
||||
#define LEGENDS_KEY @"legends"
|
||||
#define X_KEY @"x"
|
||||
@ -191,15 +193,11 @@ extern int debug;
|
||||
@interface HeadUpDisplay : NSObject {
|
||||
|
||||
PlayerEntity* player;
|
||||
|
||||
OpenGLSprite *compassSprite;
|
||||
OpenGLSprite *aegisSprite;
|
||||
|
||||
NSMutableArray *legendArray;
|
||||
NSMutableArray *dialArray;
|
||||
|
||||
// zoom indicators
|
||||
OpenGLSprite* zoomLevelSprite[SCANNER_ZOOM_LEVELS];
|
||||
// zoom level
|
||||
double scanner_zoom;
|
||||
|
||||
//where to draw it
|
||||
@ -254,6 +252,7 @@ extern int debug;
|
||||
- (void) drawDirectionCue:(NSDictionary *) info;
|
||||
- (void) drawClock:(NSDictionary *) info;
|
||||
- (void) drawFPSInfoCounter:(NSDictionary *) info;
|
||||
- (void) drawScoopStatus:(NSDictionary *) info;
|
||||
|
||||
- (void) drawGreenSurround:(NSDictionary *) info;
|
||||
- (void) drawYellowSurround:(NSDictionary *) info;
|
@ -42,8 +42,9 @@ Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
#import "HeadUpDisplay.h"
|
||||
#import "ResourceManager.h"
|
||||
#import "OpenGLSprite.h"
|
||||
//#import "OpenGLSprite.h"
|
||||
#import "PlayerEntity.h"
|
||||
#import "PlanetEntity.h"
|
||||
#import "Universe.h"
|
||||
#import "TextureStore.h"
|
||||
#import "OOTrumble.h"
|
||||
@ -56,6 +57,7 @@ GLfloat red_color[4] = {1.0, 0.0, 0.0, 1.0};
|
||||
GLfloat redplus_color[4] = {1.0, 0.0, 0.5, 1.0};
|
||||
GLfloat yellow_color[4] = {1.0, 1.0, 0.0, 1.0};
|
||||
GLfloat green_color[4] = {0.0, 1.0, 0.0, 1.0};
|
||||
GLfloat darkgreen_color[4] ={0.0, 0.75, 0.0, 1.0};
|
||||
GLfloat blue_color[4] = {0.0, 0.0, 1.0, 1.0};
|
||||
|
||||
float char_widths[128] = {
|
||||
@ -78,8 +80,7 @@ float char_widths[128] = {
|
||||
|
||||
line_width = 1.0;
|
||||
|
||||
for (i = 0; i < 360; i++)
|
||||
sin_value[i] = sin(i * PI / 180); // also used by PlanetEntity, but can't hurt to init it here too!
|
||||
setUpSinTable();
|
||||
|
||||
// int ch;
|
||||
// NSMutableDictionary *stringAttributes = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
@ -106,42 +107,7 @@ float char_widths[128] = {
|
||||
// printf(",");
|
||||
// }
|
||||
// printf("\n\n");
|
||||
|
||||
// // init sprites
|
||||
#ifndef WIN32
|
||||
compassSprite = [[OpenGLSprite alloc] initWithImage:[ResourceManager imageNamed:COMPASS_IMAGE inFolder:@"Images"]
|
||||
cropRectangle:NSMakeRect(0, 0, COMPASS_SIZE, COMPASS_SIZE)
|
||||
size:NSMakeSize(COMPASS_HALF_SIZE, COMPASS_HALF_SIZE)]; // alloc retains
|
||||
aegisSprite = [[OpenGLSprite alloc] initWithImage:[ResourceManager imageNamed:AEGIS_IMAGE inFolder:@"Images"]
|
||||
cropRectangle:NSMakeRect(0, 0, 32, 32)
|
||||
size:NSMakeSize(32, 32)]; // alloc retains
|
||||
NSImage *zoomLevelImage = [ResourceManager imageNamed:ZOOM_LEVELS_IMAGE inFolder:@"Images"];
|
||||
int w1 = [zoomLevelImage size].width / SCANNER_ZOOM_LEVELS;
|
||||
int h1 = [zoomLevelImage size].height;
|
||||
for (i = 0; i < SCANNER_ZOOM_LEVELS; i++)
|
||||
{
|
||||
zoomLevelSprite[i] = [[OpenGLSprite alloc] initWithImage:zoomLevelImage
|
||||
cropRectangle:NSMakeRect(w1*i, 0, w1, h1)
|
||||
size:NSMakeSize(16, 16)]; // alloc retains
|
||||
}
|
||||
#else
|
||||
compassSprite = [[OpenGLSprite alloc] initWithSurface:[ResourceManager surfaceNamed:COMPASS_IMAGE inFolder:@"Images"]
|
||||
cropRectangle:NSMakeRect(0, 0, COMPASS_SIZE, COMPASS_SIZE)
|
||||
size:NSMakeSize(COMPASS_HALF_SIZE, COMPASS_HALF_SIZE)]; // alloc retains
|
||||
aegisSprite = [[OpenGLSprite alloc] initWithSurface:[ResourceManager surfaceNamed:AEGIS_IMAGE inFolder:@"Images"]
|
||||
cropRectangle:NSMakeRect(0, 0, 32, 32)
|
||||
size:NSMakeSize(32, 32)]; // alloc retains
|
||||
SDLImage *zoomLevelImage = [ResourceManager surfaceNamed:ZOOM_LEVELS_IMAGE inFolder:@"Images"];
|
||||
int w1 = [zoomLevelImage size].width / SCANNER_ZOOM_LEVELS;
|
||||
int h1 = [zoomLevelImage size].height;
|
||||
for (i = 0; i < SCANNER_ZOOM_LEVELS; i++)
|
||||
{
|
||||
zoomLevelSprite[i] = [[OpenGLSprite alloc] initWithSurface:zoomLevelImage
|
||||
cropRectangle:NSMakeRect(w1*i, 0, w1, h1)
|
||||
size:NSMakeSize(16, 16)]; // alloc retains
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// init arrays
|
||||
dialArray = [[NSMutableArray alloc] initWithCapacity:16]; // alloc retains
|
||||
legendArray = [[NSMutableArray alloc] initWithCapacity:16]; // alloc retains
|
||||
@ -178,12 +144,6 @@ float char_widths[128] = {
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
int i;
|
||||
if (compassSprite) [compassSprite release];
|
||||
if (aegisSprite) [aegisSprite release];
|
||||
|
||||
for (i = 0; i < SCANNER_ZOOM_LEVELS; i++) if (zoomLevelSprite[i]) [zoomLevelSprite[i] release];
|
||||
|
||||
if (legendArray) [legendArray release];
|
||||
if (dialArray) [dialArray release];
|
||||
|
||||
@ -215,7 +175,6 @@ GLuint ascii_texture_name;
|
||||
if ([info objectForKey:IMAGE_KEY])
|
||||
{
|
||||
//NSLog(@"DEBUG adding Legend %@",[info objectForKey:IMAGE_KEY]);
|
||||
#ifndef WIN32
|
||||
NSImage *legendImage = [ResourceManager imageNamed:(NSString *)[info objectForKey:IMAGE_KEY] inFolder:@"Images"];
|
||||
NSSize imageSize = [legendImage size];
|
||||
NSSize spriteSize = imageSize;
|
||||
@ -225,18 +184,6 @@ GLuint ascii_texture_name;
|
||||
spriteSize.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
|
||||
OpenGLSprite *legendSprite = [[OpenGLSprite alloc] initWithImage:legendImage
|
||||
cropRectangle:NSMakeRect(0, 0, imageSize.width, imageSize.height) size:spriteSize]; // retained
|
||||
#else
|
||||
SDLImage *legendImage = [ResourceManager surfaceNamed:(NSString *)[info objectForKey:IMAGE_KEY] inFolder:@"Images"];
|
||||
NSSize imageSize = [legendImage size];
|
||||
NSSize spriteSize = imageSize;
|
||||
if ([info objectForKey:WIDTH_KEY])
|
||||
spriteSize.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
|
||||
if ([info objectForKey:HEIGHT_KEY])
|
||||
spriteSize.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
|
||||
|
||||
OpenGLSprite *legendSprite = [[OpenGLSprite alloc] initWithSurface:legendImage
|
||||
cropRectangle:NSMakeRect(0, 0, imageSize.width, imageSize.height) size:spriteSize]; // retained
|
||||
#endif
|
||||
NSMutableDictionary *legendDict = [NSMutableDictionary dictionaryWithDictionary:info];
|
||||
[legendDict setObject:legendSprite forKey:SPRITE_KEY];
|
||||
[legendArray addObject:legendDict];
|
||||
@ -412,7 +359,9 @@ static BOOL hostiles;
|
||||
GLfloat off_scope2 = (siz.width > siz.height) ? siz.width * siz.width : siz.height * siz.height;
|
||||
|
||||
//
|
||||
if ([[player universe] viewDir] != VIEW_DOCKED)
|
||||
int p_status = player->status;
|
||||
|
||||
if ((p_status == STATUS_IN_FLIGHT)||(p_status == STATUS_AUTOPILOT_ENGAGED)||(p_status == STATUS_LAUNCHING)||(p_status == STATUS_WITCHSPACE_COUNTDOWN))
|
||||
{
|
||||
double upscale = scanner_zoom*1.25/scanner_scale;
|
||||
off_scope2 /= upscale * upscale;
|
||||
@ -593,47 +542,100 @@ static BOOL hostiles;
|
||||
|
||||
- (void) drawScannerZoomIndicator:(NSDictionary *) info
|
||||
{
|
||||
int x = ZOOM_INDICATOR_CENTRE_X;
|
||||
int y = ZOOM_INDICATOR_CENTRE_Y;
|
||||
double alpha = 1.0;
|
||||
GLfloat zoom_color[] = { 1.0f, 0.1f, 0.0f, 1.0f };
|
||||
GLfloat x = ZOOM_INDICATOR_CENTRE_X;
|
||||
GLfloat y = ZOOM_INDICATOR_CENTRE_Y;
|
||||
NSSize siz = NSMakeSize( ZOOM_INDICATOR_WIDTH, ZOOM_INDICATOR_HEIGHT);
|
||||
GLfloat alpha = 1.0;
|
||||
if ([info objectForKey:X_KEY])
|
||||
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
|
||||
x = [(NSNumber *)[info objectForKey:X_KEY] floatValue];
|
||||
if ([info objectForKey:Y_KEY])
|
||||
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
|
||||
y = [(NSNumber *)[info objectForKey:Y_KEY] floatValue];
|
||||
if ([info objectForKey:ALPHA_KEY])
|
||||
alpha = [(NSNumber *)[info objectForKey:ALPHA_KEY] doubleValue];
|
||||
int zoom_indicator_cx = x;
|
||||
int zoom_indicator_cy = y;
|
||||
int zl = scanner_zoom - 1.0;
|
||||
if (zl < 0) zl = 0;
|
||||
if (zl >= SCANNER_ZOOM_LEVELS) zl = SCANNER_ZOOM_LEVELS - 1;
|
||||
[zoomLevelSprite[zl] blitCentredToX:zoom_indicator_cx Y:zoom_indicator_cy Z:z1 Alpha:(zl == 0) ? 0.75 * alpha : alpha]; // vary alpha up if zoomed
|
||||
alpha = [(NSNumber *)[info objectForKey:ALPHA_KEY] floatValue];
|
||||
if ([info objectForKey:WIDTH_KEY])
|
||||
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] floatValue];
|
||||
if ([info objectForKey:HEIGHT_KEY])
|
||||
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] floatValue];
|
||||
if ([info objectForKey:RGB_COLOR_KEY])
|
||||
{
|
||||
NSArray* rgb_array = (NSArray*)[info objectForKey:RGB_COLOR_KEY];
|
||||
zoom_color[0] = (GLfloat)[(NSNumber *)[rgb_array objectAtIndex:0] floatValue];
|
||||
zoom_color[1] = (GLfloat)[(NSNumber *)[rgb_array objectAtIndex:1] floatValue];
|
||||
zoom_color[2] = (GLfloat)[(NSNumber *)[rgb_array objectAtIndex:2] floatValue];
|
||||
}
|
||||
GLfloat cx = x - 0.3 * siz.width;
|
||||
GLfloat cy = y - 0.75 * siz.height;
|
||||
|
||||
int zl = scanner_zoom;
|
||||
if (zl < 1) zl = 1;
|
||||
if (zl > SCANNER_ZOOM_LEVELS) zl = SCANNER_ZOOM_LEVELS;
|
||||
if (zl == 1) alpha *= 0.75;
|
||||
zoom_color[3] = (GLfloat)alpha;
|
||||
glColor4fv( zoom_color);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glBindTexture(GL_TEXTURE_2D, ascii_texture_name);
|
||||
glBegin(GL_QUADS);
|
||||
drawCharacterQuad( 48 + zl, cx - 0.4 * siz.width, cy, z1, siz);
|
||||
drawCharacterQuad( 58, cx, cy, z1, siz);
|
||||
drawCharacterQuad( 49, cx + 0.3 * siz.width, cy, z1, siz);
|
||||
glEnd();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
}
|
||||
|
||||
- (void) drawCompass:(NSDictionary *) info
|
||||
{
|
||||
int x = COMPASS_CENTRE_X;
|
||||
int y = COMPASS_CENTRE_Y;
|
||||
double alpha = 1.0;
|
||||
NSSize siz = NSMakeSize( COMPASS_HALF_SIZE, COMPASS_HALF_SIZE);
|
||||
GLfloat x = COMPASS_CENTRE_X;
|
||||
GLfloat y = COMPASS_CENTRE_Y;
|
||||
GLfloat alpha = 1.0;
|
||||
if ([info objectForKey:X_KEY])
|
||||
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
|
||||
x = [(NSNumber *)[info objectForKey:X_KEY] floatValue];
|
||||
if ([info objectForKey:Y_KEY])
|
||||
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
|
||||
y = [(NSNumber *)[info objectForKey:Y_KEY] floatValue];
|
||||
if ([info objectForKey:WIDTH_KEY])
|
||||
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] floatValue];
|
||||
if ([info objectForKey:HEIGHT_KEY])
|
||||
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] floatValue];
|
||||
if ([info objectForKey:ALPHA_KEY])
|
||||
alpha = [(NSNumber *)[info objectForKey:ALPHA_KEY] doubleValue];
|
||||
alpha = [(NSNumber *)[info objectForKey:ALPHA_KEY] floatValue];
|
||||
// draw the compass
|
||||
Matrix rotMatrix;
|
||||
Vector position = player->position;
|
||||
gl_matrix_into_matrix([player rotationMatrix], rotMatrix);
|
||||
//
|
||||
[compassSprite blitCentredToX:x Y:y Z:z1 Alpha:alpha];
|
||||
//
|
||||
// new
|
||||
GLfloat h1 = siz.height * 0.125;
|
||||
GLfloat h3 = siz.height * 0.375;
|
||||
GLfloat w1 = siz.width * 0.125;
|
||||
GLfloat w3 = siz.width * 0.375;
|
||||
glLineWidth( 2.0 * line_width); // thicker
|
||||
glColor4f( 0.0f, 0.0f, 1.0f, alpha);
|
||||
drawOval( x, y, z1, siz, 12);
|
||||
glColor4f( 0.0f, 0.0f, 1.0f, 0.5f * alpha);
|
||||
glBegin(GL_LINES);
|
||||
glVertex3f( x - w1, y, z1); glVertex3f( x - w3, y, z1);
|
||||
glVertex3f( x + w1, y, z1); glVertex3f( x + w3, y, z1);
|
||||
glVertex3f( x, y - h1, z1); glVertex3f( x, y - h3, z1);
|
||||
glVertex3f( x, y + h1, z1); glVertex3f( x, y + h3, z1);
|
||||
glEnd();
|
||||
glLineWidth( line_width); // thinner
|
||||
|
||||
//
|
||||
PlanetEntity* the_sun = [[player universe] sun];
|
||||
PlanetEntity* the_planet = [[player universe] planet];
|
||||
StationEntity* the_station = [[player universe] station];
|
||||
Entity* the_target = [player getPrimaryTarget];
|
||||
Entity* the_next_beacon = [[player universe] entityForUniversalID:[player nextBeaconID]];
|
||||
if (([[player universe] viewDir] != VIEW_DOCKED)&&(the_sun)&&(the_planet))
|
||||
int p_status = player->status;
|
||||
if (((p_status == STATUS_IN_FLIGHT)
|
||||
||(p_status == STATUS_AUTOPILOT_ENGAGED)
|
||||
||(p_status == STATUS_LAUNCHING)
|
||||
||(p_status == STATUS_WITCHSPACE_COUNTDOWN)) // be in the right mode
|
||||
&&(the_sun)
|
||||
&&(the_planet)) // and be in a system
|
||||
{
|
||||
Vector relativePosition;
|
||||
if ([player compass_mode] == COMPASS_MODE_BASIC)
|
||||
@ -684,20 +686,19 @@ static BOOL hostiles;
|
||||
else
|
||||
relativePosition.z = 1.0;
|
||||
relativePosition = unit_vector(&relativePosition);
|
||||
relativePosition.x *= [compassSprite size].width * 0.4;
|
||||
relativePosition.y *= [compassSprite size].height * 0.4;
|
||||
relativePosition.x *= siz.width * 0.4;
|
||||
relativePosition.y *= siz.height * 0.4;
|
||||
relativePosition.x += x;
|
||||
relativePosition.y += y;
|
||||
|
||||
if ([player compass_mode] == COMPASS_MODE_BASIC)
|
||||
{
|
||||
NSSize oldblipsize = NSMakeSize( 6, 6);
|
||||
// [self drawCompassPlanetBlipAt:relativePosition Alpha:alpha];
|
||||
[self drawCompassPlanetBlipAt:relativePosition Size:oldblipsize Alpha:alpha];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSSize sz = [compassSprite size];
|
||||
NSSize sz = siz;
|
||||
sz.width *= 0.2;
|
||||
sz.height *= 0.2;
|
||||
glLineWidth(2.0);
|
||||
@ -846,19 +847,38 @@ static BOOL hostiles;
|
||||
|
||||
- (void) drawAegis:(NSDictionary *) info
|
||||
{
|
||||
if (([[player universe] viewDir] == VIEW_DOCKED)||([[player universe] sun] == nil)||([player checkForAegis] != AEGIS_IN_DOCKING_RANGE))
|
||||
return; // don't draw
|
||||
|
||||
NSSize siz = NSMakeSize( AEGIS_WIDTH, AEGIS_HEIGHT);
|
||||
int x = AEGIS_CENTRE_X;
|
||||
int y = AEGIS_CENTRE_Y;
|
||||
double alpha = 1.0;
|
||||
GLfloat alpha = 0.5;
|
||||
if ([info objectForKey:X_KEY])
|
||||
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
|
||||
if ([info objectForKey:Y_KEY])
|
||||
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
|
||||
if ([info objectForKey:ALPHA_KEY])
|
||||
alpha = [(NSNumber *)[info objectForKey:ALPHA_KEY] doubleValue];
|
||||
alpha *= [(NSNumber *)[info objectForKey:ALPHA_KEY] floatValue];
|
||||
if ([info objectForKey:WIDTH_KEY])
|
||||
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
|
||||
if ([info objectForKey:HEIGHT_KEY])
|
||||
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
|
||||
|
||||
// draw the aegis indicator
|
||||
//
|
||||
if (([[player universe] viewDir] != VIEW_DOCKED)&&([[player universe] sun])&&([player checkForAegis] == AEGIS_IN_DOCKING_RANGE))
|
||||
[aegisSprite blitCentredToX:x Y:y Z:z1 Alpha:alpha];
|
||||
GLfloat w = siz.width / 16.0;
|
||||
GLfloat h = siz.height / 16.0;
|
||||
|
||||
GLfloat strip[] = { -7,8, -6,5, 5,8, 3,5, 7,2, 4,2, 6,-1, 4,2, -4,-1, -6,2, -4,-1, -7,-1, -3,-4, -5,-7, 6,-4, 7,-7 };
|
||||
|
||||
glColor4f( 0.0f, 1.0f, 0.0f, alpha);
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
int i;
|
||||
for (i = 0; i < 32; i += 2)
|
||||
glVertex3f( x + w * strip[i], y - h * strip[i + 1], z1);
|
||||
glEnd();
|
||||
|
||||
}
|
||||
|
||||
- (void) drawSpeedBar:(NSDictionary *) info
|
||||
@ -1125,10 +1145,10 @@ static BOOL hostiles;
|
||||
if ([info objectForKey:HEIGHT_KEY])
|
||||
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
|
||||
|
||||
double temp = [player dial_cabin_temp];
|
||||
double temp = [player dial_ship_temperature];
|
||||
int flash = (int)([[player universe] getTime] * 4);
|
||||
flash &= 1;
|
||||
// draw cabin_temp bar
|
||||
// draw ship_temperature bar
|
||||
glColor4fv(green_color);
|
||||
if (temp > .25)
|
||||
glColor4fv(yellow_color);
|
||||
@ -1484,6 +1504,8 @@ static BOOL hostiles;
|
||||
|
||||
NSString* positionInfo = [universe expressPosition:player->position inCoordinateSystem:@"pwm"];
|
||||
|
||||
NSString* collDebugInfo = [NSString stringWithFormat:@"%@ - %@", [player dial_objinfo], [universe collisionDescription]];
|
||||
|
||||
int x = FPSINFO_DISPLAY_X;
|
||||
int y = FPSINFO_DISPLAY_Y;
|
||||
NSSize siz = NSMakeSize( FPSINFO_DISPLAY_WIDTH, FPSINFO_DISPLAY_HEIGHT);
|
||||
@ -1500,11 +1522,104 @@ static BOOL hostiles;
|
||||
|
||||
glColor4f( 0.0, 1.0, 0.0, 1.0);
|
||||
drawString( [player dial_fpsinfo], x, y, z1, siz);
|
||||
drawString( [player dial_objinfo], x, y - siz.height, z1, siz);
|
||||
// drawString( [player dial_objinfo], x, y - siz.height, z1, siz);
|
||||
drawString( collDebugInfo, x, y - siz.height, z1, siz);
|
||||
|
||||
drawString( positionInfo, x, y - 1.8 * siz.height, z1, siz08);
|
||||
}
|
||||
|
||||
- (void) drawScoopStatus:(NSDictionary *) info
|
||||
{
|
||||
NSSize siz = NSMakeSize( SCOOPSTATUS_WIDTH, SCOOPSTATUS_HEIGHT);
|
||||
GLfloat x = SCOOPSTATUS_CENTRE_X;
|
||||
GLfloat y = SCOOPSTATUS_CENTRE_Y;
|
||||
GLfloat alpha = 0.75;
|
||||
if ([info objectForKey:X_KEY])
|
||||
x = [(NSNumber *)[info objectForKey:X_KEY] floatValue];
|
||||
if ([info objectForKey:Y_KEY])
|
||||
y = [(NSNumber *)[info objectForKey:Y_KEY] floatValue];
|
||||
if ([info objectForKey:ALPHA_KEY])
|
||||
alpha *= [(NSNumber *)[info objectForKey:ALPHA_KEY] floatValue];
|
||||
if ([info objectForKey:WIDTH_KEY])
|
||||
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] floatValue];
|
||||
if ([info objectForKey:HEIGHT_KEY])
|
||||
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] floatValue];
|
||||
|
||||
GLfloat* s0_color = red_color;
|
||||
GLfloat s1c[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
GLfloat s2c[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
GLfloat s3c[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
int scoop_status = [player dial_fuelscoops_status];
|
||||
double t = [[player universe] getTime];
|
||||
GLfloat a1 = alpha * 0.5f * (1.0f + sin(t * 8.0f));
|
||||
GLfloat a2 = alpha * 0.5f * (1.0f + sin(t * 8.0f - 1.0f));
|
||||
GLfloat a3 = alpha * 0.5f * (1.0f + sin(t * 8.0f - 2.0f));
|
||||
|
||||
switch (scoop_status)
|
||||
{
|
||||
case SCOOP_STATUS_NOT_INSTALLED :
|
||||
return; // don't draw
|
||||
case SCOOP_STATUS_FULL_HOLD :
|
||||
s0_color = darkgreen_color;
|
||||
alpha *= 0.75;
|
||||
break;
|
||||
case SCOOP_STATUS_ACTIVE :
|
||||
case SCOOP_STATUS_OKAY :
|
||||
s0_color = green_color;
|
||||
break;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
s1c[i] = s0_color[i];
|
||||
s2c[i] = s0_color[i];
|
||||
s3c[i] = s0_color[i];
|
||||
}
|
||||
if (scoop_status == SCOOP_STATUS_FULL_HOLD)
|
||||
{
|
||||
s3c[0] = red_color[0];
|
||||
s3c[1] = red_color[1];
|
||||
s3c[2] = red_color[2];
|
||||
}
|
||||
if (scoop_status == SCOOP_STATUS_ACTIVE)
|
||||
{
|
||||
s1c[3] = alpha * a1;
|
||||
s2c[3] = alpha * a2;
|
||||
s3c[3] = alpha * a3;
|
||||
}
|
||||
else
|
||||
{
|
||||
s1c[3] = alpha;
|
||||
s2c[3] = alpha;
|
||||
s3c[3] = alpha;
|
||||
}
|
||||
|
||||
GLfloat w1 = siz.width / 8.0;
|
||||
GLfloat w2 = 2.0 * w1;
|
||||
// GLfloat w3 = 3.0 * w1;
|
||||
GLfloat w4 = 4.0 * w1;
|
||||
GLfloat h1 = siz.height / 8.0;
|
||||
GLfloat h2 = 2.0 * h1;
|
||||
GLfloat h3 = 3.0 * h1;
|
||||
GLfloat h4 = 4.0 * h1;
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBegin( GL_QUADS);
|
||||
// section 1
|
||||
glColor4fv( s1c);
|
||||
glVertex3f( x, y + h1, z1); glVertex3f( x - w2, y + h2, z1); glVertex3f( x, y + h3, z1); glVertex3f( x + w2, y + h2, z1);
|
||||
// section 2
|
||||
glColor4fv( s2c);
|
||||
glVertex3f( x, y - h1, z1); glVertex3f( x - w4, y + h1, z1); glVertex3f( x - w4, y + h2, z1); glVertex3f( x, y, z1);
|
||||
glVertex3f( x, y - h1, z1); glVertex3f( x + w4, y + h1, z1); glVertex3f( x + w4, y + h2, z1); glVertex3f( x, y, z1);
|
||||
// section 3
|
||||
glColor4fv( s3c);
|
||||
glVertex3f( x, y - h4, z1); glVertex3f( x - w2, y - h2, z1); glVertex3f( x - w2, y - h1, z1); glVertex3f( x, y - h2, z1);
|
||||
glVertex3f( x, y - h4, z1); glVertex3f( x + w2, y - h2, z1); glVertex3f( x + w2, y - h1, z1); glVertex3f( x, y - h2, z1);
|
||||
glEnd();
|
||||
|
||||
}
|
||||
|
||||
- (void) drawGreenSurround:(NSDictionary *) info
|
||||
{
|
||||
int x, y;
|
||||
@ -1799,7 +1914,8 @@ void hudDrawReticleOnTarget(Entity* target, PlayerEntity* player1, GLfloat z1)
|
||||
Vector p1 = target->position;
|
||||
p1.x -= p0.x; p1.y -= p0.y; p1.z -= p0.z;
|
||||
double rdist = sqrt(magnitude2(p1));
|
||||
double rsize = target->actual_radius;
|
||||
// double rsize = target->actual_radius;
|
||||
double rsize = target->collision_radius;
|
||||
|
||||
if (rsize < rdist * ONE_SIXTYFOURTH)
|
||||
rsize = rdist * ONE_SIXTYFOURTH;
|
||||
@ -1916,7 +2032,7 @@ void drawString(NSString *text, double x, double y, double z, NSSize siz)
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
ch = [text characterAtIndex:i];
|
||||
if (ch & 0xFC00 == 0xD800)
|
||||
if ((ch & 0xFC00) == 0xD800)
|
||||
{
|
||||
// This is a high surrogate. NSStrings don’t automagically handle surrogate pairs
|
||||
// for us for historical reasons.
|
||||
@ -1924,7 +2040,7 @@ void drawString(NSString *text, double x, double y, double z, NSSize siz)
|
||||
{
|
||||
// Check if next is a low surrogate
|
||||
next = [text characterAtIndex:i + 1];
|
||||
if (next & 0xFC00 == 0xDC00)
|
||||
if ((next & 0xFC00) == 0xDC00)
|
||||
{
|
||||
// It is; merge the surrogate pair into a code point in ch and skip
|
||||
++i;
|
||||
@ -2008,6 +2124,15 @@ static const char *toAscii(unsigned inCodePoint)
|
||||
case 0x2606: // White star
|
||||
return "-";
|
||||
|
||||
case 0x266D: // Musical flat sign
|
||||
return "b";
|
||||
|
||||
case 0x266E: // Musical natural sign
|
||||
return "=";
|
||||
|
||||
case 0x266F: // Musical sharp sign
|
||||
return "#";
|
||||
|
||||
default:
|
||||
return "?";
|
||||
}
|
||||
@ -2142,10 +2267,10 @@ void drawOval( double x, double y, double z, NSSize siz, int step)
|
||||
int i;
|
||||
GLfloat ww = 0.5 * siz.width;
|
||||
GLfloat hh = 0.5 * siz.height;
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (i = 0; i < 360; i += step)
|
||||
glVertex3f(x + ww * sin_value[i], y + hh * sin_value[(i + 90) % 360], z);
|
||||
// glVertex3f(x, y + hh, z);
|
||||
glVertex3f(x + ww * sin_value[i], y + hh * cos_value[i], z);
|
||||
glVertex3f(x, y + hh, z);
|
||||
glEnd();
|
||||
return;
|
||||
}
|
||||
@ -2158,7 +2283,7 @@ void drawFilledOval( double x, double y, double z, NSSize siz, int step)
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glVertex3f( x, y, z);
|
||||
for (i = 0; i < 360; i += step)
|
||||
glVertex3f(x + ww * sin_value[i], y + hh * sin_value[(i + 90) % 360], z);
|
||||
glVertex3f(x + ww * sin_value[i], y + hh * cos_value[i], z);
|
||||
glVertex3f(x, y + hh, z);
|
||||
glEnd();
|
||||
return;
|
||||
@ -2174,7 +2299,7 @@ void drawSpecialOval( double x, double y, double z, NSSize siz, int step, GLfloa
|
||||
for (i = 0; i < 360; i += step)
|
||||
{
|
||||
glColor4f( color4v[0], color4v[1], color4v[2], fabs(sin_value[i] * color4v[3]));
|
||||
glVertex3f(x + ww * sin_value[i], y + hh * sin_value[(i + 90) % 360], z);
|
||||
glVertex3f(x + ww * sin_value[i], y + hh * cos_value[i], z);
|
||||
}
|
||||
glEnd();
|
||||
return;
|
@ -1,4 +1,4 @@
|
||||
#ifdef LOADSAVEGUI
|
||||
|
||||
//
|
||||
// LoadSave.h
|
||||
//
|
||||
@ -47,4 +47,4 @@
|
||||
- (int) findIndexOfCommander: (NSString *)cdrName;
|
||||
|
||||
@end
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user