Initial source commit

This commit is contained in:
Tony Bark 2025-10-03 02:19:59 -04:00
commit f1384c11ee
335 changed files with 52715 additions and 0 deletions

54
.gitignore vendored Normal file
View file

@ -0,0 +1,54 @@
# Created by https://www.toptal.com/developers/gitignore/api/cmake,visualstudiocode,executable
# Edit at https://www.toptal.com/developers/gitignore?templates=cmake,visualstudiocode,executable
### CMake ###
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps
### CMake Patch ###
CMakeUserPresets.json
# External projects
*-prefix/
### Executable ###
*.app
*.bat
*.cgi
*.com
*.exe
*.gadget
*.jar
*.pif
*.vb
*.wsf
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide
# End of https://www.toptal.com/developers/gitignore/api/cmake,visualstudiocode,executable

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

View file

@ -0,0 +1,55 @@
#!/bin/sh
#
# Modification History
#
# 2007-November-12 Jason Rohrer
# Copied from Cultivation build.
#
if [ $# -lt 3 ] ; then
echo "Usage: $0 release_name unix_platform_name path_to_SDL.framework"
exit 1
fi
rm -rf mac
mkdir mac
mkdir mac/Passage
mkdir mac/Passage/graphics
mkdir mac/Passage/music
mkdir mac/Passage/settings
cp ../documentation/Readme.txt mac/Passage/
cp ../gameSource/graphics/*.tga mac/Passage/graphics
cp ../gameSource/music/*.tga mac/Passage/music
cp ../gameSource/settings/*.ini mac/Passage/settings
cp -r macOSX/Passage.app mac/Passage/Passage.app
cp ../gameSource/Passage mac/Passage/Passage.app/Contents/MacOS
rm -r mac/Passage/Passage.app/CVS
rm -r mac/Passage/Passage.app/Contents/CVS
rm -r mac/Passage/Passage.app/Contents/MacOS/CVS
rm -r mac/Passage/Passage.app/Contents/Resources/CVS
rm -r mac/Passage/Passage.app/Contents/Frameworks/CVS
# install SDL framework
cp -r $3 mac/Passage/Passage.app/Contents/Frameworks/
cd mac
tar cf "Passage_$1_$2.tar" Passage
gzip "Passage_$1_$2.tar"

View file

@ -0,0 +1,56 @@
#!/bin/sh
#
# Modification History
#
# 2007-November-12 Jason Rohrer
# Copied from Cultivation build.
#
if [ $# -lt 2 ] ; then
echo "Usage: $0 release_name unix_platform_name"
exit 1
fi
rm -rf unix
rm -rf windows
mkdir windows
mkdir unix
# work on unix tree first
mkdir unix/Passage
mkdir unix/Passage/graphics
mkdir unix/Passage/music
mkdir unix/Passage/settings
cp ../documentation/Readme.txt unix/Passage/
cp ../gameSource/graphics/*.tga unix/Passage/graphics
cp ../gameSource/music/*.tga unix/Passage/music
cp ../gameSource/settings/*.ini unix/Passage/settings
# duplicate unix tree so far to make windows tree
cp -r unix/Passage windows/
cp ../gameSource/Passage unix/Passage/
cp win32/Passage.exe win32/*.dll windows/Passage/
cd unix
tar cf "Passage_$1_$2.tar" Passage
gzip "Passage_$1_$2.tar"
cd ../windows
zip -r "Passage_$1_Windows.zip" Passage

14
gamma256/build/source/cleanSrc Executable file
View file

@ -0,0 +1,14 @@
rm -r minorGems/ai
rm -r minorGems/bench
rm -r minorGems/doc
rm -r minorGems/examples
rm -r minorGems/sound
rm -r minorGems/temp
rm -r minorGems/graphics/openGL
rm -r minorGems/network
rm -r minorGems/math
rm -r gamma256/documentation/concept
rm -r gamma256/documentation/html

View file

@ -0,0 +1,2 @@
cvs -z3 -d:ext:jcr13@minorgems.cvs.sourceforge.net:/cvsroot/minorgems export -r HEAD minorGems
cvs -z3 -d:ext:jcr13@hcsoftware.cvs.sourceforge.net:/cvsroot/hcsoftware export -r HEAD gamma256

View file

@ -0,0 +1,39 @@
#!/bin/bash
#
# Modification History
#
# 2007-November-12 Jason Rohrer
# Copied from Cultivation.
#
cd gamma256/gameSource
chmod u+x ./configure
./configure
echo "Building Passage..."
make
cd ../..
mkdir graphics
mkdir music
mkdir settings
cp gamma256/gameSource/Passage ./Passage
cp gamma256/documentation/Readme.txt .
cp gamma256/gameSource/graphics/* ./graphics
cp gamma256/gameSource/music/* ./music
cp gamma256/gameSource/settings/* ./settings
echo "Run Passage to play."

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

BIN
gamma256/build/win32/SDL.dll Executable file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

View file

@ -0,0 +1 @@
For instructions, please see: http://hcsoftware.sf.net/passage

View file

@ -0,0 +1,56 @@
Version 4 2010-May-24
--Fixed error in application of patch for older SDL versions.
--Fixed random number generation so that it works on 64-bit platforms (thanks
to Kevin Fan).
--Fixed chest gem selection behavior on certain platforms (like iPhone).
--Fixed unsafe use of pointers into vector (triggered a bug with new shorter
default vector size).
--Fixed string warnings that are caught by certain GCC versions.
Version 3 2007-December-13
--Switched to analog stick on 360 controller for much smoother play.
--Added patch for older SDL versions provided by Jarno van der Kolk.
--Added ESC in addition to Q to quit.
--Added settings files for controlling screen size and fullscreen mode.
Version 2 2007-November-13
--Added chiptune music soundtrack.
--Improved star sprite.
--Fixed bug with window sizing (manifested by title being set too low).
--Improved behavior of screen blow-up/blow-down keys.
--Fixed bug in game reset that can result in artifacts during subsequent plays.
--Fixed artifacts after screen blow-up factor change on double-buffered
platforms.
--Fixed problem with screen pitch.
--Now builds for MacOSX 10.2 and higher (using MinGW and SDL).
--Unix source distribution now available (compiles against SDL developer
library).
Version 1 2007-November-1
--Initial release (Gamma256 submission)

View file

@ -0,0 +1,92 @@
#include "Envelope.h"
#include <stdio.h>
// #include <assert.h>
Envelope::Envelope( double inAttackTime, double inDecayTime,
double inSustainLevel, double inReleaseTime,
int inMaxNoteLengthInGridSteps,
int inGridStepDurationInSamples )
: mNumComputedEnvelopes( inMaxNoteLengthInGridSteps ),
mEvelopeLengths( new int[ inMaxNoteLengthInGridSteps ] ),
mComputedEnvelopes( new double*[ inMaxNoteLengthInGridSteps ] ) {
for( int i=0; i<mNumComputedEnvelopes; i++ ) {
int length = (i+1) * inGridStepDurationInSamples;
mEvelopeLengths[i] = length;
mComputedEnvelopes[i] = new double[ length ];
for( int s=0; s<length; s++ ) {
double t = s / (double)( length - 1 );
if( t < inAttackTime ) {
// assert( inAttackTime > 0 );
mComputedEnvelopes[i][s] = t / inAttackTime;
}
else if( t < inAttackTime + inDecayTime ) {
// assert( inDecayTime > 0 );
// decay down to sustain level
mComputedEnvelopes[i][s] =
( 1.0 - inSustainLevel ) *
( inAttackTime + inDecayTime - t ) /
( inDecayTime )
+ inSustainLevel;
}
else if( 1.0 - t > inReleaseTime ) {
mComputedEnvelopes[i][s] = inSustainLevel;
}
else {
if( inReleaseTime > 0 ) {
mComputedEnvelopes[i][s] =
inSustainLevel -
inSustainLevel *
( inReleaseTime - ( 1.0 - t ) ) / inReleaseTime;
}
else {
// release time 0
// hold sustain until end
mComputedEnvelopes[i][s] = inSustainLevel;
}
}
}
// test code to output evelopes for plotting in gnuplot
if( false && i == 0 ) {
FILE *file = fopen( "env0.txt", "w" );
for( int s=0; s<length; s++ ) {
fprintf( file, "%f %f\n",
s / (double)( length - 1 ),
mComputedEnvelopes[i][s] );
}
fclose( file );
}
}
}
Envelope::~Envelope() {
for( int i=0; i<mNumComputedEnvelopes; i++ ) {
delete [] mComputedEnvelopes[i];
}
delete [] mEvelopeLengths;
delete [] mComputedEnvelopes;
}
double *Envelope::getEnvelope( int inNoteLengthInGridSteps ) {
return mComputedEnvelopes[ inNoteLengthInGridSteps - 1 ];
}

View file

@ -0,0 +1,45 @@
class Envelope {
public:
/**
* Constructs an envelope.
*
* All parameters are in range 0..1, and sum of the three time
* parameters must be <= 1.
*
* @param inMaxNoteLengthInGridSteps the maximum note length to
* cover. Exact envelopes will be generated for notes up
* to this length.
* @param inGridStepDurationInSamples the number of samples
* per grid step.
*/
Envelope( double inAttackTime, double inDecayTime,
double inSustainLevel, double inReleaseTime,
int inMaxNoteLengthInGridSteps,
int inGridStepDurationInSamples );
~Envelope();
/**
* Gets an evenlope for a given note length.
*
* @return an evelope of values in [0,1] that can be indexed by
* sample number. Will be destroyed when this class is destroyed.
*/
double *getEnvelope( int inNoteLengthInGridSteps );
private:
int mNumComputedEnvelopes;
int *mEvelopeLengths;
double **mComputedEnvelopes;
};

View file

@ -0,0 +1,133 @@
template <class Type>
class HashTable {
public:
HashTable( int inSize );
~HashTable();
Type lookup( int inKeyA, int inKeyB, char *outFound );
void insert( int inKeyA, int inKeyB, Type inItem );
// flush all entries from table
void clear();
private:
int mSize;
Type *mTable;
char *mSetFlags;
int *mKeysA;
int *mKeysB;
int mHitCount;
int mMissCount;
int computeHash( int inKeyA, int inKeyB );
};
// Wow... never new that template function implementations must be in the
// same file as the declaration
template <class Type>
HashTable<Type>::HashTable( int inSize )
: mSize( inSize ),
mTable( new Type[ inSize ] ),
mSetFlags( new char[ inSize ] ),
mKeysA( new int[ inSize ] ),
mKeysB( new int[ inSize ] ),
mHitCount( 0 ),
mMissCount( 0 ) {
clear();
}
#include <stdio.h>
template <class Type>
HashTable<Type>::~HashTable() {
delete [] mTable;
delete [] mSetFlags;
delete [] mKeysA;
delete [] mKeysB;
printf( "%d hits, %d misses, %f hit ratio\n",
mHitCount, mMissCount,
mHitCount / (double)( mHitCount + mMissCount ) );
}
template <class Type>
inline int HashTable<Type>::computeHash( int inKeyA, int inKeyB ) {
int hashKey = ( inKeyA * 734727 + inKeyB * 263474 ) % mSize;
if( hashKey < 0 ) {
hashKey += mSize;
}
return hashKey;
}
template <class Type>
Type HashTable<Type>::lookup( int inKeyA, int inKeyB, char *outFound ) {
int hashKey = computeHash( inKeyA, inKeyB );
if( mSetFlags[ hashKey ]
&&
mKeysA[ hashKey ] == inKeyA
&&
mKeysB[ hashKey ] == inKeyB ) {
// hit
mHitCount ++;
*outFound = true;
}
else {
// miss
mMissCount ++;
*outFound = false;
}
return mTable[ hashKey ];
}
template <class Type>
void HashTable<Type>::insert( int inKeyA, int inKeyB, Type inItem ) {
int hashKey = computeHash( inKeyA, inKeyB );
mSetFlags[ hashKey ] = true;
mKeysA[ hashKey ] = inKeyA;
mKeysB[ hashKey ] = inKeyB;
mTable[ hashKey ] = inItem;
}
template <class Type>
void HashTable<Type>::clear() {
for( int i=0; i<mSize; i++ ) {
mSetFlags[i] = false;
}
}

View file

@ -0,0 +1,10 @@
PLATFORM_PATH = linux
PLATFORM_NAME = Linux
TIME_PLATFORM_PATH = unix
TIME_PLATFORM_NAME = Unix
PLATFORM_COMPILE_FLAGS =
PLATFORM_LINK_FLAGS = -lSDL -lpthread

View file

@ -0,0 +1,12 @@
PLATFORM_PATH = linux
PLATFORM_NAME = Linux
TIME_PLATFORM_PATH = unix
TIME_PLATFORM_NAME = Unix
PLATFORM_COMPILE_FLAGS = -DBSD -D__mac__
# need to compile and link SDLMain.m
PLATFORM_LINK_FLAGS = -framework SDL -framework Cocoa mac/SDLMain.m

View file

@ -0,0 +1,10 @@
PLATFORM_PATH = win32
PLATFORM_NAME = Win32
TIME_PLATFORM_PATH = win32
TIME_PLATFORM_NAME = Win32
PLATFORM_COMPILE_FLAGS =
# -mwindows hides the command window on app launch
PLATFORM_LINK_FLAGS = -lmingw32 -lSDLmain -lSDL -mwindows

View file

@ -0,0 +1,96 @@
ROOT_PATH = ../..
COMPILE = g++ ${PLATFORM_COMPILE_FLAGS} -Wall -Wwrite-strings -Wchar-subscripts -Wparentheses -g -I${ROOT_PATH} -c
LINK = g++ -I${ROOT_PATH}
MG_PATH = ${ROOT_PATH}/minorGems
MINOR_GEMS_SOURCES = \
${MG_PATH}/io/file/${PLATFORM_PATH}/Path${PLATFORM_NAME}.cpp \
${MG_PATH}/util/stringUtils.cpp \
${MG_PATH}/util/StringBufferOutputStream.cpp \
${MG_PATH}/util/SettingsManager.cpp \
${MG_PATH}/system/${TIME_PLATFORM_PATH}/Time${TIME_PLATFORM_NAME}.cpp \
${MG_PATH}/system/${PLATFORM_PATH}/Thread${PLATFORM_NAME}.cpp \
${MG_PATH}/crypto/hashes/sha1.cpp \
${MG_PATH}/formats/encodingUtils.cpp \
MINOR_GEMS_OBJECTS = ${MINOR_GEMS_SOURCES:.cpp=.o}
GAME_SOURCES = \
game.cpp \
landscape.cpp \
blowUp.cpp \
World.cpp \
map.cpp \
common.cpp \
score.cpp \
musicPlayer.cpp \
Timbre.cpp \
Envelope.cpp \
GAME_GRAPHICS = \
graphics/tileSet.tga \
graphics/characterSprite.tga \
graphics/characterSpriteSad.tga \
graphics/spouseSprite.tga \
graphics/numerals.tga \
graphics/chest.tga \
graphics/chestPrize.tga \
graphics/chestDust.tga \
graphics/heart.tga \
graphics/title.tga \
music/music.tga \
GAME_OBJECTS = ${GAME_SOURCES:.cpp=.o}
all: Passage ${GAME_GRAPHICS}
clean:
rm *.o *.tga Passage testMusicPlayer
Passage: ${GAME_OBJECTS} ${MINOR_GEMS_OBJECTS}
${LINK} -o Passage ${GAME_OBJECTS} ${MINOR_GEMS_OBJECTS} ${PLATFORM_LINK_FLAGS}
testMusicPlayer: ${GAME_OBJECTS} testMusicPlayer.o common.o Timbre.o Envelope.o ${MINOR_GEMS_OBJECTS}
${LINK} -o testMusicPlayer musicPlayer.o testMusicPlayer.o common.o Timbre.o Envelope.o ${MINOR_GEMS_OBJECTS} ${PLATFORM_LINK_FLAGS}
game.o: game.cpp World.h blowUp.h common.h map.h
landscape.o: landscape.cpp landscape.h
blowUp.o: blowUp.cpp blowUp.h
World.o: World.cpp World.h common.h map.h
common.o: common.cpp common.h
map.o: map.cpp map.h landscape.h HashTable.h
#
# Generic:
#
# Map all .cpp C++ and C files into .o object files
#
# $@ represents the name.o file
# $< represents the name.cpp file
#
.cpp.o:
${COMPILE} -o $@ $<
.c.o:
${COMPILE} -o $@ $<
graphics/%.tga: %.png
convert $< $@
music/%.tga: %.png
convert $< $@

View file

@ -0,0 +1,158 @@
#include "Timbre.h"
#include "minorGems/util/stringUtils.h"
#include <math.h>
#include <stdio.h>
double twelthRootOfTwo = pow( 2, 1.0/12 );
// for major scale
// W, W, H, W, W, W, H
int halfstepMap[ 7 ] = { 0, 2, 4, 5, 7, 9, 11 };
// minor scale
// W,H,W,W,H,W,W
//int halfstepMap[ 7 ] = { 0, 2, 3, 5, 7, 8, 10 };
// gets frequency of note in our scale
double getFrequency( double inBaseFrequency, int inScaleNoteNumber ) {
int octavesUp = inScaleNoteNumber / 7;
int numHalfsteps = halfstepMap[ inScaleNoteNumber % 7 ] + octavesUp * 12;
return inBaseFrequency * pow( twelthRootOfTwo, numHalfsteps );
}
/*
Was used during testing
#include "minorGems/sound/formats/aiff.h"
int outputFileNumber = 0;
// outputs a wave table as an AIFF
void outputWaveTable( Sint16 *inTable, int inLength, int inSampleRate ) {
// generate the header
int headerSize;
unsigned char *aiffHeader =
getAIFFHeader( 1,
16,
inSampleRate,
inLength,
&headerSize );
char *fileName = autoSprintf( "waveTable%d.aiff", outputFileNumber );
outputFileNumber++;
FILE *aiffFile = fopen( fileName, "wb" );
delete [] fileName;
//printf( "Header size = %d\n", headerSize );
fwrite( aiffHeader, 1, headerSize, aiffFile );
delete [] aiffHeader;
for( int i=0; i<inLength; i++ ) {
Sint16 val = inTable[i];
unsigned char msb = val >> 8 & 0xFF;
unsigned char lsb = val && 0xFF;
fwrite( &msb, 1, 1, aiffFile );
fwrite( &lsb, 1, 1, aiffFile );
}
fclose( aiffFile );
}
*/
Timbre::Timbre( int inSampleRate,
double inLoudness,
double inBaseFrequency,
int inNumWaveTableEntries,
double( *inWaveFunction )( double ) )
: mNumWaveTableEntries( inNumWaveTableEntries ),
mWaveTable( new Sint16*[ inNumWaveTableEntries ] ),
mWaveTableLengths( new int[ inNumWaveTableEntries ] ) {
// build wave table for each possible pitch in image
for( int i=0; i<mNumWaveTableEntries; i++ ) {
double freq = getFrequency( inBaseFrequency, i );
double period = 1.0 / freq;
// wave table contains more than one period to more
// accurately represent a signal with frequency freq
int tableLength = (int)( 5 * period * inSampleRate );
mWaveTableLengths[i] = tableLength;
mWaveTable[i] = new Sint16[ tableLength ];
// store double samples in temp table so we can compute
// max value for normalization
double *tempTable = new double[ tableLength ];
double maxValue = 0;
int s;
for( s=0; s<tableLength; s++ ) {
double t = (double)s / (double)inSampleRate;
double waveValue = inWaveFunction( 2 * M_PI * t * freq );
tempTable[s] = waveValue;
// track max value
if( waveValue > maxValue ) {
maxValue = waveValue;
}
else if( -waveValue > maxValue ) {
maxValue = -waveValue;
}
}
// now normalize and convert to int
for( s=0; s<tableLength; s++ ) {
double waveValue = tempTable[s] * inLoudness / maxValue;
// convert to int
mWaveTable[i][s] = (Sint16)( 32767 * waveValue );
}
delete [] tempTable;
mWaveTableLengths[i] = tableLength;
// to examine waveforms for testing
// outputWaveTable( mWaveTable[i], tableLength, inSampleRate );
}
}
Timbre::~Timbre() {
delete [] mWaveTableLengths;
for( int i=0; i<mNumWaveTableEntries; i++ ) {
delete [] mWaveTable[i];
}
delete [] mWaveTable;
}

View file

@ -0,0 +1,35 @@
#include <stdint.h>
typedef int16_t Sint16;
class Timbre {
public:
/**
* Constructs a timbre and fills its wavetables.
*
* @param inSampleRate number of samples per second.
* @param inLoudness a scale factor in [0,1].
* @param inBaseFrequency the lowest note in the wave table, in Hz.
* This is also the key for the major scale held in the wave table.
* @param inNumWaveTableEntries the number of wavetable entries.
* @param inWaveFunction a function mapping a double parameter t
* to a wave height in [-1,1]. Must have a period of 2pi.
*/
Timbre( int inSampleRate,
double inLoudness,
double inBaseFrequency,
int inNumWaveTableEntries,
double( *inWaveFunction )( double ) );
~Timbre();
int mNumWaveTableEntries;
// mWaveTable[x] corresponds to a wave with frequency of
// getFrequency(x)
Sint16 **mWaveTable;
int *mWaveTableLengths;
};

View file

