mirror of
https://github.com/id-Software/DOOM-IOS2.git
synced 2026-03-20 08:59:35 +01:00
Initial Commit
This commit is contained in:
31
common/idmobilelib/ios/AnimatedImage.h
Executable file
31
common/idmobilelib/ios/AnimatedImage.h
Executable file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
@interface idAnimatedImage : UIImageView {
|
||||
|
||||
}
|
||||
|
||||
- (void) SetupAnimation:( NSString * )animationBaseName
|
||||
:( float )animationDuration
|
||||
:( int )animationRepeat;
|
||||
|
||||
@end
|
||||
67
common/idmobilelib/ios/AnimatedImage.mm
Executable file
67
common/idmobilelib/ios/AnimatedImage.mm
Executable file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "AnimatedImage.h"
|
||||
|
||||
|
||||
@implementation idAnimatedImage
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
SetupAnimation
|
||||
========================
|
||||
*/
|
||||
- (void) SetupAnimation:( NSString * )animationBaseName
|
||||
:( float )animationDuration
|
||||
:( int )animationRepeat {
|
||||
|
||||
// Create an Array to store our images in.
|
||||
const static int MAX_NUM_ANIMFRAMES = 20;
|
||||
NSMutableArray * imageArray = [ [ NSMutableArray alloc ] initWithCapacity:MAX_NUM_ANIMFRAMES ];
|
||||
|
||||
for( int index = 1; index < MAX_NUM_ANIMFRAMES; index++ ) {
|
||||
NSString * imageName = [ [ NSString alloc ] initWithFormat:@"%@_%d.png", animationBaseName, index ];
|
||||
|
||||
// Try and Load the Image.
|
||||
UIImage * imageCheck = [UIImage imageNamed: imageName ];
|
||||
|
||||
// are we good?
|
||||
if( imageCheck != nil ) {
|
||||
|
||||
// add it to the array of Images.
|
||||
[ imageArray addObject:imageCheck ];
|
||||
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Set the Animation Data.
|
||||
[ self setAnimationImages: imageArray ];
|
||||
[ self setAnimationDuration: animationDuration];
|
||||
[ self setAnimationRepeatCount: animationRepeat ];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@end
|
||||
91
common/idmobilelib/ios/Carousel.h
Executable file
91
common/idmobilelib/ios/Carousel.h
Executable file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
Carousel -
|
||||
|
||||
This UI Object must be setup by Interface builder.
|
||||
|
||||
items must be added by code.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "Label.h"
|
||||
|
||||
@interface idCarouselItem : NSObject
|
||||
{
|
||||
@public
|
||||
|
||||
UIImage * image; // Image Of the Item.
|
||||
NSString * title; // Title of the Item.
|
||||
int hash; // Optional Item Hash Value.
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) NSString *title;
|
||||
@property (nonatomic, retain) UIImage *image;
|
||||
@property (nonatomic, assign) int hash;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface idCarousel : UIControl {
|
||||
@public
|
||||
|
||||
NSInteger currentItem; // The Current Carousel Item.
|
||||
NSInteger prevItem; // The Prev Carousel Item.
|
||||
NSInteger nextItem; // The Next Carousel Item.
|
||||
|
||||
@private
|
||||
IBOutlet UIImageView * mainSelection; // Renderable Main Selection
|
||||
IBOutlet UIImageView * prevSelection; // Renderable Prev Selection
|
||||
IBOutlet UIImageView * nextSelection; // Renderable Next Selection
|
||||
IBOutlet idLabel * selectionLabel; // Title Label.
|
||||
|
||||
CGRect mainRect; // Main Selection Layout Rect.
|
||||
CGRect prevRect; // Prev Selection Layout Rect.
|
||||
CGRect nextRect; // Next Selection Layout Rect.
|
||||
|
||||
NSMutableArray * carouselItems; // All the Available Items to choose from.
|
||||
|
||||
int hasDragged; // if the User has Dragged for a revolution.
|
||||
CGPoint startDragPoint; // the starting point where the user has touched.
|
||||
}
|
||||
|
||||
- (void) Init;
|
||||
- (void) AddCarouselItem:( NSString* )Image
|
||||
:( NSString* )Title
|
||||
:( int )ItemHash;
|
||||
|
||||
- (NSInteger) GetSelectedItem_Index;
|
||||
- (int) GetSelectedItem_Hash;
|
||||
|
||||
- (IBAction) MoveForward;
|
||||
- (IBAction) MoveBackward;
|
||||
|
||||
- (void) RotateToOrigin;
|
||||
- (void) RotateForward;
|
||||
- (void) RotateBackward;
|
||||
|
||||
@end
|
||||
512
common/idmobilelib/ios/Carousel.mm
Executable file
512
common/idmobilelib/ios/Carousel.mm
Executable file
@@ -0,0 +1,512 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "Carousel.h"
|
||||
#include <algorithm>
|
||||
@implementation idCarouselItem
|
||||
|
||||
@synthesize image;
|
||||
@synthesize title;
|
||||
@synthesize hash;
|
||||
|
||||
@end
|
||||
|
||||
@implementation idCarousel
|
||||
|
||||
// Move full turn at this percentage
|
||||
const static float CAROUSEL_CHANGE_DRAG = 0.2f;
|
||||
const static float CAROUSEL_BACKITEMS_ALPHA = 0.5f;
|
||||
const static float CAROUSEL_FRONTITEM_ALPHA = 1.0f;
|
||||
|
||||
enum idCarouselDrag_t {
|
||||
CAROUSEL_DRAG_MOVE_NONE = 0,
|
||||
CAROUSEL_DRAG_MOVE_FORWARD,
|
||||
CAROUSEL_DRAG_MOVE_BACKWARD
|
||||
};
|
||||
|
||||
/*
|
||||
========================
|
||||
Lerp
|
||||
========================
|
||||
*/
|
||||
static CGFloat Lerp(CGFloat from, CGFloat to, CGFloat f )
|
||||
{
|
||||
return from + ( ( to - from ) * f );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
LerpPoint
|
||||
========================
|
||||
*/
|
||||
static CGPoint LerpPoint(CGPoint a, CGPoint b, CGFloat t)
|
||||
{
|
||||
CGPoint p;
|
||||
p.x = Lerp(a.x, b.x, t);
|
||||
p.y = Lerp(a.y, b.y, t);
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
LerpSize
|
||||
========================
|
||||
*/
|
||||
static CGSize LerpSize(CGSize a, CGSize b, CGFloat t)
|
||||
{
|
||||
CGSize s;
|
||||
s.width = Lerp(a.width, b.width, t);
|
||||
s.height = Lerp(a.height, b.height, t);
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
LerpRect
|
||||
========================
|
||||
*/
|
||||
static CGRect LerpRect( CGRect a, CGRect b, CGFloat t ) {
|
||||
|
||||
CGRect r;
|
||||
r.origin = LerpPoint( a.origin, b.origin, t );
|
||||
r.size = LerpSize( a.size, b.size, t );
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
awakeFromNib
|
||||
========================
|
||||
*/
|
||||
- (void) awakeFromNib {
|
||||
|
||||
mainRect = mainSelection.frame;
|
||||
prevRect = prevSelection.frame;
|
||||
nextRect = nextSelection.frame;
|
||||
|
||||
// Allocate our Items Array
|
||||
carouselItems = [[ NSMutableArray alloc ] init ];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
touchesBegan
|
||||
========================
|
||||
*/
|
||||
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
|
||||
(void)(event);
|
||||
hasDragged = 0;
|
||||
startDragPoint = [[touches anyObject] locationInView:self];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
touchesMoved
|
||||
========================
|
||||
*/
|
||||
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||
(void)(event);
|
||||
if( prevSelection == nil || nextSelection == nil ) {
|
||||
// Nothing to transition to... dont swip transition
|
||||
return;
|
||||
}
|
||||
|
||||
CGPoint movedPoint = [[touches anyObject] locationInView:self];
|
||||
CGFloat offsetX = movedPoint.x - startDragPoint.x;
|
||||
|
||||
// Find out where im at relative to the side of the screen
|
||||
CGFloat percentage = offsetX / self.frame.size.width;
|
||||
percentage = (float)fmin( percentage, 1.0f );
|
||||
percentage = (float)fmax( percentage, -1.0f );
|
||||
|
||||
if( percentage > CAROUSEL_CHANGE_DRAG ) {
|
||||
hasDragged = CAROUSEL_DRAG_MOVE_FORWARD;
|
||||
} else if( percentage < -CAROUSEL_CHANGE_DRAG ) {
|
||||
hasDragged = CAROUSEL_DRAG_MOVE_BACKWARD;
|
||||
}
|
||||
|
||||
if( percentage > 0 ) { // Going to the right of the screen..
|
||||
|
||||
CGRect newMainRect = LerpRect( mainRect, nextRect , percentage );
|
||||
CGRect newNextRect = LerpRect( nextRect, prevRect , percentage );
|
||||
CGRect newPrevRect = LerpRect( prevRect, mainRect , percentage );
|
||||
|
||||
mainSelection.frame = newMainRect;
|
||||
prevSelection.frame = newPrevRect;
|
||||
nextSelection.frame = newNextRect;
|
||||
|
||||
mainSelection.alpha = Lerp( CAROUSEL_FRONTITEM_ALPHA, CAROUSEL_BACKITEMS_ALPHA, percentage );
|
||||
prevSelection.alpha = Lerp( CAROUSEL_BACKITEMS_ALPHA, CAROUSEL_FRONTITEM_ALPHA, percentage );
|
||||
|
||||
} else { // Going the left.
|
||||
|
||||
percentage = fabsf( percentage );
|
||||
|
||||
CGRect newMainRect = LerpRect( mainRect, prevRect , percentage );
|
||||
CGRect newNextRect = LerpRect( nextRect, mainRect , percentage );
|
||||
CGRect newPrevRect = LerpRect( prevRect, nextRect , percentage );
|
||||
|
||||
mainSelection.frame = newMainRect;
|
||||
prevSelection.frame = newPrevRect;
|
||||
nextSelection.frame = newNextRect;
|
||||
|
||||
mainSelection.alpha = Lerp( CAROUSEL_FRONTITEM_ALPHA, CAROUSEL_BACKITEMS_ALPHA, percentage );
|
||||
nextSelection.alpha = Lerp( CAROUSEL_BACKITEMS_ALPHA, CAROUSEL_FRONTITEM_ALPHA, percentage );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
touchesEnded
|
||||
========================
|
||||
*/
|
||||
- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
|
||||
(void)(event);
|
||||
(void)(touches);
|
||||
|
||||
if( hasDragged == CAROUSEL_DRAG_MOVE_FORWARD ) {
|
||||
[ self RotateForward ];
|
||||
} else if( hasDragged == CAROUSEL_DRAG_MOVE_BACKWARD ) {
|
||||
[ self RotateBackward ];
|
||||
} else {
|
||||
[ self RotateToOrigin ];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Init
|
||||
========================
|
||||
*/
|
||||
- (void) Init {
|
||||
|
||||
// Get the items At the new layout.
|
||||
idCarouselItem * cItem = [ carouselItems objectAtIndex: (NSUInteger)currentItem ];
|
||||
idCarouselItem * nItem = [ carouselItems objectAtIndex: (NSUInteger)nextItem ];
|
||||
idCarouselItem * pItem = [ carouselItems objectAtIndex: (NSUInteger)prevItem ];
|
||||
|
||||
// Set the Main Selection Text.
|
||||
[ selectionLabel setText: cItem.title ];
|
||||
|
||||
// Set the prev selection UIImage
|
||||
mainSelection.image = cItem.image;
|
||||
prevSelection.image = nItem.image;
|
||||
nextSelection.image = pItem.image;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
AddCarouselItem
|
||||
========================
|
||||
*/
|
||||
- (void) AddCarouselItem:( NSString* )Image
|
||||
:( NSString* )Title
|
||||
:( int ) ItemHash {
|
||||
|
||||
idCarouselItem * Item = [ idCarouselItem alloc ];
|
||||
|
||||
// Initialize the Item with the data passed in.
|
||||
Item.image = [UIImage imageNamed: Image ];
|
||||
Item.title = Title;
|
||||
Item.hash = ItemHash;
|
||||
|
||||
// Add the Item to our object array.
|
||||
[ carouselItems addObject: Item ];
|
||||
|
||||
// Set the Cur Item as the one just added.
|
||||
currentItem = 0;
|
||||
nextItem = 1;
|
||||
prevItem = (NSInteger)[ carouselItems count ] - 1;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
GetSelectedItem_Index
|
||||
========================
|
||||
*/
|
||||
- (NSInteger) GetSelectedItem_Index {
|
||||
return currentItem;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
GetSelectedItem_Hash
|
||||
========================
|
||||
*/
|
||||
- (int) GetSelectedItem_Hash {
|
||||
idCarouselItem * item = [ carouselItems objectAtIndex: (NSUInteger)currentItem ];
|
||||
|
||||
return item.hash;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
MoveForward
|
||||
|
||||
Interface Builder Direct Access to moving the Carousel
|
||||
========================
|
||||
*/
|
||||
- (IBAction) MoveForward {
|
||||
[ self RotateForward ];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
MoveBackward -
|
||||
|
||||
Interface Builder Direct Access to moving the Carousel
|
||||
========================
|
||||
*/
|
||||
- (IBAction) MoveBackward {
|
||||
[ self RotateBackward ];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
RotateToOrigin
|
||||
========================
|
||||
*/
|
||||
- (void) RotateToOrigin {
|
||||
|
||||
// Animate back to the correct position.
|
||||
// Move the Current Selection to Next Selection
|
||||
[UIView beginAnimations:nil context:nil];
|
||||
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
|
||||
[UIView setAnimationBeginsFromCurrentState:YES];
|
||||
|
||||
// Move them into Place.
|
||||
mainSelection.frame = mainRect;
|
||||
prevSelection.frame = prevRect;
|
||||
nextSelection.frame = nextRect;
|
||||
|
||||
mainSelection.alpha = 1.0f;
|
||||
nextSelection.alpha = CAROUSEL_BACKITEMS_ALPHA;
|
||||
prevSelection.alpha = CAROUSEL_BACKITEMS_ALPHA;
|
||||
|
||||
[UIView commitAnimations];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
RotateForward
|
||||
========================
|
||||
*/
|
||||
- (void) RotateForward {
|
||||
|
||||
if( prevSelection == nil || nextSelection == nil ) {
|
||||
|
||||
// Flip book to the next selection.
|
||||
// increment the item indicies.
|
||||
currentItem++;
|
||||
nextItem++;
|
||||
prevItem++;
|
||||
|
||||
// Check the Extents.
|
||||
if( currentItem >= (NSInteger)[ carouselItems count ] ) {
|
||||
currentItem = 0;
|
||||
}
|
||||
if( nextItem >= (NSInteger)[ carouselItems count ] ) {
|
||||
nextItem = 0;
|
||||
}
|
||||
if( prevItem >= (NSInteger)[ carouselItems count ] ) {
|
||||
prevItem = 0;
|
||||
}
|
||||
|
||||
idCarouselItem * cItem = [ carouselItems objectAtIndex: (NSUInteger)currentItem ];
|
||||
|
||||
// Set the Main Selection Text.
|
||||
[ selectionLabel setText: cItem.title ];
|
||||
|
||||
// Set the prev selection UIImage
|
||||
mainSelection.image = cItem.image;
|
||||
|
||||
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
UIImageView * tempMain = mainSelection;
|
||||
UIImageView * tempPrev = prevSelection;
|
||||
UIImageView * tempNext = nextSelection;
|
||||
|
||||
// Move the Current Selection to Next Selection
|
||||
[UIView beginAnimations:nil context:nil];
|
||||
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
|
||||
[UIView setAnimationBeginsFromCurrentState:YES];
|
||||
|
||||
// Move them into Place.
|
||||
mainSelection.frame = nextRect;
|
||||
prevSelection.frame = mainRect;
|
||||
nextSelection.frame = prevRect;
|
||||
|
||||
// Darken the prev/next
|
||||
mainSelection.alpha = CAROUSEL_BACKITEMS_ALPHA;
|
||||
prevSelection.alpha = CAROUSEL_FRONTITEM_ALPHA;
|
||||
nextSelection.alpha = CAROUSEL_BACKITEMS_ALPHA;
|
||||
|
||||
[UIView commitAnimations];
|
||||
|
||||
|
||||
// Swap out the ImageViews so that they are in the correct order.
|
||||
nextSelection = tempMain;
|
||||
mainSelection = tempPrev;
|
||||
prevSelection = tempNext;
|
||||
|
||||
// Make sure they are in back of the main selection.
|
||||
[ self sendSubviewToBack: nextSelection ];
|
||||
[ self sendSubviewToBack: prevSelection ];
|
||||
|
||||
// increment the item indicies.
|
||||
currentItem++;
|
||||
nextItem++;
|
||||
prevItem++;
|
||||
|
||||
// Check the Extents.
|
||||
if( currentItem >= (NSInteger)[ carouselItems count ] ) {
|
||||
currentItem = 0;
|
||||
}
|
||||
if( nextItem >= (NSInteger)[ carouselItems count ] ) {
|
||||
nextItem = 0;
|
||||
}
|
||||
if( prevItem >= (NSInteger)[ carouselItems count ] ) {
|
||||
prevItem = 0;
|
||||
}
|
||||
|
||||
// Get the items At the new layout.
|
||||
idCarouselItem * cItem = [ carouselItems objectAtIndex: (NSUInteger)currentItem ];
|
||||
idCarouselItem * nItem = [ carouselItems objectAtIndex: (NSUInteger)nextItem ];
|
||||
idCarouselItem * pItem = [ carouselItems objectAtIndex: (NSUInteger)prevItem ];
|
||||
|
||||
// Set the Main Selection Text.
|
||||
[ selectionLabel setText: cItem.title ];
|
||||
|
||||
// Set the prev selection UIImage
|
||||
mainSelection.image = cItem.image;
|
||||
prevSelection.image = nItem.image;
|
||||
nextSelection.image = pItem.image;
|
||||
|
||||
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
RotateBackward
|
||||
========================
|
||||
*/
|
||||
- (void) RotateBackward {
|
||||
|
||||
if( nextSelection == nil || prevSelection == nil ) {
|
||||
|
||||
// increment the item indicies.
|
||||
currentItem--;
|
||||
nextItem--;
|
||||
prevItem--;
|
||||
|
||||
// Check the Extents.
|
||||
if( currentItem < 0 ) {
|
||||
currentItem = (NSInteger)[ carouselItems count ] - 1;
|
||||
}
|
||||
if( nextItem < 0 ) {
|
||||
nextItem = (NSInteger)[ carouselItems count ] - 1;;
|
||||
}
|
||||
if( prevItem < 0 ) {
|
||||
prevItem = (NSInteger)[ carouselItems count ] - 1;;
|
||||
}
|
||||
|
||||
idCarouselItem * cItem = [ carouselItems objectAtIndex: (NSUInteger)currentItem ];
|
||||
|
||||
// Set the Main Selection Text.
|
||||
[ selectionLabel setText: cItem.title ];
|
||||
|
||||
// Set the prev selection UIImage
|
||||
mainSelection.image = cItem.image;
|
||||
|
||||
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
UIImageView * tempMain = mainSelection;
|
||||
UIImageView * tempPrev = prevSelection;
|
||||
UIImageView * tempNext = nextSelection;
|
||||
|
||||
// Move the Current Selection to Next Selection
|
||||
[UIView beginAnimations:nil context:nil];
|
||||
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
|
||||
[UIView setAnimationBeginsFromCurrentState:YES];
|
||||
|
||||
// Move them into Place.
|
||||
mainSelection.frame = prevRect;
|
||||
prevSelection.frame = nextRect;
|
||||
nextSelection.frame = mainRect;
|
||||
|
||||
// Darken the prev/next
|
||||
mainSelection.alpha = CAROUSEL_BACKITEMS_ALPHA;
|
||||
prevSelection.alpha = CAROUSEL_BACKITEMS_ALPHA;
|
||||
nextSelection.alpha = CAROUSEL_FRONTITEM_ALPHA;
|
||||
|
||||
[UIView commitAnimations];
|
||||
|
||||
// Swap out the ImageViews so that they are in the correct order.
|
||||
nextSelection = tempPrev;
|
||||
mainSelection = tempNext;
|
||||
prevSelection = tempMain;
|
||||
|
||||
// Make sure they are in back of the main selection.
|
||||
[ self sendSubviewToBack: nextSelection ];
|
||||
[ self sendSubviewToBack: prevSelection ];
|
||||
|
||||
// increment the item indicies.
|
||||
currentItem--;
|
||||
nextItem--;
|
||||
prevItem--;
|
||||
|
||||
// Check the Extents.
|
||||
if( currentItem < 0 ) {
|
||||
currentItem = (NSInteger)[ carouselItems count ] - 1;
|
||||
}
|
||||
if( nextItem < 0 ) {
|
||||
nextItem = (NSInteger)[ carouselItems count ] - 1;;
|
||||
}
|
||||
if( prevItem < 0 ) {
|
||||
prevItem = (NSInteger)[ carouselItems count ] - 1;;
|
||||
}
|
||||
|
||||
// Get the items At the new layout.
|
||||
idCarouselItem * cItem = [ carouselItems objectAtIndex: (NSUInteger) currentItem ];
|
||||
idCarouselItem * nItem = [ carouselItems objectAtIndex: (NSUInteger)nextItem ];
|
||||
idCarouselItem * pItem = [ carouselItems objectAtIndex: (NSUInteger)prevItem ];
|
||||
|
||||
// Set the Main Selection Text.
|
||||
[ selectionLabel setText: cItem.title ];
|
||||
|
||||
// Set the prev selection UIImage
|
||||
mainSelection.image = cItem.image;
|
||||
prevSelection.image = nItem.image;
|
||||
nextSelection.image = pItem.image;
|
||||
|
||||
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
||||
}
|
||||
|
||||
@end
|
||||
134
common/idmobilelib/ios/GameCenter.h
Executable file
134
common/idmobilelib/ios/GameCenter.h
Executable file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
================================================================================================
|
||||
|
||||
A game-generic C++ wrapper around the iOS Game Center functionality.
|
||||
|
||||
|
||||
The class checks for Game Center availability in the constructor, and if Game Center is found
|
||||
to be unsupported, a flag is set that causes all other function calls to early-exit and
|
||||
do nothing. This way, the game code doesn't have to worry about whether Game Center is supported
|
||||
for every call it makes, but can still check for support in order to, say, adjust the UI
|
||||
if necessary.
|
||||
|
||||
This class is not meant to be subclassed.
|
||||
|
||||
This class uses the pimpl idiom (see http://herbsutter.com/gotw/_100/) to hide many of the
|
||||
implementation details. I've found this to be a decent way to hide all the Objective-C code
|
||||
from user code, so that C++-only portions of code can still access iOS functionality.
|
||||
|
||||
================================================================================================
|
||||
*/
|
||||
|
||||
#ifndef IDMOBILELIB_GAMECENTER_H
|
||||
#define IDMOBILELIB_GAMECENTER_H
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <tr1/cstdint>
|
||||
|
||||
#include "../sys/sys_defines.h"
|
||||
|
||||
|
||||
/*
|
||||
================================================
|
||||
Contains function definitions to be overridden by specific games.
|
||||
================================================
|
||||
*/
|
||||
class idGameCenterMatchHandler
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~idGameCenterMatchHandler() {}
|
||||
|
||||
void createdMatch() { createdMatchImpl(); }
|
||||
void allPlayersConnected( std::vector<std::string> connectedPlayerIDs ) {
|
||||
allPlayersConnectedImpl( connectedPlayerIDs );
|
||||
}
|
||||
|
||||
void playerConnected( std::string playerIdentifier ) {
|
||||
playerConnectedImpl( playerIdentifier );
|
||||
}
|
||||
|
||||
void playerDisconnected( std::string playerIdentifer ) {
|
||||
playerDisconnectedImpl( playerIdentifer );
|
||||
}
|
||||
|
||||
void receivedData( std::string fromPlayerID, const void * data, int numBytes ) {
|
||||
receivedDataImpl( fromPlayerID, data, numBytes );
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void createdMatchImpl() = 0;
|
||||
virtual void allPlayersConnectedImpl( std::vector<std::string> connectedPlayerIDs ) = 0;
|
||||
virtual void playerConnectedImpl( std::string playerIdentifer ) = 0;
|
||||
virtual void playerDisconnectedImpl( std::string playerIdentifer ) = 0;
|
||||
|
||||
virtual void receivedDataImpl( std::string fromPlayerID, const void * data, int numBytes ) = 0;
|
||||
};
|
||||
|
||||
|
||||
namespace idGameCenter {
|
||||
|
||||
static const int MAX_PACKET_SIZE_IN_BYTES = 1500;
|
||||
|
||||
struct matchParms_t {
|
||||
unsigned int minimumPlayers;
|
||||
unsigned int maximumPlayers;
|
||||
std::tr1::uint32_t automatchGroup;
|
||||
};
|
||||
|
||||
void Initialize();
|
||||
void Shutdown();
|
||||
|
||||
void AuthenticateLocalPlayer( id currentViewController, idGameCenterMatchHandler * handler );
|
||||
|
||||
bool IsAvailable();
|
||||
bool IsLocalPlayerAuthenticated();
|
||||
|
||||
void HandleMoveToBackground();
|
||||
|
||||
void PresentMatchmaker( id currentViewController, matchParms_t parms, idGameCenterMatchHandler * handler );
|
||||
|
||||
void PushMatchmakerToNavigationController( id navigationController,
|
||||
matchParms_t parms,
|
||||
idGameCenterMatchHandler * handler );
|
||||
|
||||
bool IsInMatch();
|
||||
|
||||
void SendPacketToPlayerUnreliable( std::string destinationPlayer,
|
||||
void * packet,
|
||||
std::size_t packetSize );
|
||||
|
||||
void SendPacketToPlayerReliable( std::string destinationPlayer,
|
||||
void * packet,
|
||||
std::size_t packetSize );
|
||||
|
||||
void BroadcastPacketReliable( void * packet, int numBytes );
|
||||
|
||||
void DisconnectFromMatch();
|
||||
}
|
||||
|
||||
#endif
|
||||
712
common/idmobilelib/ios/GameCenter.mm
Executable file
712
common/idmobilelib/ios/GameCenter.mm
Executable file
@@ -0,0 +1,712 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "GameCenter.h"
|
||||
#include "objectivec_utilities.h"
|
||||
#include "LocalizationObjectiveC.h"
|
||||
#include "ios_interface.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#import <GameKit/GameKit.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <UIKit/UIDevice.h>
|
||||
#import <Foundation/NSData.h>
|
||||
|
||||
namespace {
|
||||
enum matchmakerViewMode_t {
|
||||
MATCH_VIEW_MODAL,
|
||||
MATCH_VIEW_PUSH_TO_NAVIGATION_CONTROLLER
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
================================================
|
||||
The Objective-C delegate required for implementing Game Kit matches.
|
||||
================================================
|
||||
*/
|
||||
@interface MatchDelegate : NSObject< GKMatchmakerViewControllerDelegate, GKMatchDelegate >
|
||||
|
||||
@property(nonatomic, assign) UIViewController * gameViewController;
|
||||
@property(nonatomic, assign) idGameCenterMatchHandler * matchHandler;
|
||||
@property(nonatomic, retain) GKMatch * currentMatch;
|
||||
@property(nonatomic, assign) BOOL matchHasStarted;
|
||||
@property(nonatomic, assign) matchmakerViewMode_t matchmakerMode;
|
||||
|
||||
+ (MatchDelegate*)sharedMatchDelegate;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
static MatchDelegate * sharedMatchDelegateInstance = nil;
|
||||
|
||||
|
||||
|
||||
// Unnamed-namespace for internal-linkage definitions.
|
||||
namespace {
|
||||
/*
|
||||
========================
|
||||
Game Center is only supported on iOS 4.1 and later. If we are running on a device
|
||||
that doesn't support Game Center, we must disable its functionality.
|
||||
The implementation of the check was taken straight form the Apple documentation.
|
||||
========================
|
||||
*/
|
||||
bool HasGameCenterSupport() {
|
||||
BOOL localPlayerClassAvailable = (NSClassFromString(@"GKLocalPlayer")) != nil;
|
||||
|
||||
// The device must be running iOS 4.1 or later.
|
||||
NSString *reqSysVer = @"4.1";
|
||||
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
|
||||
BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending);
|
||||
|
||||
return (localPlayerClassAvailable && osVersionSupported);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@implementation MatchDelegate
|
||||
|
||||
@synthesize matchHandler;
|
||||
@synthesize gameViewController;
|
||||
@synthesize currentMatch;
|
||||
@synthesize matchHasStarted;
|
||||
@synthesize matchmakerMode;
|
||||
|
||||
/*
|
||||
========================
|
||||
Singleton implementation. Since we should only ever have one match going on at a time,
|
||||
the delegate might as well be a singleton. This is Apple's idiomatic example of a Singleton
|
||||
in Objective-C.
|
||||
========================
|
||||
*/
|
||||
+ (MatchDelegate*)sharedMatchDelegate
|
||||
{
|
||||
if (sharedMatchDelegateInstance == nil) {
|
||||
sharedMatchDelegateInstance = [[super allocWithZone:NULL] init];
|
||||
sharedMatchDelegateInstance->matchHandler = NULL;
|
||||
sharedMatchDelegateInstance->matchHasStarted = NO;
|
||||
sharedMatchDelegateInstance->currentMatch = nil;
|
||||
|
||||
}
|
||||
return sharedMatchDelegateInstance;
|
||||
}
|
||||
|
||||
+ (id)allocWithZone:(NSZone *)zone
|
||||
{
|
||||
(void)zone;
|
||||
return [[self sharedMatchDelegate] retain];
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
(void)zone;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)retain
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSUInteger)retainCount
|
||||
{
|
||||
return NSUIntegerMax; //denotes an object that cannot be released
|
||||
}
|
||||
|
||||
- (oneway void)release
|
||||
{
|
||||
//do nothing
|
||||
}
|
||||
|
||||
- (id)autorelease
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
Called by the system when Game Center receives a packet from another player. I was
|
||||
somewhat surprised that this method actually runs on the main thread.
|
||||
========================
|
||||
*/
|
||||
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID {
|
||||
(void)match;
|
||||
(void)playerID;
|
||||
|
||||
// Sanity-check the size of the data. Discard any packets that won't fit.
|
||||
if ( static_cast<int>( [data length] ) > idGameCenter::MAX_PACKET_SIZE_IN_BYTES ) {
|
||||
printf( "Received a packet that was too big. Discarding.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Sanity-check the size of the data. Discard any packets with zero length.
|
||||
if ( [data length] == 0 ) {
|
||||
printf( "Received a packet with zero length. Discarding.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Give the callback a chance to process the packet.
|
||||
self.matchHandler->receivedData( NSStringToStdString( playerID ),
|
||||
[data bytes],
|
||||
static_cast<int>( [data length] ) );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Called by the system when a player's state changes (for example, they connect or disconnect).
|
||||
========================
|
||||
*/
|
||||
- (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state {
|
||||
switch (state)
|
||||
{
|
||||
case GKPlayerStateConnected:
|
||||
matchHandler->playerConnected( NSStringToStdString( playerID ) );
|
||||
|
||||
if (!matchHasStarted && match.expectedPlayerCount == 0)
|
||||
{
|
||||
matchHasStarted = YES;
|
||||
|
||||
std::vector<std::string> players;
|
||||
|
||||
for( NSString* currentID in match.playerIDs ) {
|
||||
players.push_back( NSStringToStdString( currentID ) );
|
||||
}
|
||||
matchHandler->allPlayersConnected( players );
|
||||
}
|
||||
|
||||
break;
|
||||
case GKPlayerStateDisconnected:
|
||||
matchHandler->playerDisconnected( NSStringToStdString( playerID ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Called by the system if the connection with a player fails.
|
||||
========================
|
||||
*/
|
||||
- (void)match:(GKMatch *)match connectionWithPlayerFailed:(NSString *)playerID withError:(NSError *)error {
|
||||
(void)match;
|
||||
(void)playerID;
|
||||
|
||||
DisplayNSErrorMessage( @"GameKit Error", error );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Called by the system if the matchmaking interface fails.
|
||||
========================
|
||||
*/
|
||||
- (void)match:(GKMatch *)match didFailWithError:(NSError *)error {
|
||||
(void)match;
|
||||
|
||||
DisplayNSErrorMessage( @"GameKit Error", error );
|
||||
}
|
||||
|
||||
|
||||
// GKMatchmakerViewController
|
||||
|
||||
/*
|
||||
========================
|
||||
Called by the system if the user dismisses the matchmaking interface.
|
||||
========================
|
||||
*/
|
||||
- (void)matchmakerViewControllerWasCancelled:(GKMatchmakerViewController *)viewController
|
||||
{
|
||||
switch ( matchmakerMode ) {
|
||||
case MATCH_VIEW_MODAL: {
|
||||
[gameViewController dismissModalViewControllerAnimated:YES];
|
||||
break;
|
||||
}
|
||||
|
||||
case MATCH_VIEW_PUSH_TO_NAVIGATION_CONTROLLER: {
|
||||
[viewController.navigationController popViewControllerAnimated:YES];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Called by the system if there is an error in the matchmaking process.
|
||||
========================
|
||||
*/
|
||||
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFailWithError:(NSError *)error
|
||||
{
|
||||
(void)viewController;
|
||||
|
||||
DisplayNSErrorMessage( idLocalization_GetNSString( @"Matchmaking error" ), error );
|
||||
|
||||
switch ( matchmakerMode ) {
|
||||
case MATCH_VIEW_MODAL: {
|
||||
[gameViewController dismissModalViewControllerAnimated:YES];
|
||||
break;
|
||||
}
|
||||
|
||||
case MATCH_VIEW_PUSH_TO_NAVIGATION_CONTROLLER: {
|
||||
[viewController.navigationController popViewControllerAnimated:YES];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Called by the system if it finds a match.
|
||||
========================
|
||||
*/
|
||||
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)match
|
||||
{
|
||||
(void)viewController;
|
||||
(void)match;
|
||||
|
||||
switch ( matchmakerMode ) {
|
||||
case MATCH_VIEW_MODAL: {
|
||||
[gameViewController dismissModalViewControllerAnimated:YES];
|
||||
break;
|
||||
}
|
||||
|
||||
case MATCH_VIEW_PUSH_TO_NAVIGATION_CONTROLLER: {
|
||||
[viewController.navigationController popViewControllerAnimated:NO];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NSLog(@"Found a Game Center match!!!");
|
||||
|
||||
self.currentMatch = match;
|
||||
match.delegate = self;
|
||||
|
||||
matchHandler->createdMatch();
|
||||
|
||||
if (!matchHasStarted && match.expectedPlayerCount == 0)
|
||||
{
|
||||
matchHasStarted = NO;
|
||||
|
||||
std::vector<std::string> players;
|
||||
|
||||
for( NSString* currentID in match.playerIDs ) {
|
||||
players.push_back( NSStringToStdString( currentID ) );
|
||||
}
|
||||
matchHandler->allPlayersConnected( players );
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/*
|
||||
================================================
|
||||
The private implementation of idGameCenter, defined here in order to insulate user code from
|
||||
Objective-C land.
|
||||
================================================
|
||||
*/
|
||||
namespace {
|
||||
// Cache the result of HasGameCenterSupport. Even if HasGameCenterSupport returns true,
|
||||
// it's possible that a Game Kit method may cause a GKErrorNotSupported. If it does, this
|
||||
// variable will be set to false in HandleError.
|
||||
bool isAvailable;
|
||||
|
||||
// Cache the player identifier. This is the unique key used to distiguish players in
|
||||
// Game Kit. All data associated with a player should be tied to this ID, such as
|
||||
// achievement and savegame progress. Note that this ID can change if a user task-switches
|
||||
// to the Game Center app and logs in with a different account.
|
||||
// The string will be empty if no local player is authenticated.
|
||||
// The string is UTF8 encoded.
|
||||
std::string playerIdentifier;
|
||||
|
||||
// Store the match handler object. This is how we deal with "callbacks" from the Game Center
|
||||
// API.
|
||||
idGameCenterMatchHandler * matchHandler;
|
||||
|
||||
void HandleError( NSError * error );
|
||||
|
||||
void ConfigureDelegate( matchmakerViewMode_t mode,
|
||||
id currentViewController,
|
||||
idGameCenterMatchHandler * handler );
|
||||
|
||||
void SendPacketToPlayerHelper( std::string destinationPlayer,
|
||||
void *packet,
|
||||
std::size_t numBytes,
|
||||
GKMatchSendDataMode mode );
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
Handles errors reported by the Game Kit APIs. If it gets GKErrorNotSupported, this function
|
||||
sets isAvailable to false.
|
||||
========================
|
||||
*/
|
||||
void HandleError( NSError * error ) {
|
||||
if ( error == nil ) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( [error code] ) {
|
||||
case GKErrorGameUnrecognized: {
|
||||
NSLog( @"GameKit error: Game unrecognized." );
|
||||
break;
|
||||
}
|
||||
case GKErrorNotSupported: {
|
||||
NSLog( @"GameKit error: Not supported. Disabling GameKit features." );
|
||||
isAvailable = false;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
Sets up neede properties of the match delegate. Call this before showing the matchmaking view
|
||||
controller. This implementation supports two ways of showing the built-in matchmaker, either
|
||||
modally or as a new view controller on a navigation controller's stack. If using a
|
||||
navigation controller, the currentViewController parameter can be left nil.
|
||||
========================
|
||||
*/
|
||||
void ConfigureDelegate( matchmakerViewMode_t mode,
|
||||
id currentViewController,
|
||||
idGameCenterMatchHandler * handler ) {
|
||||
|
||||
[MatchDelegate sharedMatchDelegate].matchmakerMode = mode;
|
||||
[MatchDelegate sharedMatchDelegate].matchHandler = handler;
|
||||
[MatchDelegate sharedMatchDelegate].gameViewController = currentViewController;
|
||||
[MatchDelegate sharedMatchDelegate].matchHasStarted = NO;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
Sends a packet to a player ID with the data mode specified in the parameter.
|
||||
========================
|
||||
*/
|
||||
void SendPacketToPlayerHelper( std::string destinationPlayer,
|
||||
void *packet,
|
||||
std::size_t numBytes,
|
||||
GKMatchSendDataMode mode ) {
|
||||
|
||||
if ( idGameCenter::IsAvailable() == false || idGameCenter::IsLocalPlayerAuthenticated() == false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( idGameCenter::IsInMatch() == false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
GKMatch * theMatch = [MatchDelegate sharedMatchDelegate].currentMatch;
|
||||
|
||||
|
||||
NSError * theError = nil;
|
||||
|
||||
NSData *nsPacket = [ NSData dataWithBytes:packet length:static_cast<NSUInteger>( numBytes ) ];
|
||||
NSArray *playerArray = [ NSArray arrayWithObject:StdStringToNSString( destinationPlayer ) ];
|
||||
|
||||
[theMatch sendData:nsPacket toPlayers:playerArray withDataMode:mode error:&theError];
|
||||
|
||||
if ( theError != nil )
|
||||
{
|
||||
DisplayNSErrorMessage( @"GameKit Error", theError );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace idGameCenter {
|
||||
/*
|
||||
========================
|
||||
impl constructor. Sets the inital value of isAvailable based on the OS checks in
|
||||
HasGameCenterSupport. Note that isAvailable might be set to false later if a GameKit API
|
||||
returns a GKErrorNotSupported.
|
||||
========================
|
||||
*/
|
||||
void Initialize() {
|
||||
isAvailable = HasGameCenterSupport();
|
||||
matchHandler = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
Returns true if the runtime device supports Game Center. If it doesn't, we may need to
|
||||
disable UI elements, etc.
|
||||
========================
|
||||
*/
|
||||
bool IsAvailable() {
|
||||
return isAvailable;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Returns true if there is a local player authenticated.
|
||||
========================
|
||||
*/
|
||||
bool IsLocalPlayerAuthenticated() {
|
||||
return !playerIdentifier.empty();
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Attempts to authenticate the local player. Apple recommends that this be done as soon as
|
||||
possible after the game starts up and is able to display a UI (probably in
|
||||
applicationDidFinishLaunching).
|
||||
========================
|
||||
*/
|
||||
void AuthenticateLocalPlayer( id currentViewController, idGameCenterMatchHandler * handler ) {
|
||||
// Early exit if Game Center is not supported.
|
||||
if ( IsAvailable() == false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
|
||||
[localPlayer authenticateWithCompletionHandler:^(NSError * error) {
|
||||
if ( localPlayer.isAuthenticated )
|
||||
{
|
||||
// Perform additional tasks for the authenticated player.
|
||||
GKLocalPlayer * lp = [GKLocalPlayer localPlayer];
|
||||
|
||||
// Cache the player identifier string.
|
||||
std::string newPlayerIdentifier = NSStringToStdString( [lp playerID] );
|
||||
|
||||
// If the player changed while the app was in the background, the playerIDs will
|
||||
// be different. If they are, we have to switch any game state to reflect the
|
||||
// new player.
|
||||
if ( newPlayerIdentifier != playerIdentifier ) {
|
||||
// TODO: Switch game state to reflect the newly logged in player.
|
||||
}
|
||||
|
||||
playerIdentifier = newPlayerIdentifier;
|
||||
|
||||
// Set up the invitation handler. This code handles the cases where a friend
|
||||
// is invited to the game from the matchmaking UI or the Game Center application.
|
||||
[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) {
|
||||
// Disconnect from any previous game.
|
||||
idGameCenter::DisconnectFromMatch();
|
||||
|
||||
ConfigureDelegate( MATCH_VIEW_MODAL, currentViewController, handler );
|
||||
|
||||
if (acceptedInvite)
|
||||
{
|
||||
GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:acceptedInvite] autorelease];
|
||||
mmvc.matchmakerDelegate = [MatchDelegate sharedMatchDelegate];
|
||||
[currentViewController presentModalViewController:mmvc animated:YES];
|
||||
}
|
||||
else if (playersToInvite)
|
||||
{
|
||||
GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease];
|
||||
request.minPlayers = 2;
|
||||
request.maxPlayers = 4;
|
||||
request.playersToInvite = playersToInvite;
|
||||
|
||||
GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];
|
||||
mmvc.matchmakerDelegate = [MatchDelegate sharedMatchDelegate];
|
||||
[currentViewController presentModalViewController:mmvc animated:YES];
|
||||
}
|
||||
};
|
||||
} else {
|
||||
// No new local player is logged in. If no player was logged in before, we shouldn't
|
||||
// have to do anything here.
|
||||
// But if a player was previously logged in, we need to update the game state, for
|
||||
// example, clear achievement progress or load different saved games.
|
||||
if ( !playerIdentifier.empty() ) {
|
||||
// TODO: Clean up state related to the old playerIdentifier.
|
||||
}
|
||||
|
||||
// Empty the string to indicate no one is logged in.
|
||||
playerIdentifier.clear();
|
||||
}
|
||||
|
||||
HandleError( error );
|
||||
}];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
This function must be called when the app is moving to the background (such as from
|
||||
applicationWillResignActive). It will de-authenticate the local player, because the user
|
||||
might sign out while our app is in the background.
|
||||
|
||||
According to the Apple documentation, we need to de-authenticate the local player when the app
|
||||
moves to the background. The implication of this is that for lockstep games like DOOM, we
|
||||
can't continue to update the game while our app is in the background. In order to not cause
|
||||
problems for other players, we just disconnect from a match (if any) right here.
|
||||
|
||||
TODO: When we support achievements and/or leaderboards, serialize out any data that hasn't
|
||||
been successfully sent to Game Center yet. We'll need to do this because the OS might kill
|
||||
our app while it's in the background.
|
||||
========================
|
||||
*/
|
||||
void HandleMoveToBackground() {
|
||||
if ( IsInMatch() ) {
|
||||
ShowSystemAlert( "Connection lost", "Lost connection to server" );
|
||||
}
|
||||
|
||||
DisconnectFromMatch();
|
||||
playerIdentifier.empty();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
Presents Game Center's built-in matchmaking view controller as a model view controller on top
|
||||
of currentViewController.
|
||||
MAKE SURE the handler object survives the duration of the app!
|
||||
========================
|
||||
*/
|
||||
void PresentMatchmaker( id currentViewController, matchParms_t parms, idGameCenterMatchHandler * handler ) {
|
||||
// Early exit if Game Center is not active.
|
||||
if ( IsAvailable() == false || IsLocalPlayerAuthenticated() == false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigureDelegate( MATCH_VIEW_MODAL, currentViewController, handler );
|
||||
|
||||
|
||||
GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease];
|
||||
request.minPlayers = parms.minimumPlayers;
|
||||
request.maxPlayers = parms.maximumPlayers;
|
||||
request.playerGroup = parms.automatchGroup;
|
||||
|
||||
GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];
|
||||
mmvc.matchmakerDelegate = [MatchDelegate sharedMatchDelegate];
|
||||
|
||||
[(UIViewController*)currentViewController presentModalViewController:mmvc animated:YES];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Presents Game Center's built-in matchmaking view controller as a new controller on top
|
||||
of the navigationController's stack.
|
||||
MAKE SURE the handler object survives the duration of the app!
|
||||
========================
|
||||
*/
|
||||
void PushMatchmakerToNavigationController( id navigationController,
|
||||
matchParms_t parms,
|
||||
idGameCenterMatchHandler * handler ) {
|
||||
// Early exit if Game Center is not active.
|
||||
if ( IsAvailable() == false || IsLocalPlayerAuthenticated() == false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigureDelegate( MATCH_VIEW_PUSH_TO_NAVIGATION_CONTROLLER, nil, handler );
|
||||
|
||||
GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease];
|
||||
request.minPlayers = parms.minimumPlayers;
|
||||
request.maxPlayers = parms.maximumPlayers;
|
||||
request.playerGroup = parms.automatchGroup;
|
||||
|
||||
GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];
|
||||
mmvc.matchmakerDelegate = [MatchDelegate sharedMatchDelegate];
|
||||
|
||||
[navigationController pushViewController:mmvc animated:YES];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Returns true if the player is currently connected to a Game Center match, false if not.
|
||||
========================
|
||||
*/
|
||||
bool IsInMatch() {
|
||||
return [MatchDelegate sharedMatchDelegate].currentMatch != nil;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Sends an unreliable packet to a single player.
|
||||
========================
|
||||
*/
|
||||
void SendPacketToPlayerUnreliable( std::string destinationPlayer,
|
||||
void *packet,
|
||||
std::size_t numBytes ) {
|
||||
SendPacketToPlayerHelper( destinationPlayer, packet, numBytes, GKMatchSendDataUnreliable );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
Sends a reliable packet to a single player.
|
||||
========================
|
||||
*/
|
||||
void SendPacketToPlayerReliable( std::string destinationPlayer,
|
||||
void *packet,
|
||||
std::size_t numBytes ) {
|
||||
SendPacketToPlayerHelper( destinationPlayer, packet, numBytes, GKMatchSendDataReliable );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
Sends a packet to all other players in the current match. Just returns if Game Center is not
|
||||
available or if the local player is not in a match.
|
||||
========================
|
||||
*/
|
||||
void BroadcastPacketReliable( void * packet, int numBytes ) {
|
||||
if ( IsAvailable() == false || IsLocalPlayerAuthenticated() == false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( IsInMatch() == false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
GKMatch * theMatch = [MatchDelegate sharedMatchDelegate].currentMatch;
|
||||
|
||||
|
||||
NSError * theError = nil;
|
||||
|
||||
NSData *nsPacket = [NSData dataWithBytes:packet length:static_cast<NSUInteger>(numBytes)];
|
||||
|
||||
[theMatch sendDataToAllPlayers:nsPacket withDataMode:GKMatchSendDataReliable error:&theError];
|
||||
|
||||
if ( theError != nil )
|
||||
{
|
||||
DisplayNSErrorMessage( @"GameKit Error", theError );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
If this player is currently connected to a match. this will disconnect them.
|
||||
========================
|
||||
*/
|
||||
void DisconnectFromMatch() {
|
||||
if ( IsInMatch() ) {
|
||||
[[MatchDelegate sharedMatchDelegate].currentMatch disconnect];
|
||||
|
||||
// currentMatch is a retained property, so this will release it.
|
||||
[MatchDelegate sharedMatchDelegate].currentMatch = nil;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
95
common/idmobilelib/ios/InAppStore.h
Executable file
95
common/idmobilelib/ios/InAppStore.h
Executable file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
================================================================================================
|
||||
|
||||
Interface to the device's In-App Purchase system.
|
||||
|
||||
|
||||
This interface was designed to be dropped into any game that needs support for in-app purchases,
|
||||
that is, there is nothing game-specific about this interface or its implementation.
|
||||
|
||||
It is essentially a singleton implemented in the idInAppPurchase namespace. The singleton must
|
||||
be initialized at application launch (via Initialize()) and shut down at application exit (via
|
||||
Shutdown()).
|
||||
|
||||
There are functions to request information about products for sale within the app, check whether
|
||||
a particular product has been purchased, and get the localized price for a product, suitable
|
||||
for displaying in the user interface.
|
||||
|
||||
Generally an app should call RequestInformation() at startup (but after Initialize()) and pass
|
||||
in all the product identifiers that the app offers for sale. The request will run in the
|
||||
background so that the interface will remain responsive. Once the requests have been returned,
|
||||
the application can get the price information and actually initiate purchases of products.
|
||||
|
||||
================================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INAPPSTORE_H
|
||||
#define INAPPSTORE_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <tr1/functional>
|
||||
|
||||
namespace idInAppStore {
|
||||
|
||||
void Initialize( const std::vector<std::string> & productIdentifiers );
|
||||
void Shutdown();
|
||||
|
||||
bool IsEnabled();
|
||||
|
||||
void ShowDisabledAlert( std::string title,
|
||||
std::string description,
|
||||
std::string okButton );
|
||||
|
||||
bool HasPurchased( const char * const productIdentifier );
|
||||
bool CanPurchase( const char * const productIdentifier );
|
||||
bool IsWaitingForInformation( const char * const productIdentifier );
|
||||
bool IsWaitingForPurchase( const char * const productIdentifier );
|
||||
|
||||
std::string GetLocalizedPrice( const char * const productIdentifier );
|
||||
|
||||
void StartPurchase( const char * const productIdentifier );
|
||||
|
||||
/*
|
||||
========================
|
||||
The application can register callbacks to be notified of events that occur relating to
|
||||
the in-app store. The first parameter to the callback function is the product identifier
|
||||
string for the product that was affected, the second is the status of that product.
|
||||
========================
|
||||
*/
|
||||
enum productStatus_t {
|
||||
PRODUCT_STATUS_TRANSACTION_FAILED,
|
||||
PRODUCT_STATUS_RECEIVED_INFORMATION,
|
||||
PRODUCT_STATUS_PURCHASED
|
||||
};
|
||||
|
||||
typedef std::tr1::function< void ( const char * const, productStatus_t ) > callback_t;
|
||||
|
||||
void SetCallback( callback_t callback );
|
||||
void ClearCallback();
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
683
common/idmobilelib/ios/InAppStore.mm
Executable file
683
common/idmobilelib/ios/InAppStore.mm
Executable file
@@ -0,0 +1,683 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
================================================================================================
|
||||
|
||||
Implentation of the In-App Purchase system for iOS devices.
|
||||
|
||||
|
||||
This implementation conforms to the interface in InAppStore.h. It uses the NSUserDefaults object
|
||||
provided by the system to keep track of the state of the products that the application offers.
|
||||
|
||||
================================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#include "InAppStore.h"
|
||||
|
||||
#import <StoreKit/StoreKit.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
// For ease of development, leave this defined to skip in-app purchase prompts.
|
||||
//#define TEST_ALL_PRODUCTS_PURCHASED
|
||||
|
||||
@interface MyStoreObserver : NSObject<SKProductsRequestDelegate, SKPaymentTransactionObserver> {
|
||||
|
||||
}
|
||||
|
||||
// SKProductsRequestDelegate methods
|
||||
- (void)productsRequest: (SKProductsRequest *)request didReceiveResponse: (SKProductsResponse *)response;
|
||||
|
||||
// SKPaymentTransactionObserver methods
|
||||
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions;
|
||||
- (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray *)transactions;
|
||||
|
||||
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error;
|
||||
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue;
|
||||
|
||||
// MyStoreObserver methods
|
||||
- (void)completeTransaction:(SKPaymentTransaction *)transaction;
|
||||
- (void)failedTransaction:(SKPaymentTransaction *)transaction;
|
||||
- (void)restoreTransaction:(SKPaymentTransaction *)transaction;
|
||||
- (void)finalizeTransaction:(SKPaymentTransaction *)transaction;
|
||||
|
||||
@end
|
||||
|
||||
// Unnamed-namespace for stuff that's "private" to this file (internal linkage).
|
||||
namespace {
|
||||
// The single instance of the store observer. This is created in Initialize and released
|
||||
// in Shutdown.
|
||||
MyStoreObserver * observer;
|
||||
|
||||
// The callback to invoke when an interesting event occurs.
|
||||
idInAppStore::callback_t callbackObject;
|
||||
|
||||
/*
|
||||
================================================
|
||||
Each product identifier has an associated state to keep track of the progress of
|
||||
in-app purchases. These states are stored in the NSUserDefaults for the corresponding
|
||||
product identifier. These states are not in an enum because the the NSUserDefaults store
|
||||
NSIntegers, and we can't define the type of an enum in C++03.
|
||||
================================================
|
||||
*/
|
||||
typedef NSInteger productState_t;
|
||||
|
||||
// This is the state of a product if it not found in the user's defaults.
|
||||
const productState_t PRODUCT_NOT_FOUND = 0;
|
||||
|
||||
// Information from this product has been requested, but has not been received yet.
|
||||
const productState_t PRODUCT_WAIT_FOR_INFORMATION = 1;
|
||||
|
||||
// Information for this product is available, but a purchase has not been initiated.
|
||||
const productState_t PRODUCT_HAS_INFORMATION = 2;
|
||||
|
||||
// A purchase was initiated, and the application is waiting for the App Store to
|
||||
// process the purchase.
|
||||
const productState_t PRODUCT_WAIT_FOR_PURCHASE = 3;
|
||||
|
||||
// The app store has fully processed the purchase and the product is available for the
|
||||
// user/
|
||||
const productState_t PRODUCT_PURCHASED = 4;
|
||||
|
||||
|
||||
void RequestInformation( const std::vector<std::string> & productIdentifiers );
|
||||
|
||||
/*
|
||||
================================================
|
||||
Store product information in a C++ friendly way.
|
||||
================================================
|
||||
*/
|
||||
struct productInformation_t {
|
||||
std::string identifier;
|
||||
std::string localizedPrice;
|
||||
|
||||
productInformation_t( const std::string & identifier_, const std::string & localizedPrice_ )
|
||||
: identifier( identifier_ )
|
||||
, localizedPrice( localizedPrice_ )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// Cache the product information that has been received from the App Store.
|
||||
typedef std::map<std::string, productInformation_t> productMap_t;
|
||||
productMap_t productCache;
|
||||
|
||||
/*
|
||||
========================
|
||||
GetProductState
|
||||
|
||||
Queries the NSUserDefaults for the state of the product corresponding to the
|
||||
productIdentifier.
|
||||
========================
|
||||
*/
|
||||
productState_t GetProductState( const char * const productIdentifier ) {
|
||||
#if defined( TEST_ALL_PRODUCTS_PURCHASED )
|
||||
return PRODUCT_PURCHASED;
|
||||
#endif
|
||||
|
||||
// Convert the C string to an NSString for use with NSUserDefaults.
|
||||
NSString *productKey = [NSString stringWithCString:productIdentifier
|
||||
encoding:NSUTF8StringEncoding];
|
||||
|
||||
// Purchase records are stored in the standardUserDefaults, with a key equal to the
|
||||
// product identifier.
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSInteger productState = [defaults integerForKey:productKey];
|
||||
|
||||
return productState;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
SetProductState
|
||||
|
||||
Sets the NSUserDefaults value corresponding to product identifier to the given state.
|
||||
========================
|
||||
*/
|
||||
void SetProductState( NSString * productIdentifier, productState_t state ) {
|
||||
// Purchase records are stored in the standardUserDefaults, with a key equal to the
|
||||
// product identifier.
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
[defaults setInteger:state forKey:productIdentifier];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
SetProductState
|
||||
|
||||
Sets the NSUserDefaults value corresponding to product identifier to the given state.
|
||||
========================
|
||||
*/
|
||||
void SetProductState( const char * const productIdentifier, productState_t state ) {
|
||||
// Convert the C string to an NSString for use with NSUserDefaults.
|
||||
NSString *productKey = [NSString stringWithCString:productIdentifier
|
||||
encoding:NSUTF8StringEncoding];
|
||||
|
||||
SetProductState( productKey, state );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
RequestInformation
|
||||
|
||||
Queries the App Store for information about the all the identifiers in the vector.
|
||||
When the App Store responds, calls the callback. The product identifiers are UTF8 encoded.
|
||||
|
||||
If in-app purchases are disabled, this function does nothing. The application may want to
|
||||
show an alert in this case. The application can call IsEnabled() to check for this.
|
||||
========================
|
||||
*/
|
||||
void RequestInformation( const std::vector<std::string> & productIdentifiers ) {
|
||||
// Early exit if the system hasn't been initialized.
|
||||
if ( observer == nil ) {
|
||||
printf( "In-App Purchase system not initialized. Can't purchase anything!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Early exit if in-app purchases are disabled.
|
||||
if ( [SKPaymentQueue canMakePayments] == FALSE ) {
|
||||
printf( "In-App Purchases are disabled for this device. Can't purchase anything!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// This will be the set of product identifiers to request from the App Store.
|
||||
NSMutableSet * identifiersToRequest = [NSMutableSet setWithCapacity: productIdentifiers.size()];
|
||||
|
||||
#ifndef NDEBUG
|
||||
// For debugging purposes, set this flag to 'true' and all in-app purchase products
|
||||
// will be reset to the unpurchased state.
|
||||
bool resetPurchases = false;
|
||||
|
||||
if ( resetPurchases ) {
|
||||
for( std::vector<std::string>::const_iterator i = productIdentifiers.begin(); i != productIdentifiers.end(); ++i ) {
|
||||
SetProductState( i->c_str(), PRODUCT_NOT_FOUND );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check the NSUserDefaults for each identifier requested, to get the state of
|
||||
// the product.
|
||||
for( std::vector<std::string>::const_iterator i = productIdentifiers.begin(); i != productIdentifiers.end(); ++i ) {
|
||||
// If the user has not purchased this product, we need to request information about
|
||||
// it from the App Store.
|
||||
productState_t productState = GetProductState( i->c_str() );
|
||||
if ( productState != PRODUCT_PURCHASED ) {
|
||||
|
||||
SetProductState( i->c_str(), PRODUCT_WAIT_FOR_INFORMATION );
|
||||
|
||||
NSString * nsIdentifier = [NSString stringWithCString:i->c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
|
||||
[identifiersToRequest addObject:nsIdentifier];
|
||||
}
|
||||
}
|
||||
|
||||
// Now we know which identifiers to request from the store, start the request object.
|
||||
if ( [identifiersToRequest count] > 0 ) {
|
||||
SKProductsRequest *request= [[SKProductsRequest alloc]
|
||||
initWithProductIdentifiers:identifiersToRequest ];
|
||||
|
||||
request.delegate = observer;
|
||||
[request start];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace idInAppStore {
|
||||
|
||||
/*
|
||||
========================
|
||||
Initialize
|
||||
|
||||
Creates the StoreKit observer object and registers it with the payment queue. The
|
||||
application must provide all the product IDs it has available for sale to this function,
|
||||
so that it can request information from the app store.
|
||||
========================
|
||||
*/
|
||||
void Initialize( const std::vector<std::string> & productIdentifiers ) {
|
||||
if ( !observer ) {
|
||||
observer = [[MyStoreObserver alloc] init];
|
||||
|
||||
// Add the observer here in case purchase requests were interrupted last time.
|
||||
[[SKPaymentQueue defaultQueue] addTransactionObserver:observer];
|
||||
}
|
||||
|
||||
RequestInformation( productIdentifiers );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Shutdown
|
||||
|
||||
Frees the StoreKit observer object.
|
||||
========================
|
||||
*/
|
||||
void Shutdown() {
|
||||
[observer release];
|
||||
observer = nil;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
IsEnabled
|
||||
|
||||
Returns true if in-app purchases are enabled, false if they are not.
|
||||
========================
|
||||
*/
|
||||
bool IsEnabled() {
|
||||
return ( [SKPaymentQueue canMakePayments] )? true: false;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
StartPurchase
|
||||
|
||||
Begins the purchase process with the App Store. The product id must have been
|
||||
previously requested through RequestInformation. This will launch the OS-controlled
|
||||
confirmation prompt after a moment, and it might take a while to actually complete the
|
||||
purchase.
|
||||
========================
|
||||
*/
|
||||
void StartPurchase( const char * const productIdentifier ) {
|
||||
if ( ![SKPaymentQueue canMakePayments] ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !CanPurchase( productIdentifier ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetProductState( productIdentifier, PRODUCT_WAIT_FOR_PURCHASE );
|
||||
|
||||
NSString * nsProductIdentifier = [NSString stringWithCString:productIdentifier
|
||||
encoding:NSUTF8StringEncoding];
|
||||
|
||||
SKPayment * payment = [SKPayment paymentWithProductIdentifier:nsProductIdentifier];
|
||||
[[SKPaymentQueue defaultQueue] addPayment:payment];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
ShowDisabledAlert
|
||||
|
||||
If and only if in-app purchases are disabled, shows an alert notifying the user of this fact
|
||||
and reminds him or her that he or she can enable in-app purchases in settings.
|
||||
|
||||
If in-app purchasees are enabled, this function does nothing.
|
||||
|
||||
The string parameters must be encoded in UTF8.
|
||||
========================
|
||||
*/
|
||||
void ShowDisabledAlert( std::string title,
|
||||
std::string description,
|
||||
std::string okButton ) {
|
||||
if ( ![SKPaymentQueue canMakePayments] ) {
|
||||
// User has disabled In-App purchases in settings. Kindly remind him that he can
|
||||
// enable purchases again.
|
||||
|
||||
if ( title.empty() ) {
|
||||
title = "In-App Purchases are disabled";
|
||||
}
|
||||
|
||||
if ( description.empty() ) {
|
||||
description = "You can enable In-App purchases in your device's settings.";
|
||||
}
|
||||
|
||||
if ( okButton.empty() ) {
|
||||
title = "OK";
|
||||
}
|
||||
|
||||
NSString * nsTitle = [NSString stringWithCString:title.c_str() encoding:NSUTF8StringEncoding];
|
||||
NSString * nsDescription = [NSString stringWithCString:description.c_str() encoding:NSUTF8StringEncoding];
|
||||
NSString * nsOkButton = [NSString stringWithCString:okButton.c_str() encoding:NSUTF8StringEncoding];
|
||||
|
||||
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nsTitle
|
||||
message:nsDescription
|
||||
delegate:nil
|
||||
cancelButtonTitle:nsOkButton
|
||||
otherButtonTitles:nil];
|
||||
|
||||
// Make sure the alert shows up on the main thread.
|
||||
[alert show];
|
||||
[alert release];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
HasPurchased
|
||||
|
||||
Queries the standard NSUserDefaults object for the state of the product with the given
|
||||
identifier. If the state is PRODUCT_PURCHASED, the user has purchased the product.
|
||||
If the state is anything else, the user has not purchased the product.
|
||||
========================
|
||||
*/
|
||||
bool HasPurchased( const char * const productIdentifier ) {
|
||||
const productState_t state = GetProductState( productIdentifier );
|
||||
const bool stateIsPurchased = (state == PRODUCT_PURCHASED);
|
||||
return ( stateIsPurchased );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
CanPurchase
|
||||
|
||||
Returns true if it is safe for the application to start a purchase, false if the application
|
||||
should not start a purchase at this time.
|
||||
========================
|
||||
*/
|
||||
bool CanPurchase( const char * const productIdentifier ) {
|
||||
const productState_t state = GetProductState( productIdentifier );
|
||||
const bool stateHasInformaion = ( state == PRODUCT_HAS_INFORMATION );
|
||||
return ( stateHasInformaion );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
IsWaitingForInformation
|
||||
|
||||
Queries the standard NSUserDefaults object for the state of the product with the given
|
||||
identifier. If the application is still waiting for the App Store to return information,
|
||||
this function returns true. If the application has information, this function returns false.
|
||||
========================
|
||||
*/
|
||||
bool IsWaitingForInformation( const char * const productIdentifier ) {
|
||||
return ( GetProductState( productIdentifier ) == PRODUCT_WAIT_FOR_INFORMATION );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
IsWaitingForPurchase
|
||||
|
||||
Queries the standard NSUserDefaults object for the state of the product with the given
|
||||
identifier. If the application is still waiting for the App Store to purchase the item,
|
||||
this function returns true. If the application is not waiting on the app store, returns false.
|
||||
========================
|
||||
*/
|
||||
bool IsWaitingForPurchase( const char * const productIdentifier ) {
|
||||
return ( GetProductState( productIdentifier ) == PRODUCT_WAIT_FOR_PURCHASE );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
GetLocalizedPrice
|
||||
|
||||
Returns a UTF-8 encoded string that represents the price of the product. This string is
|
||||
suitable for display to the user. If the string isn't available yet, for example, if the
|
||||
App Store hasn't responded to an information request, the return value will be an empty
|
||||
string.
|
||||
========================
|
||||
*/
|
||||
std::string GetLocalizedPrice( const char * const productIdentifier ) {
|
||||
productMap_t::iterator found = productCache.find( productIdentifier );
|
||||
|
||||
if ( found != productCache.end() ) {
|
||||
return found->second.localizedPrice;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
SetCallback
|
||||
|
||||
Stores a callback function to be invoked when something happens relating to a product.
|
||||
========================
|
||||
*/
|
||||
void SetCallback( callback_t callback ) {
|
||||
callbackObject = callback;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
ClearCallback
|
||||
|
||||
Removes the callback function previously registered through SetCallback.
|
||||
========================
|
||||
*/
|
||||
void ClearCallback() {
|
||||
callbackObject = callback_t();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@implementation MyStoreObserver
|
||||
|
||||
- (void) showInvalidProductIdAlert
|
||||
{
|
||||
NSString * nsTitle = @"In-app purchase error";
|
||||
NSString * nsDescription = @"Invalid product ID requested. In-app purchase will not work!";
|
||||
NSString * nsOkButton = @"OK";
|
||||
|
||||
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nsTitle
|
||||
message:nsDescription
|
||||
delegate:nil
|
||||
cancelButtonTitle:nsOkButton
|
||||
otherButtonTitles:nil];
|
||||
|
||||
[alert show];
|
||||
[alert release];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
productsRequest:didReceiveResponse
|
||||
|
||||
Called by the OS when the application gets product information about an In-App Purchase.
|
||||
========================
|
||||
*/
|
||||
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
|
||||
{
|
||||
NSArray *myProduct = response.products;
|
||||
NSArray *invalidProducts = response.invalidProductIdentifiers;
|
||||
|
||||
for ( SKProduct * product in myProduct )
|
||||
{
|
||||
NSLog( @"Valid product: %@", product.productIdentifier);
|
||||
}
|
||||
|
||||
for ( NSString * productId in invalidProducts )
|
||||
{
|
||||
NSLog( @"Invalid product: %@", productId);
|
||||
|
||||
[self performSelectorOnMainThread:@selector(showInvalidProductIdAlert) withObject:nil waitUntilDone:NO];
|
||||
return;
|
||||
}
|
||||
|
||||
// We should handle the case of an empty array, this seems to occur if we send a request
|
||||
// with a nonexistant product ID, but there may be other cases.
|
||||
// TODO: Need a timeout to be even more robust.
|
||||
if ( [myProduct count] == 0 ) {
|
||||
//if ( clientCallback ) {
|
||||
// clientCallback( IAP_FAILURE );
|
||||
//}
|
||||
return;
|
||||
}
|
||||
|
||||
// We can use the same number formatter for all the products.
|
||||
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
|
||||
[numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
|
||||
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
|
||||
|
||||
// Get the response and cache it.
|
||||
for ( SKProduct * product in response.products )
|
||||
{
|
||||
// Convert the price to user-interface worthy representation.
|
||||
[numberFormatter setLocale:product.priceLocale];
|
||||
NSString *formattedString = [numberFormatter stringFromNumber:product.price];
|
||||
|
||||
const std::string priceString = [formattedString cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
// Convert the NSString identifier to a C++ string.
|
||||
const std::string identifierString = [product.productIdentifier cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
productInformation_t productInformation( identifierString, priceString );
|
||||
|
||||
// Add the C++ product information to the cache.
|
||||
productCache.insert( std::make_pair( identifierString, productInformation ) );
|
||||
|
||||
// Store the fact that we have information in the defaults.
|
||||
SetProductState( identifierString.c_str(), PRODUCT_HAS_INFORMATION );
|
||||
|
||||
if ( callbackObject ) {
|
||||
callbackObject( identifierString.c_str(), idInAppStore::PRODUCT_STATUS_RECEIVED_INFORMATION );
|
||||
}
|
||||
}
|
||||
|
||||
[numberFormatter release];
|
||||
[request autorelease];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
paymentQueue:updatedTransactions
|
||||
|
||||
Called by the system when purchase requests are updated.
|
||||
========================
|
||||
*/
|
||||
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
|
||||
{
|
||||
(void)queue;
|
||||
for (SKPaymentTransaction *transaction in transactions)
|
||||
{
|
||||
switch (transaction.transactionState)
|
||||
{
|
||||
case SKPaymentTransactionStatePurchased:
|
||||
[self completeTransaction:transaction];
|
||||
break;
|
||||
case SKPaymentTransactionStateFailed:
|
||||
[self failedTransaction:transaction];
|
||||
break;
|
||||
case SKPaymentTransactionStateRestored:
|
||||
[self restoreTransaction:transaction];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray *)transactions
|
||||
{
|
||||
(void)queue; (void)transactions;
|
||||
}
|
||||
|
||||
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
|
||||
{
|
||||
(void)queue; (void)error;
|
||||
}
|
||||
|
||||
|
||||
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
|
||||
{
|
||||
(void)queue;}
|
||||
|
||||
/*
|
||||
========================
|
||||
completeTransaction
|
||||
|
||||
Called by updatedTransactions when a request is completed.
|
||||
========================
|
||||
*/
|
||||
- (void)completeTransaction:(SKPaymentTransaction *)transaction
|
||||
{
|
||||
[self finalizeTransaction:transaction];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
failedTransaction
|
||||
|
||||
Called by updatedTransactions when a request fails.
|
||||
========================
|
||||
*/
|
||||
- (void)failedTransaction:(SKPaymentTransaction *)transaction
|
||||
{
|
||||
if (transaction.error.code != SKErrorPaymentCancelled)
|
||||
{
|
||||
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"In-App Purchase error"
|
||||
message:[transaction.error localizedDescription]
|
||||
delegate:nil
|
||||
cancelButtonTitle:@"OK"
|
||||
otherButtonTitles:nil];
|
||||
|
||||
[alert show];
|
||||
[alert release];
|
||||
}
|
||||
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
|
||||
|
||||
const char * const cProductIdentifier = [transaction.payment.productIdentifier cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
// Since we can get failed transactions after the user has already purchased a product,
|
||||
// don't do anthing if the user has already purchased the product.
|
||||
if ( GetProductState( cProductIdentifier ) != PRODUCT_PURCHASED ) {
|
||||
SetProductState( transaction.payment.productIdentifier, PRODUCT_HAS_INFORMATION );
|
||||
|
||||
|
||||
if ( callbackObject ) {
|
||||
callbackObject( cProductIdentifier, idInAppStore::PRODUCT_STATUS_TRANSACTION_FAILED );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
restoreTransaction
|
||||
|
||||
Called by updatedTransactions when a request is restored. This can behave identically to
|
||||
completeTransaction.
|
||||
========================
|
||||
*/
|
||||
- (void)restoreTransaction:(SKPaymentTransaction *)transaction
|
||||
{
|
||||
[self finalizeTransaction:transaction.originalTransaction];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
finalizeTransaction
|
||||
|
||||
This method actually delivers the purchased item to the user. Currently, this means setting
|
||||
the state in NSUserDefaults to PRODUCT_PURCHASED.
|
||||
========================
|
||||
*/
|
||||
- (void)finalizeTransaction:(SKPaymentTransaction *)transaction
|
||||
{
|
||||
SetProductState( transaction.payment.productIdentifier, PRODUCT_PURCHASED );
|
||||
|
||||
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
|
||||
|
||||
const char * const cProductIdentifier = [transaction.payment.productIdentifier cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
if ( callbackObject ) {
|
||||
callbackObject( cProductIdentifier, idInAppStore::PRODUCT_STATUS_PURCHASED );
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
30
common/idmobilelib/ios/Label.h
Executable file
30
common/idmobilelib/ios/Label.h
Executable file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
@interface idLabel : UILabel {
|
||||
|
||||
}
|
||||
|
||||
- (void) SetupLabel: ( NSString * )fontName ;
|
||||
|
||||
@end
|
||||
55
common/idmobilelib/ios/Label.mm
Executable file
55
common/idmobilelib/ios/Label.mm
Executable file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "Label.h"
|
||||
#include "Localization.h"
|
||||
|
||||
@implementation idLabel
|
||||
|
||||
/*
|
||||
========================
|
||||
awakeFromNib
|
||||
========================
|
||||
*/
|
||||
- (void)awakeFromNib {
|
||||
|
||||
[ self SetupLabel:@"idGinza Narrow" ];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
SetupLabel
|
||||
========================
|
||||
*/
|
||||
- (void) SetupLabel: ( NSString * )fontName {
|
||||
|
||||
// Set the Font
|
||||
CGFloat points = self.font.pointSize;
|
||||
self.font = [UIFont fontWithName:fontName size:points];
|
||||
|
||||
// Localize the text.
|
||||
NSString * unLocText = self.text;
|
||||
const char * utf8string = idLocalization_GetString( [unLocText UTF8String ] );
|
||||
self.text = [ NSString stringWithCString: utf8string encoding:NSUTF8StringEncoding ];
|
||||
}
|
||||
|
||||
@end
|
||||
40
common/idmobilelib/ios/LabelButton.h
Executable file
40
common/idmobilelib/ios/LabelButton.h
Executable file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "Label.h"
|
||||
|
||||
@interface idLabelButton : UIButton {
|
||||
|
||||
UIColor * labelColor;
|
||||
UIColor * label2Color;
|
||||
}
|
||||
|
||||
|
||||
@property (nonatomic, retain) IBOutlet idLabel *label;
|
||||
@property (nonatomic, retain) IBOutlet idLabel *label2;
|
||||
|
||||
- (void) Hide;
|
||||
- (void) Show;
|
||||
- (void) Enable;
|
||||
- (void) Disable;
|
||||
|
||||
@end
|
||||
202
common/idmobilelib/ios/LabelButton.mm
Executable file
202
common/idmobilelib/ios/LabelButton.mm
Executable file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#import "LabelButton.h"
|
||||
#import "Label.h"
|
||||
#import "Slider.h"
|
||||
#import "Switch.h"
|
||||
#import "Carousel.h"
|
||||
#import "Localization.h"
|
||||
@implementation idLabelButton
|
||||
|
||||
@synthesize label;
|
||||
@synthesize label2;
|
||||
|
||||
/*
|
||||
========================
|
||||
idLabelButton::awakeFromNib
|
||||
========================
|
||||
*/
|
||||
- (void)awakeFromNib {
|
||||
|
||||
// Do not optimize my class out
|
||||
[idLabel class ];
|
||||
[idSlider class];
|
||||
[idSwitch class];
|
||||
[idCarousel class];
|
||||
|
||||
CGFloat points = self.titleLabel.font.pointSize;
|
||||
|
||||
self.titleLabel.font = [UIFont fontWithName:@"idGinza Narrow" size:points];
|
||||
|
||||
// Localize the text.
|
||||
NSString * unLocText = self.titleLabel.text;
|
||||
if( unLocText ) {
|
||||
const char * utf8string = idLocalization_GetString( [unLocText UTF8String ] );
|
||||
|
||||
NSString * localizedString = [ NSString stringWithCString: utf8string encoding:NSUTF8StringEncoding ];
|
||||
[self setTitle: localizedString forState:UIControlStateNormal];
|
||||
[self setTitle: localizedString forState:UIControlStateHighlighted];
|
||||
}
|
||||
|
||||
if( self.label2 )
|
||||
label2Color = self.label2.textColor;
|
||||
if( self.label ) {
|
||||
labelColor = self.label.textColor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idLabelButton::setHighlighted
|
||||
========================
|
||||
*/
|
||||
- (void)setHighlighted:(BOOL)highlight {
|
||||
if( highlight ) {
|
||||
if( self.label )
|
||||
self.label.textColor = self.label.highlightedTextColor;
|
||||
if( self.label2 )
|
||||
self.label2.textColor = self.label2.highlightedTextColor;
|
||||
} else if( self.enabled ) {
|
||||
if( self.label )
|
||||
self.label.textColor = labelColor;
|
||||
if( self.label2 )
|
||||
self.label2.textColor = label2Color;
|
||||
}
|
||||
|
||||
[super setHighlighted:highlight];
|
||||
|
||||
// Localize the text.
|
||||
NSString * unLocText = self.titleLabel.text;
|
||||
if( unLocText ) {
|
||||
const char * utf8string = idLocalization_GetString( [unLocText UTF8String ] );
|
||||
self.titleLabel.text = [ NSString stringWithCString: utf8string encoding:NSUTF8StringEncoding ];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idLabelButton::setEnabled
|
||||
========================
|
||||
*/
|
||||
- (void)setEnabled:(BOOL)enabled {
|
||||
if( !enabled ) {
|
||||
if( self.label )
|
||||
self.label.textColor = self.label.highlightedTextColor;
|
||||
if( self.label2 )
|
||||
self.label2.textColor = self.label2.highlightedTextColor;
|
||||
} else {
|
||||
if( self.label )
|
||||
self.label.textColor = labelColor;
|
||||
if( self.label2 )
|
||||
self.label2.textColor = label2Color;
|
||||
}
|
||||
|
||||
[super setEnabled:enabled];
|
||||
|
||||
// Localize the text.
|
||||
NSString * unLocText = self.titleLabel.text;
|
||||
if( unLocText ) {
|
||||
const char * utf8string = idLocalization_GetString( [unLocText UTF8String ] );
|
||||
self.titleLabel.text = [ NSString stringWithCString: utf8string encoding:NSUTF8StringEncoding ];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idLabelButton::Enable
|
||||
========================
|
||||
*/
|
||||
- (void) Enable {
|
||||
|
||||
self.enabled = YES;
|
||||
if( self.label )
|
||||
label.enabled = YES;
|
||||
if( self.label2 )
|
||||
label2.enabled = YES;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idLabelButton::Disable
|
||||
========================
|
||||
*/
|
||||
- (void) Disable {
|
||||
self.enabled = NO;
|
||||
if( self.label )
|
||||
label.enabled = NO;
|
||||
if( self.label2 )
|
||||
label2.enabled = NO;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idLabelButton::Hide
|
||||
========================
|
||||
*/
|
||||
- (void) Hide {
|
||||
|
||||
[UIView beginAnimations:@"Hide" context:nil];
|
||||
[UIView setAnimationDuration:1.0f];
|
||||
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
|
||||
[UIView setAnimationBeginsFromCurrentState:YES];
|
||||
[UIView setAnimationDelegate:self];
|
||||
[UIView setAnimationDidStopSelector:@selector(Disable)];
|
||||
|
||||
self.alpha = 0.0f;
|
||||
if( self.label )
|
||||
label.alpha = 0.0f;
|
||||
if( self.label2 )
|
||||
label2.alpha = 0.0f;
|
||||
|
||||
[UIView commitAnimations];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idLabelButton::Show
|
||||
========================
|
||||
*/
|
||||
- (void) Show {
|
||||
|
||||
[UIView beginAnimations:@"Show" context:nil];
|
||||
[UIView setAnimationDuration:1.0f];
|
||||
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
|
||||
[UIView setAnimationBeginsFromCurrentState:YES];
|
||||
[UIView setAnimationDelegate:self];
|
||||
[UIView setAnimationDidStopSelector:@selector(Enable)];
|
||||
|
||||
self.alpha = 1.0f;
|
||||
if( self.label )
|
||||
label.alpha = 1.0f;
|
||||
if( self.label2 )
|
||||
label2.alpha = 1.0f;
|
||||
|
||||
[UIView commitAnimations];
|
||||
}
|
||||
|
||||
- (void) dealloc {
|
||||
label = nil;
|
||||
label2 = nil;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
83
common/idmobilelib/ios/Localization.h
Executable file
83
common/idmobilelib/ios/Localization.h
Executable file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
================================================================================================
|
||||
|
||||
A game-generic C++ wrapper around the iOS Localizable Strings functionality.
|
||||
|
||||
Basics of Localaization on Apple platforms:
|
||||
|
||||
Each Localization language has a bundle associated with it ( *.lproj ).
|
||||
We gather the bundle for the current ( or needed ) language.
|
||||
[[NSBundle mainBundle ] pathForResource:@"en" ofType:@"lproj" ];
|
||||
|
||||
You MUST add a Localizable.strings file ( named exactly that ) to the project.
|
||||
|
||||
Apple provides a system for getting strings from the localizable.strings file.
|
||||
NSString* nsString = [ bundle localizedStringForKey:key value:nil table:nil ];
|
||||
|
||||
The Localizable.strings file must be formatted like:
|
||||
"KEY" = "VALUE";
|
||||
and end with a semi-coln.
|
||||
|
||||
Apple Developer Reference:
|
||||
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html
|
||||
|
||||
We wrapper this up into 4 easy functions.
|
||||
"Localization_Initialize" Must be called to create/set the current language bundle for the system.
|
||||
"Localization_SetLanguage" Can be called at dynamically to set the language.
|
||||
"Localization_GetString" Gets a string value from a key'd pair
|
||||
|
||||
SUPPORTED LANGUAGES:
|
||||
ENGLISH,
|
||||
FRENCH,
|
||||
ITALIAN,
|
||||
GERMAN,
|
||||
SPANISH
|
||||
|
||||
================================================================================================
|
||||
*/
|
||||
|
||||
#ifndef IDMOBILELIB_LOCALIZATION_H
|
||||
#define IDMOBILELIB_LOCALIZATION_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum ID_LANGUAGE {
|
||||
LANGUAGE_ENGLISH = 0,
|
||||
LANGUAGE_FRENCH,
|
||||
LANGUAGE_ITALIAN,
|
||||
LANGUAGE_GERMAN,
|
||||
LANGUAGE_SPANISH
|
||||
};
|
||||
|
||||
void idLocalization_Initialize();
|
||||
void idLocalization_SetLanguage( enum ID_LANGUAGE language );
|
||||
enum ID_LANGUAGE idLocalization_GetLanguage();
|
||||
const char * idLocalization_GetString( const char * key );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
134
common/idmobilelib/ios/Localization.mm
Executable file
134
common/idmobilelib/ios/Localization.mm
Executable file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "Localization.h"
|
||||
#include "LocalizationObjectiveC.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
static NSBundle* mCurrentBundle = NULL;
|
||||
static ID_LANGUAGE mCurrentLanguage;
|
||||
static const char* mCurrentLanguageStr;
|
||||
|
||||
/*
|
||||
========================
|
||||
idLocalization::SetLanguage
|
||||
Sets the language of the system with an enumeration passed in.
|
||||
========================
|
||||
*/
|
||||
void idLocalization_SetLanguage( ID_LANGUAGE language ) {
|
||||
|
||||
NSString* langPath = nil;
|
||||
|
||||
switch( language ) {
|
||||
case LANGUAGE_ENGLISH:
|
||||
langPath = [[NSBundle mainBundle ] pathForResource:@"en" ofType:@"lproj" ];
|
||||
break;
|
||||
case LANGUAGE_FRENCH:
|
||||
langPath = [[NSBundle mainBundle ] pathForResource:@"fr" ofType:@"lproj" ];
|
||||
break;
|
||||
case LANGUAGE_ITALIAN:
|
||||
langPath = [[NSBundle mainBundle ] pathForResource:@"it" ofType:@"lproj" ];
|
||||
break;
|
||||
case LANGUAGE_GERMAN:
|
||||
langPath = [[NSBundle mainBundle ] pathForResource:@"de" ofType:@"lproj" ];
|
||||
break;
|
||||
case LANGUAGE_SPANISH:
|
||||
langPath = [[NSBundle mainBundle ] pathForResource:@"es" ofType:@"lproj" ];
|
||||
break;
|
||||
default:
|
||||
langPath = [[NSBundle mainBundle ] pathForResource:@"en" ofType:@"lproj" ];
|
||||
break;
|
||||
}
|
||||
|
||||
mCurrentBundle = [[NSBundle bundleWithPath:langPath] retain ];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
idLocalization::GetLanguage
|
||||
Gets the current system's language
|
||||
========================
|
||||
*/
|
||||
ID_LANGUAGE idLocalization_GetLanguage() {
|
||||
return mCurrentLanguage;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idLocalization::Initialize
|
||||
Gathers the local device's language, and sets that as the systems language.
|
||||
========================
|
||||
*/
|
||||
void idLocalization_Initialize() {
|
||||
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSArray* languages = [defaults objectForKey:@"AppleLanguages"];
|
||||
NSString* current = [[languages objectAtIndex:0] retain ];
|
||||
mCurrentLanguageStr = [current UTF8String];
|
||||
|
||||
if([current isEqualToString:@"en"]){
|
||||
mCurrentLanguage = LANGUAGE_ENGLISH;
|
||||
} else if([current isEqualToString:@"fr"]){
|
||||
mCurrentLanguage = LANGUAGE_FRENCH;
|
||||
} else if([current isEqualToString:@"it"]){
|
||||
mCurrentLanguage = LANGUAGE_ENGLISH;
|
||||
} else if([current isEqualToString:@"sp"] || [current isEqualToString:@"es"]){
|
||||
mCurrentLanguage = LANGUAGE_SPANISH;
|
||||
} else if([current isEqualToString:@"ge"] || [current isEqualToString:@"de"]){
|
||||
mCurrentLanguage = LANGUAGE_GERMAN;
|
||||
} else {
|
||||
mCurrentLanguage = LANGUAGE_ENGLISH;
|
||||
}
|
||||
|
||||
idLocalization_SetLanguage( mCurrentLanguage );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idLocalization::GetString
|
||||
Gets a String value from the pair key passed in from Localizable.strings file.
|
||||
========================
|
||||
*/
|
||||
const char * idLocalization_GetString( const char * key ) {
|
||||
|
||||
NSString* nsKey = [NSString stringWithUTF8String:key];
|
||||
NSString* nsString = [mCurrentBundle localizedStringForKey:nsKey value:nil table:nil];
|
||||
const char* cString = nil;
|
||||
|
||||
if( nsString != nil ) {
|
||||
cString = [nsString cStringUsingEncoding:NSWindowsCP1252StringEncoding];
|
||||
} else {
|
||||
cString = key;
|
||||
}
|
||||
|
||||
return cString;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idLocalization::GetString
|
||||
Gets a String value from the pair key passed in from Localizable.strings file.
|
||||
========================
|
||||
*/
|
||||
NSString * idLocalization_GetNSString( NSString * key ) {
|
||||
return [mCurrentBundle localizedStringForKey:key value:nil table:nil];
|
||||
}
|
||||
39
common/idmobilelib/ios/LocalizationObjectiveC.h
Executable file
39
common/idmobilelib/ios/LocalizationObjectiveC.h
Executable file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef idmobilelib_LocalizationObjectiveC_h
|
||||
#define idmobilelib_LocalizationObjectiveC_h
|
||||
|
||||
@class NSString;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// If we already have an NSString localization key, we can use this function and avoid the
|
||||
// overhead of the const char * <-> NSString * conversions.
|
||||
NSString * idLocalization_GetNSString( NSString * key );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
70
common/idmobilelib/ios/RenderContext.h
Executable file
70
common/idmobilelib/ios/RenderContext.h
Executable file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef IDMOBILELIB_RENDER_CONTEXT_H
|
||||
#define IDMOBILELIB_RENDER_CONTEXT_H
|
||||
|
||||
#if defined(__OBJC__) && defined(__cplusplus)
|
||||
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#include <OpenGLES/ES1/gl.h>
|
||||
#include <OpenGLES/ES1/glext.h>
|
||||
#import <OpenGLES/EAGL.h>
|
||||
#import <OpenGLES/EAGLDrawable.h>
|
||||
|
||||
|
||||
class idRenderContext {
|
||||
public:
|
||||
|
||||
idRenderContext();
|
||||
virtual ~idRenderContext();
|
||||
|
||||
void Initialize( EAGLRenderingAPI apiVersion, EAGLSharegroup * sharegroup );
|
||||
void InitFrameBuffer( CAEAGLLayer * layer );
|
||||
|
||||
void Begin();
|
||||
void End();
|
||||
|
||||
void SetActiveContext();
|
||||
void SwapBuffers();
|
||||
|
||||
void SetContextWidth( int width );
|
||||
void SetContextHeight( int height );
|
||||
|
||||
int GetContextWidth() const { return mWidth; }
|
||||
int GetContextHeight() const { return mHeight; }
|
||||
EAGLSharegroup * GetShareGroup() { return [mEAGLContext sharegroup]; }
|
||||
|
||||
protected:
|
||||
|
||||
GLuint mViewRenderbuffer;
|
||||
GLuint mViewFramebuffer;
|
||||
GLuint mDepthRenderbuffer;
|
||||
|
||||
EAGLContext *mEAGLContext;
|
||||
|
||||
int mWidth;
|
||||
int mHeight;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _RENDER_CONTEXT_H
|
||||
174
common/idmobilelib/ios/RenderContext.mm
Executable file
174
common/idmobilelib/ios/RenderContext.mm
Executable file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "RenderContext.h"
|
||||
|
||||
/*
|
||||
=========================================
|
||||
idRenderContext::idRenderContext
|
||||
=========================================
|
||||
*/
|
||||
idRenderContext::idRenderContext() :
|
||||
mViewRenderbuffer( 0 ),
|
||||
mViewFramebuffer( 0 ),
|
||||
mDepthRenderbuffer( 0 ),
|
||||
mEAGLContext( NULL ) {
|
||||
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=========================================
|
||||
idRenderContext::Initialize
|
||||
=========================================
|
||||
*/
|
||||
void idRenderContext::Initialize( EAGLRenderingAPI apiVersion, EAGLSharegroup * sharegroup ) {
|
||||
|
||||
// Allocate and initialize the Rendering context for this view.
|
||||
if( sharegroup == NULL ) {
|
||||
mEAGLContext = [[EAGLContext alloc] initWithAPI:apiVersion];
|
||||
} else {
|
||||
|
||||
mEAGLContext = [[EAGLContext alloc] initWithAPI:apiVersion sharegroup: sharegroup];
|
||||
}
|
||||
|
||||
assert( mEAGLContext );
|
||||
assert( [mEAGLContext API] == apiVersion );
|
||||
|
||||
SetActiveContext();
|
||||
}
|
||||
|
||||
/*
|
||||
=========================================
|
||||
idRenderContext::~idRenderContext
|
||||
=========================================
|
||||
*/
|
||||
idRenderContext::~idRenderContext() {
|
||||
|
||||
glDeleteFramebuffersOES( 1, &mViewFramebuffer );
|
||||
mViewFramebuffer = 0;
|
||||
glDeleteRenderbuffersOES( 1, &mViewRenderbuffer );
|
||||
mViewRenderbuffer = 0;
|
||||
glDeleteRenderbuffersOES( 1, &mDepthRenderbuffer );
|
||||
mDepthRenderbuffer = 0;
|
||||
|
||||
[ mEAGLContext release ];
|
||||
}
|
||||
|
||||
/*
|
||||
=========================================
|
||||
idRenderContext::SetActiveContext
|
||||
=========================================
|
||||
*/
|
||||
void idRenderContext::SetActiveContext() {
|
||||
|
||||
if ( ![EAGLContext setCurrentContext:mEAGLContext]) {
|
||||
assert( 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
=========================================
|
||||
idRenderContext::SwapBuffers
|
||||
=========================================
|
||||
*/
|
||||
void idRenderContext::SwapBuffers() {
|
||||
|
||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, mViewRenderbuffer);
|
||||
|
||||
// present the renderbuffer for display
|
||||
[mEAGLContext presentRenderbuffer:GL_RENDERBUFFER_OES];
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
=========================================
|
||||
idRenderContext::RenderBufferStorage
|
||||
=========================================
|
||||
*/
|
||||
void idRenderContext::InitFrameBuffer( CAEAGLLayer * layer ) {
|
||||
|
||||
|
||||
glDeleteFramebuffersOES( 1, &mViewFramebuffer );
|
||||
mViewFramebuffer = 0;
|
||||
glDeleteRenderbuffersOES( 1, &mViewRenderbuffer );
|
||||
mViewRenderbuffer = 0;
|
||||
glDeleteRenderbuffersOES( 1, &mDepthRenderbuffer );
|
||||
mDepthRenderbuffer = 0;
|
||||
|
||||
glGenFramebuffersOES(1, &mViewFramebuffer);
|
||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, mViewFramebuffer);
|
||||
|
||||
glGenRenderbuffersOES(1, &mViewRenderbuffer);
|
||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, mViewRenderbuffer);
|
||||
|
||||
[mEAGLContext renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:layer];
|
||||
|
||||
// the backing sizes should be the same as the screen
|
||||
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &mWidth);
|
||||
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &mHeight);
|
||||
|
||||
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, mViewRenderbuffer);
|
||||
|
||||
glGenRenderbuffersOES(1, &mDepthRenderbuffer);
|
||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, mDepthRenderbuffer);
|
||||
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, mWidth, mHeight);
|
||||
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, mDepthRenderbuffer);
|
||||
|
||||
// the framebuffer will stay constant
|
||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, mViewRenderbuffer);
|
||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, mViewFramebuffer);
|
||||
|
||||
|
||||
if ( glCheckFramebufferStatusOES( GL_FRAMEBUFFER_OES ) != GL_FRAMEBUFFER_COMPLETE_OES ) {
|
||||
assert( 0 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
=========================================
|
||||
idRenderContext::Begin
|
||||
=========================================
|
||||
*/
|
||||
void idRenderContext::Begin() {
|
||||
|
||||
SetActiveContext();
|
||||
|
||||
// Clear the Buffer to begin for a new Frame.
|
||||
//GL_Clear( true, true, false );
|
||||
|
||||
// Set the Viewport for our Context.
|
||||
// GL_Viewport( 0, 0, mWidth, mHeight );
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
=========================================
|
||||
idRenderContext::End
|
||||
=========================================
|
||||
*/
|
||||
void idRenderContext::End() {
|
||||
|
||||
SwapBuffers();
|
||||
}
|
||||
33
common/idmobilelib/ios/Slider.h
Executable file
33
common/idmobilelib/ios/Slider.h
Executable file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
@interface idSlider : UISlider {
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (void) CustomizeSlider:( UIImage* )minimumImage
|
||||
:( UIImage* )maximumImage
|
||||
:( UIImage* )thumbImage;
|
||||
|
||||
@end
|
||||
52
common/idmobilelib/ios/Slider.mm
Executable file
52
common/idmobilelib/ios/Slider.mm
Executable file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#import "Slider.h"
|
||||
|
||||
|
||||
@implementation idSlider
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
CustomizeSlider
|
||||
========================
|
||||
*/
|
||||
- (void) CustomizeSlider:( UIImage* )minimumImage
|
||||
:( UIImage* )maximumImage
|
||||
:( UIImage* )thumbImage {
|
||||
|
||||
minimumImage = nil;
|
||||
maximumImage = nil;
|
||||
|
||||
//[ self setMinimumTrackImage:minimumImage forState:UIControlStateNormal ];
|
||||
//[ self setMaximumTrackImage:maximumImage forState:UIControlStateNormal ];
|
||||
|
||||
[ self setThumbImage:thumbImage forState:UIControlStateNormal ];
|
||||
[ self setThumbImage:thumbImage forState:UIControlStateHighlighted ];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@end
|
||||
31
common/idmobilelib/ios/Switch.h
Executable file
31
common/idmobilelib/ios/Switch.h
Executable file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
@interface idSwitch : UIButton {
|
||||
BOOL on;
|
||||
}
|
||||
|
||||
@property(nonatomic,getter=isOn) BOOL on;
|
||||
|
||||
@end
|
||||
79
common/idmobilelib/ios/Switch.mm
Executable file
79
common/idmobilelib/ios/Switch.mm
Executable file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#import "Switch.h"
|
||||
|
||||
|
||||
@implementation idSwitch
|
||||
|
||||
@synthesize on;
|
||||
|
||||
/*
|
||||
========================
|
||||
setOn
|
||||
========================
|
||||
*/
|
||||
- (void)setOn:(BOOL)turnOn
|
||||
{
|
||||
on = turnOn;
|
||||
|
||||
if (on)
|
||||
{
|
||||
[ self setHighlighted: YES ];
|
||||
}
|
||||
else
|
||||
{
|
||||
[ self setHighlighted: NO ];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
touchesBegan
|
||||
========================
|
||||
*/
|
||||
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
|
||||
{
|
||||
[super touchesBegan:touches withEvent:event];
|
||||
[self setOn: !on ];
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
touchesEnded
|
||||
========================
|
||||
*/
|
||||
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
|
||||
{
|
||||
[super touchesEnded:touches withEvent:event];
|
||||
|
||||
if (on)
|
||||
{
|
||||
[ self setHighlighted: YES ];
|
||||
}
|
||||
else
|
||||
{
|
||||
[ self setHighlighted: NO ];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
49
common/idmobilelib/ios/View.h
Executable file
49
common/idmobilelib/ios/View.h
Executable file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef IDMOBILELIB_VIEW_H
|
||||
#define IDMOBILELIB_VIEW_H
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#import <OpenGLES/EAGL.h>
|
||||
#import <OpenGLES/EAGLDrawable.h>
|
||||
#include "RenderContext.h"
|
||||
|
||||
/*
|
||||
================================================
|
||||
idView
|
||||
|
||||
Standard Objective C OpenGL UIView Class
|
||||
================================================
|
||||
*/
|
||||
@interface idView : UIView {
|
||||
@public
|
||||
idRenderContext mRenderContext;
|
||||
|
||||
}
|
||||
extern idView * gMainView;
|
||||
|
||||
- (void) Initialize;
|
||||
- (void) EndFrame;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
165
common/idmobilelib/ios/View.mm
Executable file
165
common/idmobilelib/ios/View.mm
Executable file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#import "View.h"
|
||||
|
||||
/*
|
||||
================================================
|
||||
idView
|
||||
|
||||
Standard Objective C UIView Class
|
||||
================================================
|
||||
*/
|
||||
|
||||
idView * gMainView; // global openGL View.
|
||||
|
||||
@implementation idView
|
||||
|
||||
/*
|
||||
==================================
|
||||
idView::layerClass
|
||||
==================================
|
||||
*/
|
||||
+ (Class) layerClass
|
||||
{
|
||||
return [CAEAGLLayer class];
|
||||
}
|
||||
|
||||
/*
|
||||
==================================
|
||||
idView::initWithCoder
|
||||
==================================
|
||||
*/
|
||||
- (id) initWithCoder:(NSCoder *)aCoder{
|
||||
|
||||
if ( ( self = [super initWithCoder:aCoder] ) ) {
|
||||
[self Initialize];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/*
|
||||
==================================
|
||||
idView::initWithFrame
|
||||
==================================
|
||||
*/
|
||||
- (id) initWithFrame:(CGRect)rect{
|
||||
if ( ( self = [super initWithFrame:rect] ) ) {
|
||||
[self Initialize];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
/*
|
||||
==================================
|
||||
idView::handleTouches
|
||||
==================================
|
||||
*/
|
||||
- (void) handleTouches:(UIEvent*)event {
|
||||
(void)event;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================================
|
||||
idView::touchesBegan
|
||||
==================================
|
||||
*/
|
||||
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
|
||||
(void)touches;
|
||||
|
||||
[self handleTouches:event];
|
||||
}
|
||||
|
||||
/*
|
||||
==================================
|
||||
idView::touchesMoved
|
||||
==================================
|
||||
*/
|
||||
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||
(void)touches;
|
||||
|
||||
[self handleTouches:event];
|
||||
}
|
||||
|
||||
/*
|
||||
==================================
|
||||
idView::touchesEnded
|
||||
==================================
|
||||
*/
|
||||
- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
|
||||
|
||||
(void)touches;
|
||||
|
||||
[self handleTouches:event];
|
||||
}
|
||||
|
||||
/*
|
||||
==================================
|
||||
idView::touchesCancelled
|
||||
==================================
|
||||
*/
|
||||
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||
|
||||
(void)touches;
|
||||
|
||||
[self handleTouches:event];
|
||||
}
|
||||
|
||||
/*
|
||||
==================================
|
||||
idView::Initialize
|
||||
==================================
|
||||
*/
|
||||
- (void) Initialize {
|
||||
|
||||
self.multipleTouchEnabled = YES;
|
||||
gMainView = self;
|
||||
|
||||
// Double the resolution on iPhone 4.
|
||||
[self setContentScaleFactor:[UIScreen mainScreen].scale];
|
||||
|
||||
// Get the layer for this view
|
||||
CAEAGLLayer *glLayer = (CAEAGLLayer *)self.layer;
|
||||
glLayer.opaque = TRUE;
|
||||
glLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking,
|
||||
kEAGLColorFormatRGB565,
|
||||
kEAGLDrawablePropertyColorFormat, nil];
|
||||
|
||||
// Create Our Render Context.
|
||||
mRenderContext.Initialize( kEAGLRenderingAPIOpenGLES1, NULL );
|
||||
|
||||
// Create our Frame Buffers.
|
||||
mRenderContext.InitFrameBuffer( glLayer );
|
||||
}
|
||||
|
||||
/*
|
||||
==================================
|
||||
idView::EndFrame
|
||||
==================================
|
||||
*/
|
||||
- (void) EndFrame {
|
||||
|
||||
mRenderContext.SwapBuffers();
|
||||
}
|
||||
|
||||
@end
|
||||
432
common/idmobilelib/ios/idmobilelib.xcodeproj/project.pbxproj
Executable file
432
common/idmobilelib/ios/idmobilelib.xcodeproj/project.pbxproj
Executable file
@@ -0,0 +1,432 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
3D7D557F14D21FEC00A0F1FF /* ios_interface.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7D557E14D21FEC00A0F1FF /* ios_interface.h */; };
|
||||
3D7D558214D2201E00A0F1FF /* ios_interface.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3D7D558114D2201E00A0F1FF /* ios_interface.mm */; };
|
||||
3D80884B14928766002D6CC3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D80884A14928766002D6CC3 /* Foundation.framework */; };
|
||||
3D80885E149287EB002D6CC3 /* GameCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D80885D149287EB002D6CC3 /* GameCenter.h */; };
|
||||
3D80886D14928AED002D6CC3 /* GameCenter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3D80886C14928AED002D6CC3 /* GameCenter.mm */; };
|
||||
3D80886F14928C16002D6CC3 /* GameKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D80886E14928C16002D6CC3 /* GameKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||
3D8088721492B362002D6CC3 /* sys_defines.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D8088711492B362002D6CC3 /* sys_defines.h */; };
|
||||
3D8088741492CA59002D6CC3 /* objectivec_utilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D8088731492CA59002D6CC3 /* objectivec_utilities.h */; };
|
||||
3D8088761492CBCB002D6CC3 /* objectivec_utilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3D8088751492CBCB002D6CC3 /* objectivec_utilities.mm */; };
|
||||
3DCB047B1498279D00E986AF /* LocalizationObjectiveC.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DCB04781498279D00E986AF /* LocalizationObjectiveC.h */; };
|
||||
C8011C8D14C0EB7A007AC5C5 /* InAppStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C8011C8B14C0EB7A007AC5C5 /* InAppStore.h */; };
|
||||
C8011C8E14C0EB7A007AC5C5 /* InAppStore.mm in Sources */ = {isa = PBXBuildFile; fileRef = C8011C8C14C0EB7A007AC5C5 /* InAppStore.mm */; };
|
||||
C8011C9414C0EC70007AC5C5 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C8011C9314C0EC70007AC5C5 /* StoreKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||
C8012E5F14B61D4900B0E213 /* AnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = C8012E5314B61D4900B0E213 /* AnimatedImage.h */; };
|
||||
C8012E6014B61D4900B0E213 /* AnimatedImage.mm in Sources */ = {isa = PBXBuildFile; fileRef = C8012E5414B61D4900B0E213 /* AnimatedImage.mm */; };
|
||||
C8012E6114B61D4900B0E213 /* Carousel.h in Headers */ = {isa = PBXBuildFile; fileRef = C8012E5514B61D4900B0E213 /* Carousel.h */; };
|
||||
C8012E6214B61D4900B0E213 /* Carousel.mm in Sources */ = {isa = PBXBuildFile; fileRef = C8012E5614B61D4900B0E213 /* Carousel.mm */; };
|
||||
C8012E6314B61D4900B0E213 /* Label.h in Headers */ = {isa = PBXBuildFile; fileRef = C8012E5714B61D4900B0E213 /* Label.h */; };
|
||||
C8012E6414B61D4900B0E213 /* Label.mm in Sources */ = {isa = PBXBuildFile; fileRef = C8012E5814B61D4900B0E213 /* Label.mm */; };
|
||||
C8012E6514B61D4900B0E213 /* LabelButton.h in Headers */ = {isa = PBXBuildFile; fileRef = C8012E5914B61D4900B0E213 /* LabelButton.h */; };
|
||||
C8012E6614B61D4900B0E213 /* LabelButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = C8012E5A14B61D4900B0E213 /* LabelButton.mm */; };
|
||||
C8012E6714B61D4900B0E213 /* Slider.h in Headers */ = {isa = PBXBuildFile; fileRef = C8012E5B14B61D4900B0E213 /* Slider.h */; };
|
||||
C8012E6814B61D4900B0E213 /* Slider.mm in Sources */ = {isa = PBXBuildFile; fileRef = C8012E5C14B61D4900B0E213 /* Slider.mm */; };
|
||||
C8012E6914B61D4900B0E213 /* Switch.h in Headers */ = {isa = PBXBuildFile; fileRef = C8012E5D14B61D4900B0E213 /* Switch.h */; };
|
||||
C8012E6A14B61D4900B0E213 /* Switch.mm in Sources */ = {isa = PBXBuildFile; fileRef = C8012E5E14B61D4900B0E213 /* Switch.mm */; };
|
||||
C8A6294514969EEE002EF3F5 /* Localization.h in Headers */ = {isa = PBXBuildFile; fileRef = C8A6294414969EEE002EF3F5 /* Localization.h */; };
|
||||
C8A6294814969F07002EF3F5 /* Localization.mm in Sources */ = {isa = PBXBuildFile; fileRef = C8A6294714969F07002EF3F5 /* Localization.mm */; };
|
||||
C8A629611497F318002EF3F5 /* View.mm in Sources */ = {isa = PBXBuildFile; fileRef = C8A629601497F318002EF3F5 /* View.mm */; };
|
||||
C8A629631497F329002EF3F5 /* View.h in Headers */ = {isa = PBXBuildFile; fileRef = C8A629621497F329002EF3F5 /* View.h */; };
|
||||
C8A629651497F509002EF3F5 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C8A629641497F508002EF3F5 /* OpenGLES.framework */; };
|
||||
C8A629671497F510002EF3F5 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C8A629661497F510002EF3F5 /* QuartzCore.framework */; };
|
||||
C8A6296914980C5B002EF3F5 /* RenderContext.h in Headers */ = {isa = PBXBuildFile; fileRef = C8A6296814980C5B002EF3F5 /* RenderContext.h */; };
|
||||
C8A6296B14980C6E002EF3F5 /* RenderContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = C8A6296A14980C6E002EF3F5 /* RenderContext.mm */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
3D7D557E14D21FEC00A0F1FF /* ios_interface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ios_interface.h; sourceTree = "<group>"; };
|
||||
3D7D558114D2201E00A0F1FF /* ios_interface.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ios_interface.mm; sourceTree = "<group>"; };
|
||||
3D80884714928766002D6CC3 /* libidmobilelib.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libidmobilelib.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3D80884A14928766002D6CC3 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
3D80885D149287EB002D6CC3 /* GameCenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameCenter.h; sourceTree = "<group>"; };
|
||||
3D80886C14928AED002D6CC3 /* GameCenter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GameCenter.mm; sourceTree = "<group>"; };
|
||||
3D80886E14928C16002D6CC3 /* GameKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System/Library/Frameworks/GameKit.framework; sourceTree = SDKROOT; };
|
||||
3D8088711492B362002D6CC3 /* sys_defines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sys_defines.h; path = ../sys/sys_defines.h; sourceTree = "<group>"; };
|
||||
3D8088731492CA59002D6CC3 /* objectivec_utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = objectivec_utilities.h; sourceTree = "<group>"; };
|
||||
3D8088751492CBCB002D6CC3 /* objectivec_utilities.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = objectivec_utilities.mm; sourceTree = "<group>"; };
|
||||
3DCB04781498279D00E986AF /* LocalizationObjectiveC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalizationObjectiveC.h; sourceTree = "<group>"; };
|
||||
C8011C8B14C0EB7A007AC5C5 /* InAppStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InAppStore.h; sourceTree = "<group>"; };
|
||||
C8011C8C14C0EB7A007AC5C5 /* InAppStore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InAppStore.mm; sourceTree = "<group>"; };
|
||||
C8011C9314C0EC70007AC5C5 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
|
||||
C8012E5314B61D4900B0E213 /* AnimatedImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimatedImage.h; sourceTree = "<group>"; };
|
||||
C8012E5414B61D4900B0E213 /* AnimatedImage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AnimatedImage.mm; sourceTree = "<group>"; };
|
||||
C8012E5514B61D4900B0E213 /* Carousel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Carousel.h; sourceTree = "<group>"; };
|
||||
C8012E5614B61D4900B0E213 /* Carousel.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Carousel.mm; sourceTree = "<group>"; };
|
||||
C8012E5714B61D4900B0E213 /* Label.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Label.h; sourceTree = "<group>"; };
|
||||
C8012E5814B61D4900B0E213 /* Label.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Label.mm; sourceTree = "<group>"; };
|
||||
C8012E5914B61D4900B0E213 /* LabelButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LabelButton.h; sourceTree = "<group>"; };
|
||||
C8012E5A14B61D4900B0E213 /* LabelButton.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LabelButton.mm; sourceTree = "<group>"; };
|
||||
C8012E5B14B61D4900B0E213 /* Slider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Slider.h; sourceTree = "<group>"; };
|
||||
C8012E5C14B61D4900B0E213 /* Slider.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Slider.mm; sourceTree = "<group>"; };
|
||||
C8012E5D14B61D4900B0E213 /* Switch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Switch.h; sourceTree = "<group>"; };
|
||||
C8012E5E14B61D4900B0E213 /* Switch.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Switch.mm; sourceTree = "<group>"; };
|
||||
C8A6294414969EEE002EF3F5 /* Localization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Localization.h; sourceTree = "<group>"; };
|
||||
C8A6294714969F07002EF3F5 /* Localization.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Localization.mm; sourceTree = "<group>"; };
|
||||
C8A629601497F318002EF3F5 /* View.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = View.mm; sourceTree = "<group>"; };
|
||||
C8A629621497F329002EF3F5 /* View.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = View.h; sourceTree = "<group>"; };
|
||||
C8A629641497F508002EF3F5 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
|
||||
C8A629661497F510002EF3F5 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
C8A6296814980C5B002EF3F5 /* RenderContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderContext.h; sourceTree = "<group>"; };
|
||||
C8A6296A14980C6E002EF3F5 /* RenderContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RenderContext.mm; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
3D80884414928766002D6CC3 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C8011C9414C0EC70007AC5C5 /* StoreKit.framework in Frameworks */,
|
||||
C8A629671497F510002EF3F5 /* QuartzCore.framework in Frameworks */,
|
||||
C8A629651497F509002EF3F5 /* OpenGLES.framework in Frameworks */,
|
||||
3D80886F14928C16002D6CC3 /* GameKit.framework in Frameworks */,
|
||||
3D80884B14928766002D6CC3 /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
3D80883C14928766002D6CC3 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3D80885714928798002D6CC3 /* idmobilelib */,
|
||||
3D80884914928766002D6CC3 /* Frameworks */,
|
||||
3D80884814928766002D6CC3 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3D80884814928766002D6CC3 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3D80884714928766002D6CC3 /* libidmobilelib.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3D80884914928766002D6CC3 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C8011C9314C0EC70007AC5C5 /* StoreKit.framework */,
|
||||
C8A629661497F510002EF3F5 /* QuartzCore.framework */,
|
||||
C8A629641497F508002EF3F5 /* OpenGLES.framework */,
|
||||
3D80884A14928766002D6CC3 /* Foundation.framework */,
|
||||
3D80886E14928C16002D6CC3 /* GameKit.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3D80885714928798002D6CC3 /* idmobilelib */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3D808858149287A1002D6CC3 /* ios */,
|
||||
3D8088701492B34E002D6CC3 /* sys */,
|
||||
);
|
||||
name = idmobilelib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3D808858149287A1002D6CC3 /* ios */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C8A6295E1497F2A6002EF3F5 /* Interface Builder */,
|
||||
3D80885D149287EB002D6CC3 /* GameCenter.h */,
|
||||
3D80886C14928AED002D6CC3 /* GameCenter.mm */,
|
||||
3D8088731492CA59002D6CC3 /* objectivec_utilities.h */,
|
||||
3D8088751492CBCB002D6CC3 /* objectivec_utilities.mm */,
|
||||
C8A6294414969EEE002EF3F5 /* Localization.h */,
|
||||
C8A6294714969F07002EF3F5 /* Localization.mm */,
|
||||
3DCB04781498279D00E986AF /* LocalizationObjectiveC.h */,
|
||||
C8A6296814980C5B002EF3F5 /* RenderContext.h */,
|
||||
C8A6296A14980C6E002EF3F5 /* RenderContext.mm */,
|
||||
C8011C8B14C0EB7A007AC5C5 /* InAppStore.h */,
|
||||
C8011C8C14C0EB7A007AC5C5 /* InAppStore.mm */,
|
||||
3D7D557E14D21FEC00A0F1FF /* ios_interface.h */,
|
||||
3D7D558114D2201E00A0F1FF /* ios_interface.mm */,
|
||||
);
|
||||
name = ios;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3D8088701492B34E002D6CC3 /* sys */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3D8088711492B362002D6CC3 /* sys_defines.h */,
|
||||
);
|
||||
name = sys;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C8A6295E1497F2A6002EF3F5 /* Interface Builder */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C8012E5314B61D4900B0E213 /* AnimatedImage.h */,
|
||||
C8012E5414B61D4900B0E213 /* AnimatedImage.mm */,
|
||||
C8012E5514B61D4900B0E213 /* Carousel.h */,
|
||||
C8012E5614B61D4900B0E213 /* Carousel.mm */,
|
||||
C8012E5714B61D4900B0E213 /* Label.h */,
|
||||
C8012E5814B61D4900B0E213 /* Label.mm */,
|
||||
C8012E5914B61D4900B0E213 /* LabelButton.h */,
|
||||
C8012E5A14B61D4900B0E213 /* LabelButton.mm */,
|
||||
C8012E5B14B61D4900B0E213 /* Slider.h */,
|
||||
C8012E5C14B61D4900B0E213 /* Slider.mm */,
|
||||
C8012E5D14B61D4900B0E213 /* Switch.h */,
|
||||
C8012E5E14B61D4900B0E213 /* Switch.mm */,
|
||||
C8A629621497F329002EF3F5 /* View.h */,
|
||||
C8A629601497F318002EF3F5 /* View.mm */,
|
||||
);
|
||||
name = "Interface Builder";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
3D80884514928766002D6CC3 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3D80885E149287EB002D6CC3 /* GameCenter.h in Headers */,
|
||||
3D8088721492B362002D6CC3 /* sys_defines.h in Headers */,
|
||||
3D8088741492CA59002D6CC3 /* objectivec_utilities.h in Headers */,
|
||||
C8A6294514969EEE002EF3F5 /* Localization.h in Headers */,
|
||||
C8A629631497F329002EF3F5 /* View.h in Headers */,
|
||||
C8A6296914980C5B002EF3F5 /* RenderContext.h in Headers */,
|
||||
3DCB047B1498279D00E986AF /* LocalizationObjectiveC.h in Headers */,
|
||||
C8012E5F14B61D4900B0E213 /* AnimatedImage.h in Headers */,
|
||||
C8012E6114B61D4900B0E213 /* Carousel.h in Headers */,
|
||||
C8012E6314B61D4900B0E213 /* Label.h in Headers */,
|
||||
C8012E6514B61D4900B0E213 /* LabelButton.h in Headers */,
|
||||
C8012E6714B61D4900B0E213 /* Slider.h in Headers */,
|
||||
C8012E6914B61D4900B0E213 /* Switch.h in Headers */,
|
||||
C8011C8D14C0EB7A007AC5C5 /* InAppStore.h in Headers */,
|
||||
3D7D557F14D21FEC00A0F1FF /* ios_interface.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
3D80884614928766002D6CC3 /* idmobilelib */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 3D80885414928766002D6CC3 /* Build configuration list for PBXNativeTarget "idmobilelib" */;
|
||||
buildPhases = (
|
||||
3D80884314928766002D6CC3 /* Sources */,
|
||||
3D80884414928766002D6CC3 /* Frameworks */,
|
||||
3D80884514928766002D6CC3 /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = idmobilelib;
|
||||
productName = idmobilelib;
|
||||
productReference = 3D80884714928766002D6CC3 /* libidmobilelib.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
3D80883E14928766002D6CC3 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0500;
|
||||
};
|
||||
buildConfigurationList = 3D80884114928766002D6CC3 /* Build configuration list for PBXProject "idmobilelib" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 3D80883C14928766002D6CC3;
|
||||
productRefGroup = 3D80884814928766002D6CC3 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
3D80884614928766002D6CC3 /* idmobilelib */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
3D80884314928766002D6CC3 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3D80886D14928AED002D6CC3 /* GameCenter.mm in Sources */,
|
||||
3D8088761492CBCB002D6CC3 /* objectivec_utilities.mm in Sources */,
|
||||
C8A6294814969F07002EF3F5 /* Localization.mm in Sources */,
|
||||
C8A629611497F318002EF3F5 /* View.mm in Sources */,
|
||||
C8A6296B14980C6E002EF3F5 /* RenderContext.mm in Sources */,
|
||||
C8012E6014B61D4900B0E213 /* AnimatedImage.mm in Sources */,
|
||||
C8012E6214B61D4900B0E213 /* Carousel.mm in Sources */,
|
||||
C8012E6414B61D4900B0E213 /* Label.mm in Sources */,
|
||||
C8012E6614B61D4900B0E213 /* LabelButton.mm in Sources */,
|
||||
C8012E6814B61D4900B0E213 /* Slider.mm in Sources */,
|
||||
C8012E6A14B61D4900B0E213 /* Switch.mm in Sources */,
|
||||
C8011C8E14C0EB7A007AC5C5 /* InAppStore.mm in Sources */,
|
||||
3D7D558214D2201E00A0F1FF /* ios_interface.mm in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
3D80885214928766002D6CC3 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
|
||||
CLANG_WARN_OBJCPP_ARC_ABI = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = c99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_THUMB_SUPPORT = NO;
|
||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
||||
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_VERSION = "";
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
|
||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
|
||||
GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
|
||||
GCC_WARN_PEDANTIC = YES;
|
||||
GCC_WARN_PROTOTYPE_CONVERSION = YES;
|
||||
GCC_WARN_SIGN_COMPARE = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = NO;
|
||||
GCC_WARN_UNKNOWN_PRAGMAS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 3.2;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
SDKROOT = iphoneos;
|
||||
USER_HEADER_SEARCH_PATHS = ../;
|
||||
WARNING_CFLAGS = (
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-pedantic-errors",
|
||||
);
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
3D80885314928766002D6CC3 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
|
||||
CLANG_WARN_OBJCPP_ARC_ABI = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = c99;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = NDEBUG;
|
||||
GCC_THUMB_SUPPORT = NO;
|
||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
||||
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_VERSION = "";
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
|
||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
|
||||
GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
|
||||
GCC_WARN_PEDANTIC = YES;
|
||||
GCC_WARN_PROTOTYPE_CONVERSION = YES;
|
||||
GCC_WARN_SIGN_COMPARE = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNKNOWN_PRAGMAS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 3.2;
|
||||
SDKROOT = iphoneos;
|
||||
USER_HEADER_SEARCH_PATHS = ../;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
WARNING_CFLAGS = (
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-pedantic-errors",
|
||||
);
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
3D80885514928766002D6CC3 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
DSTROOT = /tmp/idmobilelib.dst;
|
||||
GCC_VERSION = "";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
USE_HEADERMAP = NO;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
3D80885614928766002D6CC3 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
DSTROOT = /tmp/idmobilelib.dst;
|
||||
GCC_VERSION = "";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
USE_HEADERMAP = NO;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
3D80884114928766002D6CC3 /* Build configuration list for PBXProject "idmobilelib" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
3D80885214928766002D6CC3 /* Debug */,
|
||||
3D80885314928766002D6CC3 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
3D80885414928766002D6CC3 /* Build configuration list for PBXNativeTarget "idmobilelib" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
3D80885514928766002D6CC3 /* Debug */,
|
||||
3D80885614928766002D6CC3 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 3D80883E14928766002D6CC3 /* Project object */;
|
||||
}
|
||||
7
common/idmobilelib/ios/idmobilelib.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Executable file
7
common/idmobilelib/ios/idmobilelib.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Executable file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:idmobilelib.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0500"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "3D80884614928766002D6CC3"
|
||||
BuildableName = "libidmobilelib.a"
|
||||
BlueprintName = "idmobilelib"
|
||||
ReferencedContainer = "container:idmobilelib.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>3D80884614928766002D6CC3</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>idmobilelib.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>3</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>3D80884614928766002D6CC3</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
28
common/idmobilelib/ios/ios_interface.h
Executable file
28
common/idmobilelib/ios/ios_interface.h
Executable file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef idmobilelib_ios_interface_h
|
||||
#define idmobilelib_ios_interface_h
|
||||
|
||||
#include <string>
|
||||
|
||||
void ShowSystemAlert( const std::string & title, const std::string & message ) ;
|
||||
|
||||
#endif
|
||||
42
common/idmobilelib/ios/ios_interface.mm
Executable file
42
common/idmobilelib/ios/ios_interface.mm
Executable file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "ios_interface.h"
|
||||
#import "objectivec_utilities.h"
|
||||
#import "LocalizationObjectiveC.h"
|
||||
|
||||
#import <UIKit/UIAlertView.h>
|
||||
|
||||
/*
|
||||
=======================
|
||||
Shows the blue system alert box with localized text.
|
||||
=======================
|
||||
*/
|
||||
void ShowSystemAlert( const std::string & title, const std::string & message ) {
|
||||
NSString * nsTitle = idLocalization_GetNSString( StdStringToNSString( title ) );
|
||||
NSString * nsMessage = idLocalization_GetNSString( StdStringToNSString( message ) );
|
||||
NSString * nsCancelButton = idLocalization_GetNSString( @"#OK" );
|
||||
|
||||
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:nsTitle message:nsMessage delegate:nil cancelButtonTitle:nsCancelButton otherButtonTitles:nil];
|
||||
|
||||
[alert show];
|
||||
[alert release];
|
||||
}
|
||||
|
||||
47
common/idmobilelib/ios/objectivec_utilities.h
Executable file
47
common/idmobilelib/ios/objectivec_utilities.h
Executable file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
================================================================================================
|
||||
|
||||
This header collects miscellaneous utilities that automate certain tasks in
|
||||
Objective-C programming.
|
||||
|
||||
================================================================================================
|
||||
*/
|
||||
|
||||
#ifndef IDMOBILELIB_IOS_OBJECTIVEC_UTILITIES_H
|
||||
#define IDMOBILELIB_IOS_OBJECTIVEC_UTILITIES_H
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
@class NSString;
|
||||
@class NSError;
|
||||
|
||||
std::string NSStringToStdString( NSString * toConvert );
|
||||
NSString * StdStringToNSString( const std::string & toConvert );
|
||||
|
||||
|
||||
void DisplayNSErrorMessage( NSString* title, NSError * error );
|
||||
|
||||
|
||||
#endif
|
||||
67
common/idmobilelib/ios/objectivec_utilities.mm
Executable file
67
common/idmobilelib/ios/objectivec_utilities.mm
Executable file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "objectivec_utilities.h"
|
||||
#include "LocalizationObjectiveC.h"
|
||||
|
||||
#import <Foundation/NSString.h>
|
||||
#import <UIKit/UIAlertView.h>
|
||||
#import <Foundation/NSError.h>
|
||||
|
||||
/*
|
||||
========================
|
||||
Copies an NSString object to a C++ string encoded in UTF8.
|
||||
========================
|
||||
*/
|
||||
std::string NSStringToStdString( NSString * toConvert ) {
|
||||
const char * cString = [toConvert cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
return std::string( cString );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Copies a C++ string encoded in UTF8 to an NSString object.
|
||||
========================
|
||||
*/
|
||||
NSString * StdStringToNSString( const std::string & toConvert ) {
|
||||
return [NSString stringWithCString:toConvert.c_str() encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Disaplys a system alert with information about the given error.
|
||||
========================
|
||||
*/
|
||||
void DisplayNSErrorMessage( NSString * title, NSError * error ) {
|
||||
NSString *messageString = [error localizedDescription];
|
||||
NSString *reasonString = [error localizedFailureReason];
|
||||
|
||||
if ( reasonString != nil ) {
|
||||
messageString = [NSString stringWithFormat:@"%@. %@", messageString, reasonString];
|
||||
} else {
|
||||
messageString = [NSString stringWithFormat:@"%@", messageString];
|
||||
}
|
||||
|
||||
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:idLocalization_GetNSString( title )
|
||||
message:messageString delegate:nil
|
||||
cancelButtonTitle:idLocalization_GetNSString(@"OK") otherButtonTitles:nil];
|
||||
[alertView show];
|
||||
[alertView release];
|
||||
}
|
||||
Reference in New Issue
Block a user