├── .gitignore ├── Glyphs.png ├── English.lproj ├── InfoPlist.strings └── Matrix.nib │ ├── keyedobjects.nib │ ├── keyedobjects-101300.nib │ └── designable.nib ├── Japanese.lproj └── Matrix.nib │ └── keyedobjects.nib ├── RedPill_Prefix.pch ├── RedPill.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcuserdata │ │ └── meta.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcuserdata │ └── meta.xcuserdatad │ │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ └── RedPill.xcscheme ├── meta.pbxuser └── project.pbxproj ├── GLUtils.h ├── Info-RedPill.plist ├── Info.plist ├── README.md ├── GLUtils.m ├── MatrixOpenGLView.m ├── MatrixOpenGLView.h ├── MatrixMacros.h ├── MatrixTexture.h ├── MatrixStripParams.h ├── MatrixPrefsWindow.h ├── MatrixView.h ├── MatrixStrip.h ├── MatrixPrefsWindow.m ├── MatrixTexture.m ├── MatrixView.m ├── MatrixStrip.m └── LICENSE.html /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | build 3 | -------------------------------------------------------------------------------- /Glyphs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpar/RedPill/HEAD/Glyphs.png -------------------------------------------------------------------------------- /English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpar/RedPill/HEAD/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /English.lproj/Matrix.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpar/RedPill/HEAD/English.lproj/Matrix.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Japanese.lproj/Matrix.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpar/RedPill/HEAD/Japanese.lproj/Matrix.nib/keyedobjects.nib -------------------------------------------------------------------------------- /English.lproj/Matrix.nib/keyedobjects-101300.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpar/RedPill/HEAD/English.lproj/Matrix.nib/keyedobjects-101300.nib -------------------------------------------------------------------------------- /RedPill_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'RedPill' target in the 'RedPill' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #import 8 | #endif 9 | -------------------------------------------------------------------------------- /RedPill.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RedPill.xcodeproj/project.xcworkspace/xcuserdata/meta.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpar/RedPill/HEAD/RedPill.xcodeproj/project.xcworkspace/xcuserdata/meta.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /RedPill.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /GLUtils.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | // This file contains a handy GL error checking function adapted from 5 | // the one found in the Apple OpenGL sample code. 6 | 7 | // Note that __private_extern__ protects CheckGLError from conflicting 8 | // with other screen saver modules, preference panes, frameworks, 9 | // and other bundles that get loaded into the System Preferences 10 | // application, and which have quite likely used the same function. 11 | __private_extern__ void CheckGLError(const char *func, const char *note); 12 | __private_extern__ void LogError(const char *func, const char *note); -------------------------------------------------------------------------------- /RedPill.xcodeproj/xcuserdata/meta.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | RedPill.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 8D255AC50486D3F9007BF209 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Info-RedPill.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | Red Pill 9 | CFBundleGetInfoString 10 | Version 1.5.0 11 | CFBundleIdentifier 12 | com.ath0.redpill 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | Red Pill 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleShortVersionString 20 | 1.5.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.5.0 25 | NSPrincipalClass 26 | MatrixView 27 | 28 | 29 | -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | NSPrincipalClass 26 | MatrixView 27 | 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is Red Pill, a 3D OpenGL "Matrix" screensaver for Mac OS X. 2 | Copyright © 2002-2012 mathew . 3 | 4 | Red Pill is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | or visit [http://www.fsf.org/](http://www.fsf.org/) 18 | 19 | Please note that Apple's terms and conditions on the App Store prohibit distribution of GPL-licensed software. 20 | -------------------------------------------------------------------------------- /RedPill.xcodeproj/project.xcworkspace/xcuserdata/meta.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEWorkspaceUserSettings_BuildLocationStyle 6 | 2 7 | IDEWorkspaceUserSettings_BuildSubfolderNameStyle 8 | 0 9 | IDEWorkspaceUserSettings_DerivedDataLocationStyle 10 | 0 11 | IDEWorkspaceUserSettings_HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 12 | 13 | IDEWorkspaceUserSettings_IssueFilterStyle 14 | 0 15 | IDEWorkspaceUserSettings_LiveSourceIssuesEnabled 16 | 17 | IDEWorkspaceUserSettings_SnapshotAutomaticallyBeforeSignificantChanges 18 | 19 | IDEWorkspaceUserSettings_SnapshotLocationStyle 20 | 0 21 | 22 | 23 | -------------------------------------------------------------------------------- /GLUtils.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import "GLUtils.h" 3 | 4 | // The main change between this function and the Apple version is that 5 | // this one counts the number of errors, and silently ignores errors 6 | // after the first three. 7 | // This is because some users discovered that RedPill would report GL 8 | // errors *even when everything worked fine*, and their system log would 9 | // get filled up with 30 lines of error text every second until it ate 10 | // all available disk space. Ouch! 11 | 12 | __private_extern__ void CheckGLError(const char *func, const char *note) 13 | { 14 | static int errcount = 0; 15 | 16 | GLenum error = glGetError(); 17 | if (error) 18 | { 19 | if (errcount < 4) { 20 | errcount += 1; 21 | NSLog(@"%s.%s: %s (%d)", func, note, gluErrorString(error), error); 22 | } 23 | } 24 | } 25 | 26 | __private_extern__ void LogError(const char *func, const char *note) 27 | { 28 | static int logcount = 0; 29 | 30 | if (logcount < 4) { 31 | logcount += 1; 32 | NSLog(@"%s: %s", func, note); 33 | } 34 | } -------------------------------------------------------------------------------- /MatrixOpenGLView.m: -------------------------------------------------------------------------------- 1 | // This file is part of Red Pill 2 | // A 3D OpenGL "Matrix" screensaver for Mac OS X 3 | // Copyright (C) 2002, 2003 mathew 4 | // 5 | // Red Pill is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | // or visit 19 | 20 | #import "MatrixOpenGLView.h" 21 | 22 | @implementation MatrixOpenGLView 23 | 24 | // pass drawRect to our superview so we can do all the drawing in our ScreenSaverView subclass 25 | - (void)drawRect:(NSRect)rect 26 | { 27 | NSView *superview = [self superview]; 28 | [superview lockFocus]; 29 | [superview drawRect:rect]; 30 | [superview unlockFocus]; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /MatrixOpenGLView.h: -------------------------------------------------------------------------------- 1 | // This file is part of Red Pill 2 | // A 3D OpenGL "Matrix" screensaver for Mac OS X 3 | // Copyright (C) 2002, 2003 mathew 4 | // 5 | // Red Pill is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | // or visit 19 | 20 | // This class simply passes drawRect messages up to its parent, 21 | // which is the main class defining the screensaver. 22 | // That way, you can put all the drawing code together, in the 23 | // screensaver class, where it has ready access to the screensaver 24 | // object's data, preferences, and so on. 25 | 26 | #import 27 | #import 28 | 29 | @interface MatrixOpenGLView : NSOpenGLView { 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /MatrixMacros.h: -------------------------------------------------------------------------------- 1 | // This file is part of Red Pill 2 | // A 3D OpenGL "Matrix" screensaver for Mac OS X 3 | // Copyright (C) 2002, 2003 mathew 4 | // 5 | // Red Pill is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | // or visit 19 | 20 | // Some useful macros and constants used in various places in the code 21 | 22 | // Random float from 0.0 to 1.0 23 | #define RANDOM_FLOAT_01 ((float)(random() % 100) / 100.0) 24 | // Random float from -1.0 to 1.0 25 | #define RANDOM_FLOAT_11 ((float)(random() % 200) / 100.0 - 1.0) 26 | /// Assorted constants 27 | 28 | // Near and far clipping planes, cm from the user's eye 29 | #define CLIP_NEAR 40.0 30 | #define CLIP_FAR 250.0 31 | 32 | // Field of view in degrees 33 | #define FIELD_OF_VIEW 45.0 34 | // Tangent of half that value, used for calculating coordinate ranges 35 | #define TAN_FOV 0.4142 36 | 37 | // Integer number of glyphs in the texture pixmap 38 | // The pixmap is an 8x8 grid, glyph 0 = top left, and should be empty space 39 | // Each square of the grid is 32x32 and contains one glyph 40 | // Not all squares need to be filled 41 | #define NUM_GLYPHS 64 42 | 43 | // Cell size in cm 44 | // Bear in mind that it needs to be visible when CLIP_FAR away, each cell holds one glyph 45 | #define CELL_SIZE 1.0 46 | 47 | // Cell spacing in strips is multiplied by this, to pull them apart a bit 48 | #define QUAD_SQUISH_FACTOR 1.02 49 | -------------------------------------------------------------------------------- /RedPill.xcodeproj/xcuserdata/meta.xcuserdatad/xcschemes/RedPill.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 53 | 54 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /MatrixTexture.h: -------------------------------------------------------------------------------- 1 | // This file is part of Red Pill 2 | // A 3D OpenGL "Matrix" screensaver for Mac OS X 3 | // Copyright (C) 2002, 2003 mathew 4 | // 5 | // Red Pill is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | // or visit 19 | 20 | #import 21 | #import 22 | #import 23 | #import 24 | #import 25 | #import "GLUtils.h" 26 | 27 | // This code encapsulates all the ugly details of loading a texture from a graphics file 28 | // into allocated memory, and converting it into the format needed by OpenGL. 29 | @interface MatrixTexture : NSObject { 30 | // Size of texture (height and width) 31 | NSSize size; 32 | 33 | // Format of texture (GL_RGB or GL_RGBA) 34 | GLenum format; 35 | 36 | // Raw data 37 | char *data; 38 | 39 | // OpenGL handle used to refer to texture 40 | GLuint texture; 41 | 42 | // View context to use for OpenGL operations 43 | NSOpenGLView *glview; 44 | 45 | // Has the texture data been successfully loaded? 46 | BOOL fileWasLoaded; 47 | 48 | // Bitmap data for glyphs 49 | NSMutableData *dataobj; 50 | } 51 | 52 | - (instancetype)initWithNSOpenGLView:(NSOpenGLView *)someview NS_DESIGNATED_INITIALIZER; 53 | 54 | // Method to load texture from a file 55 | // (kept in the application package Contents/Resources folder) 56 | - (BOOL)loadFromFile:(NSString *)filename; 57 | 58 | // Accessor method for GL texture ID 59 | @property (NS_NONATOMIC_IOSONLY, readonly) GLuint GLtexture; 60 | 61 | // Accessor method for whether the file has been loaded successfully yet 62 | @property (NS_NONATOMIC_IOSONLY, readonly) BOOL fileLoaded; 63 | @end 64 | -------------------------------------------------------------------------------- /MatrixStripParams.h: -------------------------------------------------------------------------------- 1 | // This file is part of Red Pill 2 | // A 3D OpenGL "Matrix" screensaver for Mac OS X 3 | // Copyright (C) 2002, 2003 mathew 4 | // 5 | // Red Pill is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | // or visit 19 | 20 | // The parameters which determine the animation behavior 21 | struct MatrixStripParams { 22 | GLfloat cellSize; // size of the quad containing one glyph 23 | int maxCellLife; // max lifetime of a living cell 24 | int numGlyphs; // number of glyphs available in texture 25 | int cursorChangeProbability; // percentage chance of cursor state change during drawing phase 26 | int cursorLiveProbability; // relative amounts of time the cursor spends drawing live cells, 27 | int cursorStaticProbability; // static cells, 28 | int cursorEmptyProbability; // or empty space 29 | int framesPerLivingCellChange; // how many 1/30ths of a second for each living cell to change glyph 30 | GLfloat cursorSpeed; // speed of cursor fall 31 | GLfloat maxDepth; // depth strips start at 32 | GLfloat minDepth; // depth at which strips are clipped away 33 | int maxStrips; // how many do we want? 34 | float spawnChance; // if we don't have enough stuff, what's the probability of adding more stuff 35 | // this animation frame? Changes to 1.0 after the first strip hits the front... 36 | GLfloat driftSpeed; // speed stuff drifts towards us at 37 | GLfloat aspectRatio; // we need this to work out when a strip falls off the sides of the visible area 38 | GLfloat minStartY; // 1.0 to start at top of screen, 0.0 to start at random point in top half 39 | GLfloat fogDensity; // 0 to 0.2, or you won't see anything 40 | GLfloat colorCycleSpeed; // color cycling speed 41 | GLfloat colorFallSpeed; // rate at which cycling colors fall 42 | }; 43 | -------------------------------------------------------------------------------- /MatrixPrefsWindow.h: -------------------------------------------------------------------------------- 1 | // This file is part of Red Pill 2 | // A 3D OpenGL "Matrix" screensaver for Mac OS X 3 | // Copyright (C) 2002, 2003 mathew 4 | // 5 | // Red Pill is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | // or visit 19 | 20 | #import 21 | #import 22 | #import 23 | 24 | #import "GLUtils.h" 25 | 26 | // Strings to use when saving the preferences 27 | #define STRIPS_KEY @"strips" 28 | #define VELOCITY_KEY @"velocity" 29 | #define DEPTH_KEY @"depth" 30 | #define CYCLING_KEY @"cycling" 31 | #define FALLING_KEY @"falling" 32 | #define CURSOR_KEY @"cursor" 33 | #define FOG_KEY @"fog" 34 | #define TOPSTART_KEY @"topstart" 35 | #define MAINONLY_KEY @"mainonly" 36 | #define SPOON_KEY @"spoon" 37 | 38 | // Default values for same 39 | #define STRIPS_DEFAULT @"50" 40 | #define VELOCITY_DEFAULT @"40" 41 | #define DEPTH_DEFAULT @"200" 42 | #define CYCLING_DEFAULT @"5" 43 | #define FALLING_DEFAULT @"2" 44 | #define CURSOR_DEFAULT @"10" 45 | #define FOG_DEFAULT @"15" 46 | #define TOPSTART_DEFAULT @"YES" 47 | #define TOPSTART_DEFAULT_BOOLEAN TRUE 48 | #define MAINONLY_DEFAULT @"NO" 49 | #define MAINONLY_DEFAULT_BOOLEAN FALSE 50 | #define SPOON_DEFAULT @"NO" 51 | #define SPOON_DEFAULT_BOOLEAN FALSE 52 | 53 | // Notification to send the main object 54 | #define PREFS_NOTIFICATION @"PreferencesChanged" 55 | 56 | @interface MatrixPrefsWindow : NSWindowController 57 | { 58 | IBOutlet NSSlider *strips; 59 | IBOutlet NSSlider *velocity; 60 | IBOutlet NSSlider *depth; 61 | IBOutlet NSSlider *cycling; 62 | IBOutlet NSSlider *falling; 63 | IBOutlet NSSlider *cursor; 64 | IBOutlet NSSlider *fog; 65 | IBOutlet NSButton *topstart; 66 | IBOutlet NSButton *mainonly; 67 | IBOutlet NSButton *spoon; 68 | IBOutlet NSTextField *version; 69 | } 70 | 71 | - (IBAction)cancel:(id)sender; 72 | - (IBAction)ok:(id)sender; 73 | - (IBAction)about:(id)sender; 74 | - (IBAction)reset:(id)sender; 75 | - (IBAction)spoonclick:(id)sender; 76 | @end 77 | -------------------------------------------------------------------------------- /MatrixView.h: -------------------------------------------------------------------------------- 1 | // This file is part of Red Pill 2 | // A 3D OpenGL "Matrix" screensaver for Mac OS X 3 | // Copyright (C) 2002, 2003 mathew 4 | // 5 | // Red Pill is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | // or visit 19 | 20 | #import 21 | #import 22 | #import 23 | #import "MatrixOpenGLView.h" 24 | #import "MatrixStripParams.h" 25 | #import "MatrixStrip.h" 26 | #import "MatrixTexture.h" 27 | #import "MatrixPrefsWindow.h" 28 | #import "GLUtils.h" 29 | 30 | // This is the main control object for the screensaver. 31 | // It inherits from and implements the ScreenSaverView API. 32 | @interface MatrixView : ScreenSaverView 33 | { 34 | // The NSOpenGLView subclass where we draw the graphics 35 | MatrixOpenGLView *glview; 36 | 37 | // Flag to indicate GL has been initialized 38 | BOOL didGLinit; 39 | 40 | // Flag indicating whether this screensaver process is drawing on the main screen, 41 | // or on a second monitor 42 | BOOL isMainScreen; 43 | // Similar flag for preference checkbox 44 | BOOL mainScreenOnly; 45 | // and for whether we're running in the preview box 46 | BOOL isPreview; 47 | 48 | // The screen aspect ratio, stored and used to compute the ranges of X and Y allowed at given depth 49 | GLfloat aspectRatio; 50 | 51 | GLfloat x; 52 | GLfloat y; 53 | 54 | // The texture containing the glyphs 55 | MatrixTexture *matrixGlyphs; 56 | 57 | // Array of strips of Matrix 58 | NSMutableArray *matrixStrips; 59 | 60 | // Parameters for the animation 61 | struct MatrixStripParams saverParams; 62 | 63 | // Preferences window 64 | MatrixPrefsWindow *prefsWindow; 65 | } 66 | 67 | // Handle a change of preferences/configuration 68 | - (void)loadDefaults:(NSNotification *)n; 69 | 70 | // Method to initialize OpenGL 71 | - (void)initGL; 72 | 73 | // Method to set up viewport and projection 74 | - (void)resizeGL:(int)width :(int)height; 75 | 76 | // Method to actually draw stuff on the screen 77 | - (void)drawGL; 78 | @end 79 | -------------------------------------------------------------------------------- /MatrixStrip.h: -------------------------------------------------------------------------------- 1 | // This file is part of Red Pill 2 | // A 3D OpenGL "Matrix" screensaver for Mac OS X 3 | // Copyright (C) 2002, 2003 mathew 4 | // 5 | // Red Pill is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | // or visit 19 | 20 | #import 21 | #import 22 | #import "GLUtils.h" 23 | #import "MatrixStripParams.h" 24 | 25 | // MatrixStrip implements a single "particle" object consisting of a strip of 26 | // animated "Matrix code" style glyphs 27 | @interface MatrixStrip : NSObject { 28 | // Internal state variables 29 | // Location of strip 30 | GLfloat myX; 31 | GLfloat myY; 32 | GLfloat myZ; 33 | // Position of the cursor which writes/erases glyphs, as a cell number 34 | int cursorPos; 35 | // Offset upwards from 0.0 to 1.0 of a cell, to allow for motion slower than 1 cell per animation frame 36 | GLfloat cursorOffset; 37 | // State the cursor writes when writing 38 | int cursorState; 39 | // Whether the cursor is drawing or erasing 40 | bool cursorDrawing; 41 | // The cursor glyph 42 | int cursorGlyph; 43 | // Number of cells in strip 44 | int stripSize; 45 | // Array of cell states 46 | int *cellState; 47 | // Array of glyphs in cells 48 | int *cellContents; 49 | // Array of texture coordinates for OpenGL 50 | GLfloat *textureArray; 51 | // Array of quad vertices for OpenGL 52 | GLfloat *quadArray; 53 | // Array of color vertices for OpenGL 54 | GLfloat *colorArray; 55 | // The tweakable parameters which alter the behavior of the strip 56 | struct MatrixStripParams stripParams; 57 | // Internal counter used to reduce the animation speed of living cells 58 | int framecounter; 59 | // Internal float used to animate the colors 60 | GLfloat startColor; 61 | // Ints used to store the first and last visible cells that need to be drawn 62 | int firstVisibleCell; 63 | int lastVisibleCell; 64 | } 65 | 66 | // Initialize with top left corner at given position 67 | - (instancetype) initWithCells:(int)cells x:(GLfloat)x y:(GLfloat)y z:(GLfloat)z params:(struct MatrixStripParams)params NS_DESIGNATED_INITIALIZER; 68 | 69 | // Return my z position 70 | @property (NS_NONATOMIC_IOSONLY, readonly) GLfloat z; 71 | 72 | // Pick a random cursor drawing state 73 | - (void) randomizeCursorState; 74 | 75 | // Pick a random glyph for the cursor 76 | - (void) randomizeCursorGlyph; 77 | 78 | // Pick a random cursor drawing state different from the current one 79 | // i.e. if drawing static, either switch to drawing live or drawing empty 80 | - (void) randomizeCursorState:(int)current; 81 | 82 | // Compute the entire array of quad vertices, for a strip with the given number of cells (excluding the cursor) 83 | - (void) computeQuadVertices:(int)cells x:(GLfloat)x y:(GLfloat)y z:(GLfloat)z; 84 | 85 | // Set up the initial state of the color vertices 86 | - (void) initializeColorVertices:(int)maxcell; 87 | 88 | // Compute the array of color vertices (excluding the cursor) 89 | - (void) computeColorVertices; 90 | 91 | // Set up the initial state of the color vertices 92 | - (void) initializeTextureVertices:(int)maxcell; 93 | 94 | // Compute the texture coordinates for a single cell of the texture coord array 95 | - (void) computeTextureVertices:(int)cellnum; 96 | 97 | // Compute quad, color and texture vertices for the cursor, bumped up by given offset 98 | - (void) computeCursor:(int)cell offset:(GLfloat)offset; 99 | 100 | // Issue GL calls to draw yourself! 101 | // Assumes context has been set up appropriately, arrays have been enabled, etc. 102 | // (Uses GL_VERTEX_ARRAY, GL_COLOR_ARRAY and GL_TEXTURE_COORD_ARRAY) 103 | - (void) drawSelf; 104 | 105 | // Animate yourself, return true if you've finished doing anything interesting 106 | @property (NS_NONATOMIC_IOSONLY, readonly) BOOL animateSelfIsComplete; 107 | @end 108 | -------------------------------------------------------------------------------- /MatrixPrefsWindow.m: -------------------------------------------------------------------------------- 1 | // This file is part of Red Pill 2 | // A 3D OpenGL "Matrix" screensaver for Mac OS X 3 | // Copyright (C) 2002, 2003 mathew 4 | // 5 | // Red Pill is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | // or visit 19 | 20 | #import "MatrixPrefsWindow.h" 21 | 22 | @implementation MatrixPrefsWindow 23 | 24 | - (NSWindow *)window 25 | { 26 | // Initialize parent 27 | NSWindow *w = [super window]; 28 | // Work out what our defaults are called 29 | NSString *identifier = [[NSBundle bundleForClass:[self class]] bundleIdentifier]; 30 | if(identifier == nil) { 31 | LogError("window", "Trying to load preferences but identifier is nil."); 32 | return w; 33 | } 34 | // Load defaults 35 | ScreenSaverDefaults *defaults = [ScreenSaverDefaults defaultsForModuleWithName:identifier]; 36 | // Initialize the UI elements 37 | [strips setFloatValue:[defaults floatForKey:STRIPS_KEY]]; 38 | [velocity setFloatValue:[defaults floatForKey:VELOCITY_KEY]]; 39 | [depth setFloatValue:[defaults floatForKey:DEPTH_KEY]]; 40 | [cycling setFloatValue:[defaults floatForKey:CYCLING_KEY]]; 41 | [falling setFloatValue:[defaults floatForKey:FALLING_KEY]]; 42 | [cursor setFloatValue:[defaults floatForKey:CURSOR_KEY]]; 43 | [fog setFloatValue:[defaults floatForKey:FOG_KEY]]; 44 | [topstart setState:[defaults boolForKey:TOPSTART_KEY]]; 45 | [mainonly setState:[defaults boolForKey:MAINONLY_KEY]]; 46 | // Find out version from bundle 47 | NSBundle *bundle = [NSBundle bundleForClass:[self class]]; 48 | NSMutableString *versionString = [[NSMutableString alloc] 49 | initWithString:[bundle infoDictionary][@"CFBundleShortVersionString"]]; 50 | [version setStringValue:versionString]; 51 | [spoon setState:FALSE]; 52 | // Hide spoon mode most of the time 53 | if ((random() % 5) != 3) { 54 | [spoon setTransparent:TRUE]; 55 | } else { 56 | [spoon setTransparent:FALSE]; 57 | } 58 | return w; 59 | } 60 | 61 | // Reset the values of the sliders to their defaults 62 | - (IBAction)reset:(id)sender 63 | { 64 | [strips setFloatValue:[STRIPS_DEFAULT floatValue]]; 65 | [velocity setFloatValue:[VELOCITY_DEFAULT floatValue]]; 66 | [depth setFloatValue:[DEPTH_DEFAULT floatValue]]; 67 | [cycling setFloatValue:[CYCLING_DEFAULT floatValue]]; 68 | [falling setFloatValue:[FALLING_DEFAULT floatValue]]; 69 | [cursor setFloatValue:[CURSOR_DEFAULT floatValue]]; 70 | [fog setFloatValue:[FOG_DEFAULT floatValue]]; 71 | [topstart setState:TOPSTART_DEFAULT_BOOLEAN]; 72 | [mainonly setState:MAINONLY_DEFAULT_BOOLEAN]; 73 | } 74 | 75 | // The About button takes them to a web site 76 | - (IBAction)about:(id)sender 77 | { 78 | NSAppleScript *go = [[NSAppleScript alloc] 79 | initWithSource:@"open location \"http://meta.ath0.com/redpill/\""]; 80 | [go executeAndReturnError:nil]; 81 | } 82 | 83 | - (IBAction)cancel:(id)sender 84 | { 85 | [NSApp endSheet:[self window]]; 86 | } 87 | 88 | - (IBAction)spoonclick:(id)sender 89 | { 90 | [spoon setTransparent:FALSE]; 91 | } 92 | 93 | - (IBAction)ok:(id)sender 94 | { 95 | // Work out what our defaults are called 96 | NSString *identifier = [[NSBundle bundleForClass:[self class]] bundleIdentifier]; 97 | if(identifier == nil) { 98 | LogError("ok", "Trying to save preferences but identifier is nil."); 99 | [NSApp endSheet:[self window]]; 100 | return; 101 | } 102 | // Load defaults 103 | ScreenSaverDefaults *defaults = [ScreenSaverDefaults defaultsForModuleWithName:identifier]; 104 | // Set values based on new positions and states of UI elements 105 | [defaults setFloat:[strips floatValue] forKey:STRIPS_KEY]; 106 | [defaults setFloat:[velocity floatValue] forKey:VELOCITY_KEY]; 107 | [defaults setFloat:[depth floatValue] forKey:DEPTH_KEY]; 108 | [defaults setFloat:[cycling floatValue] forKey:CYCLING_KEY]; 109 | [defaults setFloat:[falling floatValue] forKey:FALLING_KEY]; 110 | [defaults setFloat:[cursor floatValue] forKey:CURSOR_KEY]; 111 | [defaults setFloat:[fog floatValue] forKey:FOG_KEY]; 112 | [defaults setBool:[topstart state] forKey:TOPSTART_KEY]; 113 | [defaults setBool:[mainonly state] forKey:MAINONLY_KEY]; 114 | // Plug web site if user selects spoon mode 115 | if ([spoon state] == TRUE) { 116 | NSRunAlertPanel(@"Realize", @"There is no spoon.", @"OK", nil, nil); 117 | [self about:sender]; 118 | } 119 | // Update to disk 120 | [defaults synchronize]; 121 | 122 | // Tell the main scrensaver loop to reload the preferences from us 123 | [[NSNotificationCenter defaultCenter] postNotificationName:PREFS_NOTIFICATION object:nil]; 124 | 125 | [NSApp endSheet:[self window]]; 126 | } 127 | @end 128 | -------------------------------------------------------------------------------- /MatrixTexture.m: -------------------------------------------------------------------------------- 1 | // This file is part of Red Pill 2 | // A 3D OpenGL "Matrix" screensaver for Mac OS X 3 | // Copyright (C) 2002-2005 mathew 4 | // 5 | // Red Pill is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | // or visit 19 | 20 | #import "MatrixTexture.h" 21 | 22 | @interface MatrixTexture (InternalMethods) 23 | - (BOOL)loadBitmap:(NSString *)filename; 24 | @end 25 | 26 | @implementation MatrixTexture : NSObject 27 | 28 | void myxor(char *, size_t); 29 | 30 | // Initializer needs to know what GL view the texture will be used in. 31 | - (instancetype)initWithNSOpenGLView:(NSOpenGLView *)someview 32 | { 33 | if (self = [super init]) { 34 | glview = someview; 35 | fileWasLoaded = FALSE; 36 | } 37 | if (glview == nil) { 38 | LogError("initWithNSOpenGLView", "initWithNSOpenGLView was passed a nil NSOpenGLView. This should not happen."); 39 | } 40 | return self; 41 | } 42 | 43 | - (void) dealloc 44 | { 45 | // Unload the OpenGL texture and deallocate our memory 46 | [[glview openGLContext] makeCurrentContext]; 47 | if (texture != 0) { 48 | glDeleteTextures(1, &texture); 49 | CheckGLError("dealloc","glDeleteTextures"); 50 | } 51 | if (data) { free(data); } 52 | } 53 | 54 | - (GLuint) GLtexture 55 | { 56 | return texture; 57 | } 58 | 59 | - (BOOL) fileLoaded 60 | { 61 | return fileWasLoaded; 62 | } 63 | 64 | // Load bitmap data from a file. 65 | - (BOOL) loadBitmap:(NSString *)filename 66 | { 67 | NSBitmapImageRep *img; 68 | int depth, rowsize; 69 | unsigned char *imgdata; 70 | int row, destrow; 71 | 72 | // Load image file 73 | img = [NSBitmapImageRep imageRepWithContentsOfFile:filename]; 74 | if (img == nil) { 75 | LogError("loadBitmap", "imageRepWithContentsOfFile returned nil. Image file is broken?"); 76 | return FALSE; 77 | } 78 | 79 | // Work out format 80 | depth = [img samplesPerPixel]; 81 | rowsize = [img bytesPerRow]; 82 | if(depth == 3) { 83 | // 24 bit RGB 84 | format = GL_RGB; 85 | } else if(depth == 4) { 86 | // 24 bit RGB plus alpha 87 | format = GL_RGBA; 88 | } else { 89 | LogError("loadBitmap", "unrecognized bitmap format."); 90 | return FALSE; 91 | } 92 | size.width = [img pixelsWide]; 93 | size.height = [img pixelsHigh]; 94 | // Allocate space for the GL bitmap data 95 | data = calloc(rowsize * size.height, 1); 96 | if (data == NULL) { 97 | LogError("loadBitmap", "failed to allocate space for the bitmap."); 98 | return FALSE; 99 | } 100 | // Copy the image into the GL bitmap, 101 | // flipping the rows top to bottom 102 | imgdata = [img bitmapData]; 103 | destrow = 0; 104 | for(row = size.height - 1; row >= 0; row--, destrow++ ) { 105 | // Copy the entire row in one shot 106 | memcpy(data + (destrow * rowsize), imgdata + (row * rowsize), rowsize ); 107 | } 108 | fileWasLoaded = TRUE; 109 | return TRUE; 110 | } 111 | 112 | // Load bitmap data from a file, using the above method, then create an OpenGL texture from it. 113 | - (BOOL)loadFromFile:(NSString *)filename 114 | { 115 | NSString *filespec; 116 | 117 | // Work out full path to image file 118 | filespec = [NSString stringWithFormat:@"%@/%@", 119 | [[NSBundle bundleForClass:[self class]] resourcePath ], filename ]; 120 | // See if it exists 121 | NSFileManager *fileman = [NSFileManager defaultManager]; 122 | if (![fileman fileExistsAtPath:filespec]) { 123 | return FALSE; 124 | } 125 | if (![self loadBitmap:filespec]) { 126 | LogError("loadFromFile", "loadFromFile failed to load bitmap."); 127 | return FALSE; 128 | } 129 | if (format != GL_RGB) { 130 | LogError("loadFromFile", "Warning: Bitmaps not RGB!"); 131 | } 132 | // Now create an OpenGL texture 133 | [[glview openGLContext] makeCurrentContext]; 134 | if (texture == 0) { 135 | // Find free texture slot 136 | glGenTextures(1, &texture); 137 | CheckGLError("loadFromFile","glGenTextures"); 138 | } 139 | glBindTexture(GL_TEXTURE_2D, texture); 140 | CheckGLError("loadFromFile","glBindTexture"); 141 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 142 | CheckGLError("loadFromFile","glTexParameteri"); 143 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 144 | CheckGLError("loadFromFile","glTexParameteri"); 145 | // Define the texture from the bitmap data 146 | // We want an INTENSITY texture where alpha = intensity of pixel 147 | // as we're modulating quads into letters of whatever color 148 | // and the source image is colored letters on black 149 | glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, (GLsizei) size.width, (GLsizei) size.height, 0, format, GL_UNSIGNED_BYTE, data); 150 | CheckGLError("loadFromFile","glTexImage2D"); 151 | return TRUE; 152 | } 153 | 154 | @end 155 | -------------------------------------------------------------------------------- /RedPill.xcodeproj/meta.pbxuser: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | 089C1669FE841209C02AAC07 /* Project object */ = { 4 | activeBuildConfigurationName = Debug; 5 | activeTarget = 8D255AC50486D3F9007BF209 /* RedPill */; 6 | addToTargets = ( 7 | 8D255AC50486D3F9007BF209 /* RedPill */, 8 | ); 9 | codeSenseManager = C0F75DD514649D3000BC0085 /* Code sense */; 10 | perUserDictionary = { 11 | PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { 12 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; 13 | PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; 14 | PBXFileTableDataSourceColumnWidthsKey = ( 15 | 20, 16 | 456, 17 | 20, 18 | 48, 19 | 43, 20 | 43, 21 | 20, 22 | ); 23 | PBXFileTableDataSourceColumnsKey = ( 24 | PBXFileDataSource_FiletypeID, 25 | PBXFileDataSource_Filename_ColumnID, 26 | PBXFileDataSource_Built_ColumnID, 27 | PBXFileDataSource_ObjectSize_ColumnID, 28 | PBXFileDataSource_Errors_ColumnID, 29 | PBXFileDataSource_Warnings_ColumnID, 30 | PBXFileDataSource_Target_ColumnID, 31 | ); 32 | }; 33 | PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = { 34 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; 35 | PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; 36 | PBXFileTableDataSourceColumnWidthsKey = ( 37 | 20, 38 | 408, 39 | 60, 40 | 20, 41 | 48.16259765625, 42 | 43, 43 | 43, 44 | ); 45 | PBXFileTableDataSourceColumnsKey = ( 46 | PBXFileDataSource_FiletypeID, 47 | PBXFileDataSource_Filename_ColumnID, 48 | PBXTargetDataSource_PrimaryAttribute, 49 | PBXFileDataSource_Built_ColumnID, 50 | PBXFileDataSource_ObjectSize_ColumnID, 51 | PBXFileDataSource_Errors_ColumnID, 52 | PBXFileDataSource_Warnings_ColumnID, 53 | ); 54 | }; 55 | PBXPerProjectTemplateStateSaveDate = 342139164; 56 | PBXWorkspaceStateSaveDate = 342139164; 57 | }; 58 | perUserProjectItems = { 59 | C0F75E201464A08900BC0085 /* PBXTextBookmark */ = C0F75E201464A08900BC0085 /* PBXTextBookmark */; 60 | C0F75E211464A08900BC0085 /* PBXTextBookmark */ = C0F75E211464A08900BC0085 /* PBXTextBookmark */; 61 | C0F75E4B1464A62F00BC0085 /* PBXTextBookmark */ = C0F75E4B1464A62F00BC0085 /* PBXTextBookmark */; 62 | C0F75E4C1464A62F00BC0085 /* PBXTextBookmark */ = C0F75E4C1464A62F00BC0085 /* PBXTextBookmark */; 63 | C0F75E4D1464A62F00BC0085 /* PBXTextBookmark */ = C0F75E4D1464A62F00BC0085 /* PBXTextBookmark */; 64 | C0F75E4E1464A62F00BC0085 /* PBXTextBookmark */ = C0F75E4E1464A62F00BC0085 /* PBXTextBookmark */; 65 | C0F75E4F1464A62F00BC0085 /* PBXTextBookmark */ = C0F75E4F1464A62F00BC0085 /* PBXTextBookmark */; 66 | C0F75E501464A62F00BC0085 /* PBXTextBookmark */ = C0F75E501464A62F00BC0085 /* PBXTextBookmark */; 67 | C0F75E511464A62F00BC0085 /* PBXTextBookmark */ = C0F75E511464A62F00BC0085 /* PBXTextBookmark */; 68 | C0F75E521464A62F00BC0085 /* PBXTextBookmark */ = C0F75E521464A62F00BC0085 /* PBXTextBookmark */; 69 | }; 70 | sourceControlManager = C0F75DD414649D3000BC0085 /* Source Control */; 71 | userBuildSettings = { 72 | }; 73 | }; 74 | 089C167EFE841241C02AAC07 /* English */ = { 75 | uiCtxt = { 76 | sepNavIntBoundsRect = "{{0, 0}, {626, 422}}"; 77 | sepNavSelRange = "{119, 0}"; 78 | sepNavVisRange = "{0, 119}"; 79 | }; 80 | }; 81 | 32DBCFA80370C50100C91783 /* RedPill_Prefix.pch */ = { 82 | uiCtxt = { 83 | sepNavIntBoundsRect = "{{0, 0}, {626, 422}}"; 84 | sepNavSelRange = "{0, 0}"; 85 | sepNavVisRange = "{0, 186}"; 86 | }; 87 | }; 88 | 8D255AC50486D3F9007BF209 /* RedPill */ = { 89 | activeExec = 0; 90 | }; 91 | C0F75DD414649D3000BC0085 /* Source Control */ = { 92 | isa = PBXSourceControlManager; 93 | fallbackIsa = XCSourceControlManager; 94 | isSCMEnabled = 0; 95 | scmConfiguration = { 96 | repositoryNamesForRoots = { 97 | "" = ""; 98 | }; 99 | }; 100 | }; 101 | C0F75DD514649D3000BC0085 /* Code sense */ = { 102 | isa = PBXCodeSenseManager; 103 | indexTemplatePath = ""; 104 | }; 105 | C0F75DEC14649DBA00BC0085 /* MatrixMacros.h */ = { 106 | uiCtxt = { 107 | sepNavIntBoundsRect = "{{0, 0}, {634, 650}}"; 108 | sepNavSelRange = "{957, 187}"; 109 | sepNavVisRange = "{0, 1420}"; 110 | }; 111 | }; 112 | C0F75DF114649DBA00BC0085 /* MatrixStrip.h */ = { 113 | uiCtxt = { 114 | sepNavIntBoundsRect = "{{0, 0}, {634, 1508}}"; 115 | sepNavSelRange = "{0, 0}"; 116 | sepNavVisRange = "{2682, 1337}"; 117 | }; 118 | }; 119 | C0F75DF214649DBA00BC0085 /* MatrixStrip.m */ = { 120 | uiCtxt = { 121 | sepNavIntBoundsRect = "{{0, 0}, {634, 7059}}"; 122 | sepNavSelRange = "{0, 0}"; 123 | sepNavVisRange = "{6562, 1090}"; 124 | }; 125 | }; 126 | C0F75DF314649DBA00BC0085 /* MatrixStripParams.h */ = { 127 | uiCtxt = { 128 | sepNavIntBoundsRect = "{{0, 0}, {634, 624}}"; 129 | sepNavSelRange = "{0, 0}"; 130 | sepNavVisRange = "{586, 1773}"; 131 | }; 132 | }; 133 | C0F75DF514649DBA00BC0085 /* MatrixTexture.m */ = { 134 | uiCtxt = { 135 | sepNavIntBoundsRect = "{{0, 0}, {634, 2106}}"; 136 | sepNavSelRange = "{0, 0}"; 137 | sepNavVisRange = "{3600, 1375}"; 138 | }; 139 | }; 140 | C0F75DF614649DBA00BC0085 /* MatrixView.h */ = { 141 | uiCtxt = { 142 | sepNavIntBoundsRect = "{{0, 0}, {634, 1040}}"; 143 | sepNavSelRange = "{0, 0}"; 144 | sepNavVisRange = "{1647, 808}"; 145 | }; 146 | }; 147 | C0F75DF714649DBA00BC0085 /* MatrixView.m */ = { 148 | uiCtxt = { 149 | sepNavIntBoundsRect = "{{0, 0}, {634, 6825}}"; 150 | sepNavSelRange = "{10274, 15}"; 151 | sepNavVisRange = "{9955, 1553}"; 152 | }; 153 | }; 154 | C0F75E201464A08900BC0085 /* PBXTextBookmark */ = { 155 | isa = PBXTextBookmark; 156 | fRef = 089C167EFE841241C02AAC07 /* English */; 157 | name = "InfoPlist.strings: 4"; 158 | rLen = 0; 159 | rLoc = 119; 160 | rType = 0; 161 | vrLen = 119; 162 | vrLoc = 0; 163 | }; 164 | C0F75E211464A08900BC0085 /* PBXTextBookmark */ = { 165 | isa = PBXTextBookmark; 166 | fRef = 32DBCFA80370C50100C91783 /* RedPill_Prefix.pch */; 167 | name = "RedPill_Prefix.pch: 1"; 168 | rLen = 0; 169 | rLoc = 0; 170 | rType = 0; 171 | vrLen = 186; 172 | vrLoc = 0; 173 | }; 174 | C0F75E4B1464A62F00BC0085 /* PBXTextBookmark */ = { 175 | isa = PBXTextBookmark; 176 | fRef = C0F75DF114649DBA00BC0085 /* MatrixStrip.h */; 177 | name = "MatrixStrip.h: 1"; 178 | rLen = 0; 179 | rLoc = 0; 180 | rType = 0; 181 | vrLen = 1337; 182 | vrLoc = 2682; 183 | }; 184 | C0F75E4C1464A62F00BC0085 /* PBXTextBookmark */ = { 185 | isa = PBXTextBookmark; 186 | fRef = C0F75DF214649DBA00BC0085 /* MatrixStrip.m */; 187 | name = "MatrixStrip.m: 1"; 188 | rLen = 0; 189 | rLoc = 0; 190 | rType = 0; 191 | vrLen = 1090; 192 | vrLoc = 6562; 193 | }; 194 | C0F75E4D1464A62F00BC0085 /* PBXTextBookmark */ = { 195 | isa = PBXTextBookmark; 196 | fRef = C0F75DF314649DBA00BC0085 /* MatrixStripParams.h */; 197 | name = "MatrixStripParams.h: 1"; 198 | rLen = 0; 199 | rLoc = 0; 200 | rType = 0; 201 | vrLen = 1773; 202 | vrLoc = 586; 203 | }; 204 | C0F75E4E1464A62F00BC0085 /* PBXTextBookmark */ = { 205 | isa = PBXTextBookmark; 206 | fRef = C0F75DF514649DBA00BC0085 /* MatrixTexture.m */; 207 | name = "MatrixTexture.m: 1"; 208 | rLen = 0; 209 | rLoc = 0; 210 | rType = 0; 211 | vrLen = 1375; 212 | vrLoc = 3600; 213 | }; 214 | C0F75E4F1464A62F00BC0085 /* PBXTextBookmark */ = { 215 | isa = PBXTextBookmark; 216 | fRef = C0F75DF614649DBA00BC0085 /* MatrixView.h */; 217 | name = "MatrixView.h: 1"; 218 | rLen = 0; 219 | rLoc = 0; 220 | rType = 0; 221 | vrLen = 808; 222 | vrLoc = 1647; 223 | }; 224 | C0F75E501464A62F00BC0085 /* PBXTextBookmark */ = { 225 | isa = PBXTextBookmark; 226 | fRef = C0F75DF714649DBA00BC0085 /* MatrixView.m */; 227 | name = "MatrixView.m: 290"; 228 | rLen = 15; 229 | rLoc = 10274; 230 | rType = 0; 231 | vrLen = 1553; 232 | vrLoc = 9955; 233 | }; 234 | C0F75E511464A62F00BC0085 /* PBXTextBookmark */ = { 235 | isa = PBXTextBookmark; 236 | fRef = C0F75DEC14649DBA00BC0085 /* MatrixMacros.h */; 237 | rLen = 1; 238 | rLoc = 22; 239 | rType = 1; 240 | }; 241 | C0F75E521464A62F00BC0085 /* PBXTextBookmark */ = { 242 | isa = PBXTextBookmark; 243 | fRef = C0F75DEC14649DBA00BC0085 /* MatrixMacros.h */; 244 | name = "MatrixMacros.h: 22"; 245 | rLen = 187; 246 | rLoc = 957; 247 | rType = 0; 248 | vrLen = 1420; 249 | vrLoc = 0; 250 | }; 251 | } 252 | -------------------------------------------------------------------------------- /MatrixView.m: -------------------------------------------------------------------------------- 1 | // This file is part of Red Pill 2 | // A 3D OpenGL "Matrix" screensaver for Mac OS X 3 | // Copyright (C) 2002, 2003 mathew 4 | // 5 | // Red Pill is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | // or visit 19 | 20 | #import "MatrixView.h" 21 | #import 22 | #import 23 | #import "MatrixMacros.h" 24 | #import "MatrixStripParams.h" 25 | 26 | @implementation MatrixView 27 | 28 | /// SECTION ONE 29 | /// Core ScreenSaverView method implementations 30 | 31 | // Override setFrameSize to resize the GL universe too. 32 | - (void)setFrameSize:(NSSize)newSize 33 | { 34 | [super setFrameSize:newSize]; 35 | if (glview != nil) { 36 | [glview setFrameSize:newSize]; 37 | [self resizeGL:(int)newSize.width :(int)newSize.height]; 38 | } 39 | } 40 | 41 | // Constructor to initialize a screensaver in the specified rectangular frame. 42 | // The frame may be a full screen, or a preview window. 43 | - (instancetype)initWithFrame:(NSRect)frame isPreview:(BOOL)previewmode 44 | { 45 | // Note that double buffering makes performance worse and doesn't improve display quality, 46 | // so we don't demand it 47 | NSOpenGLPixelFormatAttribute attributes[] = { 48 | NSOpenGLPFAColorSize, 16, 49 | NSOpenGLPFAAlphaSize, 8, 50 | (NSOpenGLPixelFormatAttribute)0}; 51 | NSOpenGLPixelFormat *pixformat; 52 | 53 | isPreview = previewmode; 54 | // Initialize the superclass to set up the environment for the screensaver 55 | self = [super initWithFrame:frame isPreview:isPreview]; 56 | if (self == nil) { 57 | LogError("initWithFrame", "Failed to initialize screensaver environment. Not my fault."); 58 | return nil; 59 | } 60 | 61 | // Work out what our defaults are called 62 | NSBundle *bundle = [NSBundle bundleForClass:[self class]]; 63 | NSString *identifier = [bundle bundleIdentifier]; 64 | if(identifier == nil) { 65 | LogError("initWithFrame", "Trying to initialize preferences but identifier is nil!"); 66 | return nil; 67 | } 68 | ScreenSaverDefaults *defaults = [ScreenSaverDefaults defaultsForModuleWithName:identifier]; 69 | // Create and register an array of "default defaults" 70 | // Note that since the screensaver parameters are mostly between 0 and something < 1 internally, 71 | // and UI sliders only have a resolution of 0.1, we multiply 'em all by 100, so 0.15 becomes 15. 72 | NSDictionary *defdefs = @{STRIPS_KEY: STRIPS_DEFAULT, 73 | VELOCITY_KEY: VELOCITY_DEFAULT, 74 | DEPTH_KEY: DEPTH_DEFAULT, 75 | CYCLING_KEY: CYCLING_DEFAULT, 76 | FALLING_KEY: FALLING_DEFAULT, 77 | CURSOR_KEY: CURSOR_DEFAULT, 78 | FOG_KEY: FOG_DEFAULT, 79 | TOPSTART_KEY: TOPSTART_DEFAULT, 80 | MAINONLY_KEY: MAINONLY_DEFAULT, 81 | SPOON_KEY: SPOON_DEFAULT}; 82 | [defaults registerDefaults:defdefs]; 83 | // Now load either those defaults, or the user's prior choice of preferences 84 | [self loadDefaults:nil]; 85 | 86 | // Work out if we're running on the main display 87 | // This lets us offer a "run on main screen only" option for when OpenGL doesn't like running two monitors 88 | isMainScreen = ((frame.origin.x == 0 && frame.origin.y == 0) || isPreview); 89 | // If we're running in preview mode, we need to set up a notification so the preferences dialog 90 | // can tell us when we need to reload our parameters to show the changes. 91 | // Note that the notification center should always be set up, otherwise it's possible to cause 92 | // race conditions that result in a crash by clicking buttons quickly and repeatedly. 93 | [[NSNotificationCenter defaultCenter] 94 | addObserver:self 95 | selector:@selector(loadDefaults:) 96 | name:PREFS_NOTIFICATION 97 | object:nil]; 98 | 99 | // Create pixel format 100 | pixformat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; 101 | if(!pixformat) { 102 | LogError("initWithFrame", "Failed to create a suitable pixel format. Your graphics card can't cope with this screensaver, sorry."); 103 | return nil; 104 | } 105 | 106 | // Create the GL context 107 | // QUERY: Why NSZeroRect? Why not frame? I don't know, perhaps someone can tell me... 108 | glview = [[MatrixOpenGLView alloc] initWithFrame:NSZeroRect pixelFormat:pixformat]; 109 | if (glview == nil) { 110 | LogError("initWithFrame", "Failed to initialize OpenGL. Not my fault."); 111 | return nil; 112 | } 113 | // We do the actual glFoo initialization calls later 114 | didGLinit = FALSE; 115 | // Make the GL context a subview of us 116 | [self addSubview:glview]; 117 | // Now we can release our handle on it 118 | // Set the animation speed 119 | [self setAnimationTimeInterval:1/30.0]; 120 | // Initialize the parameters which aren't editable in the dialog box. 121 | // The idea is to parameterize everything in advance, so that you can 122 | // change what's editable in the dialog without too much pain. 123 | saverParams.cellSize = 2.0; 124 | saverParams.maxCellLife = 120; 125 | saverParams.numGlyphs = NUM_GLYPHS; 126 | saverParams.cursorChangeProbability = 20; 127 | saverParams.cursorLiveProbability = 30; 128 | saverParams.cursorStaticProbability = 30; 129 | saverParams.cursorEmptyProbability = 10; 130 | saverParams.framesPerLivingCellChange = 3; 131 | saverParams.minDepth = CLIP_NEAR; 132 | saverParams.spawnChance = 0.2; 133 | return self; 134 | } 135 | 136 | // Handle a change of preferences/configuration 137 | - (void)loadDefaults:(NSNotification *) n 138 | { 139 | // Work out what our defaults are called 140 | NSString *identifier = [[NSBundle bundleForClass:[self class]] bundleIdentifier]; 141 | if(identifier == nil) { 142 | LogError("initWithFrame", "Trying to load preferences but identifier is nil."); 143 | return; 144 | } 145 | // Load defaults 146 | ScreenSaverDefaults *defaults = [ScreenSaverDefaults defaultsForModuleWithName:identifier]; 147 | // Scale the values appropriately and set the saver parameters 148 | saverParams.maxStrips = [defaults floatForKey:STRIPS_KEY]; 149 | saverParams.driftSpeed = [defaults floatForKey:VELOCITY_KEY] / 100.0; 150 | saverParams.maxDepth = [defaults floatForKey:DEPTH_KEY]; 151 | saverParams.colorCycleSpeed = [defaults floatForKey:CYCLING_KEY] / 100.0; 152 | saverParams.colorFallSpeed = [defaults floatForKey:FALLING_KEY] / 100.0; 153 | saverParams.cursorSpeed = [defaults floatForKey:CURSOR_KEY] / 100.0; 154 | saverParams.fogDensity = [defaults floatForKey:FOG_KEY] / 100.0; 155 | saverParams.minStartY = ([defaults boolForKey:TOPSTART_KEY] ? 1.0 : 0.0); 156 | mainScreenOnly = ([defaults boolForKey:MAINONLY_KEY] ? 1 : 0); 157 | // Check for main screen only and this isn't main screen 158 | if (mainScreenOnly && !isMainScreen) { 159 | return; 160 | } 161 | // If fog value is now zero, disable fog 162 | if (glview == nil) { 163 | // Oops, nothing we can do 164 | return; 165 | } 166 | [[glview openGLContext] makeCurrentContext]; 167 | if (saverParams.fogDensity == 0.0) { 168 | glDisable(GL_FOG); 169 | CheckGLError("loadDefaults","glDisable(GL_FOG)"); 170 | } else { 171 | glEnable(GL_FOG); 172 | CheckGLError("loadDefaults","glEnable(GL_FOG)"); 173 | } 174 | } 175 | 176 | - (void)startAnimation 177 | { 178 | // Anything to do? 179 | if (mainScreenOnly && !isMainScreen) { 180 | return; 181 | } 182 | 183 | if (glview == nil) { 184 | LogError("startAnimation", "OS called startAnimation before NSOpenGLView initialized. This should not happen."); 185 | return; 186 | } 187 | // Clear the screen to black, so that the screensaver fades to black 188 | [[glview openGLContext] makeCurrentContext]; 189 | glClearColor(0.0, 0.0, 0.0, 0.0); 190 | CheckGLError("startAnimation","glClearColor(0.0, 0.0, 0.0, 0.0)"); 191 | glClear(GL_COLOR_BUFFER_BIT); 192 | CheckGLError("startAnimation","glClear(GL_COLOR_BUFFER_BIT)"); 193 | glFlush(); 194 | CheckGLError("startAnimation","glFlush"); 195 | // Allocate the texture storage object if necessary 196 | [[glview openGLContext] makeCurrentContext]; 197 | if (matrixGlyphs == nil) { 198 | matrixGlyphs = [[MatrixTexture alloc] initWithNSOpenGLView:glview]; 199 | } 200 | // Load and bind the texture bitmap 201 | if (![matrixGlyphs fileLoaded]) { 202 | // Load the PNG of glyphs 203 | [matrixGlyphs loadFromFile:@"Glyphs.png"]; 204 | } 205 | // Set up some parameters 206 | x = 0.0; 207 | y = 0.0; 208 | [super startAnimation]; 209 | } 210 | 211 | - (void)stopAnimation 212 | { 213 | // Release the textures 214 | if (matrixGlyphs != nil) { 215 | // very important! 216 | matrixGlyphs = nil; 217 | } 218 | [super stopAnimation]; 219 | } 220 | 221 | // Draw the current frame 222 | - (void)drawRect:(NSRect)rect 223 | { 224 | [super drawRect:rect]; 225 | 226 | 227 | // Initialize OpenGL if necessary 228 | if (!didGLinit) { 229 | didGLinit = TRUE; 230 | [self initGL]; 231 | } 232 | 233 | if (glview == nil) { 234 | return; 235 | } 236 | 237 | if (mainScreenOnly && !isMainScreen) { 238 | [[glview openGLContext] makeCurrentContext]; 239 | glClearColor(0.0, 0.0, 0.0, 0.0); 240 | return; 241 | } 242 | 243 | [self drawGL]; 244 | 245 | // This is where we'd flush the double buffer to the screen if we were using one, with 246 | // [[glview openGLContext] flushBuffer]; 247 | } 248 | 249 | - (void)animateOneFrame 250 | { 251 | GLfloat xs,ys; 252 | GLfloat d; 253 | int cells; 254 | MatrixStrip *strip; 255 | MatrixStrip *newstrip; 256 | int maxi,newstripi; 257 | int i; 258 | struct MatrixStripParams tweaked; 259 | 260 | 261 | if (glview == nil) { 262 | LogError("animateOneFrame", "OS called animateOneFrame before NSOpenGLView initialized. This should not happen."); 263 | return; 264 | } 265 | 266 | // Anything to do? 267 | if (mainScreenOnly && !isMainScreen) { 268 | return; 269 | } 270 | 271 | if (matrixGlyphs == nil) { 272 | // Unfortunately the OS calling "draw frame" before "initialize screensaver" happens quite a lot, 273 | // and shouldn't be reported as an error 274 | return; 275 | } 276 | 277 | // Allocate the array of matrix strips if necessary 278 | if (matrixStrips == nil) { 279 | matrixStrips = [[NSMutableArray alloc] init]; 280 | } 281 | // If the number of Matrix strips is less than the max, create another every now and again 282 | maxi = [matrixStrips count]; 283 | if ((maxi < saverParams.maxStrips) && (RANDOM_FLOAT_01 < saverParams.spawnChance)) { 284 | // Copy the current parameters 285 | tweaked = saverParams; 286 | // If the velocity is 0, we make the depth random 287 | if (saverParams.driftSpeed == 0.0) { 288 | d = -CLIP_NEAR - RANDOM_FLOAT_01 * (CLIP_FAR - CLIP_NEAR); 289 | } else { 290 | // Depth is whatever the current parameters are, only negative (away from the viewer) 291 | d = -saverParams.maxDepth; 292 | } 293 | // Work out range of X and Y at that depth 294 | ys = -d * TAN_FOV; 295 | xs = ys * aspectRatio; 296 | // Position the strip 297 | x = xs * RANDOM_FLOAT_11; 298 | y = saverParams.cellSize + ys * (saverParams.minStartY == 0.0 ? RANDOM_FLOAT_01 : saverParams.minStartY); 299 | // Work out how many cells it needs to cover the screen vertically 300 | cells = (int) ((y + ys) / saverParams.cellSize / QUAD_SQUISH_FACTOR) + 2; 301 | // Tweak the cursor speed a bit, randomly 302 | tweaked.cursorSpeed = saverParams.cursorSpeed + 0.2 * RANDOM_FLOAT_01; 303 | // I guess we could tweak the other parameters to vary things a bit, but it looks good enough anyway 304 | // Now create a strip 305 | newstrip = [[MatrixStrip alloc] initWithCells:cells x:x y:y z:d params:tweaked]; 306 | newstripi = -1; 307 | // Add it to the array 308 | if (saverParams.driftSpeed == 0.0) { 309 | // In "zero velocity mode", we need to find the first strip that's in front of this one 310 | for (i = 0; i < maxi; i++) { 311 | strip = matrixStrips[i]; 312 | if ([strip z] > d) { 313 | break; 314 | } 315 | } 316 | [matrixStrips insertObject:newstrip atIndex:i]; 317 | } else { 318 | // In regular mode, strips are always added at the back 319 | if (maxi == 0) { 320 | // Adding first strip to array, so add it to the end 321 | [matrixStrips addObject:newstrip]; 322 | } else { 323 | // Add it to the start of the array 324 | [matrixStrips insertObject:newstrip atIndex:0]; 325 | } 326 | } 327 | // Now send a release, as the array will have retained it 328 | } 329 | // Animate all the strips 330 | maxi = [matrixStrips count]; 331 | for (i = 0; i < maxi; i++) { 332 | strip = matrixStrips[i]; 333 | if ([strip animateSelfIsComplete]) { 334 | // Strip has finished doing anything interesting, so delete it from the array 335 | // Note that the array releases it for us 336 | [matrixStrips removeObjectAtIndex:i]; 337 | // The array is now one smaller, and we need to loop over the same index again 338 | i -= 1; 339 | maxi -= 1; 340 | // Plus we can now spawn new strips faster 341 | if (saverParams.spawnChance < 1.0) { 342 | saverParams.spawnChance += 0.05; 343 | } 344 | } 345 | } 346 | // Trigger a rectangle redraw 347 | [self setNeedsDisplay:YES]; 348 | } 349 | 350 | /// SECTION TWO 351 | /// Everything OpenGL 352 | 353 | // Initialize OpenGL 354 | - (void)initGL 355 | { 356 | GLfloat fogcolor[4] = {0.0, 0.0, 0.0, 1.0}; 357 | 358 | // Check there's an NSOpenGLView before we continue 359 | if (glview == nil) { 360 | LogError("initGL", "Screensaver called initGL before NSOpenGLView initialized. This should not happen."); 361 | return; 362 | } 363 | // OK, let's go 364 | [[glview openGLContext] makeCurrentContext]; 365 | // All we need is flat shaded polygons 366 | glShadeModel(GL_FLAT); 367 | CheckGLError("initGL","glShadeModel(GL_FLAT)"); 368 | // Enable textures, use them to modulate the brightness of the pixels of the quads we draw 369 | glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 370 | CheckGLError("initGL","glTexEnvf(GL_MODULATE)"); 371 | glEnable(GL_TEXTURE_2D); 372 | CheckGLError("initGL","glEnable(GL_TEXTURE_2D)"); 373 | // Skip stuff that's almost black 374 | glAlphaFunc(GL_GEQUAL, 0.0625); 375 | CheckGLError("initGL","glAlphaFunc(GL_GEQUAL, 0.0625)"); 376 | // Set up the blending function for drawing the text quads 377 | glEnable(GL_BLEND); 378 | CheckGLError("initGL","glEnable(GL_BLEND)"); 379 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 380 | // Enable fog 381 | glEnable(GL_FOG); 382 | CheckGLError("initGL","glEnable(GL_FOG)"); 383 | glFogi(GL_FOG_MODE, GL_LINEAR); 384 | CheckGLError("initGL","glFogi"); 385 | glFogfv(GL_FOG_COLOR, fogcolor); 386 | CheckGLError("initGL","glFogf(GL_FOG_COLOR)"); 387 | glFogf(GL_FOG_DENSITY, saverParams.fogDensity); 388 | CheckGLError("initGL","glFogf(GL_FOG_DENSITY)"); 389 | glFogf(GL_FOG_START, CLIP_NEAR); 390 | CheckGLError("initGL","glFogf(GL_FOG_START)"); 391 | glFogf(GL_FOG_END, CLIP_FAR*1.2); 392 | CheckGLError("initGL","glFogf(GL_FOG_END)"); 393 | // Now maybe disable fog... 394 | if (saverParams.fogDensity == 0.0) { 395 | glDisable(GL_FOG); 396 | CheckGLError("initGL","glDisable(GL_FOG)"); 397 | } else { 398 | glEnable(GL_FOG); 399 | CheckGLError("initGL","glEnable(GL_FOG)"); 400 | } 401 | // We use GL arrays for drawing the Matrix strips, so enable them now 402 | glEnableClientState(GL_VERTEX_ARRAY); 403 | CheckGLError("initGL","glEnableClientState(GL_VERTEX_ARRAY)"); 404 | glEnableClientState(GL_COLOR_ARRAY); 405 | CheckGLError("initGL","glEnableClientState(GL_COLOR_ARRAY)"); 406 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); 407 | CheckGLError("initGL","glEnableClientState(GL_TEXTURE_COORD_ARRAY)"); 408 | } 409 | 410 | // Set up viewport and projection appropriately for the given screen rectangle 411 | - (void)resizeGL:(int)width :(int) height 412 | { 413 | if (glview == nil) { 414 | LogError("resizeGL", "Screensaver called resizeGL before NSOpenGLView initialized. This should not happen."); 415 | return; 416 | } 417 | [[glview openGLContext] makeCurrentContext]; 418 | glViewport(0, 0, width, height); 419 | CheckGLError("resizeGL","glViewport"); 420 | glMatrixMode(GL_PROJECTION); 421 | CheckGLError("resizeGL","glMatrixMode(GL_PROJECTION)"); 422 | glLoadIdentity(); 423 | CheckGLError("resizeGL","glLoadIdentity"); 424 | // 45 degrees FOV = 50mm lens on a 35mm camera, should look natural 425 | // Store the aspect ratio for later use 426 | aspectRatio = (GLfloat) width / (GLfloat) height; 427 | saverParams.aspectRatio = aspectRatio; 428 | gluPerspective(FIELD_OF_VIEW, aspectRatio, CLIP_NEAR, CLIP_FAR); 429 | CheckGLError("resizeGL","gluPerspective(FIELD_OF_VIEW)"); 430 | // Go back to manipulating the model (objects) 431 | glMatrixMode(GL_MODELVIEW); 432 | CheckGLError("resizeGL","glMatrixMode(GL_MODELVIEW)"); 433 | glLoadIdentity(); 434 | CheckGLError("resizeGL","glLoadIdentity"); 435 | } 436 | 437 | - (void)drawGL 438 | { 439 | GLuint tex; 440 | NSEnumerator *e; 441 | MatrixStrip *strip; 442 | 443 | if (glview == nil) { 444 | LogError("drawGL", "Screensaver called drawGL called before NSOpenGLView initialized. This should not happen."); 445 | return; 446 | } 447 | if (matrixGlyphs == nil) { 448 | // Unfortunately the OS calling "draw frame" before "initialize screensaver" happens quite a lot, 449 | // and shouldn't be reported as an error 450 | return; 451 | } 452 | [[glview openGLContext] makeCurrentContext]; 453 | glClearColor(0.0, 0.0, 0.0, 0.0); 454 | CheckGLError("drawGL","glClearColor(0.0, 0.0, 0.0, 0.0)"); 455 | glClear(GL_COLOR_BUFFER_BIT); 456 | CheckGLError("drawGL","glClear(GL_COLOR_BUFFER_BIT)"); 457 | if (matrixStrips == nil) { 458 | // I guess we didn't get around to it yet 459 | return; 460 | } 461 | // Bind the texture we loaded 462 | tex = [matrixGlyphs GLtexture]; 463 | if (!glIsTexture(tex)) { 464 | LogError("drawGL", "Someone stole our texture, call the OpenGL texture police."); 465 | } 466 | CheckGLError("drawGL","glIsTexture"); 467 | glBindTexture(GL_TEXTURE_2D, tex); 468 | CheckGLError("drawGL","glBindTexture"); 469 | // Draw all the strips by asking them to draw themselves 470 | e = [matrixStrips objectEnumerator]; 471 | while (strip = [e nextObject]) { 472 | [strip drawSelf]; 473 | } 474 | glFlush(); 475 | CheckGLError("drawGL","glFlush"); 476 | } 477 | 478 | /// SECTION THREE 479 | /// Configuration sheet handling 480 | 481 | - (BOOL)hasConfigureSheet 482 | { 483 | return YES; 484 | } 485 | 486 | - (NSWindow*)configureSheet 487 | { 488 | if (!prefsWindow) { 489 | prefsWindow = [[MatrixPrefsWindow alloc] 490 | initWithWindowNibName:@"Matrix"]; 491 | } 492 | return [prefsWindow window]; 493 | } 494 | 495 | /// SECTION FOUR 496 | /// Clean up after ourselves 497 | - (void) dealloc 498 | { 499 | [[NSNotificationCenter defaultCenter] 500 | removeObserver:self 501 | name:PREFS_NOTIFICATION 502 | object:nil]; 503 | } 504 | @end 505 | -------------------------------------------------------------------------------- /MatrixStrip.m: -------------------------------------------------------------------------------- 1 | // This file is part of Red Pill 2 | // A 3D OpenGL "Matrix" screensaver for Mac OS X 3 | // Copyright (C) 2002, 2003 mathew 4 | // 5 | // Red Pill is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | // or visit 19 | 20 | #import 21 | #import "MatrixStrip.h" 22 | #import "MatrixView.h" 23 | #import "MatrixMacros.h" 24 | 25 | // Given bottom,left coordinates of a 32x32 square within a 256x256 texture, 26 | // this is the amount to add to both coordinates to get the top,right pixel 27 | // of the same texture. It's equal to 31.0 / 256.0. 28 | #define GLYPH_TEX_SIZE 0.121 29 | 30 | @implementation MatrixStrip 31 | 32 | - (instancetype) initWithCells:(int)cells x:(GLfloat)x y:(GLfloat)y z:(GLfloat)z params:(struct MatrixStripParams)params; 33 | { 34 | int c; 35 | 36 | // Do whatever NSObject needs to do 37 | self = [super init]; 38 | if (self == nil) { 39 | return nil; 40 | } 41 | // So far, so good; now allocate storage 42 | cellState = malloc(cells * sizeof(int)); 43 | cellContents = malloc(cells * sizeof(int)); 44 | // Each cell needs four x,y texture vertex coordinates 45 | textureArray = malloc(cells * 4 * 2 * sizeof(GLfloat)); 46 | // and four x,y,z quad vertex coordinates 47 | quadArray = malloc(cells * 4 * 3 * sizeof(GLfloat)); 48 | // and four r,g,b,a color values 49 | colorArray = malloc(cells * 4 * 4 * sizeof(GLfloat)); 50 | 51 | // Check all those mallocs worked 52 | if (cellState == NULL || cellContents == NULL || textureArray == NULL || quadArray == NULL 53 | || colorArray == NULL) { 54 | LogError("initwithCells", "Failed to allocate memory for strip. Time to buy more memory."); 55 | return nil; 56 | } 57 | // Record how big we are and where 58 | stripSize = cells; 59 | myX = x; 60 | myY = y; 61 | myZ = z; 62 | // Copy/store the behavior parameters 63 | stripParams = params; 64 | // Initialize the cursor 65 | [self randomizeCursorState]; 66 | cursorPos = 1; 67 | cursorOffset = 1.0; 68 | cursorDrawing = TRUE; 69 | framecounter = 0; 70 | startColor = 0.2; 71 | [self randomizeCursorGlyph]; 72 | // Initialize cells 73 | for (c = 0; c 1) { 133 | // Cursor is drawing live cells 134 | // Next state is either draw-static or draw-empty-space 135 | cursorState = (random() % (stripParams.cursorStaticProbability + 136 | stripParams.cursorEmptyProbability)) < stripParams.cursorStaticProbability ? 137 | 1 : 0; 138 | } else { 139 | // None of the above 140 | // Pick a state completely at random 141 | int x = (random() % (stripParams.cursorStaticProbability + 142 | stripParams.cursorEmptyProbability + stripParams.cursorLiveProbability)); 143 | if (x < stripParams.cursorEmptyProbability) { 144 | cursorState = 0; 145 | } else if (x < (stripParams.cursorEmptyProbability + stripParams.cursorStaticProbability)) { 146 | cursorState = 1; 147 | } else { 148 | cursorState = (random() % stripParams.maxCellLife); 149 | } 150 | } 151 | } 152 | 153 | // Compute an entire array of quad vertices, given x,y,z of the top left corner 154 | - (void) computeQuadVertices:(int)cells x:(GLfloat)x y:(GLfloat)y z:(GLfloat)z 155 | { 156 | int i; 157 | GLfloat by, size; 158 | GLfloat minY,maxY; 159 | 160 | minY = z * TAN_FOV; 161 | maxY = -minY; 162 | firstVisibleCell = -1; 163 | lastVisibleCell = -1; 164 | 165 | size = stripParams.cellSize; 166 | for (i = 0; i < cells; i++) { 167 | // Compute bottom y coord of cell 168 | by = y - QUAD_SQUISH_FACTOR * size * (GLfloat) i; 169 | // Record the first cell that is at least partially on screen 170 | if ((by < maxY) && (firstVisibleCell == -1)) { 171 | firstVisibleCell = i; 172 | } 173 | // and the last 174 | if (((by + size) < minY) && (lastVisibleCell == -1)) { 175 | lastVisibleCell = i-1; 176 | } 177 | // Bottom left vertex 178 | quadArray[12*i + 0] = x; 179 | quadArray[12*i + 1] = by; 180 | quadArray[12*i + 2] = z; 181 | // Bottom right vertex 182 | quadArray[12*i + 3] = x + size; 183 | quadArray[12*i + 4] = by; 184 | quadArray[12*i + 5] = z; 185 | // Top right vertex 186 | quadArray[12*i + 6] = x + size; 187 | quadArray[12*i + 7] = by + size; 188 | quadArray[12*i + 8] = z; 189 | // Top left vertex 190 | quadArray[12*i + 9] = x; 191 | quadArray[12*i +10] = by + size; 192 | quadArray[12*i +11] = z; 193 | } 194 | // Check for case where all cells are above bottom of screen 195 | if (lastVisibleCell == -1) { 196 | lastVisibleCell = cells; 197 | } 198 | } 199 | 200 | // Initialize the array of color vertices 201 | - (void) initializeColorVertices:(int)maxcell 202 | { 203 | int i; 204 | 205 | for (i=0; i< maxcell * 16; i++) { 206 | colorArray[i] = 0.0; 207 | } 208 | } 209 | 210 | // Compute the new state of the color vertices 211 | - (void) computeColorVertices 212 | { 213 | int i,maxi,c; 214 | GLfloat g, gstep, cursorglow; 215 | 216 | c = 0; // To suppress spurious warning 217 | gstep = stripParams.colorCycleSpeed; 218 | // First, run down the strip cycling colors to bright then back to dark 219 | g = startColor; 220 | maxi = cursorDrawing ? cursorPos : stripSize; 221 | for (i=0; i < maxi; i++) { 222 | for (c = 0; c < 4; c++) { 223 | // Some shade of green if cell is not empty 224 | colorArray[16*i + 4*c + 1] = (cellState[i] == 0) ? 0.0 : g; 225 | // Cells which are very bright are slightly whitened 226 | colorArray[16*i + 4*c + 0] = ((g > 0.7) && (cellState[i] != 0)) ? (g - 0.6) : 0.0; 227 | colorArray[16*i + 4*c + 2] = ((g > 0.7) && (cellState[i] != 0)) ? (g - 0.6) : 0.0; 228 | // Transparent if cell is empty, otherwise opaque 229 | colorArray[16*i + 4*c + 3] = (cellState[i] == 0) ? 0.0 : 1.0; 230 | } 231 | g += gstep; 232 | if (g > 1.0) { 233 | g = 0.2; 234 | } 235 | } 236 | // Cycle the start color used above, to make the colors appear to fall 237 | startColor -= stripParams.colorFallSpeed; 238 | if (startColor < 0.2) { 239 | startColor = 1.0; 240 | } 241 | 242 | // If the cursor's drawing, work up from its position making sure the cells aren't too dark 243 | if (cursorDrawing) { 244 | maxi = cursorPos - 1; 245 | cursorglow = 0.8; 246 | for (i = maxi; i >= 0 && cursorglow > 0.2; i--) { 247 | // If there's some cursor-imparted glow left, use it 248 | if (colorArray[16*i + 4*c + 1] < cursorglow) { 249 | for (c = 0; c < 4; c++) { 250 | // Some shade of green if cell is not empty 251 | colorArray[16*i + 4*c + 1] = (cellState[i] == 0) ? 0.0 : cursorglow; 252 | // Cells which are very bright are slightly whitened 253 | colorArray[16*i + 4*c + 0] = ((cursorglow > 0.7) && (cellState[i] != 0)) ? (cursorglow - 0.6) : 0.0; 254 | colorArray[16*i + 4*c + 2] = ((cursorglow > 0.7) && (cellState[i] != 0)) ? (cursorglow - 0.6) : 0.0; 255 | // Transparent if cell is empty, otherwise opaque 256 | colorArray[16*i + 4*c + 3] = (cellState[i] == 0) ? 0.0 : 1.0; 257 | } 258 | } 259 | cursorglow -= gstep; 260 | } 261 | } 262 | } 263 | 264 | // It's a pity memset would require nasty assumptions about the internal format of floats... 265 | - (void) initializeTextureVertices:(int)maxcell 266 | { 267 | int i; 268 | 269 | for (i=0; i< maxcell * 8; i++) { 270 | textureArray[i] = 0.0; 271 | } 272 | } 273 | 274 | // Compute the texture coordinates for a single cell of the texture coord array 275 | - (void) computeTextureVertices:(int)cellnum 276 | { 277 | int ix,iy; 278 | GLfloat tx,ty; 279 | int g; 280 | 281 | // Get the glyph 282 | g = cellContents[cellnum]; 283 | // Work out the X and Y positions of the glyph in the texture 284 | ix = (g * 32) % 256; 285 | iy = 224 - 32 * ((g * 32) / 256) + 1; 286 | // Convert to floats 287 | tx = (GLfloat) ix / 256.0; 288 | ty = (GLfloat) iy / 256.0; 289 | // Now work out the texture coordinates of the square containing the glyph 290 | // Bottom left 291 | textureArray[8*cellnum + 0] = tx; 292 | textureArray[8*cellnum + 1] = ty; 293 | // Bottom right 294 | textureArray[8*cellnum + 2] = tx + GLYPH_TEX_SIZE; 295 | textureArray[8*cellnum + 3] = ty; 296 | // Top right 297 | textureArray[8*cellnum + 4] = tx + GLYPH_TEX_SIZE; 298 | textureArray[8*cellnum + 5] = ty + GLYPH_TEX_SIZE; 299 | // Top left 300 | textureArray[8*cellnum + 6] = tx; 301 | textureArray[8*cellnum + 7] = ty + GLYPH_TEX_SIZE; 302 | } 303 | 304 | // Compute quad, color and texture vertices for the cursor, bumped up by given offset 305 | - (void) computeCursor:(int)cell offset:(GLfloat)offset 306 | { 307 | int c; 308 | GLfloat y,by,x,z; 309 | GLfloat size; 310 | GLfloat cc; 311 | 312 | // Color is easy -- bright white at all four corners if drawing, else black 313 | cc = cursorDrawing ? 1.0 : 0.0; 314 | for (c = 0; c < 4; c++) { 315 | colorArray[16*cell + 4*c + 0] = cc; 316 | colorArray[16*cell + 4*c + 1] = cc; 317 | colorArray[16*cell + 4*c + 2] = cc; 318 | colorArray[16*cell + 4*c + 3] = 1.0; 319 | } 320 | // Position is like for a regular cell, but bumped up by offset * cell height 321 | size = stripParams.cellSize; 322 | // Find the top quad 323 | x = quadArray[0]; 324 | y = quadArray[1]; 325 | z = quadArray[2]; 326 | by = y - QUAD_SQUISH_FACTOR * size * ((GLfloat) cell - offset); 327 | // Bottom left vertex 328 | quadArray[12*cell + 0] = x; 329 | quadArray[12*cell + 1] = by; 330 | quadArray[12*cell + 2] = z; 331 | // Bottom right vertex 332 | quadArray[12*cell + 3] = x + size; 333 | quadArray[12*cell + 4] = by; 334 | quadArray[12*cell + 5] = z; 335 | // Top right vertex 336 | quadArray[12*cell + 6] = x + size; 337 | quadArray[12*cell + 7] = by + size; 338 | quadArray[12*cell + 8] = z; 339 | // Top left vertex 340 | quadArray[12*cell + 9] = x; 341 | quadArray[12*cell +10] = by + size; 342 | quadArray[12*cell +11] = z; 343 | // Texture is just a call to self 344 | cellContents[cell] = cursorGlyph; 345 | [self computeTextureVertices:cell]; 346 | } 347 | 348 | // Method to issue GL calls to draw the strip 349 | // After all the work to build the OpenGL arrays, this is really easy 350 | - (void) drawSelf 351 | { 352 | int i; 353 | GLfloat jitter; 354 | GLfloat tenths; 355 | int lastcell; 356 | GLint first; 357 | GLsizei count; 358 | 359 | // Each vertex has 3 coordinates (x,y,z), which are GLfloats; it's a packed array 360 | glVertexPointer(3, GL_FLOAT, 0, quadArray); 361 | CheckGLError("drawSelf","glVertexPointer"); 362 | // Each color vertex has 4 floats (RGBA); it's a packed array 363 | glColorPointer(4, GL_FLOAT, 0, colorArray); 364 | CheckGLError("drawSelf","glColorPointer"); 365 | // Each texture coordinate has two coordinates (x and y), which are floats; it's a packed array 366 | glTexCoordPointer(2, GL_FLOAT, 0, textureArray); 367 | CheckGLError("drawSelf","glTexCoordPointer"); 368 | // Work out the last cell we actually need to draw 369 | lastcell = (cursorDrawing) ? cursorPos : (stripSize - 1); 370 | if (lastcell > lastVisibleCell) { 371 | lastcell = lastVisibleCell; 372 | } 373 | // Now go draw all array elements from firstVisibleCell to lastcell 374 | first = firstVisibleCell * 4; 375 | count = (1 + lastcell - firstVisibleCell) * 4; 376 | if (count == 0) { 377 | return; 378 | } 379 | if (first < 0) { 380 | LogError("drawSelf", "Likely error: GLint first < 0"); 381 | } 382 | if ((count % 4) != 0 || (count / 4) > stripSize) { 383 | LogError("drawSelf", "Likely error: GLsizei count incorrect"); 384 | } 385 | glDrawArrays(GL_QUADS, first, count); /// was +1 386 | CheckGLError("drawSelf","glDrawArrays"); 387 | // Now we draw some motion trails behind the falling cursor. 388 | // You don't consciously notice it, but it makes a big difference. 389 | if (cursorDrawing) { 390 | jitter = 0.75 * stripParams.cursorSpeed * stripParams.cellSize; 391 | glDisableClientState(GL_COLOR_ARRAY); 392 | CheckGLError("drawSelf","glDisableClientState(GL_COLOR_ARRAY)"); 393 | for (i=0; i<3; i++) { 394 | tenths = (GLfloat)i * 0.1; 395 | glTranslatef(0.0,jitter,0.0); // jitter translation matrix up a bit 396 | CheckGLError("drawSelf","glTranslatef"); 397 | glColor4f(1.0 - tenths, 1.0 - tenths, 1.0 - tenths, 0.5 - tenths); 398 | CheckGLError("drawSelf","glColor4f"); 399 | glDrawArrays(GL_QUADS, 4 * cursorPos, 4); 400 | CheckGLError("drawSelf","glDrawArrays"); 401 | } 402 | glEnableClientState(GL_COLOR_ARRAY); 403 | CheckGLError("drawSelf","glEnableClientState(GL_COLOR_ARRAY)"); 404 | glTranslatef(0.0,-3*jitter,0.0); // translate back again 405 | CheckGLError("drawSelf","glTranslatef"); 406 | } 407 | } 408 | 409 | // Animate the strip, return true if the entire lifecycle of this strip is complete 410 | - (BOOL) animateSelfIsComplete 411 | { 412 | int c; 413 | GLfloat minY, cursLX, cursRX, maxX; 414 | BOOL nearfront; 415 | float zapchance; 416 | 417 | // First, are we about to splat into the screen? 418 | nearfront = (-myZ - stripParams.minDepth) < 5.0; 419 | if (nearfront) { 420 | // If so, we want a 1.0 probability of the cells being dead by the time they move the last 5.0 421 | zapchance = 1.0 / (5.0 / stripParams.driftSpeed); 422 | // Zap some random cells 423 | for (c = stripSize - 1; c >= 0; c--) { 424 | if (RANDOM_FLOAT_01 < zapchance) { 425 | cellState[c] = 0; 426 | cellContents[c] = 0; 427 | [self computeTextureVertices:c]; 428 | } 429 | } 430 | } 431 | // Now for normal movement. Move the cursor down. 432 | cursorOffset -= stripParams.cursorSpeed; 433 | if (cursorOffset < 0) { 434 | cursorOffset = 1.0; 435 | // Cursor has fallen to the bottom of its cell. 436 | // Paint the cell with whatever is appropriate for the cursor mode 437 | if (cursorDrawing) { 438 | cellState[cursorPos] = cursorState; 439 | cellContents[cursorPos] = cursorGlyph; 440 | [self computeTextureVertices:cursorPos]; 441 | // Move the cursor down a cell and pick a random glyph 442 | cursorPos += 1; 443 | // Should we change the cursor's draw state? 444 | if ((random() % 100) < stripParams.cursorChangeProbability) { 445 | // Pick a different state 446 | [self randomizeCursorState:cursorState]; 447 | } 448 | } else { 449 | // We're in erase-only mode 450 | cellState[cursorPos] = 0; 451 | cellContents[cursorPos] = 0; 452 | [self computeTextureVertices:cursorPos]; 453 | cursorPos += 1; 454 | } 455 | } 456 | // When we get to the bottom of the strip or the screen, see if we're in draw mode. 457 | // If so, go into erase mode. If we're already in erase mode, return true 'cause we're done. 458 | minY = myZ * TAN_FOV; 459 | if ((cursorPos >= stripSize) || (quadArray[12*cursorPos + 10] < minY)) { 460 | if (cursorDrawing) { 461 | cursorPos = 0; 462 | cursorDrawing = false; 463 | } else { 464 | return TRUE; 465 | } 466 | } 467 | if (framecounter++ == stripParams.framesPerLivingCellChange) { 468 | framecounter = 0; 469 | [self randomizeCursorGlyph]; 470 | // Animate the cells based on their state 471 | // Work from the bottom up, as some cells take their value from the cells above 472 | for (c = stripSize - 1; c >= 0; c--) { 473 | if ((cellState[c] > 1) || (nearfront && cellState[c] > 0)) { 474 | // Animated cell, will change glyph 475 | // If it's the top cell, give it a random value 476 | if (c == 0) { 477 | cellContents[c] = 1 + (random() % (stripParams.numGlyphs - 1)); 478 | } else if (cellState[c-1] <= 1) { 479 | // If the cell above isn't alive, give this one a random value 480 | cellContents[c] = 1 + (random() % (stripParams.numGlyphs - 1)); 481 | } else { 482 | // Otherwise give this one the value of the cell above 483 | cellContents[c] = cellContents[c-1]; 484 | } 485 | // Decrement state to age the cell 486 | cellState[c] -= 1; 487 | if (cellState[c] < 0) { 488 | cellState[c] = 0; 489 | } 490 | // A cell is never less alive than the one below it 491 | if (c < stripSize) { 492 | if (cellState[c+1] > cellState[c]) { 493 | cellState[c] = cellState[c+1]; 494 | } 495 | } 496 | // Recompute the cell's texture based on the new glyph contents 497 | [self computeTextureVertices:c]; 498 | } 499 | } 500 | } 501 | // Generate color vertices 502 | [self computeColorVertices]; 503 | // Move the strip towards the viewer 504 | myZ += stripParams.driftSpeed; 505 | if (-myZ < stripParams.minDepth) { 506 | return TRUE; 507 | } 508 | // If we fell off the sides of the screen, we're done 509 | maxX = -myZ * TAN_FOV * stripParams.aspectRatio; 510 | cursLX = quadArray[12*cursorPos + 9]; // Top left x 511 | cursRX = quadArray[12*cursorPos + 6]; // Top right x 512 | if ((cursLX > maxX) || (cursRX < -maxX)) { 513 | return TRUE; 514 | } 515 | // Don't need this any more 516 | [self computeQuadVertices:stripSize x:myX y:myY z:myZ]; 517 | // Generate the cursor 518 | [self computeCursor:cursorPos offset:cursorOffset]; 519 | // I'm not dead yet! 520 | return FALSE; 521 | } 522 | @end 523 | -------------------------------------------------------------------------------- /RedPill.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 8D255AC70486D3F9007BF209 /* RedPill_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 32DBCFA80370C50100C91783 /* RedPill_Prefix.pch */; }; 11 | 8D255ACA0486D3F9007BF209 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; }; 12 | 8D255ACE0486D3F9007BF209 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; 13 | 8D255ACF0486D3F9007BF209 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 06F27B2DFFEEEFEF11CA0E56 /* ScreenSaver.framework */; }; 14 | C0F75DF814649DBA00BC0085 /* GLUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = C0F75DEA14649DBA00BC0085 /* GLUtils.h */; }; 15 | C0F75DF914649DBA00BC0085 /* GLUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = C0F75DEB14649DBA00BC0085 /* GLUtils.m */; }; 16 | C0F75DFA14649DBA00BC0085 /* MatrixMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = C0F75DEC14649DBA00BC0085 /* MatrixMacros.h */; }; 17 | C0F75DFB14649DBA00BC0085 /* MatrixOpenGLView.h in Headers */ = {isa = PBXBuildFile; fileRef = C0F75DED14649DBA00BC0085 /* MatrixOpenGLView.h */; }; 18 | C0F75DFC14649DBA00BC0085 /* MatrixOpenGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = C0F75DEE14649DBA00BC0085 /* MatrixOpenGLView.m */; }; 19 | C0F75DFD14649DBA00BC0085 /* MatrixPrefsWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = C0F75DEF14649DBA00BC0085 /* MatrixPrefsWindow.h */; }; 20 | C0F75DFE14649DBA00BC0085 /* MatrixPrefsWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = C0F75DF014649DBA00BC0085 /* MatrixPrefsWindow.m */; }; 21 | C0F75DFF14649DBA00BC0085 /* MatrixStrip.h in Headers */ = {isa = PBXBuildFile; fileRef = C0F75DF114649DBA00BC0085 /* MatrixStrip.h */; }; 22 | C0F75E0014649DBA00BC0085 /* MatrixStrip.m in Sources */ = {isa = PBXBuildFile; fileRef = C0F75DF214649DBA00BC0085 /* MatrixStrip.m */; }; 23 | C0F75E0114649DBA00BC0085 /* MatrixStripParams.h in Headers */ = {isa = PBXBuildFile; fileRef = C0F75DF314649DBA00BC0085 /* MatrixStripParams.h */; }; 24 | C0F75E0214649DBA00BC0085 /* MatrixTexture.h in Headers */ = {isa = PBXBuildFile; fileRef = C0F75DF414649DBA00BC0085 /* MatrixTexture.h */; }; 25 | C0F75E0314649DBA00BC0085 /* MatrixTexture.m in Sources */ = {isa = PBXBuildFile; fileRef = C0F75DF514649DBA00BC0085 /* MatrixTexture.m */; }; 26 | C0F75E0414649DBA00BC0085 /* MatrixView.h in Headers */ = {isa = PBXBuildFile; fileRef = C0F75DF614649DBA00BC0085 /* MatrixView.h */; }; 27 | C0F75E0514649DBA00BC0085 /* MatrixView.m in Sources */ = {isa = PBXBuildFile; fileRef = C0F75DF714649DBA00BC0085 /* MatrixView.m */; }; 28 | C0F75E0B14649E1C00BC0085 /* Matrix.nib in Resources */ = {isa = PBXBuildFile; fileRef = C0F75E0914649E1C00BC0085 /* Matrix.nib */; }; 29 | C0F75E1214649E8E00BC0085 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0F75E1114649E8E00BC0085 /* OpenGL.framework */; }; 30 | C0F75E1C1464A00100BC0085 /* Glyphs.png in Resources */ = {isa = PBXBuildFile; fileRef = C0F75E1B1464A00100BC0085 /* Glyphs.png */; }; 31 | /* End PBXBuildFile section */ 32 | 33 | /* Begin PBXFileReference section */ 34 | 06F27B2DFFEEEFEF11CA0E56 /* ScreenSaver.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ScreenSaver.framework; path = /System/Library/Frameworks/ScreenSaver.framework; sourceTree = ""; }; 35 | 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 36 | 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 37 | 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 38 | 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 39 | 32DBCFA80370C50100C91783 /* RedPill_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RedPill_Prefix.pch; sourceTree = ""; }; 40 | 8D255AD20486D3F9007BF209 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 41 | 8D255AD30486D3F9007BF209 /* RedPill.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RedPill.saver; sourceTree = BUILT_PRODUCTS_DIR; }; 42 | C0F75DEA14649DBA00BC0085 /* GLUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLUtils.h; sourceTree = ""; }; 43 | C0F75DEB14649DBA00BC0085 /* GLUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GLUtils.m; sourceTree = ""; }; 44 | C0F75DEC14649DBA00BC0085 /* MatrixMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MatrixMacros.h; sourceTree = ""; }; 45 | C0F75DED14649DBA00BC0085 /* MatrixOpenGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MatrixOpenGLView.h; sourceTree = ""; }; 46 | C0F75DEE14649DBA00BC0085 /* MatrixOpenGLView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MatrixOpenGLView.m; sourceTree = ""; }; 47 | C0F75DEF14649DBA00BC0085 /* MatrixPrefsWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MatrixPrefsWindow.h; sourceTree = ""; }; 48 | C0F75DF014649DBA00BC0085 /* MatrixPrefsWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MatrixPrefsWindow.m; sourceTree = ""; }; 49 | C0F75DF114649DBA00BC0085 /* MatrixStrip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MatrixStrip.h; sourceTree = ""; }; 50 | C0F75DF214649DBA00BC0085 /* MatrixStrip.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MatrixStrip.m; sourceTree = ""; }; 51 | C0F75DF314649DBA00BC0085 /* MatrixStripParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MatrixStripParams.h; sourceTree = ""; }; 52 | C0F75DF414649DBA00BC0085 /* MatrixTexture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MatrixTexture.h; sourceTree = ""; }; 53 | C0F75DF514649DBA00BC0085 /* MatrixTexture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MatrixTexture.m; sourceTree = ""; }; 54 | C0F75DF614649DBA00BC0085 /* MatrixView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MatrixView.h; sourceTree = ""; }; 55 | C0F75DF714649DBA00BC0085 /* MatrixView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MatrixView.m; sourceTree = ""; }; 56 | C0F75E0A14649E1C00BC0085 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/Matrix.nib; sourceTree = ""; }; 57 | C0F75E0E14649E5500BC0085 /* Japanese */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = Japanese; path = Japanese.lproj/Matrix.nib; sourceTree = ""; }; 58 | C0F75E1114649E8E00BC0085 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; 59 | C0F75E1B1464A00100BC0085 /* Glyphs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Glyphs.png; sourceTree = ""; }; 60 | /* End PBXFileReference section */ 61 | 62 | /* Begin PBXFrameworksBuildPhase section */ 63 | 8D255ACD0486D3F9007BF209 /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | 8D255ACE0486D3F9007BF209 /* Cocoa.framework in Frameworks */, 68 | 8D255ACF0486D3F9007BF209 /* ScreenSaver.framework in Frameworks */, 69 | C0F75E1214649E8E00BC0085 /* OpenGL.framework in Frameworks */, 70 | ); 71 | runOnlyForDeploymentPostprocessing = 0; 72 | }; 73 | /* End PBXFrameworksBuildPhase section */ 74 | 75 | /* Begin PBXGroup section */ 76 | 089C166AFE841209C02AAC07 /* RedPill */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 08FB77AFFE84173DC02AAC07 /* Classes */, 80 | 32DBCFA70370C4F300C91783 /* Other Sources */, 81 | 089C167CFE841241C02AAC07 /* Resources */, 82 | 089C1671FE841209C02AAC07 /* Frameworks and Libraries */, 83 | 19C28FB8FE9D52D311CA2CBB /* Products */, 84 | ); 85 | indentWidth = 2; 86 | name = RedPill; 87 | sourceTree = ""; 88 | tabWidth = 2; 89 | }; 90 | 089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */, 94 | 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */, 95 | ); 96 | name = "Frameworks and Libraries"; 97 | sourceTree = ""; 98 | }; 99 | 089C167CFE841241C02AAC07 /* Resources */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | C0F75E1B1464A00100BC0085 /* Glyphs.png */, 103 | C0F75E0914649E1C00BC0085 /* Matrix.nib */, 104 | 8D255AD20486D3F9007BF209 /* Info.plist */, 105 | 089C167DFE841241C02AAC07 /* InfoPlist.strings */, 106 | ); 107 | name = Resources; 108 | sourceTree = ""; 109 | }; 110 | 08FB77AFFE84173DC02AAC07 /* Classes */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | C0F75DEA14649DBA00BC0085 /* GLUtils.h */, 114 | C0F75DEB14649DBA00BC0085 /* GLUtils.m */, 115 | C0F75DEC14649DBA00BC0085 /* MatrixMacros.h */, 116 | C0F75DED14649DBA00BC0085 /* MatrixOpenGLView.h */, 117 | C0F75DEE14649DBA00BC0085 /* MatrixOpenGLView.m */, 118 | C0F75DEF14649DBA00BC0085 /* MatrixPrefsWindow.h */, 119 | C0F75DF014649DBA00BC0085 /* MatrixPrefsWindow.m */, 120 | C0F75DF114649DBA00BC0085 /* MatrixStrip.h */, 121 | C0F75DF214649DBA00BC0085 /* MatrixStrip.m */, 122 | C0F75DF314649DBA00BC0085 /* MatrixStripParams.h */, 123 | C0F75DF414649DBA00BC0085 /* MatrixTexture.h */, 124 | C0F75DF514649DBA00BC0085 /* MatrixTexture.m */, 125 | C0F75DF614649DBA00BC0085 /* MatrixView.h */, 126 | C0F75DF714649DBA00BC0085 /* MatrixView.m */, 127 | ); 128 | name = Classes; 129 | sourceTree = ""; 130 | }; 131 | 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */, 135 | 06F27B2DFFEEEFEF11CA0E56 /* ScreenSaver.framework */, 136 | C0F75E1114649E8E00BC0085 /* OpenGL.framework */, 137 | ); 138 | name = "Linked Frameworks"; 139 | sourceTree = ""; 140 | }; 141 | 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | 089C1672FE841209C02AAC07 /* Foundation.framework */, 145 | 089C167FFE841241C02AAC07 /* AppKit.framework */, 146 | ); 147 | name = "Other Frameworks"; 148 | sourceTree = ""; 149 | }; 150 | 19C28FB8FE9D52D311CA2CBB /* Products */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 8D255AD30486D3F9007BF209 /* RedPill.saver */, 154 | ); 155 | name = Products; 156 | sourceTree = ""; 157 | }; 158 | 32DBCFA70370C4F300C91783 /* Other Sources */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | 32DBCFA80370C50100C91783 /* RedPill_Prefix.pch */, 162 | ); 163 | name = "Other Sources"; 164 | sourceTree = ""; 165 | }; 166 | /* End PBXGroup section */ 167 | 168 | /* Begin PBXHeadersBuildPhase section */ 169 | 8D255AC60486D3F9007BF209 /* Headers */ = { 170 | isa = PBXHeadersBuildPhase; 171 | buildActionMask = 2147483647; 172 | files = ( 173 | 8D255AC70486D3F9007BF209 /* RedPill_Prefix.pch in Headers */, 174 | C0F75DF814649DBA00BC0085 /* GLUtils.h in Headers */, 175 | C0F75DFA14649DBA00BC0085 /* MatrixMacros.h in Headers */, 176 | C0F75DFB14649DBA00BC0085 /* MatrixOpenGLView.h in Headers */, 177 | C0F75DFD14649DBA00BC0085 /* MatrixPrefsWindow.h in Headers */, 178 | C0F75DFF14649DBA00BC0085 /* MatrixStrip.h in Headers */, 179 | C0F75E0114649DBA00BC0085 /* MatrixStripParams.h in Headers */, 180 | C0F75E0214649DBA00BC0085 /* MatrixTexture.h in Headers */, 181 | C0F75E0414649DBA00BC0085 /* MatrixView.h in Headers */, 182 | ); 183 | runOnlyForDeploymentPostprocessing = 0; 184 | }; 185 | /* End PBXHeadersBuildPhase section */ 186 | 187 | /* Begin PBXNativeTarget section */ 188 | 8D255AC50486D3F9007BF209 /* RedPill */ = { 189 | isa = PBXNativeTarget; 190 | buildConfigurationList = EF7AD72D08BB986600CE4634 /* Build configuration list for PBXNativeTarget "RedPill" */; 191 | buildPhases = ( 192 | 8D255AC60486D3F9007BF209 /* Headers */, 193 | 8D255AC90486D3F9007BF209 /* Resources */, 194 | 8D255ACB0486D3F9007BF209 /* Sources */, 195 | 8D255ACD0486D3F9007BF209 /* Frameworks */, 196 | 8D255AD00486D3F9007BF209 /* Rez */, 197 | ); 198 | buildRules = ( 199 | ); 200 | dependencies = ( 201 | ); 202 | name = RedPill; 203 | productInstallPath = "$(HOME)/Library/Screen Savers"; 204 | productName = RedPill; 205 | productReference = 8D255AD30486D3F9007BF209 /* RedPill.saver */; 206 | productType = "com.apple.product-type.bundle"; 207 | }; 208 | /* End PBXNativeTarget section */ 209 | 210 | /* Begin PBXProject section */ 211 | 089C1669FE841209C02AAC07 /* Project object */ = { 212 | isa = PBXProject; 213 | attributes = { 214 | LastUpgradeCheck = 1310; 215 | }; 216 | buildConfigurationList = EF7AD73108BB986600CE4634 /* Build configuration list for PBXProject "RedPill" */; 217 | compatibilityVersion = "Xcode 3.2"; 218 | developmentRegion = English; 219 | hasScannedForEncodings = 1; 220 | knownRegions = ( 221 | English, 222 | Japanese, 223 | French, 224 | German, 225 | ); 226 | mainGroup = 089C166AFE841209C02AAC07 /* RedPill */; 227 | projectDirPath = ""; 228 | projectRoot = ""; 229 | targets = ( 230 | 8D255AC50486D3F9007BF209 /* RedPill */, 231 | ); 232 | }; 233 | /* End PBXProject section */ 234 | 235 | /* Begin PBXResourcesBuildPhase section */ 236 | 8D255AC90486D3F9007BF209 /* Resources */ = { 237 | isa = PBXResourcesBuildPhase; 238 | buildActionMask = 2147483647; 239 | files = ( 240 | 8D255ACA0486D3F9007BF209 /* InfoPlist.strings in Resources */, 241 | C0F75E0B14649E1C00BC0085 /* Matrix.nib in Resources */, 242 | C0F75E1C1464A00100BC0085 /* Glyphs.png in Resources */, 243 | ); 244 | runOnlyForDeploymentPostprocessing = 0; 245 | }; 246 | /* End PBXResourcesBuildPhase section */ 247 | 248 | /* Begin PBXRezBuildPhase section */ 249 | 8D255AD00486D3F9007BF209 /* Rez */ = { 250 | isa = PBXRezBuildPhase; 251 | buildActionMask = 2147483647; 252 | files = ( 253 | ); 254 | runOnlyForDeploymentPostprocessing = 0; 255 | }; 256 | /* End PBXRezBuildPhase section */ 257 | 258 | /* Begin PBXSourcesBuildPhase section */ 259 | 8D255ACB0486D3F9007BF209 /* Sources */ = { 260 | isa = PBXSourcesBuildPhase; 261 | buildActionMask = 2147483647; 262 | files = ( 263 | C0F75DF914649DBA00BC0085 /* GLUtils.m in Sources */, 264 | C0F75DFC14649DBA00BC0085 /* MatrixOpenGLView.m in Sources */, 265 | C0F75DFE14649DBA00BC0085 /* MatrixPrefsWindow.m in Sources */, 266 | C0F75E0014649DBA00BC0085 /* MatrixStrip.m in Sources */, 267 | C0F75E0314649DBA00BC0085 /* MatrixTexture.m in Sources */, 268 | C0F75E0514649DBA00BC0085 /* MatrixView.m in Sources */, 269 | ); 270 | runOnlyForDeploymentPostprocessing = 0; 271 | }; 272 | /* End PBXSourcesBuildPhase section */ 273 | 274 | /* Begin PBXVariantGroup section */ 275 | 089C167DFE841241C02AAC07 /* InfoPlist.strings */ = { 276 | isa = PBXVariantGroup; 277 | children = ( 278 | 089C167EFE841241C02AAC07 /* English */, 279 | ); 280 | name = InfoPlist.strings; 281 | sourceTree = ""; 282 | }; 283 | C0F75E0914649E1C00BC0085 /* Matrix.nib */ = { 284 | isa = PBXVariantGroup; 285 | children = ( 286 | C0F75E0A14649E1C00BC0085 /* English */, 287 | C0F75E0E14649E5500BC0085 /* Japanese */, 288 | ); 289 | name = Matrix.nib; 290 | sourceTree = ""; 291 | }; 292 | /* End PBXVariantGroup section */ 293 | 294 | /* Begin XCBuildConfiguration section */ 295 | EF7AD72E08BB986600CE4634 /* Debug */ = { 296 | isa = XCBuildConfiguration; 297 | buildSettings = { 298 | CLANG_ENABLE_OBJC_WEAK = YES; 299 | CURRENT_PROJECT_VERSION = 2.1.1; 300 | DEBUG_INFORMATION_FORMAT = dwarf; 301 | GCC_DYNAMIC_NO_PIC = NO; 302 | GCC_MODEL_TUNING = ""; 303 | GCC_OPTIMIZATION_LEVEL = 0; 304 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 305 | GCC_PREFIX_HEADER = RedPill_Prefix.pch; 306 | INFOPLIST_FILE = Info.plist; 307 | INSTALL_PATH = ""; 308 | MARKETING_VERSION = 2.1.1; 309 | PRODUCT_BUNDLE_IDENTIFIER = "com.ATH0.${PRODUCT_NAME:identifier}"; 310 | PRODUCT_NAME = RedPill; 311 | STRIP_INSTALLED_PRODUCT = YES; 312 | WRAPPER_EXTENSION = saver; 313 | ZERO_LINK = NO; 314 | }; 315 | name = Debug; 316 | }; 317 | EF7AD72F08BB986600CE4634 /* Release */ = { 318 | isa = XCBuildConfiguration; 319 | buildSettings = { 320 | CLANG_ENABLE_OBJC_WEAK = YES; 321 | CURRENT_PROJECT_VERSION = 2.1.1; 322 | DEBUG_INFORMATION_FORMAT = dwarf; 323 | GCC_MODEL_TUNING = ""; 324 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 325 | GCC_PREFIX_HEADER = RedPill_Prefix.pch; 326 | INFOPLIST_FILE = Info.plist; 327 | INSTALL_PATH = ""; 328 | MARKETING_VERSION = 2.1.1; 329 | PRODUCT_BUNDLE_IDENTIFIER = "com.ATH0.${PRODUCT_NAME:identifier}"; 330 | PRODUCT_NAME = RedPill; 331 | STRIP_INSTALLED_PRODUCT = YES; 332 | WRAPPER_EXTENSION = saver; 333 | ZERO_LINK = NO; 334 | }; 335 | name = Release; 336 | }; 337 | EF7AD73208BB986600CE4634 /* Debug */ = { 338 | isa = XCBuildConfiguration; 339 | buildSettings = { 340 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 341 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 342 | CLANG_WARN_BOOL_CONVERSION = YES; 343 | CLANG_WARN_COMMA = YES; 344 | CLANG_WARN_CONSTANT_CONVERSION = YES; 345 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 346 | CLANG_WARN_EMPTY_BODY = YES; 347 | CLANG_WARN_ENUM_CONVERSION = YES; 348 | CLANG_WARN_INFINITE_RECURSION = YES; 349 | CLANG_WARN_INT_CONVERSION = YES; 350 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 351 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 352 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 353 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 354 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 355 | CLANG_WARN_STRICT_PROTOTYPES = YES; 356 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 357 | CLANG_WARN_UNREACHABLE_CODE = YES; 358 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 359 | ENABLE_STRICT_OBJC_MSGSEND = YES; 360 | ENABLE_TESTABILITY = YES; 361 | GCC_C_LANGUAGE_STANDARD = c99; 362 | GCC_NO_COMMON_BLOCKS = YES; 363 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 364 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 365 | GCC_WARN_UNDECLARED_SELECTOR = YES; 366 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 367 | GCC_WARN_UNUSED_FUNCTION = YES; 368 | GCC_WARN_UNUSED_VARIABLE = YES; 369 | INFOPLIST_FILE = Info.plist; 370 | MACOSX_DEPLOYMENT_TARGET = 12.0; 371 | ONLY_ACTIVE_ARCH = YES; 372 | PRODUCT_NAME = RedPill; 373 | SDKROOT = macosx; 374 | WRAPPER_EXTENSION = saver; 375 | }; 376 | name = Debug; 377 | }; 378 | EF7AD73308BB986600CE4634 /* Release */ = { 379 | isa = XCBuildConfiguration; 380 | buildSettings = { 381 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 382 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 383 | CLANG_WARN_BOOL_CONVERSION = YES; 384 | CLANG_WARN_COMMA = YES; 385 | CLANG_WARN_CONSTANT_CONVERSION = YES; 386 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 387 | CLANG_WARN_EMPTY_BODY = YES; 388 | CLANG_WARN_ENUM_CONVERSION = YES; 389 | CLANG_WARN_INFINITE_RECURSION = YES; 390 | CLANG_WARN_INT_CONVERSION = YES; 391 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 392 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 393 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 394 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 395 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 396 | CLANG_WARN_STRICT_PROTOTYPES = YES; 397 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 398 | CLANG_WARN_UNREACHABLE_CODE = YES; 399 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 400 | ENABLE_STRICT_OBJC_MSGSEND = YES; 401 | GCC_C_LANGUAGE_STANDARD = c99; 402 | GCC_NO_COMMON_BLOCKS = YES; 403 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 404 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 405 | GCC_WARN_UNDECLARED_SELECTOR = YES; 406 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 407 | GCC_WARN_UNUSED_FUNCTION = YES; 408 | GCC_WARN_UNUSED_VARIABLE = YES; 409 | INFOPLIST_FILE = Info.plist; 410 | MACOSX_DEPLOYMENT_TARGET = 12.0; 411 | PRODUCT_NAME = RedPill; 412 | SDKROOT = macosx; 413 | WRAPPER_EXTENSION = saver; 414 | }; 415 | name = Release; 416 | }; 417 | /* End XCBuildConfiguration section */ 418 | 419 | /* Begin XCConfigurationList section */ 420 | EF7AD72D08BB986600CE4634 /* Build configuration list for PBXNativeTarget "RedPill" */ = { 421 | isa = XCConfigurationList; 422 | buildConfigurations = ( 423 | EF7AD72E08BB986600CE4634 /* Debug */, 424 | EF7AD72F08BB986600CE4634 /* Release */, 425 | ); 426 | defaultConfigurationIsVisible = 0; 427 | defaultConfigurationName = Release; 428 | }; 429 | EF7AD73108BB986600CE4634 /* Build configuration list for PBXProject "RedPill" */ = { 430 | isa = XCConfigurationList; 431 | buildConfigurations = ( 432 | EF7AD73208BB986600CE4634 /* Debug */, 433 | EF7AD73308BB986600CE4634 /* Release */, 434 | ); 435 | defaultConfigurationIsVisible = 0; 436 | defaultConfigurationName = Release; 437 | }; 438 | /* End XCConfigurationList section */ 439 | }; 440 | rootObject = 089C1669FE841209C02AAC07 /* Project object */; 441 | } 442 | -------------------------------------------------------------------------------- /English.lproj/Matrix.nib/designable.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | Fast 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | Fast 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | Fast 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 326 | 340 | 353 | 366 | 374 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | -------------------------------------------------------------------------------- /LICENSE.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | GNU General Public License v3.0 - GNU Project - Free Software Foundation (FSF) 6 | 8 | 9 | 10 |