@ -0,0 +1,963 @@
#include "World.h"
#include "common.h"
#include "map.h"
#include "minorGems/graphics/Image.h"
#include "minorGems/util/SimpleVector.h"
class GraphicContainer {
public:
GraphicContainer( const char *inTGAFileName ) {
Image *image = readTGA( inTGAFileName );
mW = image->getWidth();
mH = image->getHeight();
int imagePixelCount = mW * mH;
mRed = new double[ imagePixelCount ];
mGreen = new double[ imagePixelCount ];
mBlue = new double[ imagePixelCount ];
for( int i=0; i<imagePixelCount; i++ ) {
mRed[i] = 255 * image->getChannel(0)[ i ];
mGreen[i] = 255 * image->getChannel(1)[ i ];
mBlue[i] = 255 * image->getChannel(2)[ i ];
}
delete image;
}
~GraphicContainer() {
delete [] mRed;
delete [] mGreen;
delete [] mBlue;
}
double *mRed;
double *mGreen;
double *mBlue;
int mW;
int mH;
};
GraphicContainer *tileContainer;
GraphicContainer *chestContainer;
GraphicContainer *spriteContainer;
GraphicContainer *spriteSadContainer;
GraphicContainer *spouseContainer;
GraphicContainer *prizeAnimationContainer;
GraphicContainer *dustAnimationContainer;
GraphicContainer *heartAnimationContainer;
// dimensions of one tile. TileImage contains 13 tiles, stacked vertically,
// with blank lines between tiles
int tileW = 8;
int tileH = 8;
int tileImageW;
int tileImageH;
int numTileSets;
// how wide the swath of a world is that uses a given tile set
int tileSetWorldSpan = 200;
// overlap during tile set transition
int tileSetWorldOverlap = 50;
// for testing
int tileSetSkip = 0;
int tileSetOrder[18] = { 0, 2, 10, 1, 8, 3, 5, 6, 4, 7, 13, 9, 15,
14, 16, 12, 11, 17 };
int mapTileSet( int inSetNumber ) {
// stay in bounds of tileSetOrder
inSetNumber = inSetNumber % 18;
int mappedSetNumber = tileSetOrder[ inSetNumber ];
// stay in bounds of tile set collection
return mappedSetNumber % numTileSets;
}
int chestW = 8;
int chestH = 8;
int numGems = 6;
int gemLocations[6] = { 41, 42, 43, 44, 45, 46 };
//int gemLocations[4] = { 10, 11, 12, 13 };
double gemColors[6][3] = { { 255, 0, 0 },
{ 0, 255, 0 },
{ 255, 160, 0 },
{ 0, 0, 255 },
{ 255, 255, 0 },
{ 255, 0, 255 } };
class Animation {
public:
Animation( int inX, int inY, int inFrameW, int inFrameH,
char inAutoStep,
char inRemoveAtEnd, GraphicContainer *inGraphics )
: mX( inX ), mY( inY ),
mFrameW( inFrameW ), mFrameH( inFrameH ),
mPageNumber( 0 ),
mFrameNumber( 0 ),
mAutoStep( inAutoStep ),
mRemoveAtEnd( inRemoveAtEnd ),
mGraphics( inGraphics ) {
mImageW = mGraphics->mW;
mNumFrames = ( mGraphics->mH - mFrameH ) / mFrameH + 1;
mNumPages = ( mGraphics->mW - mFrameW ) / mFrameW + 1;
}
// default constructor so that we can build a vector
// of Animations
Animation() {
}
// replaces graphics of animation
void swapGraphics( GraphicContainer *inNewGraphics ) {
mGraphics = inNewGraphics;
mImageW = mGraphics->mW;
mNumFrames = ( mGraphics->mH - mFrameH ) / mFrameH + 1;
mNumPages = ( mGraphics->mW - mFrameW ) / mFrameW + 1;
if( mPageNumber >= mNumPages ) {
mPageNumber = mNumPages - 1;
}
if( mFrameNumber >= mNumFrames ) {
mFrameNumber = mNumFrames - 1;
}
}
int mX, mY;
int mFrameW, mFrameH;
int mImageW;
// can blend between pages
double mPageNumber;
int mNumPages;
int mFrameNumber;
int mNumFrames;
char mAutoStep;
char mRemoveAtEnd;
GraphicContainer *mGraphics;
};
SimpleVector<Animation> animationList;
// pointers into vectors are unsafe
//Animation *spriteAnimation;
//Animation *spouseAnimation;
int spriteAnimationIndex;
int spouseAnimationIndex;
char playerDead = false;
char spouseDead = false;
char metSpouse = false;
void resetSampleHashTable();
void initWorld() {
resetMap();
resetSampleHashTable();
playerDead = false;
spouseDead = false;
metSpouse = false;
animationList.deleteAll();
tileImageW = tileContainer->mW;
tileImageH = tileContainer->mH;
numTileSets = (tileImageW + 1) / (tileW + 1);
Animation character( 0, 0, 8, 8, false, false, spriteContainer );
animationList.push_back( character );
// unsafe
// get pointer to animation in vector
//spriteAnimation = animationList.getElement( animationList.size() - 1 );
spriteAnimationIndex = animationList.size() - 1;
Animation spouse( 100, 7, 8, 8, false, false, spouseContainer );
spouse.mFrameNumber = 7;
animationList.push_back( spouse );
// unsafe!
// get pointer to animation in vector
//spouseAnimation = animationList.getElement( animationList.size() - 1 );
spouseAnimationIndex = animationList.size() - 1;
}
char isSpriteTransparent( GraphicContainer *inContainer, int inSpriteIndex ) {
// take transparent color from corner
return
inContainer->mRed[ inSpriteIndex ] ==
inContainer->mRed[ 0 ]
&&
inContainer->mGreen[ inSpriteIndex ] ==
inContainer->mGreen[ 0 ]
&&
inContainer->mBlue[ inSpriteIndex ] ==
inContainer->mBlue[ 0 ];
}
struct rgbColorStruct {
double r;
double g;
double b;
};
typedef struct rgbColorStruct rgbColor;
// outTransient set to true if sample returned is part of a transient
// world feature (character sprite, chest, etc.)
rgbColor sampleFromWorldNoWeight( int inX, int inY, char *outTransient );
// same, but wrapped in a hash table to store non-transient results
rgbColor sampleFromWorldNoWeightHash( int inX, int inY );
Uint32 sampleFromWorld( int inX, int inY, double inWeight ) {
rgbColor c = sampleFromWorldNoWeightHash( inX, inY );
unsigned char r = (unsigned char)( inWeight * c.r );
unsigned char g = (unsigned char)( inWeight * c.g );
unsigned char b = (unsigned char)( inWeight * c.b );
return r << 16 | g << 8 | b;
}
char isSpritePresent( int inX, int inY ) {
// look at animations
for( int i=0; i<animationList.size(); i++ ) {
Animation a = *( animationList.getElement( i ) );
int animW = a.mFrameW;
int animH = a.mFrameH;
// pixel position relative to animation center
// player position centered on sprint left-to-right
int animX = (int)( inX - a.mX + a.mFrameW / 2 );
int animY = (int)( inY - a.mY + a.mFrameH / 2 );
if( animX >= 0 && animX < animW
&&
animY >= 0 && animY < animH ) {
return true;
}
}
return false;
}
#include "HashTable.h"
HashTable<rgbColor> worldSampleHashTable( 30000 );
void resetSampleHashTable() {
worldSampleHashTable.clear();
}
rgbColor sampleFromWorldNoWeightHash( int inX, int inY ) {
char found;
rgbColor sample = worldSampleHashTable.lookup( inX, inY, &found );
if( isSpritePresent( inX, inY ) ) {
// don't consider cached result if a sprite is present
found = false;
}
if( found ) {
return sample;
}
// else not found
// call real function to get result
char transient;
sample = sampleFromWorldNoWeight( inX, inY, &transient );
// insert, but only if not transient
if( !transient ) {
worldSampleHashTable.insert( inX, inY, sample );
}
return sample;
}
rgbColor sampleFromWorldNoWeight( int inX, int inY, char *outTransient ) {
*outTransient = false;
rgbColor returnColor;
char isSampleAnim = false;
// consider sampling from an animation
// draw them in reverse order so that oldest sprites are drawn on top
for( int i=animationList.size() - 1; i>=0; i-- ) {
Animation a = *( animationList.getElement( i ) );
int animW = a.mFrameW;
int animH = a.mFrameH;
// pixel position relative to animation center
// player position centered on sprint left-to-right
int animX = (int)( inX - a.mX + a.mFrameW / 2 );
int animY = (int)( inY - a.mY + a.mFrameH / 2 );
if( animX >= 0 && animX < animW
&&
animY >= 0 && animY < animH ) {
// pixel is in animation frame
int animIndex = animY * a.mImageW + animX;
// skip to appropriate anim page
animIndex += (int)a.mPageNumber * (animW + 1);
// skip to appropriate anim frame
animIndex +=
a.mFrameNumber *
a.mImageW *
( animH + 1 );
// page to blend with
int animBlendIndex = animIndex + animW + 1;
double blendWeight = a.mPageNumber - (int)a.mPageNumber;
if( !isSpriteTransparent( a.mGraphics, animIndex ) ) {
// in non-transparent part
if( blendWeight != 0 ) {
returnColor.r =
( 1 - blendWeight ) * a.mGraphics->mRed[ animIndex ]
+
blendWeight * a.mGraphics->mRed[ animBlendIndex ];
returnColor.g =
( 1 - blendWeight ) * a.mGraphics->mGreen[ animIndex ]
+
blendWeight * a.mGraphics->mGreen[ animBlendIndex ];
returnColor.b =
( 1 - blendWeight ) * a.mGraphics->mBlue[ animIndex ]
+
blendWeight * a.mGraphics->mBlue[ animBlendIndex ];
}
else {
// no blend
returnColor.r = a.mGraphics->mRed[ animIndex ];
returnColor.g = a.mGraphics->mGreen[ animIndex ];
returnColor.b = a.mGraphics->mBlue[ animIndex ];
}
*outTransient = true;
// don't return here, because there might be other
// animations and sprites that are on top of
// this one
isSampleAnim = true;
}
}
}
if( isSampleAnim ) {
// we have already found an animation here that is on top
// of whatever map graphics we might sample below
// thus, we can return now
return returnColor;
}
int tileIndex;
char blocked = isBlocked( inX, inY );
if( !blocked ) {
// empty tile
tileIndex = 0;
}
else {
int neighborsBlockedBinary = 0;
if( isBlocked( inX, inY - tileH ) ) {
// top
neighborsBlockedBinary = neighborsBlockedBinary | 1;
}
if( isBlocked( inX + tileW, inY ) ) {
// right
neighborsBlockedBinary = neighborsBlockedBinary | 1 << 1;
}
if( isBlocked( inX, inY + tileH ) ) {
// bottom
neighborsBlockedBinary = neighborsBlockedBinary | 1 << 2;
}
if( isBlocked( inX - tileW, inY ) ) {
// left
neighborsBlockedBinary = neighborsBlockedBinary | 1 << 3;
}
// skip empty tile, treat as tile index
neighborsBlockedBinary += 1;
tileIndex = neighborsBlockedBinary;
}
// pick a tile set
int netWorldSpan = tileSetWorldSpan + tileSetWorldOverlap;
int tileSet = inX / netWorldSpan + tileSetSkip;
int overhang = inX % netWorldSpan;
if( inX < 0 ) {
// fix to a constant tile set below 0
overhang = 0;
tileSet = 0;
}
// is there blending with next tile set?
int blendTileSet = tileSet + 1;
double blendWeight = 0;
if( overhang > tileSetWorldSpan ) {
blendWeight = ( overhang - tileSetWorldSpan ) /
(double) tileSetWorldOverlap;
}
// else 100% blend of our first tile set
tileSet = tileSet % numTileSets;
blendTileSet = blendTileSet % numTileSets;
// make sure not negative
if( tileSet < 0 ) {
tileSet += numTileSets;
}
if( blendTileSet < 0 ) {
blendTileSet += numTileSets;
}
// apply mapping
tileSet = mapTileSet( tileSet );
blendTileSet = mapTileSet( blendTileSet );
// sample from tile image
int imageY = inY % tileH;
int imageX = inX % tileW;
if( imageX < 0 ) {
imageX += tileW;
}
if( imageY < 0 ) {
imageY += tileH;
}
// offset to top left corner of tile
int tileImageOffset = tileIndex * ( tileH + 1 ) * tileImageW
+ tileSet * (tileW + 1);
int blendTileImageOffset = tileIndex * ( tileH + 1 ) * tileImageW
+ blendTileSet * (tileW + 1);
int imageIndex = tileImageOffset + imageY * tileImageW + imageX;
int blendImageIndex = blendTileImageOffset + imageY * tileImageW + imageX;
returnColor.r =
(1-blendWeight) * tileContainer->mRed[ imageIndex ] +
blendWeight * tileContainer->mRed[ blendImageIndex ];
returnColor.g =
(1-blendWeight) * tileContainer->mGreen[ imageIndex ] +
blendWeight * tileContainer->mGreen[ blendImageIndex ];
returnColor.b =
(1-blendWeight) * tileContainer->mBlue[ imageIndex ] +
blendWeight * tileContainer->mBlue[ blendImageIndex ];
// only consider drawing chests in empty spots
if( !blocked && isChest( inX, inY ) ) {
// draw chest here
char chestType = isChest( inX, inY );
// sample from chest image
int imageY = inY % chestH;
int imageX = inX % chestW;
if( imageX < 0 ) {
imageX += chestW;
}
if( imageY < 0 ) {
imageY += chestH;
}
int spriteIndex = 0;
if( chestType == CHEST_OPEN ) {
spriteIndex = 1;
}
// skip to sub-sprite
int spriteOffset =
spriteIndex *
chestW *
( chestH + 1 );
int subSpriteIndex = imageY * chestW + imageX;
int imageIndex = spriteOffset + subSpriteIndex;
if( !isSpriteTransparent( chestContainer, imageIndex ) ) {
if( chestType == CHEST_CLOSED ) {
*outTransient = true;
}
// check if this is one of the gem locations
char isGem = false;
int gemNumber = 0;
for( int i=0; i<numGems && !isGem; i++ ) {
if( subSpriteIndex == gemLocations[ i ] ) {
isGem = true;
gemNumber = i;
}
}
char gemColorUsed = false;
if( isGem ) {
// check if our gem is turned on for this chest
unsigned char code = getChestCode( inX, inY );
if( code & 0x01 << gemNumber ) {
gemColorUsed = true;
returnColor.r = gemColors[ gemNumber ][ 0 ];
returnColor.g = gemColors[ gemNumber ][ 1 ];
returnColor.b = gemColors[ gemNumber ][ 2 ];
}
}
if( !gemColorUsed ) {
// use underlying chest color
returnColor.r = chestContainer->mRed[ imageIndex ];
returnColor.g = chestContainer->mGreen[ imageIndex ];
returnColor.b = chestContainer->mBlue[ imageIndex ];
}
}
}
return returnColor;
}
int getTileWidth() {
return tileW;
}
int getTileHeight() {
return tileH;
}
void destroyWorld() {
/*
printf( "%d hits, %d misses, %f hit ratio\n",
hitCount, missCount, hitCount / (double)( hitCount + missCount ) );
*/
}
void stepAnimations() {
for( int i=0; i<animationList.size(); i++ ) {
Animation *a = animationList.getElement( i );
if( a->mAutoStep ) {
if( a->mFrameNumber < a->mNumFrames - 1 ) {
a->mFrameNumber ++;
}
else if( a->mRemoveAtEnd ) {
// remove it
animationList.deleteElement( i );
// back up in list for next loop iteration
i--;
}
}
}
}
void startPrizeAnimation( int inX, int inY ) {
Animation a( inX, inY, 16, 16, true, true, prizeAnimationContainer );
animationList.push_back( a );
}
void startDustAnimation( int inX, int inY ) {
Animation a( inX, inY, 16, 16, true, true, dustAnimationContainer );
animationList.push_back( a );
}
void startHeartAnimation( int inX, int inY ) {
Animation a( inX, inY, 16, 16, true, true, heartAnimationContainer );
animationList.push_back( a );
}
#include <math.h>
void setPlayerPosition( int inX, int inY ) {
Animation *spriteAnimation =
animationList.getElement( spriteAnimationIndex );
char moving = false;
if( inX != spriteAnimation->mX ) {
moving = true;
}
spriteAnimation->mX = inX;
// player position centered at sprite's feet
int newSpriteY = inY - spriteAnimation->mFrameH / 2 + 1;
if( newSpriteY != spriteAnimation->mY ) {
moving = true;
}
spriteAnimation->mY = newSpriteY;
if( metSpouse && ! spouseDead ) {
Animation *spouseAnimation =
animationList.getElement( spouseAnimationIndex );
// spouse stands immediately in front of player
int desiredSpouseX = inX + spouseAnimation->mFrameH;
int desiredSpouseY = spriteAnimation->mY;
// gravitates there gradually one pixel at a time in each x and y
int dX = desiredSpouseX - spouseAnimation->mX;
int dY = desiredSpouseY - spouseAnimation->mY;
// convert to -1, 0, or +1
if( dX != 0 ) {
dX = (int)( dX / fabs( dX ) );
}
if( dY != 0 ) {
dY = (int)( dY / fabs( dY ) );
}
if( moving ) {
// only execute this transition when player is moving
spouseAnimation->mX += dX;
spouseAnimation->mY += dY;
}
// check for heart animation and have it track moving couple
for( int i=0; i<animationList.size(); i++ ) {
Animation *a = animationList.getElement( i );
if( a->mGraphics == heartAnimationContainer ) {
// move it halfway between player and spouse
a->mX = ( spouseAnimation->mX - spriteAnimation->mX ) / 2 +
spriteAnimation->mX;
a->mY = ( spouseAnimation->mY - spriteAnimation->mY ) / 2 +
spriteAnimation->mY + 1;
}
}
}
}
void setPlayerSpriteFrame( int inFrame ) {
Animation *spriteAnimation =
animationList.getElement( spriteAnimationIndex );
spriteAnimation->mFrameNumber = inFrame;
if( metSpouse && ! spouseDead ) {
Animation *spouseAnimation =
animationList.getElement( spouseAnimationIndex );
// spouse follows player
spouseAnimation->mFrameNumber = inFrame;
}
}
void setCharacterAges( double inAge ) {
Animation *spriteAnimation =
animationList.getElement( spriteAnimationIndex );
Animation *spouseAnimation =
animationList.getElement( spouseAnimationIndex );
// 0 -> 0.25, constant page 0
if( inAge <= 0.25 ) {
spriteAnimation->mPageNumber = 0;
spouseAnimation->mPageNumber = 0;
}
// 0.75 - 1.0, constant last page
else if( inAge >= 0.75 ) {
spriteAnimation->mPageNumber = spriteAnimation->mNumPages - 1;
spouseAnimation->mPageNumber = spouseAnimation->mNumPages - 1;
}
else {
// blend of pages in between
double blendingAge = ( inAge - 0.25 ) / 0.5;
spriteAnimation->mPageNumber =
blendingAge * ( spriteAnimation->mNumPages - 1 );
spouseAnimation->mPageNumber =
blendingAge * ( spouseAnimation->mNumPages - 1 );
}
}
void getSpousePosition( int *outX, int *outY ) {
Animation *spouseAnimation =
animationList.getElement( spouseAnimationIndex );
*outX = spouseAnimation->mX;
*outY = spouseAnimation->mY + spouseAnimation->mFrameH / 2 - 1;
}
char haveMetSpouse() {
return metSpouse && ! spouseDead;
}
void meetSpouse() {
metSpouse = true;
}
void diePlayer() {
Animation *spriteAnimation =
animationList.getElement( spriteAnimationIndex );
playerDead = true;
// tombstone
spriteAnimation->mFrameNumber = 8;
}
void dieSpouse() {
Animation *spriteAnimation =
animationList.getElement( spriteAnimationIndex );
Animation *spouseAnimation =
animationList.getElement( spouseAnimationIndex );
spouseDead = true;
// tombstone
spouseAnimation->mFrameNumber = 8;
if( metSpouse ) {
// swap player sprite with sad sprite
spriteAnimation->swapGraphics( spriteSadContainer );
}
}
char isPlayerDead() {
return playerDead;
}
char isSpouseDead() {
return spouseDead;
}
void loadWorldGraphics() {
tileContainer = new GraphicContainer( "tileSet.tga" );
chestContainer = new GraphicContainer( "chest.tga" );
spriteContainer = new GraphicContainer( "characterSprite.tga" );
spriteSadContainer = new GraphicContainer( "characterSpriteSad.tga" );
spouseContainer = new GraphicContainer( "spouseSprite.tga" );
prizeAnimationContainer = new GraphicContainer( "chestPrize.tga" );
dustAnimationContainer = new GraphicContainer( "chestDust.tga" );
heartAnimationContainer = new GraphicContainer( "heart.tga" );
}
void destroyWorldGraphics() {
delete tileContainer;
delete chestContainer;
delete spriteContainer;
delete spriteSadContainer;
delete spouseContainer;
delete prizeAnimationContainer;
delete dustAnimationContainer;
delete heartAnimationContainer;
}

View file

@ -0,0 +1,60 @@
#include <stdint.h>
typedef uint32_t Uint32;
// these can be called once at beginning and end of app execution
// since loaded graphics can be reused for multiple games
void loadWorldGraphics();
void destroyWorldGraphics();
// these should be called at the beginning and end of each new game
void initWorld();
void destroyWorld();
Uint32 sampleFromWorld( int inX, int inY, double inWeight = 1.0 );
void startPrizeAnimation( int inX, int inY );
void startDustAnimation( int inX, int inY );
void setPlayerPosition( int inX, int inY );
void setPlayerSpriteFrame( int inFrame );
void getSpousePosition( int *outX, int *outY );
char haveMetSpouse();
void meetSpouse();
void startHeartAnimation( int inX, int inY );
void diePlayer();
void dieSpouse();
char isSpouseDead();
char isPlayerDead();
// age in range 0..1
void setCharacterAges( double inAge );
// push animations forward one step
void stepAnimations();
int getTileWidth();
int getTileHeight();

View file

@ -0,0 +1,72 @@
#include "blowUp.h"
#include <string.h>
void blowupOntoScreen( Uint32 *inImage, int inWidth, int inHeight,
int inBlowFactor, SDL_Surface *inScreen ) {
int newWidth = inBlowFactor * inWidth;
int newHeight = inBlowFactor * inHeight;
int yOffset = ( inScreen->h - newHeight ) / 2;
int xOffset = ( inScreen->w - newWidth ) / 2;
// pitch is in bytes
// convert to width in pixels
int scanlineWidth = inScreen->pitch / 4;
Uint32 *pixels = (Uint32 *)( inScreen->pixels );
// looping across the smaller image, instead of across the larger screen,
// was discovered using the profiler.
// an entire screen row is repeated inBlowFactor times down the screen
// (as a row of pixel boxes)
// Thus, we can offload a lot more work onto memcpy if we assemble one
// of these rows and then memcpy it onto the screen inBlowFactor times
for( int y=0; y<inHeight; y++ ) {
Uint32 *screenRow = new Uint32[ newWidth ];
// fill the screen row with rows from the pixel boxes
for( int x=0; x<inWidth; x++ ) {
Uint32 pixelValue = inImage[ y * inWidth + x ];
// spread this pixel across an inBlowFactor-wide box row in
// the screen row
int boxXStart = inBlowFactor * x;
int boxXEnd = boxXStart + inBlowFactor;
// make an array to represent one row of this box
// we can thus replace the inner loop with a memcpy below
for( int i=boxXStart; i<boxXEnd; i++ ) {
screenRow[i] = pixelValue;
}
}
// now copy the row onto the screen inBlowFactor times
int screenRowStart = ( yOffset + y * inBlowFactor ) * scanlineWidth
+ xOffset;
int screenRowEnd = screenRowStart + inBlowFactor * scanlineWidth;
int screenRowIncrement = scanlineWidth;
for( int screenRowIndex = screenRowStart;
screenRowIndex < screenRowEnd;
screenRowIndex += screenRowIncrement ) {
memcpy( &( pixels[ screenRowIndex ] ),
screenRow, newWidth * 4 );
}
delete [] screenRow;
}
}

View file

@ -0,0 +1,11 @@
#include <SDL/SDL_video.h>
#include <SDL/SDL.h>
/**
* Blows an image up onto the screen using nearest neighbor (pixelated)
* interpolation.
*/
void blowupOntoScreen( Uint32 *inImage, int inWidth, int inHeight,
int inBlowFactor, SDL_Surface *inScreen );

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 B

