├── Classes ├── LOButtonGlowView.h ├── LOButtonGlowView.m ├── LOButtonView.h ├── LOButtonView.m ├── LOController.h ├── LOController.m ├── LODoneButtonView.h ├── LODoneButtonView.m ├── LOGlareView.h ├── LOGlareView.m ├── LOHighlightView.h ├── LOHighlightView.m ├── LOInfoButtonView.h ├── LOInfoButtonView.m ├── LOInfoView.h ├── LOInfoView.m ├── LOResetView.h ├── LOResetView.m ├── LOView.h ├── LOView.m ├── LightsOffTouchAppDelegate.h └── LightsOffTouchAppDelegate.m ├── Images ├── Default.png ├── Icon.png ├── lo-background-info.png ├── lo-background.png ├── lo-button-done-press.png ├── lo-button-done.png ├── lo-button-fullglow.png ├── lo-button-glare.png ├── lo-button-info-press.png ├── lo-button-info.png ├── lo-button-off.png ├── lo-button-on-press.png ├── lo-button-press.png ├── lo-button-reset-press.png ├── lo-button-reset.png ├── lo-glowpress.png └── lo-logoglow.png ├── Info.plist ├── Jailbreak ├── LOButtonGlowView.h ├── LOButtonGlowView.m ├── LOButtonView.h ├── LOButtonView.m ├── LOController.h ├── LOController.m ├── LODoneButtonView.h ├── LODoneButtonView.m ├── LOGlareView.h ├── LOGlareView.m ├── LOHighlightView.h ├── LOHighlightView.m ├── LOInfoButtonView.h ├── LOInfoButtonView.m ├── LOInfoView.h ├── LOInfoView.m ├── LOResetView.h ├── LOResetView.m ├── LOView.h ├── LOView.m └── main.m ├── Lights Off - iPhone X Edition.png ├── LightsOffTouch.xcodeproj └── project.pbxproj ├── LightsOffTouch_Prefix.pch ├── README.md ├── main.m └── puzzles.plist /Classes/LOButtonGlowView.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | typedef enum { 5 | LOButtonGlowLeft, 6 | LOButtonGlowRight 7 | } LOButtonGlowType; 8 | 9 | @interface LOButtonGlowView : UIView { 10 | BOOL pressed; 11 | LOButtonGlowType type; 12 | } 13 | 14 | // API 15 | - (void)setButtonType:(LOButtonGlowType)buttonType; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Classes/LOButtonGlowView.m: -------------------------------------------------------------------------------- 1 | 2 | #import "LOButtonGlowView.h" 3 | 4 | #import "LOController.h" 5 | 6 | @implementation LOButtonGlowView 7 | 8 | 9 | #pragma mark UIResponder 10 | 11 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 12 | { 13 | pressed = YES; 14 | [self setNeedsDisplay]; 15 | } 16 | 17 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 18 | { 19 | pressed = NO; 20 | [self setNeedsDisplay]; 21 | 22 | (type == LOButtonGlowLeft) ? [[self superview] skipToPreviousLevel] : [[self superview] skipToNextLevel]; 23 | } 24 | 25 | #pragma mark UIView 26 | 27 | - (void)drawRect:(CGRect)rect; 28 | { 29 | if (pressed) { 30 | static UIImage *buttonGlowImage; 31 | if (!buttonGlowImage) 32 | buttonGlowImage = [[UIImage imageNamed:@"lo-glowpress.png"] retain]; 33 | [buttonGlowImage drawInRect:rect]; 34 | } 35 | } 36 | 37 | 38 | #pragma mark API 39 | 40 | - (void)setButtonType:(LOButtonGlowType)buttonType; 41 | { 42 | type = buttonType; 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Classes/LOButtonView.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | @interface LOButtonView : UIView { 5 | BOOL lightOn; 6 | BOOL pressed; 7 | } 8 | 9 | - (void)setLightOn:(BOOL)isOn; 10 | - (BOOL)isLightOn; 11 | - (void)setPressed:(BOOL)isPressed; 12 | - (BOOL)isPressed; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Classes/LOButtonView.m: -------------------------------------------------------------------------------- 1 | 2 | #import "LOButtonView.h" 3 | 4 | #import "LOController.h" 5 | #import "LOView.h" 6 | 7 | @implementation LOButtonView 8 | 9 | #pragma mark UIView 10 | 11 | - (void)drawRect:(CGRect)rect; 12 | { 13 | if (!pressed) { 14 | static UIImage *buttonOffImage; 15 | if (!buttonOffImage) 16 | buttonOffImage = [[UIImage imageNamed:@"lo-button-off.png"] retain]; 17 | [buttonOffImage drawInRect:rect]; 18 | 19 | if (lightOn) { 20 | static UIImage *buttonGlowImage; 21 | if (!buttonGlowImage) 22 | buttonGlowImage = [[UIImage imageNamed:@"lo-button-fullglow.png"] retain]; 23 | CGRect drawRect = CGRectInset(rect, -8.0, -7.0); 24 | drawRect.origin.y -= 3.0; 25 | [buttonGlowImage drawInRect:drawRect]; 26 | } 27 | } else { 28 | if (!lightOn) { 29 | static UIImage *buttonPressedImage; 30 | if (!buttonPressedImage) 31 | buttonPressedImage = [[UIImage imageNamed:@"lo-button-press.png"] retain]; 32 | [buttonPressedImage drawInRect:rect]; 33 | } else { 34 | static UIImage *buttonOnPressedImage; 35 | if (!buttonOnPressedImage) 36 | buttonOnPressedImage = [[UIImage imageNamed:@"lo-button-on-press.png"] retain]; 37 | [buttonOnPressedImage drawInRect:rect]; 38 | } 39 | } 40 | } 41 | 42 | 43 | #pragma mark UIResponder 44 | 45 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 46 | { 47 | [self setPressed:YES]; 48 | } 49 | 50 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 51 | { 52 | [self setPressed:NO]; 53 | [(LOView *)[self superview] pressButtonView:self]; 54 | } 55 | 56 | 57 | #pragma mark API 58 | 59 | - (void)setLightOn:(BOOL)isOn; 60 | { 61 | lightOn = isOn; 62 | [self setNeedsDisplay]; 63 | } 64 | 65 | - (BOOL)isLightOn; 66 | { 67 | return lightOn; 68 | } 69 | 70 | - (void)setPressed:(BOOL)isPressed; 71 | { 72 | pressed = isPressed; 73 | [self setNeedsDisplay]; 74 | } 75 | 76 | - (BOOL)isPressed; 77 | { 78 | return pressed; 79 | } 80 | 81 | @end 82 | -------------------------------------------------------------------------------- /Classes/LOController.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | // Constants 5 | typedef enum { 6 | kUIAnimationCurveEaseInEaseOut, 7 | kUIAnimationCurveEaseIn, 8 | kUIAnimationCurveEaseOut, 9 | kUIAnimationCurveLinear 10 | } UIAnimationCurve; 11 | 12 | @interface UIView(Color) 13 | - (CGColorRef)colorWithRed:(float)red green:(float)green blue:(float)blue alpha:(float)alpha; 14 | @end 15 | 16 | @class LOButtonView, LOView; 17 | 18 | @interface LOController : UIApplication { 19 | UIWindow *window; 20 | LOView *view; 21 | NSArray *puzzles; 22 | 23 | BOOL isAcceptingInput; 24 | unsigned int currentLevel; 25 | NSString *currentLevelString; 26 | } 27 | 28 | - (NSString *)currentLevelString; 29 | - (BOOL)isAcceptingInput; 30 | - (void)pressButtonView:(LOButtonView *)buttonView; 31 | - (void)reset; 32 | - (void)skipToNextLevel; 33 | - (void)skipToPreviousLevel; 34 | @end 35 | 36 | #define ROW_COUNT (5) 37 | #define COLUMN_COUNT (5) -------------------------------------------------------------------------------- /Classes/LOController.m: -------------------------------------------------------------------------------- 1 | 2 | #import "LOController.h" 3 | 4 | #import "LOButtonView.h" 5 | #import "LOGlareView.h" 6 | #import "LOHighlightView.h" 7 | #import "LOView.h" 8 | 9 | #pragma mark - 10 | 11 | @implementation UIView(Color) 12 | 13 | - (CGColorRef)colorWithRed:(float)red green:(float)green blue:(float)blue alpha:(float)alpha; 14 | { 15 | float rgba[4]; 16 | rgba[0] = red; 17 | rgba[1] = green; 18 | rgba[2] = blue; 19 | rgba[3] = alpha; 20 | CGColorRef color = (CGColorRef)[(id)CGColorCreate((CGColorSpaceRef)[(id)CGColorSpaceCreateDeviceRGB() autorelease], rgba) autorelease]; 21 | return color; 22 | } 23 | 24 | @end 25 | 26 | #pragma mark - 27 | 28 | @interface LOController (Private) 29 | - (void)_executeLightSequence:(unsigned int *)lightSequence count:(unsigned int)count delayBetweenLights:(NSTimeInterval)lightDelay totalDelay:(NSTimeInterval *)totalDelay; 30 | - (void)_setCurrentLevelString:(NSString *)string; 31 | - (void)_setUpNextLevel; 32 | - (void)_showLightFlourishWithTotalDelay:(NSTimeInterval *)totalDelay; 33 | - (void)_showWinFlourishAndSetUpNextLevel; 34 | - (void)_toggleButtonView:(LOButtonView *)buttonView; 35 | - (void)_turnOffAllLights; 36 | @end 37 | 38 | #pragma mark - 39 | 40 | @implementation LOController 41 | 42 | 43 | #pragma mark NSObject 44 | 45 | - (void)dealloc; 46 | { 47 | [window release]; 48 | [view release]; 49 | [super dealloc]; 50 | } 51 | 52 | - (void)awakeFromNib; 53 | { 54 | } 55 | 56 | #pragma mark UIApplication 57 | 58 | - (void)applicationDidFinishLaunching:(NSNotification *)notification; 59 | { 60 | puzzles = [[[[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"puzzles" ofType:@"plist"]] allValues] lastObject] retain]; 61 | 62 | window = [[UIWindow alloc] initWithContentRect:[[UIScreen mainScreen] bounds]]; 63 | view = [[LOView alloc] initWithFrame:[window bounds] controller:self]; 64 | [window setContentView:view]; 65 | [window orderFront:self]; 66 | [window makeKey:self]; 67 | 68 | NSTimeInterval totalDelay; 69 | [self _showLightFlourishWithTotalDelay:&totalDelay]; 70 | [self performSelector:@selector(_setUpNextLevel) withObject:nil afterDelay:totalDelay]; 71 | } 72 | 73 | - (void)applicationWillTerminate:(NSNotification *)notification; 74 | { 75 | [puzzles release]; 76 | } 77 | 78 | 79 | #pragma mark API 80 | 81 | - (BOOL)isAcceptingInput; 82 | { 83 | return isAcceptingInput; 84 | } 85 | 86 | - (NSString *)currentLevelString; 87 | { 88 | return currentLevelString; 89 | } 90 | 91 | - (void)pressButtonView:(LOButtonView *)buttonView; 92 | { 93 | if (!isAcceptingInput) 94 | return; 95 | 96 | NSString *buttonName = [[[view buttonNamesToViews] allKeysForObject:buttonView] lastObject]; 97 | 98 | // do the Lights Out! logic 99 | [self _toggleButtonView:buttonView]; 100 | unsigned int buttonNumber = [[buttonName substringFromIndex:[@"button" length]] intValue]; 101 | if ((buttonNumber % ROW_COUNT) != 1) // left 102 | [self _toggleButtonView:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (buttonNumber - 1)]]]; 103 | if ((buttonNumber % ROW_COUNT) != 0) // right 104 | [self _toggleButtonView:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (buttonNumber + 1)]]]; 105 | if (buttonNumber > ROW_COUNT) // up if > 5 106 | [self _toggleButtonView:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (buttonNumber - ROW_COUNT)]]]; 107 | if (buttonNumber <= (ROW_COUNT * COLUMN_COUNT) - ROW_COUNT) // down if <= 20 108 | [self _toggleButtonView:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (buttonNumber + ROW_COUNT)]]]; 109 | 110 | // show the glare if the button is being lit 111 | static UIImage *glareImage; 112 | if (!glareImage) 113 | glareImage = [[UIImage imageNamed:@"lo-button-glare"] retain]; 114 | 115 | // show glare and add fade animation 116 | CGPoint buttonCenter = [buttonView frame].origin; 117 | buttonCenter.x -= CGRectGetWidth([buttonView frame]) - 8.0; 118 | buttonCenter.y -= (CGRectGetHeight([buttonView frame]) / 2.0) + 40.0; 119 | LOGlareView *glareView = [[[LOGlareView alloc] initWithFrame:(CGRect){buttonCenter, {175.0, 175.0}}] autorelease]; 120 | [glareView setBackgroundColor:[glareView colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0]]; 121 | [view addSubview:glareView]; 122 | #define GLARE_FADE_ANIMATION (0.4) 123 | [UIView beginAnimations:nil]; 124 | [UIView setAnimationDuration:GLARE_FADE_ANIMATION]; { 125 | [glareView setAlpha:0.0]; 126 | } [UIView endAnimations]; 127 | [glareView performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:GLARE_FADE_ANIMATION]; 128 | 129 | // check for a win 130 | BOOL didWin = YES; 131 | NSEnumerator *buttonEnumerator = [[view buttonNamesToViews] objectEnumerator]; 132 | LOButtonView *currentButtonView = nil; 133 | while ((currentButtonView = [buttonEnumerator nextObject])) 134 | didWin &= ![currentButtonView isLightOn]; 135 | if (didWin) { 136 | [self _setCurrentLevelString:@"Nice!"]; 137 | [self _showWinFlourishAndSetUpNextLevel]; 138 | } 139 | } 140 | 141 | - (void)reset; 142 | { 143 | isAcceptingInput = NO; 144 | [self _turnOffAllLights]; 145 | currentLevel--; 146 | NSTimeInterval totalDelay; 147 | [self _showLightFlourishWithTotalDelay:&totalDelay]; 148 | [self performSelector:@selector(_setUpNextLevel) withObject:nil afterDelay:totalDelay]; 149 | } 150 | 151 | - (void)skipToNextLevel; 152 | { 153 | isAcceptingInput = NO; 154 | [self _turnOffAllLights]; 155 | NSTimeInterval totalDelay; 156 | [self _showLightFlourishWithTotalDelay:&totalDelay]; 157 | [self performSelector:@selector(_setUpNextLevel) withObject:nil afterDelay:totalDelay]; 158 | } 159 | 160 | - (void)skipToPreviousLevel; 161 | { 162 | isAcceptingInput = NO; 163 | [self _turnOffAllLights]; 164 | currentLevel -= 2; 165 | NSTimeInterval totalDelay; 166 | [self _showLightFlourishWithTotalDelay:&totalDelay]; 167 | [self performSelector:@selector(_setUpNextLevel) withObject:nil afterDelay:totalDelay]; 168 | } 169 | 170 | #pragma mark Private API 171 | 172 | - (void)_executeLightSequence:(unsigned int *)lightSequence count:(unsigned int)count delayBetweenLights:(NSTimeInterval)lightDelay totalDelay:(NSTimeInterval *)totalDelay; 173 | { 174 | NSTimeInterval currentDelay = 0.0; 175 | unsigned int lightIndex = 0; 176 | while (lightIndex < count) { 177 | LOButtonView *buttonView = [[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", lightSequence[lightIndex++]]]; 178 | [self performSelector:@selector(_toggleButtonView:) withObject:buttonView afterDelay:currentDelay]; 179 | currentDelay += lightDelay; 180 | [self performSelector:@selector(_toggleButtonView:) withObject:buttonView afterDelay:currentDelay]; 181 | } 182 | currentDelay += lightDelay; 183 | if (totalDelay) 184 | *totalDelay = currentDelay; 185 | } 186 | 187 | - (void)_setCurrentLevelString:(NSString *)string; 188 | { 189 | [currentLevelString autorelease]; 190 | currentLevelString = [string retain]; 191 | [view setNeedsDisplay]; 192 | } 193 | 194 | - (void)_setUpNextLevel; 195 | { 196 | unsigned int levelCount = [puzzles count]; 197 | if ((currentLevel + 1) > levelCount) 198 | currentLevel = 0; 199 | else if (currentLevel < 1) 200 | currentLevel = 0; 201 | 202 | NSString *layoutString = [puzzles objectAtIndex:currentLevel++]; 203 | unsigned int indexInLayoutString = 0, rowIndex, columnIndex; 204 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 205 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 206 | unichar layoutCharacter = [layoutString characterAtIndex:indexInLayoutString++]; 207 | if (layoutCharacter == 'x') 208 | [self _toggleButtonView:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (((ROW_COUNT - 1) - rowIndex) * ROW_COUNT) + (columnIndex + 1)]]]; 209 | } 210 | 211 | // skip divider 212 | indexInLayoutString++; 213 | } 214 | 215 | [self _setCurrentLevelString:[NSString stringWithFormat:@"%d", currentLevel]]; 216 | 217 | isAcceptingInput = YES; 218 | } 219 | 220 | - (void)_showLightFlourishWithTotalDelay:(NSTimeInterval *)totalDelay; 221 | { 222 | isAcceptingInput = NO; 223 | 224 | NSTimeInterval lightDelay = 0.0; 225 | unsigned int rowIndex, columnIndex; 226 | 227 | // up lit 228 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 229 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 230 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 231 | } 232 | lightDelay += 0.05; 233 | } 234 | 235 | // up dark 236 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 237 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 238 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 239 | } 240 | lightDelay += 0.05; 241 | } 242 | 243 | // left lit 244 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 245 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 246 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 247 | } 248 | lightDelay += 0.05; 249 | } 250 | 251 | // left dark 252 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 253 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 254 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 255 | } 256 | lightDelay += 0.05; 257 | } 258 | 259 | // one by one lit 260 | NSTimeInterval previousDelay = lightDelay; 261 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 262 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 263 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 264 | lightDelay += 0.05; 265 | } 266 | } 267 | lightDelay = previousDelay + 0.05; 268 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 269 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 270 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 271 | lightDelay += 0.05; 272 | } 273 | } 274 | 275 | if (totalDelay) 276 | *totalDelay = lightDelay; 277 | } 278 | 279 | - (void)_showWinFlourishAndSetUpNextLevel; 280 | { 281 | isAcceptingInput = NO; 282 | 283 | // spiral sequence 284 | static unsigned int winLightSequence[] = {1, 6, 11, 16, 21, 22, 23, 24, 25, 20, 15, 10, 5, 4, 3, 2, 7, 12, 17, 18, 19, 14, 9, 8, 7, 12, 13}; 285 | NSTimeInterval winLightSequenceDelay; 286 | [self _executeLightSequence:winLightSequence count:(sizeof(winLightSequence) / sizeof(*winLightSequence)) delayBetweenLights:0.03 totalDelay:&winLightSequenceDelay]; 287 | [self performSelector:@selector(_setUpNextLevel) withObject:nil afterDelay:winLightSequenceDelay]; 288 | } 289 | 290 | - (void)_toggleButtonView:(LOButtonView *)buttonView; 291 | { 292 | [buttonView setLightOn:![buttonView isLightOn]]; 293 | } 294 | 295 | - (void)_turnOffAllLights; 296 | { 297 | NSEnumerator *buttonEnumerator = [[view buttonNamesToViews] objectEnumerator]; 298 | LOButtonView *currentButtonView = nil; 299 | while ((currentButtonView = [buttonEnumerator nextObject])) 300 | if ([currentButtonView isLightOn]) 301 | [currentButtonView setLightOn:NO]; 302 | } 303 | 304 | @end 305 | -------------------------------------------------------------------------------- /Classes/LODoneButtonView.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | @interface LODoneButtonView : UIView { 5 | BOOL pressed; 6 | } 7 | @end 8 | -------------------------------------------------------------------------------- /Classes/LODoneButtonView.m: -------------------------------------------------------------------------------- 1 | 2 | #import "LODoneButtonView.h" 3 | 4 | #import "LOController.h" 5 | #import "LOView.h" 6 | 7 | @implementation LODoneButtonView 8 | 9 | 10 | #pragma mark UIResponder 11 | 12 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 13 | { 14 | pressed = YES; 15 | [self setNeedsDisplay]; 16 | } 17 | 18 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 19 | { 20 | pressed = NO; 21 | [self setNeedsDisplay]; 22 | 23 | [[[self superview] superview] hideInfo]; 24 | } 25 | 26 | #pragma mark UIView 27 | 28 | - (void)drawRect:(CGRect)rect; 29 | { 30 | if (!pressed) { 31 | static UIImage *doneButtonImage; 32 | if (!doneButtonImage) 33 | doneButtonImage = [[UIImage imageNamed:@"lo-button-done.png"] retain]; 34 | [doneButtonImage drawInRect:rect]; 35 | } else { 36 | static UIImage *doneButtonPressedImage; 37 | if (!doneButtonPressedImage) 38 | doneButtonPressedImage = [[UIImage imageNamed:@"lo-button-done-press.png"] retain]; 39 | [doneButtonPressedImage drawInRect:rect]; 40 | } 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /Classes/LOGlareView.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | @interface LOGlareView : UIView { 5 | } 6 | @end 7 | -------------------------------------------------------------------------------- /Classes/LOGlareView.m: -------------------------------------------------------------------------------- 1 | 2 | #import "LOGlareView.h" 3 | 4 | #import "LOController.h" 5 | 6 | @implementation LOGlareView 7 | 8 | #pragma mark UIView 9 | 10 | - (void)drawRect:(CGRect)rect; 11 | { 12 | static UIImage *buttonGlareImage; 13 | if (!buttonGlareImage) 14 | buttonGlareImage = [[UIImage imageNamed:@"lo-button-glare.png"] retain]; 15 | [buttonGlareImage drawInRect:rect]; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Classes/LOHighlightView.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | @class LOButtonView; 5 | 6 | @interface LOHighlightView : UIView { 7 | LOButtonView *buttonView; 8 | } 9 | - (id)initWithFrame:(CGRect)frame buttonView:(LOButtonView *)button; 10 | @end 11 | -------------------------------------------------------------------------------- /Classes/LOHighlightView.m: -------------------------------------------------------------------------------- 1 | 2 | #import "LOHighlightView.h" 3 | 4 | #import "LOButtonView.h" 5 | #import "LOController.h" 6 | 7 | @implementation LOHighlightView 8 | 9 | #pragma mark API 10 | 11 | - (id)initWithFrame:(CGRect)frame buttonView:(LOButtonView *)button; 12 | { 13 | if (![super initWithFrame:frame]) 14 | return nil; 15 | buttonView = button; // non-retained 16 | return self; 17 | } 18 | 19 | 20 | #pragma mark UIResponder 21 | 22 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 23 | { 24 | [buttonView touchesBegan:touches withEvent:event]; 25 | } 26 | 27 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 28 | { 29 | [buttonView touchesEnded:touches withEvent:event]; 30 | } 31 | 32 | 33 | 34 | #pragma mark UIView 35 | 36 | - (void)drawRect:(CGRect)rect; 37 | { 38 | static UIImage *buttonGlowImage; 39 | if (!buttonGlowImage) 40 | buttonGlowImage = [[UIImage imageNamed:@"lo-button-fullglow.png"] retain]; 41 | [buttonGlowImage drawInRect:rect]; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /Classes/LOInfoButtonView.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | @interface LOInfoButtonView : UIView { 5 | BOOL pressed; 6 | } 7 | @end 8 | -------------------------------------------------------------------------------- /Classes/LOInfoButtonView.m: -------------------------------------------------------------------------------- 1 | 2 | #import "LOInfoButtonView.h" 3 | 4 | #import "LOController.h" 5 | #import "LOView.h" 6 | 7 | @implementation LOInfoButtonView 8 | 9 | 10 | #pragma mark UIResponder 11 | 12 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 13 | { 14 | pressed = YES; 15 | [self setNeedsDisplay]; 16 | } 17 | 18 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 19 | { 20 | pressed = NO; 21 | [self setNeedsDisplay]; 22 | 23 | [[self superview] showInfo]; 24 | } 25 | 26 | #pragma mark UIView 27 | 28 | - (void)drawRect:(CGRect)rect; 29 | { 30 | if (!pressed) { 31 | static UIImage *infoButtonImage; 32 | if (!infoButtonImage) 33 | infoButtonImage = [[UIImage imageNamed:@"lo-button-info.png"] retain]; 34 | [infoButtonImage drawInRect:rect]; 35 | } else { 36 | static UIImage *infoButtonPressedImage; 37 | if (!infoButtonPressedImage) 38 | infoButtonPressedImage = [[UIImage imageNamed:@"lo-button-info-press.png"] retain]; 39 | [infoButtonPressedImage drawInRect:rect]; 40 | } 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /Classes/LOInfoView.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | @interface LOInfoView : UIView { 5 | } 6 | @end 7 | -------------------------------------------------------------------------------- /Classes/LOInfoView.m: -------------------------------------------------------------------------------- 1 | 2 | #import "LOInfoView.h" 3 | 4 | #import "LOController.h" 5 | 6 | @implementation LOInfoView 7 | 8 | #pragma mark UIView 9 | 10 | - (void)drawRect:(CGRect)rect; 11 | { 12 | static UIImage *infoImage; 13 | if (!infoImage) 14 | infoImage = [[UIImage imageNamed:@"lo-background-info.png"] retain]; 15 | [infoImage drawInRect:rect]; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Classes/LOResetView.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | @interface LOResetView : UIView { 5 | BOOL pressed; 6 | } 7 | @end 8 | -------------------------------------------------------------------------------- /Classes/LOResetView.m: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | #import "LOResetView.h" 5 | 6 | #import "LOController.h" 7 | 8 | @implementation LOResetView 9 | 10 | 11 | #pragma mark UIResponder 12 | 13 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 14 | { 15 | pressed = YES; 16 | [self setNeedsDisplay]; 17 | } 18 | 19 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 20 | { 21 | pressed = NO; 22 | [self setNeedsDisplay]; 23 | 24 | [[self superview] reset]; 25 | } 26 | 27 | #pragma mark UIView 28 | 29 | - (void)drawRect:(CGRect)rect; 30 | { 31 | if (!pressed) { 32 | static UIImage *resetImage; 33 | if (!resetImage) 34 | resetImage = [[UIImage imageNamed:@"lo-button-reset.png"] retain]; 35 | [resetImage drawInRect:rect]; 36 | } else { 37 | static UIImage *resetPressedImage; 38 | if (!resetPressedImage) 39 | resetPressedImage = [[UIImage imageNamed:@"lo-button-reset-press.png"] retain]; 40 | [resetPressedImage drawInRect:rect]; 41 | } 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /Classes/LOView.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | @class LightsOffTouchAppDelegate, LOInfoView, LOButtonView, LOController; 5 | 6 | @interface LOView : UIView { 7 | LightsOffTouchAppDelegate *controller; 8 | LOInfoView *infoView; 9 | NSMutableDictionary *buttonNamesToViews; 10 | UILabel *levelTextLabel; 11 | } 12 | 13 | // API 14 | - (id)initWithFrame:(CGRect)frame controller:(LightsOffTouchAppDelegate *)viewController; 15 | - (NSDictionary *)buttonNamesToViews; 16 | - (void)pressButtonView:(LOButtonView *)buttonView; 17 | - (void)showInfo; 18 | - (void)hideInfo; 19 | - (void)reset; 20 | - (void)skipToNextLevel; 21 | - (void)skipToPreviousLevel; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Classes/LOView.m: -------------------------------------------------------------------------------- 1 | 2 | #import "LOView.h" 3 | 4 | //#import "LOController.h" 5 | #import "LightsOffTouchAppDelegate.h" 6 | #import "LOButtonView.h" 7 | #import "LOButtonGlowView.h" 8 | //#import "LOHighlightView.h" 9 | #import "LOInfoButtonView.h" 10 | #import "LOInfoView.h" 11 | #import "LODoneButtonView.h" 12 | #import "LOResetView.h" 13 | 14 | @implementation LOView 15 | 16 | #pragma mark NSObject 17 | 18 | - (void)dealloc; 19 | { 20 | [buttonNamesToViews release]; 21 | [super dealloc]; 22 | } 23 | 24 | 25 | #pragma mark UIResponder 26 | 27 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 28 | { 29 | // unpress all buttons? 30 | } 31 | 32 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 33 | { 34 | // unpress all buttons? 35 | } 36 | 37 | 38 | #pragma mark UIView 39 | 40 | - (void)drawRect:(CGRect)rect; 41 | { 42 | static UIImage *backgroundImage; 43 | if (!backgroundImage) 44 | backgroundImage = [[UIImage imageNamed:@"lo-background.png"] retain]; 45 | 46 | [backgroundImage drawInRect:rect]; 47 | 48 | [levelTextLabel setText:[controller currentLevelString]]; 49 | } 50 | 51 | 52 | #pragma mark API 53 | 54 | - (id)initWithFrame:(CGRect)frame controller:(LightsOffTouchAppDelegate *)viewController; 55 | { 56 | if (![super initWithFrame:frame]) 57 | return nil; 58 | 59 | controller = viewController; // non-retained 60 | 61 | buttonNamesToViews = [[NSMutableDictionary alloc] init]; 62 | 63 | UIColor *clearColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.0]; 64 | [self setBackgroundColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0]]; 65 | 66 | #define MATRIX_DISTANCE_FROM_BOTTOM (56.0) 67 | unsigned int rowIndex, columnIndex; 68 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 69 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 70 | LOButtonView *buttonView = [[[LOButtonView alloc] initWithFrame:CGRectOffset(CGRectMake(rowIndex * 64.0, columnIndex * 64.0, 63.0, 57.0), 0.0, MATRIX_DISTANCE_FROM_BOTTOM)] autorelease]; 71 | // TODO: [buttonView setClipsSubviews:NO]; // make sure the highlight can extend (doesn't actually work) 72 | //[[buttonView _layer] setMasksToBounds:NO]; // this doesn't work either 73 | [buttonView setBackgroundColor:clearColor]; 74 | [buttonNamesToViews setObject:buttonView forKey:[NSString stringWithFormat:@"button%d", (columnIndex * ROW_COUNT) + (rowIndex + 1)]]; 75 | [buttonView setLightOn:NO]; 76 | [self addSubview:buttonView]; 77 | } 78 | } 79 | 80 | // add glowing logo 81 | UIImageView *glowingLogoView = [[[UIImageView alloc] initWithFrame:CGRectMake(17.0, 0.0, 285.0, 50.0)] autorelease]; 82 | [glowingLogoView setImage:[UIImage imageNamed:@"lo-logoglow.png"]]; 83 | [self addSubview:glowingLogoView]; 84 | [UIView beginAnimations:nil context:NULL]; 85 | [UIView setAnimationRepeatCount:1e7]; 86 | [UIView setAnimationDuration:3.0]; 87 | [UIView setAnimationRepeatAutoreverses:YES]; 88 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; { 89 | [glowingLogoView setAlpha:0.0]; 90 | } [UIView commitAnimations]; 91 | 92 | // add info button 93 | LOInfoButtonView *infoButton = [[[LOInfoButtonView alloc] initWithFrame:CGRectMake(226.0, 387.0, 76.0, 24.0)] autorelease]; 94 | [infoButton setBackgroundColor:clearColor]; 95 | [self addSubview:infoButton]; 96 | 97 | // add reset button 98 | LOResetView *resetButton = [[[LOResetView alloc] initWithFrame:CGRectMake(226.0, 422.0, 76.0, 24.0)] autorelease]; 99 | [resetButton setBackgroundColor:clearColor]; 100 | [self addSubview:resetButton]; 101 | 102 | // add level skip buttons 103 | LOButtonGlowView *leftButtonGlow = [[[LOButtonGlowView alloc] initWithFrame:CGRectMake(40.0, 410.0, 40.0, 40.0)] autorelease]; 104 | [leftButtonGlow setButtonType:LOButtonGlowLeft]; 105 | [leftButtonGlow setBackgroundColor:clearColor]; 106 | [self addSubview:leftButtonGlow]; 107 | LOButtonGlowView *rightButtonGlow = [[[LOButtonGlowView alloc] initWithFrame:CGRectMake(112.0, 411.0, 40.0, 40.0)] autorelease]; 108 | [rightButtonGlow setButtonType:LOButtonGlowRight]; 109 | [rightButtonGlow setBackgroundColor:clearColor]; 110 | [self addSubview:rightButtonGlow]; 111 | 112 | // add the level text 113 | levelTextLabel = [[[UILabel alloc] initWithFrame:CGRectMake(54.0, 390.0, 84.0, 22.0)] autorelease]; // non-retained 114 | [levelTextLabel setTextColor:[UIColor colorWithRed:(242.0 / 255.0) green:(84.0 / 255.0) blue:(83.0 / 255.0) alpha:1.0]]; 115 | [levelTextLabel setBackgroundColor:clearColor]; 116 | [levelTextLabel setShadowColor:[UIColor colorWithRed:(205.0 / 255.0) green:(33.0 / 255.0) blue:(31.0 / 255.0) alpha:1.0]]; 117 | [levelTextLabel setShadowOffset:CGSizeMake(1.0, 1.0)]; 118 | [levelTextLabel setTextAlignment:NSTextAlignmentCenter]; 119 | [self addSubview:levelTextLabel]; 120 | 121 | // add hidden info window 122 | infoView = [[[LOInfoView alloc] initWithFrame:CGRectOffset([self bounds], 0.0, -CGRectGetHeight([self bounds]))] autorelease]; // non-retained 123 | [self addSubview:infoView]; 124 | 125 | // add done button to info window 126 | LODoneButtonView *doneButtonView = [[[LODoneButtonView alloc] initWithFrame:CGRectMake(125.0, 420.0, 76.0, 24.0)] autorelease]; 127 | [doneButtonView setBackgroundColor:clearColor]; 128 | [infoView addSubview:doneButtonView]; 129 | 130 | return self; 131 | } 132 | 133 | - (NSDictionary *)buttonNamesToViews; 134 | { 135 | return buttonNamesToViews; 136 | } 137 | 138 | - (void)pressButtonView:(LOButtonView *)buttonView; 139 | { 140 | // unpress all other buttons... 141 | NSEnumerator *buttonEnumerator = [buttonNamesToViews objectEnumerator]; 142 | LOButtonView *currentButtonView = nil; 143 | while ((currentButtonView = [buttonEnumerator nextObject])) 144 | if (currentButtonView != buttonView && [currentButtonView isPressed]) 145 | [currentButtonView setPressed:NO]; 146 | 147 | // send on to the controller for game logic 148 | [controller pressButtonView:buttonView]; 149 | } 150 | 151 | - (void)showInfo; 152 | { 153 | [UIView beginAnimations:nil context:NULL]; { 154 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 155 | [UIView setAnimationDuration:0.75]; 156 | [infoView setFrame:[self bounds]]; 157 | } [UIView commitAnimations]; 158 | } 159 | 160 | - (void)hideInfo; 161 | { 162 | [UIView beginAnimations:nil context:NULL]; { 163 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 164 | [UIView setAnimationDuration:0.75]; 165 | [infoView setFrame:CGRectOffset([self bounds], 0.0, -CGRectGetHeight([self bounds]))]; 166 | } [UIView commitAnimations]; 167 | } 168 | 169 | - (void)reset; 170 | { 171 | [controller reset]; 172 | } 173 | 174 | - (void)skipToNextLevel; 175 | { 176 | if ([controller isAcceptingInput]) 177 | [controller skipToNextLevel]; 178 | } 179 | 180 | - (void)skipToPreviousLevel; 181 | { 182 | if ([controller isAcceptingInput]) 183 | [controller skipToPreviousLevel]; 184 | } 185 | 186 | @end 187 | -------------------------------------------------------------------------------- /Classes/LightsOffTouchAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // LightsOffTouchAppDelegate.h 3 | // LightsOffTouch 4 | // 5 | // Created by Craig Hockenberry on 6/6/08. 6 | // Copyright The Iconfactory 2008. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "LOView.h" 12 | 13 | @class LightsOffTouchViewController; 14 | 15 | @interface LightsOffTouchAppDelegate : NSObject 16 | { 17 | UIWindow *window; 18 | LOView *view; 19 | 20 | NSArray *puzzles; 21 | 22 | BOOL isAcceptingInput; 23 | NSInteger currentLevel; 24 | NSString *currentLevelString; 25 | } 26 | 27 | - (NSString *)currentLevelString; 28 | - (BOOL)isAcceptingInput; 29 | - (void)pressButtonView:(LOButtonView *)buttonView; 30 | - (void)reset; 31 | - (void)skipToNextLevel; 32 | - (void)skipToPreviousLevel; 33 | 34 | @end 35 | 36 | #define ROW_COUNT (5) 37 | #define COLUMN_COUNT (5) 38 | -------------------------------------------------------------------------------- /Classes/LightsOffTouchAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // LightsOffTouchAppDelegate.m 3 | // LightsOffTouch 4 | // 5 | // Created by Craig Hockenberry on 6/6/08. 6 | // Copyright The Iconfactory 2008. All rights reserved. 7 | // 8 | 9 | #import "LightsOffTouchAppDelegate.h" 10 | 11 | #import "LOButtonView.h" 12 | #import "LOGlareView.h" 13 | #import "LOHighlightView.h" 14 | #import "LOView.h" 15 | 16 | @interface LightsOffTouchAppDelegate (Private) 17 | - (void)_executeLightSequence:(unsigned int *)lightSequence count:(unsigned int)count delayBetweenLights:(NSTimeInterval)lightDelay totalDelay:(NSTimeInterval *)totalDelay; 18 | - (void)_setCurrentLevelString:(NSString *)string; 19 | - (void)_setUpNextLevel; 20 | - (void)_showLightFlourishWithTotalDelay:(NSTimeInterval *)totalDelay; 21 | - (void)_showWinFlourishAndSetUpNextLevel; 22 | - (void)_toggleButtonView:(LOButtonView *)buttonView; 23 | - (void)_turnOffAllLights; 24 | @end 25 | 26 | @implementation LightsOffTouchAppDelegate 27 | 28 | /* 29 | During the Jailbreak era, no one had any idea what they were doing. The original LOController is reinterpreted here 30 | as both an application delegate and a view controller. See what I mean? 31 | 32 | The window and view hierarchy is simple, yet many changes were needed to adapt this code to the a more modern environment. 33 | For example, windows are now required to have a root view controller (the one here does nothing except host the LOView.) 34 | I've also added a simulated status bar that mimics how the views were managed prior to iOS 7 and the fullscreenification. 35 | 36 | I've also tried to follow coding conventions from the original code. Remember that back in 2007, there were no things like 37 | Objective-C properties and hard coding constants using #defines was de rigueur. It's also fun to look back fondly on the 38 | joys of retain and release. 39 | 40 | And who needs NIB files, much less storyboards and segues? 41 | 42 | Anyway, enjoy this look at the past and remember, this is NOT how you should do things now :-) 43 | */ 44 | 45 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 46 | { 47 | puzzles = [[[[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"puzzles" ofType:@"plist"]] allValues] lastObject] retain]; 48 | 49 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 50 | currentLevel = [userDefaults integerForKey:@"currentLevel"]; 51 | 52 | #define STATUS_BAR_HEIGHT (20.0) 53 | 54 | CGRect bounds = [[UIScreen mainScreen] bounds]; 55 | CGRect frame = bounds; 56 | frame.origin.y += STATUS_BAR_HEIGHT; 57 | frame.size.height -= STATUS_BAR_HEIGHT; 58 | 59 | window = [[UIWindow alloc] initWithFrame:bounds]; 60 | view = [[LOView alloc] initWithFrame:frame controller:self]; 61 | 62 | // a root view controller on the window is now a requirement after the app is launched 63 | UIViewController *viewController = [[[UIViewController alloc] init] autorelease]; 64 | viewController.view = view; 65 | [window setRootViewController:viewController]; 66 | 67 | [window makeKeyAndVisible]; 68 | 69 | // to look a little less ridiculous on the iPhone X, simulate the old school status bar from early (non-fullscreen) versions of iOS 70 | [view setFrame:frame]; 71 | UIView *statusBarView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, bounds.size.width, STATUS_BAR_HEIGHT)] autorelease]; 72 | #if 1 73 | // simulate a gray status bar 74 | // 75 | // there's no evidence of which kind of status was used in the Jailbreak code (no Info.plist) 76 | // but my failing memory remembers that it was gray in in the first version 77 | // also, the gray version was the default, and there was no documentation explaining how to change it 78 | 79 | [statusBarView setBackgroundColor:[UIColor colorWithRed:0.349 green:0.388 blue:0.392 alpha:1.000]]; 80 | CAGradientLayer *gradientLayer = [CAGradientLayer layer]; 81 | CGRect gradientFrame = [statusBarView bounds]; 82 | gradientFrame.size.height -= 1.0; 83 | [gradientLayer setFrame:gradientFrame]; 84 | UIColor *topColor = [UIColor colorWithRed:0.933 green:0.965 blue:0.976 alpha:1.0]; 85 | UIColor *bottomColor = [UIColor colorWithRed:0.741 green:0.780 blue:0.784 alpha:1.0]; 86 | [gradientLayer setColors:[NSArray arrayWithObjects:(id)[topColor CGColor], (id)[bottomColor CGColor], nil]]; 87 | [[statusBarView layer] addSublayer:gradientLayer]; 88 | [application setStatusBarStyle: UIStatusBarStyleDefault]; 89 | #else 90 | // simulate a black status bar 91 | // 92 | // this image shows the black status bar: http://www.artofadambetts.com/weblog/2007/08/lights-off-first-native-iphone-game/ 93 | // but the level counter is also different than this original version, so it's not clear if this is a mockup or a screenshot 94 | 95 | statusBarView.backgroundColor = [UIColor colorWithWhite:0.255 alpha:1.0]; 96 | [application setStatusBarStyle: UIStatusBarStyleLightContent]; 97 | #endif 98 | [window insertSubview:statusBarView aboveSubview:view]; 99 | 100 | NSTimeInterval totalDelay; 101 | [self _showLightFlourishWithTotalDelay:&totalDelay]; 102 | [self performSelector:@selector(_setUpNextLevel) withObject:nil afterDelay:totalDelay]; 103 | 104 | return YES; 105 | } 106 | 107 | - (void)applicationDidEnterBackground:(UIApplication *)application 108 | { 109 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 110 | [userDefaults setInteger:(currentLevel - 1) forKey:@"currentLevel"]; 111 | [userDefaults synchronize]; 112 | } 113 | 114 | - (void)applicationWillTerminate:(UIApplication *)application 115 | { 116 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 117 | [userDefaults setInteger:(currentLevel - 1) forKey:@"currentLevel"]; 118 | [userDefaults synchronize]; 119 | } 120 | 121 | - (void)dealloc 122 | { 123 | [window release]; 124 | [view release]; 125 | [super dealloc]; 126 | } 127 | 128 | #pragma mark API 129 | 130 | - (BOOL)isAcceptingInput; 131 | { 132 | return isAcceptingInput; 133 | } 134 | 135 | - (NSString *)currentLevelString; 136 | { 137 | return currentLevelString; 138 | } 139 | 140 | - (void)pressButtonView:(LOButtonView *)buttonView; 141 | { 142 | if (!isAcceptingInput) 143 | return; 144 | 145 | NSString *buttonName = [[[view buttonNamesToViews] allKeysForObject:buttonView] lastObject]; 146 | 147 | // do the Lights Out! logic 148 | [self _toggleButtonView:buttonView]; 149 | unsigned int buttonNumber = [[buttonName substringFromIndex:[@"button" length]] intValue]; 150 | if ((buttonNumber % ROW_COUNT) != 1) // left 151 | [self _toggleButtonView:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (buttonNumber - 1)]]]; 152 | if ((buttonNumber % ROW_COUNT) != 0) // right 153 | [self _toggleButtonView:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (buttonNumber + 1)]]]; 154 | if (buttonNumber > ROW_COUNT) // up if > 5 155 | [self _toggleButtonView:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (buttonNumber - ROW_COUNT)]]]; 156 | if (buttonNumber <= (ROW_COUNT * COLUMN_COUNT) - ROW_COUNT) // down if <= 20 157 | [self _toggleButtonView:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (buttonNumber + ROW_COUNT)]]]; 158 | 159 | // show the glare if the button is being lit 160 | static UIImage *glareImage; 161 | if (!glareImage) 162 | glareImage = [[UIImage imageNamed:@"lo-button-glare"] retain]; 163 | 164 | // show glare and add fade animation 165 | CGPoint buttonCenter = [buttonView frame].origin; 166 | buttonCenter.x -= CGRectGetWidth([buttonView frame]) - 8.0; 167 | buttonCenter.y -= (CGRectGetHeight([buttonView frame]) / 2.0) + 40.0; 168 | LOGlareView *glareView = [[[LOGlareView alloc] initWithFrame:(CGRect){buttonCenter, {175.0, 175.0}}] autorelease]; 169 | [glareView setBackgroundColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0]]; 170 | [view addSubview:glareView]; 171 | #define GLARE_FADE_ANIMATION (0.4) 172 | [UIView beginAnimations:nil context:NULL]; 173 | [UIView setAnimationDuration:GLARE_FADE_ANIMATION]; { 174 | [glareView setAlpha:0.0]; 175 | } [UIView commitAnimations]; 176 | [glareView performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:GLARE_FADE_ANIMATION]; 177 | 178 | // check for a win 179 | BOOL didWin = YES; 180 | NSEnumerator *buttonEnumerator = [[view buttonNamesToViews] objectEnumerator]; 181 | LOButtonView *currentButtonView = nil; 182 | while ((currentButtonView = [buttonEnumerator nextObject])) 183 | didWin &= ![currentButtonView isLightOn]; 184 | if (didWin) { 185 | [self _setCurrentLevelString:@"Nice!"]; 186 | [self _showWinFlourishAndSetUpNextLevel]; 187 | } 188 | } 189 | 190 | - (void)reset; 191 | { 192 | isAcceptingInput = NO; 193 | [self _turnOffAllLights]; 194 | currentLevel--; 195 | NSTimeInterval totalDelay; 196 | [self _showLightFlourishWithTotalDelay:&totalDelay]; 197 | [self performSelector:@selector(_setUpNextLevel) withObject:nil afterDelay:totalDelay]; 198 | } 199 | 200 | - (void)skipToNextLevel; 201 | { 202 | isAcceptingInput = NO; 203 | [self _turnOffAllLights]; 204 | NSUInteger levelCount = [puzzles count]; 205 | if ((currentLevel + 1) > levelCount) 206 | currentLevel = 0; 207 | NSTimeInterval totalDelay; 208 | [self _showLightFlourishWithTotalDelay:&totalDelay]; 209 | [self performSelector:@selector(_setUpNextLevel) withObject:nil afterDelay:totalDelay]; 210 | } 211 | 212 | - (void)skipToPreviousLevel; 213 | { 214 | isAcceptingInput = NO; 215 | [self _turnOffAllLights]; 216 | currentLevel -= 2; 217 | if (currentLevel < 0) { 218 | NSUInteger levelCount = [puzzles count]; 219 | currentLevel = levelCount - 1; 220 | } 221 | NSTimeInterval totalDelay; 222 | [self _showLightFlourishWithTotalDelay:&totalDelay]; 223 | [self performSelector:@selector(_setUpNextLevel) withObject:nil afterDelay:totalDelay]; 224 | } 225 | 226 | #pragma mark Private API 227 | 228 | - (void)_executeLightSequence:(unsigned int *)lightSequence count:(unsigned int)count delayBetweenLights:(NSTimeInterval)lightDelay totalDelay:(NSTimeInterval *)totalDelay; 229 | { 230 | NSTimeInterval currentDelay = 0.0; 231 | unsigned int lightIndex = 0; 232 | while (lightIndex < count) { 233 | LOButtonView *buttonView = [[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", lightSequence[lightIndex++]]]; 234 | [self performSelector:@selector(_toggleButtonView:) withObject:buttonView afterDelay:currentDelay]; 235 | currentDelay += lightDelay; 236 | [self performSelector:@selector(_toggleButtonView:) withObject:buttonView afterDelay:currentDelay]; 237 | } 238 | currentDelay += lightDelay; 239 | if (totalDelay) 240 | *totalDelay = currentDelay; 241 | } 242 | 243 | - (void)_setCurrentLevelString:(NSString *)string; 244 | { 245 | [currentLevelString autorelease]; 246 | currentLevelString = [string retain]; 247 | [view setNeedsDisplay]; 248 | } 249 | 250 | - (void)_setUpNextLevel; 251 | { 252 | NSUInteger levelCount = [puzzles count]; 253 | if ((currentLevel + 1) > levelCount) 254 | currentLevel = 0; 255 | else if (currentLevel < 1) 256 | currentLevel = 0; 257 | 258 | NSString *layoutString = [puzzles objectAtIndex:currentLevel++]; 259 | unsigned int indexInLayoutString = 0, rowIndex, columnIndex; 260 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 261 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 262 | unichar layoutCharacter = [layoutString characterAtIndex:indexInLayoutString++]; 263 | if (layoutCharacter == 'x') 264 | [self _toggleButtonView:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (((ROW_COUNT - 1) - rowIndex) * ROW_COUNT) + (columnIndex + 1)]]]; 265 | } 266 | 267 | // skip divider 268 | indexInLayoutString++; 269 | } 270 | 271 | [self _setCurrentLevelString:[NSString stringWithFormat:@"%zd", currentLevel]]; 272 | 273 | isAcceptingInput = YES; 274 | } 275 | 276 | - (void)_showLightFlourishWithTotalDelay:(NSTimeInterval *)totalDelay; 277 | { 278 | isAcceptingInput = NO; 279 | 280 | NSTimeInterval lightDelay = 0.0; 281 | unsigned int rowIndex, columnIndex; 282 | 283 | // up lit 284 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 285 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 286 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 287 | } 288 | lightDelay += 0.05; 289 | } 290 | 291 | // up dark 292 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 293 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 294 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 295 | } 296 | lightDelay += 0.05; 297 | } 298 | 299 | // left lit 300 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 301 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 302 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 303 | } 304 | lightDelay += 0.05; 305 | } 306 | 307 | // left dark 308 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 309 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 310 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 311 | } 312 | lightDelay += 0.05; 313 | } 314 | 315 | // one by one lit 316 | NSTimeInterval previousDelay = lightDelay; 317 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 318 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 319 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 320 | lightDelay += 0.05; 321 | } 322 | } 323 | lightDelay = previousDelay + 0.05; 324 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 325 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 326 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 327 | lightDelay += 0.05; 328 | } 329 | } 330 | 331 | if (totalDelay) 332 | *totalDelay = lightDelay; 333 | } 334 | 335 | - (void)_showWinFlourishAndSetUpNextLevel; 336 | { 337 | isAcceptingInput = NO; 338 | 339 | // spiral sequence 340 | static unsigned int winLightSequence[] = {1, 6, 11, 16, 21, 22, 23, 24, 25, 20, 15, 10, 5, 4, 3, 2, 7, 12, 17, 18, 19, 14, 9, 8, 7, 12, 13}; 341 | NSTimeInterval winLightSequenceDelay; 342 | [self _executeLightSequence:winLightSequence count:(sizeof(winLightSequence) / sizeof(*winLightSequence)) delayBetweenLights:0.03 totalDelay:&winLightSequenceDelay]; 343 | [self performSelector:@selector(_setUpNextLevel) withObject:nil afterDelay:winLightSequenceDelay]; 344 | } 345 | 346 | - (void)_toggleButtonView:(LOButtonView *)buttonView; 347 | { 348 | [buttonView setLightOn:![buttonView isLightOn]]; 349 | } 350 | 351 | - (void)_turnOffAllLights; 352 | { 353 | NSEnumerator *buttonEnumerator = [[view buttonNamesToViews] objectEnumerator]; 354 | LOButtonView *currentButtonView = nil; 355 | while ((currentButtonView = [buttonEnumerator nextObject])) 356 | if ([currentButtonView isLightOn]) 357 | [currentButtonView setLightOn:NO]; 358 | } 359 | 360 | @end 361 | -------------------------------------------------------------------------------- /Images/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Images/Default.png -------------------------------------------------------------------------------- /Images/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Images/Icon.png -------------------------------------------------------------------------------- /Images/lo-background-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Images/lo-background-info.png -------------------------------------------------------------------------------- /Images/lo-background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Images/lo-background.png -------------------------------------------------------------------------------- /Images/lo-button-done-press.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Images/lo-button-done-press.png -------------------------------------------------------------------------------- /Images/lo-button-done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Images/lo-button-done.png -------------------------------------------------------------------------------- /Images/lo-button-fullglow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Images/lo-button-fullglow.png -------------------------------------------------------------------------------- /Images/lo-button-glare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Images/lo-button-glare.png -------------------------------------------------------------------------------- /Images/lo-button-info-press.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Images/lo-button-info-press.png -------------------------------------------------------------------------------- /Images/lo-button-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Images/lo-button-info.png -------------------------------------------------------------------------------- /Images/lo-button-off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Images/lo-button-off.png -------------------------------------------------------------------------------- /Images/lo-button-on-press.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Images/lo-button-on-press.png -------------------------------------------------------------------------------- /Images/lo-button-press.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Images/lo-button-press.png -------------------------------------------------------------------------------- /Images/lo-button-reset-press.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Images/lo-button-reset-press.png -------------------------------------------------------------------------------- /Images/lo-button-reset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Images/lo-button-reset.png -------------------------------------------------------------------------------- /Images/lo-glowpress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Images/lo-glowpress.png -------------------------------------------------------------------------------- /Images/lo-logoglow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Images/lo-logoglow.png -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFile 12 | Icon.png 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | LSRequiresIPhoneOS 26 | 27 | UIPrerenderedIcon 28 | 1 29 | UIStatusBarStyle 30 | UIStatusBarStyleLightContent 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | 35 | UIViewControllerBasedStatusBarAppearance 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Jailbreak/LOButtonGlowView.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | typedef enum { 5 | LOButtonGlowLeft, 6 | LOButtonGlowRight 7 | } LOButtonGlowType; 8 | 9 | @interface LOButtonGlowView : UIView { 10 | BOOL pressed; 11 | LOButtonGlowType type; 12 | } 13 | 14 | // API 15 | - (void)setButtonType:(LOButtonGlowType)buttonType; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Jailbreak/LOButtonGlowView.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | #import "LOButtonGlowView.h" 6 | 7 | #import "LOController.h" 8 | 9 | @implementation LOButtonGlowView 10 | 11 | 12 | #pragma mark UIResponder 13 | 14 | - (void)mouseDown:(GSEvent *)event; 15 | { 16 | pressed = YES; 17 | [self setNeedsDisplay]; 18 | } 19 | 20 | - (void)mouseUp:(GSEvent *)event; 21 | { 22 | pressed = NO; 23 | [self setNeedsDisplay]; 24 | 25 | (type == LOButtonGlowLeft) ? [[self superview] skipToPreviousLevel] : [[self superview] skipToNextLevel]; 26 | } 27 | 28 | 29 | #pragma mark UIView 30 | 31 | - (void)drawRect:(CGRect)rect; 32 | { 33 | if (pressed) { 34 | static UIImage *buttonGlowImage; 35 | if (!buttonGlowImage) 36 | buttonGlowImage = [[UIImage applicationImageNamed:@"lo-glowpress.png"] retain]; 37 | [buttonGlowImage draw1PartImageInRect:rect]; 38 | } 39 | } 40 | 41 | 42 | #pragma mark API 43 | 44 | - (void)setButtonType:(LOButtonGlowType)buttonType; 45 | { 46 | type = buttonType; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Jailbreak/LOButtonView.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface LOButtonView : UIView { 5 | BOOL lightOn; 6 | BOOL pressed; 7 | } 8 | 9 | - (void)setLightOn:(BOOL)isOn; 10 | - (BOOL)isLightOn; 11 | - (void)setPressed:(BOOL)isPressed; 12 | - (BOOL)isPressed; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Jailbreak/LOButtonView.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | 6 | #import "LOButtonView.h" 7 | 8 | #import "LOController.h" 9 | #import "LOView.h" 10 | 11 | @implementation LOButtonView 12 | 13 | #pragma mark UIView 14 | 15 | - (void)drawRect:(CGRect)rect; 16 | { 17 | if (!pressed) { 18 | static UIImage *buttonOffImage; 19 | if (!buttonOffImage) 20 | buttonOffImage = [[UIImage applicationImageNamed:@"lo-button-off.png"] retain]; 21 | [buttonOffImage draw1PartImageInRect:rect]; 22 | 23 | if (lightOn) { 24 | static UIImage *buttonGlowImage; 25 | if (!buttonGlowImage) 26 | buttonGlowImage = [[UIImage applicationImageNamed:@"lo-button-fullglow.png"] retain]; 27 | [buttonGlowImage draw1PartImageInRect:CGRectInset(rect, -8.0, -10.0)]; 28 | } 29 | } else { 30 | if (!lightOn) { 31 | static UIImage *buttonPressedImage; 32 | if (!buttonPressedImage) 33 | buttonPressedImage = [[UIImage applicationImageNamed:@"lo-button-press.png"] retain]; 34 | [buttonPressedImage draw1PartImageInRect:rect]; 35 | } else { 36 | static UIImage *buttonOnPressedImage; 37 | if (!buttonOnPressedImage) 38 | buttonOnPressedImage = [[UIImage applicationImageNamed:@"lo-button-on-press.png"] retain]; 39 | [buttonOnPressedImage draw1PartImageInRect:rect]; 40 | } 41 | } 42 | } 43 | 44 | 45 | #pragma mark UIResponder 46 | 47 | - (void)mouseDown:(GSEvent *)event; 48 | { 49 | [self setPressed:YES]; 50 | } 51 | 52 | - (void)mouseUp:(GSEvent *)event; 53 | { 54 | [self setPressed:NO]; 55 | [(LOView *)[self superview] pressButtonView:self]; 56 | } 57 | 58 | 59 | #pragma mark API 60 | 61 | - (void)setLightOn:(BOOL)isOn; 62 | { 63 | lightOn = isOn; 64 | [self setNeedsDisplay]; 65 | } 66 | 67 | - (BOOL)isLightOn; 68 | { 69 | return lightOn; 70 | } 71 | 72 | - (void)setPressed:(BOOL)isPressed; 73 | { 74 | pressed = isPressed; 75 | [self setNeedsDisplay]; 76 | } 77 | 78 | - (BOOL)isPressed; 79 | { 80 | return pressed; 81 | } 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /Jailbreak/LOController.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #import 5 | #import // hack 6 | 7 | #import 8 | #import 9 | 10 | //extern void GSEventPlaySoundAtPath(); 11 | //3098d28c T _GSEventGetAccessoryKeyStateInfo 12 | //3098c160 T _GSEventGetCharacterSet 13 | //3098c07c T _GSEventGetClickCount 14 | //3098bfcc T _GSEventGetDeltaX 15 | //3098bfec T _GSEventGetDeltaY 16 | //3098db90 T _GSEventGetEventNumber 17 | //3098bf40 T _GSEventGetHandInfo 18 | //3098d7b4 T _GSEventGetInnerMostPathPosition 19 | //3098d9b4 T _GSEventGetKeyCode 20 | //3098c1d4 T _GSEventGetKeyWindow 21 | //3098bf84 T _GSEventGetLocationInWindow 22 | //3098c168 T _GSEventGetModifierFlags 23 | //3098d7e4 T _GSEventGetOuterMostPathPosition 24 | //3098bf60 T _GSEventGetPathInfoAtIndex 25 | //3098bfb0 T _GSEventGetSubType 26 | //3098c084 T _GSEventGetTimestamp 27 | //3098bc70 T _GSEventGetType 28 | //3098bddc T _GSEventGetTypeID 29 | //3098dbac T _GSEventGetWindow 30 | 31 | // Constants 32 | typedef enum { 33 | kUIAnimationCurveEaseInEaseOut, 34 | kUIAnimationCurveEaseIn, 35 | kUIAnimationCurveEaseOut, 36 | kUIAnimationCurveLinear 37 | } UIAnimationCurve; 38 | 39 | @interface UIView(Color) 40 | - (CGColorRef)colorWithRed:(float)red green:(float)green blue:(float)blue alpha:(float)alpha; 41 | @end 42 | 43 | @class LOButtonView, LOView; 44 | 45 | @interface LOController : UIApplication { 46 | UIWindow *window; 47 | LOView *view; 48 | NSArray *puzzles; 49 | 50 | BOOL isAcceptingInput; 51 | unsigned int currentLevel; 52 | NSString *currentLevelString; 53 | } 54 | 55 | - (NSString *)currentLevelString; 56 | - (BOOL)isAcceptingInput; 57 | - (void)pressButtonView:(LOButtonView *)buttonView; 58 | - (void)reset; 59 | - (void)skipToNextLevel; 60 | - (void)skipToPreviousLevel; 61 | @end 62 | 63 | #define ROW_COUNT (5) 64 | #define COLUMN_COUNT (5) -------------------------------------------------------------------------------- /Jailbreak/LOController.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | #import 6 | #import 7 | #import 8 | #import 9 | 10 | #import 11 | 12 | #import "LOController.h" 13 | 14 | #import "LOButtonView.h" 15 | #import "LOGlareView.h" 16 | #import "LOHighlightView.h" 17 | #import "LOView.h" 18 | 19 | #pragma mark - 20 | 21 | @implementation UIView(Color) 22 | 23 | - (CGColorRef)colorWithRed:(float)red green:(float)green blue:(float)blue alpha:(float)alpha; 24 | { 25 | float rgba[4]; 26 | rgba[0] = red; 27 | rgba[1] = green; 28 | rgba[2] = blue; 29 | rgba[3] = alpha; 30 | CGColorRef color = (CGColorRef)[(id)CGColorCreate((CGColorSpaceRef)[(id)CGColorSpaceCreateDeviceRGB() autorelease], rgba) autorelease]; 31 | return color; 32 | } 33 | 34 | @end 35 | 36 | #pragma mark - 37 | 38 | @interface LOController (Private) 39 | - (void)_executeLightSequence:(unsigned int *)lightSequence count:(unsigned int)count delayBetweenLights:(NSTimeInterval)lightDelay totalDelay:(NSTimeInterval *)totalDelay; 40 | - (void)_setCurrentLevelString:(NSString *)string; 41 | - (void)_setUpNextLevel; 42 | - (void)_showLightFlourishWithTotalDelay:(NSTimeInterval *)totalDelay; 43 | - (void)_showWinFlourishAndSetUpNextLevel; 44 | - (void)_toggleButtonView:(LOButtonView *)buttonView; 45 | - (void)_turnOffAllLights; 46 | @end 47 | 48 | #pragma mark - 49 | 50 | @implementation LOController 51 | 52 | 53 | #pragma mark NSObject 54 | 55 | - (void)dealloc; 56 | { 57 | [window release]; 58 | [view release]; 59 | [super dealloc]; 60 | } 61 | 62 | - (void)awakeFromNib; 63 | { 64 | } 65 | 66 | #pragma mark UIApplication 67 | 68 | - (void)applicationDidFinishLaunching:(NSNotification *)notification; 69 | { 70 | puzzles = [[[[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"puzzles" ofType:@"plist"]] allValues] lastObject] retain]; 71 | 72 | window = [[UIWindow alloc] initWithContentRect:[UIHardware fullScreenApplicationContentRect]]; 73 | view = [[LOView alloc] initWithFrame:[window bounds] controller:self]; 74 | [window setContentView:view]; 75 | [window orderFront:self]; 76 | [window makeKey:self]; 77 | 78 | NSTimeInterval totalDelay; 79 | [self _showLightFlourishWithTotalDelay:&totalDelay]; 80 | [self performSelector:@selector(_setUpNextLevel) withObject:nil afterDelay:totalDelay]; 81 | } 82 | 83 | - (void)applicationWillTerminate:(NSNotification *)notification; 84 | { 85 | [puzzles release]; 86 | } 87 | 88 | 89 | #pragma mark API 90 | 91 | - (BOOL)isAcceptingInput; 92 | { 93 | return isAcceptingInput; 94 | } 95 | 96 | - (NSString *)currentLevelString; 97 | { 98 | return currentLevelString; 99 | } 100 | 101 | - (void)pressButtonView:(LOButtonView *)buttonView; 102 | { 103 | if (!isAcceptingInput) 104 | return; 105 | 106 | NSString *buttonName = [[[view buttonNamesToViews] allKeysForObject:buttonView] lastObject]; 107 | 108 | // do the Lights Out! logic 109 | [self _toggleButtonView:buttonView]; 110 | unsigned int buttonNumber = [[buttonName substringFromIndex:[@"button" length]] intValue]; 111 | if ((buttonNumber % ROW_COUNT) != 1) // left 112 | [self _toggleButtonView:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (buttonNumber - 1)]]]; 113 | if ((buttonNumber % ROW_COUNT) != 0) // right 114 | [self _toggleButtonView:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (buttonNumber + 1)]]]; 115 | if (buttonNumber > ROW_COUNT) // up if > 5 116 | [self _toggleButtonView:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (buttonNumber - ROW_COUNT)]]]; 117 | if (buttonNumber <= (ROW_COUNT * COLUMN_COUNT) - ROW_COUNT) // down if <= 20 118 | [self _toggleButtonView:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (buttonNumber + ROW_COUNT)]]]; 119 | 120 | // show the glare if the button is being lit 121 | static UIImage *glareImage; 122 | if (!glareImage) 123 | glareImage = [[UIImage applicationImageNamed:@"lo-button-glare"] retain]; 124 | 125 | // show glare and add fade animation 126 | CGPoint buttonCenter = [buttonView frame].origin; 127 | buttonCenter.x -= CGRectGetWidth([buttonView frame]) - 8.0; 128 | buttonCenter.y -= (CGRectGetHeight([buttonView frame]) / 2.0) + 40.0; 129 | LOGlareView *glareView = [[[LOGlareView alloc] initWithFrame:(CGRect){buttonCenter, {175.0, 175.0}}] autorelease]; 130 | [glareView setBackgroundColor:[glareView colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0]]; 131 | [view addSubview:glareView]; 132 | #define GLARE_FADE_ANIMATION (0.4) 133 | [UIView beginAnimations:nil]; 134 | [UIView setAnimationDuration:GLARE_FADE_ANIMATION]; { 135 | [glareView setAlpha:0.0]; 136 | } [UIView endAnimations]; 137 | [glareView performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:GLARE_FADE_ANIMATION]; 138 | 139 | // check for a win 140 | BOOL didWin = YES; 141 | NSEnumerator *buttonEnumerator = [[view buttonNamesToViews] objectEnumerator]; 142 | LOButtonView *currentButtonView = nil; 143 | while ((currentButtonView = [buttonEnumerator nextObject])) 144 | didWin &= ![currentButtonView isLightOn]; 145 | if (didWin) { 146 | [self _setCurrentLevelString:@"Nice!"]; 147 | [self _showWinFlourishAndSetUpNextLevel]; 148 | } 149 | } 150 | 151 | - (void)reset; 152 | { 153 | isAcceptingInput = NO; 154 | [self _turnOffAllLights]; 155 | currentLevel--; 156 | NSTimeInterval totalDelay; 157 | [self _showLightFlourishWithTotalDelay:&totalDelay]; 158 | [self performSelector:@selector(_setUpNextLevel) withObject:nil afterDelay:totalDelay]; 159 | } 160 | 161 | - (void)skipToNextLevel; 162 | { 163 | isAcceptingInput = NO; 164 | [self _turnOffAllLights]; 165 | NSTimeInterval totalDelay; 166 | [self _showLightFlourishWithTotalDelay:&totalDelay]; 167 | [self performSelector:@selector(_setUpNextLevel) withObject:nil afterDelay:totalDelay]; 168 | } 169 | 170 | - (void)skipToPreviousLevel; 171 | { 172 | isAcceptingInput = NO; 173 | [self _turnOffAllLights]; 174 | currentLevel -= 2; 175 | NSTimeInterval totalDelay; 176 | [self _showLightFlourishWithTotalDelay:&totalDelay]; 177 | [self performSelector:@selector(_setUpNextLevel) withObject:nil afterDelay:totalDelay]; 178 | } 179 | 180 | #pragma mark Private API 181 | 182 | - (void)_executeLightSequence:(unsigned int *)lightSequence count:(unsigned int)count delayBetweenLights:(NSTimeInterval)lightDelay totalDelay:(NSTimeInterval *)totalDelay; 183 | { 184 | NSTimeInterval currentDelay = 0.0; 185 | unsigned int lightIndex = 0; 186 | while (lightIndex < count) { 187 | LOButtonView *buttonView = [[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", lightSequence[lightIndex++]]]; 188 | [self performSelector:@selector(_toggleButtonView:) withObject:buttonView afterDelay:currentDelay]; 189 | currentDelay += lightDelay; 190 | [self performSelector:@selector(_toggleButtonView:) withObject:buttonView afterDelay:currentDelay]; 191 | } 192 | currentDelay += lightDelay; 193 | if (totalDelay) 194 | *totalDelay = currentDelay; 195 | } 196 | 197 | - (void)_setCurrentLevelString:(NSString *)string; 198 | { 199 | [currentLevelString autorelease]; 200 | currentLevelString = [string retain]; 201 | [view setNeedsDisplay]; 202 | } 203 | 204 | - (void)_setUpNextLevel; 205 | { 206 | unsigned int levelCount = [puzzles count]; 207 | if ((currentLevel + 1) > levelCount) 208 | currentLevel = 0; 209 | else if (currentLevel < 1) 210 | currentLevel = 0; 211 | 212 | NSString *layoutString = [puzzles objectAtIndex:currentLevel++]; 213 | unsigned int indexInLayoutString = 0, rowIndex, columnIndex; 214 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 215 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 216 | unichar layoutCharacter = [layoutString characterAtIndex:indexInLayoutString++]; 217 | if (layoutCharacter == 'x') 218 | [self _toggleButtonView:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (((ROW_COUNT - 1) - rowIndex) * ROW_COUNT) + (columnIndex + 1)]]]; 219 | } 220 | 221 | // skip divider 222 | indexInLayoutString++; 223 | } 224 | 225 | [self _setCurrentLevelString:[NSString stringWithFormat:@"%d", currentLevel]]; 226 | 227 | isAcceptingInput = YES; 228 | } 229 | 230 | - (void)_showLightFlourishWithTotalDelay:(NSTimeInterval *)totalDelay; 231 | { 232 | isAcceptingInput = NO; 233 | 234 | NSTimeInterval lightDelay = 0.0; 235 | unsigned int rowIndex, columnIndex; 236 | 237 | // up lit 238 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 239 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 240 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 241 | } 242 | lightDelay += 0.05; 243 | } 244 | 245 | // up dark 246 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 247 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 248 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 249 | } 250 | lightDelay += 0.05; 251 | } 252 | 253 | // left lit 254 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 255 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 256 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 257 | } 258 | lightDelay += 0.05; 259 | } 260 | 261 | // left dark 262 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 263 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 264 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 265 | } 266 | lightDelay += 0.05; 267 | } 268 | 269 | // one by one lit 270 | NSTimeInterval previousDelay = lightDelay; 271 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 272 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 273 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 274 | lightDelay += 0.05; 275 | } 276 | } 277 | lightDelay = previousDelay + 0.05; 278 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 279 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 280 | [self performSelector:@selector(_toggleButtonView:) withObject:[[view buttonNamesToViews] objectForKey:[NSString stringWithFormat:@"button%d", (rowIndex * ROW_COUNT) + (columnIndex + 1)]] afterDelay:lightDelay]; 281 | lightDelay += 0.05; 282 | } 283 | } 284 | 285 | if (totalDelay) 286 | *totalDelay = lightDelay; 287 | } 288 | 289 | - (void)_showWinFlourishAndSetUpNextLevel; 290 | { 291 | isAcceptingInput = NO; 292 | 293 | // spiral sequence 294 | static unsigned int winLightSequence[] = {1, 6, 11, 16, 21, 22, 23, 24, 25, 20, 15, 10, 5, 4, 3, 2, 7, 12, 17, 18, 19, 14, 9, 8, 7, 12, 13}; 295 | NSTimeInterval winLightSequenceDelay; 296 | [self _executeLightSequence:winLightSequence count:(sizeof(winLightSequence) / sizeof(*winLightSequence)) delayBetweenLights:0.03 totalDelay:&winLightSequenceDelay]; 297 | [self performSelector:@selector(_setUpNextLevel) withObject:nil afterDelay:winLightSequenceDelay]; 298 | } 299 | 300 | - (void)_toggleButtonView:(LOButtonView *)buttonView; 301 | { 302 | [buttonView setLightOn:![buttonView isLightOn]]; 303 | } 304 | 305 | - (void)_turnOffAllLights; 306 | { 307 | NSEnumerator *buttonEnumerator = [[view buttonNamesToViews] objectEnumerator]; 308 | LOButtonView *currentButtonView = nil; 309 | while ((currentButtonView = [buttonEnumerator nextObject])) 310 | if ([currentButtonView isLightOn]) 311 | [currentButtonView setLightOn:NO]; 312 | } 313 | 314 | @end 315 | -------------------------------------------------------------------------------- /Jailbreak/LODoneButtonView.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface LODoneButtonView : UIView { 5 | BOOL pressed; 6 | } 7 | @end 8 | -------------------------------------------------------------------------------- /Jailbreak/LODoneButtonView.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | 6 | #import "LODoneButtonView.h" 7 | 8 | #import "LOController.h" 9 | #import "LOView.h" 10 | 11 | @implementation LODoneButtonView 12 | 13 | 14 | #pragma mark UIResponder 15 | 16 | - (void)mouseDown:(GSEvent *)event; 17 | { 18 | pressed = YES; 19 | [self setNeedsDisplay]; 20 | } 21 | 22 | - (void)mouseUp:(GSEvent *)event; 23 | { 24 | pressed = NO; 25 | [self setNeedsDisplay]; 26 | 27 | [[[self superview] superview] hideInfo]; 28 | } 29 | 30 | #pragma mark UIView 31 | 32 | - (void)drawRect:(CGRect)rect; 33 | { 34 | if (!pressed) { 35 | static UIImage *doneButtonImage; 36 | if (!doneButtonImage) 37 | doneButtonImage = [[UIImage applicationImageNamed:@"lo-button-done.png"] retain]; 38 | [doneButtonImage draw1PartImageInRect:rect]; 39 | } else { 40 | static UIImage *doneButtonPressedImage; 41 | if (!doneButtonPressedImage) 42 | doneButtonPressedImage = [[UIImage applicationImageNamed:@"lo-button-done-press.png"] retain]; 43 | [doneButtonPressedImage draw1PartImageInRect:rect]; 44 | } 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Jailbreak/LOGlareView.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface LOGlareView : UIView { 5 | } 6 | @end 7 | -------------------------------------------------------------------------------- /Jailbreak/LOGlareView.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | 6 | #import "LOGlareView.h" 7 | 8 | #import "LOController.h" 9 | 10 | @implementation LOGlareView 11 | 12 | #pragma mark UIView 13 | 14 | - (void)drawRect:(CGRect)rect; 15 | { 16 | static UIImage *buttonGlareImage; 17 | if (!buttonGlareImage) 18 | buttonGlareImage = [[UIImage applicationImageNamed:@"lo-button-glare.png"] retain]; 19 | [buttonGlareImage draw1PartImageInRect:rect]; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Jailbreak/LOHighlightView.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @class LOButtonView; 5 | 6 | @interface LOHighlightView : UIView { 7 | LOButtonView *buttonView; 8 | } 9 | - (id)initWithFrame:(CGRect)frame buttonView:(LOButtonView *)button; 10 | @end 11 | -------------------------------------------------------------------------------- /Jailbreak/LOHighlightView.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | 6 | #import "LOHighlightView.h" 7 | 8 | #import "LOButtonView.h" 9 | #import "LOController.h" 10 | 11 | @implementation LOHighlightView 12 | 13 | #pragma mark API 14 | 15 | - (id)initWithFrame:(CGRect)frame buttonView:(LOButtonView *)button; 16 | { 17 | if (![super initWithFrame:frame]) 18 | return nil; 19 | buttonView = button; // non-retained 20 | return self; 21 | } 22 | 23 | 24 | #pragma mark UIResponder 25 | 26 | // pass the events though 27 | - (void)mouseDown:(GSEvent *)event; 28 | { [buttonView mouseDown:event]; } 29 | - (void)mouseUp:(GSEvent *)event; 30 | { [buttonView mouseUp:event]; } 31 | 32 | 33 | #pragma mark UIView 34 | 35 | - (void)drawRect:(CGRect)rect; 36 | { 37 | static UIImage *buttonGlowImage; 38 | if (!buttonGlowImage) 39 | buttonGlowImage = [[UIImage applicationImageNamed:@"lo-button-fullglow.png"] retain]; 40 | [buttonGlowImage draw1PartImageInRect:rect]; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /Jailbreak/LOInfoButtonView.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface LOInfoButtonView : UIView { 5 | BOOL pressed; 6 | } 7 | @end 8 | -------------------------------------------------------------------------------- /Jailbreak/LOInfoButtonView.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | 6 | #import "LOInfoButtonView.h" 7 | 8 | #import "LOController.h" 9 | #import "LOView.h" 10 | 11 | @implementation LOInfoButtonView 12 | 13 | 14 | #pragma mark UIResponder 15 | 16 | - (void)mouseDown:(GSEvent *)event; 17 | { 18 | pressed = YES; 19 | [self setNeedsDisplay]; 20 | } 21 | 22 | - (void)mouseUp:(GSEvent *)event; 23 | { 24 | pressed = NO; 25 | [self setNeedsDisplay]; 26 | 27 | [[self superview] showInfo]; 28 | } 29 | 30 | #pragma mark UIView 31 | 32 | - (void)drawRect:(CGRect)rect; 33 | { 34 | if (!pressed) { 35 | static UIImage *infoButtonImage; 36 | if (!infoButtonImage) 37 | infoButtonImage = [[UIImage applicationImageNamed:@"lo-button-info.png"] retain]; 38 | [infoButtonImage draw1PartImageInRect:rect]; 39 | } else { 40 | static UIImage *infoButtonPressedImage; 41 | if (!infoButtonPressedImage) 42 | infoButtonPressedImage = [[UIImage applicationImageNamed:@"lo-button-info-press.png"] retain]; 43 | [infoButtonPressedImage draw1PartImageInRect:rect]; 44 | } 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Jailbreak/LOInfoView.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface LOInfoView : UIView { 5 | } 6 | @end 7 | -------------------------------------------------------------------------------- /Jailbreak/LOInfoView.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | 6 | #import "LOInfoView.h" 7 | 8 | #import "LOController.h" 9 | 10 | @implementation LOInfoView 11 | 12 | #pragma mark UIView 13 | 14 | - (void)drawRect:(CGRect)rect; 15 | { 16 | static UIImage *infoImage; 17 | if (!infoImage) 18 | infoImage = [[UIImage applicationImageNamed:@"lo-background-info.png"] retain]; 19 | [infoImage draw1PartImageInRect:rect]; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Jailbreak/LOResetView.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface LOResetView : UIView { 5 | BOOL pressed; 6 | } 7 | @end 8 | -------------------------------------------------------------------------------- /Jailbreak/LOResetView.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | 6 | #import "LOResetView.h" 7 | 8 | #import "LOController.h" 9 | 10 | @implementation LOResetView 11 | 12 | 13 | #pragma mark UIResponder 14 | 15 | - (void)mouseDown:(GSEvent *)event; 16 | { 17 | pressed = YES; 18 | [self setNeedsDisplay]; 19 | } 20 | 21 | - (void)mouseUp:(GSEvent *)event; 22 | { 23 | pressed = NO; 24 | [self setNeedsDisplay]; 25 | 26 | [[self superview] reset]; 27 | } 28 | 29 | #pragma mark UIView 30 | 31 | - (void)drawRect:(CGRect)rect; 32 | { 33 | if (!pressed) { 34 | static UIImage *resetImage; 35 | if (!resetImage) 36 | resetImage = [[UIImage applicationImageNamed:@"lo-button-reset.png"] retain]; 37 | [resetImage draw1PartImageInRect:rect]; 38 | } else { 39 | static UIImage *resetPressedImage; 40 | if (!resetPressedImage) 41 | resetPressedImage = [[UIImage applicationImageNamed:@"lo-button-reset-press.png"] retain]; 42 | [resetPressedImage draw1PartImageInRect:rect]; 43 | } 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Jailbreak/LOView.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @class LOInfoView, LOButtonView, LOController, UITextLabel; 5 | 6 | @interface LOView : UIView { 7 | LOController *controller; 8 | LOInfoView *infoView; 9 | NSMutableDictionary *buttonNamesToViews; 10 | UITextLabel *levelTextLabel; 11 | } 12 | 13 | // API 14 | - (id)initWithFrame:(CGRect)frame controller:(LOController *)viewController; 15 | - (NSDictionary *)buttonNamesToViews; 16 | - (void)pressButtonView:(LOButtonView *)buttonView; 17 | - (void)showInfo; 18 | - (void)hideInfo; 19 | - (void)reset; 20 | - (void)skipToNextLevel; 21 | - (void)skipToPreviousLevel; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Jailbreak/LOView.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | #import 6 | #import 7 | #import 8 | 9 | #import "LOView.h" 10 | 11 | #import "LOController.h" 12 | #import "LOButtonView.h" 13 | #import "LOButtonGlowView.h" 14 | //#import "LOHighlightView.h" 15 | #import "LOInfoButtonView.h" 16 | #import "LOInfoView.h" 17 | #import "LODoneButtonView.h" 18 | #import "LOResetView.h" 19 | 20 | @implementation LOView 21 | 22 | #pragma mark NSObject 23 | 24 | - (void)dealloc; 25 | { 26 | [buttonNamesToViews release]; 27 | [super dealloc]; 28 | } 29 | 30 | 31 | #pragma mark UIResponder 32 | 33 | - (void)mouseDown:(GSEvent *)event; 34 | { 35 | // unpress all buttons? 36 | } 37 | 38 | - (void)mouseUp:(GSEvent *)event; 39 | { 40 | // unpress all buttons? 41 | } 42 | 43 | 44 | #pragma mark UIView 45 | 46 | - (void)drawRect:(CGRect)rect; 47 | { 48 | static UIImage *backgroundImage; 49 | if (!backgroundImage) 50 | backgroundImage = [[UIImage applicationImageNamed:@"lo-background.png"] retain]; 51 | 52 | [backgroundImage compositeToPoint:CGPointMake(0.0, -20.0) operation:1]; 53 | 54 | [levelTextLabel setText:[controller currentLevelString]]; 55 | } 56 | 57 | 58 | #pragma mark API 59 | 60 | - (id)initWithFrame:(CGRect)frame controller:(LOController *)viewController; 61 | { 62 | if (![super initWithFrame:frame]) 63 | return nil; 64 | 65 | controller = viewController; // non-retained 66 | 67 | buttonNamesToViews = [[NSMutableDictionary alloc] init]; 68 | 69 | CGColorRef clearColor = [self colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.0]; 70 | [self setBackgroundColor:[self colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0]]; 71 | 72 | #define MATRIX_DISTANCE_FROM_BOTTOM (56.0) 73 | unsigned int rowIndex, columnIndex; 74 | for (rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { 75 | for (columnIndex = 0; columnIndex < COLUMN_COUNT; columnIndex++) { 76 | LOButtonView *buttonView = [[[LOButtonView alloc] initWithFrame:CGRectOffset(CGRectMake(rowIndex * 64.0, columnIndex * 64.0, 63.0, 57.0), 0.0, MATRIX_DISTANCE_FROM_BOTTOM)] autorelease]; 77 | [buttonView setClipsSubviews:NO]; // make sure the highlight can extend (doesn't actually work) 78 | //[[buttonView _layer] setMasksToBounds:NO]; // this doesn't work either 79 | [buttonView setBackgroundColor:clearColor]; 80 | [buttonNamesToViews setObject:buttonView forKey:[NSString stringWithFormat:@"button%d", (columnIndex * ROW_COUNT) + (rowIndex + 1)]]; 81 | [buttonView setLightOn:NO]; 82 | [self addSubview:buttonView]; 83 | } 84 | } 85 | 86 | // add glowing logo 87 | UIImageView *glowingLogoView = [[[UIImageView alloc] initWithFrame:CGRectMake(17.0, 0.0, 288.0, 47.0)] autorelease]; 88 | [glowingLogoView setImage:[UIImage applicationImageNamed:@"lo-logoglow.png"]]; 89 | [self addSubview:glowingLogoView]; 90 | [UIView beginAnimations:nil]; 91 | [UIView setAnimationRepeatCount:1e7]; 92 | [UIView setAnimationDuration:3.0]; 93 | [UIView setAnimationAutoreverses:YES]; 94 | [UIView setAnimationCurve:kUIAnimationCurveEaseInEaseOut]; { 95 | [glowingLogoView setAlpha:0.0]; 96 | } [UIView endAnimations]; 97 | 98 | // add info button 99 | LOInfoButtonView *infoButton = [[[LOInfoButtonView alloc] initWithFrame:CGRectMake(226.0, 387.0, 76.0, 24.0)] autorelease]; 100 | [infoButton setBackgroundColor:clearColor]; 101 | [self addSubview:infoButton]; 102 | 103 | // add reset button 104 | LOResetView *resetButton = [[[LOResetView alloc] initWithFrame:CGRectMake(226.0, 422.0, 76.0, 24.0)] autorelease]; 105 | [resetButton setBackgroundColor:clearColor]; 106 | [self addSubview:resetButton]; 107 | 108 | // add level skip buttons 109 | LOButtonGlowView *leftButtonGlow = [[[LOButtonGlowView alloc] initWithFrame:CGRectMake(40.0, 410.0, 40.0, 40.0)] autorelease]; 110 | [leftButtonGlow setButtonType:LOButtonGlowLeft]; 111 | [leftButtonGlow setBackgroundColor:clearColor]; 112 | [self addSubview:leftButtonGlow]; 113 | LOButtonGlowView *rightButtonGlow = [[[LOButtonGlowView alloc] initWithFrame:CGRectMake(112.0, 411.0, 40.0, 40.0)] autorelease]; 114 | [rightButtonGlow setButtonType:LOButtonGlowRight]; 115 | [rightButtonGlow setBackgroundColor:clearColor]; 116 | [self addSubview:rightButtonGlow]; 117 | 118 | // add the level text 119 | levelTextLabel = [[[UITextLabel alloc] initWithFrame:CGRectMake(54.0, 390.0, 84.0, 22.0)] autorelease]; // non-retained 120 | [levelTextLabel setColor:[self colorWithRed:(242.0 / 255.0) green:(84.0 / 255.0) blue:(83.0 / 255.0) alpha:1.0]]; 121 | [levelTextLabel setBackgroundColor:clearColor]; 122 | [levelTextLabel setShadowColor:[self colorWithRed:(205.0 / 255.0) green:(33.0 / 255.0) blue:(31.0 / 255.0) alpha:1.0]]; 123 | [levelTextLabel setShadowOffset:CGSizeMake(1.0, 1.0)]; 124 | [levelTextLabel setCentersHorizontally:YES]; 125 | [self addSubview:levelTextLabel]; 126 | 127 | // add hidden info window 128 | infoView = [[[LOInfoView alloc] initWithFrame:CGRectOffset([self frame], 0.0, -CGRectGetHeight([self frame]))] autorelease]; // non-retained 129 | [self addSubview:infoView]; 130 | 131 | // add done button to info window 132 | LODoneButtonView *doneButtonView = [[[LODoneButtonView alloc] initWithFrame:CGRectMake(125.0, 430.0, 76.0, 24.0)] autorelease]; 133 | [doneButtonView setBackgroundColor:clearColor]; 134 | [infoView addSubview:doneButtonView]; 135 | 136 | return self; 137 | } 138 | 139 | - (NSDictionary *)buttonNamesToViews; 140 | { 141 | return buttonNamesToViews; 142 | } 143 | 144 | - (void)pressButtonView:(LOButtonView *)buttonView; 145 | { 146 | // unpress all other buttons... 147 | NSEnumerator *buttonEnumerator = [buttonNamesToViews objectEnumerator]; 148 | LOButtonView *currentButtonView = nil; 149 | while ((currentButtonView = [buttonEnumerator nextObject])) 150 | if (currentButtonView != buttonView && [currentButtonView isPressed]) 151 | [currentButtonView setPressed:NO]; 152 | 153 | // send on to the controller for game logic 154 | [controller pressButtonView:buttonView]; 155 | } 156 | 157 | - (void)showInfo; 158 | { 159 | [UIView beginAnimations:nil]; { 160 | [UIView setAnimationCurve:kUIAnimationCurveEaseInEaseOut]; 161 | [UIView setAnimationDuration:0.75]; 162 | [infoView setFrame:[self frame]]; 163 | } [UIView endAnimations]; 164 | } 165 | 166 | - (void)hideInfo; 167 | { 168 | [UIView beginAnimations:nil]; { 169 | [UIView setAnimationCurve:kUIAnimationCurveEaseInEaseOut]; 170 | [UIView setAnimationDuration:0.75]; 171 | [infoView setFrame:CGRectOffset([self frame], 0.0, -CGRectGetHeight([self frame]))]; 172 | } [UIView endAnimations]; 173 | } 174 | 175 | - (void)reset; 176 | { 177 | [controller reset]; 178 | } 179 | 180 | - (void)skipToNextLevel; 181 | { 182 | if ([controller isAcceptingInput]) 183 | [controller skipToNextLevel]; 184 | } 185 | 186 | - (void)skipToPreviousLevel; 187 | { 188 | if ([controller isAcceptingInput]) 189 | [controller skipToPreviousLevel]; 190 | } 191 | 192 | @end 193 | -------------------------------------------------------------------------------- /Jailbreak/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "LOController.h" 4 | 5 | int main(int argc, char **argv) 6 | { 7 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 8 | return UIApplicationMain(argc, argv, [LOController class]); 9 | [pool release]; 10 | } 11 | -------------------------------------------------------------------------------- /Lights Off - iPhone X Edition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chockenberry/LightsOffTouch/437647e60b13d57b76e0cc34b5e4ec5173652a39/Lights Off - iPhone X Edition.png -------------------------------------------------------------------------------- /LightsOffTouch.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1D3623260D0F684500981E51 /* LightsOffTouchAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* LightsOffTouchAppDelegate.m */; }; 11 | 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; 12 | 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 13 | 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 14 | 4464DBD620478507005E2DD8 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4464DBD520478507005E2DD8 /* QuartzCore.framework */; }; 15 | 4468FB040E06F6B600CA0D49 /* puzzles.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4468FB030E06F6B600CA0D49 /* puzzles.plist */; }; 16 | 4468FB190E06F7AB00CA0D49 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 4468FB170E06F7AB00CA0D49 /* Default.png */; }; 17 | 4468FB1A0E06F7AB00CA0D49 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4468FB180E06F7AB00CA0D49 /* Icon.png */; }; 18 | 449ED3AD0DF9F31D003B8713 /* LOButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = 449ED3990DF9F31D003B8713 /* LOButtonView.m */; }; 19 | 449ED3AE0DF9F31D003B8713 /* LOGlareView.m in Sources */ = {isa = PBXBuildFile; fileRef = 449ED39B0DF9F31D003B8713 /* LOGlareView.m */; }; 20 | 449ED3AF0DF9F31D003B8713 /* LODoneButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = 449ED39D0DF9F31D003B8713 /* LODoneButtonView.m */; }; 21 | 449ED3B00DF9F31D003B8713 /* LOInfoButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = 449ED39F0DF9F31D003B8713 /* LOInfoButtonView.m */; }; 22 | 449ED3B10DF9F31D003B8713 /* LOHighlightView.m in Sources */ = {isa = PBXBuildFile; fileRef = 449ED3A30DF9F31D003B8713 /* LOHighlightView.m */; }; 23 | 449ED3B20DF9F31D003B8713 /* LOResetView.m in Sources */ = {isa = PBXBuildFile; fileRef = 449ED3A40DF9F31D003B8713 /* LOResetView.m */; }; 24 | 449ED3B30DF9F31D003B8713 /* LOButtonGlowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 449ED3A50DF9F31D003B8713 /* LOButtonGlowView.m */; }; 25 | 449ED3B40DF9F31D003B8713 /* LOInfoView.m in Sources */ = {isa = PBXBuildFile; fileRef = 449ED3A70DF9F31D003B8713 /* LOInfoView.m */; }; 26 | 449ED3B50DF9F31D003B8713 /* LOView.m in Sources */ = {isa = PBXBuildFile; fileRef = 449ED3A90DF9F31D003B8713 /* LOView.m */; }; 27 | 44CABF080DF9F84200D934FD /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 44CABF070DF9F84200D934FD /* CoreGraphics.framework */; }; 28 | 44CABFDB0DF9FF4E00D934FD /* lo-background-info.png in Resources */ = {isa = PBXBuildFile; fileRef = 44CABFCB0DF9FF4E00D934FD /* lo-background-info.png */; }; 29 | 44CABFDC0DF9FF4E00D934FD /* lo-background.png in Resources */ = {isa = PBXBuildFile; fileRef = 44CABFCC0DF9FF4E00D934FD /* lo-background.png */; }; 30 | 44CABFDD0DF9FF4E00D934FD /* lo-button-done-press.png in Resources */ = {isa = PBXBuildFile; fileRef = 44CABFCD0DF9FF4E00D934FD /* lo-button-done-press.png */; }; 31 | 44CABFDE0DF9FF4E00D934FD /* lo-button-done.png in Resources */ = {isa = PBXBuildFile; fileRef = 44CABFCE0DF9FF4E00D934FD /* lo-button-done.png */; }; 32 | 44CABFDF0DF9FF4E00D934FD /* lo-button-fullglow.png in Resources */ = {isa = PBXBuildFile; fileRef = 44CABFCF0DF9FF4E00D934FD /* lo-button-fullglow.png */; }; 33 | 44CABFE00DF9FF4E00D934FD /* lo-button-glare.png in Resources */ = {isa = PBXBuildFile; fileRef = 44CABFD00DF9FF4E00D934FD /* lo-button-glare.png */; }; 34 | 44CABFE10DF9FF4E00D934FD /* lo-button-info-press.png in Resources */ = {isa = PBXBuildFile; fileRef = 44CABFD10DF9FF4E00D934FD /* lo-button-info-press.png */; }; 35 | 44CABFE20DF9FF4E00D934FD /* lo-button-info.png in Resources */ = {isa = PBXBuildFile; fileRef = 44CABFD20DF9FF4E00D934FD /* lo-button-info.png */; }; 36 | 44CABFE30DF9FF4E00D934FD /* lo-button-off.png in Resources */ = {isa = PBXBuildFile; fileRef = 44CABFD30DF9FF4E00D934FD /* lo-button-off.png */; }; 37 | 44CABFE40DF9FF4E00D934FD /* lo-button-on-press.png in Resources */ = {isa = PBXBuildFile; fileRef = 44CABFD40DF9FF4E00D934FD /* lo-button-on-press.png */; }; 38 | 44CABFE50DF9FF4E00D934FD /* lo-button-press.png in Resources */ = {isa = PBXBuildFile; fileRef = 44CABFD50DF9FF4E00D934FD /* lo-button-press.png */; }; 39 | 44CABFE60DF9FF4E00D934FD /* lo-button-reset-press.png in Resources */ = {isa = PBXBuildFile; fileRef = 44CABFD60DF9FF4E00D934FD /* lo-button-reset-press.png */; }; 40 | 44CABFE70DF9FF4E00D934FD /* lo-button-reset.png in Resources */ = {isa = PBXBuildFile; fileRef = 44CABFD70DF9FF4E00D934FD /* lo-button-reset.png */; }; 41 | 44CABFE80DF9FF4E00D934FD /* lo-glowpress.png in Resources */ = {isa = PBXBuildFile; fileRef = 44CABFD80DF9FF4E00D934FD /* lo-glowpress.png */; }; 42 | 44CABFE90DF9FF4E00D934FD /* lo-logoglow.png in Resources */ = {isa = PBXBuildFile; fileRef = 44CABFD90DF9FF4E00D934FD /* lo-logoglow.png */; }; 43 | /* End PBXBuildFile section */ 44 | 45 | /* Begin PBXFileReference section */ 46 | 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 47 | 1D3623240D0F684500981E51 /* LightsOffTouchAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LightsOffTouchAppDelegate.h; sourceTree = ""; }; 48 | 1D3623250D0F684500981E51 /* LightsOffTouchAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LightsOffTouchAppDelegate.m; sourceTree = ""; }; 49 | 1D6058910D05DD3D006BFB54 /* Lights Off.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Lights Off.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 51 | 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 52 | 32CA4F630368D1EE00C91783 /* LightsOffTouch_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LightsOffTouch_Prefix.pch; sourceTree = ""; }; 53 | 4464DBD520478507005E2DD8 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 54 | 4464DBDE204E206B005E2DD8 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 55 | 4468FB030E06F6B600CA0D49 /* puzzles.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = puzzles.plist; sourceTree = ""; }; 56 | 4468FB170E06F7AB00CA0D49 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = Images/Default.png; sourceTree = ""; }; 57 | 4468FB180E06F7AB00CA0D49 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Images/Icon.png; sourceTree = ""; }; 58 | 449ED3990DF9F31D003B8713 /* LOButtonView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LOButtonView.m; sourceTree = ""; }; 59 | 449ED39A0DF9F31D003B8713 /* LODoneButtonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LODoneButtonView.h; sourceTree = ""; }; 60 | 449ED39B0DF9F31D003B8713 /* LOGlareView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LOGlareView.m; sourceTree = ""; }; 61 | 449ED39C0DF9F31D003B8713 /* LOButtonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LOButtonView.h; sourceTree = ""; }; 62 | 449ED39D0DF9F31D003B8713 /* LODoneButtonView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LODoneButtonView.m; sourceTree = ""; }; 63 | 449ED39E0DF9F31D003B8713 /* LOInfoView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LOInfoView.h; sourceTree = ""; }; 64 | 449ED39F0DF9F31D003B8713 /* LOInfoButtonView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LOInfoButtonView.m; sourceTree = ""; }; 65 | 449ED3A00DF9F31D003B8713 /* LOButtonGlowView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LOButtonGlowView.h; sourceTree = ""; }; 66 | 449ED3A10DF9F31D003B8713 /* LOHighlightView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LOHighlightView.h; sourceTree = ""; }; 67 | 449ED3A20DF9F31D003B8713 /* LOView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LOView.h; sourceTree = ""; }; 68 | 449ED3A30DF9F31D003B8713 /* LOHighlightView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LOHighlightView.m; sourceTree = ""; }; 69 | 449ED3A40DF9F31D003B8713 /* LOResetView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LOResetView.m; sourceTree = ""; }; 70 | 449ED3A50DF9F31D003B8713 /* LOButtonGlowView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LOButtonGlowView.m; sourceTree = ""; }; 71 | 449ED3A70DF9F31D003B8713 /* LOInfoView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LOInfoView.m; sourceTree = ""; }; 72 | 449ED3A80DF9F31D003B8713 /* LOResetView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LOResetView.h; sourceTree = ""; }; 73 | 449ED3A90DF9F31D003B8713 /* LOView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LOView.m; sourceTree = ""; }; 74 | 449ED3AB0DF9F31D003B8713 /* LOGlareView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LOGlareView.h; sourceTree = ""; }; 75 | 449ED3AC0DF9F31D003B8713 /* LOInfoButtonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LOInfoButtonView.h; sourceTree = ""; }; 76 | 44CABF070DF9F84200D934FD /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 77 | 44CABFCB0DF9FF4E00D934FD /* lo-background-info.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "lo-background-info.png"; path = "Images/lo-background-info.png"; sourceTree = ""; }; 78 | 44CABFCC0DF9FF4E00D934FD /* lo-background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "lo-background.png"; path = "Images/lo-background.png"; sourceTree = ""; }; 79 | 44CABFCD0DF9FF4E00D934FD /* lo-button-done-press.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "lo-button-done-press.png"; path = "Images/lo-button-done-press.png"; sourceTree = ""; }; 80 | 44CABFCE0DF9FF4E00D934FD /* lo-button-done.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "lo-button-done.png"; path = "Images/lo-button-done.png"; sourceTree = ""; }; 81 | 44CABFCF0DF9FF4E00D934FD /* lo-button-fullglow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "lo-button-fullglow.png"; path = "Images/lo-button-fullglow.png"; sourceTree = ""; }; 82 | 44CABFD00DF9FF4E00D934FD /* lo-button-glare.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "lo-button-glare.png"; path = "Images/lo-button-glare.png"; sourceTree = ""; }; 83 | 44CABFD10DF9FF4E00D934FD /* lo-button-info-press.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "lo-button-info-press.png"; path = "Images/lo-button-info-press.png"; sourceTree = ""; }; 84 | 44CABFD20DF9FF4E00D934FD /* lo-button-info.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "lo-button-info.png"; path = "Images/lo-button-info.png"; sourceTree = ""; }; 85 | 44CABFD30DF9FF4E00D934FD /* lo-button-off.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "lo-button-off.png"; path = "Images/lo-button-off.png"; sourceTree = ""; }; 86 | 44CABFD40DF9FF4E00D934FD /* lo-button-on-press.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "lo-button-on-press.png"; path = "Images/lo-button-on-press.png"; sourceTree = ""; }; 87 | 44CABFD50DF9FF4E00D934FD /* lo-button-press.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "lo-button-press.png"; path = "Images/lo-button-press.png"; sourceTree = ""; }; 88 | 44CABFD60DF9FF4E00D934FD /* lo-button-reset-press.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "lo-button-reset-press.png"; path = "Images/lo-button-reset-press.png"; sourceTree = ""; }; 89 | 44CABFD70DF9FF4E00D934FD /* lo-button-reset.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "lo-button-reset.png"; path = "Images/lo-button-reset.png"; sourceTree = ""; }; 90 | 44CABFD80DF9FF4E00D934FD /* lo-glowpress.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "lo-glowpress.png"; path = "Images/lo-glowpress.png"; sourceTree = ""; }; 91 | 44CABFD90DF9FF4E00D934FD /* lo-logoglow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "lo-logoglow.png"; path = "Images/lo-logoglow.png"; sourceTree = ""; }; 92 | 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 93 | /* End PBXFileReference section */ 94 | 95 | /* Begin PBXFrameworksBuildPhase section */ 96 | 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { 97 | isa = PBXFrameworksBuildPhase; 98 | buildActionMask = 2147483647; 99 | files = ( 100 | 4464DBD620478507005E2DD8 /* QuartzCore.framework in Frameworks */, 101 | 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, 102 | 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, 103 | 44CABF080DF9F84200D934FD /* CoreGraphics.framework in Frameworks */, 104 | ); 105 | runOnlyForDeploymentPostprocessing = 0; 106 | }; 107 | /* End PBXFrameworksBuildPhase section */ 108 | 109 | /* Begin PBXGroup section */ 110 | 080E96DDFE201D6D7F000001 /* Classes */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | 1D3623240D0F684500981E51 /* LightsOffTouchAppDelegate.h */, 114 | 1D3623250D0F684500981E51 /* LightsOffTouchAppDelegate.m */, 115 | 449ED39C0DF9F31D003B8713 /* LOButtonView.h */, 116 | 449ED3990DF9F31D003B8713 /* LOButtonView.m */, 117 | 449ED39A0DF9F31D003B8713 /* LODoneButtonView.h */, 118 | 449ED39D0DF9F31D003B8713 /* LODoneButtonView.m */, 119 | 449ED3AC0DF9F31D003B8713 /* LOInfoButtonView.h */, 120 | 449ED39F0DF9F31D003B8713 /* LOInfoButtonView.m */, 121 | 449ED3A00DF9F31D003B8713 /* LOButtonGlowView.h */, 122 | 449ED3A50DF9F31D003B8713 /* LOButtonGlowView.m */, 123 | 449ED3AB0DF9F31D003B8713 /* LOGlareView.h */, 124 | 449ED39B0DF9F31D003B8713 /* LOGlareView.m */, 125 | 449ED39E0DF9F31D003B8713 /* LOInfoView.h */, 126 | 449ED3A70DF9F31D003B8713 /* LOInfoView.m */, 127 | 449ED3A10DF9F31D003B8713 /* LOHighlightView.h */, 128 | 449ED3A30DF9F31D003B8713 /* LOHighlightView.m */, 129 | 449ED3A20DF9F31D003B8713 /* LOView.h */, 130 | 449ED3A90DF9F31D003B8713 /* LOView.m */, 131 | 449ED3A80DF9F31D003B8713 /* LOResetView.h */, 132 | 449ED3A40DF9F31D003B8713 /* LOResetView.m */, 133 | ); 134 | path = Classes; 135 | sourceTree = ""; 136 | }; 137 | 19C28FACFE9D520D11CA2CBB /* Products */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | 1D6058910D05DD3D006BFB54 /* Lights Off.app */, 141 | ); 142 | name = Products; 143 | sourceTree = ""; 144 | }; 145 | 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | 4464DBDE204E206B005E2DD8 /* README.md */, 149 | 080E96DDFE201D6D7F000001 /* Classes */, 150 | 29B97315FDCFA39411CA2CEA /* Other Sources */, 151 | 29B97317FDCFA39411CA2CEA /* Resources */, 152 | 29B97323FDCFA39411CA2CEA /* Frameworks */, 153 | 19C28FACFE9D520D11CA2CBB /* Products */, 154 | ); 155 | name = CustomTemplate; 156 | sourceTree = ""; 157 | }; 158 | 29B97315FDCFA39411CA2CEA /* Other Sources */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | 32CA4F630368D1EE00C91783 /* LightsOffTouch_Prefix.pch */, 162 | 29B97316FDCFA39411CA2CEA /* main.m */, 163 | ); 164 | name = "Other Sources"; 165 | sourceTree = ""; 166 | }; 167 | 29B97317FDCFA39411CA2CEA /* Resources */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | 44CABEE10DF9F59300D934FD /* Images */, 171 | 4468FB030E06F6B600CA0D49 /* puzzles.plist */, 172 | 8D1107310486CEB800E47090 /* Info.plist */, 173 | ); 174 | name = Resources; 175 | sourceTree = ""; 176 | }; 177 | 29B97323FDCFA39411CA2CEA /* Frameworks */ = { 178 | isa = PBXGroup; 179 | children = ( 180 | 4464DBD520478507005E2DD8 /* QuartzCore.framework */, 181 | 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, 182 | 1D30AB110D05D00D00671497 /* Foundation.framework */, 183 | 44CABF070DF9F84200D934FD /* CoreGraphics.framework */, 184 | ); 185 | name = Frameworks; 186 | sourceTree = ""; 187 | }; 188 | 44CABEE10DF9F59300D934FD /* Images */ = { 189 | isa = PBXGroup; 190 | children = ( 191 | 4468FB170E06F7AB00CA0D49 /* Default.png */, 192 | 4468FB180E06F7AB00CA0D49 /* Icon.png */, 193 | 44CABFCB0DF9FF4E00D934FD /* lo-background-info.png */, 194 | 44CABFCC0DF9FF4E00D934FD /* lo-background.png */, 195 | 44CABFCD0DF9FF4E00D934FD /* lo-button-done-press.png */, 196 | 44CABFCE0DF9FF4E00D934FD /* lo-button-done.png */, 197 | 44CABFCF0DF9FF4E00D934FD /* lo-button-fullglow.png */, 198 | 44CABFD00DF9FF4E00D934FD /* lo-button-glare.png */, 199 | 44CABFD10DF9FF4E00D934FD /* lo-button-info-press.png */, 200 | 44CABFD20DF9FF4E00D934FD /* lo-button-info.png */, 201 | 44CABFD30DF9FF4E00D934FD /* lo-button-off.png */, 202 | 44CABFD40DF9FF4E00D934FD /* lo-button-on-press.png */, 203 | 44CABFD50DF9FF4E00D934FD /* lo-button-press.png */, 204 | 44CABFD60DF9FF4E00D934FD /* lo-button-reset-press.png */, 205 | 44CABFD70DF9FF4E00D934FD /* lo-button-reset.png */, 206 | 44CABFD80DF9FF4E00D934FD /* lo-glowpress.png */, 207 | 44CABFD90DF9FF4E00D934FD /* lo-logoglow.png */, 208 | ); 209 | name = Images; 210 | sourceTree = ""; 211 | }; 212 | /* End PBXGroup section */ 213 | 214 | /* Begin PBXNativeTarget section */ 215 | 1D6058900D05DD3D006BFB54 /* LightsOffTouch */ = { 216 | isa = PBXNativeTarget; 217 | buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "LightsOffTouch" */; 218 | buildPhases = ( 219 | 1D60588D0D05DD3D006BFB54 /* Resources */, 220 | 1D60588E0D05DD3D006BFB54 /* Sources */, 221 | 1D60588F0D05DD3D006BFB54 /* Frameworks */, 222 | ); 223 | buildRules = ( 224 | ); 225 | dependencies = ( 226 | ); 227 | name = LightsOffTouch; 228 | productName = LightsOffTouch; 229 | productReference = 1D6058910D05DD3D006BFB54 /* Lights Off.app */; 230 | productType = "com.apple.product-type.application"; 231 | }; 232 | /* End PBXNativeTarget section */ 233 | 234 | /* Begin PBXProject section */ 235 | 29B97313FDCFA39411CA2CEA /* Project object */ = { 236 | isa = PBXProject; 237 | attributes = { 238 | }; 239 | buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "LightsOffTouch" */; 240 | compatibilityVersion = "Xcode 3.1"; 241 | developmentRegion = en; 242 | hasScannedForEncodings = 1; 243 | knownRegions = ( 244 | en, 245 | ); 246 | mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; 247 | projectDirPath = ""; 248 | projectRoot = ""; 249 | targets = ( 250 | 1D6058900D05DD3D006BFB54 /* LightsOffTouch */, 251 | ); 252 | }; 253 | /* End PBXProject section */ 254 | 255 | /* Begin PBXResourcesBuildPhase section */ 256 | 1D60588D0D05DD3D006BFB54 /* Resources */ = { 257 | isa = PBXResourcesBuildPhase; 258 | buildActionMask = 2147483647; 259 | files = ( 260 | 44CABFDB0DF9FF4E00D934FD /* lo-background-info.png in Resources */, 261 | 44CABFDC0DF9FF4E00D934FD /* lo-background.png in Resources */, 262 | 44CABFDD0DF9FF4E00D934FD /* lo-button-done-press.png in Resources */, 263 | 44CABFDE0DF9FF4E00D934FD /* lo-button-done.png in Resources */, 264 | 44CABFDF0DF9FF4E00D934FD /* lo-button-fullglow.png in Resources */, 265 | 44CABFE00DF9FF4E00D934FD /* lo-button-glare.png in Resources */, 266 | 44CABFE10DF9FF4E00D934FD /* lo-button-info-press.png in Resources */, 267 | 44CABFE20DF9FF4E00D934FD /* lo-button-info.png in Resources */, 268 | 44CABFE30DF9FF4E00D934FD /* lo-button-off.png in Resources */, 269 | 44CABFE40DF9FF4E00D934FD /* lo-button-on-press.png in Resources */, 270 | 44CABFE50DF9FF4E00D934FD /* lo-button-press.png in Resources */, 271 | 44CABFE60DF9FF4E00D934FD /* lo-button-reset-press.png in Resources */, 272 | 44CABFE70DF9FF4E00D934FD /* lo-button-reset.png in Resources */, 273 | 44CABFE80DF9FF4E00D934FD /* lo-glowpress.png in Resources */, 274 | 44CABFE90DF9FF4E00D934FD /* lo-logoglow.png in Resources */, 275 | 4468FB040E06F6B600CA0D49 /* puzzles.plist in Resources */, 276 | 4468FB190E06F7AB00CA0D49 /* Default.png in Resources */, 277 | 4468FB1A0E06F7AB00CA0D49 /* Icon.png in Resources */, 278 | ); 279 | runOnlyForDeploymentPostprocessing = 0; 280 | }; 281 | /* End PBXResourcesBuildPhase section */ 282 | 283 | /* Begin PBXSourcesBuildPhase section */ 284 | 1D60588E0D05DD3D006BFB54 /* Sources */ = { 285 | isa = PBXSourcesBuildPhase; 286 | buildActionMask = 2147483647; 287 | files = ( 288 | 1D60589B0D05DD56006BFB54 /* main.m in Sources */, 289 | 1D3623260D0F684500981E51 /* LightsOffTouchAppDelegate.m in Sources */, 290 | 449ED3AD0DF9F31D003B8713 /* LOButtonView.m in Sources */, 291 | 449ED3AE0DF9F31D003B8713 /* LOGlareView.m in Sources */, 292 | 449ED3AF0DF9F31D003B8713 /* LODoneButtonView.m in Sources */, 293 | 449ED3B00DF9F31D003B8713 /* LOInfoButtonView.m in Sources */, 294 | 449ED3B10DF9F31D003B8713 /* LOHighlightView.m in Sources */, 295 | 449ED3B20DF9F31D003B8713 /* LOResetView.m in Sources */, 296 | 449ED3B30DF9F31D003B8713 /* LOButtonGlowView.m in Sources */, 297 | 449ED3B40DF9F31D003B8713 /* LOInfoView.m in Sources */, 298 | 449ED3B50DF9F31D003B8713 /* LOView.m in Sources */, 299 | ); 300 | runOnlyForDeploymentPostprocessing = 0; 301 | }; 302 | /* End PBXSourcesBuildPhase section */ 303 | 304 | /* Begin XCBuildConfiguration section */ 305 | 1D6058940D05DD3E006BFB54 /* Debug */ = { 306 | isa = XCBuildConfiguration; 307 | buildSettings = { 308 | ALWAYS_SEARCH_USER_PATHS = NO; 309 | COPY_PHASE_STRIP = NO; 310 | DEVELOPMENT_TEAM = LN92RWTA45; 311 | GCC_DYNAMIC_NO_PIC = NO; 312 | GCC_OPTIMIZATION_LEVEL = 0; 313 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 314 | GCC_PREFIX_HEADER = LightsOffTouch_Prefix.pch; 315 | INFOPLIST_FILE = Info.plist; 316 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 317 | PRODUCT_BUNDLE_IDENTIFIER = com.lucasnewman.LightsOff; 318 | PRODUCT_NAME = "Lights Off"; 319 | }; 320 | name = Debug; 321 | }; 322 | 1D6058950D05DD3E006BFB54 /* Release */ = { 323 | isa = XCBuildConfiguration; 324 | buildSettings = { 325 | ALWAYS_SEARCH_USER_PATHS = NO; 326 | COPY_PHASE_STRIP = YES; 327 | DEVELOPMENT_TEAM = LN92RWTA45; 328 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 329 | GCC_PREFIX_HEADER = LightsOffTouch_Prefix.pch; 330 | INFOPLIST_FILE = Info.plist; 331 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 332 | PRODUCT_BUNDLE_IDENTIFIER = com.lucasnewman.LightsOff; 333 | PRODUCT_NAME = "Lights Off"; 334 | }; 335 | name = Release; 336 | }; 337 | C01FCF4F08A954540054247B /* Debug */ = { 338 | isa = XCBuildConfiguration; 339 | buildSettings = { 340 | ARCHS = "$(ARCHS_STANDARD)"; 341 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 342 | GCC_C_LANGUAGE_STANDARD = c99; 343 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 344 | GCC_WARN_UNUSED_VARIABLE = YES; 345 | ONLY_ACTIVE_ARCH = YES; 346 | PREBINDING = NO; 347 | SDKROOT = iphoneos; 348 | }; 349 | name = Debug; 350 | }; 351 | C01FCF5008A954540054247B /* Release */ = { 352 | isa = XCBuildConfiguration; 353 | buildSettings = { 354 | ARCHS = "$(ARCHS_STANDARD)"; 355 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 356 | GCC_C_LANGUAGE_STANDARD = c99; 357 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 358 | GCC_WARN_UNUSED_VARIABLE = YES; 359 | PREBINDING = NO; 360 | SDKROOT = iphoneos; 361 | }; 362 | name = Release; 363 | }; 364 | /* End XCBuildConfiguration section */ 365 | 366 | /* Begin XCConfigurationList section */ 367 | 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "LightsOffTouch" */ = { 368 | isa = XCConfigurationList; 369 | buildConfigurations = ( 370 | 1D6058940D05DD3E006BFB54 /* Debug */, 371 | 1D6058950D05DD3E006BFB54 /* Release */, 372 | ); 373 | defaultConfigurationIsVisible = 0; 374 | defaultConfigurationName = Release; 375 | }; 376 | C01FCF4E08A954540054247B /* Build configuration list for PBXProject "LightsOffTouch" */ = { 377 | isa = XCConfigurationList; 378 | buildConfigurations = ( 379 | C01FCF4F08A954540054247B /* Debug */, 380 | C01FCF5008A954540054247B /* Release */, 381 | ); 382 | defaultConfigurationIsVisible = 0; 383 | defaultConfigurationName = Release; 384 | }; 385 | /* End XCConfigurationList section */ 386 | }; 387 | rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; 388 | } 389 | -------------------------------------------------------------------------------- /LightsOffTouch_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'LightsOffTouch' target in the 'LightsOffTouch' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #import 8 | #endif 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lights Off 2 | 3 | This is the source code for the first iPhone game created with UIKit. It was originally written by Lucas Newman in 2008. 4 | 5 | The app in the Classes folder is an adaptation of the original in the Jailbreak folder. I've endeavored to leave the code as-is, but some changes were needed to build and run using modern tools. Use `diff` to see what I've changed. 6 | 7 | This app was resurected to celebrate the [10th anniversary of the iPhone SDK]( https://blog.iconfactory.com/2018/03/a-lot-can-happen-in-a-decade/). 8 | 9 | -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // LightsOffTouch 4 | // 5 | // Created by Craig Hockenberry on 6/6/08. 6 | // Copyright The Iconfactory 2008. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) { 12 | 13 | NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 14 | int retVal = UIApplicationMain(argc, argv, nil, @"LightsOffTouchAppDelegate"); 15 | [pool release]; 16 | return retVal; 17 | } 18 | -------------------------------------------------------------------------------- /puzzles.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | puzzles 6 | 7 | -x---|xxx--|-x-x-|--xxx|---x-| 8 | xx-xx|x---x|-----|x---x|xx-xx| 9 | --x--|--x--|xx-xx|--x--|--x--| 10 | x----|-x---|--x--|---x-|----x| 11 | xxxxx|xxxxx|-----|xxxxx|xxxxx| 12 | -----|-----|x-x-x|-----|-----| 13 | xx-xx|xx-x-|-x---|-x---|x----| 14 | -x---|--x--|xx---|--x--|-xxx-| 15 | -x--x|xxx-x|-x-x-|-xxxx|-----| 16 | xxx-x|-x-xx|-x--x|xxx--|-x---| 17 | -xxx-|-xxx-|xx-xx|---x-|xxx--| 18 | x-x--|xxxxx|x-x--|-x-x-|xx---| 19 | --x--|xxx-x|xxxx-|xx-x-|--xx-| 20 | -xxxx|xxxxx|-x-xx|--xxx|x--xx| 21 | -xxx-|x--x-|xxx--|x-xxx|x-x-x| 22 | -xxx-|x-x--|xx--x|x--xx|xx-xx| 23 | xx-xx|x--xx|---xx|-xxx-|---xx| 24 | xx-x-|---xx|-x-x-|-----|-xxx-| 25 | ---xx|-----|---x-|-xxxx|-----| 26 | xx---|xxxx-|--xx-|-xxxx|-x-x-| 27 | x-xxx|xxx--|x-xxx|x-x-x|-----| 28 | -x-x-|xxx-x|xxxxx|-x--x|----x| 29 | --xx-|---x-|xxxx-|xxx--|-x--x| 30 | -xx--|x-xxx|-xxxx|xxxx-|xx-xx| 31 | x----|-xx--|xxx-x|-x---|xxx-x| 32 | x-xx-|x-xx-|-x--x|xx--x|x----| 33 | x----|-xxxx|xx-xx|x----|---xx| 34 | --x--|-xx--|----x|x-x--|xxxx-| 35 | xx--x|-xxxx|--xxx|--x--|--xx-| 36 | -x-x-|-x-x-|-x-x-|x--x-|x--xx| 37 | -x---|x--xx|xx-xx|x-xx-|--x--| 38 | xxx--|-xxxx|--x--|-----|x---x| 39 | --x-x|xxx--|-x--x|-xxxx|xxxx-| 40 | xxx--|--xxx|--x-x|--xxx|-x--x| 41 | x-x-x|-xxxx|xxxxx|-x-xx|-xx--| 42 | -x-xx|x----|x-x--|x--x-|---xx| 43 | x--xx|x-xxx|x----|xx-xx|xxxx-| 44 | --x--|x-x-x|xxx-x|xxx--|xxxx-| 45 | --xxx|xx--x|--xxx|---x-|--xxx| 46 | x----|x-xx-|-----|xxx--|xx-xx| 47 | x--x-|xx---|xxxx-|xx---|xx-xx| 48 | --x-x|-xx--|x-x-x|x---x|--xxx| 49 | ---xx|xxx-x|-x--x|x--x-|-x---| 50 | x--xx|-x---|x-xx-|-xxxx|-xxx-| 51 | x---x|xx--x|-----|-----|x----| 52 | xxx-x|x-x-x|x-x-x|xxxxx|xx-xx| 53 | --x--|xx---|---xx|x-x-x|xx---| 54 | x-xxx|-x--x|-x-xx|xxxxx|---x-| 55 | xxxxx|x-x-x|x---x|-x-xx|---xx| 56 | x--x-|-xxxx|---x-|xx--x|--xxx| 57 | x--x-|-x--x|xx---|-x-x-|-xx-x| 58 | xx--x|x-x-x|xx---|---xx|xxxxx| 59 | xxxxx|--xxx|xx--x|--x--|--x--| 60 | x-x-x|-x--x|x-x-x|---x-|x---x| 61 | -xxxx|-xx--|x-x--|xxx-x|-x-x-| 62 | -x---|----x|x-x-x|---xx|xxxx-| 63 | xx--x|--xx-|x---x|xx-x-|x--x-| 64 | ---xx|xxxxx|x-xx-|-xxxx|x-xxx| 65 | xxxx-|-x--x|xxxx-|-xxxx|x--xx| 66 | x---x|-x-x-|x--x-|--x-x|-xx-x| 67 | -----|-xx--|xxx-x|x-x-x|x--x-| 68 | ---x-|xxxx-|-x---|-xx-x|x----| 69 | xxx--|x-xxx|-----|-xx--|-----| 70 | xxx--|-x---|x--x-|x----|x--xx| 71 | x-xxx|-xx--|--x-x|xx-x-|--x--| 72 | xx---|xxx-x|xx--x|-xxxx|-xxx-| 73 | -x--x|----x|x-x-x|----x|-xxx-| 74 | -xx-x|xx---|xxxx-|xx-xx|-xx--| 75 | --x--|-x--x|-----|-x--x|xx---| 76 | xx---|x----|xx-x-|--xx-|xx-x-| 77 | xx-x-|-xx--|xxx--|---xx|----x| 78 | x-xx-|x-x-x|-xxxx|-x-xx|x--xx| 79 | x----|x----|x-xx-|xx---|--xxx| 80 | ----x|-xxxx|-x---|xx--x|xx---| 81 | ----x|x-x-x|-xx-x|---xx|----x| 82 | -x---|x-x--|---xx|x-xxx|--xxx| 83 | xx-x-|x-xx-|x----|x--x-|----x| 84 | xx--x|---x-|xx--x|x---x|--xx-| 85 | -x---|xx---|-xx--|---xx|xxx-x| 86 | xx---|-x--x|-x-x-|---x-|--xxx| 87 | --x-x|-xx--|-x--x|-x-xx|x--x-| 88 | -----|xx-x-|xxx-x|x----|-xxxx| 89 | xx--x|xxxxx|x-xxx|-xx--|--xx-| 90 | xx-x-|x----|-x--x|--xxx|--x-x| 91 | xxxx-|x----|xx---|-xx-x|x----| 92 | --xxx|xxx-x|---x-|-x-x-|x----| 93 | x---x|xxxxx|-x--x|xx-x-|xxx--| 94 | ---x-|xx--x|xxx--|x-xx-|-x--x| 95 | x-x--|x-x-x|xx-x-|-x-x-|x--xx| 96 | --xxx|xx--x|x-xxx|--xxx|x--xx| 97 | x--xx|-x--x|x----|---x-|x-x--| 98 | xxx-x|-x---|-x-xx|x--xx|xx--x| 99 | --xx-|x---x|--xxx|xx--x|x-xx-| 100 | -xx--|-xxxx|xx--x|--xx-|--xx-| 101 | x--xx|x---x|x---x|x-xxx|-xx-x| 102 | x---x|xxx--|--xxx|----x|xx---| 103 | -x-x-|-x-xx|xx--x|--xxx|x----| 104 | x-x--|x---x|xx--x|--xx-|-xxx-| 105 | --x--|xxxx-|xxxx-|---x-|--xx-| 106 | -----|xxx-x|--x--|xxxxx|x-xxx| 107 | xxx-x|-xxx-|xxx--|-xx-x|--x-x| 108 | x---x|----x|----x|x-xxx|-xxxx| 109 | x-xx-|---xx|-xx-x|--xxx|x-x-x| 110 | -xx-x|-x--x|--xx-|xxx-x|x-x-x| 111 | ---xx|--x--|x--xx|--xxx|x-x--| 112 | -x---|-xx-x|x---x|x-xx-|xx--x| 113 | --x-x|-xxxx|---x-|x-x-x|xx---| 114 | -----|x-x-x|xxxx-|-----|----x| 115 | x----|-xx-x|x-x-x|--x-x|x-xx-| 116 | x----|xx--x|xxxx-|xxxx-|-xxx-| 117 | xxxx-|----x|-x--x|x--xx|--xx-| 118 | -xx-x|xxx-x|xx-x-|--xx-|xx--x| 119 | -xx-x|x-xx-|x-x--|xx-x-|-xx--| 120 | -x--x|-xxxx|-xx-x|--xx-|-x-xx| 121 | xxxx-|xxxxx|---xx|--xx-|xx---| 122 | -x--x|-x-x-|x--xx|xx-x-|--x-x| 123 | x---x|xx-xx|-x---|-xx--|-x-x-| 124 | x-xx-|--xxx|--xxx|x---x|xxx--| 125 | xxxx-|--xxx|xx---|--xx-|xx-xx| 126 | xx--x|x--x-|xx---|x--x-|-x---| 127 | ---xx|--x--|xx---|x-xx-|x-xxx| 128 | xxx-x|x--x-|--xx-|xx--x|-xx-x| 129 | x-xx-|-----|x-x-x|-----|xx-xx| 130 | x-x-x|-xxx-|x--x-|x-x-x|xx--x| 131 | xx-x-|x-x-x|xxx-x|xxxx-|--xxx| 132 | xx--x|--xxx|xx---|-x--x|xx-xx| 133 | -xx-x|xxxx-|-xxxx|-xxxx|---x-| 134 | -xxx-|-xx-x|-xxx-|-----|x--x-| 135 | ----x|xx-xx|--xxx|x-xxx|x-x-x| 136 | -x--x|xxx--|xx-x-|-x-xx|x--x-| 137 | --x-x|x--xx|x-x-x|x--x-|x----| 138 | xx--x|--xx-|-x--x|-xx--|x-x--| 139 | -x-xx|xxxx-|xxxx-|xx--x|---xx| 140 | ----x|x-x-x|-----|x-x-x|-xx-x| 141 | -x--x|x---x|x-xx-|xx-xx|---xx| 142 | --x--|---xx|--x-x|-x---|xx---| 143 | ---xx|-xx-x|x--x-|x---x|-x---| 144 | -----|-x---|xx-x-|xxxx-|x--x-| 145 | -----|-xxxx|-x-x-|-x---|xxx-x| 146 | ----x|--x-x|x---x|--xx-|--x--| 147 | -----|x----|-x-xx|-xxx-|x--xx| 148 | x--xx|-----|xxx-x|x---x|x-xx-| 149 | -----|-xx--|---xx|x--x-|-xx--| 150 | x--x-|-xx--|-xx-x|----x|x--xx| 151 | x-xxx|--x--|x---x|-xxx-|-xx-x| 152 | x-x-x|-xx-x|----x|xx-xx|-xx--| 153 | x-x--|x--xx|---x-|xx---|x--x-| 154 | x-xxx|-x-x-|---x-|-x-x-|xxxx-| 155 | x--x-|xx-x-|--xxx|--x--|-xxx-| 156 | x--x-|-xxxx|x----|x--x-|---xx| 157 | xxxx-|xx--x|x-x-x|xxx-x|--xx-| 158 | xxx-x|-x-xx|-xxxx|--x--|x--xx| 159 | ---xx|-xxxx|---xx|x----|-x-x-| 160 | -x-x-|-----|x--xx|x-x-x|--xx-| 161 | -xx--|--x-x|x-xx-|x--xx|xxx-x| 162 | x----|-xx--|-----|--x--|-xx--| 163 | xxxx-|xxxxx|xxx-x|-xxxx|-xxx-| 164 | x----|-----|---xx|x----|x-x-x| 165 | -x-xx|--x--|x-x--|x-xxx|xxxx-| 166 | -----|xxxxx|--x-x|x-x-x|x--x-| 167 | xxxx-|-xxx-|---xx|x--x-|xxxxx| 168 | xxx--|xxx-x|-x--x|---xx|x---x| 169 | x---x|--xx-|--xx-|--xx-|-xxxx| 170 | x-xx-|--x--|-xx-x|x-x--|-x--x| 171 | --x--|x----|-x-xx|--xx-|x-xxx| 172 | -xxxx|xxxxx|xx-xx|-x---|x----| 173 | --xxx|----x|--x-x|-xx--|-x---| 174 | -x---|--xx-|x-xx-|xx-x-|-xxx-| 175 | ----x|-x-xx|--x--|--xxx|xx--x| 176 | xx---|xxx--|-----|x--xx|-xxxx| 177 | -xx-x|-----|--xx-|xxxx-|xxxx-| 178 | xxxxx|---xx|xxxx-|x--x-|x-xx-| 179 | xxx--|x----|xxx-x|-xx-x|xx-x-| 180 | -----|-----|-x-x-|--x-x|x---x| 181 | -----|-x-xx|x-xxx|---x-|xx-xx| 182 | --x--|----x|-x--x|x-xx-|x---x| 183 | --x--|-xx--|-x-x-|xxxxx|x-x--| 184 | -xxxx|--xxx|x--xx|--xxx|x----| 185 | xx---|-xx--|--xx-|xxxx-|-x--x| 186 | --xxx|xxx--|-xx--|x-xxx|xx-xx| 187 | xx---|-x--x|-xxxx|-xx--|x-xxx| 188 | x-xx-|-x--x|xx-x-|xx-xx|-xx-x| 189 | x----|x-xx-|x-xxx|xx-x-|-x-xx| 190 | -x---|xxx-x|x-xxx|x--x-|xxx-x| 191 | xxx--|x-x-x|xx-x-|xx-x-|---xx| 192 | xxxx-|-xxxx|xxxx-|xx---|-xxx-| 193 | xxx-x|-x-x-|-xx-x|xxxx-|xx-x-| 194 | ---xx|---x-|x----|-xx-x|x-xx-| 195 | x--xx|xxxx-|-x-x-|xx-x-|--xxx| 196 | -xxx-|---x-|x--xx|xx--x|-x-xx| 197 | -----|--xxx|xxx--|xx--x|xxx--| 198 | -x-x-|x--xx|xxx-x|--xx-|-----| 199 | ---x-|---xx|xx--x|xxxxx|----x| 200 | xx-xx|x-xx-|xxxx-|xxx--|x--xx| 201 | --x--|x----|xxx--|xxxx-|x---x| 202 | ----x|--xx-|xxxxx|x----|xxx-x| 203 | -x---|x-x-x|-xxx-|-x-xx|xxxx-| 204 | x-x-x|xx---|---xx|---xx|-xxxx| 205 | x---x|----x|x--x-|xxxxx|x----| 206 | -xxxx|x-x-x|x--x-|---x-|--xx-| 207 | -x--x|xxxx-|xx-x-|x-x--|-----| 208 | xxx-x|-xx--|xxx-x|-xx-x|x---x| 209 | x-xxx|-xx--|xxxx-|x----|xxxxx| 210 | -x-xx|x-xxx|xxx-x|-x-xx|x-x-x| 211 | ----x|x-x--|---x-|xx--x|-xxxx| 212 | x-x-x|xx-xx|-x-xx|-xxx-|xxxxx| 213 | 214 | 215 | 216 | --------------------------------------------------------------------------------