GNU GENERAL PUBLIC LICENSE

11 |

Version 3, 29 June 2007

12 | 13 |

Copyright © 2007 Free Software Foundation, Inc. 14 | <http://fsf.org/>

15 | Everyone is permitted to copy and distribute verbatim copies 16 | of this license document, but changing it is not allowed.

17 | 18 |

Preamble

19 | 20 |

The GNU General Public License is a free, copyleft license for 21 | software and other kinds of works.

22 | 23 |

The licenses for most software and other practical works are designed 24 | to take away your freedom to share and change the works. By contrast, 25 | the GNU General Public License is intended to guarantee your freedom to 26 | share and change all versions of a program--to make sure it remains free 27 | software for all its users. We, the Free Software Foundation, use the 28 | GNU General Public License for most of our software; it applies also to 29 | any other work released this way by its authors. You can apply it to 30 | your programs, too.

31 | 32 |

When we speak of free software, we are referring to freedom, not 33 | price. Our General Public Licenses are designed to make sure that you 34 | have the freedom to distribute copies of free software (and charge for 35 | them if you wish), that you receive source code or can get it if you 36 | want it, that you can change the software or use pieces of it in new 37 | free programs, and that you know you can do these things.

38 | 39 |

To protect your rights, we need to prevent others from denying you 40 | these rights or asking you to surrender the rights. Therefore, you have 41 | certain responsibilities if you distribute copies of the software, or if 42 | you modify it: responsibilities to respect the freedom of others.