View file

@ -0,0 +1,24 @@
#include "common.h"
#include "minorGems/graphics/converters/TGAImageConverter.h"
#include "minorGems/io/file/File.h"
#include "minorGems/io/file/FileInputStream.h"
Image *readTGA( const char *inFileName ) {
return readTGA( "graphics", inFileName );
}
Image *readTGA( const char *inFolderName, const char *inFileName ) {
File tgaFile( new Path( inFolderName ), inFileName );
FileInputStream tgaStream( &tgaFile );
TGAImageConverter converter;
return converter.deformatImage( &tgaStream );
}

View file

@ -0,0 +1,17 @@
#ifndef COMMON_INCLUDED
#define COMMON_INCLUDED
#include "minorGems/graphics/Image.h"
// reads a TGA file from the default ("graphics") folder
Image *readTGA( const char *inFileName );
Image *readTGA( const char *inFolderName, const char *inFileName );
#endif

89
gamma256/gameSource/configure vendored Executable file
View file

@ -0,0 +1,89 @@
#!/bin/bash
#
# Modification History
#
# 2007-November-12 Jason Rohrer
# Copied/modified from Cultivation (game2) project.
#
while [ -z "$platformSelection" ]
do
echo "select platform:"
echo " 1 -- GNU/Linux"
echo " 2 -- MacOSX"
echo " 3 -- Win32 using MinGW"
echo " q -- quit"
echo ""
echo -n "> "
read platformSelection
if [ "$platformSelection" = "q" ]
then
exit
fi
# use ASCII comparison.
if [[ "$platformSelection" > "3" ]]
then
platformSelection=""
fi
if [[ "$platformSelection" < "1" ]]
then
platformSelection=""
fi
done
platformName="Generic"
platformMakefile="generic"
case "$platformSelection" in
"1" )
platformName="GNU/Linux"
platformMakefile="Makefile.GnuLinux"
;;
"2" )
platformName="MacOSX"
platformMakefile="Makefile.MacOSX"
;;
"3" )
platformName="Win32 MinGW"
platformMakefile="Makefile.MinGW"
;;
esac
rm -f Makefile.temp
echo "# Auto-generated by gamma256/gameSource/configure for the $platformName platform. Do not edit manually." > Makefile.temp
rm -f Makefile
cat Makefile.temp $platformMakefile Makefile.all > Makefile
rm Makefile.temp
exit

1300
gamma256/gameSource/game.cpp Normal file

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//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>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string>Icon.png</string>
<key>CFBundleIdentifier</key>
<string>net.sf.hcsoftware.${PRODUCT_NAME}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>3.1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSMainNibFile</key>
<string>MainWindow</string>
<key>UIStatusBarHidden</key>
<true/>
</dict>
</plist>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -0,0 +1,237 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.03">
<data>
<int key="IBDocument.SystemTarget">528</int>
<string key="IBDocument.SystemVersion">9F33</string>
<string key="IBDocument.InterfaceBuilderVersion">677</string>
<string key="IBDocument.AppKitVersion">949.34</string>
<string key="IBDocument.HIToolboxVersion">352.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="2"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBProxyObject" id="841351856">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
</object>
<object class="IBProxyObject" id="427554174">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
</object>
<object class="IBUICustomObject" id="664661524"/>
<object class="IBUIWindow" id="380026005">
<reference key="NSNextResponder"/>
<int key="NSvFlags">1316</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBUIView" id="309370163">
<reference key="NSNextResponder" ref="380026005"/>
<int key="NSvFlags">1298</int>
<string key="NSFrameSize">{320, 480}</string>
<reference key="NSSuperview" ref="380026005"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
<object class="NSColorSpace" key="NSCustomColorSpace">
<int key="NSID">2</int>
</object>
</object>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
</object>
</object>
<object class="NSPSMatrix" key="NSFrameMatrix"/>
<string key="NSFrameSize">{320, 480}</string>
<reference key="NSSuperview"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MSAxIDEAA</bytes>
</object>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
<object class="NSMutableArray" key="connectionRecords">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="664661524"/>
</object>
<int key="connectionID">4</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">window</string>
<reference key="source" ref="664661524"/>
<reference key="destination" ref="380026005"/>
</object>
<int key="connectionID">5</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="664661524"/>
<reference key="destination" ref="309370163"/>
</object>
<int key="connectionID">11</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBObjectRecord">
<int key="objectID">0</int>
<object class="NSArray" key="object" id="957960031">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2</int>
<reference key="object" ref="380026005"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="309370163"/>
</object>
<reference key="parent" ref="957960031"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="841351856"/>
<reference key="parent" ref="957960031"/>
<string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="664661524"/>
<reference key="parent" ref="957960031"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="427554174"/>
<reference key="parent" ref="957960031"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">10</int>
<reference key="object" ref="309370163"/>
<reference key="parent" ref="380026005"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>-1.CustomClassName</string>
<string>-2.CustomClassName</string>
<string>10.CustomClassName</string>
<string>10.IBPluginDependency</string>
<string>2.IBAttributePlaceholdersKey</string>
<string>2.IBEditorWindowLastContentRect</string>
<string>2.IBPluginDependency</string>
<string>3.CustomClassName</string>
<string>3.IBPluginDependency</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>UIApplication</string>
<string>UIResponder</string>
<string>MyView</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<object class="NSMutableDictionary">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<string>{{411, 129}, {320, 480}}</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>gameWindowAppDelegate</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<nil key="activeLocalization"/>
<object class="NSMutableDictionary" key="localizations">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">11</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">MyView</string>
<string key="superclassName">UIView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="747307864">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">gameWindowAppDelegate.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">MyView</string>
<string key="superclassName">UIView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBUserSource</string>
<string key="minorKey"/>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">gameWindowAppDelegate</string>
<string key="superclassName">NSObject</string>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>view</string>
<string>window</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>MyView</string>
<string>UIWindow</string>
</object>
</object>
<reference key="sourceIdentifier" ref="747307864"/>
</object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.LastKnownRelativeProjectPath">gameWindowApp.xcodeproj</string>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
</data>
</archive>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View file

@ -0,0 +1,84 @@
#include "blowUp.h"
#include <string.h>
void blowupOntoScreen( Uint32 *inImage, int inWidth, int inHeight,
int inBlowFactor, Uint32 *inScreenPixels,
int inScreenWidth, int inScreenHeight ) {
int newWidth = inBlowFactor * inWidth;
int newHeight = inBlowFactor * inHeight;
int yOffset = ( inScreenHeight - newHeight ) / 2;
// "up" a bit more on iPhone to make room for touch widget
int xOffset = 2 * ( inScreenWidth - newWidth ) / 3;
// pitch equals width for iPhone implementation
int scanlineWidth = inScreenWidth;
Uint32 *pixels = inScreenPixels;
// looping across the smaller image, instead of across the larger screen,
// was discovered using the profiler.
// an entire screen row is repeated inBlowFactor times down the screen
// (as a row of pixel boxes)
// Thus, we can offload a lot more work onto memcpy if we assemble one
// of these rows and then memcpy it onto the screen inBlowFactor times
for( int y=0; y<inHeight; y++ ) {
Uint32 *screenRow = new Uint32[ newWidth ];
// flip image vertically for iPhone
int gameY = (inHeight - 1) - y;
// fill the screen row with rows from the pixel boxes
for( int x=0; x<inWidth; x++ ) {
Uint32 pixelValue = inImage[ gameY * inWidth + x ];
// swap red and blue on iPhone
unsigned char red = (pixelValue >> 16) & 0xFF;
unsigned char green = (pixelValue >> 8) & 0xFF;
unsigned char blue = (pixelValue >> 0) & 0xFF;
pixelValue = blue << 16 | green << 8 | red;
// spread this pixel across an inBlowFactor-wide box row in
// the screen row
int boxXStart = inBlowFactor * x;
int boxXEnd = boxXStart + inBlowFactor;
// make an array to represent one row of this box
// we can thus replace the inner loop with a memcpy below
for( int i=boxXStart; i<boxXEnd; i++ ) {
screenRow[i] = pixelValue;
}
}
// now copy the row onto the screen inBlowFactor times
int screenRowStart = ( yOffset + y * inBlowFactor ) * scanlineWidth
+ xOffset;
int screenRowEnd = screenRowStart + inBlowFactor * scanlineWidth;
int screenRowIncrement = scanlineWidth;
for( int screenRowIndex = screenRowStart;
screenRowIndex < screenRowEnd;
screenRowIndex += screenRowIncrement ) {
memcpy( &( pixels[ screenRowIndex ] ),
screenRow, newWidth * 4 );
}
delete [] screenRow;
}
}

View file

@ -0,0 +1,10 @@
#include "drawIntoScreen.h"
/**
* Blows an image up onto the screen using nearest neighbor (pixelated)
* interpolation.
*/
void blowupOntoScreen( Uint32 *inImage, int inWidth, int inHeight,
int inBlowFactor, Uint32 *inScreenPixels,
int inScreenWidth, int inScreenHeight );

View file

@ -0,0 +1,25 @@
#include "common.h"
#include "minorGems/graphics/converters/TGAImageConverter.h"
#include "minorGems/io/file/File.h"
#include "minorGems/io/file/FileInputStream.h"
Image *readTGA( char *inFileName ) {
return readTGA( "graphics", inFileName );
}
Image *readTGA( char *inFolderName, char *inFileName ) {
// ignore passed-in path (use bundle root)
File tgaFile( NULL, inFileName );
FileInputStream tgaStream( &tgaFile );
TGAImageConverter converter;
return converter.deformatImage( &tgaStream );
}

View file

@ -0,0 +1,22 @@
// interface for generic screen drawing framework
#include <stdint.h>
typedef uint32_t Uint32;
void initScreenDrawer( Uint32 *inScreenBuffer, int inWidth, int inHeight );
// each pixel is 4 characters
void drawIntoScreen( Uint32 *inScreenBuffer, int inWidth, int inHeight );
// set device orientation from accelerometer
void setOrientation( float inX, float inY );
void touchStartPoint( float inX, float inY );
void touchMovePoint( float inX, float inY );
void touchEndPoint( float inX, float inY );
void freeScreenDrawer();

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,468 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 45;
objects = {
/* Begin PBXBuildFile section */
1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
DA12F3060EF6E70100A40C6D /* title.tga in Resources */ = {isa = PBXBuildFile; fileRef = DA12F2FC0EF6E70100A40C6D /* title.tga */; };
DA12F3070EF6E70100A40C6D /* heart.tga in Resources */ = {isa = PBXBuildFile; fileRef = DA12F2FD0EF6E70100A40C6D /* heart.tga */; };
DA12F3080EF6E70100A40C6D /* numerals.tga in Resources */ = {isa = PBXBuildFile; fileRef = DA12F2FE0EF6E70100A40C6D /* numerals.tga */; };
DA12F3090EF6E70100A40C6D /* spouseSprite.tga in Resources */ = {isa = PBXBuildFile; fileRef = DA12F2FF0EF6E70100A40C6D /* spouseSprite.tga */; };
DA12F30A0EF6E70100A40C6D /* tileSet.tga in Resources */ = {isa = PBXBuildFile; fileRef = DA12F3000EF6E70100A40C6D /* tileSet.tga */; };
DA12F30B0EF6E70100A40C6D /* chestPrize.tga in Resources */ = {isa = PBXBuildFile; fileRef = DA12F3010EF6E70100A40C6D /* chestPrize.tga */; };
DA12F30C0EF6E70100A40C6D /* chestDust.tga in Resources */ = {isa = PBXBuildFile; fileRef = DA12F3020EF6E70100A40C6D /* chestDust.tga */; };
DA12F30D0EF6E70100A40C6D /* chest.tga in Resources */ = {isa = PBXBuildFile; fileRef = DA12F3030EF6E70100A40C6D /* chest.tga */; };
DA12F30E0EF6E70100A40C6D /* characterSpriteSad.tga in Resources */ = {isa = PBXBuildFile; fileRef = DA12F3040EF6E70100A40C6D /* characterSpriteSad.tga */; };
DA12F30F0EF6E70100A40C6D /* characterSprite.tga in Resources */ = {isa = PBXBuildFile; fileRef = DA12F3050EF6E70100A40C6D /* characterSprite.tga */; };
DA12F3390EF6E89F00A40C6D /* World.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA12F32E0EF6E89F00A40C6D /* World.cpp */; };
DA12F33A0EF6E89F00A40C6D /* score.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA12F3300EF6E89F00A40C6D /* score.cpp */; };
DA12F33B0EF6E89F00A40C6D /* map.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA12F3320EF6E89F00A40C6D /* map.cpp */; };
DA12F33C0EF6E89F00A40C6D /* landscape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA12F3340EF6E89F00A40C6D /* landscape.cpp */; };
DA12F33D0EF6E89F00A40C6D /* Envelope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA12F3370EF6E89F00A40C6D /* Envelope.cpp */; };
DA12F3420EF6E8BD00A40C6D /* blowUp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA12F33E0EF6E8BD00A40C6D /* blowUp.cpp */; };
DA12F3430EF6E8BD00A40C6D /* common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA12F3400EF6E8BD00A40C6D /* common.cpp */; };
DA12F3440EF6E8BD00A40C6D /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA12F3410EF6E8BD00A40C6D /* game.cpp */; };
DA12F3E60EF6F00600A40C6D /* music.tga in Resources */ = {isa = PBXBuildFile; fileRef = DA12F3E50EF6F00600A40C6D /* music.tga */; };
DA7F11810EF6D77000CB6D50 /* gameWindowAppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA7F117E0EF6D77000CB6D50 /* gameWindowAppDelegate.mm */; };
DA8276E60EF9B2290061079D /* arrows.tga in Resources */ = {isa = PBXBuildFile; fileRef = DA8276E50EF9B2290061079D /* arrows.tga */; };
DA8277840EF9FFE80061079D /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = DA8277830EF9FFE80061079D /* Icon.png */; };
DA86AEC90EF53C7100054E6B /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; };
DA8C9E1C0EF8095C002FCA67 /* TimeUnix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA8C9E1B0EF8095C002FCA67 /* TimeUnix.cpp */; };
DA8C9E1E0EF80968002FCA67 /* ThreadLinux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA8C9E1D0EF80968002FCA67 /* ThreadLinux.cpp */; };
DA8C9E200EF80985002FCA67 /* PathLinux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA8C9E1F0EF80985002FCA67 /* PathLinux.cpp */; };
DA8C9F090EF817F7002FCA67 /* StringBufferOutputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA8C9F050EF817F7002FCA67 /* StringBufferOutputStream.cpp */; };
DA8C9F0A0EF817F7002FCA67 /* stringUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA8C9F070EF817F7002FCA67 /* stringUtils.cpp */; };
DA90DD060EFAB907001BABB5 /* musicPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA90DD050EFAB907001BABB5 /* musicPlayer.cpp */; };
DA90DD140EFAC2AF001BABB5 /* Timbre.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA90DD110EFAC2AF001BABB5 /* Timbre.cpp */; };
DA90DD4A0EFADE15001BABB5 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA90DD490EFADE15001BABB5 /* AudioToolbox.framework */; };
DA9E302E0EFC010300DFACC7 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA9E302C0EFC010300DFACC7 /* QuartzCore.framework */; };
DA9E302F0EFC010300DFACC7 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA9E302D0EFC010300DFACC7 /* OpenGLES.framework */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
1D6058910D05DD3D006BFB54 /* Passage.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Passage.app; sourceTree = BUILT_PRODUCTS_DIR; };
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = "<group>"; };
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
DA12F2FC0EF6E70100A40C6D /* title.tga */ = {isa = PBXFileReference; lastKnownFileType = file; name = title.tga; path = ../graphics/title.tga; sourceTree = SOURCE_ROOT; };
DA12F2FD0EF6E70100A40C6D /* heart.tga */ = {isa = PBXFileReference; lastKnownFileType = file; name = heart.tga; path = ../graphics/heart.tga; sourceTree = SOURCE_ROOT; };
DA12F2FE0EF6E70100A40C6D /* numerals.tga */ = {isa = PBXFileReference; lastKnownFileType = file; name = numerals.tga; path = ../graphics/numerals.tga; sourceTree = SOURCE_ROOT; };
DA12F2FF0EF6E70100A40C6D /* spouseSprite.tga */ = {isa = PBXFileReference; lastKnownFileType = file; name = spouseSprite.tga; path = ../graphics/spouseSprite.tga; sourceTree = SOURCE_ROOT; };
DA12F3000EF6E70100A40C6D /* tileSet.tga */ = {isa = PBXFileReference; lastKnownFileType = file; name = tileSet.tga; path = ../graphics/tileSet.tga; sourceTree = SOURCE_ROOT; };
DA12F3010EF6E70100A40C6D /* chestPrize.tga */ = {isa = PBXFileReference; lastKnownFileType = file; name = chestPrize.tga; path = ../graphics/chestPrize.tga; sourceTree = SOURCE_ROOT; };
DA12F3020EF6E70100A40C6D /* chestDust.tga */ = {isa = PBXFileReference; lastKnownFileType = file; name = chestDust.tga; path = ../graphics/chestDust.tga; sourceTree = SOURCE_ROOT; };
DA12F3030EF6E70100A40C6D /* chest.tga */ = {isa = PBXFileReference; lastKnownFileType = file; name = chest.tga; path = ../graphics/chest.tga; sourceTree = SOURCE_ROOT; };
DA12F3040EF6E70100A40C6D /* characterSpriteSad.tga */ = {isa = PBXFileReference; lastKnownFileType = file; name = characterSpriteSad.tga; path = ../graphics/characterSpriteSad.tga; sourceTree = SOURCE_ROOT; };
DA12F3050EF6E70100A40C6D /* characterSprite.tga */ = {isa = PBXFileReference; lastKnownFileType = file; name = characterSprite.tga; path = ../graphics/characterSprite.tga; sourceTree = SOURCE_ROOT; };
DA12F32D0EF6E89F00A40C6D /* World.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = World.h; path = ../World.h; sourceTree = SOURCE_ROOT; };
DA12F32E0EF6E89F00A40C6D /* World.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = World.cpp; path = ../World.cpp; sourceTree = SOURCE_ROOT; };
DA12F32F0EF6E89F00A40C6D /* score.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = score.h; path = ../score.h; sourceTree = SOURCE_ROOT; };
DA12F3300EF6E89F00A40C6D /* score.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = score.cpp; path = ../score.cpp; sourceTree = SOURCE_ROOT; };
DA12F3310EF6E89F00A40C6D /* map.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = map.h; path = ../map.h; sourceTree = SOURCE_ROOT; };
DA12F3320EF6E89F00A40C6D /* map.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = map.cpp; path = ../map.cpp; sourceTree = SOURCE_ROOT; };
DA12F3330EF6E89F00A40C6D /* landscape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = landscape.h; path = ../landscape.h; sourceTree = SOURCE_ROOT; };
DA12F3340EF6E89F00A40C6D /* landscape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = landscape.cpp; path = ../landscape.cpp; sourceTree = SOURCE_ROOT; };
DA12F3350EF6E89F00A40C6D /* HashTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HashTable.h; path = ../HashTable.h; sourceTree = SOURCE_ROOT; };
DA12F3360EF6E89F00A40C6D /* Envelope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Envelope.h; path = ../Envelope.h; sourceTree = SOURCE_ROOT; };
DA12F3370EF6E89F00A40C6D /* Envelope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Envelope.cpp; path = ../Envelope.cpp; sourceTree = SOURCE_ROOT; };
DA12F33E0EF6E8BD00A40C6D /* blowUp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = blowUp.cpp; sourceTree = "<group>"; };
DA12F33F0EF6E8BD00A40C6D /* blowUp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = blowUp.h; sourceTree = "<group>"; };
DA12F3400EF6E8BD00A40C6D /* common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = common.cpp; sourceTree = "<group>"; };
DA12F3410EF6E8BD00A40C6D /* game.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = game.cpp; sourceTree = "<group>"; };
DA12F3CF0EF6EED000A40C6D /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = common.h; path = ../common.h; sourceTree = SOURCE_ROOT; };
DA12F3E50EF6F00600A40C6D /* music.tga */ = {isa = PBXFileReference; lastKnownFileType = file; name = music.tga; path = ../music/music.tga; sourceTree = SOURCE_ROOT; };
DA7F10EE0EF6CA2500CB6D50 /* drawIntoScreen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = drawIntoScreen.h; sourceTree = "<group>"; };
DA7F117E0EF6D77000CB6D50 /* gameWindowAppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = gameWindowAppDelegate.mm; sourceTree = "<group>"; };
DA7F117F0EF6D77000CB6D50 /* gameWindowAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gameWindowAppDelegate.h; sourceTree = "<group>"; };
DA7F11800EF6D77000CB6D50 /* gameWindowApp_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gameWindowApp_Prefix.pch; sourceTree = "<group>"; };
DA8276E50EF9B2290061079D /* arrows.tga */ = {isa = PBXFileReference; lastKnownFileType = file; path = arrows.tga; sourceTree = "<group>"; };
DA8277830EF9FFE80061079D /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = "<group>"; };
DA8C9E1B0EF8095C002FCA67 /* TimeUnix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TimeUnix.cpp; path = ../../../minorGems/system/unix/TimeUnix.cpp; sourceTree = SOURCE_ROOT; };
DA8C9E1D0EF80968002FCA67 /* ThreadLinux.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadLinux.cpp; path = ../../../minorGems/system/linux/ThreadLinux.cpp; sourceTree = SOURCE_ROOT; };
DA8C9E1F0EF80985002FCA67 /* PathLinux.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PathLinux.cpp; path = ../../../minorGems/io/file/linux/PathLinux.cpp; sourceTree = SOURCE_ROOT; };
DA8C9F050EF817F7002FCA67 /* StringBufferOutputStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringBufferOutputStream.cpp; path = ../../../minorGems/util/StringBufferOutputStream.cpp; sourceTree = SOURCE_ROOT; };
DA8C9F060EF817F7002FCA67 /* StringBufferOutputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringBufferOutputStream.h; path = ../../../minorGems/util/StringBufferOutputStream.h; sourceTree = SOURCE_ROOT; };
DA8C9F070EF817F7002FCA67 /* stringUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stringUtils.cpp; path = ../../../minorGems/util/stringUtils.cpp; sourceTree = SOURCE_ROOT; };
DA8C9F080EF817F7002FCA67 /* stringUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stringUtils.h; path = ../../../minorGems/util/stringUtils.h; sourceTree = SOURCE_ROOT; };
DA90DD050EFAB907001BABB5 /* musicPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = musicPlayer.cpp; sourceTree = "<group>"; };
DA90DD110EFAC2AF001BABB5 /* Timbre.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Timbre.cpp; path = ../Timbre.cpp; sourceTree = SOURCE_ROOT; };
DA90DD120EFAC2AF001BABB5 /* Timbre.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Timbre.h; path = ../Timbre.h; sourceTree = SOURCE_ROOT; };
DA90DD130EFAC2AF001BABB5 /* musicPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = musicPlayer.h; path = ../musicPlayer.h; sourceTree = SOURCE_ROOT; };
DA90DD490EFADE15001BABB5 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
DA9E302C0EFC010300DFACC7 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
DA9E302D0EFC010300DFACC7 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
1D60588F0D05DD3D006BFB54 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
DA90DD4A0EFADE15001BABB5 /* AudioToolbox.framework in Frameworks */,
DA9E302E0EFC010300DFACC7 /* QuartzCore.framework in Frameworks */,
DA9E302F0EFC010300DFACC7 /* OpenGLES.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
080E96DDFE201D6D7F000001 /* Classes */ = {
isa = PBXGroup;
children = (
);
path = Classes;
sourceTree = "<group>";
};
19C28FACFE9D520D11CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
1D6058910D05DD3D006BFB54 /* Passage.app */,
);
name = Products;
sourceTree = "<group>";
};
29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
isa = PBXGroup;
children = (
080E96DDFE201D6D7F000001 /* Classes */,
29B97315FDCFA39411CA2CEA /* Other Sources */,
29B97317FDCFA39411CA2CEA /* Resources */,
29B97323FDCFA39411CA2CEA /* Frameworks */,
19C28FACFE9D520D11CA2CBB /* Products */,
);
name = CustomTemplate;
sourceTree = "<group>";
};
29B97315FDCFA39411CA2CEA /* Other Sources */ = {
isa = PBXGroup;
children = (
DA12F31E0EF6E84900A40C6D /* Unchanged */,
DA12F31D0EF6E83D00A40C6D /* Customized */,
DA7F117E0EF6D77000CB6D50 /* gameWindowAppDelegate.mm */,
DA7F117F0EF6D77000CB6D50 /* gameWindowAppDelegate.h */,
DA7F11800EF6D77000CB6D50 /* gameWindowApp_Prefix.pch */,
DA7F10EE0EF6CA2500CB6D50 /* drawIntoScreen.h */,
29B97316FDCFA39411CA2CEA /* main.m */,
);
name = "Other Sources";
sourceTree = "<group>";
};
29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup;
children = (
DA8277830EF9FFE80061079D /* Icon.png */,
DA12F2FB0EF6E6B100A40C6D /* graphics */,
28AD733E0D9D9553002E5188 /* MainWindow.xib */,
8D1107310486CEB800E47090 /* Info.plist */,
);
name = Resources;
sourceTree = "<group>";
};
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
DA9E302C0EFC010300DFACC7 /* QuartzCore.framework */,
DA9E302D0EFC010300DFACC7 /* OpenGLES.framework */,
DA90DD490EFADE15001BABB5 /* AudioToolbox.framework */,
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
1D30AB110D05D00D00671497 /* Foundation.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
DA12F2FB0EF6E6B100A40C6D /* graphics */ = {
isa = PBXGroup;
children = (
DA8276E50EF9B2290061079D /* arrows.tga */,
DA12F3E50EF6F00600A40C6D /* music.tga */,
DA12F2FC0EF6E70100A40C6D /* title.tga */,
DA12F2FD0EF6E70100A40C6D /* heart.tga */,
DA12F2FE0EF6E70100A40C6D /* numerals.tga */,
DA12F2FF0EF6E70100A40C6D /* spouseSprite.tga */,
DA12F3000EF6E70100A40C6D /* tileSet.tga */,
DA12F3010EF6E70100A40C6D /* chestPrize.tga */,
DA12F3020EF6E70100A40C6D /* chestDust.tga */,
DA12F3030EF6E70100A40C6D /* chest.tga */,
DA12F3040EF6E70100A40C6D /* characterSpriteSad.tga */,
DA12F3050EF6E70100A40C6D /* characterSprite.tga */,
);
name = graphics;
sourceTree = "<group>";
};
DA12F31D0EF6E83D00A40C6D /* Customized */ = {
isa = PBXGroup;
children = (
DA12F33E0EF6E8BD00A40C6D /* blowUp.cpp */,
DA90DD050EFAB907001BABB5 /* musicPlayer.cpp */,
DA12F33F0EF6E8BD00A40C6D /* blowUp.h */,
DA12F3400EF6E8BD00A40C6D /* common.cpp */,
DA12F3410EF6E8BD00A40C6D /* game.cpp */,
);
name = Customized;
sourceTree = "<group>";
};
DA12F31E0EF6E84900A40C6D /* Unchanged */ = {
isa = PBXGroup;
children = (
DA8C9E030EF80930002FCA67 /* minorGems */,
DA90DD110EFAC2AF001BABB5 /* Timbre.cpp */,
DA90DD120EFAC2AF001BABB5 /* Timbre.h */,
DA90DD130EFAC2AF001BABB5 /* musicPlayer.h */,
DA12F3CF0EF6EED000A40C6D /* common.h */,
DA12F32D0EF6E89F00A40C6D /* World.h */,
DA12F32E0EF6E89F00A40C6D /* World.cpp */,
DA12F32F0EF6E89F00A40C6D /* score.h */,
DA12F3300EF6E89F00A40C6D /* score.cpp */,
DA12F3310EF6E89F00A40C6D /* map.h */,
DA12F3320EF6E89F00A40C6D /* map.cpp */,
DA12F3330EF6E89F00A40C6D /* landscape.h */,
DA12F3340EF6E89F00A40C6D /* landscape.cpp */,
DA12F3350EF6E89F00A40C6D /* HashTable.h */,
DA12F3360EF6E89F00A40C6D /* Envelope.h */,
DA12F3370EF6E89F00A40C6D /* Envelope.cpp */,
);
name = Unchanged;
sourceTree = "<group>";
};
DA8C9E030EF80930002FCA67 /* minorGems */ = {
isa = PBXGroup;
children = (
DA8C9F050EF817F7002FCA67 /* StringBufferOutputStream.cpp */,
DA8C9F060EF817F7002FCA67 /* StringBufferOutputStream.h */,
DA8C9F070EF817F7002FCA67 /* stringUtils.cpp */,
DA8C9F080EF817F7002FCA67 /* stringUtils.h */,
DA8C9E1F0EF80985002FCA67 /* PathLinux.cpp */,
DA8C9E1B0EF8095C002FCA67 /* TimeUnix.cpp */,
DA8C9E1D0EF80968002FCA67 /* ThreadLinux.cpp */,
);
name = minorGems;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
1D6058900D05DD3D006BFB54 /* Passage */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Passage" */;
buildPhases = (
1D60588D0D05DD3D006BFB54 /* Resources */,
1D60588E0D05DD3D006BFB54 /* Sources */,
1D60588F0D05DD3D006BFB54 /* Frameworks */,
DA12F31C0EF6E79F00A40C6D /* ShellScript */,
);
buildRules = (
);
dependencies = (
);
name = Passage;
productName = testWindowApp;
productReference = 1D6058910D05DD3D006BFB54 /* Passage.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject;
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "gameWindowApp" */;
compatibilityVersion = "Xcode 3.1";
hasScannedForEncodings = 1;
mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
projectDirPath = "";
projectRoot = "";
targets = (
1D6058900D05DD3D006BFB54 /* Passage */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
1D60588D0D05DD3D006BFB54 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DA86AEC90EF53C7100054E6B /* MainWindow.xib in Resources */,
DA12F3060EF6E70100A40C6D /* title.tga in Resources */,
DA12F3070EF6E70100A40C6D /* heart.tga in Resources */,
DA12F3080EF6E70100A40C6D /* numerals.tga in Resources */,
DA12F3090EF6E70100A40C6D /* spouseSprite.tga in Resources */,
DA12F30A0EF6E70100A40C6D /* tileSet.tga in Resources */,
DA12F30B0EF6E70100A40C6D /* chestPrize.tga in Resources */,
DA12F30C0EF6E70100A40C6D /* chestDust.tga in Resources */,
DA12F30D0EF6E70100A40C6D /* chest.tga in Resources */,
DA12F30E0EF6E70100A40C6D /* characterSpriteSad.tga in Resources */,
DA12F30F0EF6E70100A40C6D /* characterSprite.tga in Resources */,
DA12F3E60EF6F00600A40C6D /* music.tga in Resources */,
DA8276E60EF9B2290061079D /* arrows.tga in Resources */,
DA8277840EF9FFE80061079D /* Icon.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
DA12F31C0EF6E79F00A40C6D /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
1D60588E0D05DD3D006BFB54 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1D60589B0D05DD56006BFB54 /* main.m in Sources */,
DA7F11810EF6D77000CB6D50 /* gameWindowAppDelegate.mm in Sources */,
DA12F3390EF6E89F00A40C6D /* World.cpp in Sources */,
DA12F33A0EF6E89F00A40C6D /* score.cpp in Sources */,
DA12F33B0EF6E89F00A40C6D /* map.cpp in Sources */,
DA12F33C0EF6E89F00A40C6D /* landscape.cpp in Sources */,
DA12F33D0EF6E89F00A40C6D /* Envelope.cpp in Sources */,
DA12F3420EF6E8BD00A40C6D /* blowUp.cpp in Sources */,
DA12F3430EF6E8BD00A40C6D /* common.cpp in Sources */,
DA12F3440EF6E8BD00A40C6D /* game.cpp in Sources */,
DA8C9E1C0EF8095C002FCA67 /* TimeUnix.cpp in Sources */,
DA8C9E1E0EF80968002FCA67 /* ThreadLinux.cpp in Sources */,
DA8C9E200EF80985002FCA67 /* PathLinux.cpp in Sources */,
DA8C9F090EF817F7002FCA67 /* StringBufferOutputStream.cpp in Sources */,
DA8C9F0A0EF817F7002FCA67 /* stringUtils.cpp in Sources */,
DA90DD060EFAB907001BABB5 /* musicPlayer.cpp in Sources */,
DA90DD140EFAC2AF001BABB5 /* Timbre.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
1D6058940D05DD3E006BFB54 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = gameWindowApp_Prefix.pch;
HEADER_SEARCH_PATHS = /Users/jasonrohrer/cpp;
INFOPLIST_FILE = Info.plist;
PRODUCT_NAME = Passage;
};
name = Debug;
};
1D6058950D05DD3E006BFB54 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = gameWindowApp_Prefix.pch;
HEADER_SEARCH_PATHS = /Users/jasonrohrer/cpp;
INFOPLIST_FILE = Info.plist;
PRODUCT_NAME = Passage;
};
name = Release;
};
C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
SDKROOT = iphoneos2.2;
};
name = Debug;
};
C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = iphoneos2.2;
};
name = Release;
};
DA9E30CB0EFC240700DFACC7 /* Distribution */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = iphoneos2.2;
};
name = Distribution;
};
DA9E30CC0EFC240700DFACC7 /* Distribution */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Jason Rohrer";
COPY_PHASE_STRIP = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = gameWindowApp_Prefix.pch;
HEADER_SEARCH_PATHS = /Users/jasonrohrer/cpp;
INFOPLIST_FILE = Info.plist;
PRODUCT_NAME = Passage;
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "0BE1AB5F-422D-4C27-A26D-B23A5A1F89C1";
};
name = Distribution;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Passage" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1D6058940D05DD3E006BFB54 /* Debug */,
1D6058950D05DD3E006BFB54 /* Release */,
DA9E30CC0EFC240700DFACC7 /* Distribution */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "gameWindowApp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C01FCF4F08A954540054247B /* Debug */,
C01FCF5008A954540054247B /* Release */,
DA9E30CB0EFC240700DFACC7 /* Distribution */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
}

