iOS frontend and XCode project
This commit is contained in:
349
JGE/src/iOS/EAGLView.m
Executable file
349
JGE/src/iOS/EAGLView.m
Executable file
@@ -0,0 +1,349 @@
|
||||
#import "EAGLView.h"
|
||||
|
||||
#import "ES2Renderer.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
#include "JGE.h"
|
||||
#include "JTypes.h"
|
||||
#include "JApp.h"
|
||||
#include "JFileSystem.h"
|
||||
#include "JRenderer.h"
|
||||
#include "JGameLauncher.h"
|
||||
|
||||
|
||||
uint64_t lastTickCount;
|
||||
JGE* g_engine = NULL;
|
||||
static JApp* g_app = NULL;
|
||||
static JGameLauncher* g_launcher = NULL;
|
||||
|
||||
void JGECreateDefaultBindings()
|
||||
{
|
||||
}
|
||||
|
||||
int JGEGetTime()
|
||||
{
|
||||
return CFAbsoluteTimeGetCurrent() * 1000;
|
||||
}
|
||||
|
||||
bool InitGame(void)
|
||||
{
|
||||
g_engine = JGE::GetInstance();
|
||||
g_app = g_launcher->GetGameApp();
|
||||
g_app->Create();
|
||||
g_engine->SetApp(g_app);
|
||||
|
||||
JRenderer::GetInstance()->Enable2D();
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
lastTickCount = tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DestroyGame(void)
|
||||
{
|
||||
g_engine->SetApp(NULL);
|
||||
if (g_app)
|
||||
{
|
||||
g_app->Destroy();
|
||||
delete g_app;
|
||||
g_app = NULL;
|
||||
}
|
||||
|
||||
JGE::Destroy();
|
||||
|
||||
g_engine = NULL;
|
||||
}
|
||||
|
||||
|
||||
@implementation EAGLView
|
||||
|
||||
@synthesize animating;
|
||||
@dynamic animationFrameInterval;
|
||||
@synthesize currentLocation;
|
||||
|
||||
// You must implement this method
|
||||
+ (Class)layerClass
|
||||
{
|
||||
return [CAEAGLLayer class];
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[renderer release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(id)initWithFrame:(CGRect)frame {
|
||||
|
||||
NSLog(@"EAGL View - init With Frame: origin(%f %f) size(%f %f)",
|
||||
frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
|
||||
|
||||
if ((self = [super initWithFrame:frame])) {
|
||||
|
||||
self = [self initialize];
|
||||
|
||||
} // if ((self = [super initWithFrame:frame]))
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
//The EAGL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
|
||||
- (id)initWithCoder:(NSCoder*)coder
|
||||
{
|
||||
if ((self = [super initWithCoder:coder]))
|
||||
{
|
||||
self = [self initialize];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id)initialize {
|
||||
|
||||
NSLog(@"EAGL View - initialize EAGL");
|
||||
|
||||
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
|
||||
|
||||
NSLog(@"bounds: %f %f %f %f", eaglLayer.bounds.origin.x, eaglLayer.bounds.origin.y, eaglLayer.bounds.size.width, eaglLayer.bounds.size.height);
|
||||
|
||||
eaglLayer.opaque = TRUE;
|
||||
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking,
|
||||
kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
|
||||
nil];
|
||||
|
||||
renderer = [[ES2Renderer alloc] init];
|
||||
|
||||
if (!renderer)
|
||||
{
|
||||
NSLog(@"OpenGl ES2 Renderer creation failed, time to code some OpenGl ES1.1 Renderer !!!");
|
||||
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
|
||||
animating = FALSE;
|
||||
started = FALSE;
|
||||
animationFrameInterval = 1;
|
||||
displayLink = nil;
|
||||
|
||||
UIGestureRecognizer *recognizer;
|
||||
|
||||
/*
|
||||
Create a double tap recognizer to handle OK.
|
||||
*/
|
||||
recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleOK:)];
|
||||
[self addGestureRecognizer:recognizer];
|
||||
((UITapGestureRecognizer*)recognizer).numberOfTapsRequired = 2;
|
||||
[recognizer release];
|
||||
|
||||
/*
|
||||
Create a 2 fingers right swipe gesture recognizer to handle next phase.
|
||||
*/
|
||||
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleNextPhase:)];
|
||||
((UISwipeGestureRecognizer*)recognizer).direction = UISwipeGestureRecognizerDirectionRight;
|
||||
((UISwipeGestureRecognizer*)recognizer).numberOfTouchesRequired = 2;
|
||||
[self addGestureRecognizer:recognizer];
|
||||
[recognizer release];
|
||||
|
||||
/*
|
||||
Create a 2 fingers left swipe gesture recognizer to handle interruption.
|
||||
*/
|
||||
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleInterrupt:)];
|
||||
((UISwipeGestureRecognizer*)recognizer).direction = UISwipeGestureRecognizerDirectionLeft;
|
||||
((UISwipeGestureRecognizer*)recognizer).numberOfTouchesRequired = 2;
|
||||
[self addGestureRecognizer:recognizer];
|
||||
[recognizer release];
|
||||
|
||||
/*
|
||||
Create a 3 fingers up swipe gesture recognizer to handle menu.
|
||||
*/
|
||||
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleMenu:)];
|
||||
((UISwipeGestureRecognizer*)recognizer).direction = UISwipeGestureRecognizerDirectionUp;
|
||||
((UISwipeGestureRecognizer*)recognizer).numberOfTouchesRequired = 3;
|
||||
[self addGestureRecognizer:recognizer];
|
||||
[recognizer release];
|
||||
|
||||
/*
|
||||
Create a 2 fingers long press gesture recognizer to handle hand display.
|
||||
*/
|
||||
recognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleHand:)];
|
||||
((UILongPressGestureRecognizer*)recognizer).minimumPressDuration = 1;
|
||||
((UILongPressGestureRecognizer*)recognizer).numberOfTouchesRequired = 2;
|
||||
|
||||
[self addGestureRecognizer:recognizer];
|
||||
[recognizer release];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)handleHand:(UILongPressGestureRecognizer *)recognizer {
|
||||
g_engine->HoldKey_NoRepeat(JGE_BTN_NEXT);
|
||||
}
|
||||
|
||||
- (void)handleMenu:(UISwipeGestureRecognizer *)recognizer {
|
||||
g_engine->HoldKey_NoRepeat(JGE_BTN_MENU);
|
||||
}
|
||||
|
||||
- (void)handleInterrupt:(UISwipeGestureRecognizer *)recognizer {
|
||||
g_engine->HoldKey_NoRepeat(JGE_BTN_SEC);
|
||||
}
|
||||
|
||||
- (void)handleNextPhase:(UISwipeGestureRecognizer *)recognizer {
|
||||
g_engine->HoldKey_NoRepeat(JGE_BTN_PREV);
|
||||
}
|
||||
|
||||
- (void)handleOK:(UITapGestureRecognizer *)recognizer {
|
||||
g_engine->HoldKey_NoRepeat(JGE_BTN_OK);
|
||||
}
|
||||
|
||||
- (void)drawView:(id)sender
|
||||
{
|
||||
[renderer render];
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[self stopAnimation];
|
||||
[renderer resizeFromLayer:(CAEAGLLayer*)self.layer];
|
||||
[self startAnimation];
|
||||
|
||||
[self drawView:nil];
|
||||
}
|
||||
|
||||
- (NSInteger)animationFrameInterval
|
||||
{
|
||||
return animationFrameInterval;
|
||||
}
|
||||
|
||||
- (void)setAnimationFrameInterval:(NSInteger)frameInterval
|
||||
{
|
||||
// Frame interval defines how many display frames must pass between each time the
|
||||
// display link fires. The display link will only fire 30 times a second when the
|
||||
// frame internal is two on a display that refreshes 60 times a second. The default
|
||||
// frame interval setting of one will fire 60 times a second when the display refreshes
|
||||
// at 60 times a second. A frame interval setting of less than one results in undefined
|
||||
// behavior.
|
||||
if (frameInterval >= 1)
|
||||
{
|
||||
animationFrameInterval = frameInterval;
|
||||
|
||||
if (animating)
|
||||
{
|
||||
[self stopAnimation];
|
||||
[self startAnimation];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)startAnimation
|
||||
{
|
||||
if (!animating)
|
||||
{
|
||||
// CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed
|
||||
// if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will
|
||||
// not be called in system versions earlier than 3.1.
|
||||
|
||||
displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView:)];
|
||||
[displayLink setFrameInterval:animationFrameInterval];
|
||||
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
|
||||
|
||||
animating = TRUE;
|
||||
}
|
||||
|
||||
if(!started)
|
||||
{
|
||||
// Init JGE mess
|
||||
g_launcher = new JGameLauncher();
|
||||
|
||||
u32 flags = g_launcher->GetInitFlags();
|
||||
|
||||
if ((flags&JINIT_FLAG_ENABLE3D)!=0)
|
||||
{
|
||||
JRenderer::Set3DFlag(true);
|
||||
}
|
||||
|
||||
if (!InitGame())
|
||||
{
|
||||
//return 1;
|
||||
}
|
||||
|
||||
JGECreateDefaultBindings();
|
||||
|
||||
started = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)stopAnimation
|
||||
{
|
||||
if (animating)
|
||||
{
|
||||
[displayLink invalidate];
|
||||
displayLink = nil;
|
||||
|
||||
animating = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Handles the start of a touch
|
||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
UITouch* touch = [[event touchesForView:self] anyObject];
|
||||
|
||||
// Convert touch point from UIView referential to OpenGL one (upside-down flip)
|
||||
currentLocation = [touch previousLocationInView:self];
|
||||
ES2Renderer* es2renderer = (ES2Renderer*)renderer;
|
||||
|
||||
int actualWidth = (int) JRenderer::GetInstance()->GetActualWidth();
|
||||
int actualHeight = (int) JRenderer::GetInstance()->GetActualHeight();
|
||||
if (currentLocation.y >= es2renderer.viewPort.top &&
|
||||
currentLocation.y <= es2renderer.viewPort.bottom &&
|
||||
currentLocation.x <= es2renderer.viewPort.right &&
|
||||
currentLocation.x >= es2renderer.viewPort.left) {
|
||||
g_engine->LeftClicked(
|
||||
((currentLocation.x-es2renderer.viewPort.left)*SCREEN_WIDTH)/actualWidth,
|
||||
((currentLocation.y-es2renderer.viewPort.top)*SCREEN_HEIGHT)/actualHeight);
|
||||
} else if(currentLocation.y<es2renderer.viewPort.top) {
|
||||
g_engine->HoldKey_NoRepeat(JGE_BTN_MENU);
|
||||
} else if(currentLocation.y>es2renderer.viewPort.bottom) {
|
||||
g_engine->HoldKey_NoRepeat(JGE_BTN_NEXT);
|
||||
}
|
||||
}
|
||||
|
||||
// Handles the continuation of a touch.
|
||||
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
UITouch* touch = [[event touchesForView:self] anyObject];
|
||||
|
||||
// Convert touch point from UIView referential to OpenGL one (upside-down flip)
|
||||
currentLocation = [touch previousLocationInView:self];
|
||||
ES2Renderer* es2renderer = (ES2Renderer*)renderer;
|
||||
|
||||
int actualWidth = (int) JRenderer::GetInstance()->GetActualWidth();
|
||||
int actualHeight = (int) JRenderer::GetInstance()->GetActualHeight();
|
||||
if (currentLocation.y >= es2renderer.viewPort.top &&
|
||||
currentLocation.y <= es2renderer.viewPort.bottom &&
|
||||
currentLocation.x <= es2renderer.viewPort.right &&
|
||||
currentLocation.x >= es2renderer.viewPort.left) {
|
||||
g_engine->LeftClicked(
|
||||
((currentLocation.x-es2renderer.viewPort.left)*SCREEN_WIDTH)/actualWidth,
|
||||
((currentLocation.y-es2renderer.viewPort.top)*SCREEN_HEIGHT)/actualHeight);
|
||||
} else if(currentLocation.y<es2renderer.viewPort.top) {
|
||||
g_engine->HoldKey_NoRepeat(JGE_BTN_MENU);
|
||||
} else if(currentLocation.y>es2renderer.viewPort.bottom) {
|
||||
g_engine->HoldKey_NoRepeat(JGE_BTN_NEXT);
|
||||
}
|
||||
}
|
||||
|
||||
// Handles the end of a touch event.
|
||||
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
// If appropriate, add code necessary to save the state of the application.
|
||||
// This application is not saving state.
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user