43 | 44 |

For example, if you distribute copies of such a program, whether 45 | gratis or for a fee, you must pass on to the recipients the same 46 | freedoms that you received. You must make sure that they, too, receive 47 | or can get the source code. And you must show them these terms so they 48 | know their rights.

49 | 50 |

Developers that use the GNU GPL protect your rights with two steps: 51 | (1) assert copyright on the software, and (2) offer you this License 52 | giving you legal permission to copy, distribute and/or modify it.

53 | 54 |

For the developers' and authors' protection, the GPL clearly explains 55 | that there is no warranty for this free software. For both users' and 56 | authors' sake, the GPL requires that modified versions be marked as 57 | changed, so that their problems will not be attributed erroneously to 58 | authors of previous versions.

59 | 60 |

Some devices are designed to deny users access to install or run 61 | modified versions of the software inside them, although the manufacturer 62 | can do so. This is fundamentally incompatible with the aim of 63 | protecting users' freedom to change the software. The systematic 64 | pattern of such abuse occurs in the area of products for individuals to 65 | use, which is precisely where it is most unacceptable. Therefore, we 66 | have designed this version of the GPL to prohibit the practice for those 67 | products. If such problems arise substantially in other domains, we 68 | stand ready to extend this provision to those domains in future versions 69 | of the GPL, as needed to protect the freedom of users.