View file

@ -0,0 +1,74 @@
//
// testWindowAppAppDelegate.h
// testWindowApp
//
// Created by Jason Rohrer on 12/14/08.
// Copyright __MyCompanyName__ 2008. All rights reserved.
//
#include "drawIntoScreen.h"
#import <UIKit/UIKit.h>
#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
@interface MyView : UIView {
@private
NSTimer *animationTimer;
/* The pixel dimensions of the backbuffer */
GLint backingWidth;
GLint backingHeight;
EAGLContext *context;
/* OpenGL names for the renderbuffer and framebuffers used to render to this view */
GLuint viewRenderbuffer, viewFramebuffer;
/* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
GLuint depthRenderbuffer;
GLuint textureID;
Uint32 *screenBitmap;
int bitmapW;
int bitmapH;
int bitmapBytes;
// for old DrawImage version
// CGDataProviderRef provider;
// CGColorSpaceRef colorSpaceRef;
// CGImageRef imageRef;
}
@property NSTimer *animationTimer;
@property (nonatomic, retain) EAGLContext *context;
- (void)startAnimation;
- (void)stopAnimation;
- (void)drawFrame;
- (BOOL) createFramebuffer;
- (void) destroyFramebuffer;
@end
@interface gameWindowAppDelegate : NSObject <UIAccelerometerDelegate> {
UIWindow *window;
MyView *view;
// used for low-pass filtering
UIAccelerationValue accelerationBuffer[3];
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet MyView *view;
@end

View file

@ -0,0 +1,434 @@
//
// testWindowAppAppDelegate.m
// testWindowApp
//
// Created by Jason Rohrer on 12/14/08.
// Copyright __MyCompanyName__ 2008. All rights reserved.
//
#import "gameWindowAppDelegate.h"
@implementation gameWindowAppDelegate
@synthesize window;
@synthesize view;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
printf( "App finished launching\n" );
printf( "Calling start anim\n" );
[view startAnimation];
printf( "Done starting animation\n" );
// Override point for customization after application launch
[window makeKeyAndVisible];
// Configure and start the accelerometer
// off for now
//[[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / 15)];
//[[UIAccelerometer sharedAccelerometer] setDelegate:self];
}
// UIAccelerometerDelegate method, called when the device accelerates.
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
//printf( "%d --- accel called w %f,%f\n", timeOfCall, acceleration.x, acceleration.y );
// low pass filter
float filterFactor = 0.5;
accelerationBuffer[0] = acceleration.x * filterFactor + (1-filterFactor) * accelerationBuffer[0];
accelerationBuffer[1] = acceleration.y * filterFactor + (1-filterFactor) * accelerationBuffer[1];
accelerationBuffer[2] = acceleration.z * filterFactor + (1-filterFactor) * accelerationBuffer[2];
setOrientation( asin( accelerationBuffer[0] ), asin( accelerationBuffer[1] ) );
}
- (void)dealloc {
[window release];
[view stopAnimation];
[view release];
[super dealloc];
}
@end
#include "drawIntoScreen.h"
#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/EAGLDrawable.h>
@implementation MyView
@synthesize animationTimer;
@synthesize context;
// You must implement this method
+ (Class)layerClass {
return [CAEAGLLayer class];
}
//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
- (id)initWithCoder:(NSCoder*)coder {
if ((self = [super initWithCoder:coder])) {
// Get the layer
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
eaglLayer.opaque = YES;
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
if (!context || ![EAGLContext setCurrentContext:context]) {
[self release];
return nil;
}
}
return self;
}
NSTimeInterval countStartTime;
int appFrameCount = 0;
- (void)layoutSubviews {
[EAGLContext setCurrentContext:context];
[self destroyFramebuffer];
[self createFramebuffer];
NSDate *then = [NSDate date];
countStartTime = [then timeIntervalSinceReferenceDate];
[self drawFrame];
}
- (BOOL)createFramebuffer {
glGenFramebuffersOES(1, &viewFramebuffer);
glGenRenderbuffersOES(1, &viewRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
return NO;
}
glGenTextures( 1, &textureID );
return YES;
}
- (void)destroyFramebuffer {
glDeleteFramebuffersOES(1, &viewFramebuffer);
viewFramebuffer = 0;
glDeleteRenderbuffersOES(1, &viewRenderbuffer);
viewRenderbuffer = 0;
if(depthRenderbuffer) {
glDeleteRenderbuffersOES(1, &depthRenderbuffer);
depthRenderbuffer = 0;
}
glDeleteTextures( 1, &textureID );
}
- (void)setAnimationTimer:(NSTimer *)newTimer {
[animationTimer invalidate];
animationTimer = newTimer;
}
- (void)startAnimation {
NSTimeInterval animationInterval = 1 / 15.0;
self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawFrame) userInfo:nil repeats:YES];
bitmapW = 128;
bitmapH = 128;
int screenPixels = bitmapW * bitmapH;
bitmapBytes = screenPixels* 4;
screenBitmap = (Uint32 *) malloc( bitmapBytes );
/*
// for old DrawImage version
provider = CGDataProviderCreateWithData( NULL, screenBitmap, screenPixels * 4, NULL );
colorSpaceRef = CGColorSpaceCreateDeviceRGB();
imageRef = CGImageCreate(
bitmapW,
bitmapH,
8,
32,
4 * bitmapW,
colorSpaceRef,
kCGImageAlphaNoneSkipLast,
provider,
NULL,
NO,
kCGRenderingIntentDefault );
*/
initScreenDrawer( screenBitmap, bitmapW, bitmapH );
}
- (void)stopAnimation {
printf( "Stop anim called\n" );
self.animationTimer = nil;
free( screenBitmap );
freeScreenDrawer();
}
- (void)drawFrame {
// old DrawImage version
//[self setNeedsDisplay];
const GLfloat squareVertices[] = {
-1.6f, -1.6f,
1.6f, -1.6f,
-1.6f, 1.6f,
1.6f, 1.6f,
};
/*
const GLubyte squareColors[] = {
255, 255, 0, 255,
0, 255, 255, 255,
255, 0, 0, 0,
255, 0, 255, 255,
};
*/
const GLfloat squareTextureCoords[] = {
0, 0,
1, 0,
0, 1,
1, 1
};
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glViewport(0, 0, backingWidth, backingHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
//glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
//glClear(GL_COLOR_BUFFER_BIT);
glVertexPointer(2, GL_FLOAT, 0, squareVertices);
glEnableClientState(GL_VERTEX_ARRAY);
//glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors);
//glEnableClientState(GL_COLOR_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, squareTextureCoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// set new texture data
drawIntoScreen( screenBitmap, bitmapW, bitmapH );
int error;
GLenum texFormat = GL_RGBA;
glBindTexture( GL_TEXTURE_2D, textureID );
error = glGetError();
if( error != GL_NO_ERROR ) { // error
printf( "Error binding to texture id %d, error = %d\n",
(int)textureID,
error );
}
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
glTexImage2D( GL_TEXTURE_2D, 0,
texFormat, bitmapW,
bitmapH, 0,
texFormat, GL_UNSIGNED_BYTE, screenBitmap );
error = glGetError();
if( error != GL_NO_ERROR ) { // error
printf( "Error setting texture data for id %d, error = %d\n",
(int)textureID, error );
printf( "Perhaps texture image width or height is not a power of 2\n"
"Width = %lu, Height = %lu\n",
bitmapW, bitmapH );
}
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, textureID );
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
appFrameCount++;
// disable FPS tracking
if( false && appFrameCount > 100 ) {
NSDate *now = [NSDate date];
NSTimeInterval newStartTime = [now timeIntervalSinceReferenceDate];
NSTimeInterval elapsedTime = newStartTime - countStartTime;
printf( "FPS: %f\n", appFrameCount / elapsedTime );
countStartTime = newStartTime;
appFrameCount = 0;
}
}
/*
// old DrawImage version
#include <time.h>
unsigned int appFrameCountStartTime = time( NULL );
int appFrameCount = 0;
- (void)drawRect:(CGRect)rect {
//printf( "Draw Rect called!\n" );
drawIntoScreen( screenBitmap, bitmapW, bitmapH );
CGContextRef context = UIGraphicsGetCurrentContext();
//CGContextRotateCTM ( context, M_PI / 2 );
//CGContextTranslateCTM ( context, 0, -bitmapH );
CGRect imageRect = CGRectMake ( 0, 0, bitmapW, bitmapH );
CGContextDrawImage(context, imageRect, imageRef );
appFrameCount++;
if( appFrameCount > 100 ) {
unsigned int newTime = time( NULL );
unsigned int timeDelta = newTime - appFrameCountStartTime;
printf( "FPS = %f\n", (double)appFrameCount / (double)timeDelta );
appFrameCount = 0;
appFrameCountStartTime = newTime;
}
}
*/
// Handles the start of a touch
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGRect bounds = [self bounds];
UITouch* touch = [[event touchesForView:self] anyObject];
//Convert touch point from UIView referential to OpenGL one (upside-down flip)
CGPoint location = [touch locationInView:self];
location.y = bounds.size.height - location.y;
touchStartPoint( location.x, location.y );
}
// Handles touch motion
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
CGRect bounds = [self bounds];
UITouch* touch = [[event touchesForView:self] anyObject];
//Convert touch point from UIView referential to OpenGL one (upside-down flip)
CGPoint location = [touch locationInView:self];
location.y = bounds.size.height - location.y;
touchMovePoint( location.x, location.y );
}
// Handles touch end
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
CGRect bounds = [self bounds];
UITouch* touch = [[event touchesForView:self] anyObject];
//Convert touch point from UIView referential to OpenGL one (upside-down flip)
CGPoint location = [touch locationInView:self];
location.y = bounds.size.height - location.y;
touchEndPoint( location.x, location.y );
}
@end

View file

@ -0,0 +1,8 @@
//
// Prefix header for all source files of the 'testWindowApp' target in the 'testWindowApp' project
//
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#endif

View file

@ -0,0 +1,41 @@
//
// main.m
// testWindowApp
//
// Created by Jason Rohrer on 12/14/08.
// Copyright __MyCompanyName__ 2008. All rights reserved.
//
#import <UIKit/UIKit.h>
int main(int argc, char *argv[]) {
//printf( "Arg 0 = %s\n", argv[0] );
// arg 0 is the path to the app executable
char *appDirectoryPath = strdup( argv[ 0 ] );
//printf( "Mac: app path %s\n", appDirectoryPath );
char *bundleName = "Passage.app";
char *appNamePointer = strstr( appDirectoryPath, bundleName );
if( appNamePointer != NULL ) {
// terminate full app path to get bundle directory
appNamePointer[ strlen( bundleName ) ] = '\0';
printf( "Mac: changing working dir to %s\n", appDirectoryPath );
chdir( appDirectoryPath );
}
free( appDirectoryPath );
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}

View file