70 | 71 |

Finally, every program is threatened constantly by software patents. 72 | States should not allow patents to restrict development and use of 73 | software on general-purpose computers, but in those that do, we wish to 74 | avoid the special danger that patents applied to a free program could 75 | make it effectively proprietary. To prevent this, the GPL assures that 76 | patents cannot be used to render the program non-free.

77 | 78 |

The precise terms and conditions for copying, distribution and 79 | modification follow.

80 | 81 |

TERMS AND CONDITIONS

82 | 83 |

0. Definitions.

84 | 85 |

“This License” refers to version 3 of the GNU General Public License.

86 | 87 |

“Copyright” also means copyright-like laws that apply to other kinds of 88 | works, such as semiconductor masks.

89 | 90 |

“The Program” refers to any copyrightable work licensed under this 91 | License. Each licensee is addressed as “you”. “Licensees” and 92 | “recipients” may be individuals or organizations.

93 | 94 |

To “modify” a work means to copy from or adapt all or part of the work 95 | in a fashion requiring copyright permission, other than the making of an 96 | exact copy. The resulting work is called a “modified version” of the 97 | earlier work or a work “based on” the earlier work.

98 | 99 |

A “covered work” means either the unmodified Program or a work based 100 | on the Program.

101 | 102 |

To “propagate” a work means to do anything with it that, without 103 | permission, would make you directly or secondarily liable for 104 | infringement under applicable copyright law, except executing it on a 105 | computer or modifying a private copy. Propagation includes copying, 106 | distribution (with or without modification), making available to the 107 | public, and in some countries other activities as well.