@ -0,0 +1,799 @@
#include "common.h"
#include "Timbre.h"
#include "Envelope.h"
#include "minorGems/util/SimpleVector.h"
//#include <CoreServices.h>
#include <AudioUnit/AudioUnit.h>
#include <AudioUnit/AUComponent.h>
#include <math.h>
#include <stdlib.h>
#include <stdint.h>
typedef int16_t Sint16;
typedef uint8_t Uint8;
int sampleRate = 22050;
//int sampleRate = 11025;
Image *musicImage = NULL;
int w, h;
// total number of samples played so far
int streamSamples = 0;
// offset into grid at start
// for testing
int gridStartOffset = 0;
// overal loudness of music
double musicLoudness = 1.0;
// one grid step in seconds
double gridStepDuration = 0.25;
int gridStepDurationInSamples = (int)( gridStepDuration * sampleRate );
double entireGridDuraton;
// c
double keyFrequency = 261.63;
int numTimbres = 4;
Timbre *musicTimbres[ 4 ];
int numEnvelopes = 4;
Envelope *musicEnvelopes[ 4 ];
class Note {
public:
// index into musicTimbres array
int mTimbreNumber;
// index into musicEnvelopes array
int mEnvelopeNumber;
int mScaleNoteNumber;
// additional loudness adjustment
// places note in stereo space
double mLoudnessLeft;
double mLoudnessRight;
// start time, in seconds from start of note grid
double mStartTime;
// duration in seconds
double mDuration;
// used when note is currently playing to track progress in note
// negative if we should wait before starting to play the note
int mCurrentSampleNumber;
// duration in samples
int mNumSamples;
};
// isomorphic to our music image, except only has an entry for each note
// start (all others, including grid spots that contain note continuations,
// are NULL)
// indexed as noteGrid[y][x]
Note ***noteGrid;
SimpleVector<Note*> currentlyPlayingNotes;
// need to synch these with audio thread
void setMusicLoudness( double inLoudness ) {
//SDL_LockAudio();
musicLoudness = inLoudness;
//SDL_UnlockAudio();
}
void restartMusic() {
//SDL_LockAudio();
// return to beginning (and forget samples we've played so far)
streamSamples = 0;
// drop all currently-playing notes
currentlyPlayingNotes.deleteAll();
//SDL_UnlockAudio();
}
// called by SDL to get more samples
void audioCallback( void *inUserData, Uint8 *inStream, int inLengthToFill ) {
// 2 bytes for each channel of stereo sample
int numSamples = inLengthToFill / 4;
Sint16 *samplesL = new Sint16[ numSamples ];
Sint16 *samplesR = new Sint16[ numSamples ];
// first, zero-out the buffer to prepare it for our sum of note samples
// each sample is 2 bytes
memset( samplesL, 0, 2 * numSamples );
memset( samplesR, 0, 2 * numSamples );
int i;
// hop through all grid steps that *start* in this stream buffer
// add notes that start during this stream buffer
// how far into stream buffer before we hit our first grid step?
int startOfFirstGridStep = streamSamples % gridStepDurationInSamples;
if( startOfFirstGridStep != 0 ) {
startOfFirstGridStep =
gridStepDurationInSamples - startOfFirstGridStep;
}
// hop from start of grid step to start of next grid step
// ignore samples in between, since notes don't start there,
// and all we're doing right now is finding notes that start
for( i=startOfFirstGridStep;
i<numSamples;
i += gridStepDurationInSamples ) {
// start of new grid position
// check for new notes that are starting
// map into our music image:
int x = ( streamSamples + i ) / gridStepDurationInSamples;
// wrap in image
x = x % w;
for( int y=0; y<h; y++ ) {
Note *note = noteGrid[y][x];
if( note != NULL ) {
// new note
currentlyPlayingNotes.push_back( note );
// start it
// set a delay for its start based on our position
// in this callback buffer
note->mCurrentSampleNumber = -i;
}
}
}
streamSamples += numSamples;
// loop over all current notes and add their samples to buffer
for( int n=0; n<currentlyPlayingNotes.size(); n++ ) {
Note *note = *( currentlyPlayingNotes.getElement( n ) );
int waveTableNumber = note->mScaleNoteNumber;
Timbre *timbre = musicTimbres[ note->mTimbreNumber ];
int tableLength = timbre->mWaveTableLengths[ waveTableNumber ];
Sint16 *waveTable = timbre->mWaveTable[ waveTableNumber ];
Envelope *env = musicEnvelopes[ note->mEnvelopeNumber ];
double *envLevels =
env->getEnvelope(
// index envelope by number of grid steps in note
note->mNumSamples / gridStepDurationInSamples );
double noteLoudnessL = note->mLoudnessLeft;
double noteLoudnessR = note->mLoudnessRight;
// do this outside inner loop
noteLoudnessL *= musicLoudness;
noteLoudnessR *= musicLoudness;
int noteStartInBuffer = 0;
int noteEndInBuffer = numSamples;
if( note->mCurrentSampleNumber < 0 ) {
// delay before note starts in this sample buffer
noteStartInBuffer = - note->mCurrentSampleNumber;
// we've taken account of the delay
note->mCurrentSampleNumber = 0;
}
char endNote = false;
int numSamplesLeftInNote =
note->mNumSamples - note->mCurrentSampleNumber;
if( noteStartInBuffer + numSamplesLeftInNote < noteEndInBuffer ) {
// note ends before end of buffer
noteEndInBuffer = noteStartInBuffer + numSamplesLeftInNote;
endNote = true;
}
int waveTablePos = note->mCurrentSampleNumber % tableLength;
int currentSampleNumber = note->mCurrentSampleNumber;
for( i=noteStartInBuffer; i != noteEndInBuffer; i++ ) {
double envelope = envLevels[ currentSampleNumber ];
double monoSample = envelope *
waveTable[ waveTablePos ];
samplesL[i] += (Sint16)( noteLoudnessL * monoSample );
samplesR[i] += (Sint16)( noteLoudnessR * monoSample );
currentSampleNumber ++;
waveTablePos ++;
// avoid using mod operator (%) in inner loop
// found with profiler
if( waveTablePos == tableLength ) {
// back to start of table
waveTablePos = 0;
}
}
note->mCurrentSampleNumber += ( noteEndInBuffer - noteStartInBuffer );
if( endNote ) {
// note ended in this buffer
currentlyPlayingNotes.deleteElement( n );
n--;
}
}
// now copy samples into Uint8 buffer
int streamPosition = 0;
for( i=0; i != numSamples; i++ ) {
Sint16 intSampleL = samplesL[i];
Sint16 intSampleR = samplesR[i];
inStream[ streamPosition ] = (Uint8)( intSampleL & 0xFF );
inStream[ streamPosition + 1 ] = (Uint8)( ( intSampleL >> 8 ) & 0xFF );
inStream[ streamPosition + 2 ] = (Uint8)( intSampleR & 0xFF );
inStream[ streamPosition + 3 ] = (Uint8)( ( intSampleR >> 8 ) & 0xFF );
streamPosition += 4;
}
delete [] samplesL;
delete [] samplesR;
}
// limit on n, based on Nyquist, when summing sine components
//int nLimit = (int)( sampleRate * M_PI );
// actually, this is way too many: it takes forever to compute
// use a lower limit instead
// This produces fine results (almost perfect square wave)
int nLimit = 40;
// square wave with period of 2pi
double squareWave( double inT ) {
double sum = 0;
for( int n=1; n<nLimit; n+=2 ) {
sum += 1.0/n * sin( n * inT );
}
return sum;
}
// sawtoot wave with period of 2pi
double sawWave( double inT ) {
double sum = 0;
for( int n=1; n<nLimit; n++ ) {
sum += 1.0/n * sin( n * inT );
}
return sum;
}
// white noise, ignores inT
double whiteNoise( double inT ) {
return 2.0 * ( rand() / (double)RAND_MAX ) - 1.0;
}
// white noise where each sample is averaged with last sample
// effectively a low-pass filter
double lastSample = 0;
double smoothedWhiteNoise( double inT ) {
// give double-weight to last sample to make it even smoother
lastSample = ( 2 * lastSample + whiteNoise( inT ) ) / 3;
return lastSample;
}
void loadMusicImage( char *inTGAFileName ) {
musicImage = readTGA( "music", inTGAFileName );
w = musicImage->getWidth();
h = musicImage->getHeight();
// notes are in red and green channel
double *redChannel = musicImage->getChannel( 0 );
double *greenChannel = musicImage->getChannel( 1 );
entireGridDuraton = gridStepDuration * w;
// jump ahead in stream, if needed
streamSamples += gridStartOffset * gridStepDurationInSamples;
// blank line of pixels between timbres
int heightPerTimbre = (h+1) / numTimbres - 1;
// find the maximum number of simultaneous notes in the song
// take loudness into account
double maxNoteLoudnessInAColumn = 0;
int x, y;
for( x=0; x<w; x++ ) {
double noteLoudnessInColumnL = 0;
double noteLoudnessInColumnR = 0;
for( y=0; y<h; y++ ) {
int imageIndex = y * w + x;
// the note number in our scale
// scale starts over for each timbre, with blank line
// in between timbres
int noteNumber = (h - y - 1) % (heightPerTimbre + 1);
if( // not blank line between timbres
noteNumber < heightPerTimbre &&
// tone present in image
( redChannel[ imageIndex ] > 0 ||
greenChannel[ imageIndex ] > 0 ) ) {
noteLoudnessInColumnL += greenChannel[ imageIndex ];
noteLoudnessInColumnR += redChannel[ imageIndex ];
}
}
// pick loudest channel for this column and compare it to
// loudest column/channel seen so far
if( maxNoteLoudnessInAColumn < noteLoudnessInColumnL ) {
maxNoteLoudnessInAColumn = noteLoudnessInColumnL;
}
if( maxNoteLoudnessInAColumn < noteLoudnessInColumnR ) {
maxNoteLoudnessInAColumn = noteLoudnessInColumnR;
}
}
// divide loudness amoung timbres to avoid clipping
double loudnessPerTimbre = 1.0 / maxNoteLoudnessInAColumn;
// further adjust loudness per channel here as we construct
// each timbre.
// This is easier than tweaking loundness of a given part by hand
// using a painting program
musicTimbres[0] = new Timbre( sampleRate, 0.6 * loudnessPerTimbre,
keyFrequency,
heightPerTimbre, sawWave );
musicTimbres[1] = new Timbre( sampleRate, loudnessPerTimbre,
keyFrequency,
heightPerTimbre, sin );
musicTimbres[2] = new Timbre( sampleRate, 0.4 * loudnessPerTimbre,
keyFrequency / 4,
heightPerTimbre, squareWave );
musicTimbres[3] = new Timbre( sampleRate, 0.75 * loudnessPerTimbre,
keyFrequency / 4,
heightPerTimbre, smoothedWhiteNoise );
// next, compute the longest note in the song
int maxNoteLength = 0;
for( y=0; y<h; y++ ) {
int currentNoteLength = 0;
for( x=0; x<w; x++ ) {
int imageIndex = y * w + x;
// the note number in our scale
// scale starts over for each timbre, with blank line
// in between timbres
int noteNumber = (h - y - 1) % (heightPerTimbre + 1);
if( // not blank line between timbres
noteNumber < heightPerTimbre &&
// tone present in image
( redChannel[ imageIndex ] > 0 ||
greenChannel[ imageIndex ] > 0 ) ) {
currentNoteLength ++;
}
else {
currentNoteLength = 0;
}
if( currentNoteLength > maxNoteLength ) {
maxNoteLength = currentNoteLength;
}
}
}
printf( "Max note length in song = %d\n", maxNoteLength );
musicEnvelopes[0] = new Envelope( 0.05, 0.7, 0.25, 0.1,
maxNoteLength,
gridStepDurationInSamples );
musicEnvelopes[1] = new Envelope( 0.1, 0.9, 0.0, 0.0,
maxNoteLength,
gridStepDurationInSamples );
musicEnvelopes[2] = new Envelope( 0.25, 0.0, 1.0, 0.1,
maxNoteLength,
gridStepDurationInSamples );
musicEnvelopes[3] = new Envelope( 0.0, 0.2, 0.0, 0.0,
maxNoteLength,
gridStepDurationInSamples );
noteGrid = new Note**[ h ];
for( int y=0; y<h; y++ ) {
noteGrid[y] = new Note*[ w ];
// each row is one pitch for a given instrument
// thus, two consecutive pixels should be the same note
// handle this by tracking whether a note is playing or not
char notePlaying = false;
Note *noteStart = NULL;
for( int x=0; x<w; x++ ) {
int imageIndex = y * w + x;
// default to NULL
noteGrid[y][x] = NULL;
// the note number in our scale
// scale starts over for each timbre, with blank line
// in between timbres
int noteNumber = (h - y - 1) % (heightPerTimbre + 1);
if( // not blank line between timbres
noteNumber < heightPerTimbre &&
// tone present in image
( redChannel[ imageIndex ] > 0 ||
greenChannel[ imageIndex ] > 0 ) ) {
if( notePlaying ) {
// part of note that's already playing
// one more grid step
noteStart->mDuration += gridStepDuration;
noteStart->mNumSamples += gridStepDurationInSamples;
}
else {
// start a new note
noteGrid[y][x] = new Note();
noteGrid[y][x]->mScaleNoteNumber = noteNumber;
noteGrid[y][x]->mTimbreNumber =
y / ( heightPerTimbre + 1 );
// same as timbre number
noteGrid[y][x]->mEnvelopeNumber =
noteGrid[y][x]->mTimbreNumber;
// left loudness from green brightness
noteGrid[y][x]->mLoudnessLeft = greenChannel[ imageIndex ];
// right loudness from red brightness
noteGrid[y][x]->mLoudnessRight = redChannel[ imageIndex ];
noteGrid[y][x]->mStartTime = gridStepDuration * x;
// one grid step so far
noteGrid[y][x]->mDuration = gridStepDuration;
noteGrid[y][x]->mNumSamples = gridStepDurationInSamples;
// track if it needs to be continued
notePlaying = true;
noteStart = noteGrid[y][x];
}
}
else {
// no tone
if( notePlaying ) {
// stop it
notePlaying = false;
noteStart = NULL;
}
}
}
}
}
AudioUnit gOutputUnit;
OSStatus MyRenderer(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
audioCallback( NULL, (Uint8 *)( ioData->mBuffers[0].mData ), ioData->mBuffers[0].mDataByteSize );
/*
RenderSin (sSinWaveFrameCount,
inNumberFrames,
ioData->mBuffers[0].mData,
sSampleRate,
sAmplitude,
sToneFrequency,
sWhichFormat);
//we're just going to copy the data into each channel
for (UInt32 channel = 1; channel < ioData->mNumberBuffers; channel++)
memcpy (ioData->mBuffers[channel].mData, ioData->mBuffers[0].mData, ioData->mBuffers[0].mDataByteSize);
sSinWaveFrameCount += inNumberFrames;
*/
return noErr;
}
// ________________________________________________________________________________
//
// CreateDefaultAU
//
void CreateDefaultAU()
{
OSStatus err = noErr;
// Open the default output unit
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_RemoteIO;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
AudioComponent comp = AudioComponentFindNext(NULL, &desc);
if (comp == NULL) { printf ("FindNextComponent\n"); return; }
err = AudioComponentInstanceNew(comp, &gOutputUnit);
if (comp == NULL) { printf ("OpenAComponent=%ld\n", (long int)err); return; }
// Set up a callback function to generate output to the output unit
AURenderCallbackStruct input;
input.inputProc = MyRenderer;
input.inputProcRefCon = NULL;
err = AudioUnitSetProperty (gOutputUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input,
0,
&input,
sizeof(input));
if (err) { printf ("AudioUnitSetProperty-CB=%ld\n", (long int)err); return; }
}
// ________________________________________________________________________________
//
// TestDefaultAU
//
void TestDefaultAU()
{
OSStatus err = noErr;
// We tell the Output Unit what format we're going to supply data to it
// this is necessary if you're providing data through an input callback
// AND you want the DefaultOutputUnit to do any format conversions
// necessary from your format to the device's format.
AudioStreamBasicDescription streamFormat;
streamFormat.mSampleRate = sampleRate;
streamFormat.mFormatID = kAudioFormatLinearPCM;
streamFormat.mFormatFlags =
kLinearPCMFormatFlagIsSignedInteger
| kAudioFormatFlagsNativeEndian
| kLinearPCMFormatFlagIsPacked;
//| kAudioFormatFlagIsNonInterleaved;
streamFormat.mBytesPerPacket = 4;
streamFormat.mFramesPerPacket = 1;
streamFormat.mBytesPerFrame = 4;
streamFormat.mChannelsPerFrame = 2;
streamFormat.mBitsPerChannel = 16;
printf("Rendering source:\n\t");
printf ("SampleRate=%f,", streamFormat.mSampleRate);
printf ("BytesPerPacket=%ld,", (long int)streamFormat.mBytesPerPacket);
printf ("FramesPerPacket=%ld,", (long int)streamFormat.mFramesPerPacket);
printf ("BytesPerFrame=%ld,", (long int)streamFormat.mBytesPerFrame);
printf ("BitsPerChannel=%ld,", (long int)streamFormat.mBitsPerChannel);
printf ("ChannelsPerFrame=%ld\n", (long int)streamFormat.mChannelsPerFrame);
err = AudioUnitSetProperty ( gOutputUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&streamFormat,
sizeof(AudioStreamBasicDescription) );
if (err) { printf ("AudioUnitSetProperty-SF=%4.4s, %ld\n", (char*)&err, (long int)err); return; }
// Initialize unit
err = AudioUnitInitialize(gOutputUnit);
if (err) { printf ("AudioUnitInitialize=%ld\n", (long int)err); return; }
Float64 outSampleRate;
UInt32 size = sizeof(Float64);
err = AudioUnitGetProperty (gOutputUnit,
kAudioUnitProperty_SampleRate,
kAudioUnitScope_Output,
0,
&outSampleRate,
&size);
if (err) { printf ("AudioUnitSetProperty-GF=%4.4s, %ld\n", (char*)&err, (long int)err); return; }
// Start the rendering
// The DefaultOutputUnit will do any format conversions to the format of the default device
err = AudioOutputUnitStart (gOutputUnit);
if (err) { printf ("AudioOutputUnitStart=%ld\n", (long int)err); return; }
// we call the CFRunLoopRunInMode to service any notifications that the audio
// system has to deal with
//CFRunLoopRunInMode(kCFRunLoopDefaultMode, 2, false);
}
void CloseDefaultAU ()
{
// Clean up
OSStatus err = noErr;
err = AudioOutputUnitStop( gOutputUnit );
if (err) { printf ("AudioOutputUnitStop=%ld\n", (long int)err); return; }
err = AudioUnitUninitialize (gOutputUnit);
if (err) { printf ("AudioUnitUninitialize=%ld\n", (long int)err); return; }
AudioComponentInstanceDispose( gOutputUnit );
//CloseComponent(gOutputUnit);
}
void startMusic( char *inTGAFileName ) {
loadMusicImage( inTGAFileName );
CreateDefaultAU();
TestDefaultAU();
}
void stopMusic() {
CloseDefaultAU();
if( musicImage != NULL ) {
delete musicImage;
musicImage = NULL;
}
for( int y=0; y<h; y++ ) {
for( int x=0; x<w; x++ ) {
if( noteGrid[y][x] != NULL ) {
delete noteGrid[y][x];
}
}
delete [] noteGrid[y];
}
delete [] noteGrid;
int i;
for( i=0; i<numTimbres; i++ ) {
delete musicTimbres[i];
}
for( i=0; i<numEnvelopes; i++ ) {
delete musicEnvelopes[i];
}
}

View file

@ -0,0 +1,3 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 1 1 .7 12/23/2008 12/23/2008 CAD CA CAD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 3 .7 12/23/2008 12/23/2008 USD US USD 300702040 .99

View file

@ -0,0 +1,14 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 1 8 .36 12/24/2008 12/24/2008 GBP GB GBP 300702040 .59
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/24/2008 12/24/2008 EUR BE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 81 12/24/2008 12/24/2008 JPY JP JPY 300702040 115
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/24/2008 12/24/2008 EUR DE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/24/2008 12/24/2008 SEK SE EUR 300702040 7
APPLE US 1001 Jason Rohrer Passage 1 162 .7 12/24/2008 12/24/2008 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/24/2008 12/24/2008 EUR FI EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/24/2008 12/24/2008 EUR ES EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/24/2008 12/24/2008 EUR FR EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/24/2008 12/24/2008 EUR NL EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 0 12/24/2008 12/24/2008 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/24/2008 12/24/2008 EUR IE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 11 .7 12/24/2008 12/24/2008 CAD CA CAD 300702040 .99

View file

@ -0,0 +1,16 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 1 99 .7 12/25/2008 12/25/2008 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 3 .48 12/25/2008 12/25/2008 EUR FR EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 5 .48 12/25/2008 12/25/2008 EUR DE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/25/2008 12/25/2008 EUR PT EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/25/2008 12/25/2008 EUR IE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 4 .48 12/25/2008 12/25/2008 EUR NL EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/25/2008 12/25/2008 EUR ES EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 5 .48 12/25/2008 12/25/2008 SEK SE EUR 300702040 7
APPLE US 1001 Jason Rohrer Passage 1 4 .48 12/25/2008 12/25/2008 DKK DK EUR 300702040 6
APPLE US 1001 Jason Rohrer Passage 1 1 .76 12/25/2008 12/25/2008 NZD NZ AUD 300702040 1.29
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/25/2008 12/25/2008 EUR BE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 6 .7 12/25/2008 12/25/2008 CAD CA CAD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 8 .76 12/25/2008 12/25/2008 AUD AU AUD 300702040 1.19
APPLE US 1001 Jason Rohrer Passage 1 32 .36 12/25/2008 12/25/2008 GBP GB GBP 300702040 .59
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/25/2008 12/25/2008 EUR IT EUR 300702040 .79

View file

@ -0,0 +1,20 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 1 -1 .7 12/26/2008 12/26/2008 USD US USD 300702040 -.99
APPLE US 1001 Jason Rohrer Passage 1 2 .7 12/26/2008 12/26/2008 USD SG USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 1 .7 12/26/2008 12/26/2008 USD AR USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/26/2008 12/26/2008 EUR FR EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/26/2008 12/26/2008 EUR AT EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 3 .48 12/26/2008 12/26/2008 DKK DK EUR 300702040 6
APPLE US 1001 Jason Rohrer Passage 1 31 .36 12/26/2008 12/26/2008 GBP GB GBP 300702040 .59
APPLE US 1001 Jason Rohrer Passage 1 25 .7 12/26/2008 12/26/2008 CAD CA CAD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/26/2008 12/26/2008 NOK NO EUR 300702040 6
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/26/2008 12/26/2008 EUR NL EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 254 .7 12/26/2008 12/26/2008 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 9 .48 12/26/2008 12/26/2008 EUR DE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 6 .76 12/26/2008 12/26/2008 AUD AU AUD 300702040 1.19
APPLE US 1001 Jason Rohrer Passage 1 1 81 12/26/2008 12/26/2008 JPY JP JPY 300702040 115
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/26/2008 12/26/2008 EUR PL EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/26/2008 12/26/2008 EUR BE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/26/2008 12/26/2008 EUR IT EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 5 .48 12/26/2008 12/26/2008 SEK SE EUR 300702040 7
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/26/2008 12/26/2008 CHF CH EUR 300702040 1.1

View file