108 | 109 |

To “convey” a work means any kind of propagation that enables other 110 | parties to make or receive copies. Mere interaction with a user through 111 | a computer network, with no transfer of a copy, is not conveying.

112 | 113 |

An interactive user interface displays “Appropriate Legal Notices” 114 | to the extent that it includes a convenient and prominently visible 115 | feature that (1) displays an appropriate copyright notice, and (2) 116 | tells the user that there is no warranty for the work (except to the 117 | extent that warranties are provided), that licensees may convey the 118 | work under this License, and how to view a copy of this License. If 119 | the interface presents a list of user commands or options, such as a 120 | menu, a prominent item in the list meets this criterion.

121 | 122 |

1. Source Code.

123 | 124 |

The “source code” for a work means the preferred form of the work 125 | for making modifications to it. “Object code” means any non-source 126 | form of a work.

127 | 128 |

A “Standard Interface” means an interface that either is an official 129 | standard defined by a recognized standards body, or, in the case of 130 | interfaces specified for a particular programming language, one that 131 | is widely used among developers working in that language.

132 | 133 |

The “System Libraries” of an executable work include anything, other 134 | than the work as a whole, that (a) is included in the normal form of 135 | packaging a Major Component, but which is not part of that Major 136 | Component, and (b) serves only to enable use of the work with that 137 | Major Component, or to implement a Standard Interface for which an 138 | implementation is available to the public in source code form. A 139 | “Major Component”, in this context, means a major essential component 140 | (kernel, window system, and so on) of the specific operating system 141 | (if any) on which the executable work runs, or a compiler used to 142 | produce the work, or an object code interpreter used to run it.