@ -0,0 +1,24 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/27/2008 12/27/2008 EUR GR EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/27/2008 12/27/2008 EUR NL EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 7 .48 12/27/2008 12/27/2008 SEK SE EUR 300702040 7
APPLE US 1001 Jason Rohrer Passage 1 5 .48 12/27/2008 12/27/2008 EUR FR EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 43 .36 12/27/2008 12/27/2008 GBP GB GBP 300702040 .59
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/27/2008 12/27/2008 EUR BE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/27/2008 12/27/2008 CHF CH EUR 300702040 1.1
APPLE US 1001 Jason Rohrer Passage 1 1 .7 12/27/2008 12/27/2008 MXN MX USD 300702040 10
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/27/2008 12/27/2008 EUR PL EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 141 .7 12/27/2008 12/27/2008 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 14 .48 12/27/2008 12/27/2008 EUR DE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .7 12/27/2008 12/27/2008 USD SG USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/27/2008 12/27/2008 EUR ES EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .7 12/27/2008 12/27/2008 USD PH USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 3 .76 12/27/2008 12/27/2008 NZD NZ AUD 300702040 1.29
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/27/2008 12/27/2008 EUR CZ EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/27/2008 12/27/2008 EUR AT EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/27/2008 12/27/2008 EUR IE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 3 .7 12/27/2008 12/27/2008 CAD CA CAD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/27/2008 12/27/2008 DKK DK EUR 300702040 6
APPLE US 1001 Jason Rohrer Passage 1 15 .76 12/27/2008 12/27/2008 AUD AU AUD 300702040 1.19
APPLE US 1001 Jason Rohrer Passage 1 3 81 12/27/2008 12/27/2008 JPY JP JPY 300702040 115
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/27/2008 12/27/2008 EUR FI EUR 300702040 .79

View file

@ -0,0 +1,18 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 1 14 .36 12/28/2008 12/28/2008 GBP GB GBP 300702040 .59
APPLE US 1001 Jason Rohrer Passage 1 7 .7 12/28/2008 12/28/2008 CAD CA CAD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 79 .7 12/28/2008 12/28/2008 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/28/2008 12/28/2008 EUR FI EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/28/2008 12/28/2008 EUR ES EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/28/2008 12/28/2008 CHF CH EUR 300702040 1.1
APPLE US 1001 Jason Rohrer Passage 1 5 .76 12/28/2008 12/28/2008 AUD AU AUD 300702040 1.19
APPLE US 1001 Jason Rohrer Passage 1 1 .76 12/28/2008 12/28/2008 NZD NZ AUD 300702040 1.29
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/28/2008 12/28/2008 EUR IE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 81 12/28/2008 12/28/2008 JPY JP JPY 300702040 115
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/28/2008 12/28/2008 EUR PL EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/28/2008 12/28/2008 EUR FR EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/28/2008 12/28/2008 EUR IT EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 3 .48 12/28/2008 12/28/2008 SEK SE EUR 300702040 7
APPLE US 1001 Jason Rohrer Passage 1 8 .48 12/28/2008 12/28/2008 EUR DE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .7 12/28/2008 12/28/2008 USD SG USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 3 .48 12/28/2008 12/28/2008 EUR NL EUR 300702040 .79

View file

@ -0,0 +1,14 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/29/2008 12/29/2008 EUR AT EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 6 .48 12/29/2008 12/29/2008 EUR DE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 3 .48 12/29/2008 12/29/2008 EUR FR EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 5 .7 12/29/2008 12/29/2008 CAD CA CAD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/29/2008 12/29/2008 CHF CH EUR 300702040 1.1
APPLE US 1001 Jason Rohrer Passage 1 90 .7 12/29/2008 12/29/2008 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 13 .36 12/29/2008 12/29/2008 GBP GB GBP 300702040 .59
APPLE US 1001 Jason Rohrer Passage 1 1 .7 12/29/2008 12/29/2008 USD SG USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 7 .48 12/29/2008 12/29/2008 EUR NL EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 7 .76 12/29/2008 12/29/2008 AUD AU AUD 300702040 1.19
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/29/2008 12/29/2008 EUR HU EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/29/2008 12/29/2008 EUR FI EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/29/2008 12/29/2008 SEK SE EUR 300702040 7

View file

@ -0,0 +1,15 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/30/2008 12/30/2008 NOK NO EUR 300702040 6
APPLE US 1001 Jason Rohrer Passage 1 3 .76 12/30/2008 12/30/2008 NZD NZ AUD 300702040 1.29
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/30/2008 12/30/2008 EUR FI EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .7 12/30/2008 12/30/2008 USD IN USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/30/2008 12/30/2008 EUR FR EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 3 .48 12/30/2008 12/30/2008 EUR NL EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/30/2008 12/30/2008 EUR IT EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 2 .48 12/30/2008 12/30/2008 EUR DE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 54 .7 12/30/2008 12/30/2008 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 12 .36 12/30/2008 12/30/2008 GBP GB GBP 300702040 .59
APPLE US 1001 Jason Rohrer Passage 1 3 .48 12/30/2008 12/30/2008 SEK SE EUR 300702040 7
APPLE US 1001 Jason Rohrer Passage 1 4 .76 12/30/2008 12/30/2008 AUD AU AUD 300702040 1.19
APPLE US 1001 Jason Rohrer Passage 1 6 .7 12/30/2008 12/30/2008 CAD CA CAD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 2 .7 12/30/2008 12/30/2008 USD SG USD 300702040 .99

View file

@ -0,0 +1,9 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 1 4 .7 12/31/2008 12/31/2008 CAD CA CAD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/31/2008 12/31/2008 EUR DE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/31/2008 12/31/2008 EUR FI EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 81 12/31/2008 12/31/2008 JPY JP JPY 300702040 115
APPLE US 1001 Jason Rohrer Passage 1 32 .7 12/31/2008 12/31/2008 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/31/2008 12/31/2008 EUR IE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 12/31/2008 12/31/2008 SEK SE EUR 300702040 7
APPLE US 1001 Jason Rohrer Passage 1 10 .36 12/31/2008 12/31/2008 GBP GB GBP 300702040 .59

View file

@ -0,0 +1,11 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 1 3 .76 01/01/2009 01/01/2009 AUD AU AUD 300702040 1.19
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/01/2009 01/01/2009 EUR LU EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 81 01/01/2009 01/01/2009 JPY JP JPY 300702040 115
APPLE US 1001 Jason Rohrer Passage 1 1 .7 01/01/2009 01/01/2009 CAD CA CAD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 1 .76 01/01/2009 01/01/2009 NZD NZ AUD 300702040 1.29
APPLE US 1001 Jason Rohrer Passage 1 33 .7 01/01/2009 01/01/2009 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 6 .36 01/01/2009 01/01/2009 GBP GB GBP 300702040 .59
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/01/2009 01/01/2009 EUR FR EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 4 .48 01/01/2009 01/01/2009 SEK SE EUR 300702040 7
APPLE US 1001 Jason Rohrer Passage 1 2 .48 01/01/2009 01/01/2009 EUR DE EUR 300702040 .79

View file

@ -0,0 +1,9 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 1 26 .7 01/02/2009 01/02/2009 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 2 .48 01/02/2009 01/02/2009 EUR DE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 81 01/02/2009 01/02/2009 JPY JP JPY 300702040 115
APPLE US 1001 Jason Rohrer Passage 1 8 .36 01/02/2009 01/02/2009 GBP GB GBP 300702040 .59
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/02/2009 01/02/2009 EUR NL EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 5 .7 01/02/2009 01/02/2009 CAD CA CAD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 3 .48 01/02/2009 01/02/2009 EUR FR EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/02/2009 01/02/2009 SEK SE EUR 300702040 7

View file

@ -0,0 +1,11 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 1 29 .7 01/03/2009 01/03/2009 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/03/2009 01/03/2009 EUR IE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 7 15 0 01/03/2009 01/03/2009 CAD CA CAD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 2 81 01/03/2009 01/03/2009 JPY JP JPY 300702040 115
APPLE US 1001 Jason Rohrer Passage 7 183 0 01/03/2009 01/03/2009 USD US USD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 .76 01/03/2009 01/03/2009 AUD AU AUD 300702040 1.19
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/03/2009 01/03/2009 EUR ES EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/03/2009 01/03/2009 EUR FR EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 2 .7 01/03/2009 01/03/2009 CAD CA CAD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 6 .36 01/03/2009 01/03/2009 GBP GB GBP 300702040 .59

View file

@ -0,0 +1,35 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 7 16 0 01/04/2009 01/04/2009 AUD AU AUD 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 2 0 01/04/2009 01/04/2009 NZD NZ AUD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 81 01/04/2009 01/04/2009 JPY JP JPY 300702040 115
APPLE US 1001 Jason Rohrer Passage 7 11 0 01/04/2009 01/04/2009 EUR NL EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/04/2009 01/04/2009 USD IN USD 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 3 0 01/04/2009 01/04/2009 EUR PL EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/04/2009 01/04/2009 EUR LU EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/04/2009 01/04/2009 EUR ES EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 3 .7 01/04/2009 01/04/2009 CAD CA CAD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 7 2 0 01/04/2009 01/04/2009 CHF CH EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 4 0 01/04/2009 01/04/2009 USD SG USD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 37 .7 01/04/2009 01/04/2009 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 7 19 0 01/04/2009 01/04/2009 EUR DE EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 4 .48 01/04/2009 01/04/2009 EUR DE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/04/2009 01/04/2009 EUR BE EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/04/2009 01/04/2009 EUR GR EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/04/2009 01/04/2009 EUR IE EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/04/2009 01/04/2009 EUR PT EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 19 0 01/04/2009 01/04/2009 CAD CA CAD 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 11 0 01/04/2009 01/04/2009 SEK SE EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/04/2009 01/04/2009 NOK NO EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 10 0 01/04/2009 01/04/2009 EUR FR EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 68 0 01/04/2009 01/04/2009 GBP GB GBP 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/04/2009 01/04/2009 EUR FI EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/04/2009 01/04/2009 EUR IT EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/04/2009 01/04/2009 DKK DK EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/04/2009 01/04/2009 USD AR USD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 4 .36 01/04/2009 01/04/2009 GBP GB GBP 300702040 .59
APPLE US 1001 Jason Rohrer Passage 7 3 0 01/04/2009 01/04/2009 EUR FI EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/04/2009 01/04/2009 MXN MX USD 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 214 0 01/04/2009 01/04/2009 USD US USD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/04/2009 01/04/2009 SEK SE EUR 300702040 7
APPLE US 1001 Jason Rohrer Passage 7 6 0 01/04/2009 01/04/2009 JPY JP JPY 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/04/2009 01/04/2009 USD PH USD 300702040 0

View file

@ -0,0 +1,26 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 1 22 .7 01/05/2009 01/05/2009 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/05/2009 01/05/2009 CHF CH EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 2 .76 01/05/2009 01/05/2009 AUD AU AUD 300702040 1.19
APPLE US 1001 Jason Rohrer Passage 7 106 0 01/05/2009 01/05/2009 USD US USD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/05/2009 01/05/2009 EUR DE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/05/2009 01/05/2009 EUR ES EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/05/2009 01/05/2009 DKK DK EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 2 81 01/05/2009 01/05/2009 JPY JP JPY 300702040 115
APPLE US 1001 Jason Rohrer Passage 7 22 0 01/05/2009 01/05/2009 GBP GB GBP 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/05/2009 01/05/2009 EUR IE EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/05/2009 01/05/2009 EUR IT EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 2 0 01/05/2009 01/05/2009 EUR NL EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 11 0 01/05/2009 01/05/2009 EUR DE EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 6 .36 01/05/2009 01/05/2009 GBP GB GBP 300702040 .59
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/05/2009 01/05/2009 EUR NL EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 7 6 0 01/05/2009 01/05/2009 SEK SE EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 9 0 01/05/2009 01/05/2009 AUD AU AUD 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 2 0 01/05/2009 01/05/2009 NZD NZ AUD 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 3 0 01/05/2009 01/05/2009 EUR FR EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/05/2009 01/05/2009 EUR FI EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/05/2009 01/05/2009 DKK DK EUR 300702040 6
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/05/2009 01/05/2009 EUR BE EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 6 0 01/05/2009 01/05/2009 CAD CA CAD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 .7 01/05/2009 01/05/2009 CAD CA CAD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/05/2009 01/05/2009 USD SG USD 300702040 0

View file

@ -0,0 +1,19 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/07/2009 01/07/2009 SEK SE EUR 300702040 7
APPLE US 1001 Jason Rohrer Passage 7 2 0 01/07/2009 01/07/2009 AUD AU AUD 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 42 0 01/07/2009 01/07/2009 USD US USD 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 4 0 01/07/2009 01/07/2009 EUR DE EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/07/2009 01/07/2009 EUR ES EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 3 .48 01/07/2009 01/07/2009 EUR DE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .7 01/07/2009 01/07/2009 CAD CA CAD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 2 .76 01/07/2009 01/07/2009 AUD AU AUD 300702040 1.19
APPLE US 1001 Jason Rohrer Passage 1 3 .48 01/07/2009 01/07/2009 EUR FR EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/07/2009 01/07/2009 EUR IT EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 3 0 01/07/2009 01/07/2009 CAD CA CAD 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 3 0 01/07/2009 01/07/2009 SEK SE EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 2 0 01/07/2009 01/07/2009 DKK DK EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 25 .7 01/07/2009 01/07/2009 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 7 2 0 01/07/2009 01/07/2009 EUR FR EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 10 0 01/07/2009 01/07/2009 GBP GB GBP 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 2 .36 01/07/2009 01/07/2009 GBP GB GBP 300702040 .59
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/07/2009 01/07/2009 EUR NL EUR 300702040 .79

View file

@ -0,0 +1,17 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 7 32 0 01/08/2009 01/08/2009 USD US USD 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 3 0 01/08/2009 01/08/2009 CAD CA CAD 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/08/2009 01/08/2009 NZD NZ AUD 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/08/2009 01/08/2009 JPY JP JPY 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 .36 01/08/2009 01/08/2009 GBP GB GBP 300702040 .59
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/08/2009 01/08/2009 EUR AT EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 .7 01/08/2009 01/08/2009 USD HK USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 7 4 0 01/08/2009 01/08/2009 GBP GB GBP 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/08/2009 01/08/2009 EUR ES EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/08/2009 01/08/2009 EUR BE EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 2 81 01/08/2009 01/08/2009 JPY JP JPY 300702040 115
APPLE US 1001 Jason Rohrer Passage 1 26 .7 01/08/2009 01/08/2009 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/08/2009 01/08/2009 EUR FR EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 7 2 0 01/08/2009 01/08/2009 EUR FI EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 3 0 01/08/2009 01/08/2009 EUR DE EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/08/2009 01/08/2009 CHF CH EUR 300702040 0

View file

@ -0,0 +1,17 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 1 16 .7 01/09/2009 01/09/2009 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 7 23 0 01/09/2009 01/09/2009 USD US USD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 2 .48 01/09/2009 01/09/2009 EUR FR EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 7 3 0 01/09/2009 01/09/2009 CAD CA CAD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 81 01/09/2009 01/09/2009 JPY JP JPY 300702040 115
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/09/2009 01/09/2009 EUR HU EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 2 0 01/09/2009 01/09/2009 GBP GB GBP 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 2 .36 01/09/2009 01/09/2009 GBP GB GBP 300702040 .59
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/09/2009 01/09/2009 SEK SE EUR 300702040 7
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/09/2009 01/09/2009 JPY JP JPY 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/09/2009 01/09/2009 EUR IE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/09/2009 01/09/2009 EUR IT EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 2 .7 01/09/2009 01/09/2009 CAD CA CAD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/09/2009 01/09/2009 EUR CZ EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/09/2009 01/09/2009 EUR FR EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 2 0 01/09/2009 01/09/2009 DKK DK EUR 300702040 0

View file

@ -0,0 +1,15 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 7 17 0 01/10/2009 01/10/2009 USD US USD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 .7 01/10/2009 01/10/2009 USD SG USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 1 .36 01/10/2009 01/10/2009 GBP GB GBP 300702040 .59
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/10/2009 01/10/2009 CHF CH EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/10/2009 01/10/2009 EUR DE EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/10/2009 01/10/2009 EUR NL EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/10/2009 01/10/2009 EUR FI EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 .7 01/10/2009 01/10/2009 CAD CA CAD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 1 81 01/10/2009 01/10/2009 JPY JP JPY 300702040 115
APPLE US 1001 Jason Rohrer Passage 1 16 .7 01/10/2009 01/10/2009 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 7 2 0 01/10/2009 01/10/2009 AUD AU AUD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 2 .76 01/10/2009 01/10/2009 AUD AU AUD 300702040 1.19
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/10/2009 01/10/2009 GBP GB GBP 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 2 0 01/10/2009 01/10/2009 CAD CA CAD 300702040 0

View file

@ -0,0 +1,14 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 7 2 0 01/11/2009 01/11/2009 GBP GB GBP 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/11/2009 01/11/2009 EUR FR EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/11/2009 01/11/2009 CAD CA CAD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 .7 01/11/2009 01/11/2009 USD AR USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/11/2009 01/11/2009 EUR FI EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/11/2009 01/11/2009 AUD AU AUD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 .76 01/11/2009 01/11/2009 AUD AU AUD 300702040 1.19
APPLE US 1001 Jason Rohrer Passage 7 24 0 01/11/2009 01/11/2009 USD US USD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/11/2009 01/11/2009 SEK SE EUR 300702040 7
APPLE US 1001 Jason Rohrer Passage 1 29 .7 01/11/2009 01/11/2009 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/11/2009 01/11/2009 EUR DE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 2 81 01/11/2009 01/11/2009 JPY JP JPY 300702040 115
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/11/2009 01/11/2009 EUR FR EUR 300702040 .79

View file

@ -0,0 +1,12 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 1 3 .36 01/12/2009 01/12/2009 GBP GB GBP 300702040 .59
APPLE US 1001 Jason Rohrer Passage 7 2 0 01/12/2009 01/12/2009 AUD AU AUD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 .7 01/12/2009 01/12/2009 USD SG USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/12/2009 01/12/2009 EUR SK EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 7 10 0 01/12/2009 01/12/2009 USD US USD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 20 .7 01/12/2009 01/12/2009 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/12/2009 01/12/2009 EUR PT EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 2 .7 01/12/2009 01/12/2009 CAD CA CAD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/12/2009 01/12/2009 EUR AT EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 3 0 01/12/2009 01/12/2009 GBP GB GBP 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/12/2009 01/12/2009 SEK SE EUR 300702040 0

View file

@ -0,0 +1,16 @@
Provider Provider Country Vendor Identifier UPC ISRC Artist / Show Title / Episode / Season Label/Studio/Network Product Type Identifier Units Royalty Price Begin Date End Date Customer Currency Country Code Royalty Currency Preorder Season Pass ISAN Apple Identifier Customer Price CMA Asset/Content Flavor
APPLE US 1001 Jason Rohrer Passage 1 7 .7 01/13/2009 01/13/2009 USD US USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 2 .36 01/13/2009 01/13/2009 GBP GB GBP 300702040 .59
APPLE US 1001 Jason Rohrer Passage 1 2 .76 01/13/2009 01/13/2009 AUD AU AUD 300702040 1.19
APPLE US 1001 Jason Rohrer Passage 7 12 0 01/13/2009 01/13/2009 USD US USD 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/13/2009 01/13/2009 EUR FR EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/13/2009 01/13/2009 EUR IE EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/13/2009 01/13/2009 AUD AU AUD 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 1 .7 01/13/2009 01/13/2009 USD SG USD 300702040 .99
APPLE US 1001 Jason Rohrer Passage 1 3 .48 01/13/2009 01/13/2009 EUR DE EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/13/2009 01/13/2009 SEK SE EUR 300702040 7
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/13/2009 01/13/2009 NOK NO EUR 300702040 6
APPLE US 1001 Jason Rohrer Passage 7 1 0 01/13/2009 01/13/2009 SEK SE EUR 300702040 0
APPLE US 1001 Jason Rohrer Passage 1 2 81 01/13/2009 01/13/2009 JPY JP JPY 300702040 115
APPLE US 1001 Jason Rohrer Passage 1 1 .48 01/13/2009 01/13/2009 EUR ES EUR 300702040 .79
APPLE US 1001 Jason Rohrer Passage 7 2 0 01/13/2009 01/13/2009 GBP GB GBP 300702040 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -0,0 +1,9 @@
The critically-acclaimed breakout-hit from art game designer Jason Rohrer. Passage is a tiny, touching, five-minute game about life.
"More than any game I've ever played, it illustrates how a game can be a fantastically expressive, artistic vehicle for exploring the human condition." -- Clive Thompson, Wired
"Passage may look primitive but it's an absolute pinnacle of videogame development." --Andy Chalk, The Escapist
"Portal is a fine game---nothing less than excellent... Passage is even better." --Nick Montfort, MIT
You can read an in-depth profile of Jason Rohrer, along with an extensive discussion of Passage, in Esquire Magazine's December 2008 "Genius" issue.

View file

@ -0,0 +1,21 @@
#include "drawIntoScreen.h"
#include <stdlib.h>
void drawIntoScreen( Uint32 *inScreenBuffer, int inWidth, int inHeight ) {
// add dot at random spot
int x = rand() % inWidth;
int y = rand() % inHeight;
int i = y * inWidth + x;
inScreenBuffer[ i ] = 0xFFFFFFFF;
}
void initScreenDrawer( Uint32 *inScreenBuffer, int inWidth, int inHeight ) {
}
void freeScreenDrawer() {
}

View file