143 | 144 |

The “Corresponding Source” for a work in object code form means all 145 | the source code needed to generate, install, and (for an executable 146 | work) run the object code and to modify the work, including scripts to 147 | control those activities. However, it does not include the work's 148 | System Libraries, or general-purpose tools or generally available free 149 | programs which are used unmodified in performing those activities but 150 | which are not part of the work. For example, Corresponding Source 151 | includes interface definition files associated with source files for 152 | the work, and the source code for shared libraries and dynamically 153 | linked subprograms that the work is specifically designed to require, 154 | such as by intimate data communication or control flow between those 155 | subprograms and other parts of the work.

156 | 157 |

The Corresponding Source need not include anything that users 158 | can regenerate automatically from other parts of the Corresponding 159 | Source.

160 | 161 |

The Corresponding Source for a work in source code form is that 162 | same work.

163 | 164 |

2. Basic Permissions.

165 | 166 |

All rights granted under this License are granted for the term of 167 | copyright on the Program, and are irrevocable provided the stated 168 | conditions are met. This License explicitly affirms your unlimited 169 | permission to run the unmodified Program. The output from running a 170 | covered work is covered by this License only if the output, given its 171 | content, constitutes a covered work. This License acknowledges your 172 | rights of fair use or other equivalent, as provided by copyright law.