@ -0,0 +1,454 @@
/*
* Modification History
*
* 2006-September-26 Jason Rohrer
* Switched to cosine interpolation.
* Added optimizations discovered with profiler. Reduced running time by 18%.
*/
#include "landscape.h"
#include <math.h>
#include <stdlib.h>
#include "minorGems/util/SimpleVector.h"
double landscape( double inX, double inY, double inT,
double inBaseFrequency, double inRoughness,
int inDetail ) {
if( inDetail < 0 ) {
return 0.0;
}
else {
// frequency of octave
double frequency = inBaseFrequency * pow( 2, inDetail );
double amplitude = pow( inRoughness, inDetail );
return amplitude * noise4d( inX * frequency,
inY * frequency,
// index different planes of noise
inDetail,
inT )
+ landscape( inX, inY, inT, inBaseFrequency, inRoughness,
inDetail - 1 );
}
}
double variableRoughnessLandscape( double inX, double inY, double inT,
double inBaseFrequency,
double inRoughnessChangeFrequency,
double inMinRoughness,
double inMaxRoughness,
int inDetail ) {
double roughnessFreqX = inX * inRoughnessChangeFrequency;
double roughnessFreqY = inY * inRoughnessChangeFrequency;
// use low-frequency noise 4d to select landscape roughness
// between 0 and 1
double roughness =
( noise4d( 6, roughnessFreqX, roughnessFreqY, inT ) + 1 ) / 2;
// move roughness into specified range
roughness =
roughness * ( inMaxRoughness - inMinRoughness ) +
inMinRoughness;
return landscape( inX, inY, inT, inBaseFrequency, roughness, inDetail );
}
int getRandomPoints( double inStartX, double inEndX,
double inStartY, double inEndY,
double inT,
double inSampleStepSize,
double inDensity,
double **outXCoordinates,
double **outYCoordinates ) {
SimpleVector<double> *xCoordinates = new SimpleVector<double>();
SimpleVector<double> *yCoordinates = new SimpleVector<double>();
// discretize startX and start Y so that sample grid for differently-placed
// windows always meshes
// use ceil to ensure that starting points are always inside the
// inStart/inEnd bounds
double discretizedStartX =
inSampleStepSize * ceil( inStartX / inSampleStepSize );
double discretizedStartY =
inSampleStepSize * ceil( inStartY / inSampleStepSize );
// put a point wherever we have a zero-crossing
double lastSample = 1;
for( double x=discretizedStartX; x<=inEndX; x+=inSampleStepSize ) {
for( double y=discretizedStartY; y<=inEndY; y+=inSampleStepSize ) {
double landscapeSample =
variableRoughnessLandscape(
30 * x + 1000, 30 * y + 1000, inT + 1000,
0.01, 0.001, 0.25, 0.65, 0 );
// shift landscape up to reduce chance of zero-crossing
landscapeSample = (1-inDensity) * 0.5 + 0.5 + landscapeSample ;
if( landscapeSample < 0 &&
lastSample >= 0 ||
landscapeSample >= 0 &&
landscapeSample < 0 ) {
// sign change
// hit
xCoordinates->push_back( x );
yCoordinates->push_back( y );
}
lastSample = landscapeSample;
}
}
*outXCoordinates = xCoordinates->getElementArray();
*outYCoordinates = yCoordinates->getElementArray();
int numPoints = xCoordinates->size();
delete xCoordinates;
delete yCoordinates;
return numPoints;
}
/**
* Computes a 32-bit random number.
* Use linear congruential method.
*
* @param inSeed the seed to use.
*/
// this is the readable version of the funcion
// it has been turned into a set of macros below
inline unsigned int random32_readable( unsigned int inSeed ) {
// this is the true hot-spot of the entire landscape function
// thus, optimization is warranted.
// multiplier = 3141592621
// use hex to avoid warnings
//unsigned int multiplier = 0xBB40E62D;
//unsigned int increment = 1;
// better:
// unsigned int multiplier = 196314165
// unsigned int increment = 907633515
// this will automatically be mod-ed by 2^32 because of the limit
// of the unsigned int type
// return multiplier * inSeed + increment;
//return 0xBB40E62D * inSeed + 1;
//return 196314165 * inSeed + 907633515;
//int n = ( inSeed << 13 ) ^ inSeed;
//return n * (n * n * 15731 + 789221) + 1376312589;
//const unsigned int Num1 = (inSeed * 0xFEA09B9DU) + 1;
//const unsigned int Num2 = ((inSeed * 0xB89C8895U) + 1) >> 16;
//return Num1 ^ Num2;
/*
unsigned int rseed=(inSeed*15064013)^(inSeed*99991+604322121)^(inSeed*45120321)^(inSeed*5034121+13);
const unsigned int Num1 = (inSeed * 0xFEA09B9DU) + 1;
const unsigned int Num2 = ((inSeed * 0xB89C8895U) + 1) >> 16;
rseed *= Num1 ^ Num2;
return rseed;
*/
const unsigned int Num1 = (inSeed * 0xFEA09B9DU) + 1;
const unsigned int Num2 = ((inSeed^Num1) * 0x9C129511U) + 1;
const unsigned int Num3 = (inSeed * 0x2512CFB8U) + 1;
const unsigned int Num4 = ((inSeed^Num3) * 0xB89C8895U) + 1;
const unsigned int Num5 = (inSeed * 0x6BF962C1U) + 1;
const unsigned int Num6 = ((inSeed^Num5) * 0x4BF962C1U) + 1;
return Num2 ^ (Num4 >> 11) ^ (Num6 >> 22);
}
// faster as a set of macros
#define Num1( inSeed ) \
( ( inSeed * 0xFEA09B9DU ) + 1 )
#define Num2( inSeed ) \
( ( ( inSeed ^ Num1( inSeed ) ) * 0x9C129511U ) + 1 )
#define Num3( inSeed ) \
( ( inSeed * 0x2512CFB8U ) + 1 )
#define Num4( inSeed ) \
( ( ( inSeed ^ Num3( inSeed ) ) * 0xB89C8895U ) + 1 )
#define Num5( inSeed ) \
( ( inSeed * 0x6BF962C1U ) + 1 )
#define Num6( inSeed ) \
( ( ( inSeed ^ Num5( inSeed ) ) * 0x4BF962C1U ) + 1 )
#define random32( inSeed ) \
( Num2( inSeed ) ^ (Num4( inSeed ) >> 11) ^ (Num6( inSeed ) >> 22) )
#define invMaxIntAsDouble 2.32830643708e-10
// 1/(x/2) = 2*(1/x)
//double invHalfMaxIntAsDouble = 2 * invMaxIntAsDouble;
// 2.32830643708e-10
//+ 2.32830643708e-10
//-------------------
// 4.65661287416e-10
#define invHalfMaxIntAsDouble 4.65661287416e-10
#define mixFour( x, y, z, t ) ( x ^ (y * 57) ^ (z * 131) ^ (t * 2383) )
/**
* Maps 4d integer coordinates into a [-1..1] noise space.
*
* @param x, y, z, t the 4d coordinates.
*
* @return a random value in the range [-1..1]
*/
// keep readable version around for reference
// it has been replaced by a macro below
inline double noise4dInt32_readable( unsigned int x,
unsigned int y,
unsigned int z,
unsigned int t ) {
//double maxIntAsDouble = 4294967295.0;
// modular addition automatic
// multiply x, y, z, and t by distinct primes to
// avoid correllations.
// using xor ( ^ ) here seems to avoid correllations that show
// up when using addition.
// mix x, y, z, and t
unsigned int randomSeed =
x ^
y * 57 ^
z * 131 ^
t * 2383;
// a random value between 0 and max unsigned int
unsigned int randomValue = random32( randomSeed );
// a random value between 0 and 2
double zeroTwoValue = randomValue * invHalfMaxIntAsDouble;
// a random value between -1 and 1
return zeroTwoValue - 1;
}
// noise4dInt32 function call itself was the slowest spot in code
// (found with profiler)
// turn into a set of macros
// matches original parameter format
#define noise4dInt32( x, y, z, t ) \
random32( mixFour( x, y, z, t ) ) \
* invHalfMaxIntAsDouble - 1
// problem: now that random32 is a macro, we are passing the unevaluated
// expression, ( x ^ (y * 57) ^ (z * 131) ^ (t * 2383) ), down into it.
// it is being evaluated 6 times within the depths of the random32 macro
// thus, we need to provide a new format where the caller can precompute
// the mix for us. This is even faster.
#define noise1dInt32( precomputedMix ) \
random32( precomputedMix ) \
* invHalfMaxIntAsDouble - 1
/*
* The following functions (blendNoiseNd) do 4d linear interpolation
* one dimension at a time.
*
* The end result is 8 calls to blendNoise1d (and 16 calls to noise4dInt32).
*
* This method was inspired by the functional implementations---I am
* decomposing a complicated problem into sub-problems that are easier
* to solve.
*/
// faster than f * b + (1-f) * a
// one less multiply
#define linearInterpolation( t, a, b ) ( a + t * ( b - a ) )
/**
* Blends 4d discrete (integer-parameter) noise function along one dimension
* with 3 fixed integer parameters.
*/
inline double blendNoise1d( double x,
unsigned int y,
unsigned int z,
unsigned int t ) {
double floorX = floor( x );
unsigned int floorIntX = (unsigned int)floorX;
if( floorX == x ) {
unsigned int precomputedMix = mixFour( floorIntX, y, z, t );
return noise1dInt32( precomputedMix );
}
else {
unsigned int ceilIntX = floorIntX + 1;
// cosine interpolation
// from http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
double ft = ( x - floorX ) * M_PI;
double f = ( 1 - cos( ft ) ) * .5;
// need to pre-store intermediate values because noise4dInt32 is a
// macro
// thus, we end up calling the noise1dInt32 function instead
unsigned int precomputedMix = mixFour( floorIntX, y, z, t );
double valueAtFloor = noise1dInt32( precomputedMix );
precomputedMix = mixFour( ceilIntX, y, z, t );
double valueAtCeiling = noise1dInt32( precomputedMix );
return linearInterpolation( f, valueAtFloor, valueAtCeiling );
}
}
/**
* Blends 4d discrete (integer-parameter) noise function along 2 dimensions
* with 2 fixed integer parameters.
*/
double blendNoise2d( double x,
double y,
unsigned int z,
unsigned int t ) {
double floorY = floor( y );
unsigned int floorIntY = (unsigned int)floorY;
if( floorY == y ) {
return blendNoise1d( x, floorIntY, z, t );
}
else {
unsigned int ceilIntY = floorIntY + 1;
// cosine interpolation
// from http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
double ft = ( y - floorY ) * M_PI;
double f = ( 1 - cos( ft ) ) * .5;
return ( f ) * blendNoise1d( x, ceilIntY, z, t ) +
( 1 - f ) * blendNoise1d( x, floorIntY, z, t );
}
}
/**
* Blends 4d discrete (integer-parameter) noise function along 3 dimensions
* with 1 fixed integer parameters.
*/
double blendNoise3d( double x,
double y,
double z,
unsigned int t ) {
double floorZ = floor( z );
unsigned int floorIntZ = (unsigned int)floorZ;
if( floorZ == z ) {
return blendNoise2d( x, y, floorIntZ, t );
}
else {
unsigned int ceilIntZ = floorIntZ + 1;
// cosine interpolation
// from http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
double ft = ( z - floorZ ) * M_PI;
double f = ( 1 - cos( ft ) ) * .5;
return ( f ) * blendNoise2d( x, y, ceilIntZ, t ) +
( 1 - f ) * blendNoise2d( x, y, floorIntZ, t );
}
}
/**
* Blends 4d discrete (integer-parameter) noise function along 4 dimensions.
*/
double noise4d( double x,
double y,
double z,
double t ) {
double floorT = floor( t );
unsigned int floorIntT = (unsigned int)floorT;
if( floorT == t ) {
return blendNoise3d( x, y, z, floorIntT );
}
else {
unsigned int ceilIntT = floorIntT + 1;
// cosine interpolation
// from http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
double ft = ( t - floorT ) * M_PI;
double f = ( 1 - cos( ft ) ) * .5;
return ( f ) * blendNoise3d( x, y, z, ceilIntT ) +
( 1 - f ) * blendNoise3d( x, y, z, floorIntT );
}
}
/**
* Blends 4d discrete (integer-parameter) noise function along 3 dimensions
* to get a 3D noise function.
*/
double noise3d( double x,
double y,
double z ) {
return blendNoise3d( x, y, z, 0 );
}

View file

@ -0,0 +1,113 @@
#ifndef LANDSCAPE_INCLUDED
#define LANDSCAPE_INCLUDED
/**
* Gets height samples from an "infinite" fractal landscape.
* The landscape can change over time by varying t.
*
* @param x the x coordinate of the sample.
* @param y the y coordinate of the sample.
* @param t the time of the sample.
* @param baseFrequency the frequency to use for the lowest detail component.
* @param inRoughness the roughness of the landscape (how much high frequencies
* are factored in). Should be in the range [0..1] with 0 making a very
* smooth landscape and 1 making a very rough landscape.
* @param detail the detail level. Larger numbers result in more
* detail. Defaults to 10.
*
* @return the height of the landscape at the sample point/time.
*/
double landscape( double inX, double inY, double inT,
double inBaseFrequency, double inRoughness,
int inDetail = 10 );
/**
* Samples height of a landscape that varies in roughness over the xy plane.
*
* @params same as for landscape, except:
* @param inRoughnessChangeFrequency the rate at which roughness changes
* over space. Should, in general, be less than inBaseFrequency.
* @param inMinRoughness the minimum roughness value, in the range [0..1].
* @param inMaxRoughness the maximum roughness value, in the range [0..1].
*
* @return same as for landscape.
*/
double variableRoughnessLandscape( double inX, double inY, double inT,
double inBaseFrequency,
double inRoughnessChangeFrequency,
double inMinRoughness,
double inMaxRoughness,
int inDetail );
/**
* Computes linearly-blended random values in the range [-1..1] from a
* 4d parameterized noise space.
*
* @param x, y, z, t the 4d floating-point coordinates.
*
* @return a blended random value in the range [-1..1].
*/
double noise4d( double x,
double y,
double z,
double t );
/**
* Computes linearly-blended random values in the range [-1..1] from a
* 4d parameterized noise space (keeping one dimension constant).
*
* Should be faster than noise4D.
*
* @param x, y, z the 3d floating-point coordinates.
*
* @return a blended random value in the range [-1..1].
*/
double noise3d( double x,
double y,
double z );
/**
* Gets a set of randomly-chosen (though stable) points in a given
* region of the landscape.
*
* @param inStartX, inEndX the x region.
* @param inStartY, inEndY the y region.
* @param inT the time.
* @param inSampleStepSize the step size in the sample grid.
* Higher values are faster but result in sparser distributions of points.
* @param inDensity the density of points, in the range [0,1].
* @param outXCoordinates pointer to where array of x coordinates should
* be returned. Array must be destroyed by caller.
* @param outYCoordinates pointer to where array of x coordinates should
* be returned. Array must be destroyed by caller.
*
* @return the number of points (the length of outXCoordinates).
*/
int getRandomPoints( double inStartX, double inEndX,
double inStartY, double inEndY,
double inT,
double inSampleStepSize,
double inDensity,
double **outXCoordinates,
double **outYCoordinates );
#endif

View file

@ -0,0 +1,11 @@
/* SDLMain.m - main entry point for our Cocoa-ized SDL app
Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
Non-NIB-Code & other changes: Max Horn <max@quendi.de>
Feel free to customize this file to suit your needs
*/
#import <Cocoa/Cocoa.h>
@interface SDLMain : NSObject
@end

View file