173 | 174 |

You may make, run and propagate covered works that you do not 175 | convey, without conditions so long as your license otherwise remains 176 | in force. You may convey covered works to others for the sole purpose 177 | of having them make modifications exclusively for you, or provide you 178 | with facilities for running those works, provided that you comply with 179 | the terms of this License in conveying all material for which you do 180 | not control copyright. Those thus making or running the covered works 181 | for you must do so exclusively on your behalf, under your direction 182 | and control, on terms that prohibit them from making any copies of 183 | your copyrighted material outside their relationship with you.

184 | 185 |

Conveying under any other circumstances is permitted solely under 186 | the conditions stated below. Sublicensing is not allowed; section 10 187 | makes it unnecessary.

188 | 189 |

3. Protecting Users' Legal Rights From Anti-Circumvention Law.

190 | 191 |

No covered work shall be deemed part of an effective technological 192 | measure under any applicable law fulfilling obligations under article 193 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 194 | similar laws prohibiting or restricting circumvention of such 195 | measures.

196 | 197 |

When you convey a covered work, you waive any legal power to forbid 198 | circumvention of technological measures to the extent such circumvention 199 | is effected by exercising rights under this License with respect to 200 | the covered work, and you disclaim any intention to limit operation or 201 | modification of the work as a means of enforcing, against the work's 202 | users, your or third parties' legal rights to forbid circumvention of 203 | technological measures.

204 | 205 |

4. Conveying Verbatim Copies.

206 | 207 |

You may convey verbatim copies of the Program's source code as you 208 | receive it, in any medium, provided that you conspicuously and 209 | appropriately publish on each copy an appropriate copyright notice; 210 | keep intact all notices stating that this License and any 211 | non-permissive terms added in accord with section 7 apply to the code; 212 | keep intact all notices of the absence of any warranty; and give all 213 | recipients a copy of this License along with the Program.

214 | 215 |

You may charge any price or no price for each copy that you convey, 216 | and you may offer support or warranty protection for a fee.

217 | 218 |

5. Conveying Modified Source Versions.

219 | 220 |

You may convey a work based on the Program, or the modifications to 221 | produce it from the Program, in the form of source code under the 222 | terms of section 4, provided that you also meet all of these conditions:

223 | 224 |
    225 |
  • a) The work must carry prominent notices stating that you modified 226 | it, and giving a relevant date.
  • 227 | 228 |
  • b) The work must carry prominent notices stating that it is 229 | released under this License and any conditions added under section 230 | 7. This requirement modifies the requirement in section 4 to 231 | “keep intact all notices”.
  • 232 | 233 |
  • c) You must license the entire work, as a whole, under this 234 | License to anyone who comes into possession of a copy. This 235 | License will therefore apply, along with any applicable section 7 236 | additional terms, to the whole of the work, and all its parts, 237 | regardless of how they are packaged. This License gives no 238 | permission to license the work in any other way, but it does not 239 | invalidate such permission if you have separately received it.
  • 240 | 241 |
  • d) If the work has interactive user interfaces, each must display 242 | Appropriate Legal Notices; however, if the Program has interactive 243 | interfaces that do not display Appropriate Legal Notices, your 244 | work need not make them do so.
  • 245 |
246 | 247 |

A compilation of a covered work with other separate and independent 248 | works, which are not by their nature extensions of the covered work, 249 | and which are not combined with it such as to form a larger program, 250 | in or on a volume of a storage or distribution medium, is called an 251 | “aggregate” if the compilation and its resulting copyright are not 252 | used to limit the access or legal rights of the compilation's users 253 | beyond what the individual works permit. Inclusion of a covered work 254 | in an aggregate does not cause this License to apply to the other 255 | parts of the aggregate.

256 | 257 |

6. Conveying Non-Source Forms.

258 | 259 |

You may convey a covered work in object code form under the terms 260 | of sections 4 and 5, provided that you also convey the 261 | machine-readable Corresponding Source under the terms of this License, 262 | in one of these ways:

263 | 264 |
    265 |
  • a) Convey the object code in, or embodied in, a physical product 266 | (including a physical distribution medium), accompanied by the 267 | Corresponding Source fixed on a durable physical medium 268 | customarily used for software interchange.
  • 269 | 270 |
  • b) Convey the object code in, or embodied in, a physical product 271 | (including a physical distribution medium), accompanied by a 272 | written offer, valid for at least three years and valid for as 273 | long as you offer spare parts or customer support for that product 274 | model, to give anyone who possesses the object code either (1) a 275 | copy of the Corresponding Source for all the software in the 276 | product that is covered by this License, on a durable physical 277 | medium customarily used for software interchange, for a price no 278 | more than your reasonable cost of physically performing this 279 | conveying of source, or (2) access to copy the 280 | Corresponding Source from a network server at no charge.
  • 281 | 282 |
  • c) Convey individual copies of the object code with a copy of the 283 | written offer to provide the Corresponding Source. This 284 | alternative is allowed only occasionally and noncommercially, and 285 | only if you received the object code with such an offer, in accord 286 | with subsection 6b.
  • 287 | 288 |
  • d) Convey the object code by offering access from a designated 289 | place (gratis or for a charge), and offer equivalent access to the 290 | Corresponding Source in the same way through the same place at no 291 | further charge. You need not require recipients to copy the 292 | Corresponding Source along with the object code. If the place to 293 | copy the object code is a network server, the Corresponding Source 294 | may be on a different server (operated by you or a third party) 295 | that supports equivalent copying facilities, provided you maintain 296 | clear directions next to the object code saying where to find the 297 | Corresponding Source. Regardless of what server hosts the 298 | Corresponding Source, you remain obligated to ensure that it is 299 | available for as long as needed to satisfy these requirements.
  • 300 | 301 |
  • e) Convey the object code using peer-to-peer transmission, provided 302 | you inform other peers where the object code and Corresponding 303 | Source of the work are being offered to the general public at no 304 | charge under subsection 6d.
  • 305 |