@ -0,0 +1,384 @@
/* SDLMain.m - main entry point for our Cocoa-ized SDL app
Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
Non-NIB-Code & other changes: Max Horn <max@quendi.de>
Feel free to customize this file to suit your needs
*/
#import <SDL/SDL.h>
#import "SDLMain.h"
#import <sys/param.h> /* for MAXPATHLEN */
#import <unistd.h>
/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
but the method still is there and works. To avoid warnings, we declare
it ourselves here. */
@interface NSApplication(SDL_Missing_Methods)
- (void)setAppleMenu:(NSMenu *)menu;
@end
/* Use this flag to determine whether we use SDLMain.nib or not */
#define SDL_USE_NIB_FILE 0
/* Use this flag to determine whether we use CPS (docking) or not */
#define SDL_USE_CPS 1
#ifdef SDL_USE_CPS
/* Portions of CPS.h */
typedef struct CPSProcessSerNum
{
UInt32 lo;
UInt32 hi;
} CPSProcessSerNum;
extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
#endif /* SDL_USE_CPS */
static int gArgc;
static char **gArgv;
static BOOL gFinderLaunch;
static BOOL gCalledAppMainline = FALSE;
static NSString *getApplicationName(void)
{
NSDictionary *dict;
NSString *appName = 0;
/* Determine the application name */
dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
if (dict)
appName = [dict objectForKey: @"CFBundleName"];
if (![appName length])
appName = [[NSProcessInfo processInfo] processName];
return appName;
}
#if SDL_USE_NIB_FILE
/* A helper category for NSString */
@interface NSString (ReplaceSubString)
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
@end
#endif
@interface SDLApplication : NSApplication
@end
@implementation SDLApplication
/* Invoked from the Quit menu item */
- (void)terminate:(id)sender
{
/* Post a SDL_QUIT event */
SDL_Event event;
event.type = SDL_QUIT;
SDL_PushEvent(&event);
}
@end
/* The main class of the application, the application's delegate */
@implementation SDLMain
/* Set the working directory to the .app's parent directory */
- (void) setupWorkingDirectory:(BOOL)shouldChdir
{
if (shouldChdir)
{
char parentdir[MAXPATHLEN];
CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) {
assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */
}
CFRelease(url);
CFRelease(url2);
}
}
#if SDL_USE_NIB_FILE
/* Fix menu to contain the real app name instead of "SDL App" */
- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
{
NSRange aRange;
NSEnumerator *enumerator;
NSMenuItem *menuItem;
aRange = [[aMenu title] rangeOfString:@"SDL App"];
if (aRange.length != 0)
[aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
enumerator = [[aMenu itemArray] objectEnumerator];
while ((menuItem = [enumerator nextObject]))
{
aRange = [[menuItem title] rangeOfString:@"SDL App"];
if (aRange.length != 0)
[menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
if ([menuItem hasSubmenu])
[self fixMenu:[menuItem submenu] withAppName:appName];
}
[ aMenu sizeToFit ];
}
#else
static void setApplicationMenu(void)
{
/* warning: this code is very odd */
NSMenu *appleMenu;
NSMenuItem *menuItem;
NSString *title;
NSString *appName;
appName = getApplicationName();
appleMenu = [[NSMenu alloc] initWithTitle:@""];
/* Add menu items */
title = [@"About " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
[appleMenu addItem:[NSMenuItem separatorItem]];
title = [@"Hide " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
[menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
[appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
[appleMenu addItem:[NSMenuItem separatorItem]];
title = [@"Quit " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
/* Put menu into the menubar */
menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
[menuItem setSubmenu:appleMenu];
[[NSApp mainMenu] addItem:menuItem];
/* Tell the application object that this is now the application menu */
[NSApp setAppleMenu:appleMenu];
/* Finally give up our references to the objects */
[appleMenu release];
[menuItem release];
}
/* Create a window menu */
static void setupWindowMenu(void)
{
NSMenu *windowMenu;
NSMenuItem *windowMenuItem;
NSMenuItem *menuItem;
windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
/* "Minimize" item */
menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
[windowMenu addItem:menuItem];
[menuItem release];
/* Put menu into the menubar */
windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
[windowMenuItem setSubmenu:windowMenu];
[[NSApp mainMenu] addItem:windowMenuItem];
/* Tell the application object that this is now the window menu */
[NSApp setWindowsMenu:windowMenu];
/* Finally give up our references to the objects */
[windowMenu release];
[windowMenuItem release];
}
/* Replacement for NSApplicationMain */
static void CustomApplicationMain (int argc, char **argv)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
SDLMain *sdlMain;
/* Ensure the application object is initialised */
[SDLApplication sharedApplication];
#ifdef SDL_USE_CPS
{
CPSProcessSerNum PSN;
/* Tell the dock about us */
if (!CPSGetCurrentProcess(&PSN))
if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
if (!CPSSetFrontProcess(&PSN))
[SDLApplication sharedApplication];
}
#endif /* SDL_USE_CPS */
/* Set up the menubar */
[NSApp setMainMenu:[[NSMenu alloc] init]];
setApplicationMenu();
setupWindowMenu();
/* Create SDLMain and make it the app delegate */
sdlMain = [[SDLMain alloc] init];
[NSApp setDelegate:sdlMain];
/* Start the main event loop */
[NSApp run];
[sdlMain release];
[pool release];
}
#endif
/*
* Catch document open requests...this lets us notice files when the app
* was launched by double-clicking a document, or when a document was
* dragged/dropped on the app's icon. You need to have a
* CFBundleDocumentsType section in your Info.plist to get this message,
* apparently.
*
* Files are added to gArgv, so to the app, they'll look like command line
* arguments. Previously, apps launched from the finder had nothing but
* an argv[0].
*
* This message may be received multiple times to open several docs on launch.
*
* This message is ignored once the app's mainline has been called.
*/
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
const char *temparg;
size_t arglen;
char *arg;
char **newargv;
if (!gFinderLaunch) /* MacOS is passing command line args. */
return FALSE;
if (gCalledAppMainline) /* app has started, ignore this document. */
return FALSE;
temparg = [filename UTF8String];
arglen = SDL_strlen(temparg) + 1;
arg = (char *) SDL_malloc(arglen);
if (arg == NULL)
return FALSE;
newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
if (newargv == NULL)
{
SDL_free(arg);
return FALSE;
}
gArgv = newargv;
SDL_strlcpy(arg, temparg, arglen);
gArgv[gArgc++] = arg;
gArgv[gArgc] = NULL;
return TRUE;
}
/* Called when the internal event loop has just started running */
- (void) applicationDidFinishLaunching: (NSNotification *) note
{
int status;
/* Set the working directory to the .app's parent directory */
[self setupWorkingDirectory:gFinderLaunch];
#if SDL_USE_NIB_FILE
/* Set the main menu to contain the real app name instead of "SDL App" */
[self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
#endif
/* Hand off to main application code */
gCalledAppMainline = TRUE;
status = SDL_main (gArgc, gArgv);
/* We're done, thank you for playing */
exit(status);
}
@end
@implementation NSString (ReplaceSubString)
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
{
unsigned int bufferSize;
unsigned int selfLen = [self length];
unsigned int aStringLen = [aString length];
unichar *buffer;
NSRange localRange;
NSString *result;
bufferSize = selfLen + aStringLen - aRange.length;
buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
/* Get first part into buffer */
localRange.location = 0;
localRange.length = aRange.location;
[self getCharacters:buffer range:localRange];
/* Get middle part into buffer */
localRange.location = 0;
localRange.length = aStringLen;
[aString getCharacters:(buffer+aRange.location) range:localRange];
/* Get last part into buffer */
localRange.location = aRange.location + aRange.length;
localRange.length = selfLen - localRange.location;
[self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
/* Build output string */
result = [NSString stringWithCharacters:buffer length:bufferSize];
NSDeallocateMemoryPages(buffer, bufferSize);
return result;
}
@end
#ifdef main
# undef main
#endif
/* Main entry point to executable - should *not* be SDL_main! */
int main (int argc, char **argv)
{
/* Copy the arguments into a global variable */
/* This is passed if we are launched by double-clicking */
if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
gArgv[0] = argv[0];
gArgv[1] = NULL;
gArgc = 1;
gFinderLaunch = YES;
} else {
int i;
gArgc = argc;
gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
for (i = 0; i <= argc; i++)
gArgv[i] = argv[i];
gFinderLaunch = NO;
}
#if SDL_USE_NIB_FILE
[SDLApplication poseAsClass:[NSApplication class]];
NSApplicationMain (argc, argv);
#else
CustomApplicationMain (argc, argv);
#endif
return 0;
}

297
gamma256/gameSource/map.cpp Normal file
View file

@ -0,0 +1,297 @@
#include "map.h"
#include "landscape.h"
#include "minorGems/util/SimpleVector.h"
#include <time.h>
int seed = time( NULL );
//int seed = 10;
extern int tileH;
extern int tileW;
char isBlockedGrid( int inGridX, int inGridY, char inDoNotRecurse );
char isBlockedGridHash( int inGridX, int inGridY, char inDoNotRecurse );
char allNeighborsBlocked( int inGridX, int inGridY ) {
if( ! isBlockedGridHash( inGridX, inGridY - 1, true ) ) {
// top
return false;
}
if( ! isBlockedGridHash( inGridX + 1, inGridY, true ) ) {
// right
return false;
}
if( ! isBlockedGridHash( inGridX, inGridY + 1, true ) ) {
// bottom
return false;
}
if( ! isBlockedGridHash( inGridX - 1, inGridY, true ) ) {
// left
return false;
}
// all neighbors blocked
return true;
}
#include "HashTable.h"
HashTable<char> blockedHashTable( 3000 );
char isBlockedGridHash( int inGridX, int inGridY, char inDoNotRecurse ) {
char found;
char blocked = blockedHashTable.lookup( inGridX, inGridY, &found );
if( found ) {
return blocked;
}
// else not found
// call real function to get result
blocked = isBlockedGrid( inGridX, inGridY, inDoNotRecurse );
// only insert result if we called the full recursive version of
// inBlockGrid. Otherwise, we aren't getting the real result back
// so we shouldn't be tracking it in our table
if( ! inDoNotRecurse ) {
blockedHashTable.insert( inGridX, inGridY, blocked );
}
return blocked;
}
char isBlocked( int inX, int inY ) {
// reduce to grid coordinates
int gridX = inX / tileW;
int gridY = inY / tileH;
// try hash first
return isBlockedGridHash( gridX, gridY, false );
}
char isBlockedGrid( int inGridX, int inGridY, char inDoNotRecurse ) {
// wall along far left and top
if( inGridX <=0 || inGridY <= 0 ) {
return true;
}
// empty passage at top
if( inGridY <= 1 ) {
return false;
}
// make a grid of empty spaces from which blocks can be
// removed below to make a maze
if( inGridX % 2 != 0 && inGridY % 2 != 0 ) {
// however, if all neighbors are blocked, this should
// be blocked too
if( !inDoNotRecurse ) {
return allNeighborsBlocked( inGridX, inGridY );
}
else {
// non-recursive mode
return false;
}
}
// blocks get denser as y increases
double threshold = 1 - inGridY / 20.0;
double randValue = noise3d( inGridX, inGridY, seed );
char returnValue = randValue > threshold;
if( returnValue ) {
return true;
}
else {
// not blocked
// should be blocked if all neighbors are blocked
if( !inDoNotRecurse ) {
return allNeighborsBlocked( inGridX, inGridY );
}
else {
// non-recursive mode
return false;
}
}
}
struct pairStruct {
int x;
int y;
};
typedef struct pairStruct pair;
SimpleVector<pair> openedChests;
char isChest( int inX, int inY ) {
// reduce to grid coordinates
int gridX = inX / tileW;
int gridY = inY / tileH;
// chests get denser as y increases
// no chests where gridY < 5
// even less dense than blocks
double threshold = 1 - ( gridY - 5 ) / 200.0;
// use different seed than for blocks
double randValue = noise3d( 73642 * gridX, 283277 * gridY, seed * 987423 );
char returnValue = randValue > threshold;
if( returnValue ) {
// make sure it's not opened already
for( int i=0; i<openedChests.size(); i++ ) {
pair *p = openedChests.getElement( i );
if( p->x == gridX && p->y == gridY ) {
return CHEST_OPEN;
}
}
return CHEST_CLOSED;
}
else {
return CHEST_NONE;
}
}
unsigned char getChestCode( int inX, int inY ) {
// reduce to grid coordinates
int gridX = inX / tileW;
int gridY = inY / tileH;
// use different seed
double randValue = noise3d( 37462 * gridX, 1747 * gridY, seed * 3748147 );
/*
Note:
Original versions of Passage (up to v3 for Mac/PC/Unix) contained a bug.
This was the original code:
// use it to fill first 6 binary digits
return (unsigned char)( randValue * 15 ) & 0x3F;
Note two things:
1. That randValue is *signed* (and can be negative), so casting
it to an uchar is a weird thing to do.
2. That we're only multiplying randValue by 15, which only fills
the first 4 binary digits (there used to be only 4 gems).
Thus, if randValue is actually *positive* between 0 and 1, only
the first 4 gems have a chance of being activated.
What this code should have done was convert randValue to the range
[0..1] first and then multiply it by 63 (to convert it to a 6-bit
random binary string).
However, this code *seems* to work, anyway, since 2's compliment was
being invoked to handle casting of negative randValues, so all 6 gems
were sometimes being activated.
However, the 6-bit gem strings were always of the form 00XXXX or 11XXXX
(where XXXX is a random 4-bit sting) due to the 2's compliment and
the fact that the negative numbers being complimented were never less
than -15.
So, 2 of the gems were tied together in their on/off status, essentially
turning 6 gems into 5.
The problem appeared on platforms (like iPhone) that don't preserve
2's compliment bits when doing signed to unsigned casting. On these
platforms, all negative numbers were being casted to 0 when turned to
uchars. Thus, half the treasure chests, on average, had no gems at all.
Of course, a proper fix, as described above, would go beyond just making
it work on these platforms, but would also change the behavior of the game
(those last two gems would no longer be tied together in their on-off
status).
After much deliberation, I came to the following solution:
The following code emulates 2's compliment casting, whether the platform
does it or not, making behavior on all platforms identical.
(And preserving the original bug!!)
*/
unsigned char castedChar;
if( randValue < 0 ) {
castedChar = (unsigned char)( 256 + (char)( randValue * 15 ) );
}
else {
castedChar = (unsigned char)( randValue * 15 );
}
return castedChar & 0x3F;
}
void getChestCenter( int inX, int inY, int *outCenterX, int *outCenterY ) {
int gridX = inX / tileW;
int gridY = inY / tileH;
*outCenterX = gridX * tileW + tileW / 2;
*outCenterY = gridY * tileH + tileH / 2;
}
void openChest( int inX, int inY ) {
pair p;
// reduce to grid coordinates
p.x = inX / tileW;
p.y = inY / tileH;
openedChests.push_back( p );
}
void resetMap() {
// new seed
seed = time( NULL );
//seed = 10;
openedChests.deleteAll();
blockedHashTable.clear();
}

30
gamma256/gameSource/map.h Normal file
View file

@ -0,0 +1,30 @@
// checks if position is blocked by wall
char isBlocked( int inX, int inY );
// checks if chest is present
// assumes position is not blocked
#define CHEST_NONE 0
#define CHEST_CLOSED 1
#define CHEST_OPEN 2
char isChest( int inX, int inY );
// 8-bit binary indicating which of six external chest gems are present
#define CHEST_RED_GEM 0x01
#define CHEST_GREEN_GEM 0x02
#define CHEST_ORANGE_GEM 0x04
#define CHEST_BLUE_GEM 0x08
#define CHEST_YELLOW_GEM 0x10
#define CHEST_MAGENTA_GEM 0x20
// assumes a chest is present
unsigned char getChestCode( int inX, int inY );
void getChestCenter( int inX, int inY, int *outCenterX, int *outCenterY );
void openChest( int inX, int inY );
// resets map to a fresh state
void resetMap();

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

View file

@ -0,0 +1,645 @@
#include "common.h"
#include "Timbre.h"
#include "Envelope.h"
#include "minorGems/util/SimpleVector.h"
#include <SDL/SDL.h>
#include <SDL/SDL_audio.h>
#include <math.h>
#include <stdlib.h>
int sampleRate = 22050;
//int sampleRate = 11025;
Image *musicImage = NULL;
int w, h;
// total number of samples played so far
int streamSamples = 0;
// offset into grid at start
// for testing
int gridStartOffset = 0;
// overal loudness of music
double musicLoudness = 1.0;
// one grid step in seconds
double gridStepDuration = 0.25;
int gridStepDurationInSamples = (int)( gridStepDuration * sampleRate );
double entireGridDuraton;
// c
double keyFrequency = 261.63;
int numTimbres = 4;
Timbre *musicTimbres[ 4 ];
int numEnvelopes = 4;
Envelope *musicEnvelopes[ 4 ];
class Note {
public:
// index into musicTimbres array
int mTimbreNumber;
// index into musicEnvelopes array
int mEnvelopeNumber;
int mScaleNoteNumber;
// additional loudness adjustment
// places note in stereo space
double mLoudnessLeft;
double mLoudnessRight;
// start time, in seconds from start of note grid
double mStartTime;
// duration in seconds
double mDuration;
// used when note is currently playing to track progress in note
// negative if we should wait before starting to play the note
int mCurrentSampleNumber;
// duration in samples
int mNumSamples;
};
// isomorphic to our music image, except only has an entry for each note
// start (all others, including grid spots that contain note continuations,
// are NULL)
// indexed as noteGrid[y][x]
Note ***noteGrid;
SimpleVector<Note*> currentlyPlayingNotes;
// need to synch these with audio thread
void setMusicLoudness( double inLoudness ) {
SDL_LockAudio();
musicLoudness = inLoudness;
SDL_UnlockAudio();
}
void restartMusic() {
SDL_LockAudio();
// return to beginning (and forget samples we've played so far)
streamSamples = 0;
// drop all currently-playing notes
currentlyPlayingNotes.deleteAll();
SDL_UnlockAudio();
}
// called by SDL to get more samples
void audioCallback( void *inUserData, Uint8 *inStream, int inLengthToFill ) {
// 2 bytes for each channel of stereo sample
int numSamples = inLengthToFill / 4;
Sint16 *samplesL = new Sint16[ numSamples ];
Sint16 *samplesR = new Sint16[ numSamples ];
// first, zero-out the buffer to prepare it for our sum of note samples
// each sample is 2 bytes
memset( samplesL, 0, 2 * numSamples );
memset( samplesR, 0, 2 * numSamples );
int i;
// hop through all grid steps that *start* in this stream buffer
// add notes that start during this stream buffer
// how far into stream buffer before we hit our first grid step?
int startOfFirstGridStep = streamSamples % gridStepDurationInSamples;
if( startOfFirstGridStep != 0 ) {
startOfFirstGridStep =
gridStepDurationInSamples - startOfFirstGridStep;
}
// hop from start of grid step to start of next grid step
// ignore samples in between, since notes don't start there,
// and all we're doing right now is finding notes that start
for( i=startOfFirstGridStep;
i<numSamples;
i += gridStepDurationInSamples ) {
// start of new grid position
// check for new notes that are starting
// map into our music image:
int x = ( streamSamples + i ) / gridStepDurationInSamples;
// wrap in image
x = x % w;
for( int y=0; y<h; y++ ) {
Note *note = noteGrid[y][x];
if( note != NULL ) {
// new note
currentlyPlayingNotes.push_back( note );
// start it
// set a delay for its start based on our position
// in this callback buffer
note->mCurrentSampleNumber = -i;
}
}
}
streamSamples += numSamples;
// loop over all current notes and add their samples to buffer
for( int n=0; n<currentlyPlayingNotes.size(); n++ ) {
Note *note = *( currentlyPlayingNotes.getElement( n ) );
int waveTableNumber = note->mScaleNoteNumber;
Timbre *timbre = musicTimbres[ note->mTimbreNumber ];
int tableLength = timbre->mWaveTableLengths[ waveTableNumber ];
Sint16 *waveTable = timbre->mWaveTable[ waveTableNumber ];
Envelope *env = musicEnvelopes[ note->mEnvelopeNumber ];
double *envLevels =
env->getEnvelope(
// index envelope by number of grid steps in note
note->mNumSamples / gridStepDurationInSamples );
double noteLoudnessL = note->mLoudnessLeft;
double noteLoudnessR = note->mLoudnessRight;
// do this outside inner loop
noteLoudnessL *= musicLoudness;
noteLoudnessR *= musicLoudness;
int noteStartInBuffer = 0;
int noteEndInBuffer = numSamples;
if( note->mCurrentSampleNumber < 0 ) {
// delay before note starts in this sample buffer
noteStartInBuffer = - note->mCurrentSampleNumber;
// we've taken account of the delay
note->mCurrentSampleNumber = 0;
}
char endNote = false;
int numSamplesLeftInNote =
note->mNumSamples - note->mCurrentSampleNumber;
if( noteStartInBuffer + numSamplesLeftInNote < noteEndInBuffer ) {
// note ends before end of buffer
noteEndInBuffer = noteStartInBuffer + numSamplesLeftInNote;
endNote = true;
}
int waveTablePos = note->mCurrentSampleNumber % tableLength;
int currentSampleNumber = note->mCurrentSampleNumber;
for( i=noteStartInBuffer; i != noteEndInBuffer; i++ ) {
double envelope = envLevels[ currentSampleNumber ];
double monoSample = envelope *
waveTable[ waveTablePos ];
samplesL[i] += (Sint16)( noteLoudnessL * monoSample );
samplesR[i] += (Sint16)( noteLoudnessR * monoSample );
currentSampleNumber ++;
waveTablePos ++;
// avoid using mod operator (%) in inner loop
// found with profiler
if( waveTablePos == tableLength ) {
// back to start of table
waveTablePos = 0;
}
}
note->mCurrentSampleNumber += ( noteEndInBuffer - noteStartInBuffer );
if( endNote ) {
// note ended in this buffer
currentlyPlayingNotes.deleteElement( n );
n--;
}
}
// now copy samples into Uint8 buffer
int streamPosition = 0;
for( i=0; i != numSamples; i++ ) {
Sint16 intSampleL = samplesL[i];
Sint16 intSampleR = samplesR[i];
inStream[ streamPosition ] = (Uint8)( intSampleL & 0xFF );
inStream[ streamPosition + 1 ] = (Uint8)( ( intSampleL >> 8 ) & 0xFF );
inStream[ streamPosition + 2 ] = (Uint8)( intSampleR & 0xFF );
inStream[ streamPosition + 3 ] = (Uint8)( ( intSampleR >> 8 ) & 0xFF );
streamPosition += 4;
}
delete [] samplesL;
delete [] samplesR;
}
// limit on n, based on Nyquist, when summing sine components
//int nLimit = (int)( sampleRate * M_PI );
// actually, this is way too many: it takes forever to compute
// use a lower limit instead
// This produces fine results (almost perfect square wave)
int nLimit = 40;
// square wave with period of 2pi
double squareWave( double inT ) {
double sum = 0;
for( int n=1; n<nLimit; n+=2 ) {
sum += 1.0/n * sin( n * inT );
}
return sum;
}
// sawtoot wave with period of 2pi
double sawWave( double inT ) {
double sum = 0;
for( int n=1; n<nLimit; n++ ) {
sum += 1.0/n * sin( n * inT );
}
return sum;
}
// white noise, ignores inT
double whiteNoise( double inT ) {
return 2.0 * ( rand() / (double)RAND_MAX ) - 1.0;
}
// white noise where each sample is averaged with last sample
// effectively a low-pass filter
double lastSample = 0;
double smoothedWhiteNoise( double inT ) {
// give double-weight to last sample to make it even smoother
lastSample = ( 2 * lastSample + whiteNoise( inT ) ) / 3;
return lastSample;
}
void loadMusicImage( const char *inTGAFileName ) {
musicImage = readTGA( "music", inTGAFileName );
w = musicImage->getWidth();
h = musicImage->getHeight();
// notes are in red and green channel
double *redChannel = musicImage->getChannel( 0 );
double *greenChannel = musicImage->getChannel( 1 );
entireGridDuraton = gridStepDuration * w;
// jump ahead in stream, if needed
streamSamples += gridStartOffset * gridStepDurationInSamples;
// blank line of pixels between timbres
int heightPerTimbre = (h+1) / numTimbres - 1;
// find the maximum number of simultaneous notes in the song
// take loudness into account
double maxNoteLoudnessInAColumn = 0;
int x, y;
for( x=0; x<w; x++ ) {
double noteLoudnessInColumnL = 0;
double noteLoudnessInColumnR = 0;
for( y=0; y<h; y++ ) {
int imageIndex = y * w + x;
// the note number in our scale
// scale starts over for each timbre, with blank line
// in between timbres
int noteNumber = (h - y - 1) % (heightPerTimbre + 1);
if( // not blank line between timbres
noteNumber < heightPerTimbre &&
// tone present in image
( redChannel[ imageIndex ] > 0 ||
greenChannel[ imageIndex ] > 0 ) ) {
noteLoudnessInColumnL += greenChannel[ imageIndex ];
noteLoudnessInColumnR += redChannel[ imageIndex ];
}
}
// pick loudest channel for this column and compare it to
// loudest column/channel seen so far
if( maxNoteLoudnessInAColumn < noteLoudnessInColumnL ) {
maxNoteLoudnessInAColumn = noteLoudnessInColumnL;
}
if( maxNoteLoudnessInAColumn < noteLoudnessInColumnR ) {
maxNoteLoudnessInAColumn = noteLoudnessInColumnR;
}
}
// divide loudness amoung timbres to avoid clipping
double loudnessPerTimbre = 1.0 / maxNoteLoudnessInAColumn;
// further adjust loudness per channel here as we construct
// each timbre.
// This is easier than tweaking loundness of a given part by hand
// using a painting program
musicTimbres[0] = new Timbre( sampleRate, 0.6 * loudnessPerTimbre,
keyFrequency,
heightPerTimbre, sawWave );
musicTimbres[1] = new Timbre( sampleRate, loudnessPerTimbre,
keyFrequency,
heightPerTimbre, sin );
musicTimbres[2] = new Timbre( sampleRate, 0.4 * loudnessPerTimbre,
keyFrequency / 4,
heightPerTimbre, squareWave );
musicTimbres[3] = new Timbre( sampleRate, 0.75 * loudnessPerTimbre,
keyFrequency / 4,
heightPerTimbre, smoothedWhiteNoise );
// next, compute the longest note in the song
int maxNoteLength = 0;
for( y=0; y<h; y++ ) {
int currentNoteLength = 0;
for( x=0; x<w; x++ ) {
int imageIndex = y * w + x;
// the note number in our scale
// scale starts over for each timbre, with blank line
// in between timbres
int noteNumber = (h - y - 1) % (heightPerTimbre + 1);
if( // not blank line between timbres
noteNumber < heightPerTimbre &&
// tone present in image
( redChannel[ imageIndex ] > 0 ||
greenChannel[ imageIndex ] > 0 ) ) {
currentNoteLength ++;
}
else {
currentNoteLength = 0;
}
if( currentNoteLength > maxNoteLength ) {
maxNoteLength = currentNoteLength;
}
}
}
printf( "Max note length in song = %d\n", maxNoteLength );
musicEnvelopes[0] = new Envelope( 0.05, 0.7, 0.25, 0.1,
maxNoteLength,
gridStepDurationInSamples );
musicEnvelopes[1] = new Envelope( 0.1, 0.9, 0.0, 0.0,
maxNoteLength,
gridStepDurationInSamples );
musicEnvelopes[2] = new Envelope( 0.25, 0.0, 1.0, 0.1,
maxNoteLength,
gridStepDurationInSamples );
musicEnvelopes[3] = new Envelope( 0.0, 0.2, 0.0, 0.0,
maxNoteLength,
gridStepDurationInSamples );
noteGrid = new Note**[ h ];
for( int y=0; y<h; y++ ) {
noteGrid[y] = new Note*[ w ];
// each row is one pitch for a given instrument
// thus, two consecutive pixels should be the same note
// handle this by tracking whether a note is playing or not
char notePlaying = false;
Note *noteStart = NULL;
for( int x=0; x<w; x++ ) {
int imageIndex = y * w + x;
// default to NULL
noteGrid[y][x] = NULL;
// the note number in our scale
// scale starts over for each timbre, with blank line
// in between timbres
int noteNumber = (h - y - 1) % (heightPerTimbre + 1);
if( // not blank line between timbres
noteNumber < heightPerTimbre &&
// tone present in image
( redChannel[ imageIndex ] > 0 ||
greenChannel[ imageIndex ] > 0 ) ) {
if( notePlaying ) {
// part of note that's already playing
// one more grid step
noteStart->mDuration += gridStepDuration;
noteStart->mNumSamples += gridStepDurationInSamples;
}
else {
// start a new note
noteGrid[y][x] = new Note();
noteGrid[y][x]->mScaleNoteNumber = noteNumber;
noteGrid[y][x]->mTimbreNumber =
y / ( heightPerTimbre + 1 );
// same as timbre number
noteGrid[y][x]->mEnvelopeNumber =
noteGrid[y][x]->mTimbreNumber;
// left loudness from green brightness
noteGrid[y][x]->mLoudnessLeft = greenChannel[ imageIndex ];
// right loudness from red brightness
noteGrid[y][x]->mLoudnessRight = redChannel[ imageIndex ];
noteGrid[y][x]->mStartTime = gridStepDuration * x;
// one grid step so far
noteGrid[y][x]->mDuration = gridStepDuration;
noteGrid[y][x]->mNumSamples = gridStepDurationInSamples;
// track if it needs to be continued
notePlaying = true;
noteStart = noteGrid[y][x];
}
}
else {
// no tone
if( notePlaying ) {
// stop it
notePlaying = false;
noteStart = NULL;
}
}
}
}
}
void startMusic( const char *inTGAFileName ) {
loadMusicImage( inTGAFileName );
SDL_AudioSpec audioFormat;
/* Set 16-bit stereo audio at 22Khz */
audioFormat.freq = sampleRate;
audioFormat.format = AUDIO_S16;
audioFormat.channels = 2;
audioFormat.samples = 512; /* A good value for games */
audioFormat.callback = audioCallback;
audioFormat.userdata = NULL;
/* Open the audio device and start playing sound! */
if( SDL_OpenAudio( &audioFormat, NULL ) < 0 ) {
printf( "Unable to open audio: %s\n", SDL_GetError() );
}
// set pause to 0 to start audio
SDL_PauseAudio(0);
}
void stopMusic() {
SDL_CloseAudio();
if( musicImage != NULL ) {
delete musicImage;
musicImage = NULL;
}
for( int y=0; y<h; y++ ) {
for( int x=0; x<w; x++ ) {
if( noteGrid[y][x] != NULL ) {
delete noteGrid[y][x];
}
}
delete [] noteGrid[y];
}
delete [] noteGrid;
int i;
for( i=0; i<numTimbres; i++ ) {
delete musicTimbres[i];
}
for( i=0; i<numEnvelopes; i++ ) {
delete musicEnvelopes[i];
}
}

View file

@ -0,0 +1,20 @@
// starts playing music, reading notes from a TGA graphics file
// the file must be in the "music" directory
void startMusic( const char *inTGAFileName );
// set loudness in range [0.0,1.0]
void setMusicLoudness( double inLoudness );
// causes music to jump back to beginning
void restartMusic();
void stopMusic();

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Some files were not shown because too many files have changed in this diff Show more