306 | 307 |

A separable portion of the object code, whose source code is excluded 308 | from the Corresponding Source as a System Library, need not be 309 | included in conveying the object code work.

310 | 311 |

A “User Product” is either (1) a “consumer product”, which means any 312 | tangible personal property which is normally used for personal, family, 313 | or household purposes, or (2) anything designed or sold for incorporation 314 | into a dwelling. In determining whether a product is a consumer product, 315 | doubtful cases shall be resolved in favor of coverage. For a particular 316 | product received by a particular user, “normally used” refers to a 317 | typical or common use of that class of product, regardless of the status 318 | of the particular user or of the way in which the particular user 319 | actually uses, or expects or is expected to use, the product. A product 320 | is a consumer product regardless of whether the product has substantial 321 | commercial, industrial or non-consumer uses, unless such uses represent 322 | the only significant mode of use of the product.

323 | 324 |

“Installation Information” for a User Product means any methods, 325 | procedures, authorization keys, or other information required to install 326 | and execute modified versions of a covered work in that User Product from 327 | a modified version of its Corresponding Source. The information must 328 | suffice to ensure that the continued functioning of the modified object 329 | code is in no case prevented or interfered with solely because 330 | modification has been made.

331 | 332 |

If you convey an object code work under this section in, or with, or 333 | specifically for use in, a User Product, and the conveying occurs as 334 | part of a transaction in which the right of possession and use of the 335 | User Product is transferred to the recipient in perpetuity or for a 336 | fixed term (regardless of how the transaction is characterized), the 337 | Corresponding Source conveyed under this section must be accompanied 338 | by the Installation Information. But this requirement does not apply 339 | if neither you nor any third party retains the ability to install 340 | modified object code on the User Product (for example, the work has 341 | been installed in ROM).

342 | 343 |

The requirement to provide Installation Information does not include a 344 | requirement to continue to provide support service, warranty, or updates 345 | for a work that has been modified or installed by the recipient, or for 346 | the User Product in which it has been modified or installed. Access to a 347 | network may be denied when the modification itself materially and 348 | adversely affects the operation of the network or violates the rules and 349 | protocols for communication across the network.

350 | 351 |

Corresponding Source conveyed, and Installation Information provided, 352 | in accord with this section must be in a format that is publicly 353 | documented (and with an implementation available to the public in 354 | source code form), and must require no special password or key for 355 | unpacking, reading or copying.

356 | 357 |

7. Additional Terms.

358 | 359 |

“Additional permissions” are terms that supplement the terms of this 360 | License by making exceptions from one or more of its conditions. 361 | Additional permissions that are applicable to the entire Program shall 362 | be treated as though they were included in this License, to the extent 363 | that they are valid under applicable law. If additional permissions 364 | apply only to part of the Program, that part may be used separately 365 | under those permissions, but the entire Program remains governed by 366 | this License without regard to the additional permissions.

367 | 368 |

When you convey a copy of a covered work, you may at your option 369 | remove any additional permissions from that copy, or from any part of 370 | it. (Additional permissions may be written to require their own 371 | removal in certain cases when you modify the work.) You may place 372 | additional permissions on material, added by you to a covered work, 373 | for which you have or can give appropriate copyright permission.

374 | 375 |

Notwithstanding any other provision of this License, for material you 376 | add to a covered work, you may (if authorized by the copyright holders of 377 | that material) supplement the terms of this License with terms:

378 | 379 |
    380 |
  • a) Disclaiming warranty or limiting liability differently from the 381 | terms of sections 15 and 16 of this License; or
  • 382 | 383 |
  • b) Requiring preservation of specified reasonable legal notices or 384 | author attributions in that material or in the Appropriate Legal 385 | Notices displayed by works containing it; or
  • 386 | 387 |
  • c) Prohibiting misrepresentation of the origin of that material, or 388 | requiring that modified versions of such material be marked in 389 | reasonable ways as different from the original version; or
  • 390 | 391 |
  • d) Limiting the use for publicity purposes of names of licensors or 392 | authors of the material; or
  • 393 | 394 |
  • e) Declining to grant rights under trademark law for use of some 395 | trade names, trademarks, or service marks; or
  • 396 | 397 |
  • f) Requiring indemnification of licensors and authors of that 398 | material by anyone who conveys the material (or modified versions of 399 | it) with contractual assumptions of liability to the recipient, for 400 | any liability that these contractual assumptions directly impose on 401 | those licensors and authors.
  • 402 |
403 | 404 |

All other non-permissive additional terms are considered “further 405 | restrictions” within the meaning of section 10. If the Program as you 406 | received it, or any part of it, contains a notice stating that it is 407 | governed by this License along with a term that is a further 408 | restriction, you may remove that term. If a license document contains 409 | a further restriction but permits relicensing or conveying under this 410 | License, you may add to a covered work material governed by the terms 411 | of that license document, provided that the further restriction does 412 | not survive such relicensing or conveying.

413 | 414 |

If you add terms to a covered work in accord with this section, you 415 | must place, in the relevant source files, a statement of the 416 | additional terms that apply to those files, or a notice indicating 417 | where to find the applicable terms.

418 | 419 |

Additional terms, permissive or non-permissive, may be stated in the 420 | form of a separately written license, or stated as exceptions; 421 | the above requirements apply either way.

422 | 423 |

8. Termination.

424 | 425 |

You may not propagate or modify a covered work except as expressly 426 | provided under this License. Any attempt otherwise to propagate or 427 | modify it is void, and will automatically terminate your rights under 428 | this License (including any patent licenses granted under the third 429 | paragraph of section 11).

430 | 431 |

However, if you cease all violation of this License, then your 432 | license from a particular copyright holder is reinstated (a) 433 | provisionally, unless and until the copyright holder explicitly and 434 | finally terminates your license, and (b) permanently, if the copyright 435 | holder fails to notify you of the violation by some reasonable means 436 | prior to 60 days after the cessation.

437 | 438 |

Moreover, your license from a particular copyright holder is 439 | reinstated permanently if the copyright holder notifies you of the 440 | violation by some reasonable means, this is the first time you have 441 | received notice of violation of this License (for any work) from that 442 | copyright holder, and you cure the violation prior to 30 days after 443 | your receipt of the notice.

444 | 445 |

Termination of your rights under this section does not terminate the 446 | licenses of parties who have received copies or rights from you under 447 | this License. If your rights have been terminated and not permanently 448 | reinstated, you do not qualify to receive new licenses for the same 449 | material under section 10.

450 | 451 |

9. Acceptance Not Required for Having Copies.

452 | 453 |

You are not required to accept this License in order to receive or 454 | run a copy of the Program. Ancillary propagation of a covered work 455 | occurring solely as a consequence of using peer-to-peer transmission 456 | to receive a copy likewise does not require acceptance. However, 457 | nothing other than this License grants you permission to propagate or 458 | modify any covered work. These actions infringe copyright if you do 459 | not accept this License. Therefore, by modifying or propagating a 460 | covered work, you indicate your acceptance of this License to do so.

461 | 462 |

10. Automatic Licensing of Downstream Recipients.

463 | 464 |

Each time you convey a covered work, the recipient automatically 465 | receives a license from the original licensors, to run, modify and 466 | propagate that work, subject to this License. You are not responsible 467 | for enforcing compliance by third parties with this License.

468 | 469 |

An “entity transaction” is a transaction transferring control of an 470 | organization, or substantially all assets of one, or subdividing an 471 | organization, or merging organizations. If propagation of a covered 472 | work results from an entity transaction, each party to that 473 | transaction who receives a copy of the work also receives whatever 474 | licenses to the work the party's predecessor in interest had or could 475 | give under the previous paragraph, plus a right to possession of the 476 | Corresponding Source of the work from the predecessor in interest, if 477 | the predecessor has it or can get it with reasonable efforts.

478 | 479 |

You may not impose any further restrictions on the exercise of the 480 | rights granted or affirmed under this License. For example, you may 481 | not impose a license fee, royalty, or other charge for exercise of 482 | rights granted under this License, and you may not initiate litigation 483 | (including a cross-claim or counterclaim in a lawsuit) alleging that 484 | any patent claim is infringed by making, using, selling, offering for 485 | sale, or importing the Program or any portion of it.

486 | 487 |

11. Patents.

488 | 489 |

A “contributor” is a copyright holder who authorizes use under this 490 | License of the Program or a work on which the Program is based. The 491 | work thus licensed is called the contributor's “contributor version”.

492 | 493 |

A contributor's “essential patent claims” are all patent claims 494 | owned or controlled by the contributor, whether already acquired or 495 | hereafter acquired, that would be infringed by some manner, permitted 496 | by this License, of making, using, or selling its contributor version, 497 | but do not include claims that would be infringed only as a 498 | consequence of further modification of the contributor version. For 499 | purposes of this definition, “control” includes the right to grant 500 | patent sublicenses in a manner consistent with the requirements of 501 | this License.

502 | 503 |

Each contributor grants you a non-exclusive, worldwide, royalty-free 504 | patent license under the contributor's essential patent claims, to 505 | make, use, sell, offer for sale, import and otherwise run, modify and 506 | propagate the contents of its contributor version.

507 | 508 |

In the following three paragraphs, a “patent license” is any express 509 | agreement or commitment, however denominated, not to enforce a patent 510 | (such as an express permission to practice a patent or covenant not to 511 | sue for patent infringement). To “grant” such a patent license to a 512 | party means to make such an agreement or commitment not to enforce a 513 | patent against the party.

514 | 515 |

If you convey a covered work, knowingly relying on a patent license, 516 | and the Corresponding Source of the work is not available for anyone 517 | to copy, free of charge and under the terms of this License, through a 518 | publicly available network server or other readily accessible means, 519 | then you must either (1) cause the Corresponding Source to be so 520 | available, or (2) arrange to deprive yourself of the benefit of the 521 | patent license for this particular work, or (3) arrange, in a manner 522 | consistent with the requirements of this License, to extend the patent 523 | license to downstream recipients. “Knowingly relying” means you have 524 | actual knowledge that, but for the patent license, your conveying the 525 | covered work in a country, or your recipient's use of the covered work 526 | in a country, would infringe one or more identifiable patents in that 527 | country that you have reason to believe are valid.

528 | 529 |

If, pursuant to or in connection with a single transaction or 530 | arrangement, you convey, or propagate by procuring conveyance of, a 531 | covered work, and grant a patent license to some of the parties 532 | receiving the covered work authorizing them to use, propagate, modify 533 | or convey a specific copy of the covered work, then the patent license 534 | you grant is automatically extended to all recipients of the covered 535 | work and works based on it.

536 | 537 |

A patent license is “discriminatory” if it does not include within 538 | the scope of its coverage, prohibits the exercise of, or is 539 | conditioned on the non-exercise of one or more of the rights that are 540 | specifically granted under this License. You may not convey a covered 541 | work if you are a party to an arrangement with a third party that is 542 | in the business of distributing software, under which you make payment 543 | to the third party based on the extent of your activity of conveying 544 | the work, and under which the third party grants, to any of the 545 | parties who would receive the covered work from you, a discriminatory 546 | patent license (a) in connection with copies of the covered work 547 | conveyed by you (or copies made from those copies), or (b) primarily 548 | for and in connection with specific products or compilations that 549 | contain the covered work, unless you entered into that arrangement, 550 | or that patent license was granted, prior to 28 March 2007.

551 | 552 |

Nothing in this License shall be construed as excluding or limiting 553 | any implied license or other defenses to infringement that may 554 | otherwise be available to you under applicable patent law.

555 | 556 |

12. No Surrender of Others' Freedom.

557 | 558 |

If conditions are imposed on you (whether by court order, agreement or 559 | otherwise) that contradict the conditions of this License, they do not 560 | excuse you from the conditions of this License. If you cannot convey a 561 | covered work so as to satisfy simultaneously your obligations under this 562 | License and any other pertinent obligations, then as a consequence you may 563 | not convey it at all. For example, if you agree to terms that obligate you 564 | to collect a royalty for further conveying from those to whom you convey 565 | the Program, the only way you could satisfy both those terms and this 566 | License would be to refrain entirely from conveying the Program.

567 | 568 |

13. Use with the GNU Affero General Public License.

569 | 570 |

Notwithstanding any other provision of this License, you have 571 | permission to link or combine any covered work with a work licensed 572 | under version 3 of the GNU Affero General Public License into a single 573 | combined work, and to convey the resulting work. The terms of this 574 | License will continue to apply to the part which is the covered work, 575 | but the special requirements of the GNU Affero General Public License, 576 | section 13, concerning interaction through a network will apply to the 577 | combination as such.

578 | 579 |

14. Revised Versions of this License.

580 | 581 |

The Free Software Foundation may publish revised and/or new versions of 582 | the GNU General Public License from time to time. Such new versions will 583 | be similar in spirit to the present version, but may differ in detail to 584 | address new problems or concerns.

585 | 586 |

Each version is given a distinguishing version number. If the 587 | Program specifies that a certain numbered version of the GNU General 588 | Public License “or any later version” applies to it, you have the 589 | option of following the terms and conditions either of that numbered 590 | version or of any later version published by the Free Software 591 | Foundation. If the Program does not specify a version number of the 592 | GNU General Public License, you may choose any version ever published 593 | by the Free Software Foundation.

594 | 595 |

If the Program specifies that a proxy can decide which future 596 | versions of the GNU General Public License can be used, that proxy's 597 | public statement of acceptance of a version permanently authorizes you 598 | to choose that version for the Program.

599 | 600 |

Later license versions may give you additional or different 601 | permissions. However, no additional obligations are imposed on any 602 | author or copyright holder as a result of your choosing to follow a 603 | later version.

604 | 605 |

15. Disclaimer of Warranty.

606 | 607 |

THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 608 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 609 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY 610 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 611 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 612 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 613 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 614 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

615 | 616 |

16. Limitation of Liability.

617 | 618 |

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 619 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 620 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 621 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 622 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 623 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 624 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 625 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 626 | SUCH DAMAGES.

627 | 628 |

17. Interpretation of Sections 15 and 16.

629 | 630 |

If the disclaimer of warranty and limitation of liability provided 631 | above cannot be given local legal effect according to their terms, 632 | reviewing courts shall apply local law that most closely approximates 633 | an absolute waiver of all civil liability in connection with the 634 | Program, unless a warranty or assumption of liability accompanies a 635 | copy of the Program in return for a fee.

636 | 637 |

END OF TERMS AND CONDITIONS

638 | 639 |

How to Apply These Terms to Your New Programs

640 | 641 |

If you develop a new program, and you want it to be of the greatest 642 | possible use to the public, the best way to achieve this is to make it 643 | free software which everyone can redistribute and change under these terms.

644 | 645 |

To do so, attach the following notices to the program. It is safest 646 | to attach them to the start of each source file to most effectively 647 | state the exclusion of warranty; and each file should have at least 648 | the “copyright” line and a pointer to where the full notice is found.

649 | 650 |
    <one line to give the program's name and a brief idea of what it does.>
651 |     Copyright (C) <year>  <name of author>
652 | 
653 |     This program is free software: you can redistribute it and/or modify
654 |     it under the terms of the GNU General Public License as published by
655 |     the Free Software Foundation, either version 3 of the License, or
656 |     (at your option) any later version.
657 | 
658 |     This program is distributed in the hope that it will be useful,
659 |     but WITHOUT ANY WARRANTY; without even the implied warranty of
660 |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
661 |     GNU General Public License for more details.
662 | 
663 |     You should have received a copy of the GNU General Public License
664 |     along with this program.  If not, see <http://www.gnu.org/licenses/>.
665 | 
666 | 667 |

Also add information on how to contact you by electronic and paper mail.

668 | 669 |

If the program does terminal interaction, make it output a short 670 | notice like this when it starts in an interactive mode:

671 | 672 |
    <program>  Copyright (C) <year>  <name of author>
673 |     This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
674 |     This is free software, and you are welcome to redistribute it
675 |     under certain conditions; type `show c' for details.
676 | 
677 | 678 |

The hypothetical commands `show w' and `show c' should show the appropriate 679 | parts of the General Public License. Of course, your program's commands 680 | might be different; for a GUI interface, you would use an “about box”.

681 | 682 |

You should also get your employer (if you work as a programmer) or school, 683 | if any, to sign a “copyright disclaimer” for the program, if necessary. 684 | For more information on this, and how to apply and follow the GNU GPL, see 685 | <http://www.gnu.org/licenses/>.

686 | 687 |

The GNU General Public License does not permit incorporating your program 688 | into proprietary programs. If your program is a subroutine library, you 689 | may consider it more useful to permit linking proprietary applications with 690 | the library. If this is what you want to do, use the GNU Lesser General 691 | Public License instead of this License. But first, please read 692 | <http://www.gnu.org/philosophy/why-not-lgpl.html>.

693 | 694 | 695 | --------------------------------------------------------------------------------