From a37a19e40d88409d05131c729e5133cf0befccab Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 6 Feb 2013 09:54:15 -0500 Subject: [PATCH 001/108] First revision of iOS port. Only tested on simulator thus far. --- gfx/context/ioseagl_ctx.m | 175 ++++ gfx/gfx_context.c | 3 + gfx/gfx_context.h | 1 + gfx/gl_common.h | 9 +- gfx/shader_glsl.c | 5 +- ios/RetroArch.xcodeproj/project.pbxproj | 987 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + ios/RetroArch/AppDelegate.h | 18 + ios/RetroArch/AppDelegate.m | 70 ++ ios/RetroArch/Default-568h@2x.png | Bin 0 -> 18594 bytes ios/RetroArch/Default.png | Bin 0 -> 6540 bytes ios/RetroArch/Default@2x.png | Bin 0 -> 16107 bytes ios/RetroArch/RetroArch-Info.plist | 47 + ios/RetroArch/RetroArch-Prefix.pch | 14 + ios/RetroArch/ViewController.h | 13 + ios/RetroArch/en.lproj/InfoPlist.strings | 2 + .../en.lproj/ViewController_iPad.xib | 112 ++ .../en.lproj/ViewController_iPhone.xib | 127 +++ ios/RetroArch/main.mm | 17 + retroarch.c | 2 +- 20 files changed, 1606 insertions(+), 3 deletions(-) create mode 100644 gfx/context/ioseagl_ctx.m create mode 100644 ios/RetroArch.xcodeproj/project.pbxproj create mode 100644 ios/RetroArch.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 ios/RetroArch/AppDelegate.h create mode 100644 ios/RetroArch/AppDelegate.m create mode 100644 ios/RetroArch/Default-568h@2x.png create mode 100644 ios/RetroArch/Default.png create mode 100644 ios/RetroArch/Default@2x.png create mode 100644 ios/RetroArch/RetroArch-Info.plist create mode 100644 ios/RetroArch/RetroArch-Prefix.pch create mode 100644 ios/RetroArch/ViewController.h create mode 100644 ios/RetroArch/en.lproj/InfoPlist.strings create mode 100644 ios/RetroArch/en.lproj/ViewController_iPad.xib create mode 100644 ios/RetroArch/en.lproj/ViewController_iPhone.xib create mode 100644 ios/RetroArch/main.mm diff --git a/gfx/context/ioseagl_ctx.m b/gfx/context/ioseagl_ctx.m new file mode 100644 index 0000000000..85c3c0f4bc --- /dev/null +++ b/gfx/context/ioseagl_ctx.m @@ -0,0 +1,175 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2013 - Hans-Kristian Arntzen + * Copyright (C) 2011-2013 - Daniel De Matteis + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#include "../../driver.h" +#include "../gfx_common.h" +#include "../gl_common.h" +#include "../image.h" + +#include "../fonts/gl_font.h" +#include + +#ifdef HAVE_GLSL +#include "../shader_glsl.h" +#endif + +#import "../../ios/RetroArch/ViewController.h" + +static GLKView *gl_view; + +// Objective-C interface used to interact with the GLES context and display. +@interface ViewController () + +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKView *view; + +@end + +@implementation ViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + self.view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) context:self.context]; + + [EAGLContext setCurrentContext:self.context]; + + gl_view = self.view; +} + +- (void)dealloc +{ + if ([EAGLContext currentContext] == self.context) [EAGLContext setCurrentContext:nil]; +} + +@end + + +// C interface +static void gfx_ctx_set_swap_interval(unsigned interval) +{ + RARCH_LOG("gfx_ctx_set_swap_interval not supported.\n"); +} + +static void gfx_ctx_destroy(void) +{ + RARCH_LOG("gfx_ctx_destroy().\n"); +} + +static void gfx_ctx_get_video_size(unsigned *width, unsigned *height) +{ + *width = gl_view.bounds.size.width; + *height = gl_view.bounds.size.height; +} + +static bool gfx_ctx_init(void) +{ + return true; +} + +static void gfx_ctx_swap_buffers(void) +{ + [gl_view setNeedsDisplay]; + [gl_view bindDrawable]; +} + +static void gfx_ctx_check_window(bool *quit, + bool *resize, unsigned *width, unsigned *height, unsigned frame_count) +{ + (void)frame_count; + + *quit = false; + + while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE) == kCFRunLoopRunHandledSource); + + unsigned new_width, new_height; + gfx_ctx_get_video_size(&new_width, &new_height); + if (new_width != *width || new_height != *height) + { + *width = new_width; + *height = new_height; + *resize = true; + } +} + +static void gfx_ctx_set_resize(unsigned width, unsigned height) +{ + (void)width; + (void)height; +} + +static void gfx_ctx_update_window_title(bool reset) +{ +} + +static bool gfx_ctx_set_video_mode( + unsigned width, unsigned height, + bool fullscreen) +{ + (void)width; + (void)height; + (void)fullscreen; + return true; +} + +static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data) +{ + *input = NULL; + *input_data = NULL; +} + +static bool gfx_ctx_bind_api(enum gfx_ctx_api api) +{ + return api == GFX_CTX_OPENGL_ES_API; +} + +static bool gfx_ctx_has_focus(void) +{ + return true; +} + +static bool gfx_ctx_init_egl_image_buffer(const video_info_t *video) +{ + return false; +} + +static bool gfx_ctx_write_egl_image(const void *frame, unsigned width, unsigned height, unsigned pitch, bool rgb32, unsigned index, void **image_handle) +{ + return false; +} + +const gfx_ctx_driver_t gfx_ctx_ios = { + gfx_ctx_init, + gfx_ctx_destroy, + gfx_ctx_bind_api, + gfx_ctx_set_swap_interval, + gfx_ctx_set_video_mode, + gfx_ctx_get_video_size, + NULL, + gfx_ctx_update_window_title, + gfx_ctx_check_window, + gfx_ctx_set_resize, + gfx_ctx_has_focus, + gfx_ctx_swap_buffers, + gfx_ctx_input_driver, + NULL, + gfx_ctx_init_egl_image_buffer, + gfx_ctx_write_egl_image, + NULL, + "ios", +}; diff --git a/gfx/gfx_context.c b/gfx/gfx_context.c index 2c00351d01..0b43698fb2 100644 --- a/gfx/gfx_context.c +++ b/gfx/gfx_context.c @@ -48,6 +48,9 @@ static const gfx_ctx_driver_t *gfx_ctx_drivers[] = { #if defined(ANDROID) &gfx_ctx_android, #endif +#if defined(IOS) + &gfx_ctx_ios, +#endif }; const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident) diff --git a/gfx/gfx_context.h b/gfx/gfx_context.h index 3a4453e49a..55f2be318e 100644 --- a/gfx/gfx_context.h +++ b/gfx/gfx_context.h @@ -136,6 +136,7 @@ extern const gfx_ctx_driver_t gfx_ctx_ps3; extern const gfx_ctx_driver_t gfx_ctx_xdk; extern const gfx_ctx_driver_t gfx_ctx_wgl; extern const gfx_ctx_driver_t gfx_ctx_videocore; +extern const gfx_ctx_driver_t gfx_ctx_ios; const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident); // Finds driver with ident. Does not initialize. const gfx_ctx_driver_t *gfx_ctx_init_first(enum gfx_ctx_api api); // Finds first suitable driver and initializes. diff --git a/gfx/gl_common.h b/gfx/gl_common.h index 2617f84d28..27c5cb9547 100644 --- a/gfx/gl_common.h +++ b/gfx/gl_common.h @@ -34,7 +34,10 @@ #include #endif -#if defined(__APPLE__) +#if defined(IOS) +#include +#include +#elif defined(__APPLE__) #include #include #elif defined(HAVE_PSGL) @@ -324,7 +327,11 @@ extern PFNGLACTIVETEXTUREPROC pglActiveTexture; #ifndef GL_BGRA_EXT #define GL_BGRA_EXT 0x80E1 #endif +#ifdef IOS +#define RARCH_GL_INTERNAL_FORMAT32 GL_RGBA // Stupid Apple +#else #define RARCH_GL_INTERNAL_FORMAT32 GL_BGRA_EXT +#endif #define RARCH_GL_INTERNAL_FORMAT16 GL_RGB #define RARCH_GL_TEXTURE_TYPE32 GL_BGRA_EXT #define RARCH_GL_TEXTURE_TYPE16 GL_RGB diff --git a/gfx/shader_glsl.c b/gfx/shader_glsl.c index 4de50804a2..4bb7ff2667 100644 --- a/gfx/shader_glsl.c +++ b/gfx/shader_glsl.c @@ -27,7 +27,10 @@ #include "../config.h" #endif -#if defined(__APPLE__) // Because they like to be "oh, so, special". +#if defined(IOS) +#include +#include +#elif defined(__APPLE__) // Because they like to be "oh, so, special". #include #include #elif defined(HAVE_PSGL) diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..c0ba76bca0 --- /dev/null +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -0,0 +1,987 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 968A572A16C2A06800BE12F8 /* test.img in Resources */ = {isa = PBXBuildFile; fileRef = 968A572816C2A06800BE12F8 /* test.img */; }; + 968A572B16C2A06800BE12F8 /* libretro.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 968A572916C2A06800BE12F8 /* libretro.a */; }; + 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; + 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; + 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; + 96AFAE3016C1D4EA009DE44C /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2F16C1D4EA009DE44C /* GLKit.framework */; }; + 96AFAE3216C1D4EA009DE44C /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE3116C1D4EA009DE44C /* OpenGLES.framework */; }; + 96AFAE3816C1D4EA009DE44C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE3616C1D4EA009DE44C /* InfoPlist.strings */; }; + 96AFAE3A16C1D4EA009DE44C /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAE3916C1D4EA009DE44C /* main.mm */; }; + 96AFAE3E16C1D4EA009DE44C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAE3D16C1D4EA009DE44C /* AppDelegate.m */; }; + 96AFAE4016C1D4EA009DE44C /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE3F16C1D4EA009DE44C /* Default.png */; }; + 96AFAE4216C1D4EA009DE44C /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4116C1D4EA009DE44C /* Default@2x.png */; }; + 96AFAE4416C1D4EA009DE44C /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4316C1D4EA009DE44C /* Default-568h@2x.png */; }; + 96AFAE4E16C1D4EA009DE44C /* ViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4C16C1D4EA009DE44C /* ViewController_iPhone.xib */; }; + 96AFAE5116C1D4EA009DE44C /* ViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4F16C1D4EA009DE44C /* ViewController_iPad.xib */; }; + 96AFAECA16C1D9A9009DE44C /* autosave.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAE9D16C1D9A9009DE44C /* autosave.c */; }; + 96AFAECB16C1D9A9009DE44C /* cheats.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEA016C1D9A9009DE44C /* cheats.c */; }; + 96AFAECC16C1D9A9009DE44C /* command.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEA216C1D9A9009DE44C /* command.c */; }; + 96AFAECD16C1D9A9009DE44C /* driver.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEA716C1D9A9009DE44C /* driver.c */; }; + 96AFAECE16C1D9A9009DE44C /* dynamic.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEA916C1D9A9009DE44C /* dynamic.c */; }; + 96AFAECF16C1D9A9009DE44C /* fifo_buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEAB16C1D9A9009DE44C /* fifo_buffer.c */; }; + 96AFAED016C1D9A9009DE44C /* file_extract.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEAD16C1D9A9009DE44C /* file_extract.c */; }; + 96AFAED116C1D9A9009DE44C /* file_path.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEAF16C1D9A9009DE44C /* file_path.c */; }; + 96AFAED216C1D9A9009DE44C /* file.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEB016C1D9A9009DE44C /* file.c */; }; + 96AFAED316C1D9A9009DE44C /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEB316C1D9A9009DE44C /* hash.c */; }; + 96AFAED416C1D9A9009DE44C /* message.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEB616C1D9A9009DE44C /* message.c */; }; + 96AFAED516C1D9A9009DE44C /* movie.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEB816C1D9A9009DE44C /* movie.c */; }; + 96AFAED716C1D9A9009DE44C /* patch.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEBD16C1D9A9009DE44C /* patch.c */; }; + 96AFAED816C1D9A9009DE44C /* performance.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEBF16C1D9A9009DE44C /* performance.c */; }; + 96AFAED916C1D9A9009DE44C /* retroarch.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEC216C1D9A9009DE44C /* retroarch.c */; }; + 96AFAEDA16C1D9A9009DE44C /* rewind.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEC316C1D9A9009DE44C /* rewind.c */; }; + 96AFAEDB16C1D9A9009DE44C /* screenshot.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEC516C1D9A9009DE44C /* screenshot.c */; }; + 96AFAEDC16C1D9A9009DE44C /* settings.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEC716C1D9A9009DE44C /* settings.c */; }; + 96AFAEDD16C1D9A9009DE44C /* thread.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEC816C1D9A9009DE44C /* thread.c */; }; + 96AFAEE416C1DBDB009DE44C /* config_file.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEE116C1DBDB009DE44C /* config_file.c */; }; + 96AFAF0B16C1DC73009DE44C /* null.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEEE16C1DC73009DE44C /* null.c */; }; + 96AFAF1816C1DC73009DE44C /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEFD16C1DC73009DE44C /* utils.c */; }; + 96AFAF1F16C1DF0A009DE44C /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAF1E16C1DF0A009DE44C /* OpenAL.framework */; }; + 96AFAF2016C1DF3A009DE44C /* openal.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEEF16C1DC73009DE44C /* openal.c */; }; + 96AFAF2216C1DF88009DE44C /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAF2116C1DF88009DE44C /* libz.dylib */; }; + 96AFAF2D16C1DFC8009DE44C /* compat.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF2416C1DFC8009DE44C /* compat.c */; }; + 96AFAF2F16C1DFC8009DE44C /* rxml.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF2916C1DFC8009DE44C /* rxml.c */; }; + 96AFAF8D16C1E00A009DE44C /* bitmapfont.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF4816C1E00A009DE44C /* bitmapfont.c */; }; + 96AFAF8F16C1E00A009DE44C /* fonts.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF4B16C1E00A009DE44C /* fonts.c */; }; + 96AFAF9116C1E00A009DE44C /* gl_font.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF4E16C1E00A009DE44C /* gl_font.c */; }; + 96AFAF9216C1E00A009DE44C /* gl_raster_font.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF5016C1E00A009DE44C /* gl_raster_font.c */; }; + 96AFAF9616C1E00A009DE44C /* gfx_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF5416C1E00A009DE44C /* gfx_common.c */; }; + 96AFAF9716C1E00A009DE44C /* gfx_context.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF5616C1E00A009DE44C /* gfx_context.c */; }; + 96AFAF9816C1E00A009DE44C /* gl.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF5816C1E00A009DE44C /* gl.c */; }; + 96AFAF9916C1E00A009DE44C /* image.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF5A16C1E00A009DE44C /* image.c */; }; + 96AFAF9A16C1E00A009DE44C /* matrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF5D16C1E00A009DE44C /* matrix.c */; }; + 96AFAF9B16C1E00A009DE44C /* matrix_3x3.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF5F16C1E00A009DE44C /* matrix_3x3.c */; }; + 96AFAF9C16C1E00A009DE44C /* null.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF6116C1E00A009DE44C /* null.c */; }; + 96AFAF9F16C1E00A009DE44C /* rpng.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF6716C1E00A009DE44C /* rpng.c */; }; + 96AFAFA116C1E00A009DE44C /* filter.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF6B16C1E00A009DE44C /* filter.c */; }; + 96AFAFA216C1E00A009DE44C /* pixconv.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF6D16C1E00A009DE44C /* pixconv.c */; }; + 96AFAFA316C1E00A009DE44C /* scaler.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF6F16C1E00A009DE44C /* scaler.c */; }; + 96AFAFA416C1E00A009DE44C /* scaler_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF7116C1E00A009DE44C /* scaler_int.c */; }; + 96AFAFA716C1E00A009DE44C /* shader_glsl.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF7716C1E00A009DE44C /* shader_glsl.c */; }; + 96AFAFAC16C1E279009DE44C /* state_tracker.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF7B16C1E00A009DE44C /* state_tracker.c */; }; + 96AFAFAD16C1EEE9009DE44C /* sinc.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEF716C1DC73009DE44C /* sinc.c */; }; + 96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFC916C1FBC0009DE44C /* input_common.c */; }; + 96AFAFD716C1FBC0009DE44C /* null.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCD16C1FBC0009DE44C /* null.c */; }; + 96AFAFDD16C2149A009DE44C /* ioseagl_ctx.m in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFDC16C2149A009DE44C /* ioseagl_ctx.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 968A572816C2A06800BE12F8 /* test.img */ = {isa = PBXFileReference; lastKnownFileType = file; path = test.img; sourceTree = ""; }; + 968A572916C2A06800BE12F8 /* libretro.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libretro.a; sourceTree = ""; }; + 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 96AFAE2F16C1D4EA009DE44C /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; }; + 96AFAE3116C1D4EA009DE44C /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + 96AFAE3516C1D4EA009DE44C /* RetroArch-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RetroArch-Info.plist"; sourceTree = ""; }; + 96AFAE3716C1D4EA009DE44C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 96AFAE3916C1D4EA009DE44C /* main.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; }; + 96AFAE3B16C1D4EA009DE44C /* RetroArch-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RetroArch-Prefix.pch"; sourceTree = ""; }; + 96AFAE3C16C1D4EA009DE44C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 96AFAE3D16C1D4EA009DE44C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 96AFAE3F16C1D4EA009DE44C /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 96AFAE4116C1D4EA009DE44C /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; + 96AFAE4316C1D4EA009DE44C /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; + 96AFAE4916C1D4EA009DE44C /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 96AFAE4D16C1D4EA009DE44C /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPhone.xib; sourceTree = ""; }; + 96AFAE5016C1D4EA009DE44C /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPad.xib; sourceTree = ""; }; + 96AFAE9D16C1D9A9009DE44C /* autosave.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = autosave.c; path = ../autosave.c; sourceTree = ""; }; + 96AFAE9E16C1D9A9009DE44C /* autosave.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = autosave.h; path = ../autosave.h; sourceTree = ""; }; + 96AFAE9F16C1D9A9009DE44C /* boolean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = boolean.h; path = ../boolean.h; sourceTree = ""; }; + 96AFAEA016C1D9A9009DE44C /* cheats.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cheats.c; path = ../cheats.c; sourceTree = ""; }; + 96AFAEA116C1D9A9009DE44C /* cheats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cheats.h; path = ../cheats.h; sourceTree = ""; }; + 96AFAEA216C1D9A9009DE44C /* command.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = command.c; path = ../command.c; sourceTree = ""; }; + 96AFAEA316C1D9A9009DE44C /* command.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = command.h; path = ../command.h; sourceTree = ""; }; + 96AFAEA416C1D9A9009DE44C /* config.def.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = config.def.h; path = ../config.def.h; sourceTree = ""; }; + 96AFAEA516C1D9A9009DE44C /* config.features.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = config.features.h; path = ../config.features.h; sourceTree = ""; }; + 96AFAEA616C1D9A9009DE44C /* driver_funcs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = driver_funcs.h; path = ../driver_funcs.h; sourceTree = ""; }; + 96AFAEA716C1D9A9009DE44C /* driver.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = driver.c; path = ../driver.c; sourceTree = ""; }; + 96AFAEA816C1D9A9009DE44C /* driver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = driver.h; path = ../driver.h; sourceTree = ""; }; + 96AFAEA916C1D9A9009DE44C /* dynamic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = dynamic.c; path = ../dynamic.c; sourceTree = ""; }; + 96AFAEAA16C1D9A9009DE44C /* dynamic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dynamic.h; path = ../dynamic.h; sourceTree = ""; }; + 96AFAEAB16C1D9A9009DE44C /* fifo_buffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = fifo_buffer.c; path = ../fifo_buffer.c; sourceTree = ""; }; + 96AFAEAC16C1D9A9009DE44C /* fifo_buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fifo_buffer.h; path = ../fifo_buffer.h; sourceTree = ""; }; + 96AFAEAD16C1D9A9009DE44C /* file_extract.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = file_extract.c; path = ../file_extract.c; sourceTree = ""; }; + 96AFAEAE16C1D9A9009DE44C /* file_extract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = file_extract.h; path = ../file_extract.h; sourceTree = ""; }; + 96AFAEAF16C1D9A9009DE44C /* file_path.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = file_path.c; path = ../file_path.c; sourceTree = ""; }; + 96AFAEB016C1D9A9009DE44C /* file.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = file.c; path = ../file.c; sourceTree = ""; }; + 96AFAEB116C1D9A9009DE44C /* file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = file.h; path = ../file.h; sourceTree = ""; }; + 96AFAEB216C1D9A9009DE44C /* general.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = general.h; path = ../general.h; sourceTree = ""; }; + 96AFAEB316C1D9A9009DE44C /* hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hash.c; path = ../hash.c; sourceTree = ""; }; + 96AFAEB416C1D9A9009DE44C /* hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = hash.h; path = ../hash.h; sourceTree = ""; }; + 96AFAEB516C1D9A9009DE44C /* libretro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = libretro.h; path = ../libretro.h; sourceTree = ""; }; + 96AFAEB616C1D9A9009DE44C /* message.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = message.c; path = ../message.c; sourceTree = ""; }; + 96AFAEB716C1D9A9009DE44C /* message.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = message.h; path = ../message.h; sourceTree = ""; }; + 96AFAEB816C1D9A9009DE44C /* movie.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = movie.c; path = ../movie.c; sourceTree = ""; }; + 96AFAEB916C1D9A9009DE44C /* movie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = movie.h; path = ../movie.h; sourceTree = ""; }; + 96AFAEBA16C1D9A9009DE44C /* netplay_compat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = netplay_compat.h; path = ../netplay_compat.h; sourceTree = ""; }; + 96AFAEBB16C1D9A9009DE44C /* netplay.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = netplay.c; path = ../netplay.c; sourceTree = ""; }; + 96AFAEBC16C1D9A9009DE44C /* netplay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = netplay.h; path = ../netplay.h; sourceTree = ""; }; + 96AFAEBD16C1D9A9009DE44C /* patch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = patch.c; path = ../patch.c; sourceTree = ""; }; + 96AFAEBE16C1D9A9009DE44C /* patch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = patch.h; path = ../patch.h; sourceTree = ""; }; + 96AFAEBF16C1D9A9009DE44C /* performance.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = performance.c; path = ../performance.c; sourceTree = ""; }; + 96AFAEC016C1D9A9009DE44C /* performance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = performance.h; path = ../performance.h; sourceTree = ""; }; + 96AFAEC116C1D9A9009DE44C /* retroarch_logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = retroarch_logger.h; path = ../retroarch_logger.h; sourceTree = ""; }; + 96AFAEC216C1D9A9009DE44C /* retroarch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = retroarch.c; path = ../retroarch.c; sourceTree = ""; }; + 96AFAEC316C1D9A9009DE44C /* rewind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rewind.c; path = ../rewind.c; sourceTree = ""; }; + 96AFAEC416C1D9A9009DE44C /* rewind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rewind.h; path = ../rewind.h; sourceTree = ""; }; + 96AFAEC516C1D9A9009DE44C /* screenshot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = screenshot.c; path = ../screenshot.c; sourceTree = ""; }; + 96AFAEC616C1D9A9009DE44C /* screenshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = screenshot.h; path = ../screenshot.h; sourceTree = ""; }; + 96AFAEC716C1D9A9009DE44C /* settings.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = settings.c; path = ../settings.c; sourceTree = ""; }; + 96AFAEC816C1D9A9009DE44C /* thread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = thread.c; path = ../thread.c; sourceTree = ""; }; + 96AFAEC916C1D9A9009DE44C /* thread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = thread.h; path = ../thread.h; sourceTree = ""; }; + 96AFAEE116C1DBDB009DE44C /* config_file.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = config_file.c; sourceTree = ""; }; + 96AFAEE216C1DBDB009DE44C /* config_file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config_file.h; sourceTree = ""; }; + 96AFAEE316C1DBDB009DE44C /* config_file_macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config_file_macros.h; sourceTree = ""; }; + 96AFAEE616C1DC73009DE44C /* alsa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alsa.c; sourceTree = ""; }; + 96AFAEE716C1DC73009DE44C /* alsathread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alsathread.c; sourceTree = ""; }; + 96AFAEE816C1DC73009DE44C /* coreaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = coreaudio.c; sourceTree = ""; }; + 96AFAEE916C1DC73009DE44C /* dsound.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dsound.c; sourceTree = ""; }; + 96AFAEEB16C1DC73009DE44C /* rarch_dsp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rarch_dsp.h; sourceTree = ""; }; + 96AFAEEC16C1DC73009DE44C /* hermite.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hermite.c; sourceTree = ""; }; + 96AFAEED16C1DC73009DE44C /* jack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = jack.c; sourceTree = ""; }; + 96AFAEEE16C1DC73009DE44C /* null.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = null.c; sourceTree = ""; }; + 96AFAEEF16C1DC73009DE44C /* openal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = openal.c; sourceTree = ""; }; + 96AFAEF016C1DC73009DE44C /* opensl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = opensl.c; sourceTree = ""; }; + 96AFAEF116C1DC73009DE44C /* oss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = oss.c; sourceTree = ""; }; + 96AFAEF216C1DC73009DE44C /* pulse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pulse.c; sourceTree = ""; }; + 96AFAEF316C1DC73009DE44C /* resampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resampler.h; sourceTree = ""; }; + 96AFAEF416C1DC73009DE44C /* roar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = roar.c; sourceTree = ""; }; + 96AFAEF516C1DC73009DE44C /* rsound.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsound.c; sourceTree = ""; }; + 96AFAEF616C1DC73009DE44C /* sdl_audio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_audio.c; sourceTree = ""; }; + 96AFAEF716C1DC73009DE44C /* sinc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sinc.c; sourceTree = ""; }; + 96AFAEF816C1DC73009DE44C /* sinc_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sinc_neon.S; sourceTree = ""; }; + 96AFAEFA16C1DC73009DE44C /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; + 96AFAEFB16C1DC73009DE44C /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 96AFAEFC16C1DC73009DE44C /* snr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = snr.c; sourceTree = ""; }; + 96AFAEFD16C1DC73009DE44C /* utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utils.c; sourceTree = ""; }; + 96AFAEFE16C1DC73009DE44C /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = ""; }; + 96AFAEFF16C1DC73009DE44C /* utils_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = utils_neon.S; sourceTree = ""; }; + 96AFAF0116C1DC73009DE44C /* xaudio-c.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "xaudio-c.cpp"; sourceTree = ""; }; + 96AFAF0216C1DC73009DE44C /* xaudio-c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "xaudio-c.h"; sourceTree = ""; }; + 96AFAF0316C1DC73009DE44C /* xaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xaudio.h; sourceTree = ""; }; + 96AFAF0416C1DC73009DE44C /* xaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xaudio.c; sourceTree = ""; }; + 96AFAF1E16C1DF0A009DE44C /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; }; + 96AFAF2116C1DF88009DE44C /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; + 96AFAF2416C1DFC8009DE44C /* compat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = compat.c; sourceTree = ""; }; + 96AFAF2516C1DFC8009DE44C /* getopt_rarch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = getopt_rarch.h; sourceTree = ""; }; + 96AFAF2616C1DFC8009DE44C /* posix_string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = posix_string.h; sourceTree = ""; }; + 96AFAF2816C1DFC8009DE44C /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 96AFAF2916C1DFC8009DE44C /* rxml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rxml.c; sourceTree = ""; }; + 96AFAF2A16C1DFC8009DE44C /* rxml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rxml.h; sourceTree = ""; }; + 96AFAF2B16C1DFC8009DE44C /* rxml_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rxml_test.c; sourceTree = ""; }; + 96AFAF2C16C1DFC8009DE44C /* strl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strl.h; sourceTree = ""; }; + 96AFAF3316C1E00A009DE44C /* androidegl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = androidegl_ctx.c; sourceTree = ""; }; + 96AFAF3416C1E00A009DE44C /* drm_egl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = drm_egl_ctx.c; sourceTree = ""; }; + 96AFAF3516C1E00A009DE44C /* glx_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = glx_ctx.c; sourceTree = ""; }; + 96AFAF3616C1E00A009DE44C /* ps3_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps3_ctx.c; sourceTree = ""; }; + 96AFAF3716C1E00A009DE44C /* sdl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_ctx.c; sourceTree = ""; }; + 96AFAF3816C1E00A009DE44C /* vc_egl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vc_egl_ctx.c; sourceTree = ""; }; + 96AFAF3916C1E00A009DE44C /* wgl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wgl_ctx.c; sourceTree = ""; }; + 96AFAF3A16C1E00A009DE44C /* x11_common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x11_common.c; sourceTree = ""; }; + 96AFAF3B16C1E00A009DE44C /* x11_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = x11_common.h; sourceTree = ""; }; + 96AFAF3C16C1E00A009DE44C /* xdk_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdk_ctx.c; sourceTree = ""; }; + 96AFAF3D16C1E00A009DE44C /* xegl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xegl_ctx.c; sourceTree = ""; }; + 96AFAF3F16C1E00A009DE44C /* config_file.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = config_file.hpp; sourceTree = ""; }; + 96AFAF4016C1E00A009DE44C /* d3d9.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = d3d9.cpp; sourceTree = ""; }; + 96AFAF4116C1E00A009DE44C /* d3d9.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = d3d9.hpp; sourceTree = ""; }; + 96AFAF4216C1E00A009DE44C /* render_chain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = render_chain.cpp; sourceTree = ""; }; + 96AFAF4316C1E00A009DE44C /* render_chain.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = render_chain.hpp; sourceTree = ""; }; + 96AFAF4516C1E00A009DE44C /* bitmap.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = bitmap.bin; sourceTree = ""; }; + 96AFAF4616C1E00A009DE44C /* bitmap.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = bitmap.bmp; sourceTree = ""; }; + 96AFAF4716C1E00A009DE44C /* bitmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bitmap.h; sourceTree = ""; }; + 96AFAF4816C1E00A009DE44C /* bitmapfont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bitmapfont.c; sourceTree = ""; }; + 96AFAF4916C1E00A009DE44C /* d3d_font.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = d3d_font.c; sourceTree = ""; }; + 96AFAF4A16C1E00A009DE44C /* d3d_font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = d3d_font.h; sourceTree = ""; }; + 96AFAF4B16C1E00A009DE44C /* fonts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fonts.c; sourceTree = ""; }; + 96AFAF4C16C1E00A009DE44C /* fonts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fonts.h; sourceTree = ""; }; + 96AFAF4D16C1E00A009DE44C /* freetype.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = freetype.c; sourceTree = ""; }; + 96AFAF4E16C1E00A009DE44C /* gl_font.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gl_font.c; sourceTree = ""; }; + 96AFAF4F16C1E00A009DE44C /* gl_font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gl_font.h; sourceTree = ""; }; + 96AFAF5016C1E00A009DE44C /* gl_raster_font.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gl_raster_font.c; sourceTree = ""; }; + 96AFAF5116C1E00A009DE44C /* ps_libdbgfont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps_libdbgfont.c; sourceTree = ""; }; + 96AFAF5216C1E00A009DE44C /* xdk1_xfonts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdk1_xfonts.c; sourceTree = ""; }; + 96AFAF5316C1E00A009DE44C /* xdk360_fonts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xdk360_fonts.cpp; sourceTree = ""; }; + 96AFAF5416C1E00A009DE44C /* gfx_common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gfx_common.c; sourceTree = ""; }; + 96AFAF5516C1E00A009DE44C /* gfx_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gfx_common.h; sourceTree = ""; }; + 96AFAF5616C1E00A009DE44C /* gfx_context.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gfx_context.c; sourceTree = ""; }; + 96AFAF5716C1E00A009DE44C /* gfx_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gfx_context.h; sourceTree = ""; }; + 96AFAF5816C1E00A009DE44C /* gl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gl.c; sourceTree = ""; }; + 96AFAF5916C1E00A009DE44C /* gl_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gl_common.h; sourceTree = ""; }; + 96AFAF5A16C1E00A009DE44C /* image.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = image.c; sourceTree = ""; }; + 96AFAF5B16C1E00A009DE44C /* image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = image.h; sourceTree = ""; }; + 96AFAF5D16C1E00A009DE44C /* matrix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = matrix.c; sourceTree = ""; }; + 96AFAF5E16C1E00A009DE44C /* matrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = matrix.h; sourceTree = ""; }; + 96AFAF5F16C1E00A009DE44C /* matrix_3x3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = matrix_3x3.c; sourceTree = ""; }; + 96AFAF6016C1E00A009DE44C /* matrix_3x3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = matrix_3x3.h; sourceTree = ""; }; + 96AFAF6116C1E00A009DE44C /* null.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = null.c; sourceTree = ""; }; + 96AFAF6316C1E00A009DE44C /* py_state.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = py_state.c; sourceTree = ""; }; + 96AFAF6416C1E00A009DE44C /* py_state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = py_state.h; sourceTree = ""; }; + 96AFAF6616C1E00A009DE44C /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 96AFAF6716C1E00A009DE44C /* rpng.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpng.c; sourceTree = ""; }; + 96AFAF6816C1E00A009DE44C /* rpng.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rpng.h; sourceTree = ""; }; + 96AFAF6916C1E00A009DE44C /* rpng_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpng_test.c; sourceTree = ""; }; + 96AFAF6B16C1E00A009DE44C /* filter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = filter.c; sourceTree = ""; }; + 96AFAF6C16C1E00A009DE44C /* filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = filter.h; sourceTree = ""; }; + 96AFAF6D16C1E00A009DE44C /* pixconv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pixconv.c; sourceTree = ""; }; + 96AFAF6E16C1E00A009DE44C /* pixconv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pixconv.h; sourceTree = ""; }; + 96AFAF6F16C1E00A009DE44C /* scaler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = scaler.c; sourceTree = ""; }; + 96AFAF7016C1E00A009DE44C /* scaler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scaler.h; sourceTree = ""; }; + 96AFAF7116C1E00A009DE44C /* scaler_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = scaler_int.c; sourceTree = ""; }; + 96AFAF7216C1E00A009DE44C /* scaler_int.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scaler_int.h; sourceTree = ""; }; + 96AFAF7316C1E00A009DE44C /* sdl_gfx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_gfx.c; sourceTree = ""; }; + 96AFAF7416C1E00A009DE44C /* shader_cg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = shader_cg.c; sourceTree = ""; }; + 96AFAF7516C1E00A009DE44C /* shader_cg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shader_cg.h; sourceTree = ""; }; + 96AFAF7616C1E00A009DE44C /* shader_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shader_common.h; sourceTree = ""; }; + 96AFAF7716C1E00A009DE44C /* shader_glsl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = shader_glsl.c; sourceTree = ""; }; + 96AFAF7816C1E00A009DE44C /* shader_glsl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shader_glsl.h; sourceTree = ""; }; + 96AFAF7916C1E00A009DE44C /* shader_hlsl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = shader_hlsl.c; sourceTree = ""; }; + 96AFAF7A16C1E00A009DE44C /* shader_hlsl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shader_hlsl.h; sourceTree = ""; }; + 96AFAF7B16C1E00A009DE44C /* state_tracker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = state_tracker.c; sourceTree = ""; }; + 96AFAF7C16C1E00A009DE44C /* state_tracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = state_tracker.h; sourceTree = ""; }; + 96AFAF7D16C1E00A009DE44C /* vg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vg.c; sourceTree = ""; }; + 96AFAF7E16C1E00A009DE44C /* xvideo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xvideo.c; sourceTree = ""; }; + 96AFAFC816C1FBC0009DE44C /* dinput.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dinput.c; sourceTree = ""; }; + 96AFAFC916C1FBC0009DE44C /* input_common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = input_common.c; sourceTree = ""; }; + 96AFAFCA16C1FBC0009DE44C /* input_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = input_common.h; sourceTree = ""; }; + 96AFAFCB16C1FBC0009DE44C /* linuxraw_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = linuxraw_input.c; sourceTree = ""; }; + 96AFAFCC16C1FBC0009DE44C /* linuxraw_joypad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = linuxraw_joypad.c; sourceTree = ""; }; + 96AFAFCD16C1FBC0009DE44C /* null.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = null.c; sourceTree = ""; }; + 96AFAFCE16C1FBC0009DE44C /* overlay.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = overlay.c; sourceTree = ""; }; + 96AFAFCF16C1FBC0009DE44C /* overlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = overlay.h; sourceTree = ""; }; + 96AFAFD016C1FBC0009DE44C /* sdl_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_input.c; sourceTree = ""; }; + 96AFAFD116C1FBC0009DE44C /* sdl_joypad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_joypad.c; sourceTree = ""; }; + 96AFAFD216C1FBC0009DE44C /* x11_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x11_input.c; sourceTree = ""; }; + 96AFAFDC16C2149A009DE44C /* ioseagl_ctx.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ioseagl_ctx.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 96AFAE2216C1D4EA009DE44C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 96AFAF2216C1DF88009DE44C /* libz.dylib in Frameworks */, + 96AFAF1F16C1DF0A009DE44C /* OpenAL.framework in Frameworks */, + 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */, + 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */, + 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */, + 96AFAE3016C1D4EA009DE44C /* GLKit.framework in Frameworks */, + 96AFAE3216C1D4EA009DE44C /* OpenGLES.framework in Frameworks */, + 968A572B16C2A06800BE12F8 /* libretro.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 96AFAE1A16C1D4EA009DE44C = { + isa = PBXGroup; + children = ( + 968A572816C2A06800BE12F8 /* test.img */, + 968A572916C2A06800BE12F8 /* libretro.a */, + 96AFAF2116C1DF88009DE44C /* libz.dylib */, + 96AFAF1E16C1DF0A009DE44C /* OpenAL.framework */, + 96AFAE9C16C1D976009DE44C /* core */, + 96AFAE3316C1D4EA009DE44C /* RetroArch */, + 96AFAE2816C1D4EA009DE44C /* Frameworks */, + 96AFAE2616C1D4EA009DE44C /* Products */, + ); + sourceTree = ""; + }; + 96AFAE2616C1D4EA009DE44C /* Products */ = { + isa = PBXGroup; + children = ( + 96AFAE2516C1D4EA009DE44C /* RetroArch.app */, + ); + name = Products; + sourceTree = ""; + }; + 96AFAE2816C1D4EA009DE44C /* Frameworks */ = { + isa = PBXGroup; + children = ( + 96AFAE2916C1D4EA009DE44C /* UIKit.framework */, + 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */, + 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */, + 96AFAE2F16C1D4EA009DE44C /* GLKit.framework */, + 96AFAE3116C1D4EA009DE44C /* OpenGLES.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 96AFAE3316C1D4EA009DE44C /* RetroArch */ = { + isa = PBXGroup; + children = ( + 96AFAE3C16C1D4EA009DE44C /* AppDelegate.h */, + 96AFAE3D16C1D4EA009DE44C /* AppDelegate.m */, + 96AFAE4916C1D4EA009DE44C /* ViewController.h */, + 96AFAE4C16C1D4EA009DE44C /* ViewController_iPhone.xib */, + 96AFAE4F16C1D4EA009DE44C /* ViewController_iPad.xib */, + 96AFAE3416C1D4EA009DE44C /* Supporting Files */, + ); + path = RetroArch; + sourceTree = ""; + }; + 96AFAE3416C1D4EA009DE44C /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 96AFAE3516C1D4EA009DE44C /* RetroArch-Info.plist */, + 96AFAE3616C1D4EA009DE44C /* InfoPlist.strings */, + 96AFAE3916C1D4EA009DE44C /* main.mm */, + 96AFAE3B16C1D4EA009DE44C /* RetroArch-Prefix.pch */, + 96AFAE3F16C1D4EA009DE44C /* Default.png */, + 96AFAE4116C1D4EA009DE44C /* Default@2x.png */, + 96AFAE4316C1D4EA009DE44C /* Default-568h@2x.png */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 96AFAE9C16C1D976009DE44C /* core */ = { + isa = PBXGroup; + children = ( + 96AFAFC716C1FBB3009DE44C /* input */, + 96AFAF3116C1E00A009DE44C /* gfx */, + 96AFAF2316C1DFC8009DE44C /* compat */, + 96AFAEE516C1DC73009DE44C /* audio */, + 96AFAEE016C1DBDB009DE44C /* conf */, + 96AFAE9D16C1D9A9009DE44C /* autosave.c */, + 96AFAE9E16C1D9A9009DE44C /* autosave.h */, + 96AFAE9F16C1D9A9009DE44C /* boolean.h */, + 96AFAEA016C1D9A9009DE44C /* cheats.c */, + 96AFAEA116C1D9A9009DE44C /* cheats.h */, + 96AFAEA216C1D9A9009DE44C /* command.c */, + 96AFAEA316C1D9A9009DE44C /* command.h */, + 96AFAEA416C1D9A9009DE44C /* config.def.h */, + 96AFAEA516C1D9A9009DE44C /* config.features.h */, + 96AFAEA616C1D9A9009DE44C /* driver_funcs.h */, + 96AFAEA716C1D9A9009DE44C /* driver.c */, + 96AFAEA816C1D9A9009DE44C /* driver.h */, + 96AFAEA916C1D9A9009DE44C /* dynamic.c */, + 96AFAEAA16C1D9A9009DE44C /* dynamic.h */, + 96AFAEAB16C1D9A9009DE44C /* fifo_buffer.c */, + 96AFAEAC16C1D9A9009DE44C /* fifo_buffer.h */, + 96AFAEAD16C1D9A9009DE44C /* file_extract.c */, + 96AFAEAE16C1D9A9009DE44C /* file_extract.h */, + 96AFAEAF16C1D9A9009DE44C /* file_path.c */, + 96AFAEB016C1D9A9009DE44C /* file.c */, + 96AFAEB116C1D9A9009DE44C /* file.h */, + 96AFAEB216C1D9A9009DE44C /* general.h */, + 96AFAEB316C1D9A9009DE44C /* hash.c */, + 96AFAEB416C1D9A9009DE44C /* hash.h */, + 96AFAEB516C1D9A9009DE44C /* libretro.h */, + 96AFAEB616C1D9A9009DE44C /* message.c */, + 96AFAEB716C1D9A9009DE44C /* message.h */, + 96AFAEB816C1D9A9009DE44C /* movie.c */, + 96AFAEB916C1D9A9009DE44C /* movie.h */, + 96AFAEBA16C1D9A9009DE44C /* netplay_compat.h */, + 96AFAEBB16C1D9A9009DE44C /* netplay.c */, + 96AFAEBC16C1D9A9009DE44C /* netplay.h */, + 96AFAEBD16C1D9A9009DE44C /* patch.c */, + 96AFAEBE16C1D9A9009DE44C /* patch.h */, + 96AFAEBF16C1D9A9009DE44C /* performance.c */, + 96AFAEC016C1D9A9009DE44C /* performance.h */, + 96AFAEC116C1D9A9009DE44C /* retroarch_logger.h */, + 96AFAEC216C1D9A9009DE44C /* retroarch.c */, + 96AFAEC316C1D9A9009DE44C /* rewind.c */, + 96AFAEC416C1D9A9009DE44C /* rewind.h */, + 96AFAEC516C1D9A9009DE44C /* screenshot.c */, + 96AFAEC616C1D9A9009DE44C /* screenshot.h */, + 96AFAEC716C1D9A9009DE44C /* settings.c */, + 96AFAEC816C1D9A9009DE44C /* thread.c */, + 96AFAEC916C1D9A9009DE44C /* thread.h */, + ); + name = core; + sourceTree = ""; + }; + 96AFAEE016C1DBDB009DE44C /* conf */ = { + isa = PBXGroup; + children = ( + 96AFAEE116C1DBDB009DE44C /* config_file.c */, + 96AFAEE216C1DBDB009DE44C /* config_file.h */, + 96AFAEE316C1DBDB009DE44C /* config_file_macros.h */, + ); + name = conf; + path = ../conf; + sourceTree = ""; + }; + 96AFAEE516C1DC73009DE44C /* audio */ = { + isa = PBXGroup; + children = ( + 96AFAEE616C1DC73009DE44C /* alsa.c */, + 96AFAEE716C1DC73009DE44C /* alsathread.c */, + 96AFAEE816C1DC73009DE44C /* coreaudio.c */, + 96AFAEE916C1DC73009DE44C /* dsound.c */, + 96AFAEEA16C1DC73009DE44C /* ext */, + 96AFAEEC16C1DC73009DE44C /* hermite.c */, + 96AFAEED16C1DC73009DE44C /* jack.c */, + 96AFAEEE16C1DC73009DE44C /* null.c */, + 96AFAEEF16C1DC73009DE44C /* openal.c */, + 96AFAEF016C1DC73009DE44C /* opensl.c */, + 96AFAEF116C1DC73009DE44C /* oss.c */, + 96AFAEF216C1DC73009DE44C /* pulse.c */, + 96AFAEF316C1DC73009DE44C /* resampler.h */, + 96AFAEF416C1DC73009DE44C /* roar.c */, + 96AFAEF516C1DC73009DE44C /* rsound.c */, + 96AFAEF616C1DC73009DE44C /* sdl_audio.c */, + 96AFAEF716C1DC73009DE44C /* sinc.c */, + 96AFAEF816C1DC73009DE44C /* sinc_neon.S */, + 96AFAEF916C1DC73009DE44C /* test */, + 96AFAEFD16C1DC73009DE44C /* utils.c */, + 96AFAEFE16C1DC73009DE44C /* utils.h */, + 96AFAEFF16C1DC73009DE44C /* utils_neon.S */, + 96AFAF0016C1DC73009DE44C /* xaudio-c */, + 96AFAF0416C1DC73009DE44C /* xaudio.c */, + ); + name = audio; + path = ../audio; + sourceTree = ""; + }; + 96AFAEEA16C1DC73009DE44C /* ext */ = { + isa = PBXGroup; + children = ( + 96AFAEEB16C1DC73009DE44C /* rarch_dsp.h */, + ); + path = ext; + sourceTree = ""; + }; + 96AFAEF916C1DC73009DE44C /* test */ = { + isa = PBXGroup; + children = ( + 96AFAEFA16C1DC73009DE44C /* main.c */, + 96AFAEFB16C1DC73009DE44C /* Makefile */, + 96AFAEFC16C1DC73009DE44C /* snr.c */, + ); + path = test; + sourceTree = ""; + }; + 96AFAF0016C1DC73009DE44C /* xaudio-c */ = { + isa = PBXGroup; + children = ( + 96AFAF0116C1DC73009DE44C /* xaudio-c.cpp */, + 96AFAF0216C1DC73009DE44C /* xaudio-c.h */, + 96AFAF0316C1DC73009DE44C /* xaudio.h */, + ); + path = "xaudio-c"; + sourceTree = ""; + }; + 96AFAF2316C1DFC8009DE44C /* compat */ = { + isa = PBXGroup; + children = ( + 96AFAF2416C1DFC8009DE44C /* compat.c */, + 96AFAF2516C1DFC8009DE44C /* getopt_rarch.h */, + 96AFAF2616C1DFC8009DE44C /* posix_string.h */, + 96AFAF2716C1DFC8009DE44C /* rxml */, + 96AFAF2C16C1DFC8009DE44C /* strl.h */, + ); + name = compat; + path = ../compat; + sourceTree = ""; + }; + 96AFAF2716C1DFC8009DE44C /* rxml */ = { + isa = PBXGroup; + children = ( + 96AFAF2816C1DFC8009DE44C /* Makefile */, + 96AFAF2916C1DFC8009DE44C /* rxml.c */, + 96AFAF2A16C1DFC8009DE44C /* rxml.h */, + 96AFAF2B16C1DFC8009DE44C /* rxml_test.c */, + ); + path = rxml; + sourceTree = ""; + }; + 96AFAF3116C1E00A009DE44C /* gfx */ = { + isa = PBXGroup; + children = ( + 96AFAF3216C1E00A009DE44C /* context */, + 96AFAF3E16C1E00A009DE44C /* d3d9 */, + 96AFAF4416C1E00A009DE44C /* fonts */, + 96AFAF5416C1E00A009DE44C /* gfx_common.c */, + 96AFAF5516C1E00A009DE44C /* gfx_common.h */, + 96AFAF5616C1E00A009DE44C /* gfx_context.c */, + 96AFAF5716C1E00A009DE44C /* gfx_context.h */, + 96AFAF5816C1E00A009DE44C /* gl.c */, + 96AFAF5916C1E00A009DE44C /* gl_common.h */, + 96AFAF5A16C1E00A009DE44C /* image.c */, + 96AFAF5B16C1E00A009DE44C /* image.h */, + 96AFAF5C16C1E00A009DE44C /* math */, + 96AFAF6116C1E00A009DE44C /* null.c */, + 96AFAF6216C1E00A009DE44C /* py_state */, + 96AFAF6516C1E00A009DE44C /* rpng */, + 96AFAF6A16C1E00A009DE44C /* scaler */, + 96AFAF7316C1E00A009DE44C /* sdl_gfx.c */, + 96AFAF7416C1E00A009DE44C /* shader_cg.c */, + 96AFAF7516C1E00A009DE44C /* shader_cg.h */, + 96AFAF7616C1E00A009DE44C /* shader_common.h */, + 96AFAF7716C1E00A009DE44C /* shader_glsl.c */, + 96AFAF7816C1E00A009DE44C /* shader_glsl.h */, + 96AFAF7916C1E00A009DE44C /* shader_hlsl.c */, + 96AFAF7A16C1E00A009DE44C /* shader_hlsl.h */, + 96AFAF7B16C1E00A009DE44C /* state_tracker.c */, + 96AFAF7C16C1E00A009DE44C /* state_tracker.h */, + 96AFAF7D16C1E00A009DE44C /* vg.c */, + 96AFAF7E16C1E00A009DE44C /* xvideo.c */, + ); + name = gfx; + path = ../gfx; + sourceTree = ""; + }; + 96AFAF3216C1E00A009DE44C /* context */ = { + isa = PBXGroup; + children = ( + 96AFAFDC16C2149A009DE44C /* ioseagl_ctx.m */, + 96AFAF3316C1E00A009DE44C /* androidegl_ctx.c */, + 96AFAF3416C1E00A009DE44C /* drm_egl_ctx.c */, + 96AFAF3516C1E00A009DE44C /* glx_ctx.c */, + 96AFAF3616C1E00A009DE44C /* ps3_ctx.c */, + 96AFAF3716C1E00A009DE44C /* sdl_ctx.c */, + 96AFAF3816C1E00A009DE44C /* vc_egl_ctx.c */, + 96AFAF3916C1E00A009DE44C /* wgl_ctx.c */, + 96AFAF3A16C1E00A009DE44C /* x11_common.c */, + 96AFAF3B16C1E00A009DE44C /* x11_common.h */, + 96AFAF3C16C1E00A009DE44C /* xdk_ctx.c */, + 96AFAF3D16C1E00A009DE44C /* xegl_ctx.c */, + ); + path = context; + sourceTree = ""; + }; + 96AFAF3E16C1E00A009DE44C /* d3d9 */ = { + isa = PBXGroup; + children = ( + 96AFAF3F16C1E00A009DE44C /* config_file.hpp */, + 96AFAF4016C1E00A009DE44C /* d3d9.cpp */, + 96AFAF4116C1E00A009DE44C /* d3d9.hpp */, + 96AFAF4216C1E00A009DE44C /* render_chain.cpp */, + 96AFAF4316C1E00A009DE44C /* render_chain.hpp */, + ); + path = d3d9; + sourceTree = ""; + }; + 96AFAF4416C1E00A009DE44C /* fonts */ = { + isa = PBXGroup; + children = ( + 96AFAF4516C1E00A009DE44C /* bitmap.bin */, + 96AFAF4616C1E00A009DE44C /* bitmap.bmp */, + 96AFAF4716C1E00A009DE44C /* bitmap.h */, + 96AFAF4816C1E00A009DE44C /* bitmapfont.c */, + 96AFAF4916C1E00A009DE44C /* d3d_font.c */, + 96AFAF4A16C1E00A009DE44C /* d3d_font.h */, + 96AFAF4B16C1E00A009DE44C /* fonts.c */, + 96AFAF4C16C1E00A009DE44C /* fonts.h */, + 96AFAF4D16C1E00A009DE44C /* freetype.c */, + 96AFAF4E16C1E00A009DE44C /* gl_font.c */, + 96AFAF4F16C1E00A009DE44C /* gl_font.h */, + 96AFAF5016C1E00A009DE44C /* gl_raster_font.c */, + 96AFAF5116C1E00A009DE44C /* ps_libdbgfont.c */, + 96AFAF5216C1E00A009DE44C /* xdk1_xfonts.c */, + 96AFAF5316C1E00A009DE44C /* xdk360_fonts.cpp */, + ); + path = fonts; + sourceTree = ""; + }; + 96AFAF5C16C1E00A009DE44C /* math */ = { + isa = PBXGroup; + children = ( + 96AFAF5D16C1E00A009DE44C /* matrix.c */, + 96AFAF5E16C1E00A009DE44C /* matrix.h */, + 96AFAF5F16C1E00A009DE44C /* matrix_3x3.c */, + 96AFAF6016C1E00A009DE44C /* matrix_3x3.h */, + ); + path = math; + sourceTree = ""; + }; + 96AFAF6216C1E00A009DE44C /* py_state */ = { + isa = PBXGroup; + children = ( + 96AFAF6316C1E00A009DE44C /* py_state.c */, + 96AFAF6416C1E00A009DE44C /* py_state.h */, + ); + path = py_state; + sourceTree = ""; + }; + 96AFAF6516C1E00A009DE44C /* rpng */ = { + isa = PBXGroup; + children = ( + 96AFAF6616C1E00A009DE44C /* Makefile */, + 96AFAF6716C1E00A009DE44C /* rpng.c */, + 96AFAF6816C1E00A009DE44C /* rpng.h */, + 96AFAF6916C1E00A009DE44C /* rpng_test.c */, + ); + path = rpng; + sourceTree = ""; + }; + 96AFAF6A16C1E00A009DE44C /* scaler */ = { + isa = PBXGroup; + children = ( + 96AFAF6B16C1E00A009DE44C /* filter.c */, + 96AFAF6C16C1E00A009DE44C /* filter.h */, + 96AFAF6D16C1E00A009DE44C /* pixconv.c */, + 96AFAF6E16C1E00A009DE44C /* pixconv.h */, + 96AFAF6F16C1E00A009DE44C /* scaler.c */, + 96AFAF7016C1E00A009DE44C /* scaler.h */, + 96AFAF7116C1E00A009DE44C /* scaler_int.c */, + 96AFAF7216C1E00A009DE44C /* scaler_int.h */, + ); + path = scaler; + sourceTree = ""; + }; + 96AFAFC716C1FBB3009DE44C /* input */ = { + isa = PBXGroup; + children = ( + 96AFAFC816C1FBC0009DE44C /* dinput.c */, + 96AFAFC916C1FBC0009DE44C /* input_common.c */, + 96AFAFCA16C1FBC0009DE44C /* input_common.h */, + 96AFAFCB16C1FBC0009DE44C /* linuxraw_input.c */, + 96AFAFCC16C1FBC0009DE44C /* linuxraw_joypad.c */, + 96AFAFCD16C1FBC0009DE44C /* null.c */, + 96AFAFCE16C1FBC0009DE44C /* overlay.c */, + 96AFAFCF16C1FBC0009DE44C /* overlay.h */, + 96AFAFD016C1FBC0009DE44C /* sdl_input.c */, + 96AFAFD116C1FBC0009DE44C /* sdl_joypad.c */, + 96AFAFD216C1FBC0009DE44C /* x11_input.c */, + ); + name = input; + path = ../input; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 96AFAE2416C1D4EA009DE44C /* RetroArch */ = { + isa = PBXNativeTarget; + buildConfigurationList = 96AFAE5416C1D4EA009DE44C /* Build configuration list for PBXNativeTarget "RetroArch" */; + buildPhases = ( + 96AFAE2116C1D4EA009DE44C /* Sources */, + 96AFAE2216C1D4EA009DE44C /* Frameworks */, + 96AFAE2316C1D4EA009DE44C /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RetroArch; + productName = RetroArch; + productReference = 96AFAE2516C1D4EA009DE44C /* RetroArch.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 96AFAE1C16C1D4EA009DE44C /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0450; + ORGANIZATIONNAME = RetroArch; + }; + buildConfigurationList = 96AFAE1F16C1D4EA009DE44C /* Build configuration list for PBXProject "RetroArch" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 96AFAE1A16C1D4EA009DE44C; + productRefGroup = 96AFAE2616C1D4EA009DE44C /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 96AFAE2416C1D4EA009DE44C /* RetroArch */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 96AFAE2316C1D4EA009DE44C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 96AFAE3816C1D4EA009DE44C /* InfoPlist.strings in Resources */, + 96AFAE4016C1D4EA009DE44C /* Default.png in Resources */, + 96AFAE4216C1D4EA009DE44C /* Default@2x.png in Resources */, + 96AFAE4416C1D4EA009DE44C /* Default-568h@2x.png in Resources */, + 96AFAE4E16C1D4EA009DE44C /* ViewController_iPhone.xib in Resources */, + 96AFAE5116C1D4EA009DE44C /* ViewController_iPad.xib in Resources */, + 968A572A16C2A06800BE12F8 /* test.img in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 96AFAE2116C1D4EA009DE44C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 96AFAE3A16C1D4EA009DE44C /* main.mm in Sources */, + 96AFAE3E16C1D4EA009DE44C /* AppDelegate.m in Sources */, + 96AFAECA16C1D9A9009DE44C /* autosave.c in Sources */, + 96AFAECB16C1D9A9009DE44C /* cheats.c in Sources */, + 96AFAECC16C1D9A9009DE44C /* command.c in Sources */, + 96AFAECD16C1D9A9009DE44C /* driver.c in Sources */, + 96AFAECE16C1D9A9009DE44C /* dynamic.c in Sources */, + 96AFAECF16C1D9A9009DE44C /* fifo_buffer.c in Sources */, + 96AFAED016C1D9A9009DE44C /* file_extract.c in Sources */, + 96AFAED116C1D9A9009DE44C /* file_path.c in Sources */, + 96AFAED216C1D9A9009DE44C /* file.c in Sources */, + 96AFAED316C1D9A9009DE44C /* hash.c in Sources */, + 96AFAED416C1D9A9009DE44C /* message.c in Sources */, + 96AFAED516C1D9A9009DE44C /* movie.c in Sources */, + 96AFAED716C1D9A9009DE44C /* patch.c in Sources */, + 96AFAED816C1D9A9009DE44C /* performance.c in Sources */, + 96AFAED916C1D9A9009DE44C /* retroarch.c in Sources */, + 96AFAEDA16C1D9A9009DE44C /* rewind.c in Sources */, + 96AFAEDB16C1D9A9009DE44C /* screenshot.c in Sources */, + 96AFAEDC16C1D9A9009DE44C /* settings.c in Sources */, + 96AFAEDD16C1D9A9009DE44C /* thread.c in Sources */, + 96AFAEE416C1DBDB009DE44C /* config_file.c in Sources */, + 96AFAF0B16C1DC73009DE44C /* null.c in Sources */, + 96AFAF1816C1DC73009DE44C /* utils.c in Sources */, + 96AFAF2016C1DF3A009DE44C /* openal.c in Sources */, + 96AFAF2D16C1DFC8009DE44C /* compat.c in Sources */, + 96AFAF2F16C1DFC8009DE44C /* rxml.c in Sources */, + 96AFAF8D16C1E00A009DE44C /* bitmapfont.c in Sources */, + 96AFAF8F16C1E00A009DE44C /* fonts.c in Sources */, + 96AFAF9116C1E00A009DE44C /* gl_font.c in Sources */, + 96AFAF9216C1E00A009DE44C /* gl_raster_font.c in Sources */, + 96AFAF9616C1E00A009DE44C /* gfx_common.c in Sources */, + 96AFAF9716C1E00A009DE44C /* gfx_context.c in Sources */, + 96AFAF9816C1E00A009DE44C /* gl.c in Sources */, + 96AFAF9916C1E00A009DE44C /* image.c in Sources */, + 96AFAF9A16C1E00A009DE44C /* matrix.c in Sources */, + 96AFAF9B16C1E00A009DE44C /* matrix_3x3.c in Sources */, + 96AFAF9C16C1E00A009DE44C /* null.c in Sources */, + 96AFAF9F16C1E00A009DE44C /* rpng.c in Sources */, + 96AFAFA116C1E00A009DE44C /* filter.c in Sources */, + 96AFAFA216C1E00A009DE44C /* pixconv.c in Sources */, + 96AFAFA316C1E00A009DE44C /* scaler.c in Sources */, + 96AFAFA416C1E00A009DE44C /* scaler_int.c in Sources */, + 96AFAFA716C1E00A009DE44C /* shader_glsl.c in Sources */, + 96AFAFAC16C1E279009DE44C /* state_tracker.c in Sources */, + 96AFAFAD16C1EEE9009DE44C /* sinc.c in Sources */, + 96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */, + 96AFAFD716C1FBC0009DE44C /* null.c in Sources */, + 96AFAFDD16C2149A009DE44C /* ioseagl_ctx.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 96AFAE3616C1D4EA009DE44C /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 96AFAE3716C1D4EA009DE44C /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 96AFAE4C16C1D4EA009DE44C /* ViewController_iPhone.xib */ = { + isa = PBXVariantGroup; + children = ( + 96AFAE4D16C1D4EA009DE44C /* en */, + ); + name = ViewController_iPhone.xib; + sourceTree = ""; + }; + 96AFAE4F16C1D4EA009DE44C /* ViewController_iPad.xib */ = { + isa = PBXVariantGroup; + children = ( + 96AFAE5016C1D4EA009DE44C /* en */, + ); + name = ViewController_iPad.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 96AFAE5216C1D4EA009DE44C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ../; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + ONLY_ACTIVE_ARCH = YES; + OTHER_CFLAGS = ( + "-DHAVE_GRIFFIN", + "-DIOS", + "-DHAVE_DYNAMIC", + "-DHAVE_OPENGL", + "-DHAVE_FBO", + "-DHAVE_OPENGLES", + "-DHAVE_VID_CONTEXT", + "-DHAVE_OPENGLES2", + "-DHAVE_GLSL", + "-DINLINE=inline", + "-DLSB_FIRST", + "-DHAVE_THREAD", + "-D__LIBRETRO__", + "-DRARCH_PERFORMANCE_MODE", + "-DPACKAGE_VERSION=\\\"1.0\\\"", + "-std=gnu99", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 96AFAE5316C1D4EA009DE44C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ../; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + OTHER_CFLAGS = ( + "-DNS_BLOCK_ASSERTIONS=1", + "-DNDEBUG", + "-DHAVE_GRIFFIN", + "-DIOS", + "-DHAVE_DYNAMIC", + "-DHAVE_OPENGL", + "-DHAVE_FBO", + "-DHAVE_OPENGLES", + "-DHAVE_VID_CONTEXT", + "-DHAVE_OPENGLES2", + "-DHAVE_GLSL", + "-DINLINE=inline", + "-DLSB_FIRST", + "-DHAVE_THREAD", + "-D__LIBRETRO__", + "-DRARCH_PERFORMANCE_MODE", + "-DPACKAGE_VERSION=\\\"1.0\\\"", + "-std=gnu99", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 96AFAE5516C1D4EA009DE44C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LIBRARY = "libstdc++"; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "RetroArch/RetroArch-Prefix.pch"; + INFOPLIST_FILE = "RetroArch/RetroArch-Info.plist"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)\"", + ); + OTHER_CFLAGS = ( + "-DHAVE_RARCH_MAIN_WRAP", + "-DIOS", + "-DHAVE_OPENGL", + "-DHAVE_FBO", + "-DHAVE_OPENGLES", + "-DHAVE_VID_CONTEXT", + "-DHAVE_OPENGLES2", + "-DHAVE_GLSL", + "-DINLINE=inline", + "-DLSB_FIRST", + "-DHAVE_THREAD", + "-D__LIBRETRO__", + "-DRARCH_PERFORMANCE_MODE", + "-DPACKAGE_VERSION=\\\"1.0\\\"", + "-DHAVE_AL", + "-DHAVE_NULLINPUT", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + 96AFAE5616C1D4EA009DE44C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LIBRARY = "libstdc++"; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "RetroArch/RetroArch-Prefix.pch"; + INFOPLIST_FILE = "RetroArch/RetroArch-Info.plist"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)\"", + ); + OTHER_CFLAGS = ( + "-DNS_BLOCK_ASSERTIONS=1", + "-DNDEBUG", + "-DHAVE_RARCH_MAIN_WRAP", + "-DIOS", + "-DHAVE_OPENGL", + "-DHAVE_OPENGLES", + "-DHAVE_VID_CONTEXT", + "-DHAVE_OPENGLES2", + "-DHAVE_GLSL", + "-DINLINE=inline", + "-DLSB_FIRST", + "-DHAVE_THREAD", + "-D__LIBRETRO__", + "-DRARCH_PERFORMANCE_MODE", + "-DPACKAGE_VERSION=\\\"1.0\\\"", + "-DHAVE_AL", + "-DHAVE_NULLINPUT", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 96AFAE1F16C1D4EA009DE44C /* Build configuration list for PBXProject "RetroArch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 96AFAE5216C1D4EA009DE44C /* Debug */, + 96AFAE5316C1D4EA009DE44C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 96AFAE5416C1D4EA009DE44C /* Build configuration list for PBXNativeTarget "RetroArch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 96AFAE5516C1D4EA009DE44C /* Debug */, + 96AFAE5616C1D4EA009DE44C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 96AFAE1C16C1D4EA009DE44C /* Project object */; +} diff --git a/ios/RetroArch.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/RetroArch.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..6bce578a7f --- /dev/null +++ b/ios/RetroArch.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/RetroArch/AppDelegate.h b/ios/RetroArch/AppDelegate.h new file mode 100644 index 0000000000..afcb44d684 --- /dev/null +++ b/ios/RetroArch/AppDelegate.h @@ -0,0 +1,18 @@ +// +// AppDelegate.h +// RetroArch +// +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +#import + +@class ViewController; + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + +@property (strong, nonatomic) ViewController *viewController; + +@end diff --git a/ios/RetroArch/AppDelegate.m b/ios/RetroArch/AppDelegate.m new file mode 100644 index 0000000000..001cd70399 --- /dev/null +++ b/ios/RetroArch/AppDelegate.m @@ -0,0 +1,70 @@ +// +// AppDelegate.m +// RetroArch +// +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +#import "AppDelegate.h" + +#import "ViewController.h" + +#include "general.h" + +@implementation AppDelegate + +- (void)runMain:(id)sender +{ + const char* filename = [[[NSBundle mainBundle] pathForResource:@"test" ofType:@"img"] UTF8String]; + + const char* argv[] = {"retroarch", filename, 0}; + if(rarch_main_init(2, argv) == 0) + { + while(rarch_main_iterate()); + } +} + + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + // Override point for customization after application launch. + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { + self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; + } else { + self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; + } + self.window.rootViewController = self.viewController; + [self.window makeKeyAndVisible]; + + [self performSelector:@selector(runMain:) withObject:nil afterDelay:0.2f]; +} + +- (void)applicationWillResignActive:(UIApplication *)application +{ + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application +{ + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application +{ + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application +{ + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application +{ + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/ios/RetroArch/Default-568h@2x.png b/ios/RetroArch/Default-568h@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0891b7aabfcf3422423b109c8beed2bab838c607 GIT binary patch literal 18594 zcmeI4X;f257Jx&9fS`ixvS;&$x8J@slQFSel)6zJN=?13FB7H(lQjRkSy8x_-S~tvu2gzn1oS+dLcF#eqtq$ z%tf9TTvX?`)R@}3uBI;jzS-=ZR-Td&MHaS&;!0?Ni*#$#`n*~CcQK)Q9vAQ~TUpnI!j)a2biYK^R)M~A5wUDZhx?ULMX z3x1P&qt=trOY6P2U67L=m=U?F|5#Uj(eCueNTZaHs_ceWiHeET+j+tp3Jt9g(ekqP z2WOvfR{qV+9r+o4J5?qK>7;;^+I7tGv-i)es$X_D=EoKF+S?zsyj^oRFElP}c}JT< zd8SUs-?O?}2YD#ngKbnHgzHBcboxK_2r9l(?eNCl-pEzkJm}fY?WC*jnS?VBE4EpY zO$fEejz6fU;W2Kl>JeQBZBl-%Irg`obSlg*@4QB;Dd1H7^Oi5wvt4d{RZ!8Og?^aE z)k0$1g+V3fd(gdQ3d&q2q-FL*uy#}|bc^=VhFsl0jBgUGJ+-s3U8MK9A!YJJMxpci z5hJ%|{DwV48fZn0{n5l$N_KcSb#NKE4plB`9I6Zt=Z!~-zw0{9tg$L&Ju1F0X)Cy8 zKF;(&lJ>x)Jw(=;p~sF(Sd9VWGwFE2rnyS9!f^DZ8+aCLq zQ};>lcJ1GDLqjm6Hd>|Eabno@P`~Bn(~6^aD_#yoEH(a?Nm1S<;S+hSxI5d16^<1lEM3NPFi zkqPrpL)+ zgnseFikg`gJVBha1&7C4;O6>h=dt~`ND+;Zd?W(4v2JIb7Pt>Td42%M-Ju-XAH#Pns762L}K3 zDhvsRqN0Ni(1UrishD2YvV?4*h2iFj$+&N||Fn$4n|^NSU+o?~jq`0jVQt8T9l{7b zXiwwODFh2V!Q6sqP9S>WH$oOf$N~=d0-bqTlD61!=`&0eAP-F>XN?*|gtOXX{ zQVTWyYo4ZK0GAw!GHf|pz9`D;-bbb*5LBX*{bnz|+)$@&P9|ORM2o?95{;ejvo&r- zq8cBhTN6nn)7~W>54U)%-F_-b?YKdfk5I8MHcuzBD5)!;yv#Z&R&^y=@=>VTIMy#r zX&U<=BsPkdqcMe<_}2+>H%XKyrr5ZR8_KVe>ZqYN z^=^~TFD};;rHJ$U;{~w^hYojl4hRI@SH$^K{YEo=sg)WY87r!*7blQK&qnpDo0`Vn zkl)9u9g=mCh&ZCJS(L4yN3k0kQ zuvg$h2KEEk51T+O0JQ+r0`R>g{jvqM0Mr6d3qUOZwE!?PI7HY@CE|dr sfw?Q;rAv?G4&^^8-z_>&sWXMxvD*gPOU4CBe-*@OtE+wfmVJNyHv)PfH~;_u literal 0 HcmV?d00001 diff --git a/ios/RetroArch/Default.png b/ios/RetroArch/Default.png new file mode 100644 index 0000000000000000000000000000000000000000..4c8ca6f693f96d511e9113c0eb59eec552354e42 GIT binary patch literal 6540 zcmeAS@N?(olHy`uVBq!ia0y~yU~~ZD2OMlbkt;o0To@QwR5G2N13aCb6#|O#(=u~X z85k@CTSM>X-wqM6>&y>YB4)1;;ojbLbbV-W^iFB1wa3^zCog^LCAReC4K0-?R_2{6 zrP*)4+_uWUy3w5N52M3PW_}MFMP9a~>YLvVZ1D_k*IMQ2QT^fwzoOb(*3gH$%aYWC zkHmcab=va2<#X%jakpJ;<1@F;k__#bwtC&%^D0v(FBh9K&$sK+<}2RJS609D)17$w ztdQP8(eLM8Ka}m_IQ@3wyMKP)l=oM4-?`YS_*P?4V_ORLPxsj&7Ju#kH;>6^Kp?T7~ zl+q?{UOOqV==?+d{=)5s|M~T1mwtH@+Z^$G&eEO9JNP^AX@3jZ*J*!!>lc|1-W%fA z@AOQpXZ_Lt>rxFXrGp*zLPiW@uo_c7C{As>j zWeX)wi+LTp_)@KYZCX{j;H?|1yXT4DnlS(Fr8gyP5|uaX_gLvaW0ScZdnG7o+u{T6 zFI-%d{ls*WuCDa5UJ@|RXv&ejZe}*BMkiWY51&pnRPw(hlykSzvj6e%mYz-GdvzBD zF10?szF_~!jS=?2HyQuPCvARXAe}C}WP|yQ*>5~~=*Nxq8+HHW1~FMDRCP^TcacKuk$ z(U#REVv)D!PhJ*ecH-ELFUrfyV&*)Z)>UCOuS?yd^L@Afk>ihynYPc{^CRwu+JHX+#$@YsC4c|l0tGigsn@jy) zXD($Ouk>H+V(Mr6NQT0S9BFM~V6nkj;1OBOz`zY;a|<&v%$g$sEJPk;hD4M^`1)8S z=jZArrsOB3>Q&?x097+E*i={nnYpPYi3%0DIeEoa6}C!X6;?ntNLXJ<0j#7X+g2&U zH$cHTzbI9~RL@Y)NXd>%K|#T$C?(A*$i)q+9mum)$|xx*u+rBrFE7_CH`dE9O4m2E zw6xSWFw!?N(gmu}Ew0QfNvzP#D^`XW0yD=YwK%ybv!En1KTiQ3|)OBHVcpi zp&D%TL4k-AsNfg_g$9~9p}$+4Ynr|VULLgiakg&)DD)EWO!OHC@snXr}UI${nVUP zpr1>Mf#G6^ng~;pt%^&NvQm>vU@-wn)!_JWN=(;B61LIDR86%A1?G9U(@`={MPdPF zbOKdd`R1o&rd7HmmZaJl85kPr8kp-EnTHsfS{ayIfdU*&4N@e5WSomq6HD@oLh|!- z?7;Dr3*ssm=^5w&a}>G?yzvAH17L|`#|6|0E4}QvA~xC{V_*wu2^AHZU}H9f($4F$btFf{}TLQXUhF5fht1@YV$^ z9BUdFV+73^nIsvRXRM40U}6b7z_6}kHbY}i1LK(xT@6Mi?F5GKBfbp|ZU-3BR*6kv zXcRSQ(0-)mprD+wTr)o_4I;(%zOu)+jEgNB)_SXCVoSa}|F?cfwR!69+L=W3IX z!UiU`0@ph%94Rb33Cpq^IY*r_8XBW%V>G9XmK&p`=xCiXTEmXEH%41uqixaAmicH0 zVYIt6!aI*K%s=kP-v##6IXGZ2Cama>{@)81;C?K-P&M2k<0!GL}5+H~XTq*@SQi|Ft z2*0X`$`8S!qO#)xBeJRkf?;t189=ZB6Imw-h=`q;FP(2UpWZvmJ@=k-@45M(dtb7r zyVEiaLk$=Vw#>zu;st}j6Jf9=m1+nXCFe!$1PrEZ%5Ze_ba8YX_9-*rJujiLuQmJo&2v+Cxes}ec zU|qeux&7*yz#W=X_|wGQskL7*OHNjwFs@sEC+64Hb$Z(#H21Gh$Pe2WzOubdr6fzg z{l{!k%OD?N5Z7j33SoK?YdV6Scm>})U+MIQLNRgIvkZQEc^mP9XBPg%y|S$~Br|;N zk?-!-(Qqh_mQ|6WINQ{hHAjBRV#O#!FkAJ+oxy`L#f8V45*VvWMJFBB5m zG6vOLtDvgoDjHlSq-*h5xM56O>Jjau2f2IxKItIb@coX4XTyf$^{LZG&lI|D95wN1 z!fo0)q>WV7-V;q|A?HR!*bgozJw%j98-~gwBKVV0;=hZIF>7oJSr2YjOWO*rSxz#& z;KXnDrJVZp;Yduiy1-H%s$ZFz6Q=x@$V_B@Tqwl?>6e;EHt|MiK<(#hXQMuj@Jseeh&eN{FxsQ$iw>D1aX1HMMlUbh?Z zmhY4eHffn5&LUbL_}o8|$JYz&$WFiLWmEg0ZPX+;W>@CxQz-%{E5+P7dH9&ey_y$R z@Zzje>2B%z!i!7Brqi{t5Y)~5>vpqRs~2aXD8DVE8vKl=`k(`duI1-k@?!pJ^HA6S zS;3WpuhjQHyoC>X>Xf8gze%_8^#+^RTV>V9&YPAWMjd~%xpSg?ON?kK^X*Pb(o8jR zz;DmaOWMMr6=M~K?MFx4_xDkARTxLJ@W@ohAx z5RD0jGgk?QL@H`VubD2k4}?VtB8@g`%hHBA$2pJ(gK5g1HMNysXEF_BNu-p!&+Qa8_APgopHWnRgg=TZZF*sXWTMQPD z!Q(Au5|+F;7M~`tWbsU98~NA{h0Y7%GB|t&n}w9OOABU4^X*V5xuN;rY(M#ouuqm) zyt!e?28fY!FgP?8GvBsMl_aM^UUVKiGFsleFN?t^<46kO#pF-cX0;sIOb(aM z)^jQgX^Z6pKA9mC@N)_aiHj9HxD2|?A@Y9B_h}(*v3%ek8CXc1Qy^jFPF&zrMa1OZ zSVaF{&ZY|(|H0XE&X>-XQz1`=fF2n@VKC_|h3jlKVM&-jmyMavllcYr`6LVtfq2ou zd+8zkkCB+2)rxq0Lkq_&Ad@g(O8;pAm96>tu79?81T@Z<;gm^3ZtPG-SR94Mr<3tm z9NrR3u*4I5aMlo(09g@8m_;%Rf+XiSa_KZao9n}7N0JrsV#;5Ucr+F*TTzQ8{%f3O zeIUy?WDS|-$LvMc@Z7320)tr}bfIka5hx9H;8H|%our=C+Do0CSFRWue14o5#r8v2 zw=|&r4*eMX%lgCV(ka?*j%H^UuP4LmBC(ON`)&7>NF-|PDRU{-7o`CU0HNbd&c~))@yl9IKu_ zXA+A-!khpP_yx=f#qt2_0ptmgBf4gF!{Y)MW6R$cC1d7@$Yb?+_j zYwfE^5_e`vhT zX=u3r>4$fsxP&apbm@Rcbyuc2T=giqZiMo9@9=oua6#YH0hO-1ak9^rJTPMM qY4Yr5Cu^v99p{E9VdroUHKlRW;M8#BJ^AOQE?e9wSHJo8(7yq;BYKSh literal 0 HcmV?d00001 diff --git a/ios/RetroArch/RetroArch-Info.plist b/ios/RetroArch/RetroArch-Info.plist new file mode 100644 index 0000000000..858508d759 --- /dev/null +++ b/ios/RetroArch/RetroArch-Info.plist @@ -0,0 +1,47 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + libretro.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/ios/RetroArch/RetroArch-Prefix.pch b/ios/RetroArch/RetroArch-Prefix.pch new file mode 100644 index 0000000000..7a94ed3c55 --- /dev/null +++ b/ios/RetroArch/RetroArch-Prefix.pch @@ -0,0 +1,14 @@ +// +// Prefix header for all source files of the 'RetroArch' target in the 'RetroArch' project +// + +#import + +#ifndef __IPHONE_5_0 +#warning "This project uses features only available in iOS SDK 5.0 and later." +#endif + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/ios/RetroArch/ViewController.h b/ios/RetroArch/ViewController.h new file mode 100644 index 0000000000..77f2dfafb3 --- /dev/null +++ b/ios/RetroArch/ViewController.h @@ -0,0 +1,13 @@ +// +// ViewController.h +// RetroArch +// +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +#import +#import + +@interface ViewController : UIViewController + +@end diff --git a/ios/RetroArch/en.lproj/InfoPlist.strings b/ios/RetroArch/en.lproj/InfoPlist.strings new file mode 100644 index 0000000000..477b28ff8f --- /dev/null +++ b/ios/RetroArch/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/ios/RetroArch/en.lproj/ViewController_iPad.xib b/ios/RetroArch/en.lproj/ViewController_iPad.xib new file mode 100644 index 0000000000..103cc68cb7 --- /dev/null +++ b/ios/RetroArch/en.lproj/ViewController_iPad.xib @@ -0,0 +1,112 @@ + + + + 1536 + 12A206j + 2519 + 1172.1 + 613.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 1856 + + + IBProxyObject + IBUIView + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + + IBFilesOwner + IBIPadFramework + + + IBFirstResponder + IBIPadFramework + + + + 274 + {{0, 20}, {768, 1004}} + + + + + 3 + MQA + + 2 + + + + 2 + + IBIPadFramework + + + + + + + view + + + + 3 + + + + + + 0 + + + + + + 1 + + + + + -1 + + + File's Owner + + + -2 + + + + + + + ViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + GLKView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + 3 + + + 0 + IBIPadFramework + YES + 3 + YES + 1856 + + diff --git a/ios/RetroArch/en.lproj/ViewController_iPhone.xib b/ios/RetroArch/en.lproj/ViewController_iPhone.xib new file mode 100644 index 0000000000..6b89ba8f0a --- /dev/null +++ b/ios/RetroArch/en.lproj/ViewController_iPhone.xib @@ -0,0 +1,127 @@ + + + + 1536 + 12A269 + 2835 + 1187 + 624.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 1919 + + + IBProxyObject + IBUIView + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + {320, 568} + + + + + 3 + MQA + + 2 + + + NO + + IBUIScreenMetrics + + YES + + + + + + {320, 568} + {568, 320} + + + IBCocoaTouchFramework + Retina 4 Full Screen + 2 + + IBCocoaTouchFramework + + + + + + + view + + + + 3 + + + + + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + + + + + ViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + GLKView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + 4 + + + 0 + IBCocoaTouchFramework + YES + 3 + YES + 1919 + + diff --git a/ios/RetroArch/main.mm b/ios/RetroArch/main.mm new file mode 100644 index 0000000000..5f122bee14 --- /dev/null +++ b/ios/RetroArch/main.mm @@ -0,0 +1,17 @@ +// +// main.m +// RetroArch +// +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +#import + +#import "AppDelegate.h" + +int main(int argc, char *argv[]) +{ + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/retroarch.c b/retroarch.c index 3c1dd6486c..58546bf090 100644 --- a/retroarch.c +++ b/retroarch.c @@ -45,7 +45,7 @@ #include "msvc/msvc_compat.h" #endif -#ifdef __APPLE__ +#if defined(__APPLE__) && !defined(IOS) #include "SDL.h" // OSX seems to really need -lSDLmain, // so we include SDL.h here so it can hack our main. From 6ab845b795b1037ef7d5068bfa94569ccadd8275 Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 6 Feb 2013 11:35:46 -0500 Subject: [PATCH 002/108] ios: Use dynamic loading; add clean up after rarch_main_iterate. --- ios/RetroArch.xcodeproj/project.pbxproj | 10 +++--- ios/RetroArch/AppDelegate.m | 46 ++++++++++++++++--------- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index c0ba76bca0..4083c2357a 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ 968A572A16C2A06800BE12F8 /* test.img in Resources */ = {isa = PBXBuildFile; fileRef = 968A572816C2A06800BE12F8 /* test.img */; }; - 968A572B16C2A06800BE12F8 /* libretro.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 968A572916C2A06800BE12F8 /* libretro.a */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -71,11 +70,11 @@ 96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFC916C1FBC0009DE44C /* input_common.c */; }; 96AFAFD716C1FBC0009DE44C /* null.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCD16C1FBC0009DE44C /* null.c */; }; 96AFAFDD16C2149A009DE44C /* ioseagl_ctx.m in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFDC16C2149A009DE44C /* ioseagl_ctx.m */; }; + 96CF014F16C2BB9E00ABF9C9 /* libretro.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 96CF014A16C2BA1900ABF9C9 /* libretro.dylib */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 968A572816C2A06800BE12F8 /* test.img */ = {isa = PBXFileReference; lastKnownFileType = file; path = test.img; sourceTree = ""; }; - 968A572916C2A06800BE12F8 /* libretro.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libretro.a; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -262,6 +261,7 @@ 96AFAFD116C1FBC0009DE44C /* sdl_joypad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_joypad.c; sourceTree = ""; }; 96AFAFD216C1FBC0009DE44C /* x11_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x11_input.c; sourceTree = ""; }; 96AFAFDC16C2149A009DE44C /* ioseagl_ctx.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ioseagl_ctx.m; sourceTree = ""; }; + 96CF014A16C2BA1900ABF9C9 /* libretro.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libretro.dylib; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -276,7 +276,6 @@ 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */, 96AFAE3016C1D4EA009DE44C /* GLKit.framework in Frameworks */, 96AFAE3216C1D4EA009DE44C /* OpenGLES.framework in Frameworks */, - 968A572B16C2A06800BE12F8 /* libretro.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -286,8 +285,8 @@ 96AFAE1A16C1D4EA009DE44C = { isa = PBXGroup; children = ( + 96CF014A16C2BA1900ABF9C9 /* libretro.dylib */, 968A572816C2A06800BE12F8 /* test.img */, - 968A572916C2A06800BE12F8 /* libretro.a */, 96AFAF2116C1DF88009DE44C /* libz.dylib */, 96AFAF1E16C1DF0A009DE44C /* OpenAL.framework */, 96AFAE9C16C1D976009DE44C /* core */, @@ -708,6 +707,7 @@ 96AFAE4E16C1D4EA009DE44C /* ViewController_iPhone.xib in Resources */, 96AFAE5116C1D4EA009DE44C /* ViewController_iPad.xib in Resources */, 968A572A16C2A06800BE12F8 /* test.img in Resources */, + 96CF014F16C2BB9E00ABF9C9 /* libretro.dylib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -919,6 +919,7 @@ "-DPACKAGE_VERSION=\\\"1.0\\\"", "-DHAVE_AL", "-DHAVE_NULLINPUT", + "-DHAVE_DYNAMIC", ); PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; @@ -954,6 +955,7 @@ "-DPACKAGE_VERSION=\\\"1.0\\\"", "-DHAVE_AL", "-DHAVE_NULLINPUT", + "-DHAVE_DYNAMIC", ); PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; diff --git a/ios/RetroArch/AppDelegate.m b/ios/RetroArch/AppDelegate.m index 001cd70399..250fc1942b 100644 --- a/ios/RetroArch/AppDelegate.m +++ b/ios/RetroArch/AppDelegate.m @@ -15,29 +15,41 @@ - (void)runMain:(id)sender { - const char* filename = [[[NSBundle mainBundle] pathForResource:@"test" ofType:@"img"] UTF8String]; + const char* filename = [[[NSBundle mainBundle] pathForResource:@"test" ofType:@"img"] UTF8String]; + const char* libretro = [[[NSBundle mainBundle] pathForResource:@"libretro" ofType:@"dylib"] UTF8String]; - const char* argv[] = {"retroarch", filename, 0}; - if(rarch_main_init(2, argv) == 0) - { - while(rarch_main_iterate()); - } + printf("%s\n", libretro); + + const char* argv[] = {"retroarch", "-L", libretro, filename, 0}; + if (rarch_main_init(4, (char**)argv) == 0) + { + rarch_init_msg_queue(); + while (rarch_main_iterate()); + rarch_main_deinit(); + rarch_deinit_msg_queue(); + +#ifdef PERF_TEST + rarch_perf_log(); +#endif + + rarch_main_clear_state(); + } } - - (void)applicationDidFinishLaunching:(UIApplication *)application { - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - // Override point for customization after application launch. - if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { - self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; - } else { - self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; - } - self.window.rootViewController = self.viewController; - [self.window makeKeyAndVisible]; + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - [self performSelector:@selector(runMain:) withObject:nil afterDelay:0.2f]; + // Override point for customization after application launch. + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) + self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; + else + self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; + + self.window.rootViewController = self.viewController; + [self.window makeKeyAndVisible]; + + [self performSelector:@selector(runMain:) withObject:nil afterDelay:0.2f]; } - (void)applicationWillResignActive:(UIApplication *)application From 1d727e50e755114da7f323795eb5c48d69afa98a Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 6 Feb 2013 13:10:07 -0500 Subject: [PATCH 003/108] ios: Will load a file named 'overlay.cfg' stored in the bundles root directory. --- ios/RetroArch.xcodeproj/project.pbxproj | 8 +++++++- ios/RetroArch/AppDelegate.m | 24 +++++++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 4083c2357a..3e64c0ea4e 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -71,6 +71,7 @@ 96AFAFD716C1FBC0009DE44C /* null.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCD16C1FBC0009DE44C /* null.c */; }; 96AFAFDD16C2149A009DE44C /* ioseagl_ctx.m in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFDC16C2149A009DE44C /* ioseagl_ctx.m */; }; 96CF014F16C2BB9E00ABF9C9 /* libretro.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 96CF014A16C2BA1900ABF9C9 /* libretro.dylib */; }; + 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCE16C1FBC0009DE44C /* overlay.c */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -635,8 +636,8 @@ children = ( 96AFAFC816C1FBC0009DE44C /* dinput.c */, 96AFAFC916C1FBC0009DE44C /* input_common.c */, - 96AFAFCA16C1FBC0009DE44C /* input_common.h */, 96AFAFCB16C1FBC0009DE44C /* linuxraw_input.c */, + 96AFAFCA16C1FBC0009DE44C /* input_common.h */, 96AFAFCC16C1FBC0009DE44C /* linuxraw_joypad.c */, 96AFAFCD16C1FBC0009DE44C /* null.c */, 96AFAFCE16C1FBC0009DE44C /* overlay.c */, @@ -767,6 +768,7 @@ 96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */, 96AFAFD716C1FBC0009DE44C /* null.c in Sources */, 96AFAFDD16C2149A009DE44C /* ioseagl_ctx.m in Sources */, + 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -920,6 +922,8 @@ "-DHAVE_AL", "-DHAVE_NULLINPUT", "-DHAVE_DYNAMIC", + "-DHAVE_OVERLAY", + "-DHAVE_ZLIB", ); PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; @@ -956,6 +960,8 @@ "-DHAVE_AL", "-DHAVE_NULLINPUT", "-DHAVE_DYNAMIC", + "-DHAVE_OVERLAY", + "-DHAVE_ZLIB", ); PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; diff --git a/ios/RetroArch/AppDelegate.m b/ios/RetroArch/AppDelegate.m index 250fc1942b..2cf0f201bc 100644 --- a/ios/RetroArch/AppDelegate.m +++ b/ios/RetroArch/AppDelegate.m @@ -13,15 +13,33 @@ @implementation AppDelegate +- (const char*)generate_config +{ + const char* overlay = [[[NSBundle mainBundle] pathForResource:@"overlay" ofType:@"cfg"] UTF8String]; + const char* config = [[NSTemporaryDirectory() stringByAppendingPathComponent: @"retroarch.cfg"] UTF8String]; + + FILE* config_file = fopen(config, "wb"); + + if (config_file) + { + if (overlay) fprintf(config_file, "input_overlay = \"%s\"\n", overlay); + fclose(config_file); + return config; + } + + return 0; +} + - (void)runMain:(id)sender { const char* filename = [[[NSBundle mainBundle] pathForResource:@"test" ofType:@"img"] UTF8String]; const char* libretro = [[[NSBundle mainBundle] pathForResource:@"libretro" ofType:@"dylib"] UTF8String]; + const char* config_file = [self generate_config]; - printf("%s\n", libretro); + if (!config_file) return; - const char* argv[] = {"retroarch", "-L", libretro, filename, 0}; - if (rarch_main_init(4, (char**)argv) == 0) + const char* argv[] = {"retroarch", "-L", libretro, "-c", config_file, filename, 0}; + if (rarch_main_init(6, (char**)argv) == 0) { rarch_init_msg_queue(); while (rarch_main_iterate()); From 7e4e028fc86ed92b44004ab2234ace96d8989053 Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 6 Feb 2013 18:23:11 -0500 Subject: [PATCH 004/108] ios: Add a simple input driver draft; tracks only one touch for now. --- config.def.h | 3 + driver.c | 3 + driver.h | 1 + ios/RetroArch.xcodeproj/project.pbxproj | 6 +- ios/RetroArch/AppDelegate.m | 38 +++++++++++ ios/RetroArch/ios_input.c | 83 +++++++++++++++++++++++++ settings.c | 2 + 7 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 ios/RetroArch/ios_input.c diff --git a/config.def.h b/config.def.h index c3e7aa26d4..228befb46c 100644 --- a/config.def.h +++ b/config.def.h @@ -72,6 +72,7 @@ enum INPUT_WII, INPUT_XINPUT, INPUT_LINUXRAW, + INPUT_IOS, INPUT_NULL }; @@ -157,6 +158,8 @@ enum #define INPUT_DEFAULT_DRIVER INPUT_WII #elif defined(HAVE_XVIDEO) #define INPUT_DEFAULT_DRIVER INPUT_X +#elif defined(IOS) +#define INPUT_DEFAULT_DRIVER INPUT_IOS #else #define INPUT_DEFAULT_DRIVER INPUT_NULL #endif diff --git a/driver.c b/driver.c index 17369e1968..636579e7cc 100644 --- a/driver.c +++ b/driver.c @@ -150,6 +150,9 @@ static const input_driver_t *input_drivers[] = { #if defined(__linux__) && !defined(ANDROID) &input_linuxraw, #endif +#ifdef IOS + &input_ios, +#endif #ifdef HAVE_NULLINPUT &input_null, #endif diff --git a/driver.h b/driver.h index 580999e379..864b716f95 100644 --- a/driver.h +++ b/driver.h @@ -373,6 +373,7 @@ extern const input_driver_t input_xenon360; extern const input_driver_t input_gx; extern const input_driver_t input_xinput; extern const input_driver_t input_linuxraw; +extern const input_driver_t input_ios; extern const input_driver_t input_null; #include "driver_funcs.h" diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 3e64c0ea4e..d5f70c00b2 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -72,6 +72,7 @@ 96AFAFDD16C2149A009DE44C /* ioseagl_ctx.m in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFDC16C2149A009DE44C /* ioseagl_ctx.m */; }; 96CF014F16C2BB9E00ABF9C9 /* libretro.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 96CF014A16C2BA1900ABF9C9 /* libretro.dylib */; }; 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCE16C1FBC0009DE44C /* overlay.c */; }; + 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CF015B16C2F72900ABF9C9 /* ios_input.c */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -263,6 +264,7 @@ 96AFAFD216C1FBC0009DE44C /* x11_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x11_input.c; sourceTree = ""; }; 96AFAFDC16C2149A009DE44C /* ioseagl_ctx.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ioseagl_ctx.m; sourceTree = ""; }; 96CF014A16C2BA1900ABF9C9 /* libretro.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libretro.dylib; sourceTree = ""; }; + 96CF015B16C2F72900ABF9C9 /* ios_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ios_input.c; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -326,6 +328,7 @@ 96AFAE4C16C1D4EA009DE44C /* ViewController_iPhone.xib */, 96AFAE4F16C1D4EA009DE44C /* ViewController_iPad.xib */, 96AFAE3416C1D4EA009DE44C /* Supporting Files */, + 96CF015B16C2F72900ABF9C9 /* ios_input.c */, ); path = RetroArch; sourceTree = ""; @@ -769,6 +772,7 @@ 96AFAFD716C1FBC0009DE44C /* null.c in Sources */, 96AFAFDD16C2149A009DE44C /* ioseagl_ctx.m in Sources */, 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */, + 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -920,7 +924,6 @@ "-DRARCH_PERFORMANCE_MODE", "-DPACKAGE_VERSION=\\\"1.0\\\"", "-DHAVE_AL", - "-DHAVE_NULLINPUT", "-DHAVE_DYNAMIC", "-DHAVE_OVERLAY", "-DHAVE_ZLIB", @@ -958,7 +961,6 @@ "-DRARCH_PERFORMANCE_MODE", "-DPACKAGE_VERSION=\\\"1.0\\\"", "-DHAVE_AL", - "-DHAVE_NULLINPUT", "-DHAVE_DYNAMIC", "-DHAVE_OVERLAY", "-DHAVE_ZLIB", diff --git a/ios/RetroArch/AppDelegate.m b/ios/RetroArch/AppDelegate.m index 2cf0f201bc..ef08051c61 100644 --- a/ios/RetroArch/AppDelegate.m +++ b/ios/RetroArch/AppDelegate.m @@ -11,6 +11,13 @@ #include "general.h" + +extern bool IOS_is_down; +extern int16_t IOS_touch_x, IOS_fix_x; +extern int16_t IOS_touch_y, IOS_fix_y; +extern int16_t IOS_full_x, IOS_full_y; + + @implementation AppDelegate - (const char*)generate_config @@ -70,6 +77,36 @@ [self performSelector:@selector(runMain:) withObject:nil afterDelay:0.2f]; } +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + UITouch *touch = [[event allTouches] anyObject]; + CGPoint coord = [touch locationInView:self.viewController.view]; + + IOS_is_down = true; + IOS_touch_x = coord.x; + IOS_touch_y = coord.y; +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + UITouch *touch = [[event allTouches] anyObject]; + CGPoint coord = [touch locationInView:self.viewController.view]; + + IOS_is_down = true; + IOS_touch_x = coord.x; + IOS_touch_y = coord.y; +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + IOS_is_down = false; +} + +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ + IOS_is_down = false; +} + - (void)applicationWillResignActive:(UIApplication *)application { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. @@ -98,3 +135,4 @@ } @end + diff --git a/ios/RetroArch/ios_input.c b/ios/RetroArch/ios_input.c new file mode 100644 index 0000000000..05f99cd687 --- /dev/null +++ b/ios/RetroArch/ios_input.c @@ -0,0 +1,83 @@ +// Input Driver Below +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2013 - Hans-Kristian Arntzen + * Copyright (C) 2011-2013 - Daniel De Matteis + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#include +#include "../../input/input_common.h" +#include "../../performance.h" +#include "../../general.h" +#include "../../driver.h" + +#define MAX_TOUCH 16 + +bool IOS_is_down; +int16_t IOS_touch_x, IOS_fix_x; +int16_t IOS_touch_y, IOS_fix_y; +int16_t IOS_full_x, IOS_full_y; + +static void *ios_input_init(void) +{ + return (void*)-1; +} + +static void ios_input_poll(void *data) +{ + input_translate_coord_viewport(IOS_touch_x, IOS_touch_y, + &IOS_fix_x, &IOS_fix_y, + &IOS_full_x, &IOS_full_y); +} + +static int16_t ios_input_state(void *data, const struct retro_keybind **binds, unsigned port, unsigned device, unsigned index, unsigned id) +{ + if (index != 0) return 0; + switch (device) + { + case RARCH_DEVICE_POINTER_SCREEN: + switch (id) + { + case RETRO_DEVICE_ID_POINTER_X: + return IOS_full_x; + case RETRO_DEVICE_ID_POINTER_Y: + return IOS_full_y; + case RETRO_DEVICE_ID_POINTER_PRESSED: + return IOS_is_down; + default: + return 0; + } + default: + return 0; + } +} + +static bool ios_input_key_pressed(void *data, int key) +{ + return false; +} + +static void ios_input_free_input(void *data) +{ + (void)data; +} + +const input_driver_t input_ios = { + ios_input_init, + ios_input_poll, + ios_input_state, + ios_input_key_pressed, + ios_input_free_input, + "ios_input", +}; + diff --git a/settings.c b/settings.c index b57f2b84ed..1de569b709 100644 --- a/settings.c +++ b/settings.c @@ -130,6 +130,8 @@ const char *config_get_default_input(void) return "gx"; case INPUT_LINUXRAW: return "linuxraw"; + case INPUT_IOS: + return "ios_input"; case INPUT_NULL: return "null"; default: From 7b9490db48d8f4a4668bd6370abbe4a2bc22961c Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 6 Feb 2013 20:48:32 -0500 Subject: [PATCH 005/108] ios: Fix size on retina screens; 'improve' life cycle management. --- gfx/context/ioseagl_ctx.m | 8 ++--- ios/RetroArch/AppDelegate.m | 64 +++++++++++++++++++++++++++++-------- 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/gfx/context/ioseagl_ctx.m b/gfx/context/ioseagl_ctx.m index 85c3c0f4bc..b82a4ac19f 100644 --- a/gfx/context/ioseagl_ctx.m +++ b/gfx/context/ioseagl_ctx.m @@ -29,6 +29,7 @@ #import "../../ios/RetroArch/ViewController.h" static GLKView *gl_view; +static float screen_scale; // Objective-C interface used to interact with the GLES context and display. @interface ViewController () @@ -50,6 +51,7 @@ static GLKView *gl_view; [EAGLContext setCurrentContext:self.context]; gl_view = self.view; + screen_scale = [[UIScreen mainScreen] scale]; } - (void)dealloc @@ -73,8 +75,8 @@ static void gfx_ctx_destroy(void) static void gfx_ctx_get_video_size(unsigned *width, unsigned *height) { - *width = gl_view.bounds.size.width; - *height = gl_view.bounds.size.height; + *width = gl_view.bounds.size.width * screen_scale; + *height = gl_view.bounds.size.height * screen_scale; } static bool gfx_ctx_init(void) @@ -95,8 +97,6 @@ static void gfx_ctx_check_window(bool *quit, *quit = false; - while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE) == kCFRunLoopRunHandledSource); - unsigned new_width, new_height; gfx_ctx_get_video_size(&new_width, &new_height); if (new_width != *width || new_height != *height) diff --git a/ios/RetroArch/AppDelegate.m b/ios/RetroArch/AppDelegate.m index ef08051c61..c1604507bb 100644 --- a/ios/RetroArch/AppDelegate.m +++ b/ios/RetroArch/AppDelegate.m @@ -19,6 +19,11 @@ extern int16_t IOS_full_x, IOS_full_y; @implementation AppDelegate +{ + BOOL ra_initialized; + BOOL ra_paused; + BOOL ra_done; +} - (const char*)generate_config { @@ -37,19 +42,42 @@ extern int16_t IOS_full_x, IOS_full_y; return 0; } -- (void)runMain:(id)sender +- (void)schedule_iterate +{ + if (ra_initialized && !ra_paused && !ra_done) + { + [self performSelector:@selector(rarch_iterate:) withObject:nil afterDelay:0.002f]; + } +} + +- (void)rarch_init { const char* filename = [[[NSBundle mainBundle] pathForResource:@"test" ofType:@"img"] UTF8String]; const char* libretro = [[[NSBundle mainBundle] pathForResource:@"libretro" ofType:@"dylib"] UTF8String]; const char* config_file = [self generate_config]; - if (!config_file) return; + if(!config_file) return; const char* argv[] = {"retroarch", "-L", libretro, "-c", config_file, filename, 0}; if (rarch_main_init(6, (char**)argv) == 0) { rarch_init_msg_queue(); - while (rarch_main_iterate()); + ra_initialized = TRUE; + } +} + +- (void)rarch_iterate:(id)sender +{ + if (!ra_paused && ra_initialized && !ra_done) + ra_done = !rarch_main_iterate(); + + [self schedule_iterate]; +} + +- (void)rarch_deinit +{ + if (ra_initialized) + { rarch_main_deinit(); rarch_deinit_msg_queue(); @@ -59,10 +87,16 @@ extern int16_t IOS_full_x, IOS_full_y; rarch_main_clear_state(); } + + ra_initialized = FALSE; } - (void)applicationDidFinishLaunching:(UIApplication *)application { + ra_paused = NO; + ra_done = NO; + ra_initialized = NO; + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. @@ -73,18 +107,20 @@ extern int16_t IOS_full_x, IOS_full_y; self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; - - [self performSelector:@selector(runMain:) withObject:nil afterDelay:0.2f]; + + [self rarch_init]; + [self performSelector:@selector(rarch_iterate:) withObject:nil afterDelay:1]; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [[event allTouches] anyObject]; CGPoint coord = [touch locationInView:self.viewController.view]; + float scale = [[UIScreen mainScreen] scale]; IOS_is_down = true; - IOS_touch_x = coord.x; - IOS_touch_y = coord.y; + IOS_touch_x = coord.x * scale; + IOS_touch_y = coord.y * scale; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event @@ -109,29 +145,29 @@ extern int16_t IOS_full_x, IOS_full_y; - (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + ra_paused = YES; } - (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + ra_paused = YES; } - (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + if (ra_paused) + { + ra_paused = NO; + [self schedule_iterate]; + } } - (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } @end From 8315a05f5fc9de0f2d75255149fe9b9c5f86cd51 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 7 Feb 2013 08:47:35 -0500 Subject: [PATCH 006/108] ios: Add incomplete code for basic directory list. --- ios/RetroArch.xcodeproj/project.pbxproj | 6 + ios/RetroArch/dirlist.h | 12 ++ ios/RetroArch/dirlist.m | 140 ++++++++++++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 ios/RetroArch/dirlist.h create mode 100644 ios/RetroArch/dirlist.m diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index d5f70c00b2..b5c4f94bcc 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 9629797716C3CD2400E6DCE0 /* dirlist.m in Sources */ = {isa = PBXBuildFile; fileRef = 9629797616C3CD2400E6DCE0 /* dirlist.m */; }; 968A572A16C2A06800BE12F8 /* test.img in Resources */ = {isa = PBXBuildFile; fileRef = 968A572816C2A06800BE12F8 /* test.img */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; @@ -76,6 +77,8 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 9629797516C3CD2400E6DCE0 /* dirlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dirlist.h; sourceTree = ""; }; + 9629797616C3CD2400E6DCE0 /* dirlist.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = dirlist.m; sourceTree = ""; }; 968A572816C2A06800BE12F8 /* test.img */ = {isa = PBXFileReference; lastKnownFileType = file; path = test.img; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; @@ -329,6 +332,8 @@ 96AFAE4F16C1D4EA009DE44C /* ViewController_iPad.xib */, 96AFAE3416C1D4EA009DE44C /* Supporting Files */, 96CF015B16C2F72900ABF9C9 /* ios_input.c */, + 9629797516C3CD2400E6DCE0 /* dirlist.h */, + 9629797616C3CD2400E6DCE0 /* dirlist.m */, ); path = RetroArch; sourceTree = ""; @@ -773,6 +778,7 @@ 96AFAFDD16C2149A009DE44C /* ioseagl_ctx.m in Sources */, 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */, 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */, + 9629797716C3CD2400E6DCE0 /* dirlist.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/dirlist.h b/ios/RetroArch/dirlist.h new file mode 100644 index 0000000000..3c4e58cf60 --- /dev/null +++ b/ios/RetroArch/dirlist.h @@ -0,0 +1,12 @@ +// +// UIViewController_m.h +// RetroArch +// +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +#import + +@interface DirectoryView : UIViewController + +@end diff --git a/ios/RetroArch/dirlist.m b/ios/RetroArch/dirlist.m new file mode 100644 index 0000000000..2f4169d311 --- /dev/null +++ b/ios/RetroArch/dirlist.m @@ -0,0 +1,140 @@ +// +// dirlist.m +// RetroArch +// +// Created by Jason Fetters on 2/7/13. +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +#include +#import "dirlist.h" + +struct dirent_list +{ + struct dirent_list* next; + struct dirent entry; +}; + +const struct dirent* get_dirent_at_index(struct dirent_list* list, unsigned index) +{ + while (list && index) + { + list = list->next; + index --; + } + + return list ? &list->entry : 0; +} + +unsigned get_dirent_list_count(struct dirent_list* list) +{ + unsigned result = 0; + + while (list) + { + result ++; + list = list->next; + } + + return result; +} + +void free_dirent_list(struct dirent_list* list) +{ + struct dirent_list* next = 0; + if (list) + { + next = list->next; + free(list); + } + + free_dirent_list(next); +} + +struct dirent_list* build_dirent_list(const char* path) +{ + struct dirent_list* result = 0; + struct dirent_list* iterate = 0; + + DIR* dir = opendir(path); + if (dir) + { + struct dirent* ent = 0; + while ((ent = readdir(dir))) + { + if (!iterate) + { + iterate = malloc(sizeof(struct dirent_list)); + iterate->next = 0; + result = iterate; + } + else + { + iterate->next = malloc(sizeof(struct dirent_list)); + iterate = iterate->next; + iterate->next = 0; + } + + memcpy(&iterate->entry, ent, sizeof(struct dirent)); + } + + closedir(dir); + } + + return result; +} + +@implementation DirectoryView +{ + UITableView* table; + struct dirent_list* files; +}; + +-(void)dealloc +{ + free_dirent_list(files); + files = 0; + + // Do I need to kill table here? +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + files = build_dirent_list([NSTemporaryDirectory() UTF8String]); + + table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) style:UITableViewStylePlain]; + table.dataSource = self; + table.delegate = self; + + self.view = table; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + const struct dirent* item = get_dirent_at_index(files, indexPath.row); +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return get_dirent_list_count(files); +} + +- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell* cell = [table dequeueReusableCellWithIdentifier:@"path"]; + cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"path"]; + + const struct dirent* item = get_dirent_at_index(files, indexPath.row); + + if (item) + { + cell.textLabel.text = [[NSString string] initWithUTF8String:item->d_name]; + cell.accessoryType = (item->d_type & DT_DIR) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; + } + + return cell; +} + +@end From ec51c819a39e96d0bb4715aad88d71f3494b8122 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 7 Feb 2013 08:58:36 -0500 Subject: [PATCH 007/108] ios: Change ioseagl_ctx to a C file that uses external functions to interact with obj-c. --- gfx/context/{ioseagl_ctx.m => ioseagl_ctx.c} | 44 ++----------- ios/RetroArch.xcodeproj/project.pbxproj | 16 +++-- ios/RetroArch/AppDelegate.h | 2 +- ios/RetroArch/AppDelegate.m | 6 +- .../{ViewController.h => gameview.h} | 2 +- ios/RetroArch/gameview.m | 61 +++++++++++++++++++ 6 files changed, 80 insertions(+), 51 deletions(-) rename gfx/context/{ioseagl_ctx.m => ioseagl_ctx.c} (75%) rename ios/RetroArch/{ViewController.h => gameview.h} (77%) create mode 100644 ios/RetroArch/gameview.m diff --git a/gfx/context/ioseagl_ctx.m b/gfx/context/ioseagl_ctx.c similarity index 75% rename from gfx/context/ioseagl_ctx.m rename to gfx/context/ioseagl_ctx.c index b82a4ac19f..a445113f24 100644 --- a/gfx/context/ioseagl_ctx.m +++ b/gfx/context/ioseagl_ctx.c @@ -26,42 +26,6 @@ #include "../shader_glsl.h" #endif -#import "../../ios/RetroArch/ViewController.h" - -static GLKView *gl_view; -static float screen_scale; - -// Objective-C interface used to interact with the GLES context and display. -@interface ViewController () - -@property (strong, nonatomic) EAGLContext *context; -@property (strong, nonatomic) GLKView *view; - -@end - -@implementation ViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - self.view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) context:self.context]; - - [EAGLContext setCurrentContext:self.context]; - - gl_view = self.view; - screen_scale = [[UIScreen mainScreen] scale]; -} - -- (void)dealloc -{ - if ([EAGLContext currentContext] == self.context) [EAGLContext setCurrentContext:nil]; -} - -@end - - // C interface static void gfx_ctx_set_swap_interval(unsigned interval) { @@ -75,8 +39,8 @@ static void gfx_ctx_destroy(void) static void gfx_ctx_get_video_size(unsigned *width, unsigned *height) { - *width = gl_view.bounds.size.width * screen_scale; - *height = gl_view.bounds.size.height * screen_scale; + extern void get_game_view_size(unsigned *, unsigned *); + get_game_view_size(width, height); } static bool gfx_ctx_init(void) @@ -86,8 +50,8 @@ static bool gfx_ctx_init(void) static void gfx_ctx_swap_buffers(void) { - [gl_view setNeedsDisplay]; - [gl_view bindDrawable]; + extern void flip_game_view(); + flip_game_view(); } static void gfx_ctx_check_window(bool *quit, diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index b5c4f94bcc..fd4c42e748 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -8,6 +8,8 @@ /* Begin PBXBuildFile section */ 9629797716C3CD2400E6DCE0 /* dirlist.m in Sources */ = {isa = PBXBuildFile; fileRef = 9629797616C3CD2400E6DCE0 /* dirlist.m */; }; + 962979ED16C3E86F00E6DCE0 /* gameview.m in Sources */ = {isa = PBXBuildFile; fileRef = 962979EB16C3E86F00E6DCE0 /* gameview.m */; }; + 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */; }; 968A572A16C2A06800BE12F8 /* test.img in Resources */ = {isa = PBXBuildFile; fileRef = 968A572816C2A06800BE12F8 /* test.img */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; @@ -70,7 +72,6 @@ 96AFAFAD16C1EEE9009DE44C /* sinc.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEF716C1DC73009DE44C /* sinc.c */; }; 96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFC916C1FBC0009DE44C /* input_common.c */; }; 96AFAFD716C1FBC0009DE44C /* null.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCD16C1FBC0009DE44C /* null.c */; }; - 96AFAFDD16C2149A009DE44C /* ioseagl_ctx.m in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFDC16C2149A009DE44C /* ioseagl_ctx.m */; }; 96CF014F16C2BB9E00ABF9C9 /* libretro.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 96CF014A16C2BA1900ABF9C9 /* libretro.dylib */; }; 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCE16C1FBC0009DE44C /* overlay.c */; }; 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CF015B16C2F72900ABF9C9 /* ios_input.c */; }; @@ -79,6 +80,9 @@ /* Begin PBXFileReference section */ 9629797516C3CD2400E6DCE0 /* dirlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dirlist.h; sourceTree = ""; }; 9629797616C3CD2400E6DCE0 /* dirlist.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = dirlist.m; sourceTree = ""; }; + 962979EB16C3E86F00E6DCE0 /* gameview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = gameview.m; sourceTree = ""; }; + 962979EC16C3E86F00E6DCE0 /* gameview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gameview.h; sourceTree = ""; }; + 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioseagl_ctx.c; sourceTree = ""; }; 968A572816C2A06800BE12F8 /* test.img */ = {isa = PBXFileReference; lastKnownFileType = file; path = test.img; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; @@ -95,7 +99,6 @@ 96AFAE3F16C1D4EA009DE44C /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 96AFAE4116C1D4EA009DE44C /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 96AFAE4316C1D4EA009DE44C /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; - 96AFAE4916C1D4EA009DE44C /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 96AFAE4D16C1D4EA009DE44C /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPhone.xib; sourceTree = ""; }; 96AFAE5016C1D4EA009DE44C /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPad.xib; sourceTree = ""; }; 96AFAE9D16C1D9A9009DE44C /* autosave.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = autosave.c; path = ../autosave.c; sourceTree = ""; }; @@ -265,7 +268,6 @@ 96AFAFD016C1FBC0009DE44C /* sdl_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_input.c; sourceTree = ""; }; 96AFAFD116C1FBC0009DE44C /* sdl_joypad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_joypad.c; sourceTree = ""; }; 96AFAFD216C1FBC0009DE44C /* x11_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x11_input.c; sourceTree = ""; }; - 96AFAFDC16C2149A009DE44C /* ioseagl_ctx.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ioseagl_ctx.m; sourceTree = ""; }; 96CF014A16C2BA1900ABF9C9 /* libretro.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libretro.dylib; sourceTree = ""; }; 96CF015B16C2F72900ABF9C9 /* ios_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ios_input.c; sourceTree = ""; }; /* End PBXFileReference section */ @@ -325,9 +327,10 @@ 96AFAE3316C1D4EA009DE44C /* RetroArch */ = { isa = PBXGroup; children = ( + 962979EB16C3E86F00E6DCE0 /* gameview.m */, + 962979EC16C3E86F00E6DCE0 /* gameview.h */, 96AFAE3C16C1D4EA009DE44C /* AppDelegate.h */, 96AFAE3D16C1D4EA009DE44C /* AppDelegate.m */, - 96AFAE4916C1D4EA009DE44C /* ViewController.h */, 96AFAE4C16C1D4EA009DE44C /* ViewController_iPhone.xib */, 96AFAE4F16C1D4EA009DE44C /* ViewController_iPad.xib */, 96AFAE3416C1D4EA009DE44C /* Supporting Files */, @@ -543,7 +546,7 @@ 96AFAF3216C1E00A009DE44C /* context */ = { isa = PBXGroup; children = ( - 96AFAFDC16C2149A009DE44C /* ioseagl_ctx.m */, + 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */, 96AFAF3316C1E00A009DE44C /* androidegl_ctx.c */, 96AFAF3416C1E00A009DE44C /* drm_egl_ctx.c */, 96AFAF3516C1E00A009DE44C /* glx_ctx.c */, @@ -775,10 +778,11 @@ 96AFAFAD16C1EEE9009DE44C /* sinc.c in Sources */, 96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */, 96AFAFD716C1FBC0009DE44C /* null.c in Sources */, - 96AFAFDD16C2149A009DE44C /* ioseagl_ctx.m in Sources */, 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */, 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */, 9629797716C3CD2400E6DCE0 /* dirlist.m in Sources */, + 962979ED16C3E86F00E6DCE0 /* gameview.m in Sources */, + 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/AppDelegate.h b/ios/RetroArch/AppDelegate.h index afcb44d684..2f02605b45 100644 --- a/ios/RetroArch/AppDelegate.h +++ b/ios/RetroArch/AppDelegate.h @@ -13,6 +13,6 @@ @property (strong, nonatomic) UIWindow *window; -@property (strong, nonatomic) ViewController *viewController; +@property (strong, nonatomic) UIViewController *viewController; @end diff --git a/ios/RetroArch/AppDelegate.m b/ios/RetroArch/AppDelegate.m index c1604507bb..e75697e695 100644 --- a/ios/RetroArch/AppDelegate.m +++ b/ios/RetroArch/AppDelegate.m @@ -7,7 +7,7 @@ #import "AppDelegate.h" -#import "ViewController.h" +#import "gameview.h" #include "general.h" @@ -101,9 +101,9 @@ extern int16_t IOS_full_x, IOS_full_y; // Override point for customization after application launch. if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) - self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; + self.viewController = [[game_view alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; else - self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; + self.viewController = [[game_view alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; diff --git a/ios/RetroArch/ViewController.h b/ios/RetroArch/gameview.h similarity index 77% rename from ios/RetroArch/ViewController.h rename to ios/RetroArch/gameview.h index 77f2dfafb3..5b82589110 100644 --- a/ios/RetroArch/ViewController.h +++ b/ios/RetroArch/gameview.h @@ -8,6 +8,6 @@ #import #import -@interface ViewController : UIViewController +@interface game_view : UIViewController @end diff --git a/ios/RetroArch/gameview.m b/ios/RetroArch/gameview.m new file mode 100644 index 0000000000..5fdf82d3f7 --- /dev/null +++ b/ios/RetroArch/gameview.m @@ -0,0 +1,61 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2013 - Hans-Kristian Arntzen + * Copyright (C) 2011-2013 - Daniel De Matteis + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#import "gameview.h" + +static GLKView *gl_view; +static float screen_scale; + +@interface game_view () + +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKView *view; + +@end + +@implementation game_view + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + self.view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) context:self.context]; + + [EAGLContext setCurrentContext:self.context]; + + gl_view = self.view; + screen_scale = [[UIScreen mainScreen] scale]; +} + +- (void)dealloc +{ + if ([EAGLContext currentContext] == self.context) [EAGLContext setCurrentContext:nil]; +} + +@end + +void flip_game_view() +{ + [gl_view setNeedsDisplay]; + [gl_view bindDrawable]; +} + +void get_game_view_size(unsigned *width, unsigned *height) +{ + *width = gl_view.bounds.size.width * screen_scale; + *height = gl_view.bounds.size.height * screen_scale; +} From 5d0828d009f19c364fdd23736f966bb4c0231693 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 7 Feb 2013 12:05:46 -0500 Subject: [PATCH 008/108] ios: Now starts with a directory browser to let you choose the game you wan't to play. --- ios/RetroArch.xcodeproj/project.pbxproj | 4 - ios/RetroArch/AppDelegate.m | 99 ++----------------------- ios/RetroArch/dirlist.h | 2 +- ios/RetroArch/dirlist.m | 45 ++++++++--- ios/RetroArch/gameview.h | 2 +- ios/RetroArch/gameview.m | 80 +++++++++++++++++++- 6 files changed, 122 insertions(+), 110 deletions(-) diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index fd4c42e748..c120b37d1a 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -10,7 +10,6 @@ 9629797716C3CD2400E6DCE0 /* dirlist.m in Sources */ = {isa = PBXBuildFile; fileRef = 9629797616C3CD2400E6DCE0 /* dirlist.m */; }; 962979ED16C3E86F00E6DCE0 /* gameview.m in Sources */ = {isa = PBXBuildFile; fileRef = 962979EB16C3E86F00E6DCE0 /* gameview.m */; }; 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */; }; - 968A572A16C2A06800BE12F8 /* test.img in Resources */ = {isa = PBXBuildFile; fileRef = 968A572816C2A06800BE12F8 /* test.img */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -83,7 +82,6 @@ 962979EB16C3E86F00E6DCE0 /* gameview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = gameview.m; sourceTree = ""; }; 962979EC16C3E86F00E6DCE0 /* gameview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gameview.h; sourceTree = ""; }; 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioseagl_ctx.c; sourceTree = ""; }; - 968A572816C2A06800BE12F8 /* test.img */ = {isa = PBXFileReference; lastKnownFileType = file; path = test.img; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -294,7 +292,6 @@ isa = PBXGroup; children = ( 96CF014A16C2BA1900ABF9C9 /* libretro.dylib */, - 968A572816C2A06800BE12F8 /* test.img */, 96AFAF2116C1DF88009DE44C /* libz.dylib */, 96AFAF1E16C1DF0A009DE44C /* OpenAL.framework */, 96AFAE9C16C1D976009DE44C /* core */, @@ -718,7 +715,6 @@ 96AFAE4416C1D4EA009DE44C /* Default-568h@2x.png in Resources */, 96AFAE4E16C1D4EA009DE44C /* ViewController_iPhone.xib in Resources */, 96AFAE5116C1D4EA009DE44C /* ViewController_iPad.xib in Resources */, - 968A572A16C2A06800BE12F8 /* test.img in Resources */, 96CF014F16C2BB9E00ABF9C9 /* libretro.dylib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/ios/RetroArch/AppDelegate.m b/ios/RetroArch/AppDelegate.m index e75697e695..38d1976ed6 100644 --- a/ios/RetroArch/AppDelegate.m +++ b/ios/RetroArch/AppDelegate.m @@ -6,11 +6,8 @@ // #import "AppDelegate.h" - #import "gameview.h" - -#include "general.h" - +#import "dirlist.h" extern bool IOS_is_down; extern int16_t IOS_touch_x, IOS_fix_x; @@ -19,103 +16,25 @@ extern int16_t IOS_full_x, IOS_full_y; @implementation AppDelegate -{ - BOOL ra_initialized; - BOOL ra_paused; - BOOL ra_done; -} - -- (const char*)generate_config -{ - const char* overlay = [[[NSBundle mainBundle] pathForResource:@"overlay" ofType:@"cfg"] UTF8String]; - const char* config = [[NSTemporaryDirectory() stringByAppendingPathComponent: @"retroarch.cfg"] UTF8String]; - - FILE* config_file = fopen(config, "wb"); - - if (config_file) - { - if (overlay) fprintf(config_file, "input_overlay = \"%s\"\n", overlay); - fclose(config_file); - return config; - } - - return 0; -} - -- (void)schedule_iterate -{ - if (ra_initialized && !ra_paused && !ra_done) - { - [self performSelector:@selector(rarch_iterate:) withObject:nil afterDelay:0.002f]; - } -} - -- (void)rarch_init -{ - const char* filename = [[[NSBundle mainBundle] pathForResource:@"test" ofType:@"img"] UTF8String]; - const char* libretro = [[[NSBundle mainBundle] pathForResource:@"libretro" ofType:@"dylib"] UTF8String]; - const char* config_file = [self generate_config]; - - if(!config_file) return; - - const char* argv[] = {"retroarch", "-L", libretro, "-c", config_file, filename, 0}; - if (rarch_main_init(6, (char**)argv) == 0) - { - rarch_init_msg_queue(); - ra_initialized = TRUE; - } -} - -- (void)rarch_iterate:(id)sender -{ - if (!ra_paused && ra_initialized && !ra_done) - ra_done = !rarch_main_iterate(); - - [self schedule_iterate]; -} - -- (void)rarch_deinit -{ - if (ra_initialized) - { - rarch_main_deinit(); - rarch_deinit_msg_queue(); - -#ifdef PERF_TEST - rarch_perf_log(); -#endif - - rarch_main_clear_state(); - } - - ra_initialized = FALSE; -} - (void)applicationDidFinishLaunching:(UIApplication *)application { - ra_paused = NO; - ra_done = NO; - ra_initialized = NO; - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) - self.viewController = [[game_view alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; + self.viewController = [[dirlist_view alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; else - self.viewController = [[game_view alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; + self.viewController = [[dirlist_view alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; - - [self rarch_init]; - [self performSelector:@selector(rarch_iterate:) withObject:nil afterDelay:1]; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [[event allTouches] anyObject]; - CGPoint coord = [touch locationInView:self.viewController.view]; + CGPoint coord = [touch locationInView:self.window.rootViewController.view]; float scale = [[UIScreen mainScreen] scale]; IOS_is_down = true; @@ -126,8 +45,7 @@ extern int16_t IOS_full_x, IOS_full_y; - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [[event allTouches] anyObject]; - CGPoint coord = [touch locationInView:self.viewController.view]; - + CGPoint coord = [touch locationInView:self.window.rootViewController.view]; IOS_is_down = true; IOS_touch_x = coord.x; IOS_touch_y = coord.y; @@ -145,12 +63,10 @@ extern int16_t IOS_full_x, IOS_full_y; - (void)applicationWillResignActive:(UIApplication *)application { - ra_paused = YES; } - (void)applicationDidEnterBackground:(UIApplication *)application { - ra_paused = YES; } - (void)applicationWillEnterForeground:(UIApplication *)application @@ -159,11 +75,6 @@ extern int16_t IOS_full_x, IOS_full_y; - (void)applicationDidBecomeActive:(UIApplication *)application { - if (ra_paused) - { - ra_paused = NO; - [self schedule_iterate]; - } } - (void)applicationWillTerminate:(UIApplication *)application diff --git a/ios/RetroArch/dirlist.h b/ios/RetroArch/dirlist.h index 3c4e58cf60..147f763049 100644 --- a/ios/RetroArch/dirlist.h +++ b/ios/RetroArch/dirlist.h @@ -7,6 +7,6 @@ #import -@interface DirectoryView : UIViewController +@interface dirlist_view : UIViewController @end diff --git a/ios/RetroArch/dirlist.m b/ios/RetroArch/dirlist.m index 2f4169d311..d923f24b2d 100644 --- a/ios/RetroArch/dirlist.m +++ b/ios/RetroArch/dirlist.m @@ -8,6 +8,7 @@ #include #import "dirlist.h" +#import "gameview.h" struct dirent_list { @@ -41,14 +42,14 @@ unsigned get_dirent_list_count(struct dirent_list* list) void free_dirent_list(struct dirent_list* list) { - struct dirent_list* next = 0; - if (list) - { - next = list->next; - free(list); - } + struct dirent_list* next = list ? list : 0; - free_dirent_list(next); + while (next) + { + struct dirent_list* me = next; + next = next->next; + free(me); + } } struct dirent_list* build_dirent_list(const char* path) @@ -84,8 +85,9 @@ struct dirent_list* build_dirent_list(const char* path) return result; } -@implementation DirectoryView +@implementation dirlist_view { + char path[4096]; UITableView* table; struct dirent_list* files; }; @@ -102,7 +104,8 @@ struct dirent_list* build_dirent_list(const char* path) { [super viewDidLoad]; - files = build_dirent_list([NSTemporaryDirectory() UTF8String]); + strcpy(path, "/"); + files = build_dirent_list(path); table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) style:UITableViewStylePlain]; table.dataSource = self; @@ -114,6 +117,30 @@ struct dirent_list* build_dirent_list(const char* path) - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { const struct dirent* item = get_dirent_at_index(files, indexPath.row); + + if (!item) return; + + strcat(path, "/"); + strcat(path, item->d_name); + + if (item->d_type & DT_DIR) + { + free_dirent_list(files); + files = build_dirent_list(path); + [table reloadData]; + } + else + { + UIWindow *window = [UIApplication sharedApplication].keyWindow; + + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) + window.rootViewController = [[game_view alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; + else + window.rootViewController = [[game_view alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; + + game_view* game = (game_view*)window.rootViewController; + [game load_game:path]; + } } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section diff --git a/ios/RetroArch/gameview.h b/ios/RetroArch/gameview.h index 5b82589110..f5a7ed868b 100644 --- a/ios/RetroArch/gameview.h +++ b/ios/RetroArch/gameview.h @@ -9,5 +9,5 @@ #import @interface game_view : UIViewController - +- (void)load_game:(const char*)file_name; @end diff --git a/ios/RetroArch/gameview.m b/ios/RetroArch/gameview.m index 5fdf82d3f7..0beef6a225 100644 --- a/ios/RetroArch/gameview.m +++ b/ios/RetroArch/gameview.m @@ -15,6 +15,7 @@ */ #import "gameview.h" +#include "general.h" static GLKView *gl_view; static float screen_scale; @@ -27,14 +28,90 @@ static float screen_scale; @end @implementation game_view +{ + BOOL ra_initialized; + BOOL ra_done; +} + +- (const char*)generate_config +{ + const char* overlay = [[[NSBundle mainBundle] pathForResource:@"overlay" ofType:@"cfg"] UTF8String]; + const char* config = [[NSTemporaryDirectory() stringByAppendingPathComponent: @"retroarch.cfg"] UTF8String]; + + FILE* config_file = fopen(config, "wb"); + + if (config_file) + { + if (overlay) fprintf(config_file, "input_overlay = \"%s\"\n", overlay); + fclose(config_file); + return config; + } + + return 0; +} + +- (void)schedule_iterate +{ + if (ra_initialized && !ra_done) + { + [self performSelector:@selector(rarch_iterate:) withObject:nil afterDelay:0.002f]; + } +} + +- (void)rarch_iterate:(id)sender +{ + if (ra_initialized && !ra_done) + ra_done = !rarch_main_iterate(); + + [self schedule_iterate]; +} + +- (void)rarch_deinit +{ + if (ra_initialized) + { + rarch_main_deinit(); + rarch_deinit_msg_queue(); + +#ifdef PERF_TEST + rarch_perf_log(); +#endif + + rarch_main_clear_state(); + } + + ra_initialized = FALSE; +} + +- (void)load_game:(const char*)file_name +{ + if(!ra_initialized && file_name) + { + const char* libretro = [[[NSBundle mainBundle] pathForResource:@"libretro" ofType:@"dylib"] UTF8String]; + const char* config_file = [self generate_config]; + + if(!config_file) return; + + const char* argv[] = {"retroarch", "-L", libretro, "-c", config_file, file_name, 0}; + if (rarch_main_init(6, (char**)argv) == 0) + { + rarch_init_msg_queue(); + ra_initialized = TRUE; + [self schedule_iterate]; + } + } +} - (void)viewDidLoad { [super viewDidLoad]; + ra_done = NO; + ra_initialized = NO; + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; self.view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) context:self.context]; - + [EAGLContext setCurrentContext:self.context]; gl_view = self.view; @@ -59,3 +136,4 @@ void get_game_view_size(unsigned *width, unsigned *height) *width = gl_view.bounds.size.width * screen_scale; *height = gl_view.bounds.size.height * screen_scale; } + From 16759620b50bac991b72e876abdf8ee7985d47f0 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 7 Feb 2013 12:38:30 -0500 Subject: [PATCH 009/108] ios: Some cleanup and simplifications --- ios/RetroArch/AppDelegate.h | 4 -- ios/RetroArch/AppDelegate.m | 33 ++----------- ios/RetroArch/dirlist.m | 4 +- ios/RetroArch/gameview.m | 98 ++++++++++++++++--------------------- 4 files changed, 46 insertions(+), 93 deletions(-) diff --git a/ios/RetroArch/AppDelegate.h b/ios/RetroArch/AppDelegate.h index 2f02605b45..a1c6c7f0ad 100644 --- a/ios/RetroArch/AppDelegate.h +++ b/ios/RetroArch/AppDelegate.h @@ -7,12 +7,8 @@ #import -@class ViewController; - @interface AppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; -@property (strong, nonatomic) UIViewController *viewController; - @end diff --git a/ios/RetroArch/AppDelegate.m b/ios/RetroArch/AppDelegate.m index 38d1976ed6..72f671ded0 100644 --- a/ios/RetroArch/AppDelegate.m +++ b/ios/RetroArch/AppDelegate.m @@ -6,14 +6,10 @@ // #import "AppDelegate.h" -#import "gameview.h" #import "dirlist.h" extern bool IOS_is_down; -extern int16_t IOS_touch_x, IOS_fix_x; -extern int16_t IOS_touch_y, IOS_fix_y; -extern int16_t IOS_full_x, IOS_full_y; - +extern int16_t IOS_touch_x, IOS_touch_y; @implementation AppDelegate @@ -23,11 +19,10 @@ extern int16_t IOS_full_x, IOS_full_y; // Override point for customization after application launch. if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) - self.viewController = [[dirlist_view alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; + self.window.rootViewController = [[dirlist_view alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; else - self.viewController = [[dirlist_view alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; - - self.window.rootViewController = self.viewController; + self.window.rootViewController = [[dirlist_view alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; + [self.window makeKeyAndVisible]; } @@ -61,25 +56,5 @@ extern int16_t IOS_full_x, IOS_full_y; IOS_is_down = false; } -- (void)applicationWillResignActive:(UIApplication *)application -{ -} - -- (void)applicationDidEnterBackground:(UIApplication *)application -{ -} - -- (void)applicationWillEnterForeground:(UIApplication *)application -{ -} - -- (void)applicationDidBecomeActive:(UIApplication *)application -{ -} - -- (void)applicationWillTerminate:(UIApplication *)application -{ -} - @end diff --git a/ios/RetroArch/dirlist.m b/ios/RetroArch/dirlist.m index d923f24b2d..95a2a3ded4 100644 --- a/ios/RetroArch/dirlist.m +++ b/ios/RetroArch/dirlist.m @@ -96,8 +96,6 @@ struct dirent_list* build_dirent_list(const char* path) { free_dirent_list(files); files = 0; - - // Do I need to kill table here? } - (void)viewDidLoad @@ -120,11 +118,11 @@ struct dirent_list* build_dirent_list(const char* path) if (!item) return; - strcat(path, "/"); strcat(path, item->d_name); if (item->d_type & DT_DIR) { + strcat(path, "/"); free_dirent_list(files); files = build_dirent_list(path); [table reloadData]; diff --git a/ios/RetroArch/gameview.m b/ios/RetroArch/gameview.m index 0beef6a225..4c7e7bcc5f 100644 --- a/ios/RetroArch/gameview.m +++ b/ios/RetroArch/gameview.m @@ -20,42 +20,17 @@ static GLKView *gl_view; static float screen_scale; -@interface game_view () - -@property (strong, nonatomic) EAGLContext *context; -@property (strong, nonatomic) GLKView *view; - -@end - @implementation game_view { - BOOL ra_initialized; - BOOL ra_done; -} + EAGLContext *gl_context; -- (const char*)generate_config -{ - const char* overlay = [[[NSBundle mainBundle] pathForResource:@"overlay" ofType:@"cfg"] UTF8String]; - const char* config = [[NSTemporaryDirectory() stringByAppendingPathComponent: @"retroarch.cfg"] UTF8String]; - - FILE* config_file = fopen(config, "wb"); - - if (config_file) - { - if (overlay) fprintf(config_file, "input_overlay = \"%s\"\n", overlay); - fclose(config_file); - return config; - } - - return 0; + BOOL ra_initialized; + BOOL ra_done; } - (void)schedule_iterate { - if (ra_initialized && !ra_done) - { - [self performSelector:@selector(rarch_iterate:) withObject:nil afterDelay:0.002f]; - } + if (ra_initialized && !ra_done) [self performSelector:@selector(rarch_iterate:) withObject:nil afterDelay:0.002f]; } - (void)rarch_iterate:(id)sender @@ -66,7 +41,26 @@ static float screen_scale; [self schedule_iterate]; } -- (void)rarch_deinit +- (void)load_game:(const char*)file_name +{ + if(!ra_initialized && file_name) + { + const char* libretro = [[[NSBundle mainBundle] pathForResource:@"libretro" ofType:@"dylib"] UTF8String]; + const char* overlay = [[[NSBundle mainBundle] pathForResource:@"overlay" ofType:@"cfg"] UTF8String]; + + strcpy(g_settings.input.overlay, overlay ? overlay : ""); + + const char* argv[] = {"retroarch", "-L", libretro, file_name, 0}; + if (rarch_main_init(6, (char**)argv) == 0) + { + rarch_init_msg_queue(); + ra_initialized = TRUE; + [self schedule_iterate]; + } + } +} + +- (void)close_game { if (ra_initialized) { @@ -83,24 +77,6 @@ static float screen_scale; ra_initialized = FALSE; } -- (void)load_game:(const char*)file_name -{ - if(!ra_initialized && file_name) - { - const char* libretro = [[[NSBundle mainBundle] pathForResource:@"libretro" ofType:@"dylib"] UTF8String]; - const char* config_file = [self generate_config]; - - if(!config_file) return; - - const char* argv[] = {"retroarch", "-L", libretro, "-c", config_file, file_name, 0}; - if (rarch_main_init(6, (char**)argv) == 0) - { - rarch_init_msg_queue(); - ra_initialized = TRUE; - [self schedule_iterate]; - } - } -} - (void)viewDidLoad { @@ -109,31 +85,39 @@ static float screen_scale; ra_done = NO; ra_initialized = NO; - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - self.view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) context:self.context]; + gl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + [EAGLContext setCurrentContext:gl_context]; - [EAGLContext setCurrentContext:self.context]; + gl_view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) context:gl_context]; + self.view = gl_view; - gl_view = self.view; screen_scale = [[UIScreen mainScreen] scale]; } - (void)dealloc { - if ([EAGLContext currentContext] == self.context) [EAGLContext setCurrentContext:nil]; + if ([EAGLContext currentContext] == gl_context) [EAGLContext setCurrentContext:nil]; + gl_context = nil; + gl_view = nil; } @end void flip_game_view() { - [gl_view setNeedsDisplay]; - [gl_view bindDrawable]; + if (gl_view) + { + [gl_view setNeedsDisplay]; + [gl_view bindDrawable]; + } } void get_game_view_size(unsigned *width, unsigned *height) { - *width = gl_view.bounds.size.width * screen_scale; - *height = gl_view.bounds.size.height * screen_scale; + if (gl_view) + { + *width = gl_view.bounds.size.width * screen_scale; + *height = gl_view.bounds.size.height * screen_scale; + } } From 7a44d9bcba76744749ff045ea5debd24fcb69b0b Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 7 Feb 2013 13:43:42 -0500 Subject: [PATCH 010/108] ios: As a hack, force app to terminate when entering background. --- ios/RetroArch/AppDelegate.m | 6 ++ ios/RetroArch/RetroArch-Info.plist | 2 + ios/RetroArch/dirlist.m | 4 +- ios/RetroArch/gameview.m | 90 +++++++++++++++--------------- 4 files changed, 56 insertions(+), 46 deletions(-) diff --git a/ios/RetroArch/AppDelegate.m b/ios/RetroArch/AppDelegate.m index 72f671ded0..5226907a47 100644 --- a/ios/RetroArch/AppDelegate.m +++ b/ios/RetroArch/AppDelegate.m @@ -56,5 +56,11 @@ extern int16_t IOS_touch_x, IOS_touch_y; IOS_is_down = false; } +- (void)applicationWillTerminate:(UIApplication *)application +{ + extern void ios_close_game(); + ios_close_game(); +} + @end diff --git a/ios/RetroArch/RetroArch-Info.plist b/ios/RetroArch/RetroArch-Info.plist index 858508d759..6a3d2960f5 100644 --- a/ios/RetroArch/RetroArch-Info.plist +++ b/ios/RetroArch/RetroArch-Info.plist @@ -36,6 +36,8 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + UIApplicationExitsOnSuspend + UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait diff --git a/ios/RetroArch/dirlist.m b/ios/RetroArch/dirlist.m index 95a2a3ded4..024bda1ebe 100644 --- a/ios/RetroArch/dirlist.m +++ b/ios/RetroArch/dirlist.m @@ -137,7 +137,9 @@ struct dirent_list* build_dirent_list(const char* path) window.rootViewController = [[game_view alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; game_view* game = (game_view*)window.rootViewController; - [game load_game:path]; + + extern void ios_load_game(const char*); + ios_load_game(path); } } diff --git a/ios/RetroArch/gameview.m b/ios/RetroArch/gameview.m index 4c7e7bcc5f..33d837abb8 100644 --- a/ios/RetroArch/gameview.m +++ b/ios/RetroArch/gameview.m @@ -17,20 +17,21 @@ #import "gameview.h" #include "general.h" +static game_view *current_view; static GLKView *gl_view; static float screen_scale; +static bool ra_initialized = false; +static bool ra_done = false; @implementation game_view { EAGLContext *gl_context; - - BOOL ra_initialized; - BOOL ra_done; } - (void)schedule_iterate { - if (ra_initialized && !ra_done) [self performSelector:@selector(rarch_iterate:) withObject:nil afterDelay:0.002f]; + if (ra_initialized && !ra_done) + [self performSelector:@selector(rarch_iterate:) withObject:nil afterDelay:0.002f]; } - (void)rarch_iterate:(id)sender @@ -41,50 +42,10 @@ static float screen_scale; [self schedule_iterate]; } -- (void)load_game:(const char*)file_name -{ - if(!ra_initialized && file_name) - { - const char* libretro = [[[NSBundle mainBundle] pathForResource:@"libretro" ofType:@"dylib"] UTF8String]; - const char* overlay = [[[NSBundle mainBundle] pathForResource:@"overlay" ofType:@"cfg"] UTF8String]; - - strcpy(g_settings.input.overlay, overlay ? overlay : ""); - - const char* argv[] = {"retroarch", "-L", libretro, file_name, 0}; - if (rarch_main_init(6, (char**)argv) == 0) - { - rarch_init_msg_queue(); - ra_initialized = TRUE; - [self schedule_iterate]; - } - } -} - -- (void)close_game -{ - if (ra_initialized) - { - rarch_main_deinit(); - rarch_deinit_msg_queue(); - -#ifdef PERF_TEST - rarch_perf_log(); -#endif - - rarch_main_clear_state(); - } - - ra_initialized = FALSE; -} - - - (void)viewDidLoad { [super viewDidLoad]; - ra_done = NO; - ra_initialized = NO; - gl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; [EAGLContext setCurrentContext:gl_context]; @@ -92,10 +53,11 @@ static float screen_scale; self.view = gl_view; screen_scale = [[UIScreen mainScreen] scale]; + current_view = self; } - (void)dealloc -{ +{ if ([EAGLContext currentContext] == gl_context) [EAGLContext setCurrentContext:nil]; gl_context = nil; gl_view = nil; @@ -121,3 +83,41 @@ void get_game_view_size(unsigned *width, unsigned *height) } } +void ios_close_game() +{ + if (ra_initialized) + { + rarch_main_deinit(); + rarch_deinit_msg_queue(); + +#ifdef PERF_TEST + rarch_perf_log(); +#endif + + rarch_main_clear_state(); + + ra_done = true; + } + + ra_initialized = false; +} + +void ios_load_game(const char* file_name) +{ + if(!ra_initialized && file_name) + { + const char* libretro = [[[NSBundle mainBundle] pathForResource:@"libretro" ofType:@"dylib"] UTF8String]; + const char* overlay = [[[NSBundle mainBundle] pathForResource:@"overlay" ofType:@"cfg"] UTF8String]; + + strcpy(g_settings.input.overlay, overlay ? overlay : ""); + + const char* argv[] = {"retroarch", "-L", libretro, file_name, 0}; + if (rarch_main_init(6, (char**)argv) == 0) + { + rarch_init_msg_queue(); + ra_initialized = TRUE; + + if (current_view) [current_view schedule_iterate]; + } + } +} From cb484546b20692b1341d7087b0d456fcd5f3df61 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 7 Feb 2013 14:45:30 -0500 Subject: [PATCH 011/108] ios: Spruce up browser with sorting and icons. (The icons are just borrowed from android for now). --- ios/RetroArch.xcodeproj/project.pbxproj | 8 ++ ios/RetroArch/dirlist.m | 98 +++++++++++++++---------- 2 files changed, 66 insertions(+), 40 deletions(-) diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index c120b37d1a..c3cef6924c 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -10,6 +10,8 @@ 9629797716C3CD2400E6DCE0 /* dirlist.m in Sources */ = {isa = PBXBuildFile; fileRef = 9629797616C3CD2400E6DCE0 /* dirlist.m */; }; 962979ED16C3E86F00E6DCE0 /* gameview.m in Sources */ = {isa = PBXBuildFile; fileRef = 962979EB16C3E86F00E6DCE0 /* gameview.m */; }; 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */; }; + 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; }; + 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -82,6 +84,8 @@ 962979EB16C3E86F00E6DCE0 /* gameview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = gameview.m; sourceTree = ""; }; 962979EC16C3E86F00E6DCE0 /* gameview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gameview.h; sourceTree = ""; }; 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioseagl_ctx.c; sourceTree = ""; }; + 962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = ""; }; + 962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -291,6 +295,8 @@ 96AFAE1A16C1D4EA009DE44C = { isa = PBXGroup; children = ( + 962979F416C43B9500E6DCE0 /* ic_dir.png */, + 962979F516C43B9500E6DCE0 /* ic_file.png */, 96CF014A16C2BA1900ABF9C9 /* libretro.dylib */, 96AFAF2116C1DF88009DE44C /* libz.dylib */, 96AFAF1E16C1DF0A009DE44C /* OpenAL.framework */, @@ -716,6 +722,8 @@ 96AFAE4E16C1D4EA009DE44C /* ViewController_iPhone.xib in Resources */, 96AFAE5116C1D4EA009DE44C /* ViewController_iPad.xib in Resources */, 96CF014F16C2BB9E00ABF9C9 /* libretro.dylib in Resources */, + 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */, + 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/dirlist.m b/ios/RetroArch/dirlist.m index 024bda1ebe..759df1eee5 100644 --- a/ios/RetroArch/dirlist.m +++ b/ios/RetroArch/dirlist.m @@ -12,74 +12,74 @@ struct dirent_list { - struct dirent_list* next; - struct dirent entry; + size_t count; + struct dirent* entries; }; const struct dirent* get_dirent_at_index(struct dirent_list* list, unsigned index) { - while (list && index) - { - list = list->next; - index --; - } - - return list ? &list->entry : 0; + if (!list) return 0; + return (index < list->count) ? &list->entries[index] : 0; } unsigned get_dirent_list_count(struct dirent_list* list) { - unsigned result = 0; - - while (list) - { - result ++; - list = list->next; - } - - return result; + return list ? list->count : 0; } void free_dirent_list(struct dirent_list* list) { - struct dirent_list* next = list ? list : 0; + if (list) free(list->entries); + free(list); +} + +static int compare_dirent(const void *left, const void *right) +{ + const struct dirent* l = (const struct dirent*) left; + const struct dirent* r = (const struct dirent*) right; - while (next) + // Directories first + if ((l->d_type & DT_DIR) != (r->d_type & DT_DIR)) { - struct dirent_list* me = next; - next = next->next; - free(me); + return (l->d_type & DT_DIR) ? -1 : 1; } + + // Name + return strcmp(l->d_name, r->d_name); } struct dirent_list* build_dirent_list(const char* path) { struct dirent_list* result = 0; - struct dirent_list* iterate = 0; DIR* dir = opendir(path); if (dir) - { + { struct dirent* ent = 0; + + // Count the number of items + size_t count = 0; while ((ent = readdir(dir))) { - if (!iterate) - { - iterate = malloc(sizeof(struct dirent_list)); - iterate->next = 0; - result = iterate; - } - else - { - iterate->next = malloc(sizeof(struct dirent_list)); - iterate = iterate->next; - iterate->next = 0; - } - - memcpy(&iterate->entry, ent, sizeof(struct dirent)); + count += (strcmp(ent->d_name, ".") ? 1 : 0); } + rewinddir(dir); + + // Build and fill the result + result = malloc(sizeof(struct dirent_list)); + result->count = count; + result->entries = malloc(sizeof(struct dirent) * count); + size_t index = 0; + while ((ent = readdir(dir))) + { + if (strcmp(ent->d_name, ".") == 0) continue; + memcpy(&result->entries[index ++], ent, sizeof(struct dirent)); + } + closedir(dir); + + qsort(result->entries, result->count, sizeof(struct dirent), &compare_dirent); } return result; @@ -90,6 +90,9 @@ struct dirent_list* build_dirent_list(const char* path) char path[4096]; UITableView* table; struct dirent_list* files; + + UIImage* file_icon; + UIImage* folder_icon; }; -(void)dealloc @@ -100,6 +103,9 @@ struct dirent_list* build_dirent_list(const char* path) - (void)viewDidLoad { + file_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_file" ofType:@"png"]]; + folder_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_dir" ofType:@"png"]]; + [super viewDidLoad]; strcpy(path, "/"); @@ -158,7 +164,19 @@ struct dirent_list* build_dirent_list(const char* path) if (item) { cell.textLabel.text = [[NSString string] initWithUTF8String:item->d_name]; - cell.accessoryType = (item->d_type & DT_DIR) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; + + if (item->d_type & DT_DIR) + { + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + cell.imageView.image = folder_icon; + } + else + { + cell.accessoryType = UITableViewCellAccessoryNone; + cell.imageView.image = file_icon; + } + + [cell.imageView sizeToFit]; } return cell; From 5f5be7c4dc4023bafc0cd8ffb7ac7bb786498903 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 7 Feb 2013 16:10:56 -0500 Subject: [PATCH 012/108] ios: Multi-touch support --- ios/RetroArch/AppDelegate.m | 51 +++++++++++++++++++++++++------------ ios/RetroArch/dirlist.m | 2 -- ios/RetroArch/gameview.m | 1 + ios/RetroArch/ios_input.c | 30 ++++++++++++++-------- 4 files changed, 55 insertions(+), 29 deletions(-) diff --git a/ios/RetroArch/AppDelegate.m b/ios/RetroArch/AppDelegate.m index 5226907a47..0bc7e022f6 100644 --- a/ios/RetroArch/AppDelegate.m +++ b/ios/RetroArch/AppDelegate.m @@ -8,8 +8,16 @@ #import "AppDelegate.h" #import "dirlist.h" -extern bool IOS_is_down; -extern int16_t IOS_touch_x, IOS_touch_y; +#define MAX_TOUCH 16 +extern struct +{ + bool is_down; + int16_t screen_x, screen_y; + int16_t fixed_x, fixed_y; + int16_t full_x, full_y; +} ios_touches[MAX_TOUCH]; + +extern uint32_t ios_current_touch_count ; @implementation AppDelegate @@ -26,34 +34,45 @@ extern int16_t IOS_touch_x, IOS_touch_y; [self.window makeKeyAndVisible]; } +- (void)processTouches:(NSArray*)touches +{ + ios_current_touch_count = [touches count]; + + for(int i = 0; i != [touches count]; i ++) + { + UITouch *touch = [touches objectAtIndex:i]; + CGPoint coord = [touch locationInView:self.window.rootViewController.view]; + float scale = [[UIScreen mainScreen] scale]; + + ios_touches[i].is_down = (touch.phase != UITouchPhaseEnded) && (touch.phase != UITouchPhaseCancelled); + + ios_touches[i].screen_x = coord.x * scale; + ios_touches[i].screen_y = coord.y * scale; + } +} + - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { - UITouch *touch = [[event allTouches] anyObject]; - CGPoint coord = [touch locationInView:self.window.rootViewController.view]; - float scale = [[UIScreen mainScreen] scale]; - - IOS_is_down = true; - IOS_touch_x = coord.x * scale; - IOS_touch_y = coord.y * scale; + [super touchesBegan:touches withEvent:event]; + [self processTouches:[[event allTouches] allObjects]]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - UITouch *touch = [[event allTouches] anyObject]; - CGPoint coord = [touch locationInView:self.window.rootViewController.view]; - IOS_is_down = true; - IOS_touch_x = coord.x; - IOS_touch_y = coord.y; + [super touchesMoved:touches withEvent:event]; + [self processTouches:[[event allTouches] allObjects]]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { - IOS_is_down = false; + [super touchesEnded:touches withEvent:event]; + [self processTouches:[[event allTouches] allObjects]]; } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { - IOS_is_down = false; + [super touchesCancelled:touches withEvent:event]; + [self processTouches:[[event allTouches] allObjects]]; } - (void)applicationWillTerminate:(UIApplication *)application diff --git a/ios/RetroArch/dirlist.m b/ios/RetroArch/dirlist.m index 759df1eee5..74076b4ee3 100644 --- a/ios/RetroArch/dirlist.m +++ b/ios/RetroArch/dirlist.m @@ -142,8 +142,6 @@ struct dirent_list* build_dirent_list(const char* path) else window.rootViewController = [[game_view alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; - game_view* game = (game_view*)window.rootViewController; - extern void ios_load_game(const char*); ios_load_game(path); } diff --git a/ios/RetroArch/gameview.m b/ios/RetroArch/gameview.m index 33d837abb8..a191798ef3 100644 --- a/ios/RetroArch/gameview.m +++ b/ios/RetroArch/gameview.m @@ -50,6 +50,7 @@ static bool ra_done = false; [EAGLContext setCurrentContext:gl_context]; gl_view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) context:gl_context]; + gl_view.multipleTouchEnabled = YES; self.view = gl_view; screen_scale = [[UIScreen mainScreen] scale]; diff --git a/ios/RetroArch/ios_input.c b/ios/RetroArch/ios_input.c index 05f99cd687..54df016725 100644 --- a/ios/RetroArch/ios_input.c +++ b/ios/RetroArch/ios_input.c @@ -23,37 +23,45 @@ #define MAX_TOUCH 16 -bool IOS_is_down; -int16_t IOS_touch_x, IOS_fix_x; -int16_t IOS_touch_y, IOS_fix_y; -int16_t IOS_full_x, IOS_full_y; +struct +{ + bool is_down; + int16_t screen_x, screen_y; + int16_t fixed_x, fixed_y; + int16_t full_x, full_y; +} ios_touches[MAX_TOUCH]; + +uint32_t ios_current_touch_count = 0; static void *ios_input_init(void) { + memset(ios_touches, 0, sizeof(ios_touches)); return (void*)-1; } static void ios_input_poll(void *data) { - input_translate_coord_viewport(IOS_touch_x, IOS_touch_y, - &IOS_fix_x, &IOS_fix_y, - &IOS_full_x, &IOS_full_y); + for (int i = 0; i != ios_current_touch_count; i ++) + { + input_translate_coord_viewport(ios_touches[i].screen_x, ios_touches[i].screen_y, + &ios_touches[i].fixed_x, &ios_touches[i].fixed_y, + &ios_touches[i].full_x, &ios_touches[i].full_y); + } } static int16_t ios_input_state(void *data, const struct retro_keybind **binds, unsigned port, unsigned device, unsigned index, unsigned id) { - if (index != 0) return 0; switch (device) { case RARCH_DEVICE_POINTER_SCREEN: switch (id) { case RETRO_DEVICE_ID_POINTER_X: - return IOS_full_x; + return (index < ios_current_touch_count) ? ios_touches[index].full_x : 0; case RETRO_DEVICE_ID_POINTER_Y: - return IOS_full_y; + return (index < ios_current_touch_count) ? ios_touches[index].full_y : 0; case RETRO_DEVICE_ID_POINTER_PRESSED: - return IOS_is_down; + return (index < ios_current_touch_count) ? ios_touches[index].is_down : 0; default: return 0; } From 80c0d35f58df5ef279f7d5ab77034bb4c484f5ac Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 7 Feb 2013 16:53:17 -0500 Subject: [PATCH 013/108] ios: Fix symlinks in the file browser; remove the top entry of the path instead of appending '..' when going back a directory. --- ios/RetroArch/dirlist.m | 52 +++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/ios/RetroArch/dirlist.m b/ios/RetroArch/dirlist.m index 74076b4ee3..2ddca5d5fa 100644 --- a/ios/RetroArch/dirlist.m +++ b/ios/RetroArch/dirlist.m @@ -6,6 +6,7 @@ // Copyright (c) 2013 RetroArch. All rights reserved. // +#include #include #import "dirlist.h" #import "gameview.h" @@ -39,10 +40,8 @@ static int compare_dirent(const void *left, const void *right) const struct dirent* r = (const struct dirent*) right; // Directories first - if ((l->d_type & DT_DIR) != (r->d_type & DT_DIR)) - { - return (l->d_type & DT_DIR) ? -1 : 1; - } + if (l->d_type != r->d_type) + return (l->d_type) ? -1 : 1; // Name return strcmp(l->d_name, r->d_name); @@ -56,7 +55,7 @@ struct dirent_list* build_dirent_list(const char* path) if (dir) { struct dirent* ent = 0; - + // Count the number of items size_t count = 0; while ((ent = readdir(dir))) @@ -64,6 +63,11 @@ struct dirent_list* build_dirent_list(const char* path) count += (strcmp(ent->d_name, ".") ? 1 : 0); } rewinddir(dir); + + // String buffer for 'stat'ing + char* stat_path = malloc(strlen(path) + sizeof(ent->d_name)); + strcpy(stat_path, path); + uint32_t last_index = strlen(stat_path); // Build and fill the result result = malloc(sizeof(struct dirent_list)); @@ -74,10 +78,21 @@ struct dirent_list* build_dirent_list(const char* path) while ((ent = readdir(dir))) { if (strcmp(ent->d_name, ".") == 0) continue; - memcpy(&result->entries[index ++], ent, sizeof(struct dirent)); + memcpy(&result->entries[index], ent, sizeof(struct dirent)); + + // Chage dirent.d_type to a boolean indication if it is a directory + struct stat stat_buf; + strcat(stat_path, "/"); + strcat(stat_path, ent->d_name); + stat(stat_path, &stat_buf); + result->entries[index].d_type = S_ISDIR(stat_buf.st_mode) ? 1 : 0; + stat_path[last_index] = 0; + + index ++; } closedir(dir); + free(stat_path); qsort(result->entries, result->count, sizeof(struct dirent), &compare_dirent); } @@ -124,11 +139,21 @@ struct dirent_list* build_dirent_list(const char* path) if (!item) return; - strcat(path, item->d_name); - - if (item->d_type & DT_DIR) + if (item->d_type) { - strcat(path, "/"); + if (strcmp(item->d_name, "..") == 0) + { + char* last_slash = strrchr(path, '/'); + if (last_slash) *last_slash = 0; + path[0] = (path[0] == 0) ? '/' : path[0]; + printf("%s\n", path); + } + else + { + strcat(path, "/"); + strcat(path, item->d_name); + } + free_dirent_list(files); files = build_dirent_list(path); [table reloadData]; @@ -141,7 +166,10 @@ struct dirent_list* build_dirent_list(const char* path) window.rootViewController = [[game_view alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; else window.rootViewController = [[game_view alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; - + + strcat(path, "/"); + strcat(path, item->d_name); + extern void ios_load_game(const char*); ios_load_game(path); } @@ -163,7 +191,7 @@ struct dirent_list* build_dirent_list(const char* path) { cell.textLabel.text = [[NSString string] initWithUTF8String:item->d_name]; - if (item->d_type & DT_DIR) + if (item->d_type) { cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; cell.imageView.image = folder_icon; From 33d57ee3a0ca15d70cd30b38629850d625ae0d91 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 7 Feb 2013 19:03:57 -0500 Subject: [PATCH 014/108] ios: Don't use performSelector to schedule every frame, the rarch_iterate method runs the UI loop internally; Split dirent_list code out of dirlist.m. --- ios/RetroArch.xcodeproj/project.pbxproj | 6 ++ ios/RetroArch/dirent_list.c | 97 +++++++++++++++++++++++++ ios/RetroArch/dirent_list.h | 33 +++++++++ ios/RetroArch/dirlist.m | 95 +----------------------- ios/RetroArch/gameview.m | 97 +++++++++++++------------ 5 files changed, 187 insertions(+), 141 deletions(-) create mode 100644 ios/RetroArch/dirent_list.c create mode 100644 ios/RetroArch/dirent_list.h diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index c3cef6924c..27e3f32966 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */; }; 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; }; 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; }; + 96297A0116C4767F00E6DCE0 /* dirent_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979FF16C4767F00E6DCE0 /* dirent_list.c */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -86,6 +87,8 @@ 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioseagl_ctx.c; sourceTree = ""; }; 962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = ""; }; 962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = ""; }; + 962979FF16C4767F00E6DCE0 /* dirent_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dirent_list.c; sourceTree = ""; }; + 96297A0016C4767F00E6DCE0 /* dirent_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dirent_list.h; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -330,6 +333,8 @@ 96AFAE3316C1D4EA009DE44C /* RetroArch */ = { isa = PBXGroup; children = ( + 962979FF16C4767F00E6DCE0 /* dirent_list.c */, + 96297A0016C4767F00E6DCE0 /* dirent_list.h */, 962979EB16C3E86F00E6DCE0 /* gameview.m */, 962979EC16C3E86F00E6DCE0 /* gameview.h */, 96AFAE3C16C1D4EA009DE44C /* AppDelegate.h */, @@ -787,6 +792,7 @@ 9629797716C3CD2400E6DCE0 /* dirlist.m in Sources */, 962979ED16C3E86F00E6DCE0 /* gameview.m in Sources */, 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */, + 96297A0116C4767F00E6DCE0 /* dirent_list.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/dirent_list.c b/ios/RetroArch/dirent_list.c new file mode 100644 index 0000000000..c6ee5102e7 --- /dev/null +++ b/ios/RetroArch/dirent_list.c @@ -0,0 +1,97 @@ +#include +#include +#include + +#include "general.h" +#include "dirent_list.h" + +static int compare_dirent(const void *left, const void *right) +{ + const struct dirent* l = (const struct dirent*) left; + const struct dirent* r = (const struct dirent*) right; + + // Directories first + if (l->d_type != r->d_type) + return (l->d_type) ? -1 : 1; + + // Name + return strcmp(l->d_name, r->d_name); +} + +static bool is_dirent_verboten(const struct dirent* entry) +{ + if (!entry) return true; + if (strcmp(entry->d_name, ".") == 0) return true; + //if (strcmp(entry->d_name, "..") == 0) return true; + return false; +} + +struct dirent_list* build_dirent_list(const char* path) +{ + struct dirent_list* result = 0; + + DIR* dir = opendir(path); + if (dir) + { + struct dirent* ent = 0; + + // Count the number of items + size_t count = 0; + while ((ent = readdir(dir))) + { + count += is_dirent_verboten(ent) ? 0 : 1; + } + rewinddir(dir); + + // String buffer for 'stat'ing + char* stat_path = malloc(strlen(path) + sizeof(ent->d_name)); + strcpy(stat_path, path); + uint32_t last_index = strlen(stat_path); + + // Build and fill the result + result = malloc(sizeof(struct dirent_list)); + result->count = count; + result->entries = malloc(sizeof(struct dirent) * count); + + size_t index = 0; + while ((ent = readdir(dir))) + { + if (is_dirent_verboten(ent)) continue; + memcpy(&result->entries[index], ent, sizeof(struct dirent)); + + // Chage dirent.d_type to a boolean indication if it is a directory + struct stat stat_buf; + strcat(strcat(stat_path, "/"), ent->d_name); + stat(stat_path, &stat_buf); + result->entries[index].d_type = S_ISDIR(stat_buf.st_mode) ? 1 : 0; + stat_path[last_index] = 0; + + index ++; + } + + closedir(dir); + free(stat_path); + + qsort(result->entries, result->count, sizeof(struct dirent), &compare_dirent); + } + + return result; +} + +void free_dirent_list(struct dirent_list* list) +{ + if (list) free(list->entries); + free(list); +} + +const struct dirent* get_dirent_at_index(struct dirent_list* list, unsigned index) +{ + if (!list) return 0; + return (index < list->count) ? &list->entries[index] : 0; +} + +unsigned get_dirent_list_count(struct dirent_list* list) +{ + return list ? list->count : 0; +} + diff --git a/ios/RetroArch/dirent_list.h b/ios/RetroArch/dirent_list.h new file mode 100644 index 0000000000..0b0155f44e --- /dev/null +++ b/ios/RetroArch/dirent_list.h @@ -0,0 +1,33 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2013 - Hans-Kristian Arntzen + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#ifndef __RARCH_IOS_DIRENT_LIST_H +#define __RARCH_IOS_DIRENT_LIST_H + +#include + +struct dirent_list +{ + size_t count; + struct dirent* entries; +}; + +struct dirent_list* build_dirent_list(const char* path); +void free_dirent_list(struct dirent_list* list); + +const struct dirent* get_dirent_at_index(struct dirent_list* list, unsigned index); +unsigned get_dirent_list_count(struct dirent_list* list); + +#endif \ No newline at end of file diff --git a/ios/RetroArch/dirlist.m b/ios/RetroArch/dirlist.m index 2ddca5d5fa..8bbc489c48 100644 --- a/ios/RetroArch/dirlist.m +++ b/ios/RetroArch/dirlist.m @@ -6,100 +6,10 @@ // Copyright (c) 2013 RetroArch. All rights reserved. // -#include -#include +#include "dirent_list.h" #import "dirlist.h" #import "gameview.h" -struct dirent_list -{ - size_t count; - struct dirent* entries; -}; - -const struct dirent* get_dirent_at_index(struct dirent_list* list, unsigned index) -{ - if (!list) return 0; - return (index < list->count) ? &list->entries[index] : 0; -} - -unsigned get_dirent_list_count(struct dirent_list* list) -{ - return list ? list->count : 0; -} - -void free_dirent_list(struct dirent_list* list) -{ - if (list) free(list->entries); - free(list); -} - -static int compare_dirent(const void *left, const void *right) -{ - const struct dirent* l = (const struct dirent*) left; - const struct dirent* r = (const struct dirent*) right; - - // Directories first - if (l->d_type != r->d_type) - return (l->d_type) ? -1 : 1; - - // Name - return strcmp(l->d_name, r->d_name); -} - -struct dirent_list* build_dirent_list(const char* path) -{ - struct dirent_list* result = 0; - - DIR* dir = opendir(path); - if (dir) - { - struct dirent* ent = 0; - - // Count the number of items - size_t count = 0; - while ((ent = readdir(dir))) - { - count += (strcmp(ent->d_name, ".") ? 1 : 0); - } - rewinddir(dir); - - // String buffer for 'stat'ing - char* stat_path = malloc(strlen(path) + sizeof(ent->d_name)); - strcpy(stat_path, path); - uint32_t last_index = strlen(stat_path); - - // Build and fill the result - result = malloc(sizeof(struct dirent_list)); - result->count = count; - result->entries = malloc(sizeof(struct dirent) * count); - - size_t index = 0; - while ((ent = readdir(dir))) - { - if (strcmp(ent->d_name, ".") == 0) continue; - memcpy(&result->entries[index], ent, sizeof(struct dirent)); - - // Chage dirent.d_type to a boolean indication if it is a directory - struct stat stat_buf; - strcat(stat_path, "/"); - strcat(stat_path, ent->d_name); - stat(stat_path, &stat_buf); - result->entries[index].d_type = S_ISDIR(stat_buf.st_mode) ? 1 : 0; - stat_path[last_index] = 0; - - index ++; - } - - closedir(dir); - free(stat_path); - - qsort(result->entries, result->count, sizeof(struct dirent), &compare_dirent); - } - - return result; -} - @implementation dirlist_view { char path[4096]; @@ -146,7 +56,6 @@ struct dirent_list* build_dirent_list(const char* path) char* last_slash = strrchr(path, '/'); if (last_slash) *last_slash = 0; path[0] = (path[0] == 0) ? '/' : path[0]; - printf("%s\n", path); } else { @@ -170,7 +79,7 @@ struct dirent_list* build_dirent_list(const char* path) strcat(path, "/"); strcat(path, item->d_name); - extern void ios_load_game(const char*); + extern void ios_run_game(const char*); ios_load_game(path); } } diff --git a/ios/RetroArch/gameview.m b/ios/RetroArch/gameview.m index a191798ef3..7ced4be91c 100644 --- a/ios/RetroArch/gameview.m +++ b/ios/RetroArch/gameview.m @@ -23,23 +23,63 @@ static float screen_scale; static bool ra_initialized = false; static bool ra_done = false; +void ios_load_game(const char* file_name) +{ + if(!ra_initialized && file_name) + { + const char* libretro = [[[NSBundle mainBundle] pathForResource:@"libretro" ofType:@"dylib"] UTF8String]; + const char* overlay = [[[NSBundle mainBundle] pathForResource:@"overlay" ofType:@"cfg"] UTF8String]; + + strcpy(g_settings.input.overlay, overlay ? overlay : ""); + + const char* argv[] = {"retroarch", "-L", libretro, file_name, 0}; + if (rarch_main_init(6, (char**)argv) == 0) + { + rarch_init_msg_queue(); + ra_initialized = TRUE; + + [current_view performSelector:@selector(rarch_iterate:) withObject:nil afterDelay:0.2f]; + } + } +} + +void ios_close_game() +{ + if (ra_initialized) + { + rarch_main_deinit(); + rarch_deinit_msg_queue(); + +#ifdef PERF_TEST + rarch_perf_log(); +#endif + + rarch_main_clear_state(); + + ra_done = true; + } + + ra_initialized = false; +} + @implementation game_view { EAGLContext *gl_context; } -- (void)schedule_iterate -{ - if (ra_initialized && !ra_done) - [self performSelector:@selector(rarch_iterate:) withObject:nil afterDelay:0.002f]; -} - - (void)rarch_iterate:(id)sender { if (ra_initialized && !ra_done) - ra_done = !rarch_main_iterate(); - - [self schedule_iterate]; + { + while (!ra_done && rarch_main_iterate()) + { + while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource); + } + + ios_close_game(); + + ra_done = true; + } } - (void)viewDidLoad @@ -83,42 +123,3 @@ void get_game_view_size(unsigned *width, unsigned *height) *height = gl_view.bounds.size.height * screen_scale; } } - -void ios_close_game() -{ - if (ra_initialized) - { - rarch_main_deinit(); - rarch_deinit_msg_queue(); - -#ifdef PERF_TEST - rarch_perf_log(); -#endif - - rarch_main_clear_state(); - - ra_done = true; - } - - ra_initialized = false; -} - -void ios_load_game(const char* file_name) -{ - if(!ra_initialized && file_name) - { - const char* libretro = [[[NSBundle mainBundle] pathForResource:@"libretro" ofType:@"dylib"] UTF8String]; - const char* overlay = [[[NSBundle mainBundle] pathForResource:@"overlay" ofType:@"cfg"] UTF8String]; - - strcpy(g_settings.input.overlay, overlay ? overlay : ""); - - const char* argv[] = {"retroarch", "-L", libretro, file_name, 0}; - if (rarch_main_init(6, (char**)argv) == 0) - { - rarch_init_msg_queue(); - ra_initialized = TRUE; - - if (current_view) [current_view schedule_iterate]; - } - } -} From 1a236f4a6723c9457a8824403b5ac875c1efd877 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 7 Feb 2013 19:07:50 -0500 Subject: [PATCH 015/108] ios: Fix a couple of warnings --- ios/RetroArch/dirlist.m | 2 +- ios/RetroArch/gameview.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ios/RetroArch/dirlist.m b/ios/RetroArch/dirlist.m index 8bbc489c48..2088d55446 100644 --- a/ios/RetroArch/dirlist.m +++ b/ios/RetroArch/dirlist.m @@ -79,7 +79,7 @@ strcat(path, "/"); strcat(path, item->d_name); - extern void ios_run_game(const char*); + extern void ios_load_game(const char*); ios_load_game(path); } } diff --git a/ios/RetroArch/gameview.h b/ios/RetroArch/gameview.h index f5a7ed868b..5b82589110 100644 --- a/ios/RetroArch/gameview.h +++ b/ios/RetroArch/gameview.h @@ -9,5 +9,5 @@ #import @interface game_view : UIViewController -- (void)load_game:(const char*)file_name; + @end From 675468e9d6cd0ee2384d5202768917df3d200ff2 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 7 Feb 2013 19:10:46 -0500 Subject: [PATCH 016/108] ios: Enable the android portrait mode hack for ios too. --- gfx/gl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/gl.c b/gfx/gl.c index d4ec5e5eab..263cdc8549 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -725,7 +725,7 @@ void gl_set_viewport(void *data, unsigned width, unsigned height, bool force_ful gl->vp.height = height; } -#ifdef ANDROID +#if defined(ANDROID) || defined(IOS) // In portrait mode, we want viewport to gravitate to top of screen. if (device_aspect < 1.0f) gl->vp.y *= 2; From 7b3ebc30784dacaaa8fc6f1b597336b245c44af7 Mon Sep 17 00:00:00 2001 From: meancoot Date: Fri, 8 Feb 2013 15:43:19 -0500 Subject: [PATCH 017/108] ios: Use a UINavigationController to manage file browser history. --- ios/RetroArch.xcodeproj/project.pbxproj | 6 ++ ios/RetroArch/AppDelegate.m | 5 +- ios/RetroArch/browser.h | 14 +++++ ios/RetroArch/browser.m | 21 +++++++ ios/RetroArch/dirent_list.c | 2 +- ios/RetroArch/dirlist.h | 2 +- ios/RetroArch/dirlist.m | 83 ++++++++++++------------- 7 files changed, 86 insertions(+), 47 deletions(-) create mode 100644 ios/RetroArch/browser.h create mode 100644 ios/RetroArch/browser.m diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 27e3f32966..34b3f65c71 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; }; 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; }; 96297A0116C4767F00E6DCE0 /* dirent_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979FF16C4767F00E6DCE0 /* dirent_list.c */; }; + 96297A0516C4996400E6DCE0 /* browser.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0416C4996400E6DCE0 /* browser.m */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -89,6 +90,8 @@ 962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = ""; }; 962979FF16C4767F00E6DCE0 /* dirent_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dirent_list.c; sourceTree = ""; }; 96297A0016C4767F00E6DCE0 /* dirent_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dirent_list.h; sourceTree = ""; }; + 96297A0316C4996400E6DCE0 /* browser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = browser.h; sourceTree = ""; }; + 96297A0416C4996400E6DCE0 /* browser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = browser.m; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -345,6 +348,8 @@ 96CF015B16C2F72900ABF9C9 /* ios_input.c */, 9629797516C3CD2400E6DCE0 /* dirlist.h */, 9629797616C3CD2400E6DCE0 /* dirlist.m */, + 96297A0316C4996400E6DCE0 /* browser.h */, + 96297A0416C4996400E6DCE0 /* browser.m */, ); path = RetroArch; sourceTree = ""; @@ -793,6 +798,7 @@ 962979ED16C3E86F00E6DCE0 /* gameview.m in Sources */, 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */, 96297A0116C4767F00E6DCE0 /* dirent_list.c in Sources */, + 96297A0516C4996400E6DCE0 /* browser.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/AppDelegate.m b/ios/RetroArch/AppDelegate.m index 0bc7e022f6..2ae4f83424 100644 --- a/ios/RetroArch/AppDelegate.m +++ b/ios/RetroArch/AppDelegate.m @@ -7,6 +7,7 @@ #import "AppDelegate.h" #import "dirlist.h" +#import "browser.h" #define MAX_TOUCH 16 extern struct @@ -27,9 +28,9 @@ extern uint32_t ios_current_touch_count ; // Override point for customization after application launch. if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) - self.window.rootViewController = [[dirlist_view alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; + self.window.rootViewController = [[browser alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; else - self.window.rootViewController = [[dirlist_view alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; + self.window.rootViewController = [[browser alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; [self.window makeKeyAndVisible]; } diff --git a/ios/RetroArch/browser.h b/ios/RetroArch/browser.h new file mode 100644 index 0000000000..990c8caf64 --- /dev/null +++ b/ios/RetroArch/browser.h @@ -0,0 +1,14 @@ +// +// browser.h +// RetroArch +// +// Created by Jason Fetters on 2/7/13. +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +#import +#import + +@interface browser : UINavigationController + +@end diff --git a/ios/RetroArch/browser.m b/ios/RetroArch/browser.m new file mode 100644 index 0000000000..36e5e131e8 --- /dev/null +++ b/ios/RetroArch/browser.m @@ -0,0 +1,21 @@ +// +// browser.m +// RetroArch +// +// Created by Jason Fetters on 2/7/13. +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +#import "browser.h" +#import "dirlist.h" +@implementation browser + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + [self pushViewController:[[[dirlist_view alloc] init] load_path:"/" ] animated:NO]; +} + + +@end diff --git a/ios/RetroArch/dirent_list.c b/ios/RetroArch/dirent_list.c index c6ee5102e7..095d64ca80 100644 --- a/ios/RetroArch/dirent_list.c +++ b/ios/RetroArch/dirent_list.c @@ -22,7 +22,7 @@ static bool is_dirent_verboten(const struct dirent* entry) { if (!entry) return true; if (strcmp(entry->d_name, ".") == 0) return true; - //if (strcmp(entry->d_name, "..") == 0) return true; + if (strcmp(entry->d_name, "..") == 0) return true; return false; } diff --git a/ios/RetroArch/dirlist.h b/ios/RetroArch/dirlist.h index 147f763049..5e18b2a88e 100644 --- a/ios/RetroArch/dirlist.h +++ b/ios/RetroArch/dirlist.h @@ -8,5 +8,5 @@ #import @interface dirlist_view : UIViewController - +- (id)load_path:(const char*)directory; @end diff --git a/ios/RetroArch/dirlist.m b/ios/RetroArch/dirlist.m index 2088d55446..5da701f778 100644 --- a/ios/RetroArch/dirlist.m +++ b/ios/RetroArch/dirlist.m @@ -12,7 +12,8 @@ @implementation dirlist_view { - char path[4096]; + char* path; + UITableView* table; struct dirent_list* files; @@ -20,26 +21,43 @@ UIImage* folder_icon; }; --(void)dealloc +- (id)load_path:(const char*)directory { free_dirent_list(files); - files = 0; + files = build_dirent_list(directory); + [table reloadData]; + + free(path); + path = strdup(directory); + + [self setTitle: [[NSString alloc] initWithUTF8String:directory]]; + + return self; +} + +- (void)dealloc +{ + free_dirent_list(files); + free(path); } - (void)viewDidLoad { + [super viewDidLoad]; + file_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_file" ofType:@"png"]]; folder_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_dir" ofType:@"png"]]; - [super viewDidLoad]; - - strcpy(path, "/"); - files = build_dirent_list(path); - table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) style:UITableViewStylePlain]; table.dataSource = self; table.delegate = self; + self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] + initWithTitle:@"Parent" + style:UIBarButtonItemStyleBordered + target:nil action:nil]; + + self.view = table; } @@ -49,38 +67,27 @@ if (!item) return; + char new_path[4096]; + strcpy(new_path, path); + strcat(new_path, item->d_name); + if (item->d_type) { - if (strcmp(item->d_name, "..") == 0) - { - char* last_slash = strrchr(path, '/'); - if (last_slash) *last_slash = 0; - path[0] = (path[0] == 0) ? '/' : path[0]; - } - else - { - strcat(path, "/"); - strcat(path, item->d_name); - } + strcat(new_path, "/"); - free_dirent_list(files); - files = build_dirent_list(path); - [table reloadData]; + UINavigationController *pvc = (UINavigationController*)self.parentViewController; + [pvc pushViewController:[[[dirlist_view alloc] init] load_path: new_path] animated:YES]; } else { UIWindow *window = [UIApplication sharedApplication].keyWindow; - - if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) - window.rootViewController = [[game_view alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; - else - window.rootViewController = [[game_view alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; - - strcat(path, "/"); - strcat(path, item->d_name); + + bool is_phone = ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone); + window.rootViewController = [[game_view alloc] initWithNibName: + (is_phone ? @"ViewController_iPhone" : @"ViewController_iPad") bundle:nil]; extern void ios_load_game(const char*); - ios_load_game(path); + ios_load_game(new_path); } } @@ -99,18 +106,8 @@ if (item) { cell.textLabel.text = [[NSString string] initWithUTF8String:item->d_name]; - - if (item->d_type) - { - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - cell.imageView.image = folder_icon; - } - else - { - cell.accessoryType = UITableViewCellAccessoryNone; - cell.imageView.image = file_icon; - } - + cell.accessoryType = (item->d_type) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; + cell.imageView.image = (item->d_type) ? folder_icon : file_icon; [cell.imageView sizeToFit]; } From 23a3fe63bf3e2ac4c5b42319b72daf286cddce02 Mon Sep 17 00:00:00 2001 From: meancoot Date: Fri, 8 Feb 2013 15:50:55 -0500 Subject: [PATCH 018/108] ios: Apply a small patch to gfx/gl.c to allow HAVE_FBO to work. --- gfx/context/ioseagl_ctx.c | 8 ++++---- gfx/gl.c | 6 ++++++ ios/RetroArch.xcodeproj/project.pbxproj | 2 ++ ios/RetroArch/gameview.m | 12 ++++++++++-- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/gfx/context/ioseagl_ctx.c b/gfx/context/ioseagl_ctx.c index a445113f24..8140835a5d 100644 --- a/gfx/context/ioseagl_ctx.c +++ b/gfx/context/ioseagl_ctx.c @@ -39,8 +39,8 @@ static void gfx_ctx_destroy(void) static void gfx_ctx_get_video_size(unsigned *width, unsigned *height) { - extern void get_game_view_size(unsigned *, unsigned *); - get_game_view_size(width, height); + extern void ios_get_game_view_size(unsigned *, unsigned *); + ios_get_game_view_size(width, height); } static bool gfx_ctx_init(void) @@ -50,8 +50,8 @@ static bool gfx_ctx_init(void) static void gfx_ctx_swap_buffers(void) { - extern void flip_game_view(); - flip_game_view(); + extern void ios_flip_game_view(); + ios_flip_game_view(); } static void gfx_ctx_check_window(bool *quit, diff --git a/gfx/gl.c b/gfx/gl.c index 263cdc8549..1890cc8c49 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -867,7 +867,13 @@ static void gl_frame_fbo(void *data, const struct gl_tex_info *tex_info) set_texture_coords(fbo_tex_coords, xamt, yamt); // Render our FBO texture to back buffer. +#ifdef IOS + // There is no default frame buffer on IOS. + extern void ios_bind_game_view_fbo(); + ios_bind_game_view_fbo(); +#else pglBindFramebuffer(GL_FRAMEBUFFER, 0); +#endif gl_shader_use_func(gl, gl->fbo_pass + 1); glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[gl->fbo_pass - 1]); diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 34b3f65c71..550cae4aa6 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -874,6 +874,7 @@ "-DRARCH_PERFORMANCE_MODE", "-DPACKAGE_VERSION=\\\"1.0\\\"", "-std=gnu99", + "-DHAVE_FBO", ); SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; @@ -916,6 +917,7 @@ "-DRARCH_PERFORMANCE_MODE", "-DPACKAGE_VERSION=\\\"1.0\\\"", "-std=gnu99", + "-DHAVE_FBO", ); SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/ios/RetroArch/gameview.m b/ios/RetroArch/gameview.m index 7ced4be91c..8e63ea82f8 100644 --- a/ios/RetroArch/gameview.m +++ b/ios/RetroArch/gameview.m @@ -106,7 +106,7 @@ void ios_close_game() @end -void flip_game_view() +void ios_flip_game_view() { if (gl_view) { @@ -115,7 +115,7 @@ void flip_game_view() } } -void get_game_view_size(unsigned *width, unsigned *height) +void ios_get_game_view_size(unsigned *width, unsigned *height) { if (gl_view) { @@ -123,3 +123,11 @@ void get_game_view_size(unsigned *width, unsigned *height) *height = gl_view.bounds.size.height * screen_scale; } } + +void ios_bind_game_view_fbo() +{ + if (gl_view) + { + [gl_view bindDrawable]; + } +} From 83f0a9ec380b4b087c72603d8d354dd9826ba23d Mon Sep 17 00:00:00 2001 From: meancoot Date: Fri, 8 Feb 2013 17:03:19 -0500 Subject: [PATCH 019/108] ios: Add a module selector. --- ios/RetroArch.xcodeproj/project.pbxproj | 28 +++--- ios/RetroArch/AppDelegate.h | 14 --- ios/RetroArch/RetroArch-Prefix.pch | 1 + ios/RetroArch/RetroArch_iOS.h | 19 ++++ .../{AppDelegate.m => RetroArch_iOS.m} | 24 ++--- ios/RetroArch/browser.h | 14 --- ios/RetroArch/browser.m | 21 ----- ios/RetroArch/dirlist.m | 11 +-- ios/RetroArch/gameview.m | 4 +- ios/RetroArch/main.mm | 4 +- ios/RetroArch/module_list.h | 13 +++ ios/RetroArch/module_list.m | 90 +++++++++++++++++++ 12 files changed, 157 insertions(+), 86 deletions(-) delete mode 100644 ios/RetroArch/AppDelegate.h create mode 100644 ios/RetroArch/RetroArch_iOS.h rename ios/RetroArch/{AppDelegate.m => RetroArch_iOS.m} (76%) delete mode 100644 ios/RetroArch/browser.h delete mode 100644 ios/RetroArch/browser.m create mode 100644 ios/RetroArch/module_list.h create mode 100644 ios/RetroArch/module_list.m diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 550cae4aa6..3732d00cac 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -13,7 +13,8 @@ 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; }; 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; }; 96297A0116C4767F00E6DCE0 /* dirent_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979FF16C4767F00E6DCE0 /* dirent_list.c */; }; - 96297A0516C4996400E6DCE0 /* browser.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0416C4996400E6DCE0 /* browser.m */; }; + 96297A0916C59EC000E6DCE0 /* module_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0816C59EC000E6DCE0 /* module_list.m */; }; + 96297A0C16C5AD8D00E6DCE0 /* RetroArch_iOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -21,7 +22,6 @@ 96AFAE3216C1D4EA009DE44C /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE3116C1D4EA009DE44C /* OpenGLES.framework */; }; 96AFAE3816C1D4EA009DE44C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE3616C1D4EA009DE44C /* InfoPlist.strings */; }; 96AFAE3A16C1D4EA009DE44C /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAE3916C1D4EA009DE44C /* main.mm */; }; - 96AFAE3E16C1D4EA009DE44C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAE3D16C1D4EA009DE44C /* AppDelegate.m */; }; 96AFAE4016C1D4EA009DE44C /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE3F16C1D4EA009DE44C /* Default.png */; }; 96AFAE4216C1D4EA009DE44C /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4116C1D4EA009DE44C /* Default@2x.png */; }; 96AFAE4416C1D4EA009DE44C /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4316C1D4EA009DE44C /* Default-568h@2x.png */; }; @@ -75,7 +75,6 @@ 96AFAFAD16C1EEE9009DE44C /* sinc.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEF716C1DC73009DE44C /* sinc.c */; }; 96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFC916C1FBC0009DE44C /* input_common.c */; }; 96AFAFD716C1FBC0009DE44C /* null.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCD16C1FBC0009DE44C /* null.c */; }; - 96CF014F16C2BB9E00ABF9C9 /* libretro.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 96CF014A16C2BA1900ABF9C9 /* libretro.dylib */; }; 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCE16C1FBC0009DE44C /* overlay.c */; }; 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CF015B16C2F72900ABF9C9 /* ios_input.c */; }; /* End PBXBuildFile section */ @@ -90,8 +89,10 @@ 962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = ""; }; 962979FF16C4767F00E6DCE0 /* dirent_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dirent_list.c; sourceTree = ""; }; 96297A0016C4767F00E6DCE0 /* dirent_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dirent_list.h; sourceTree = ""; }; - 96297A0316C4996400E6DCE0 /* browser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = browser.h; sourceTree = ""; }; - 96297A0416C4996400E6DCE0 /* browser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = browser.m; sourceTree = ""; }; + 96297A0716C59EC000E6DCE0 /* module_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = module_list.h; sourceTree = ""; }; + 96297A0816C59EC000E6DCE0 /* module_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = module_list.m; sourceTree = ""; }; + 96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RetroArch_iOS.h; sourceTree = ""; }; + 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RetroArch_iOS.m; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -102,8 +103,6 @@ 96AFAE3716C1D4EA009DE44C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 96AFAE3916C1D4EA009DE44C /* main.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; }; 96AFAE3B16C1D4EA009DE44C /* RetroArch-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RetroArch-Prefix.pch"; sourceTree = ""; }; - 96AFAE3C16C1D4EA009DE44C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 96AFAE3D16C1D4EA009DE44C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 96AFAE3F16C1D4EA009DE44C /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 96AFAE4116C1D4EA009DE44C /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 96AFAE4316C1D4EA009DE44C /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; @@ -276,7 +275,6 @@ 96AFAFD016C1FBC0009DE44C /* sdl_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_input.c; sourceTree = ""; }; 96AFAFD116C1FBC0009DE44C /* sdl_joypad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_joypad.c; sourceTree = ""; }; 96AFAFD216C1FBC0009DE44C /* x11_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x11_input.c; sourceTree = ""; }; - 96CF014A16C2BA1900ABF9C9 /* libretro.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libretro.dylib; sourceTree = ""; }; 96CF015B16C2F72900ABF9C9 /* ios_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ios_input.c; sourceTree = ""; }; /* End PBXFileReference section */ @@ -303,7 +301,6 @@ children = ( 962979F416C43B9500E6DCE0 /* ic_dir.png */, 962979F516C43B9500E6DCE0 /* ic_file.png */, - 96CF014A16C2BA1900ABF9C9 /* libretro.dylib */, 96AFAF2116C1DF88009DE44C /* libz.dylib */, 96AFAF1E16C1DF0A009DE44C /* OpenAL.framework */, 96AFAE9C16C1D976009DE44C /* core */, @@ -336,20 +333,20 @@ 96AFAE3316C1D4EA009DE44C /* RetroArch */ = { isa = PBXGroup; children = ( + 96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */, + 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */, 962979FF16C4767F00E6DCE0 /* dirent_list.c */, 96297A0016C4767F00E6DCE0 /* dirent_list.h */, 962979EB16C3E86F00E6DCE0 /* gameview.m */, 962979EC16C3E86F00E6DCE0 /* gameview.h */, - 96AFAE3C16C1D4EA009DE44C /* AppDelegate.h */, - 96AFAE3D16C1D4EA009DE44C /* AppDelegate.m */, 96AFAE4C16C1D4EA009DE44C /* ViewController_iPhone.xib */, 96AFAE4F16C1D4EA009DE44C /* ViewController_iPad.xib */, 96AFAE3416C1D4EA009DE44C /* Supporting Files */, 96CF015B16C2F72900ABF9C9 /* ios_input.c */, 9629797516C3CD2400E6DCE0 /* dirlist.h */, 9629797616C3CD2400E6DCE0 /* dirlist.m */, - 96297A0316C4996400E6DCE0 /* browser.h */, - 96297A0416C4996400E6DCE0 /* browser.m */, + 96297A0716C59EC000E6DCE0 /* module_list.h */, + 96297A0816C59EC000E6DCE0 /* module_list.m */, ); path = RetroArch; sourceTree = ""; @@ -731,7 +728,6 @@ 96AFAE4416C1D4EA009DE44C /* Default-568h@2x.png in Resources */, 96AFAE4E16C1D4EA009DE44C /* ViewController_iPhone.xib in Resources */, 96AFAE5116C1D4EA009DE44C /* ViewController_iPad.xib in Resources */, - 96CF014F16C2BB9E00ABF9C9 /* libretro.dylib in Resources */, 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */, 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */, ); @@ -745,7 +741,6 @@ buildActionMask = 2147483647; files = ( 96AFAE3A16C1D4EA009DE44C /* main.mm in Sources */, - 96AFAE3E16C1D4EA009DE44C /* AppDelegate.m in Sources */, 96AFAECA16C1D9A9009DE44C /* autosave.c in Sources */, 96AFAECB16C1D9A9009DE44C /* cheats.c in Sources */, 96AFAECC16C1D9A9009DE44C /* command.c in Sources */, @@ -798,7 +793,8 @@ 962979ED16C3E86F00E6DCE0 /* gameview.m in Sources */, 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */, 96297A0116C4767F00E6DCE0 /* dirent_list.c in Sources */, - 96297A0516C4996400E6DCE0 /* browser.m in Sources */, + 96297A0916C59EC000E6DCE0 /* module_list.m in Sources */, + 96297A0C16C5AD8D00E6DCE0 /* RetroArch_iOS.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/AppDelegate.h b/ios/RetroArch/AppDelegate.h deleted file mode 100644 index a1c6c7f0ad..0000000000 --- a/ios/RetroArch/AppDelegate.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// AppDelegate.h -// RetroArch -// -// Copyright (c) 2013 RetroArch. All rights reserved. -// - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - -@end diff --git a/ios/RetroArch/RetroArch-Prefix.pch b/ios/RetroArch/RetroArch-Prefix.pch index 7a94ed3c55..a8848af140 100644 --- a/ios/RetroArch/RetroArch-Prefix.pch +++ b/ios/RetroArch/RetroArch-Prefix.pch @@ -11,4 +11,5 @@ #ifdef __OBJC__ #import #import + #import "RetroArch_iOS.h" #endif diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h new file mode 100644 index 0000000000..d8cb0c95c4 --- /dev/null +++ b/ios/RetroArch/RetroArch_iOS.h @@ -0,0 +1,19 @@ +// +// AppDelegate.h +// RetroArch +// +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +#import + +@interface RetroArch_iOS : UIResponder + ++ (RetroArch_iOS*)get; + +@property (strong, nonatomic) UIWindow *window; +@property (strong, nonatomic) NSString *module_path; +@property (strong, nonatomic) UINavigationController *navigator; +@property (strong, nonatomic) NSString *nib_name; + +@end diff --git a/ios/RetroArch/AppDelegate.m b/ios/RetroArch/RetroArch_iOS.m similarity index 76% rename from ios/RetroArch/AppDelegate.m rename to ios/RetroArch/RetroArch_iOS.m index 2ae4f83424..0643315a5c 100644 --- a/ios/RetroArch/AppDelegate.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -5,9 +5,8 @@ // Copyright (c) 2013 RetroArch. All rights reserved. // -#import "AppDelegate.h" #import "dirlist.h" -#import "browser.h" +#import "module_list.h" #define MAX_TOUCH 16 extern struct @@ -20,18 +19,23 @@ extern struct extern uint32_t ios_current_touch_count ; -@implementation AppDelegate +@implementation RetroArch_iOS + ++ (RetroArch_iOS*)get +{ + return (RetroArch_iOS*)[[UIApplication sharedApplication] delegate]; +} - (void)applicationDidFinishLaunching:(UIApplication *)application { - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + bool is_iphone = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone; + self.nib_name = is_iphone ? @"ViewController_iPhone" : @"ViewController_iPad"; - // Override point for customization after application launch. - if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) - self.window.rootViewController = [[browser alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; - else - self.window.rootViewController = [[browser alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; - + self.navigator = [[UINavigationController alloc] initWithNibName:self.nib_name bundle:nil]; + [self.navigator pushViewController: [[module_list alloc] initWithNibName:self.nib_name bundle:nil] animated:YES]; + + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + self.window.rootViewController = self.navigator; [self.window makeKeyAndVisible]; } diff --git a/ios/RetroArch/browser.h b/ios/RetroArch/browser.h deleted file mode 100644 index 990c8caf64..0000000000 --- a/ios/RetroArch/browser.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// browser.h -// RetroArch -// -// Created by Jason Fetters on 2/7/13. -// Copyright (c) 2013 RetroArch. All rights reserved. -// - -#import -#import - -@interface browser : UINavigationController - -@end diff --git a/ios/RetroArch/browser.m b/ios/RetroArch/browser.m deleted file mode 100644 index 36e5e131e8..0000000000 --- a/ios/RetroArch/browser.m +++ /dev/null @@ -1,21 +0,0 @@ -// -// browser.m -// RetroArch -// -// Created by Jason Fetters on 2/7/13. -// Copyright (c) 2013 RetroArch. All rights reserved. -// - -#import "browser.h" -#import "dirlist.h" -@implementation browser - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - [self pushViewController:[[[dirlist_view alloc] init] load_path:"/" ] animated:NO]; -} - - -@end diff --git a/ios/RetroArch/dirlist.m b/ios/RetroArch/dirlist.m index 5da701f778..bfeb8ce0c0 100644 --- a/ios/RetroArch/dirlist.m +++ b/ios/RetroArch/dirlist.m @@ -75,16 +75,13 @@ { strcat(new_path, "/"); - UINavigationController *pvc = (UINavigationController*)self.parentViewController; - [pvc pushViewController:[[[dirlist_view alloc] init] load_path: new_path] animated:YES]; + [[RetroArch_iOS get].navigator pushViewController:[[[dirlist_view alloc] init] load_path: new_path] animated:YES]; } else { - UIWindow *window = [UIApplication sharedApplication].keyWindow; - - bool is_phone = ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone); - window.rootViewController = [[game_view alloc] initWithNibName: - (is_phone ? @"ViewController_iPhone" : @"ViewController_iPad") bundle:nil]; + [RetroArch_iOS get].window.rootViewController = [[game_view alloc] + initWithNibName: [RetroArch_iOS get].nib_name + bundle:nil]; extern void ios_load_game(const char*); ios_load_game(new_path); diff --git a/ios/RetroArch/gameview.m b/ios/RetroArch/gameview.m index 8e63ea82f8..1b16e5a000 100644 --- a/ios/RetroArch/gameview.m +++ b/ios/RetroArch/gameview.m @@ -27,8 +27,10 @@ void ios_load_game(const char* file_name) { if(!ra_initialized && file_name) { - const char* libretro = [[[NSBundle mainBundle] pathForResource:@"libretro" ofType:@"dylib"] UTF8String]; + const char* libretro = [[RetroArch_iOS get].module_path UTF8String]; const char* overlay = [[[NSBundle mainBundle] pathForResource:@"overlay" ofType:@"cfg"] UTF8String]; + + printf("%s\n", overlay); strcpy(g_settings.input.overlay, overlay ? overlay : ""); diff --git a/ios/RetroArch/main.mm b/ios/RetroArch/main.mm index 5f122bee14..04cc63c413 100644 --- a/ios/RetroArch/main.mm +++ b/ios/RetroArch/main.mm @@ -7,11 +7,9 @@ #import -#import "AppDelegate.h" - int main(int argc, char *argv[]) { @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + return UIApplicationMain(argc, argv, nil, NSStringFromClass([RetroArch_iOS class])); } } diff --git a/ios/RetroArch/module_list.h b/ios/RetroArch/module_list.h new file mode 100644 index 0000000000..42733d5a4c --- /dev/null +++ b/ios/RetroArch/module_list.h @@ -0,0 +1,13 @@ +// +// module_list.h +// RetroArch +// +// Created by Jason Fetters on 2/8/13. +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +#import + +@interface module_list : UIViewController + +@end diff --git a/ios/RetroArch/module_list.m b/ios/RetroArch/module_list.m new file mode 100644 index 0000000000..99c167026c --- /dev/null +++ b/ios/RetroArch/module_list.m @@ -0,0 +1,90 @@ +// +// module_list.m +// RetroArch +// +// Created by Jason Fetters on 2/8/13. +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +#import "module_list.h" +#import "dirlist.h" + +@interface module_list () + +@end + +@implementation module_list +{ + UITableView* table; + + NSString* module_dir; + NSMutableArray* modules; +}; + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + // Get the contents of the modules directory of the bundle. + module_dir = [NSString stringWithFormat:@"%@/%@", + [[NSBundle mainBundle] bundlePath], + @"modules"]; + + NSArray *module_list = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:module_dir error:nil]; + + if (module_list == nil || [module_list count] == 0) + { + // TODO: Handle error! + } + + // Remove non .dylib files from the list + modules = [NSMutableArray arrayWithArray:module_list]; + for (int i = 0; i < [modules count];) + { + if (![[modules objectAtIndex:i] hasSuffix:@".dylib"]) + { + [modules removeObjectAtIndex:i]; + } + else + { + i ++; + } + } + + [self setTitle:@"Choose Emulator"]; + table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) style:UITableViewStylePlain]; + table.dataSource = self; + table.delegate = self; + self.view = table; + + self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] + initWithTitle:@"Parent" + style:UIBarButtonItemStyleBordered + target:nil action:nil]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [RetroArch_iOS get].module_path = [NSString stringWithFormat:@"%@/%@", module_dir, [modules objectAtIndex:indexPath.row]]; + [[RetroArch_iOS get].navigator pushViewController:[[[dirlist_view alloc] init] load_path:"/"] animated:YES]; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return modules ? [modules count] : 0; +} + +- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell* cell = [table dequeueReusableCellWithIdentifier:@"module"]; + cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"module"]; + + if (modules) + { + cell.textLabel.text = [modules objectAtIndex:indexPath.row]; + } + + return cell; +} + +@end From 0e29ad3af23ec9928a1f5121f2c75fda93837adc Mon Sep 17 00:00:00 2001 From: meancoot Date: Fri, 8 Feb 2013 17:12:21 -0500 Subject: [PATCH 020/108] ios: Some source cleanup and small header merging. --- ios/RetroArch.xcodeproj/project.pbxproj | 32 ++++++++----------- ios/RetroArch/RetroArch-Prefix.pch | 1 + ios/RetroArch/RetroArch_iOS.m | 3 -- ios/RetroArch/{dirlist.m => directory_list.m} | 6 ++-- ios/RetroArch/dirlist.h | 12 ------- ios/RetroArch/{gameview.m => game_view.m} | 1 - ios/RetroArch/gameview.h | 13 -------- ios/RetroArch/{main.mm => main.m} | 0 ios/RetroArch/module_list.h | 13 -------- ios/RetroArch/module_list.m | 9 +----- ios/RetroArch/views.h | 14 ++++++++ 11 files changed, 32 insertions(+), 72 deletions(-) rename ios/RetroArch/{dirlist.m => directory_list.m} (93%) delete mode 100644 ios/RetroArch/dirlist.h rename ios/RetroArch/{gameview.m => game_view.m} (99%) delete mode 100644 ios/RetroArch/gameview.h rename ios/RetroArch/{main.mm => main.m} (100%) delete mode 100644 ios/RetroArch/module_list.h create mode 100644 ios/RetroArch/views.h diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 3732d00cac..bd2b800d9f 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -7,21 +7,21 @@ objects = { /* Begin PBXBuildFile section */ - 9629797716C3CD2400E6DCE0 /* dirlist.m in Sources */ = {isa = PBXBuildFile; fileRef = 9629797616C3CD2400E6DCE0 /* dirlist.m */; }; - 962979ED16C3E86F00E6DCE0 /* gameview.m in Sources */ = {isa = PBXBuildFile; fileRef = 962979EB16C3E86F00E6DCE0 /* gameview.m */; }; 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */; }; 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; }; 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; }; 96297A0116C4767F00E6DCE0 /* dirent_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979FF16C4767F00E6DCE0 /* dirent_list.c */; }; 96297A0916C59EC000E6DCE0 /* module_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0816C59EC000E6DCE0 /* module_list.m */; }; 96297A0C16C5AD8D00E6DCE0 /* RetroArch_iOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */; }; + 96297A0F16C5AEA100E6DCE0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0E16C5AEA100E6DCE0 /* main.m */; }; + 96297A1116C5AEDE00E6DCE0 /* game_view.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A1016C5AEDE00E6DCE0 /* game_view.m */; }; + 96297A1316C5AEFD00E6DCE0 /* directory_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A1216C5AEFD00E6DCE0 /* directory_list.m */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; 96AFAE3016C1D4EA009DE44C /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2F16C1D4EA009DE44C /* GLKit.framework */; }; 96AFAE3216C1D4EA009DE44C /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE3116C1D4EA009DE44C /* OpenGLES.framework */; }; 96AFAE3816C1D4EA009DE44C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE3616C1D4EA009DE44C /* InfoPlist.strings */; }; - 96AFAE3A16C1D4EA009DE44C /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAE3916C1D4EA009DE44C /* main.mm */; }; 96AFAE4016C1D4EA009DE44C /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE3F16C1D4EA009DE44C /* Default.png */; }; 96AFAE4216C1D4EA009DE44C /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4116C1D4EA009DE44C /* Default@2x.png */; }; 96AFAE4416C1D4EA009DE44C /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4316C1D4EA009DE44C /* Default-568h@2x.png */; }; @@ -80,19 +80,18 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 9629797516C3CD2400E6DCE0 /* dirlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dirlist.h; sourceTree = ""; }; - 9629797616C3CD2400E6DCE0 /* dirlist.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = dirlist.m; sourceTree = ""; }; - 962979EB16C3E86F00E6DCE0 /* gameview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = gameview.m; sourceTree = ""; }; - 962979EC16C3E86F00E6DCE0 /* gameview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gameview.h; sourceTree = ""; }; 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioseagl_ctx.c; sourceTree = ""; }; 962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = ""; }; 962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = ""; }; 962979FF16C4767F00E6DCE0 /* dirent_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dirent_list.c; sourceTree = ""; }; 96297A0016C4767F00E6DCE0 /* dirent_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dirent_list.h; sourceTree = ""; }; - 96297A0716C59EC000E6DCE0 /* module_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = module_list.h; sourceTree = ""; }; 96297A0816C59EC000E6DCE0 /* module_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = module_list.m; sourceTree = ""; }; 96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RetroArch_iOS.h; sourceTree = ""; }; 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RetroArch_iOS.m; sourceTree = ""; }; + 96297A0D16C5ADDA00E6DCE0 /* views.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = views.h; sourceTree = ""; }; + 96297A0E16C5AEA100E6DCE0 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 96297A1016C5AEDE00E6DCE0 /* game_view.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = game_view.m; sourceTree = ""; }; + 96297A1216C5AEFD00E6DCE0 /* directory_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = directory_list.m; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -101,7 +100,6 @@ 96AFAE3116C1D4EA009DE44C /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; 96AFAE3516C1D4EA009DE44C /* RetroArch-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RetroArch-Info.plist"; sourceTree = ""; }; 96AFAE3716C1D4EA009DE44C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - 96AFAE3916C1D4EA009DE44C /* main.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; }; 96AFAE3B16C1D4EA009DE44C /* RetroArch-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RetroArch-Prefix.pch"; sourceTree = ""; }; 96AFAE3F16C1D4EA009DE44C /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 96AFAE4116C1D4EA009DE44C /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; @@ -333,19 +331,17 @@ 96AFAE3316C1D4EA009DE44C /* RetroArch */ = { isa = PBXGroup; children = ( + 96297A1216C5AEFD00E6DCE0 /* directory_list.m */, + 96297A1016C5AEDE00E6DCE0 /* game_view.m */, + 96297A0D16C5ADDA00E6DCE0 /* views.h */, 96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */, 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */, 962979FF16C4767F00E6DCE0 /* dirent_list.c */, 96297A0016C4767F00E6DCE0 /* dirent_list.h */, - 962979EB16C3E86F00E6DCE0 /* gameview.m */, - 962979EC16C3E86F00E6DCE0 /* gameview.h */, 96AFAE4C16C1D4EA009DE44C /* ViewController_iPhone.xib */, 96AFAE4F16C1D4EA009DE44C /* ViewController_iPad.xib */, 96AFAE3416C1D4EA009DE44C /* Supporting Files */, 96CF015B16C2F72900ABF9C9 /* ios_input.c */, - 9629797516C3CD2400E6DCE0 /* dirlist.h */, - 9629797616C3CD2400E6DCE0 /* dirlist.m */, - 96297A0716C59EC000E6DCE0 /* module_list.h */, 96297A0816C59EC000E6DCE0 /* module_list.m */, ); path = RetroArch; @@ -354,9 +350,9 @@ 96AFAE3416C1D4EA009DE44C /* Supporting Files */ = { isa = PBXGroup; children = ( + 96297A0E16C5AEA100E6DCE0 /* main.m */, 96AFAE3516C1D4EA009DE44C /* RetroArch-Info.plist */, 96AFAE3616C1D4EA009DE44C /* InfoPlist.strings */, - 96AFAE3916C1D4EA009DE44C /* main.mm */, 96AFAE3B16C1D4EA009DE44C /* RetroArch-Prefix.pch */, 96AFAE3F16C1D4EA009DE44C /* Default.png */, 96AFAE4116C1D4EA009DE44C /* Default@2x.png */, @@ -740,7 +736,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 96AFAE3A16C1D4EA009DE44C /* main.mm in Sources */, 96AFAECA16C1D9A9009DE44C /* autosave.c in Sources */, 96AFAECB16C1D9A9009DE44C /* cheats.c in Sources */, 96AFAECC16C1D9A9009DE44C /* command.c in Sources */, @@ -789,12 +784,13 @@ 96AFAFD716C1FBC0009DE44C /* null.c in Sources */, 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */, 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */, - 9629797716C3CD2400E6DCE0 /* dirlist.m in Sources */, - 962979ED16C3E86F00E6DCE0 /* gameview.m in Sources */, 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */, 96297A0116C4767F00E6DCE0 /* dirent_list.c in Sources */, 96297A0916C59EC000E6DCE0 /* module_list.m in Sources */, 96297A0C16C5AD8D00E6DCE0 /* RetroArch_iOS.m in Sources */, + 96297A0F16C5AEA100E6DCE0 /* main.m in Sources */, + 96297A1116C5AEDE00E6DCE0 /* game_view.m in Sources */, + 96297A1316C5AEFD00E6DCE0 /* directory_list.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/RetroArch-Prefix.pch b/ios/RetroArch/RetroArch-Prefix.pch index a8848af140..ce1bb8668a 100644 --- a/ios/RetroArch/RetroArch-Prefix.pch +++ b/ios/RetroArch/RetroArch-Prefix.pch @@ -12,4 +12,5 @@ #import #import #import "RetroArch_iOS.h" + #import "views.h" #endif diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 0643315a5c..f15015cb95 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -5,9 +5,6 @@ // Copyright (c) 2013 RetroArch. All rights reserved. // -#import "dirlist.h" -#import "module_list.h" - #define MAX_TOUCH 16 extern struct { diff --git a/ios/RetroArch/dirlist.m b/ios/RetroArch/directory_list.m similarity index 93% rename from ios/RetroArch/dirlist.m rename to ios/RetroArch/directory_list.m index bfeb8ce0c0..3e8d2b04be 100644 --- a/ios/RetroArch/dirlist.m +++ b/ios/RetroArch/directory_list.m @@ -7,10 +7,8 @@ // #include "dirent_list.h" -#import "dirlist.h" -#import "gameview.h" -@implementation dirlist_view +@implementation directory_list { char* path; @@ -75,7 +73,7 @@ { strcat(new_path, "/"); - [[RetroArch_iOS get].navigator pushViewController:[[[dirlist_view alloc] init] load_path: new_path] animated:YES]; + [[RetroArch_iOS get].navigator pushViewController:[[[directory_list alloc] init] load_path: new_path] animated:YES]; } else { diff --git a/ios/RetroArch/dirlist.h b/ios/RetroArch/dirlist.h deleted file mode 100644 index 5e18b2a88e..0000000000 --- a/ios/RetroArch/dirlist.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// UIViewController_m.h -// RetroArch -// -// Copyright (c) 2013 RetroArch. All rights reserved. -// - -#import - -@interface dirlist_view : UIViewController -- (id)load_path:(const char*)directory; -@end diff --git a/ios/RetroArch/gameview.m b/ios/RetroArch/game_view.m similarity index 99% rename from ios/RetroArch/gameview.m rename to ios/RetroArch/game_view.m index 1b16e5a000..ef1e8b77ba 100644 --- a/ios/RetroArch/gameview.m +++ b/ios/RetroArch/game_view.m @@ -14,7 +14,6 @@ * If not, see . */ -#import "gameview.h" #include "general.h" static game_view *current_view; diff --git a/ios/RetroArch/gameview.h b/ios/RetroArch/gameview.h deleted file mode 100644 index 5b82589110..0000000000 --- a/ios/RetroArch/gameview.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// ViewController.h -// RetroArch -// -// Copyright (c) 2013 RetroArch. All rights reserved. -// - -#import -#import - -@interface game_view : UIViewController - -@end diff --git a/ios/RetroArch/main.mm b/ios/RetroArch/main.m similarity index 100% rename from ios/RetroArch/main.mm rename to ios/RetroArch/main.m diff --git a/ios/RetroArch/module_list.h b/ios/RetroArch/module_list.h deleted file mode 100644 index 42733d5a4c..0000000000 --- a/ios/RetroArch/module_list.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// module_list.h -// RetroArch -// -// Created by Jason Fetters on 2/8/13. -// Copyright (c) 2013 RetroArch. All rights reserved. -// - -#import - -@interface module_list : UIViewController - -@end diff --git a/ios/RetroArch/module_list.m b/ios/RetroArch/module_list.m index 99c167026c..15369f55fc 100644 --- a/ios/RetroArch/module_list.m +++ b/ios/RetroArch/module_list.m @@ -6,13 +6,6 @@ // Copyright (c) 2013 RetroArch. All rights reserved. // -#import "module_list.h" -#import "dirlist.h" - -@interface module_list () - -@end - @implementation module_list { UITableView* table; @@ -66,7 +59,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [RetroArch_iOS get].module_path = [NSString stringWithFormat:@"%@/%@", module_dir, [modules objectAtIndex:indexPath.row]]; - [[RetroArch_iOS get].navigator pushViewController:[[[dirlist_view alloc] init] load_path:"/"] animated:YES]; + [[RetroArch_iOS get].navigator pushViewController:[[[directory_list alloc] init] load_path:"/"] animated:YES]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h new file mode 100644 index 0000000000..5b4f321ddd --- /dev/null +++ b/ios/RetroArch/views.h @@ -0,0 +1,14 @@ +#import +#import + +@interface game_view : UIViewController + +@end + +@interface module_list : UIViewController + +@end + +@interface directory_list : UIViewController +- (id)load_path:(const char*)directory; +@end From b4814a96f25b426474e99a42141223cdb4c1120e Mon Sep 17 00:00:00 2001 From: meancoot Date: Fri, 8 Feb 2013 19:42:41 -0500 Subject: [PATCH 021/108] ios: Add a system directory '/var/mobile/Library/RetroArch' All save games are store there. It is also searched for a retroarch.cfg file. If you want to run in the simulator you will need to create and give yourself access to this directory manually. --- ios/RetroArch/RetroArch_iOS.h | 4 ++++ ios/RetroArch/RetroArch_iOS.m | 10 ++++++++++ ios/RetroArch/directory_list.m | 8 +------- ios/RetroArch/game_view.m | 13 +++++++------ 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index d8cb0c95c4..c9cd7f427a 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -15,5 +15,9 @@ @property (strong, nonatomic) NSString *module_path; @property (strong, nonatomic) UINavigationController *navigator; @property (strong, nonatomic) NSString *nib_name; +@property (strong, nonatomic) UIImage* file_icon; +@property (strong, nonatomic) UIImage* folder_icon; + +@property const char* system_directory; @end diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index f15015cb95..26acd373d2 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -5,6 +5,8 @@ // Copyright (c) 2013 RetroArch. All rights reserved. // +#include + #define MAX_TOUCH 16 extern struct { @@ -25,8 +27,16 @@ extern uint32_t ios_current_touch_count ; - (void)applicationDidFinishLaunching:(UIApplication *)application { + // TODO: Relocate this! + self.system_directory = "/var/mobile/Library/RetroArch/"; + mkdir(self.system_directory, 0755); + bool is_iphone = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone; self.nib_name = is_iphone ? @"ViewController_iPhone" : @"ViewController_iPad"; + + self.file_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_file" ofType:@"png"]]; + self.folder_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_dir" ofType:@"png"]]; + self.navigator = [[UINavigationController alloc] initWithNibName:self.nib_name bundle:nil]; [self.navigator pushViewController: [[module_list alloc] initWithNibName:self.nib_name bundle:nil] animated:YES]; diff --git a/ios/RetroArch/directory_list.m b/ios/RetroArch/directory_list.m index 3e8d2b04be..33a3e8f5f4 100644 --- a/ios/RetroArch/directory_list.m +++ b/ios/RetroArch/directory_list.m @@ -14,9 +14,6 @@ UITableView* table; struct dirent_list* files; - - UIImage* file_icon; - UIImage* folder_icon; }; - (id)load_path:(const char*)directory @@ -43,9 +40,6 @@ { [super viewDidLoad]; - file_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_file" ofType:@"png"]]; - folder_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_dir" ofType:@"png"]]; - table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) style:UITableViewStylePlain]; table.dataSource = self; table.delegate = self; @@ -102,7 +96,7 @@ { cell.textLabel.text = [[NSString string] initWithUTF8String:item->d_name]; cell.accessoryType = (item->d_type) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; - cell.imageView.image = (item->d_type) ? folder_icon : file_icon; + cell.imageView.image = (item->d_type) ? [RetroArch_iOS get].folder_icon : [RetroArch_iOS get].file_icon; [cell.imageView sizeToFit]; } diff --git a/ios/RetroArch/game_view.m b/ios/RetroArch/game_view.m index ef1e8b77ba..95c3aa46f8 100644 --- a/ios/RetroArch/game_view.m +++ b/ios/RetroArch/game_view.m @@ -26,15 +26,16 @@ void ios_load_game(const char* file_name) { if(!ra_initialized && file_name) { + const char* const sd = [RetroArch_iOS get].system_directory; const char* libretro = [[RetroArch_iOS get].module_path UTF8String]; - const char* overlay = [[[NSBundle mainBundle] pathForResource:@"overlay" ofType:@"cfg"] UTF8String]; - - printf("%s\n", overlay); - strcpy(g_settings.input.overlay, overlay ? overlay : ""); + char config_path[PATH_MAX]; + snprintf(config_path, PATH_MAX, "%s/retroarch.cfg", sd); + config_path[PATH_MAX - 1] = 0; + bool have_config = 0 == access(config_path, R_OK); - const char* argv[] = {"retroarch", "-L", libretro, file_name, 0}; - if (rarch_main_init(6, (char**)argv) == 0) + struct rarch_main_wrap main_wrapper = {file_name, sd, sd, have_config ? config_path : 0, libretro}; + if (rarch_main_init_wrap(&main_wrapper) == 0) { rarch_init_msg_queue(); ra_initialized = TRUE; From de05d7d7fb5866f0a9bec04d4c2b274f22e58978 Mon Sep 17 00:00:00 2001 From: meancoot Date: Fri, 8 Feb 2013 20:35:19 -0500 Subject: [PATCH 022/108] ios: Add a hack to skip frames when video non-block is used, this allows the fast forward function to be used. --- gfx/context/ioseagl_ctx.c | 3 ++- ios/RetroArch/game_view.m | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/gfx/context/ioseagl_ctx.c b/gfx/context/ioseagl_ctx.c index 8140835a5d..106eb3d242 100644 --- a/gfx/context/ioseagl_ctx.c +++ b/gfx/context/ioseagl_ctx.c @@ -29,7 +29,8 @@ // C interface static void gfx_ctx_set_swap_interval(unsigned interval) { - RARCH_LOG("gfx_ctx_set_swap_interval not supported.\n"); + extern void ios_set_game_view_sync(bool on); + ios_set_game_view_sync(interval ? true : false); } static void gfx_ctx_destroy(void) diff --git a/ios/RetroArch/game_view.m b/ios/RetroArch/game_view.m index 95c3aa46f8..ef16a371ea 100644 --- a/ios/RetroArch/game_view.m +++ b/ios/RetroArch/game_view.m @@ -21,6 +21,8 @@ static GLKView *gl_view; static float screen_scale; static bool ra_initialized = false; static bool ra_done = false; +static int frame_skips = 4; +static bool is_syncing = true; void ios_load_game(const char* file_name) { @@ -112,11 +114,21 @@ void ios_flip_game_view() { if (gl_view) { - [gl_view setNeedsDisplay]; - [gl_view bindDrawable]; + if (--frame_skips < 0) + { + [gl_view setNeedsDisplay]; + [gl_view bindDrawable]; + frame_skips = is_syncing ? 0 : 3; + } } } +void ios_set_game_view_sync(bool on) +{ + is_syncing = on; + frame_skips = on ? 0 : 3; +} + void ios_get_game_view_size(unsigned *width, unsigned *height) { if (gl_view) From 291220aa5457060d9d4ce55ae0352be8e034aa08 Mon Sep 17 00:00:00 2001 From: meancoot Date: Fri, 8 Feb 2013 22:18:42 -0500 Subject: [PATCH 023/108] ios: File browser tweaks. The title is now just the last component of the path. The custom back button text is removed. A settings button is added to the right of the navigation bar. --- ios/RetroArch/RetroArch_iOS.h | 1 + ios/RetroArch/RetroArch_iOS.m | 7 +++++++ ios/RetroArch/directory_list.m | 8 ++------ ios/RetroArch/module_list.m | 5 +---- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index c9cd7f427a..3d55e4069e 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -17,6 +17,7 @@ @property (strong, nonatomic) NSString *nib_name; @property (strong, nonatomic) UIImage* file_icon; @property (strong, nonatomic) UIImage* folder_icon; +@property (strong, nonatomic) UIBarButtonItem* settings_button; @property const char* system_directory; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 26acd373d2..f69f5c56e4 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -34,9 +34,16 @@ extern uint32_t ios_current_touch_count ; bool is_iphone = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone; self.nib_name = is_iphone ? @"ViewController_iPhone" : @"ViewController_iPad"; + // Load icons self.file_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_file" ofType:@"png"]]; self.folder_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_dir" ofType:@"png"]]; + // Load buttons + self.settings_button = [[UIBarButtonItem alloc] + initWithTitle:@"Settings" + style:UIBarButtonItemStyleBordered + target:nil action:nil]; + self.navigator = [[UINavigationController alloc] initWithNibName:self.nib_name bundle:nil]; [self.navigator pushViewController: [[module_list alloc] initWithNibName:self.nib_name bundle:nil] animated:YES]; diff --git a/ios/RetroArch/directory_list.m b/ios/RetroArch/directory_list.m index 33a3e8f5f4..62aa9397a3 100644 --- a/ios/RetroArch/directory_list.m +++ b/ios/RetroArch/directory_list.m @@ -25,7 +25,7 @@ free(path); path = strdup(directory); - [self setTitle: [[NSString alloc] initWithUTF8String:directory]]; + [self setTitle: [[[NSString alloc] initWithUTF8String:directory] lastPathComponent]]; return self; } @@ -44,11 +44,7 @@ table.dataSource = self; table.delegate = self; - self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] - initWithTitle:@"Parent" - style:UIBarButtonItemStyleBordered - target:nil action:nil]; - + self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; self.view = table; } diff --git a/ios/RetroArch/module_list.m b/ios/RetroArch/module_list.m index 15369f55fc..68ed5ee5a0 100644 --- a/ios/RetroArch/module_list.m +++ b/ios/RetroArch/module_list.m @@ -50,10 +50,7 @@ table.delegate = self; self.view = table; - self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] - initWithTitle:@"Parent" - style:UIBarButtonItemStyleBordered - target:nil action:nil]; + self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath From 4d9233b02ab827c8c3a17abc1dde9bf21c086ffc Mon Sep 17 00:00:00 2001 From: meancoot Date: Fri, 8 Feb 2013 23:58:22 -0500 Subject: [PATCH 024/108] ios: Made things more simple. --- ios/RetroArch/RetroArch_iOS.h | 1 - ios/RetroArch/RetroArch_iOS.m | 9 ++---- ios/RetroArch/directory_list.m | 50 ++++++++++-------------------- ios/RetroArch/game_view.m | 47 +++++++++++++++------------- ios/RetroArch/module_list.m | 56 +++++++++------------------------- ios/RetroArch/views.h | 6 ++-- 6 files changed, 62 insertions(+), 107 deletions(-) diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index 3d55e4069e..8d137eab63 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -14,7 +14,6 @@ @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) NSString *module_path; @property (strong, nonatomic) UINavigationController *navigator; -@property (strong, nonatomic) NSString *nib_name; @property (strong, nonatomic) UIImage* file_icon; @property (strong, nonatomic) UIImage* folder_icon; @property (strong, nonatomic) UIBarButtonItem* settings_button; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index f69f5c56e4..e10fd59b64 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -30,9 +30,6 @@ extern uint32_t ios_current_touch_count ; // TODO: Relocate this! self.system_directory = "/var/mobile/Library/RetroArch/"; mkdir(self.system_directory, 0755); - - bool is_iphone = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone; - self.nib_name = is_iphone ? @"ViewController_iPhone" : @"ViewController_iPad"; // Load icons self.file_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_file" ofType:@"png"]]; @@ -44,9 +41,9 @@ extern uint32_t ios_current_touch_count ; style:UIBarButtonItemStyleBordered target:nil action:nil]; - - self.navigator = [[UINavigationController alloc] initWithNibName:self.nib_name bundle:nil]; - [self.navigator pushViewController: [[module_list alloc] initWithNibName:self.nib_name bundle:nil] animated:YES]; + // Setup window + self.navigator = [[UINavigationController alloc] init]; + [self.navigator pushViewController: [[module_list alloc] init] animated:YES]; self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.rootViewController = self.navigator; diff --git a/ios/RetroArch/directory_list.m b/ios/RetroArch/directory_list.m index 62aa9397a3..d3abc836ec 100644 --- a/ios/RetroArch/directory_list.m +++ b/ios/RetroArch/directory_list.m @@ -10,21 +10,18 @@ @implementation directory_list { - char* path; - - UITableView* table; + char* directory; struct dirent_list* files; }; -- (id)load_path:(const char*)directory +- (id)initWithPath:(const char*)path { - free_dirent_list(files); + self = [super initWithStyle:UITableViewStylePlain]; + + directory = strdup(path); files = build_dirent_list(directory); - [table reloadData]; - - free(path); - path = strdup(directory); - + + self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; [self setTitle: [[[NSString alloc] initWithUTF8String:directory] lastPathComponent]]; return self; @@ -33,20 +30,7 @@ - (void)dealloc { free_dirent_list(files); - free(path); -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) style:UITableViewStylePlain]; - table.dataSource = self; - table.delegate = self; - - self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; - - self.view = table; + free(directory); } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath @@ -56,20 +40,18 @@ if (!item) return; char new_path[4096]; - strcpy(new_path, path); - strcat(new_path, item->d_name); + snprintf(new_path, 4096, "%s/%s", directory, item->d_name); + new_path[4095] = 0; if (item->d_type) - { - strcat(new_path, "/"); - - [[RetroArch_iOS get].navigator pushViewController:[[[directory_list alloc] init] load_path: new_path] animated:YES]; + { + [[RetroArch_iOS get].navigator + pushViewController:[[directory_list alloc] initWithPath:new_path] + animated:YES]; } else { - [RetroArch_iOS get].window.rootViewController = [[game_view alloc] - initWithNibName: [RetroArch_iOS get].nib_name - bundle:nil]; + [RetroArch_iOS get].window.rootViewController = [[game_view alloc] init]; extern void ios_load_game(const char*); ios_load_game(new_path); @@ -83,7 +65,7 @@ - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - UITableViewCell* cell = [table dequeueReusableCellWithIdentifier:@"path"]; + UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"path"]; cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"path"]; const struct dirent* item = get_dirent_at_index(files, indexPath.row); diff --git a/ios/RetroArch/game_view.m b/ios/RetroArch/game_view.m index ef16a371ea..dbdd2bd4b5 100644 --- a/ios/RetroArch/game_view.m +++ b/ios/RetroArch/game_view.m @@ -71,6 +71,31 @@ void ios_close_game() EAGLContext *gl_context; } +- (id)init +{ + self = [super init]; + + gl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + [EAGLContext setCurrentContext:gl_context]; + + gl_view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) context:gl_context]; + gl_view.multipleTouchEnabled = YES; + self.view = gl_view; + + screen_scale = [[UIScreen mainScreen] scale]; + current_view = self; + + return self; +} + +- (void)dealloc +{ + if ([EAGLContext currentContext] == gl_context) [EAGLContext setCurrentContext:nil]; + gl_context = nil; + gl_view = nil; +} + + - (void)rarch_iterate:(id)sender { if (ra_initialized && !ra_done) @@ -86,28 +111,6 @@ void ios_close_game() } } -- (void)viewDidLoad -{ - [super viewDidLoad]; - - gl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - [EAGLContext setCurrentContext:gl_context]; - - gl_view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) context:gl_context]; - gl_view.multipleTouchEnabled = YES; - self.view = gl_view; - - screen_scale = [[UIScreen mainScreen] scale]; - current_view = self; -} - -- (void)dealloc -{ - if ([EAGLContext currentContext] == gl_context) [EAGLContext setCurrentContext:nil]; - gl_context = nil; - gl_view = nil; -} - @end void ios_flip_game_view() diff --git a/ios/RetroArch/module_list.m b/ios/RetroArch/module_list.m index 68ed5ee5a0..aab1416d28 100644 --- a/ios/RetroArch/module_list.m +++ b/ios/RetroArch/module_list.m @@ -8,55 +8,32 @@ @implementation module_list { - UITableView* table; - - NSString* module_dir; - NSMutableArray* modules; + NSArray* modules; }; -- (void)viewDidLoad +- (id)init { - [super viewDidLoad]; + self = [super initWithStyle:UITableViewStylePlain]; // Get the contents of the modules directory of the bundle. - module_dir = [NSString stringWithFormat:@"%@/%@", - [[NSBundle mainBundle] bundlePath], - @"modules"]; + NSString* module_dir = [NSString stringWithFormat:@"%@/%@", + [[NSBundle mainBundle] bundlePath], + @"modules"]; - NSArray *module_list = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:module_dir error:nil]; - - if (module_list == nil || [module_list count] == 0) - { - // TODO: Handle error! - } - - // Remove non .dylib files from the list - modules = [NSMutableArray arrayWithArray:module_list]; - for (int i = 0; i < [modules count];) - { - if (![[modules objectAtIndex:i] hasSuffix:@".dylib"]) - { - [modules removeObjectAtIndex:i]; - } - else - { - i ++; - } - } + modules = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:module_dir error:nil]; + modules = [module_dir stringsByAppendingPaths:modules]; + modules = [modules pathsMatchingExtensions:[NSArray arrayWithObject:@"dylib"]]; [self setTitle:@"Choose Emulator"]; - table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) style:UITableViewStylePlain]; - table.dataSource = self; - table.delegate = self; - self.view = table; - self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; + + return self; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - [RetroArch_iOS get].module_path = [NSString stringWithFormat:@"%@/%@", module_dir, [modules objectAtIndex:indexPath.row]]; - [[RetroArch_iOS get].navigator pushViewController:[[[directory_list alloc] init] load_path:"/"] animated:YES]; + [RetroArch_iOS get].module_path = [modules objectAtIndex:indexPath.row]; + [[RetroArch_iOS get].navigator pushViewController:[[directory_list alloc] initWithPath:"/"] animated:YES]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section @@ -66,13 +43,10 @@ - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - UITableViewCell* cell = [table dequeueReusableCellWithIdentifier:@"module"]; + UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"module"]; cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"module"]; - if (modules) - { - cell.textLabel.text = [modules objectAtIndex:indexPath.row]; - } + cell.textLabel.text = [[modules objectAtIndex:indexPath.row] lastPathComponent]; return cell; } diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index 5b4f321ddd..aa712b18f1 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -5,10 +5,10 @@ @end -@interface module_list : UIViewController +@interface module_list : UITableViewController @end -@interface directory_list : UIViewController -- (id)load_path:(const char*)directory; +@interface directory_list : UITableViewController +- (id)initWithPath:(const char*)path; @end From 2d04aefe5f452a685d0a0c342bacdc188059f280 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sat, 9 Feb 2013 12:01:33 -0500 Subject: [PATCH 025/108] ios: Clean up directory listing code. --- ios/RetroArch.xcodeproj/project.pbxproj | 6 -- ios/RetroArch/directory_list.m | 84 ++++++++++----------- ios/RetroArch/dirent_list.c | 97 ------------------------- ios/RetroArch/dirent_list.h | 33 --------- ios/RetroArch/module_list.m | 4 +- ios/RetroArch/views.h | 2 +- 6 files changed, 46 insertions(+), 180 deletions(-) delete mode 100644 ios/RetroArch/dirent_list.c delete mode 100644 ios/RetroArch/dirent_list.h diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index bd2b800d9f..9e0f0e876b 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -10,7 +10,6 @@ 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */; }; 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; }; 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; }; - 96297A0116C4767F00E6DCE0 /* dirent_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979FF16C4767F00E6DCE0 /* dirent_list.c */; }; 96297A0916C59EC000E6DCE0 /* module_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0816C59EC000E6DCE0 /* module_list.m */; }; 96297A0C16C5AD8D00E6DCE0 /* RetroArch_iOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */; }; 96297A0F16C5AEA100E6DCE0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0E16C5AEA100E6DCE0 /* main.m */; }; @@ -83,8 +82,6 @@ 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioseagl_ctx.c; sourceTree = ""; }; 962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = ""; }; 962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = ""; }; - 962979FF16C4767F00E6DCE0 /* dirent_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dirent_list.c; sourceTree = ""; }; - 96297A0016C4767F00E6DCE0 /* dirent_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dirent_list.h; sourceTree = ""; }; 96297A0816C59EC000E6DCE0 /* module_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = module_list.m; sourceTree = ""; }; 96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RetroArch_iOS.h; sourceTree = ""; }; 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RetroArch_iOS.m; sourceTree = ""; }; @@ -336,8 +333,6 @@ 96297A0D16C5ADDA00E6DCE0 /* views.h */, 96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */, 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */, - 962979FF16C4767F00E6DCE0 /* dirent_list.c */, - 96297A0016C4767F00E6DCE0 /* dirent_list.h */, 96AFAE4C16C1D4EA009DE44C /* ViewController_iPhone.xib */, 96AFAE4F16C1D4EA009DE44C /* ViewController_iPad.xib */, 96AFAE3416C1D4EA009DE44C /* Supporting Files */, @@ -785,7 +780,6 @@ 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */, 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */, 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */, - 96297A0116C4767F00E6DCE0 /* dirent_list.c in Sources */, 96297A0916C59EC000E6DCE0 /* module_list.m in Sources */, 96297A0C16C5AD8D00E6DCE0 /* RetroArch_iOS.m in Sources */, 96297A0F16C5AEA100E6DCE0 /* main.m in Sources */, diff --git a/ios/RetroArch/directory_list.m b/ios/RetroArch/directory_list.m index d3abc836ec..5e84f988ff 100644 --- a/ios/RetroArch/directory_list.m +++ b/ios/RetroArch/directory_list.m @@ -6,76 +6,78 @@ // Copyright (c) 2013 RetroArch. All rights reserved. // -#include "dirent_list.h" - @implementation directory_list { - char* directory; - struct dirent_list* files; + NSString* directory; + NSArray* list; }; -- (id)initWithPath:(const char*)path +- (id)initWithPath:(NSString*)path { self = [super initWithStyle:UITableViewStylePlain]; - directory = strdup(path); - files = build_dirent_list(directory); + directory = path; + + list = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directory error:nil]; + list = [directory stringsByAppendingPaths:list]; + + list = [list sortedArrayUsingComparator:^(id left, id right) + { + BOOL left_is_dir; + BOOL right_is_dir; + + [[NSFileManager defaultManager] fileExistsAtPath:left isDirectory:&left_is_dir]; + [[NSFileManager defaultManager] fileExistsAtPath:right isDirectory:&right_is_dir]; + + return (left_is_dir != right_is_dir) ? (left_is_dir < right_is_dir) : ([left caseInsensitiveCompare:right]); + }]; self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; - [self setTitle: [[[NSString alloc] initWithUTF8String:directory] lastPathComponent]]; + [self setTitle: [directory lastPathComponent]]; return self; } -- (void)dealloc -{ - free_dirent_list(files); - free(directory); -} - - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - const struct dirent* item = get_dirent_at_index(files, indexPath.row); - - if (!item) return; - - char new_path[4096]; - snprintf(new_path, 4096, "%s/%s", directory, item->d_name); - new_path[4095] = 0; - - if (item->d_type) - { - [[RetroArch_iOS get].navigator - pushViewController:[[directory_list alloc] initWithPath:new_path] - animated:YES]; - } - else + NSString* path = [list objectAtIndex: indexPath.row]; + BOOL isdir; + + if([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isdir]) { - [RetroArch_iOS get].window.rootViewController = [[game_view alloc] init]; + if (isdir) + { + [[RetroArch_iOS get].navigator + pushViewController:[[directory_list alloc] initWithPath:path] + animated:YES]; + } + else + { + [RetroArch_iOS get].window.rootViewController = [[game_view alloc] init]; - extern void ios_load_game(const char*); - ios_load_game(new_path); + extern void ios_load_game(const char*); + ios_load_game([path UTF8String]); + } } } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return get_dirent_list_count(files); + return [list count]; } - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"path"]; cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"path"]; - - const struct dirent* item = get_dirent_at_index(files, indexPath.row); - - if (item) + + NSString* path = [list objectAtIndex: indexPath.row]; + BOOL isdir; + if([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isdir]) { - cell.textLabel.text = [[NSString string] initWithUTF8String:item->d_name]; - cell.accessoryType = (item->d_type) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; - cell.imageView.image = (item->d_type) ? [RetroArch_iOS get].folder_icon : [RetroArch_iOS get].file_icon; - [cell.imageView sizeToFit]; + cell.textLabel.text = [path lastPathComponent]; + cell.accessoryType = (isdir) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; + cell.imageView.image = (isdir) ? [RetroArch_iOS get].folder_icon : [RetroArch_iOS get].file_icon; } return cell; diff --git a/ios/RetroArch/dirent_list.c b/ios/RetroArch/dirent_list.c deleted file mode 100644 index 095d64ca80..0000000000 --- a/ios/RetroArch/dirent_list.c +++ /dev/null @@ -1,97 +0,0 @@ -#include -#include -#include - -#include "general.h" -#include "dirent_list.h" - -static int compare_dirent(const void *left, const void *right) -{ - const struct dirent* l = (const struct dirent*) left; - const struct dirent* r = (const struct dirent*) right; - - // Directories first - if (l->d_type != r->d_type) - return (l->d_type) ? -1 : 1; - - // Name - return strcmp(l->d_name, r->d_name); -} - -static bool is_dirent_verboten(const struct dirent* entry) -{ - if (!entry) return true; - if (strcmp(entry->d_name, ".") == 0) return true; - if (strcmp(entry->d_name, "..") == 0) return true; - return false; -} - -struct dirent_list* build_dirent_list(const char* path) -{ - struct dirent_list* result = 0; - - DIR* dir = opendir(path); - if (dir) - { - struct dirent* ent = 0; - - // Count the number of items - size_t count = 0; - while ((ent = readdir(dir))) - { - count += is_dirent_verboten(ent) ? 0 : 1; - } - rewinddir(dir); - - // String buffer for 'stat'ing - char* stat_path = malloc(strlen(path) + sizeof(ent->d_name)); - strcpy(stat_path, path); - uint32_t last_index = strlen(stat_path); - - // Build and fill the result - result = malloc(sizeof(struct dirent_list)); - result->count = count; - result->entries = malloc(sizeof(struct dirent) * count); - - size_t index = 0; - while ((ent = readdir(dir))) - { - if (is_dirent_verboten(ent)) continue; - memcpy(&result->entries[index], ent, sizeof(struct dirent)); - - // Chage dirent.d_type to a boolean indication if it is a directory - struct stat stat_buf; - strcat(strcat(stat_path, "/"), ent->d_name); - stat(stat_path, &stat_buf); - result->entries[index].d_type = S_ISDIR(stat_buf.st_mode) ? 1 : 0; - stat_path[last_index] = 0; - - index ++; - } - - closedir(dir); - free(stat_path); - - qsort(result->entries, result->count, sizeof(struct dirent), &compare_dirent); - } - - return result; -} - -void free_dirent_list(struct dirent_list* list) -{ - if (list) free(list->entries); - free(list); -} - -const struct dirent* get_dirent_at_index(struct dirent_list* list, unsigned index) -{ - if (!list) return 0; - return (index < list->count) ? &list->entries[index] : 0; -} - -unsigned get_dirent_list_count(struct dirent_list* list) -{ - return list ? list->count : 0; -} - diff --git a/ios/RetroArch/dirent_list.h b/ios/RetroArch/dirent_list.h deleted file mode 100644 index 0b0155f44e..0000000000 --- a/ios/RetroArch/dirent_list.h +++ /dev/null @@ -1,33 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2013 - Hans-Kristian Arntzen - * - * RetroArch 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 Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch 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 RetroArch. - * If not, see . - */ - -#ifndef __RARCH_IOS_DIRENT_LIST_H -#define __RARCH_IOS_DIRENT_LIST_H - -#include - -struct dirent_list -{ - size_t count; - struct dirent* entries; -}; - -struct dirent_list* build_dirent_list(const char* path); -void free_dirent_list(struct dirent_list* list); - -const struct dirent* get_dirent_at_index(struct dirent_list* list, unsigned index); -unsigned get_dirent_list_count(struct dirent_list* list); - -#endif \ No newline at end of file diff --git a/ios/RetroArch/module_list.m b/ios/RetroArch/module_list.m index aab1416d28..151efdc6f5 100644 --- a/ios/RetroArch/module_list.m +++ b/ios/RetroArch/module_list.m @@ -33,7 +33,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [RetroArch_iOS get].module_path = [modules objectAtIndex:indexPath.row]; - [[RetroArch_iOS get].navigator pushViewController:[[directory_list alloc] initWithPath:"/"] animated:YES]; + [[RetroArch_iOS get].navigator pushViewController:[[directory_list alloc] initWithPath:@"/"] animated:YES]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section @@ -46,7 +46,7 @@ UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"module"]; cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"module"]; - cell.textLabel.text = [[modules objectAtIndex:indexPath.row] lastPathComponent]; + cell.textLabel.text = [[[modules objectAtIndex:indexPath.row] lastPathComponent] stringByDeletingPathExtension]; return cell; } diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index aa712b18f1..f7056c7a13 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -10,5 +10,5 @@ @end @interface directory_list : UITableViewController -- (id)initWithPath:(const char*)path; +- (id)initWithPath:(NSString*)path; @end From 7cbfae88c1806e74a652eddc80c8b8ed0d621fc7 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sat, 9 Feb 2013 13:22:31 -0500 Subject: [PATCH 026/108] ios: Add ios/BUILDING to describe the simplest way to get libretro cores building for iOS devices. --- ios/BUILDING | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 ios/BUILDING diff --git a/ios/BUILDING b/ios/BUILDING new file mode 100644 index 0000000000..bac8293360 --- /dev/null +++ b/ios/BUILDING @@ -0,0 +1,27 @@ +The following instructions will only work if building from OS X. + +In general, to build for iOS devices, copy the configuration for OSX, then at the end add the lines: + sysroot = -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/ + CC = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc -arch armv7 $(sysroot) + CXX = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/g++ -arch armv7 $(sysroot) + +Here is how it would look in Makefile.libretro for vba-next: + ... + else ifeq ($(platform), osx) + TARGET := vba_next_libretro.dylib + fpic := -fPIC + SHARED := -dynamiclib + ENDIANNESS_DEFINES = -DLSB_FIRST + else ifeq ($(platform), ios) + TARGET := vba_next_libretro.dylib + fpic := -fPIC + SHARED := -dynamiclib + ENDIANNESS_DEFINES = -DLSB_FIRST + + sysroot = -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/ + CC = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc -arch armv7 $(sysroot) + CXX = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/g++ -arch armv7 $(sysroot) + else ifeq ($(platform), ps3) + ... + +Other arm specific flags can be added if needed. From 73fc504546f61534fca594b75bc45f46f3972c57 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sat, 9 Feb 2013 13:49:04 -0500 Subject: [PATCH 027/108] ios: File browser cleanup. --- ios/RetroArch/directory_list.m | 60 ++++++++++++++++------------------ 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/ios/RetroArch/directory_list.m b/ios/RetroArch/directory_list.m index 5e84f988ff..c8b74543ea 100644 --- a/ios/RetroArch/directory_list.m +++ b/ios/RetroArch/directory_list.m @@ -6,6 +6,13 @@ // Copyright (c) 2013 RetroArch. All rights reserved. // +static BOOL is_directory(NSString* path) +{ + BOOL result = NO; + [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&result]; + return result; +} + @implementation directory_list { NSString* directory; @@ -23,13 +30,12 @@ list = [list sortedArrayUsingComparator:^(id left, id right) { - BOOL left_is_dir; - BOOL right_is_dir; + const BOOL left_is_dir = is_directory((NSString*)left); + const BOOL right_is_dir = is_directory((NSString*)right); - [[NSFileManager defaultManager] fileExistsAtPath:left isDirectory:&left_is_dir]; - [[NSFileManager defaultManager] fileExistsAtPath:right isDirectory:&right_is_dir]; - - return (left_is_dir != right_is_dir) ? (left_is_dir < right_is_dir) : ([left caseInsensitiveCompare:right]); + return (left_is_dir != right_is_dir) ? + (left_is_dir ? -1 : 1) : + ([left caseInsensitiveCompare:right]); }]; self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; @@ -41,23 +47,19 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSString* path = [list objectAtIndex: indexPath.row]; - BOOL isdir; - - if([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isdir]) + + if(is_directory(path)) { - if (isdir) - { - [[RetroArch_iOS get].navigator - pushViewController:[[directory_list alloc] initWithPath:path] - animated:YES]; - } - else - { - [RetroArch_iOS get].window.rootViewController = [[game_view alloc] init]; + [[RetroArch_iOS get].navigator + pushViewController:[[directory_list alloc] initWithPath:path] + animated:YES]; + } + else + { + [RetroArch_iOS get].window.rootViewController = [[game_view alloc] init]; - extern void ios_load_game(const char*); - ios_load_game([path UTF8String]); - } + extern void ios_load_game(const char*); + ios_load_game([path UTF8String]); } } @@ -68,18 +70,14 @@ - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + NSString* path = [list objectAtIndex: indexPath.row]; + BOOL isdir = is_directory(path); + UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"path"]; cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"path"]; - - NSString* path = [list objectAtIndex: indexPath.row]; - BOOL isdir; - if([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isdir]) - { - cell.textLabel.text = [path lastPathComponent]; - cell.accessoryType = (isdir) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; - cell.imageView.image = (isdir) ? [RetroArch_iOS get].folder_icon : [RetroArch_iOS get].file_icon; - } - + cell.textLabel.text = [path lastPathComponent]; + cell.accessoryType = (isdir) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; + cell.imageView.image = (isdir) ? [RetroArch_iOS get].folder_icon : [RetroArch_iOS get].file_icon; return cell; } From 582ba2ccd5a10b398697e57da7eec1f2ae4a309a Mon Sep 17 00:00:00 2001 From: meancoot Date: Sat, 9 Feb 2013 18:47:44 -0500 Subject: [PATCH 028/108] ios: First draft of settings menu. --- ios/RetroArch.xcodeproj/project.pbxproj | 4 + ios/RetroArch/RetroArch_iOS.m | 7 ++ ios/RetroArch/settings_list.m | 121 ++++++++++++++++++++++++ ios/RetroArch/views.h | 3 + 4 files changed, 135 insertions(+) create mode 100644 ios/RetroArch/settings_list.m diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 9e0f0e876b..17c04a9c68 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 96297A0F16C5AEA100E6DCE0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0E16C5AEA100E6DCE0 /* main.m */; }; 96297A1116C5AEDE00E6DCE0 /* game_view.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A1016C5AEDE00E6DCE0 /* game_view.m */; }; 96297A1316C5AEFD00E6DCE0 /* directory_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A1216C5AEFD00E6DCE0 /* directory_list.m */; }; + 96297A1D16C6D20900E6DCE0 /* settings_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A1C16C6D20900E6DCE0 /* settings_list.m */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -89,6 +90,7 @@ 96297A0E16C5AEA100E6DCE0 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 96297A1016C5AEDE00E6DCE0 /* game_view.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = game_view.m; sourceTree = ""; }; 96297A1216C5AEFD00E6DCE0 /* directory_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = directory_list.m; sourceTree = ""; }; + 96297A1C16C6D20900E6DCE0 /* settings_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = settings_list.m; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -338,6 +340,7 @@ 96AFAE3416C1D4EA009DE44C /* Supporting Files */, 96CF015B16C2F72900ABF9C9 /* ios_input.c */, 96297A0816C59EC000E6DCE0 /* module_list.m */, + 96297A1C16C6D20900E6DCE0 /* settings_list.m */, ); path = RetroArch; sourceTree = ""; @@ -785,6 +788,7 @@ 96297A0F16C5AEA100E6DCE0 /* main.m in Sources */, 96297A1116C5AEDE00E6DCE0 /* game_view.m in Sources */, 96297A1316C5AEFD00E6DCE0 /* directory_list.m in Sources */, + 96297A1D16C6D20900E6DCE0 /* settings_list.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index e10fd59b64..f5bb8e984f 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -40,6 +40,8 @@ extern uint32_t ios_current_touch_count ; initWithTitle:@"Settings" style:UIBarButtonItemStyleBordered target:nil action:nil]; + self.settings_button.target = self; + self.settings_button.action = @selector(show_settings); // Setup window self.navigator = [[UINavigationController alloc] init]; @@ -50,6 +52,11 @@ extern uint32_t ios_current_touch_count ; [self.window makeKeyAndVisible]; } +- (void)show_settings +{ + [self.navigator pushViewController: [[settings_list alloc] init] animated:YES]; +} + - (void)processTouches:(NSArray*)touches { ios_current_touch_count = [touches count]; diff --git a/ios/RetroArch/settings_list.m b/ios/RetroArch/settings_list.m new file mode 100644 index 0000000000..41d3475ffe --- /dev/null +++ b/ios/RetroArch/settings_list.m @@ -0,0 +1,121 @@ +// +// settings_list.m +// RetroArch +// +// Created by Jason Fetters on 2/8/13. +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +static NSDictionary* boolean_setting(NSString* name, NSString* label, NSString* value) +{ + return [[NSDictionary alloc] initWithObjectsAndKeys: + @"B", @"TYPE", + name, @"NAME", + label, @"LABEL", + value, @"VALUE", + nil]; +} + +@implementation settings_list +{ + NSArray* settings; +}; + +- (id)init +{ + self = [super initWithStyle:UITableViewStyleGrouped]; + + settings = [NSArray arrayWithObjects: + [NSArray arrayWithObjects:@"Video", + boolean_setting(@"video_smooth", @"Smooth Video", @"true"), + boolean_setting(@"video_crop_overscan", @"Crop Overscan", @"false"), + nil], + + [NSArray arrayWithObjects:@"Audio", + boolean_setting(@"audio_enable", @"Enable Output", @"true"), + boolean_setting(@"audio_sync", @"Sync on Audio Stream", @"true"), + boolean_setting(@"audio_rate_control", @"Adjust for Better Sync", @"true"), + nil], + + [NSArray arrayWithObjects:@"Save States", + boolean_setting(@"rewind_enable", @"Enable Rewinding", @"false"), + boolean_setting(@"block_sram_overwrite", @"Disable SRAM on Load", @"false"), + boolean_setting(@"savestate_auto_save", @"Auto Save on Exit", @"false"), + boolean_setting(@"savestate_auto_load", @"Auto Load on Startup", @"true"), + nil], + nil + ]; + + [self setTitle:@"RetroArch Settings"]; + return self; +} + +- (void)write_to_file +{ + const char* const sd = [RetroArch_iOS get].system_directory; + char config_path[PATH_MAX]; + snprintf(config_path, PATH_MAX, "%s/retroarch.cfg", sd); + config_path[PATH_MAX - 1] = 0; + + FILE* output = fopen(config_path, "w"); + + for (int i = 0; i != [settings count]; i ++) + { + NSArray* group = [settings objectAtIndex:i]; + + for (int j = 1; j < [group count]; j ++) + { + NSDictionary* setting = [group objectAtIndex:j]; + + fprintf(output, "%s = %s\n", [[setting objectForKey:@"NAME"] UTF8String], [[setting objectForKey:@"VALUE"] UTF8String]); + } + } + + fclose(output); +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return [settings count]; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [[settings objectAtIndex:section] count] -1; +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + return [[settings objectAtIndex:section] objectAtIndex:0]; +} + +- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + NSDictionary* setting = [[settings objectAtIndex:indexPath.section] objectAtIndex:indexPath.row + 1]; + UITableViewCell* cell = nil; + + if ([[setting valueForKey:@"TYPE"] isEqualToString:@"B"]) + { + cell = [self.tableView dequeueReusableCellWithIdentifier:@"boolean"]; + + if (cell == nil) + { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"boolean"]; + cell.accessoryView = [[UISwitch alloc] init]; + [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; + } + + UISwitch* swt = (UISwitch*)cell.accessoryView; + swt.on = [[setting valueForKey:@"VALUE"] isEqualToString:@"true"]; + } + + cell.textLabel.text = [setting valueForKey:@"LABEL"]; + + return cell; +} + +@end diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index f7056c7a13..bb93246564 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -12,3 +12,6 @@ @interface directory_list : UITableViewController - (id)initWithPath:(NSString*)path; @end + +@interface settings_list : UITableViewController +@end \ No newline at end of file From 72543d13107b0fb34d3611ca02f3ed8845e24d38 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sat, 9 Feb 2013 21:24:09 -0500 Subject: [PATCH 029/108] ios: Add support for enumeration and file based settings. --- ios/RetroArch/RetroArch_iOS.h | 1 + ios/RetroArch/RetroArch_iOS.m | 2 + ios/RetroArch/settings_list.m | 117 ++++++++++++++++++++++++++++++++-- 3 files changed, 114 insertions(+), 6 deletions(-) diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index 8d137eab63..37391de73a 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -13,6 +13,7 @@ @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) NSString *module_path; +@property (strong, nonatomic) NSString *overlay_path; @property (strong, nonatomic) UINavigationController *navigator; @property (strong, nonatomic) UIImage* file_icon; @property (strong, nonatomic) UIImage* folder_icon; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index f5bb8e984f..39eff8bb2c 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -31,6 +31,8 @@ extern uint32_t ios_current_touch_count ; self.system_directory = "/var/mobile/Library/RetroArch/"; mkdir(self.system_directory, 0755); + self.overlay_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/overlays"]; + // Load icons self.file_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_file" ofType:@"png"]]; self.folder_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_dir" ofType:@"png"]]; diff --git a/ios/RetroArch/settings_list.m b/ios/RetroArch/settings_list.m index 41d3475ffe..79344e80b5 100644 --- a/ios/RetroArch/settings_list.m +++ b/ios/RetroArch/settings_list.m @@ -6,9 +6,9 @@ // Copyright (c) 2013 RetroArch. All rights reserved. // -static NSDictionary* boolean_setting(NSString* name, NSString* label, NSString* value) +static NSMutableDictionary* boolean_setting(NSString* name, NSString* label, NSString* value) { - return [[NSDictionary alloc] initWithObjectsAndKeys: + return [[NSMutableDictionary alloc] initWithObjectsAndKeys: @"B", @"TYPE", name, @"NAME", label, @"LABEL", @@ -16,6 +16,81 @@ static NSDictionary* boolean_setting(NSString* name, NSString* label, NSString* nil]; } +static NSMutableDictionary* enumeration_setting(NSString* name, NSString* label, NSString* value, NSArray* values) +{ + return [[NSMutableDictionary alloc] initWithObjectsAndKeys: + @"E", @"TYPE", + name, @"NAME", + label, @"LABEL", + value, @"VALUE", + values, @"VALUES", + nil]; +} + +static NSMutableDictionary* subpath_setting(NSString* name, NSString* label, NSString* value, NSString* path, NSString* extension) +{ + NSArray* values = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:[RetroArch_iOS get].overlay_path error:nil]; + values = [values pathsMatchingExtensions:[NSArray arrayWithObject:extension]]; + + return [[NSMutableDictionary alloc] initWithObjectsAndKeys: + @"F", @"TYPE", + name, @"NAME", + label, @"LABEL", + value, @"VALUE", + values, @"VALUES", + path, @"PATH", + nil]; +} + +@interface enumeration_list : UITableViewController +@end + +@implementation enumeration_list +{ + NSMutableDictionary* value; + UITableView* view; +}; + +- (id)initWithSetting:(NSMutableDictionary*)setting fromTable:(UITableView*)table +{ + self = [super initWithStyle:UITableViewStyleGrouped]; + + value = setting; + view = table; + [self setTitle: [value objectForKey:@"LABEL"]]; + return self; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [[value objectForKey:@"VALUES"] count]; +} + +- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"option"]; + cell = cell ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"option"]; + + cell.textLabel.text = [[value objectForKey:@"VALUES"] objectAtIndex:indexPath.row]; + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [value setObject:[[value objectForKey:@"VALUES"] objectAtIndex:indexPath.row] forKey:@"VALUE"]; + + [view reloadData]; + [[RetroArch_iOS get].navigator popViewControllerAnimated:YES]; +} + +@end + @implementation settings_list { NSArray* settings; @@ -25,6 +100,7 @@ static NSDictionary* boolean_setting(NSString* name, NSString* label, NSString* { self = [super initWithStyle:UITableViewStyleGrouped]; + settings = [NSArray arrayWithObjects: [NSArray arrayWithObjects:@"Video", boolean_setting(@"video_smooth", @"Smooth Video", @"true"), @@ -36,6 +112,10 @@ static NSDictionary* boolean_setting(NSString* name, NSString* label, NSString* boolean_setting(@"audio_sync", @"Sync on Audio Stream", @"true"), boolean_setting(@"audio_rate_control", @"Adjust for Better Sync", @"true"), nil], + + [NSArray arrayWithObjects:@"Input", + subpath_setting(@"input_overlay", @"Input Overlay", @"", [RetroArch_iOS get].overlay_path, @"cfg"), + nil], [NSArray arrayWithObjects:@"Save States", boolean_setting(@"rewind_enable", @"Enable Rewinding", @"false"), @@ -65,9 +145,12 @@ static NSDictionary* boolean_setting(NSString* name, NSString* label, NSString* for (int j = 1; j < [group count]; j ++) { - NSDictionary* setting = [group objectAtIndex:j]; + NSMutableDictionary* setting = [group objectAtIndex:j]; - fprintf(output, "%s = %s\n", [[setting objectForKey:@"NAME"] UTF8String], [[setting objectForKey:@"VALUE"] UTF8String]); + if ([[setting objectForKey:@"TYPE"] isEqualToString:@"F"]) + fprintf(output, "%s = \"%s/%s\"\n", [[setting objectForKey:@"NAME"] UTF8String], [[setting objectForKey:@"PATH"] UTF8String], [[setting objectForKey:@"VALUE"] UTF8String]); + else + fprintf(output, "%s = %s\n", [[setting objectForKey:@"NAME"] UTF8String], [[setting objectForKey:@"VALUE"] UTF8String]); } } @@ -76,10 +159,20 @@ static NSDictionary* boolean_setting(NSString* name, NSString* label, NSString* - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + NSMutableDictionary* setting = [[settings objectAtIndex:indexPath.section] objectAtIndex:indexPath.row + 1]; + NSString* type = [setting valueForKey:@"TYPE"]; + + if ([type isEqualToString:@"E"] || [type isEqualToString:@"F"]) + { + [[RetroArch_iOS get].navigator + pushViewController:[[enumeration_list alloc] initWithSetting:setting fromTable:(UITableView*)self.view] + animated:YES]; + } } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + [self write_to_file]; return [settings count]; } @@ -95,10 +188,12 @@ static NSDictionary* boolean_setting(NSString* name, NSString* label, NSString* - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - NSDictionary* setting = [[settings objectAtIndex:indexPath.section] objectAtIndex:indexPath.row + 1]; + NSMutableDictionary* setting = [[settings objectAtIndex:indexPath.section] objectAtIndex:indexPath.row + 1]; UITableViewCell* cell = nil; - if ([[setting valueForKey:@"TYPE"] isEqualToString:@"B"]) + NSString* type = [setting valueForKey:@"TYPE"]; + + if ([type isEqualToString:@"B"]) { cell = [self.tableView dequeueReusableCellWithIdentifier:@"boolean"]; @@ -112,8 +207,18 @@ static NSDictionary* boolean_setting(NSString* name, NSString* label, NSString* UISwitch* swt = (UISwitch*)cell.accessoryView; swt.on = [[setting valueForKey:@"VALUE"] isEqualToString:@"true"]; } + else if ([type isEqualToString:@"E"] || [type isEqualToString:@"F"]) + { + cell = [self.tableView dequeueReusableCellWithIdentifier:@"enumeration"]; + + if (cell == nil) + { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"enumeration"]; + } + } cell.textLabel.text = [setting valueForKey:@"LABEL"]; + cell.detailTextLabel.text = [setting valueForKey:@"VALUE"]; return cell; } From a136789ff5d7812aa21047f700c284631585bd50 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 10 Feb 2013 05:46:30 -0500 Subject: [PATCH 030/108] ios: Settings values are now loaded from the existing config file. --- ios/RetroArch/settings_list.m | 87 ++++++++++++++++++++++++----------- 1 file changed, 61 insertions(+), 26 deletions(-) diff --git a/ios/RetroArch/settings_list.m b/ios/RetroArch/settings_list.m index 79344e80b5..f7311e706b 100644 --- a/ios/RetroArch/settings_list.m +++ b/ios/RetroArch/settings_list.m @@ -6,8 +6,30 @@ // Copyright (c) 2013 RetroArch. All rights reserved. // -static NSMutableDictionary* boolean_setting(NSString* name, NSString* label, NSString* value) +#include "config_file.h" + +static NSString* get_value_from_config(config_file_t* config, NSString* name, NSString* defaultValue) { + NSString* value = nil; + + char* v = 0; + if (config_get_string(config, [name UTF8String], &v)) + { + value = [[NSString alloc] initWithUTF8String:v]; + free(v); + } + else + { + value = defaultValue; + } + + return value; +} + +static NSMutableDictionary* boolean_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue) +{ + NSString* value = get_value_from_config(config, name, defaultValue); + return [[NSMutableDictionary alloc] initWithObjectsAndKeys: @"B", @"TYPE", name, @"NAME", @@ -16,8 +38,10 @@ static NSMutableDictionary* boolean_setting(NSString* name, NSString* label, NSS nil]; } -static NSMutableDictionary* enumeration_setting(NSString* name, NSString* label, NSString* value, NSArray* values) +static NSMutableDictionary* enumeration_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue, NSArray* values) { + NSString* value = get_value_from_config(config, name, defaultValue); + return [[NSMutableDictionary alloc] initWithObjectsAndKeys: @"E", @"TYPE", name, @"NAME", @@ -27,8 +51,11 @@ static NSMutableDictionary* enumeration_setting(NSString* name, NSString* label, nil]; } -static NSMutableDictionary* subpath_setting(NSString* name, NSString* label, NSString* value, NSString* path, NSString* extension) +static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue, NSString* path, NSString* extension) { + NSString* value = get_value_from_config(config, name, defaultValue); + value = [value stringByReplacingOccurrencesOfString:path withString:@""]; + NSArray* values = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:[RetroArch_iOS get].overlay_path error:nil]; values = [values pathsMatchingExtensions:[NSArray arrayWithObject:extension]]; @@ -94,34 +121,42 @@ static NSMutableDictionary* subpath_setting(NSString* name, NSString* label, NSS @implementation settings_list { NSArray* settings; + config_file_t* config; }; - (id)init { self = [super initWithStyle:UITableViewStyleGrouped]; + const char* const sd = [RetroArch_iOS get].system_directory; + char config_path[PATH_MAX]; + snprintf(config_path, PATH_MAX, "%s/retroarch.cfg", sd); + config_path[PATH_MAX - 1] = 0; + + config = config_file_new(config_path); + if (!config) config = config_file_new(0); settings = [NSArray arrayWithObjects: [NSArray arrayWithObjects:@"Video", - boolean_setting(@"video_smooth", @"Smooth Video", @"true"), - boolean_setting(@"video_crop_overscan", @"Crop Overscan", @"false"), + boolean_setting(config, @"video_smooth", @"Smooth Video", @"true"), + boolean_setting(config, @"video_crop_overscan", @"Crop Overscan", @"false"), nil], [NSArray arrayWithObjects:@"Audio", - boolean_setting(@"audio_enable", @"Enable Output", @"true"), - boolean_setting(@"audio_sync", @"Sync on Audio Stream", @"true"), - boolean_setting(@"audio_rate_control", @"Adjust for Better Sync", @"true"), + boolean_setting(config, @"audio_enable", @"Enable Output", @"true"), + boolean_setting(config, @"audio_sync", @"Sync on Audio Stream", @"true"), + boolean_setting(config, @"audio_rate_control", @"Adjust for Better Sync", @"true"), nil], [NSArray arrayWithObjects:@"Input", - subpath_setting(@"input_overlay", @"Input Overlay", @"", [RetroArch_iOS get].overlay_path, @"cfg"), + subpath_setting(config, @"input_overlay", @"Input Overlay", @"", [RetroArch_iOS get].overlay_path, @"cfg"), nil], [NSArray arrayWithObjects:@"Save States", - boolean_setting(@"rewind_enable", @"Enable Rewinding", @"false"), - boolean_setting(@"block_sram_overwrite", @"Disable SRAM on Load", @"false"), - boolean_setting(@"savestate_auto_save", @"Auto Save on Exit", @"false"), - boolean_setting(@"savestate_auto_load", @"Auto Load on Startup", @"true"), + boolean_setting(config, @"rewind_enable", @"Enable Rewinding", @"false"), + boolean_setting(config, @"block_sram_overwrite", @"Disable SRAM on Load", @"false"), + boolean_setting(config, @"savestate_auto_save", @"Auto Save on Exit", @"false"), + boolean_setting(config, @"savestate_auto_load", @"Auto Load on Startup", @"true"), nil], nil ]; @@ -132,13 +167,6 @@ static NSMutableDictionary* subpath_setting(NSString* name, NSString* label, NSS - (void)write_to_file { - const char* const sd = [RetroArch_iOS get].system_directory; - char config_path[PATH_MAX]; - snprintf(config_path, PATH_MAX, "%s/retroarch.cfg", sd); - config_path[PATH_MAX - 1] = 0; - - FILE* output = fopen(config_path, "w"); - for (int i = 0; i != [settings count]; i ++) { NSArray* group = [settings objectAtIndex:i]; @@ -146,15 +174,22 @@ static NSMutableDictionary* subpath_setting(NSString* name, NSString* label, NSS for (int j = 1; j < [group count]; j ++) { NSMutableDictionary* setting = [group objectAtIndex:j]; - + + NSString* name = [setting objectForKey:@"NAME"]; + NSString* value = [setting objectForKey:@"VALUE"]; + if ([[setting objectForKey:@"TYPE"] isEqualToString:@"F"]) - fprintf(output, "%s = \"%s/%s\"\n", [[setting objectForKey:@"NAME"] UTF8String], [[setting objectForKey:@"PATH"] UTF8String], [[setting objectForKey:@"VALUE"] UTF8String]); - else - fprintf(output, "%s = %s\n", [[setting objectForKey:@"NAME"] UTF8String], [[setting objectForKey:@"VALUE"] UTF8String]); + value = [[setting objectForKey:@"PATH"] stringByAppendingPathComponent:value]; + + config_set_string(config, [name UTF8String], [value UTF8String]); } } - - fclose(output); + + const char* const sd = [RetroArch_iOS get].system_directory; + char config_path[PATH_MAX]; + snprintf(config_path, PATH_MAX, "%s/retroarch.cfg", sd); + config_path[PATH_MAX - 1] = 0; + config_file_write(config, config_path); } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath From 98990ce330d3eeec5a2cf6fedbf2b4038d88a921 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 10 Feb 2013 05:49:05 -0500 Subject: [PATCH 031/108] ios: Remove reference to UI views once game has started. --- ios/RetroArch/RetroArch_iOS.h | 1 + ios/RetroArch/RetroArch_iOS.m | 5 +++++ ios/RetroArch/game_view.m | 1 + 3 files changed, 7 insertions(+) diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index 37391de73a..d92e2201c1 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -10,6 +10,7 @@ @interface RetroArch_iOS : UIResponder + (RetroArch_iOS*)get; +- (void)game_has_started; @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) NSString *module_path; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 39eff8bb2c..29e222b2dc 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -59,6 +59,11 @@ extern uint32_t ios_current_touch_count ; [self.navigator pushViewController: [[settings_list alloc] init] animated:YES]; } +- (void)game_has_started +{ + self.navigator = nil; +} + - (void)processTouches:(NSArray*)touches { ios_current_touch_count = [touches count]; diff --git a/ios/RetroArch/game_view.m b/ios/RetroArch/game_view.m index dbdd2bd4b5..6754b96465 100644 --- a/ios/RetroArch/game_view.m +++ b/ios/RetroArch/game_view.m @@ -42,6 +42,7 @@ void ios_load_game(const char* file_name) rarch_init_msg_queue(); ra_initialized = TRUE; + [[RetroArch_iOS get ]game_has_started]; [current_view performSelector:@selector(rarch_iterate:) withObject:nil afterDelay:0.2f]; } } From 4a8831cbdd2a199a038e714791ded7312115365d Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 10 Feb 2013 06:39:47 -0500 Subject: [PATCH 032/108] ios: Make the boolean switches in the settings screen work. --- ios/RetroArch/settings_list.m | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/ios/RetroArch/settings_list.m b/ios/RetroArch/settings_list.m index f7311e706b..81b93bf8f5 100644 --- a/ios/RetroArch/settings_list.m +++ b/ios/RetroArch/settings_list.m @@ -6,8 +6,11 @@ // Copyright (c) 2013 RetroArch. All rights reserved. // +#import #include "config_file.h" +static const char* const SETTINGID = "SETTING"; + static NSString* get_value_from_config(config_file_t* config, NSString* name, NSString* defaultValue) { NSString* value = nil; @@ -165,6 +168,11 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam return self; } +- (void)dealloc +{ + [self write_to_file]; +} + - (void)write_to_file { for (int i = 0; i != [settings count]; i ++) @@ -207,7 +215,6 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - [self write_to_file]; return [settings count]; } @@ -221,6 +228,12 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam return [[settings objectAtIndex:section] objectAtIndex:0]; } +- (void)handle_boolean_switch:(UISwitch*)swt +{ + NSDictionary* setting = objc_getAssociatedObject(swt, SETTINGID); + [setting setValue: (swt.on ? @"true" : @"false") forKey:@"VALUE"]; +} + - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSMutableDictionary* setting = [[settings objectAtIndex:indexPath.section] objectAtIndex:indexPath.row + 1]; @@ -235,12 +248,18 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"boolean"]; - cell.accessoryView = [[UISwitch alloc] init]; + + UISwitch* accessory = [[UISwitch alloc] init]; + [accessory addTarget:self action:@selector(handle_boolean_switch:) forControlEvents:UIControlEventValueChanged]; + + cell.accessoryView = accessory; [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; } UISwitch* swt = (UISwitch*)cell.accessoryView; swt.on = [[setting valueForKey:@"VALUE"] isEqualToString:@"true"]; + + objc_setAssociatedObject(swt, SETTINGID, setting, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } else if ([type isEqualToString:@"E"] || [type isEqualToString:@"F"]) { From 64673845ddfec7a8cf55a11afc76e0ab5d88ba23 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 10 Feb 2013 07:22:03 -0500 Subject: [PATCH 033/108] ios: File browser now tries to root itself at '/var/mobile/RetroArchGames' and '/var/mobile' before settling on '/'. --- ios/RetroArch/directory_list.m | 7 +++++++ ios/RetroArch/module_list.m | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ios/RetroArch/directory_list.m b/ios/RetroArch/directory_list.m index c8b74543ea..de985884a9 100644 --- a/ios/RetroArch/directory_list.m +++ b/ios/RetroArch/directory_list.m @@ -23,6 +23,13 @@ static BOOL is_directory(NSString* path) { self = [super initWithStyle:UITableViewStylePlain]; + if (path == nil) + { + if (is_directory(@"/var/mobile/RetroArchGames")) path = @"/var/mobile/RetroArchGames"; + else if (is_directory(@"/var/mobile")) path = @"/var/mobile"; + else path = @"/"; + } + directory = path; list = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directory error:nil]; diff --git a/ios/RetroArch/module_list.m b/ios/RetroArch/module_list.m index 151efdc6f5..f898c1b12a 100644 --- a/ios/RetroArch/module_list.m +++ b/ios/RetroArch/module_list.m @@ -33,7 +33,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [RetroArch_iOS get].module_path = [modules objectAtIndex:indexPath.row]; - [[RetroArch_iOS get].navigator pushViewController:[[directory_list alloc] initWithPath:@"/"] animated:YES]; + [[RetroArch_iOS get].navigator pushViewController:[[directory_list alloc] initWithPath:nil] animated:YES]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section From be6b99b69a64fedf8c83204c43e48aa3d56da0bf Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 10 Feb 2013 12:11:37 -0500 Subject: [PATCH 034/108] ios: Add a shader option on the settings page (put them in shaders directory just inside RetroArch.app) Add a 'None' option to both the shader and overlay settings sub pages to allow them to be disabled. --- ios/RetroArch/RetroArch_iOS.h | 1 - ios/RetroArch/RetroArch_iOS.m | 4 +--- ios/RetroArch/settings_list.m | 24 +++++++++++++++++------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index d92e2201c1..0d99c6644f 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -14,7 +14,6 @@ @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) NSString *module_path; -@property (strong, nonatomic) NSString *overlay_path; @property (strong, nonatomic) UINavigationController *navigator; @property (strong, nonatomic) UIImage* file_icon; @property (strong, nonatomic) UIImage* folder_icon; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 29e222b2dc..bac4d5567c 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -30,9 +30,7 @@ extern uint32_t ios_current_touch_count ; // TODO: Relocate this! self.system_directory = "/var/mobile/Library/RetroArch/"; mkdir(self.system_directory, 0755); - - self.overlay_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/overlays"]; - + // Load icons self.file_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_file" ofType:@"png"]]; self.folder_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_dir" ofType:@"png"]]; diff --git a/ios/RetroArch/settings_list.m b/ios/RetroArch/settings_list.m index 81b93bf8f5..108637fddc 100644 --- a/ios/RetroArch/settings_list.m +++ b/ios/RetroArch/settings_list.m @@ -59,7 +59,7 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam NSString* value = get_value_from_config(config, name, defaultValue); value = [value stringByReplacingOccurrencesOfString:path withString:@""]; - NSArray* values = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:[RetroArch_iOS get].overlay_path error:nil]; + NSArray* values = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:path error:nil]; values = [values pathsMatchingExtensions:[NSArray arrayWithObject:extension]]; return [[NSMutableDictionary alloc] initWithObjectsAndKeys: @@ -93,12 +93,12 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 1; + return 2; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return [[value objectForKey:@"VALUES"] count]; + return (section == 1) ? [[value objectForKey:@"VALUES"] count] : 1; } - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath @@ -106,14 +106,20 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"option"]; cell = cell ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"option"]; - cell.textLabel.text = [[value objectForKey:@"VALUES"] objectAtIndex:indexPath.row]; + if (indexPath.section == 1) + cell.textLabel.text = [[value objectForKey:@"VALUES"] objectAtIndex:indexPath.row]; + else + cell.textLabel.text = @"None"; return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - [value setObject:[[value objectForKey:@"VALUES"] objectAtIndex:indexPath.row] forKey:@"VALUE"]; + if (indexPath.section == 1) + [value setObject:[[value objectForKey:@"VALUES"] objectAtIndex:indexPath.row] forKey:@"VALUE"]; + else + [value setObject:@"" forKey:@"VALUE"]; [view reloadData]; [[RetroArch_iOS get].navigator popViewControllerAnimated:YES]; @@ -139,10 +145,14 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam config = config_file_new(config_path); if (!config) config = config_file_new(0); + NSString* overlay_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/overlays/"]; + NSString* shader_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/shaders/"]; + settings = [NSArray arrayWithObjects: [NSArray arrayWithObjects:@"Video", boolean_setting(config, @"video_smooth", @"Smooth Video", @"true"), boolean_setting(config, @"video_crop_overscan", @"Crop Overscan", @"false"), + subpath_setting(config, @"video_bsnes_shader", @"Shader", @"", shader_path, @"shader"), nil], [NSArray arrayWithObjects:@"Audio", @@ -152,7 +162,7 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam nil], [NSArray arrayWithObjects:@"Input", - subpath_setting(config, @"input_overlay", @"Input Overlay", @"", [RetroArch_iOS get].overlay_path, @"cfg"), + subpath_setting(config, @"input_overlay", @"Input Overlay", @"", overlay_path, @"cfg"), nil], [NSArray arrayWithObjects:@"Save States", @@ -186,7 +196,7 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam NSString* name = [setting objectForKey:@"NAME"]; NSString* value = [setting objectForKey:@"VALUE"]; - if ([[setting objectForKey:@"TYPE"] isEqualToString:@"F"]) + if ([[setting objectForKey:@"TYPE"] isEqualToString:@"F"] && [value length] > 0) value = [[setting objectForKey:@"PATH"] stringByAppendingPathComponent:value]; config_set_string(config, [name UTF8String], [value UTF8String]); From 12b079dd6116868c861a36525dbbe1ee71e5a960 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 10 Feb 2013 13:08:29 -0500 Subject: [PATCH 035/108] ios: Add icon. (I copied the android xhdpi icon and scaled it to the needed sizes, it's ugly but better than a blank square.) --- ios/RetroArch.xcodeproj/project.pbxproj | 8 ++++++++ ios/RetroArch/Icon-72.png | Bin 0 -> 3173 bytes ios/RetroArch/Icon.png | Bin 0 -> 2291 bytes 3 files changed, 8 insertions(+) create mode 100644 ios/RetroArch/Icon-72.png create mode 100644 ios/RetroArch/Icon.png diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 17c04a9c68..1e9aa17d5d 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -16,6 +16,8 @@ 96297A1116C5AEDE00E6DCE0 /* game_view.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A1016C5AEDE00E6DCE0 /* game_view.m */; }; 96297A1316C5AEFD00E6DCE0 /* directory_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A1216C5AEFD00E6DCE0 /* directory_list.m */; }; 96297A1D16C6D20900E6DCE0 /* settings_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A1C16C6D20900E6DCE0 /* settings_list.m */; }; + 96297A2416C818FF00E6DCE0 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2216C818FF00E6DCE0 /* Icon-72.png */; }; + 96297A2516C818FF00E6DCE0 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2316C818FF00E6DCE0 /* Icon.png */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -91,6 +93,8 @@ 96297A1016C5AEDE00E6DCE0 /* game_view.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = game_view.m; sourceTree = ""; }; 96297A1216C5AEFD00E6DCE0 /* directory_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = directory_list.m; sourceTree = ""; }; 96297A1C16C6D20900E6DCE0 /* settings_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = settings_list.m; sourceTree = ""; }; + 96297A2216C818FF00E6DCE0 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "RetroArch/Icon-72.png"; sourceTree = ""; }; + 96297A2316C818FF00E6DCE0 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = RetroArch/Icon.png; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -296,6 +300,8 @@ 96AFAE1A16C1D4EA009DE44C = { isa = PBXGroup; children = ( + 96297A2216C818FF00E6DCE0 /* Icon-72.png */, + 96297A2316C818FF00E6DCE0 /* Icon.png */, 962979F416C43B9500E6DCE0 /* ic_dir.png */, 962979F516C43B9500E6DCE0 /* ic_file.png */, 96AFAF2116C1DF88009DE44C /* libz.dylib */, @@ -724,6 +730,8 @@ 96AFAE5116C1D4EA009DE44C /* ViewController_iPad.xib in Resources */, 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */, 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */, + 96297A2416C818FF00E6DCE0 /* Icon-72.png in Resources */, + 96297A2516C818FF00E6DCE0 /* Icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/Icon-72.png b/ios/RetroArch/Icon-72.png new file mode 100644 index 0000000000000000000000000000000000000000..a0c2cc6e2261ad4c98a148ede7fa26737a9f8974 GIT binary patch literal 3173 zcmV-r44U(aP)e%`S96~6%((l{eES=->~HCNX1c4ZYu;2>Rd<&?IOoh=n^Nff`{fs(w>Rid`xE?uK zi$z66{eAT4(f^2vi79mW@L}fb>&prkF3dbVJsE^yUAlDP5PH_op+lo`Dwy4V>FMd; zU%!5R{fZSUSVBSq^YQUvDJdxoz_5sj2-c@hA9nBFz3O%A*1c_)r-6gvN zELyb4@8!#vilEd+Q+46Og`doH27uswE>){m&5Kl%3K?CR$5*agxxISz>R$8b&renv z6fa&}z0G#TVC>YXQ(d=j-`*H~(=rL-09gNQ#7u?k&%4w-n|^Q zBEDk9iUo;>v%lK4YnOZT=FJ(BanPVaeE9I;yho27+Iaf0)%zkvitxC&xD0sIKhk*h z>eVX@56AJLIkl;Dbfxzu-q6PJdf5~~r%js{47)<})X+(Nu3Wh?2dW${JeWGSYu7I5 z;lqdbpx%7y)TzpE^5n_9b?ergG*0bjzT#^?0l3Ze0@%H$vEj;j!GZ;){5y2$z^6=^ zqR9je;~zhMJg$xb4GBAU?p!u-R5@F;Xu+R6c>?mR52#EriXGq$G<8DCpY+r?9-<#?bq|@ z-Mcqiym;{ge}DhKd3$?*%xp{T*skj}bJCBTV3eg%Wq`p)Ki(jIyVS%G)s2p-dA?N;@q z`m&PgP|C{MseakAWp~NB5D=mw0!Z^>jsT*LP~FqeqL+Hch)_4<`2*Df7$3ZRtBDgQ z>PZau$BrHQ4o3SYDBoRL4meY`Y}pdLcI{f0mZmyIWAEL&cQY977|3)IEoy*zvUBIo z|Acu^23xXZiK6%=N|a#Fo;@=%z!PbgS%Wly9H}00qOY%VMDSGvFMAO4xiP$x2Qejp zQKv?(DyiX$_{sb62R_KX|C&{GBb>_?&hAFH#6+NALKW^MO zwr}6QAb6@EvQwC94B+&Ib14CuIru5^6JKf*72y;nwS{LX3#PZADa0h(uV&4f{N1~E zD`4dn7d?IY^gmz$n1sQy(Te)#R~;6p91B>3SAqlK<;#~B%H6G7H~#9?t0Q_Zrr00= zl=$GmgOtp$Tm-JUE`z**=*yc4^Ya;zvZAGW87Rt^X;8Ux&lyzUp%4&K(BR z!4U*sCPC-To9A`t&>?pJ{(akW8vv5^q6o8l_wI$l!oq4|!%W$^+p}knj9i(jFzDKp zC6{{o^l1hSl=iXPK+}eJtJ8#RA?^9lzL2?)rnGP0-UHEeFvUN#PvuB%bARQT)R2CN zA1;&CM`f;m6DCXm%dA2x<u*Khlt+tpJ&nY34 z_AAZH4GJ`!@Q@A%YS5s8q1|f3%s`xjhdcoYt}+Lr*z4jb;U`-jN2QbGBarWd^v*;czDjb@}(Fhp0JYBSlZizz7LsqFnA`{Of`3GN|((EbLnkej@+YSpS0u?_5xy=I2Y4iqjDy1nxXBmbC-f2n1`OahYnx$*mkVe@khma}14qmpc~2aPTfR9R$8w4x zKJdg|bxqg;&7ebbI^meNqzG`T!xW@M0blA1!PIkd8F{Yik;)Q_lM5jaoRYHm_;`*J zn7IIHrAh=-k%U~OMD^Lx)e<1=6Gh@n%t1<>FWDgaQRIn404ZP5j-r$}mkng72?$xi z9*+k;Xe9D1BZ-y{4qLWt8M}1p(*Fz@GDHg$W&O3?dyxv_v|tbds$^u;D=BJ}rbcQj zJHy8y99qL+4>FL<6fNTE>N;{mMTYbB*zwL1~h1A&z?QK>sA-T_=KhF`qRJ9u4;S>WSFC6$u&!g!u4z~Cuk~4pXw@~~n z(qYnY`ufAhjT^tn<`O0RARV|K?BpQ4?01wVLj@p3;lNNBCsAw#FU+=X-TE((wp2Pu z{x}4P`Z%&Dl$M9Z?2GZ^$1i}b5?e~iz^<&${1^tKh>sRU=W((?QWiIv<h3sH+c_5|(^qJo2J`=gyrG zR=cCLB7p3c%MHsHqoixuOVqDlpArdPV>?9tzW}n%d05}KZ{IaA(oD8PivK2HjT<*+ z_@6dfAvi3SOAQ2B+nYCU-W0~KEYk3lgd~cEu%7t{FYp-lXBu33jKfj#p%H7yaIC*p z9zTA(JY2ex)=JY3Ga?;XDoL_s-AXh|fQSLyeJjKg;d*9J&jciPpFqGEudn}F z?h%jqz{6I?wKGhCzbY4=lkpsjwm4iZ7t*!>QknlAua-9G_Xvvqo!tQG(Gc9b0TO_s zuW|#VM?-M$21o#kzRC@d9u2|08z2EF`YJa-dNc(0Zh!=!=&Sw*3Lt2xTwM-K00000 LNkvXXu0mjfviuJr literal 0 HcmV?d00001 diff --git a/ios/RetroArch/Icon.png b/ios/RetroArch/Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..690f28b4b334f46d8b3f4b441a767f2993f1db55 GIT binary patch literal 2291 zcmV0twQWN75HD2`sMInlU913iI^ZEAkd*9pddyj{vLfB;A+izxfW@mP0c6Zjo zIcLqixHWeHNxl{#o69Pgn4&fmOw^Y`r8v)eR? zB%OGispH3wAC;b-PRApg+OAzYUQ<(354@){be!!|TwH9!NAR69XAZw}=gv}R=}|o9o)OYtuS( z=pZ4%n8jjYJ$m%8NRciA+qZ8o9Z7Jk&OcJ50ZvI3<0Lj-`_tG{r;rR@AN<|+tR;(e>P*r zjI1$Z#xVFO8#{Jv8G88J_A>vvapOkb(W6Jdguk)8ygask{d(yDKR-VezIgHCpHWtX zhK71pR#vL;{QUe%xK~tSV&W|YXm#KzBSws{bM(%gJM*%#GIZgrOP4OKpFDX|v~Alq zo{^EkGcz-JY;3IE7!c*FR;}V2Hf;FHO53TxwtV?=DXo~87!H9|o|wZ;LAR=^YA*#o z;;F5$27VYt^i$0h!9x*R`-7;-gocWWiYj4}!2tmQe!;=PeqFnE_1(I4>m!-(yng*! zOU9`-lxf$mRjXF);K74ez$=J&LeYL3H*Wk~bj18D6!`Q7R%ruLqbuy(20((}Km}I#CY}&LbZ}8y3NiZ`3QvQ8>d~Cj*`Ox#BF&-WsWI@ZpQ=K)rgec%64R(6| zs*u+BBE~EKRw1Wpfw1*dn1QnFNl8h=mMmGKMJsIz^I2J0GxzM-Gt3St0f2XqUi;Lo zuC9)imX@aD5D*2PWRmRAp+kS{+O?~c+ACMCycQM~_QU=A_vuqDMnYQL-QCqrqCtX# z_FMYKiO1*MxpS9p-n`l4_U+q@q8ymeBt&=hKRY{{%sioAzkUfgp)jg6VQnGH@$~d$ zWRh?NwsYrBEm~>QxPb!)Mxg#eu0zos2a>OW9Ez$4Ewca$e%c~d@~|GE?L_U49XtAC zGMy11^eDS;QaX-hO0`2a5ODYIT}D-uh=_>6^XJc31SFVjaeDUbNsE&q#wd=66{|)h z6)>BBEfGhGuo?J~KH9czYeQKU_^?ltkpGH~YP2CI*B7g~h7cU)#mPti??UD+3if9Y znxnqxgQzN`tTS#M44ZQr{EKcJkGE{uVr%SH>O_>3L{&ydKMA968Y}4NCo0C!&8NJ) zoMW5f-Me>Rdgja-finEJUp`G&+Jm4iH#+@L;J`+#!M?dS2p1X-&D9Z2I^8T=woKixC|Ffg zR5%(Y#m}8PmqkZMD@rqS5$RwPV55bsuC8WjX=x@boJS#_!>E4fqMEC#CibBx^fBnE zLXvMam!kJ)RY(f^&86rgv+&6}g63Kk14qAjh5du}lU5Q+-mS1-1F9uOdy9+)I|9QiVW6 z_@ox5wvh{^TZsB?))2P`QVeNO6bb_RKp=2J)8d=@(fySs?P%g+3|xxN%BFWfLm{tU zzkUL_(89}?FMAOoT({gNO_~&V^{SfJRrt`vC`Ss%Ke>PZ{$jzrG5Z!E`~yqw!}(l|LJ`MdDnVcJzT3eO!W*NVBO7_xPpU# z9Wd^DJV0?|88|k4j%Y6x6eqL#i4!M|HR5CFlgRJbr@CaJ9tl z+qcg)bBunCEy(dw);bq&q86kfEqGk&M3Gfi9zJ|%fl}n}iWp!hq>LEB=xGlcGbCs< zuCZ`r@Pmym(vB|ahC&)8lC60d<>{cY6K}})^XJcpYZKktu~=c~oqK9w+P2|g0BOkl zg$oycgXpFBEp7UgnVvOkR{6Sh>vHg-tflkO+u&V*h+2$`LlC7a$^WQOx&&{SIdO4u zzZ*?Ly@kj+T)cR33g8PgxJzr+tVzSux^rhe&A<=Q#CvFDR8-Vt2&hfS?np>T$i$O= zwGj_fA&mw#HMpTqHZ?)a=G!8qnRc2Iu4N^g(rTH_wPhvEw9}Mu{{io~NPfC;t|I^d N002ovPDHLkV1i(haYX Date: Sun, 10 Feb 2013 15:11:21 -0500 Subject: [PATCH 036/108] ios: Include overlays in built app bundles. Fix crash if the RetroArch.app/modules directory is missing or has no .dylib files inside. --- ios/RetroArch.xcodeproj/project.pbxproj | 4 ++++ ios/RetroArch/module_list.m | 23 +++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 1e9aa17d5d..aed5b097af 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -18,6 +18,7 @@ 96297A1D16C6D20900E6DCE0 /* settings_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A1C16C6D20900E6DCE0 /* settings_list.m */; }; 96297A2416C818FF00E6DCE0 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2216C818FF00E6DCE0 /* Icon-72.png */; }; 96297A2516C818FF00E6DCE0 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2316C818FF00E6DCE0 /* Icon.png */; }; + 96297A2716C82FF100E6DCE0 /* overlays in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2616C82FF100E6DCE0 /* overlays */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -95,6 +96,7 @@ 96297A1C16C6D20900E6DCE0 /* settings_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = settings_list.m; sourceTree = ""; }; 96297A2216C818FF00E6DCE0 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "RetroArch/Icon-72.png"; sourceTree = ""; }; 96297A2316C818FF00E6DCE0 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = RetroArch/Icon.png; sourceTree = ""; }; + 96297A2616C82FF100E6DCE0 /* overlays */ = {isa = PBXFileReference; lastKnownFileType = folder; name = overlays; path = ../media/overlays; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -300,6 +302,7 @@ 96AFAE1A16C1D4EA009DE44C = { isa = PBXGroup; children = ( + 96297A2616C82FF100E6DCE0 /* overlays */, 96297A2216C818FF00E6DCE0 /* Icon-72.png */, 96297A2316C818FF00E6DCE0 /* Icon.png */, 962979F416C43B9500E6DCE0 /* ic_dir.png */, @@ -722,6 +725,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 96297A2716C82FF100E6DCE0 /* overlays in Resources */, 96AFAE3816C1D4EA009DE44C /* InfoPlist.strings in Resources */, 96AFAE4016C1D4EA009DE44C /* Default.png in Resources */, 96AFAE4216C1D4EA009DE44C /* Default@2x.png in Resources */, diff --git a/ios/RetroArch/module_list.m b/ios/RetroArch/module_list.m index f898c1b12a..758ea06222 100644 --- a/ios/RetroArch/module_list.m +++ b/ios/RetroArch/module_list.m @@ -6,6 +6,16 @@ // Copyright (c) 2013 RetroArch. All rights reserved. // +static void display_error_alert(NSString* message) +{ + UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"RetroArch" + message:message + delegate:nil + cancelButtonTitle:@"OK" + otherButtonTitles:nil]; + [alert show]; +} + @implementation module_list { NSArray* modules; @@ -21,8 +31,17 @@ @"modules"]; modules = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:module_dir error:nil]; - modules = [module_dir stringsByAppendingPaths:modules]; - modules = [modules pathsMatchingExtensions:[NSArray arrayWithObject:@"dylib"]]; + + if (modules != nil) + { + modules = [module_dir stringsByAppendingPaths:modules]; + modules = [modules pathsMatchingExtensions:[NSArray arrayWithObject:@"dylib"]]; + } + + if (modules == nil || [modules count] == 0) + { + display_error_alert(@"No libretro cores were found."); + } [self setTitle:@"Choose Emulator"]; self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; From 31a3611fa0b73d07dfe5dd72d899f76215990e86 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 10 Feb 2013 15:24:35 -0500 Subject: [PATCH 037/108] ios: Consolidate generation of the config file path. Add the system directory whenever writing the config file. Refresh the config file before loaded a game. --- ios/RetroArch/RetroArch_iOS.h | 5 +++-- ios/RetroArch/RetroArch_iOS.m | 6 ++++-- ios/RetroArch/game_view.m | 14 +++++++------- ios/RetroArch/settings_list.m | 20 +++++++++----------- ios/RetroArch/views.h | 1 + 5 files changed, 24 insertions(+), 22 deletions(-) diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index 0d99c6644f..7bb85a7a26 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -12,6 +12,9 @@ + (RetroArch_iOS*)get; - (void)game_has_started; +@property (strong, nonatomic) NSString* system_directory; +@property (strong, nonatomic) NSString* config_file_path; + @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) NSString *module_path; @property (strong, nonatomic) UINavigationController *navigator; @@ -19,6 +22,4 @@ @property (strong, nonatomic) UIImage* folder_icon; @property (strong, nonatomic) UIBarButtonItem* settings_button; -@property const char* system_directory; - @end diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index bac4d5567c..1ab241eb12 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -28,8 +28,10 @@ extern uint32_t ios_current_touch_count ; - (void)applicationDidFinishLaunching:(UIApplication *)application { // TODO: Relocate this! - self.system_directory = "/var/mobile/Library/RetroArch/"; - mkdir(self.system_directory, 0755); + self.system_directory = @"/var/mobile/Library/RetroArch/"; + mkdir([self.system_directory UTF8String], 0755); + + self.config_file_path = [self.system_directory stringByAppendingPathComponent:@"retroarch.cfg"]; // Load icons self.file_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_file" ofType:@"png"]]; diff --git a/ios/RetroArch/game_view.m b/ios/RetroArch/game_view.m index 6754b96465..850d5463a5 100644 --- a/ios/RetroArch/game_view.m +++ b/ios/RetroArch/game_view.m @@ -28,15 +28,15 @@ void ios_load_game(const char* file_name) { if(!ra_initialized && file_name) { - const char* const sd = [RetroArch_iOS get].system_directory; - const char* libretro = [[RetroArch_iOS get].module_path UTF8String]; + [settings_list refresh_config_file]; + + const char* const sd = [[RetroArch_iOS get].system_directory UTF8String]; + const char* const cf =[[RetroArch_iOS get].config_file_path UTF8String]; + const char* const libretro = [[RetroArch_iOS get].module_path UTF8String]; - char config_path[PATH_MAX]; - snprintf(config_path, PATH_MAX, "%s/retroarch.cfg", sd); - config_path[PATH_MAX - 1] = 0; - bool have_config = 0 == access(config_path, R_OK); + bool have_config = 0 == access(cf, R_OK); - struct rarch_main_wrap main_wrapper = {file_name, sd, sd, have_config ? config_path : 0, libretro}; + struct rarch_main_wrap main_wrapper = {file_name, sd, sd, have_config ? cf : 0, libretro}; if (rarch_main_init_wrap(&main_wrapper) == 0) { rarch_init_msg_queue(); diff --git a/ios/RetroArch/settings_list.m b/ios/RetroArch/settings_list.m index 108637fddc..06f969b76f 100644 --- a/ios/RetroArch/settings_list.m +++ b/ios/RetroArch/settings_list.m @@ -137,12 +137,7 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam { self = [super initWithStyle:UITableViewStyleGrouped]; - const char* const sd = [RetroArch_iOS get].system_directory; - char config_path[PATH_MAX]; - snprintf(config_path, PATH_MAX, "%s/retroarch.cfg", sd); - config_path[PATH_MAX - 1] = 0; - - config = config_file_new(config_path); + config = config_file_new([[RetroArch_iOS get].config_file_path UTF8String]); if (!config) config = config_file_new(0); NSString* overlay_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/overlays/"]; @@ -183,8 +178,15 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam [self write_to_file]; } ++ (void)refresh_config_file +{ + [[[settings_list alloc] init] write_to_file]; +} + - (void)write_to_file { + config_set_string(config, "system_directory", [[RetroArch_iOS get].system_directory UTF8String]); + for (int i = 0; i != [settings count]; i ++) { NSArray* group = [settings objectAtIndex:i]; @@ -203,11 +205,7 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam } } - const char* const sd = [RetroArch_iOS get].system_directory; - char config_path[PATH_MAX]; - snprintf(config_path, PATH_MAX, "%s/retroarch.cfg", sd); - config_path[PATH_MAX - 1] = 0; - config_file_write(config, config_path); + config_file_write(config, [[RetroArch_iOS get].config_file_path UTF8String]); } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index bb93246564..19bda460db 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -14,4 +14,5 @@ @end @interface settings_list : UITableViewController ++ (void)refresh_config_file; @end \ No newline at end of file From 3127b4a1726f17fdc748b1e83faa97b4ee539504 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 10 Feb 2013 15:58:29 -0500 Subject: [PATCH 038/108] ios: Fill out the BUILDING instructions more. --- ios/BUILDING | 74 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 23 deletions(-) diff --git a/ios/BUILDING b/ios/BUILDING index bac8293360..aa1e6fb3d0 100644 --- a/ios/BUILDING +++ b/ios/BUILDING @@ -1,27 +1,55 @@ -The following instructions will only work if building from OS X. +The following instructions will only work if building from OS X, using latest XCode with fake signing enabled. -In general, to build for iOS devices, copy the configuration for OSX, then at the end add the lines: - sysroot = -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/ - CC = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc -arch armv7 $(sysroot) - CXX = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/g++ -arch armv7 $(sysroot) +To build RetroArch: + Open $(root)/ios/RetroArch.xcodeproj, change build type to iOSDevice then choose Product->Build For->Archiving. + After compilation finishes goto Window->Organizer->Projects->RetroArch then click the small arrow beside + the Derived Data field, this will open a finder window with the projects build files directory highlighted. + The app bundle can be found at Build/Products/* in that folder. Use scp to copy the .app bundle to the appropriate place + on your device. -Here is how it would look in Makefile.libretro for vba-next: - ... - else ifeq ($(platform), osx) - TARGET := vba_next_libretro.dylib - fpic := -fPIC - SHARED := -dynamiclib - ENDIANNESS_DEFINES = -DLSB_FIRST - else ifeq ($(platform), ios) - TARGET := vba_next_libretro.dylib - fpic := -fPIC - SHARED := -dynamiclib - ENDIANNESS_DEFINES = -DLSB_FIRST + +To build libretro cores: + In general, to build for iOS devices, copy the configuration for OSX, then at the end add the lines: + sysroot = -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/ + CC = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc -arch armv7 $(sysroot) + CXX = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/g++ -arch armv7 $(sysroot) - sysroot = -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/ - CC = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc -arch armv7 $(sysroot) - CXX = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/g++ -arch armv7 $(sysroot) - else ifeq ($(platform), ps3) - ... + Here is how it would look in Makefile.libretro for vba-next: + ... + else ifeq ($(platform), osx) + TARGET := vba_next_libretro.dylib + fpic := -fPIC + SHARED := -dynamiclib + ENDIANNESS_DEFINES = -DLSB_FIRST + else ifeq ($(platform), ios) + TARGET := vba_next_libretro.dylib + fpic := -fPIC + SHARED := -dynamiclib + ENDIANNESS_DEFINES = -DLSB_FIRST + + sysroot = -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/ + CC = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc -arch armv7 $(sysroot) + CXX = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/g++ -arch armv7 $(sysroot) + else ifeq ($(platform), ps3) + ... + + Other arm specific flags can be added if needed. + + Finally issue the make command for the module adding 'platform=ios' at the of the command. + (e.g. 'make -f Makefile.libretro platform=ios'). Then copy the resulting .dylib file into a sub-directory of the app + bundle named modules. (e.g. RetroArch.app/modules/vba_next_libretro.dylib). + +Paths: + /var/mobile/Library/RetroArch: Will be created to store both saved games and the retroarch.cfg. + /var/mobile/RetroArchGames: If this exists and is a directory it will be used as the root for game browsing. + /var/mobile: If RetroArchGames does not exist this will be used as the root for game browsing, + if another browser root is desired make RetroArchGames a symlink to the preferred path. + RetroArch.app/shaders: Contains .shader format shaders, sub-directories are supported. + RetroArch.app/overlays: Contains input overlay definitions, sub-directories are supported. + RetroArch.app/modules: Contains .dylib files for the libretro modules. The only constraint on the file name + is that it must end in .dylib, sub-directories are not supported. + +Simulator: + To test in iOS Simulator you will need to create the '/var/mobile' directory on you computer, and give yourself full + access to it. -Other arm specific flags can be added if needed. From 540788caf9e43bb1f74aed7e88d5d713675485c6 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 10 Feb 2013 19:32:22 -0500 Subject: [PATCH 039/108] ios: Add, but leave disabled, hack for getting key press/release events from a bluetooth keyboard. --- ios/RetroArch/RetroArch_iOS.h | 3 +++ ios/RetroArch/RetroArch_iOS.m | 20 +++++++++++++- ios/RetroArch/ios_input.c | 14 ++++++++++ ios/RetroArch/main.m | 49 ++++++++++++++++++++++++++++++++++- 4 files changed, 84 insertions(+), 2 deletions(-) diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index 7bb85a7a26..d5eacee460 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -7,6 +7,9 @@ #import +extern NSString *const GSEventKeyDownNotification; +extern NSString *const GSEventKeyUpNotification; + @interface RetroArch_iOS : UIResponder + (RetroArch_iOS*)get; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 1ab241eb12..2f26890426 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -16,7 +16,9 @@ extern struct int16_t full_x, full_y; } ios_touches[MAX_TOUCH]; -extern uint32_t ios_current_touch_count ; +extern bool ios_keys[256]; + +extern uint32_t ios_current_touch_count; @implementation RetroArch_iOS @@ -52,6 +54,22 @@ extern uint32_t ios_current_touch_count ; self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.rootViewController = self.navigator; [self.window makeKeyAndVisible]; + + // Setup keyboard hack + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyPressed:) name: GSEventKeyDownNotification object: nil]; + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyReleased:) name: GSEventKeyUpNotification object: nil]; +} + +-(void) keyPressed: (NSNotification*) notification +{ + int keycode = [[notification.userInfo objectForKey:@"keycode"] intValue]; + if (keycode < 256) ios_keys[keycode] = true; +} + +-(void) keyReleased: (NSNotification*) notification +{ + int keycode = [[notification.userInfo objectForKey:@"keycode"] intValue]; + if (keycode < 256) ios_keys[keycode] = false; } - (void)show_settings diff --git a/ios/RetroArch/ios_input.c b/ios/RetroArch/ios_input.c index 54df016725..c8aeb20f54 100644 --- a/ios/RetroArch/ios_input.c +++ b/ios/RetroArch/ios_input.c @@ -31,11 +31,14 @@ struct int16_t full_x, full_y; } ios_touches[MAX_TOUCH]; +bool ios_keys[256]; + uint32_t ios_current_touch_count = 0; static void *ios_input_init(void) { memset(ios_touches, 0, sizeof(ios_touches)); + memset(ios_keys, 0, sizeof(ios_keys)); return (void*)-1; } @@ -53,6 +56,17 @@ static int16_t ios_input_state(void *data, const struct retro_keybind **binds, u { switch (device) { + case RETRO_DEVICE_JOYPAD: + switch (id) + { + case RETRO_DEVICE_ID_JOYPAD_UP: return ios_keys[82]; + case RETRO_DEVICE_ID_JOYPAD_DOWN: return ios_keys[81]; + case RETRO_DEVICE_ID_JOYPAD_LEFT: return ios_keys[80]; + case RETRO_DEVICE_ID_JOYPAD_RIGHT: return ios_keys[79]; + default: return 0; + } + return 0; + case RARCH_DEVICE_POINTER_SCREEN: switch (id) { diff --git a/ios/RetroArch/main.m b/ios/RetroArch/main.m index 04cc63c413..cc78259734 100644 --- a/ios/RetroArch/main.m +++ b/ios/RetroArch/main.m @@ -7,9 +7,56 @@ #import +#define GSEVENT_TYPE 2 +#define GSEVENT_FLAGS 12 +#define GSEVENTKEY_KEYCODE 15 +#define GSEVENT_TYPE_KEYDOWN 10 +#define GSEVENT_TYPE_KEYUP 11 + +NSString *const GSEventKeyDownNotification = @"GSEventKeyDownHackNotification"; +NSString *const GSEventKeyUpNotification = @"GSEventKeyUpHackNotification"; + +@interface RApplication : UIApplication +@end + +@implementation RApplication + +#ifdef HWKB_HACK // Disabled pending further testing +// Stolen from: http://nacho4d-nacho4d.blogspot.com/2012/01/catching-keyboard-events-in-ios.html +- (void)sendEvent:(UIEvent *)event +{ + [super sendEvent:event]; + + if ([event respondsToSelector:@selector(_gsEvent)]) + { + int* eventMem = (int *)(void*)CFBridgingRetain([event performSelector:@selector(_gsEvent)]); + int eventType = eventMem ? eventMem[GSEVENT_TYPE] : 0; + + if (eventMem && (eventType == GSEVENT_TYPE_KEYDOWN || eventType == GSEVENT_TYPE_KEYUP)) + { + // Read keycode from GSEventKey + int tmp = eventMem[GSEVENTKEY_KEYCODE]; + UniChar *keycode = (UniChar *)&tmp; + + // Post notification + NSDictionary *inf = [[NSDictionary alloc] initWithObjectsAndKeys: + [NSNumber numberWithShort:keycode[0]], @"keycode", + nil]; + + [[NSNotificationCenter defaultCenter] + postNotificationName:(eventType == GSEVENT_TYPE_KEYDOWN) ? GSEventKeyDownNotification : GSEventKeyUpNotification + object:nil userInfo:inf]; + } + } +} +#endif + +@end + int main(int argc, char *argv[]) { @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([RetroArch_iOS class])); + return UIApplicationMain(argc, argv, NSStringFromClass([RApplication class]), NSStringFromClass([RetroArch_iOS class])); } } + From 546058c704465db0fff3c4ea6d6db19319bb5649 Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 11 Feb 2013 06:12:16 -0500 Subject: [PATCH 040/108] ios: Enable the keyboard hack, and map some default keys to it. --- ios/RetroArch/ios_input.c | 23 +++++++++++++++++++++++ ios/RetroArch/main.m | 1 + 2 files changed, 24 insertions(+) diff --git a/ios/RetroArch/ios_input.c b/ios/RetroArch/ios_input.c index c8aeb20f54..82a633ba3c 100644 --- a/ios/RetroArch/ios_input.c +++ b/ios/RetroArch/ios_input.c @@ -57,12 +57,21 @@ static int16_t ios_input_state(void *data, const struct retro_keybind **binds, u switch (device) { case RETRO_DEVICE_JOYPAD: + if (port != 0) return 0; switch (id) { case RETRO_DEVICE_ID_JOYPAD_UP: return ios_keys[82]; case RETRO_DEVICE_ID_JOYPAD_DOWN: return ios_keys[81]; case RETRO_DEVICE_ID_JOYPAD_LEFT: return ios_keys[80]; case RETRO_DEVICE_ID_JOYPAD_RIGHT: return ios_keys[79]; + case RETRO_DEVICE_ID_JOYPAD_B: return ios_keys[0x1D]; + case RETRO_DEVICE_ID_JOYPAD_A: return ios_keys[0x1B]; + case RETRO_DEVICE_ID_JOYPAD_Y: return ios_keys[0x04]; + case RETRO_DEVICE_ID_JOYPAD_X: return ios_keys[0x1D]; + case RETRO_DEVICE_ID_JOYPAD_START: return ios_keys[0x1A]; + case RETRO_DEVICE_ID_JOYPAD_SELECT: return ios_keys[0x14]; + case RETRO_DEVICE_ID_JOYPAD_L: return ios_keys[0x07]; + case RETRO_DEVICE_ID_JOYPAD_R: return ios_keys[0x06]; default: return 0; } return 0; @@ -86,6 +95,20 @@ static int16_t ios_input_state(void *data, const struct retro_keybind **binds, u static bool ios_input_key_pressed(void *data, int key) { + switch (key) + { + case RARCH_FAST_FORWARD_KEY: return ios_keys[0x2C]; + case RARCH_FAST_FORWARD_HOLD_KEY: return ios_keys[0x0F]; + case RARCH_LOAD_STATE_KEY: return ios_keys[0x03D]; + case RARCH_SAVE_STATE_KEY: return ios_keys[0x03B]; + case RARCH_STATE_SLOT_PLUS: return ios_keys[0x40]; + case RARCH_STATE_SLOT_MINUS: return ios_keys[0x3F]; + case RARCH_REWIND: return ios_keys[0x15]; + case RARCH_PAUSE_TOGGLE: return ios_keys[0x13]; + case RARCH_FRAMEADVANCE: return ios_keys[0x0E]; + case RARCH_RESET: return ios_keys[0x0B]; + } + return false; } diff --git a/ios/RetroArch/main.m b/ios/RetroArch/main.m index cc78259734..1a80052609 100644 --- a/ios/RetroArch/main.m +++ b/ios/RetroArch/main.m @@ -21,6 +21,7 @@ NSString *const GSEventKeyUpNotification = @"GSEventKeyUpHackNotification"; @implementation RApplication +#define HWKB_HACK #ifdef HWKB_HACK // Disabled pending further testing // Stolen from: http://nacho4d-nacho4d.blogspot.com/2012/01/catching-keyboard-events-in-ios.html - (void)sendEvent:(UIEvent *)event From 7096b0ac5e60095c4daf58f0ad2bf6c49a7d3d1c Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 11 Feb 2013 06:12:43 -0500 Subject: [PATCH 041/108] ios: Reset the opengl viewport every frame, seems the GL driver resets it... --- gfx/gl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gfx/gl.c b/gfx/gl.c index 1890cc8c49..c054b6ba5a 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -1254,6 +1254,10 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei RARCH_PERFORMANCE_START(copy_frame); gl_copy_frame(gl, frame, width, height, pitch); RARCH_PERFORMANCE_STOP(copy_frame); + +#ifdef IOS // Apparently the viewport is lost each frame, thanks apple. + gl_set_viewport(gl, gl->win_width, gl->win_height, false, true); +#endif } else glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); From 8e709702b083f5dd811edf887792b8d4d9c1b2e6 Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 11 Feb 2013 17:15:56 -0500 Subject: [PATCH 042/108] ios: Fixup for changes to audio resampler. --- ios/RetroArch.xcodeproj/project.pbxproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index aed5b097af..55fbcb2f86 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -19,6 +19,8 @@ 96297A2416C818FF00E6DCE0 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2216C818FF00E6DCE0 /* Icon-72.png */; }; 96297A2516C818FF00E6DCE0 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2316C818FF00E6DCE0 /* Icon.png */; }; 96297A2716C82FF100E6DCE0 /* overlays in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2616C82FF100E6DCE0 /* overlays */; }; + 96366C5016C9A4E100D64A22 /* resampler.c in Sources */ = {isa = PBXBuildFile; fileRef = 96366C4F16C9A4E100D64A22 /* resampler.c */; }; + 96366C5216C9A4E600D64A22 /* hermite.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEEC16C1DC73009DE44C /* hermite.c */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -97,6 +99,7 @@ 96297A2216C818FF00E6DCE0 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "RetroArch/Icon-72.png"; sourceTree = ""; }; 96297A2316C818FF00E6DCE0 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = RetroArch/Icon.png; sourceTree = ""; }; 96297A2616C82FF100E6DCE0 /* overlays */ = {isa = PBXFileReference; lastKnownFileType = folder; name = overlays; path = ../media/overlays; sourceTree = ""; }; + 96366C4F16C9A4E100D64A22 /* resampler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resampler.c; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -439,6 +442,7 @@ 96AFAEE516C1DC73009DE44C /* audio */ = { isa = PBXGroup; children = ( + 96366C4F16C9A4E100D64A22 /* resampler.c */, 96AFAEE616C1DC73009DE44C /* alsa.c */, 96AFAEE716C1DC73009DE44C /* alsathread.c */, 96AFAEE816C1DC73009DE44C /* coreaudio.c */, @@ -801,6 +805,8 @@ 96297A1116C5AEDE00E6DCE0 /* game_view.m in Sources */, 96297A1316C5AEFD00E6DCE0 /* directory_list.m in Sources */, 96297A1D16C6D20900E6DCE0 /* settings_list.m in Sources */, + 96366C5016C9A4E100D64A22 /* resampler.c in Sources */, + 96366C5216C9A4E600D64A22 /* hermite.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; From 634f4dd54322b030bc2c36dcb1ebab0243d29b0d Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 11 Feb 2013 18:45:45 -0500 Subject: [PATCH 043/108] ios: Patch coreaudio.c and use it instead of OpenAL. --- audio/coreaudio.c | 93 +++++++++++-------------- ios/RetroArch.xcodeproj/project.pbxproj | 20 +++--- 2 files changed, 54 insertions(+), 59 deletions(-) diff --git a/audio/coreaudio.c b/audio/coreaudio.c index f3bbaddd72..239a421218 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -22,8 +22,7 @@ #include "../boolean.h" #include -#include -#include +#include #include #include @@ -32,7 +31,7 @@ typedef struct coreaudio pthread_mutex_t lock; pthread_cond_t cond; - ComponentInstance dev; + AudioComponentInstance dev; bool dev_alive; fifo_buffer_t *buffer; @@ -49,7 +48,7 @@ static void coreaudio_free(void *data) if (dev->dev_alive) { AudioOutputUnitStop(dev->dev); - CloseComponent(dev->dev); + AudioComponentInstanceDispose(dev->dev); } if (dev->buffer) @@ -102,43 +101,32 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency) if (!dev) return NULL; - CFRunLoopRef run_loop = NULL; - AudioObjectPropertyAddress addr = { - kAudioHardwarePropertyRunLoop, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster - }; - pthread_mutex_init(&dev->lock, NULL); pthread_cond_init(&dev->cond, NULL); - AudioObjectSetPropertyData(kAudioObjectSystemObject, &addr, 0, NULL, - sizeof(CFRunLoopRef), &run_loop); - ComponentDescription desc = {0}; + // Create AudioComponent + AudioComponentDescription desc = {0}; desc.componentType = kAudioUnitType_Output; +#ifdef IOS + desc.componentSubType = kAudioUnitSubType_RemoteIO; +#else desc.componentSubType = kAudioUnitSubType_HALOutput; +#endif desc.componentManufacturer = kAudioUnitManufacturer_Apple; - AudioStreamBasicDescription stream_desc = {0}; - AudioStreamBasicDescription real_desc; - AudioChannelLayout layout = {0}; - AURenderCallbackStruct cb = {0}; - - Component comp = NULL; - OSStatus res = noErr; - UInt32 i_size = 0; - size_t fifo_size; - - comp = FindNextComponent(NULL, &desc); + AudioComponent comp = AudioComponentFindNext(NULL, &desc); if (comp == NULL) goto error; - - res = OpenAComponent(comp, &dev->dev); - if (res != noErr) + + if (AudioComponentInstanceNew(comp, &dev->dev) != noErr) goto error; dev->dev_alive = true; + // Set audio format + AudioStreamBasicDescription stream_desc = {0}; + AudioStreamBasicDescription real_desc; + stream_desc.mSampleRate = rate; stream_desc.mBitsPerChannel = sizeof(float) * CHAR_BIT; stream_desc.mChannelsPerFrame = 2; @@ -147,20 +135,16 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency) stream_desc.mFramesPerPacket = 1; stream_desc.mFormatID = kAudioFormatLinearPCM; stream_desc.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked | (is_little_endian() ? 0 : kAudioFormatFlagIsBigEndian); - - res = AudioUnitSetProperty(dev->dev, kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Input, 0, &stream_desc, sizeof(stream_desc)); - if (res != noErr) + + if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, 0, &stream_desc, sizeof(stream_desc)) != noErr) goto error; - - i_size = sizeof(real_desc); - res = AudioUnitGetProperty(dev->dev, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &real_desc, &i_size); - if (res != noErr) + + // Check returned audio format + UInt32 i_size = sizeof(real_desc);; + if (AudioUnitGetProperty(dev->dev, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &real_desc, &i_size) != noErr) goto error; - RARCH_LOG("[CoreAudio]: Using output sample rate of %.1f Hz\n", (float)real_desc.mSampleRate); - g_settings.audio.out_rate = real_desc.mSampleRate; - if (real_desc.mChannelsPerFrame != stream_desc.mChannelsPerFrame) goto error; if (real_desc.mBitsPerChannel != stream_desc.mBitsPerChannel) @@ -170,26 +154,34 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency) if (real_desc.mFormatID != stream_desc.mFormatID) goto error; - layout.mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelBitmap; - layout.mChannelBitmap = 0x03; + RARCH_LOG("[CoreAudio]: Using output sample rate of %.1f Hz\n", (float)real_desc.mSampleRate); + g_settings.audio.out_rate = real_desc.mSampleRate; - res = AudioUnitSetProperty(dev->dev, kAudioUnitProperty_AudioChannelLayout, - kAudioUnitScope_Input, 0, &layout, sizeof(layout)); - if (res != noErr) + + // Set channel layout (fails on iOS) +#ifndef IOS + AudioChannelLayout layout = {0}; + + layout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; + if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_AudioChannelLayout, + kAudioUnitScope_Input, 0, &layout, sizeof(layout)) != noErr) goto error; +#endif + // Set callbacks and finish up + AURenderCallbackStruct cb = {0}; cb.inputProc = audio_cb; cb.inputProcRefCon = dev; - res = AudioUnitSetProperty(dev->dev, kAudioUnitProperty_SetRenderCallback, - kAudioUnitScope_Input, 0, &cb, sizeof(cb)); - if (res != noErr) + if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_SetRenderCallback, + kAudioUnitScope_Input, 0, &cb, sizeof(cb)) != noErr) goto error; - res = AudioUnitInitialize(dev->dev); - if (res != noErr) + if (AudioUnitInitialize(dev->dev) != noErr) goto error; + size_t fifo_size; + fifo_size = (latency * g_settings.audio.out_rate) / 1000; fifo_size *= 2 * sizeof(float); dev->buffer_size = fifo_size; @@ -200,8 +192,7 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency) RARCH_LOG("[CoreAudio]: Using buffer size of %u bytes: (latency = %u ms)\n", (unsigned)fifo_size, latency); - res = AudioOutputUnitStart(dev->dev); - if (res != noErr) + if (AudioOutputUnitStart(dev->dev) != noErr) goto error; return dev; diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 55fbcb2f86..1db4b195b8 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -21,6 +21,9 @@ 96297A2716C82FF100E6DCE0 /* overlays in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2616C82FF100E6DCE0 /* overlays */; }; 96366C5016C9A4E100D64A22 /* resampler.c in Sources */ = {isa = PBXBuildFile; fileRef = 96366C4F16C9A4E100D64A22 /* resampler.c */; }; 96366C5216C9A4E600D64A22 /* hermite.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEEC16C1DC73009DE44C /* hermite.c */; }; + 96366C5316C9A7C100D64A22 /* coreaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEE816C1DC73009DE44C /* coreaudio.c */; }; + 96366C5516C9AC3300D64A22 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5416C9AC3300D64A22 /* CoreAudio.framework */; }; + 96366C5916C9ACF500D64A22 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -54,8 +57,6 @@ 96AFAEE416C1DBDB009DE44C /* config_file.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEE116C1DBDB009DE44C /* config_file.c */; }; 96AFAF0B16C1DC73009DE44C /* null.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEEE16C1DC73009DE44C /* null.c */; }; 96AFAF1816C1DC73009DE44C /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEFD16C1DC73009DE44C /* utils.c */; }; - 96AFAF1F16C1DF0A009DE44C /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAF1E16C1DF0A009DE44C /* OpenAL.framework */; }; - 96AFAF2016C1DF3A009DE44C /* openal.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEEF16C1DC73009DE44C /* openal.c */; }; 96AFAF2216C1DF88009DE44C /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAF2116C1DF88009DE44C /* libz.dylib */; }; 96AFAF2D16C1DFC8009DE44C /* compat.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF2416C1DFC8009DE44C /* compat.c */; }; 96AFAF2F16C1DFC8009DE44C /* rxml.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF2916C1DFC8009DE44C /* rxml.c */; }; @@ -100,6 +101,8 @@ 96297A2316C818FF00E6DCE0 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = RetroArch/Icon.png; sourceTree = ""; }; 96297A2616C82FF100E6DCE0 /* overlays */ = {isa = PBXFileReference; lastKnownFileType = folder; name = overlays; path = ../media/overlays; sourceTree = ""; }; 96366C4F16C9A4E100D64A22 /* resampler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resampler.c; sourceTree = ""; }; + 96366C5416C9AC3300D64A22 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; + 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -190,7 +193,6 @@ 96AFAF0216C1DC73009DE44C /* xaudio-c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "xaudio-c.h"; sourceTree = ""; }; 96AFAF0316C1DC73009DE44C /* xaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xaudio.h; sourceTree = ""; }; 96AFAF0416C1DC73009DE44C /* xaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xaudio.c; sourceTree = ""; }; - 96AFAF1E16C1DF0A009DE44C /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; }; 96AFAF2116C1DF88009DE44C /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; 96AFAF2416C1DFC8009DE44C /* compat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = compat.c; sourceTree = ""; }; 96AFAF2516C1DFC8009DE44C /* getopt_rarch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = getopt_rarch.h; sourceTree = ""; }; @@ -289,8 +291,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 96366C5916C9ACF500D64A22 /* AudioToolbox.framework in Frameworks */, + 96366C5516C9AC3300D64A22 /* CoreAudio.framework in Frameworks */, 96AFAF2216C1DF88009DE44C /* libz.dylib in Frameworks */, - 96AFAF1F16C1DF0A009DE44C /* OpenAL.framework in Frameworks */, 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */, 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */, 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */, @@ -311,7 +314,6 @@ 962979F416C43B9500E6DCE0 /* ic_dir.png */, 962979F516C43B9500E6DCE0 /* ic_file.png */, 96AFAF2116C1DF88009DE44C /* libz.dylib */, - 96AFAF1E16C1DF0A009DE44C /* OpenAL.framework */, 96AFAE9C16C1D976009DE44C /* core */, 96AFAE3316C1D4EA009DE44C /* RetroArch */, 96AFAE2816C1D4EA009DE44C /* Frameworks */, @@ -330,6 +332,8 @@ 96AFAE2816C1D4EA009DE44C /* Frameworks */ = { isa = PBXGroup; children = ( + 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */, + 96366C5416C9AC3300D64A22 /* CoreAudio.framework */, 96AFAE2916C1D4EA009DE44C /* UIKit.framework */, 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */, 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */, @@ -772,7 +776,6 @@ 96AFAEE416C1DBDB009DE44C /* config_file.c in Sources */, 96AFAF0B16C1DC73009DE44C /* null.c in Sources */, 96AFAF1816C1DC73009DE44C /* utils.c in Sources */, - 96AFAF2016C1DF3A009DE44C /* openal.c in Sources */, 96AFAF2D16C1DFC8009DE44C /* compat.c in Sources */, 96AFAF2F16C1DFC8009DE44C /* rxml.c in Sources */, 96AFAF8D16C1E00A009DE44C /* bitmapfont.c in Sources */, @@ -807,6 +810,7 @@ 96297A1D16C6D20900E6DCE0 /* settings_list.m in Sources */, 96366C5016C9A4E100D64A22 /* resampler.c in Sources */, 96366C5216C9A4E600D64A22 /* hermite.c in Sources */, + 96366C5316C9A7C100D64A22 /* coreaudio.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -959,7 +963,7 @@ "-D__LIBRETRO__", "-DRARCH_PERFORMANCE_MODE", "-DPACKAGE_VERSION=\\\"1.0\\\"", - "-DHAVE_AL", + "-DHAVE_COREAUDIO", "-DHAVE_DYNAMIC", "-DHAVE_OVERLAY", "-DHAVE_ZLIB", @@ -996,7 +1000,7 @@ "-D__LIBRETRO__", "-DRARCH_PERFORMANCE_MODE", "-DPACKAGE_VERSION=\\\"1.0\\\"", - "-DHAVE_AL", + "-DHAVE_COREAUDIO", "-DHAVE_DYNAMIC", "-DHAVE_OVERLAY", "-DHAVE_ZLIB", From cf78e13e6ea4afe428f91f124d4713681152d6a2 Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 11 Feb 2013 20:56:26 -0500 Subject: [PATCH 044/108] ios: Add -DHAVE_FBO to release builds; doesn't fix shaders on device though. --- ios/RetroArch.xcodeproj/project.pbxproj | 1 + 1 file changed, 1 insertion(+) diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 1db4b195b8..e455106e18 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -990,6 +990,7 @@ "-DHAVE_RARCH_MAIN_WRAP", "-DIOS", "-DHAVE_OPENGL", + "-DHAVE_FBO", "-DHAVE_OPENGLES", "-DHAVE_VID_CONTEXT", "-DHAVE_OPENGLES2", From e3447803a40bf59aab5a80ffee7c1952dc54d5ab Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 12 Feb 2013 16:01:11 -0500 Subject: [PATCH 045/108] ios: Start adding bluetooth keyboard remapping support. --- ios/RetroArch/ios_input.c | 256 ++++++++++++++++++++++++++++++---- ios/RetroArch/settings_list.m | 74 +++++++++- 2 files changed, 299 insertions(+), 31 deletions(-) diff --git a/ios/RetroArch/ios_input.c b/ios/RetroArch/ios_input.c index 82a633ba3c..528089cb4b 100644 --- a/ios/RetroArch/ios_input.c +++ b/ios/RetroArch/ios_input.c @@ -21,7 +21,190 @@ #include "../../general.h" #include "../../driver.h" +/* + 0x00 Reserved (no event indicated) + 0x01 Keyboard ErrorRollOver + 0x02 Keyboard POSTFail + 0x03 Keyboard ErrorUndefined + 0x2D Keyboard - and (underscore) + 0x2E Keyboard = and + + 0x2F Keyboard [ and { + 0x30 Keyboard ] and } + 0x31 Keyboard \ and | + 0x32 Keyboard Non-US # and ~ + 0x33 Keyboard ; and : + 0x34 Keyboard ' and " + 0x36 Keyboard, and < + 0x37 Keyboard . and > + 0x38 Keyboard / and ? + 0x39 Keyboard Caps Lock + 0x46 Keyboard PrintScreen + 0x47 Keyboard Scroll Lock + 0x4C Keyboard Delete Forward + 0x53 Keypad Num Lock and Clear + 0x63 Keypad . and Delete + 0x64 Keyboard Non-US \ and | + 0x65 Keyboard Application + 0x66 Keyboard Power + 0x67 Keypad = + 0x68 Keyboard F13 + 0x69 Keyboard F14 + 0x6A Keyboard F15 + 0x6B Keyboard F16 + 0x6C Keyboard F17 + 0x6D Keyboard F18 + 0x6E Keyboard F19 + 0x6F Keyboard F20 + 0x70 Keyboard F21 + 0x71 Keyboard F22 + 0x72 Keyboard F23 + 0x73 Keyboard F24 + 0x74 Keyboard Execute + 0x75 Keyboard Help + 0x76 Keyboard Menu + 0x77 Keyboard Select + 0x78 Keyboard Stop + 0x79 Keyboard Again + 0x7A Keyboard Undo + 0x7B Keyboard Cut + 0x7C Keyboard Copy + 0x7D Keyboard Paste + 0x7E Keyboard Find + 0x7F Keyboard Mute + 0x80 Keyboard Volume Up + 0x81 Keyboard Volume Down + 0x82 Keyboard Locking Caps Lock + 0x83 Keyboard Locking Num Lock + 0x84 Keyboard Locking Scroll Lock + 0x85 Keypad Comma + 0x86 Keypad Equal Sign + 0x87 Keyboard International1 + 0x88 Keyboard International2 + 0x89 Keyboard International3 + 0x8A Keyboard International4 + 0x8B Keyboard International5 + 0x8C Keyboard International6 + 0x8D Keyboard International7 + 0x8E Keyboard International8 + 0x8F Keyboard International9 + 0x90 Keyboard LANG1 + 0x91 Keyboard LANG2 + 0x92 Keyboard LANG3 + 0x93 Keyboard LANG4 + 0x94 Keyboard LANG5 + 0x95 Keyboard LANG6 + 0x96 Keyboard LANG7 + 0x97 Keyboard LANG8 + 0x98 Keyboard LANG9 + 0x99 Keyboard Alternate Erase + 0x9A Keyboard SysReq/Attention + 0x9B Keyboard Cancel + 0x9C Keyboard Clear + 0x9D Keyboard Prior + 0x9E Keyboard Return + 0x9F Keyboard Separator + 0xA0 Keyboard Out + 0xA1 Keyboard Oper + 0xA2 Keyboard Clear/Again + 0xA3 Keyboard CrSel/Props + 0xA4 Keyboard ExSel + 0xE3 Keyboard Left GUI + 0xE4 Keyboard RightControl + 0xE6 Keyboard RightAlt + 0xE7 Keyboard Right GUI +*/ + +// This may be useful for other platforms too +static const struct rarch_key_map rarch_key_map_hidusage[] = { + { 0x50, RETROK_LEFT }, + { 0x4F, RETROK_RIGHT }, + { 0x52, RETROK_UP }, + { 0x51, RETROK_DOWN }, + { 0x28, RETROK_RETURN }, + { 0x2B, RETROK_TAB }, + { 0x49, RETROK_INSERT }, + { 0x4C, RETROK_DELETE }, + { 0xE5, RETROK_RSHIFT }, + { 0xE1, RETROK_LSHIFT }, + { 0xE0, RETROK_LCTRL }, + { 0x4D, RETROK_END }, + { 0x4A, RETROK_HOME }, + { 0x4E, RETROK_PAGEDOWN }, + { 0x4B, RETROK_PAGEUP }, + { 0xE2, RETROK_LALT }, + { 0x2C, RETROK_SPACE }, + { 0x29, RETROK_ESCAPE }, + { 0x2A, RETROK_BACKSPACE }, + { 0x58, RETROK_KP_ENTER }, + { 0x57, RETROK_KP_PLUS }, + { 0x56, RETROK_KP_MINUS }, + { 0x55, RETROK_KP_MULTIPLY }, + { 0x54, RETROK_KP_DIVIDE }, + { 0x35, RETROK_BACKQUOTE }, + { 0x48, RETROK_PAUSE }, + { 0x62, RETROK_KP0 }, + { 0x59, RETROK_KP1 }, + { 0x5A, RETROK_KP2 }, + { 0x5B, RETROK_KP3 }, + { 0x5C, RETROK_KP4 }, + { 0x5D, RETROK_KP5 }, + { 0x5E, RETROK_KP6 }, + { 0x5F, RETROK_KP7 }, + { 0x60, RETROK_KP8 }, + { 0x61, RETROK_KP9 }, + { 0x27, RETROK_0 }, + { 0x1E, RETROK_1 }, + { 0x1F, RETROK_2 }, + { 0x20, RETROK_3 }, + { 0x21, RETROK_4 }, + { 0x22, RETROK_5 }, + { 0x23, RETROK_6 }, + { 0x24, RETROK_7 }, + { 0x25, RETROK_8 }, + { 0x26, RETROK_9 }, + { 0x3A, RETROK_F1 }, + { 0x3B, RETROK_F2 }, + { 0x3C, RETROK_F3 }, + { 0x3D, RETROK_F4 }, + { 0x3E, RETROK_F5 }, + { 0x3F, RETROK_F6 }, + { 0x40, RETROK_F7 }, + { 0x41, RETROK_F8 }, + { 0x42, RETROK_F9 }, + { 0x43, RETROK_F10 }, + { 0x44, RETROK_F11 }, + { 0x45, RETROK_F12 }, + { 0x04, RETROK_a }, + { 0x05, RETROK_b }, + { 0x06, RETROK_c }, + { 0x07, RETROK_d }, + { 0x08, RETROK_e }, + { 0x09, RETROK_f }, + { 0x0A, RETROK_g }, + { 0x0B, RETROK_h }, + { 0x0C, RETROK_i }, + { 0x0D, RETROK_j }, + { 0x0E, RETROK_k }, + { 0x0F, RETROK_l }, + { 0x10, RETROK_m }, + { 0x11, RETROK_n }, + { 0x12, RETROK_o }, + { 0x13, RETROK_p }, + { 0x14, RETROK_q }, + { 0x15, RETROK_r }, + { 0x16, RETROK_s }, + { 0x17, RETROK_t }, + { 0x18, RETROK_u }, + { 0x19, RETROK_v }, + { 0x1A, RETROK_w }, + { 0x1B, RETROK_x }, + { 0x1C, RETROK_y }, + { 0x1D, RETROK_z }, + { 0, RETROK_UNKNOWN } +}; + #define MAX_TOUCH 16 +#define MAX_KEYS 256 struct { @@ -31,12 +214,38 @@ struct int16_t full_x, full_y; } ios_touches[MAX_TOUCH]; -bool ios_keys[256]; +bool ios_keys[MAX_KEYS]; uint32_t ios_current_touch_count = 0; +static bool l_ios_is_key_pressed(enum retro_key key) +{ + if ((int)key >= 0 && key < RETROK_LAST) + { + int hidkey = input_translate_rk_to_keysym(key); + return (hidkey < MAX_KEYS) ? ios_keys[hidkey] : false; + } + + return false; +} + +static int16_t l_ios_joypad_device_state(const struct retro_keybind **binds_, + unsigned port_num, unsigned id) +{ + const struct retro_keybind *binds = binds_[port_num]; + if (id < RARCH_BIND_LIST_END) + { + const struct retro_keybind *bind = &binds[id]; + return bind->valid && l_ios_is_key_pressed(bind->key); + } + else + return 0; +} + static void *ios_input_init(void) { + input_init_keyboard_lut(rarch_key_map_hidusage); + memset(ios_touches, 0, sizeof(ios_touches)); memset(ios_keys, 0, sizeof(ios_keys)); return (void*)-1; @@ -57,25 +266,13 @@ static int16_t ios_input_state(void *data, const struct retro_keybind **binds, u switch (device) { case RETRO_DEVICE_JOYPAD: - if (port != 0) return 0; - switch (id) - { - case RETRO_DEVICE_ID_JOYPAD_UP: return ios_keys[82]; - case RETRO_DEVICE_ID_JOYPAD_DOWN: return ios_keys[81]; - case RETRO_DEVICE_ID_JOYPAD_LEFT: return ios_keys[80]; - case RETRO_DEVICE_ID_JOYPAD_RIGHT: return ios_keys[79]; - case RETRO_DEVICE_ID_JOYPAD_B: return ios_keys[0x1D]; - case RETRO_DEVICE_ID_JOYPAD_A: return ios_keys[0x1B]; - case RETRO_DEVICE_ID_JOYPAD_Y: return ios_keys[0x04]; - case RETRO_DEVICE_ID_JOYPAD_X: return ios_keys[0x1D]; - case RETRO_DEVICE_ID_JOYPAD_START: return ios_keys[0x1A]; - case RETRO_DEVICE_ID_JOYPAD_SELECT: return ios_keys[0x14]; - case RETRO_DEVICE_ID_JOYPAD_L: return ios_keys[0x07]; - case RETRO_DEVICE_ID_JOYPAD_R: return ios_keys[0x06]; - default: return 0; - } + return l_ios_joypad_device_state(binds, port, id); + case RETRO_DEVICE_ANALOG: + return 0; + case RETRO_DEVICE_MOUSE: + return 0; + case RETRO_DEVICE_POINTER: return 0; - case RARCH_DEVICE_POINTER_SCREEN: switch (id) { @@ -88,6 +285,11 @@ static int16_t ios_input_state(void *data, const struct retro_keybind **binds, u default: return 0; } + case RETRO_DEVICE_KEYBOARD: + return 0; + case RETRO_DEVICE_LIGHTGUN: + return 0; + default: return 0; } @@ -95,18 +297,12 @@ static int16_t ios_input_state(void *data, const struct retro_keybind **binds, u static bool ios_input_key_pressed(void *data, int key) { - switch (key) + const struct retro_keybind *binds = g_settings.input.binds[0]; + + if (key >= 0 && key < RARCH_BIND_LIST_END) { - case RARCH_FAST_FORWARD_KEY: return ios_keys[0x2C]; - case RARCH_FAST_FORWARD_HOLD_KEY: return ios_keys[0x0F]; - case RARCH_LOAD_STATE_KEY: return ios_keys[0x03D]; - case RARCH_SAVE_STATE_KEY: return ios_keys[0x03B]; - case RARCH_STATE_SLOT_PLUS: return ios_keys[0x40]; - case RARCH_STATE_SLOT_MINUS: return ios_keys[0x3F]; - case RARCH_REWIND: return ios_keys[0x15]; - case RARCH_PAUSE_TOGGLE: return ios_keys[0x13]; - case RARCH_FRAMEADVANCE: return ios_keys[0x0E]; - case RARCH_RESET: return ios_keys[0x0B]; + const struct retro_keybind *bind = &binds[key]; + return l_ios_is_key_pressed(bind->key); } return false; diff --git a/ios/RetroArch/settings_list.m b/ios/RetroArch/settings_list.m index 06f969b76f..ad16e5db73 100644 --- a/ios/RetroArch/settings_list.m +++ b/ios/RetroArch/settings_list.m @@ -41,6 +41,18 @@ static NSMutableDictionary* boolean_setting(config_file_t* config, NSString* nam nil]; } +static NSMutableDictionary* button_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue) +{ + NSString* value = get_value_from_config(config, name, defaultValue); + + return [[NSMutableDictionary alloc] initWithObjectsAndKeys: + @"C", @"TYPE", + name, @"NAME", + label, @"LABEL", + value, @"VALUE", + nil]; +} + static NSMutableDictionary* enumeration_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue, NSArray* values) { NSString* value = get_value_from_config(config, name, defaultValue); @@ -72,6 +84,47 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam nil]; } +@interface button_getter : NSObject +@end + +@implementation button_getter +{ + button_getter* me; + NSMutableDictionary* value; + UIAlertView* alert; +} + +- (id)initWithSetting:(NSMutableDictionary*)setting +{ + value = setting; + + alert = [[UIAlertView alloc] initWithTitle:@"RetroArch" + message:[value objectForKey:@"LABEL"] + delegate:self + cancelButtonTitle:@"Cancel" + otherButtonTitles:nil]; + [alert show]; + + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyReleased:) name: GSEventKeyUpNotification object: nil]; + + me = self; + return self; +} + +- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; + me = nil; +} + +- (void)keyReleased:(NSNotification*) notification +{ + [alert dismissWithClickedButtonIndex:0 animated:YES]; +} + +@end + + @interface enumeration_list : UITableViewController @end @@ -160,6 +213,21 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam subpath_setting(config, @"input_overlay", @"Input Overlay", @"", overlay_path, @"cfg"), nil], + [NSArray arrayWithObjects:@"System Keys", + button_setting(config, @"input_save_state", @"Save State", @"f2"), + button_setting(config, @"input_load_state", @"Load State", @"f4"), + button_setting(config, @"input_state_slot_increase", @"Next State Slot", @"f7"), + button_setting(config, @"input_state_slot_decrease", @"Previous State Slot", @"f6"), + button_setting(config, @"input_toggle_fast_forward", @"Toggle Fast Forward", @"space"), + button_setting(config, @"input_hold_fast_forward", @"Hold Fast Forward", @"l"), + button_setting(config, @"input_rewind", @"Rewind", @"r"), + button_setting(config, @"input_slowmotion", @"Slow Motion", @"e"), + button_setting(config, @"input_pause_toogle", @"Pause", @"p"), + button_setting(config, @"input_frame_advance", @"Advance Frame", @"k"), + button_setting(config, @"input_reset", @"Reset", @"h"), + button_setting(config, @"input_exit_emulator", @"Close Game", @"escape"), + nil], + [NSArray arrayWithObjects:@"Save States", boolean_setting(config, @"rewind_enable", @"Enable Rewinding", @"false"), boolean_setting(config, @"block_sram_overwrite", @"Disable SRAM on Load", @"false"), @@ -219,6 +287,10 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam pushViewController:[[enumeration_list alloc] initWithSetting:setting fromTable:(UITableView*)self.view] animated:YES]; } + else if([type isEqualToString:@"C"]) + { + [[button_getter alloc] initWithSetting:setting]; + } } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView @@ -269,7 +341,7 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam objc_setAssociatedObject(swt, SETTINGID, setting, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - else if ([type isEqualToString:@"E"] || [type isEqualToString:@"F"]) + else if ([type isEqualToString:@"E"] || [type isEqualToString:@"F"] || [type isEqualToString:@"C"]) { cell = [self.tableView dequeueReusableCellWithIdentifier:@"enumeration"]; From c46de51fc384b4c5c09876a28fda589cd3627885 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 12 Feb 2013 17:16:34 -0500 Subject: [PATCH 046/108] ios: Add working setting items for key binding; split settings_list.m up. --- ios/RetroArch.xcodeproj/project.pbxproj | 26 +++- ios/RetroArch/settings/button_getter.m | 126 +++++++++++++++++++ ios/RetroArch/settings/enumeration_list.m | 62 +++++++++ ios/RetroArch/settings/settings.h | 15 +++ ios/RetroArch/{ => settings}/settings_list.m | 98 +-------------- 5 files changed, 227 insertions(+), 100 deletions(-) create mode 100644 ios/RetroArch/settings/button_getter.m create mode 100644 ios/RetroArch/settings/enumeration_list.m create mode 100644 ios/RetroArch/settings/settings.h rename ios/RetroArch/{ => settings}/settings_list.m (77%) diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index e455106e18..21cbe0468c 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -15,7 +15,6 @@ 96297A0F16C5AEA100E6DCE0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0E16C5AEA100E6DCE0 /* main.m */; }; 96297A1116C5AEDE00E6DCE0 /* game_view.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A1016C5AEDE00E6DCE0 /* game_view.m */; }; 96297A1316C5AEFD00E6DCE0 /* directory_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A1216C5AEFD00E6DCE0 /* directory_list.m */; }; - 96297A1D16C6D20900E6DCE0 /* settings_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A1C16C6D20900E6DCE0 /* settings_list.m */; }; 96297A2416C818FF00E6DCE0 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2216C818FF00E6DCE0 /* Icon-72.png */; }; 96297A2516C818FF00E6DCE0 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2316C818FF00E6DCE0 /* Icon.png */; }; 96297A2716C82FF100E6DCE0 /* overlays in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2616C82FF100E6DCE0 /* overlays */; }; @@ -24,6 +23,9 @@ 96366C5316C9A7C100D64A22 /* coreaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEE816C1DC73009DE44C /* coreaudio.c */; }; 96366C5516C9AC3300D64A22 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5416C9AC3300D64A22 /* CoreAudio.framework */; }; 96366C5916C9ACF500D64A22 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */; }; + 96366C7416CAF62200D64A22 /* button_getter.m in Sources */ = {isa = PBXBuildFile; fileRef = 96366C7016CAF62200D64A22 /* button_getter.m */; }; + 96366C7516CAF62200D64A22 /* enumeration_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96366C7116CAF62200D64A22 /* enumeration_list.m */; }; + 96366C7616CAF62200D64A22 /* settings_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96366C7316CAF62200D64A22 /* settings_list.m */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -96,13 +98,16 @@ 96297A0E16C5AEA100E6DCE0 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 96297A1016C5AEDE00E6DCE0 /* game_view.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = game_view.m; sourceTree = ""; }; 96297A1216C5AEFD00E6DCE0 /* directory_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = directory_list.m; sourceTree = ""; }; - 96297A1C16C6D20900E6DCE0 /* settings_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = settings_list.m; sourceTree = ""; }; 96297A2216C818FF00E6DCE0 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "RetroArch/Icon-72.png"; sourceTree = ""; }; 96297A2316C818FF00E6DCE0 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = RetroArch/Icon.png; sourceTree = ""; }; 96297A2616C82FF100E6DCE0 /* overlays */ = {isa = PBXFileReference; lastKnownFileType = folder; name = overlays; path = ../media/overlays; sourceTree = ""; }; 96366C4F16C9A4E100D64A22 /* resampler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resampler.c; sourceTree = ""; }; 96366C5416C9AC3300D64A22 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 96366C7016CAF62200D64A22 /* button_getter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = button_getter.m; sourceTree = ""; }; + 96366C7116CAF62200D64A22 /* enumeration_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = enumeration_list.m; sourceTree = ""; }; + 96366C7216CAF62200D64A22 /* settings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = settings.h; sourceTree = ""; }; + 96366C7316CAF62200D64A22 /* settings_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = settings_list.m; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -305,6 +310,17 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 96366C6F16CAF62200D64A22 /* settings */ = { + isa = PBXGroup; + children = ( + 96366C7016CAF62200D64A22 /* button_getter.m */, + 96366C7116CAF62200D64A22 /* enumeration_list.m */, + 96366C7216CAF62200D64A22 /* settings.h */, + 96366C7316CAF62200D64A22 /* settings_list.m */, + ); + path = settings; + sourceTree = ""; + }; 96AFAE1A16C1D4EA009DE44C = { isa = PBXGroup; children = ( @@ -346,6 +362,7 @@ 96AFAE3316C1D4EA009DE44C /* RetroArch */ = { isa = PBXGroup; children = ( + 96366C6F16CAF62200D64A22 /* settings */, 96297A1216C5AEFD00E6DCE0 /* directory_list.m */, 96297A1016C5AEDE00E6DCE0 /* game_view.m */, 96297A0D16C5ADDA00E6DCE0 /* views.h */, @@ -356,7 +373,6 @@ 96AFAE3416C1D4EA009DE44C /* Supporting Files */, 96CF015B16C2F72900ABF9C9 /* ios_input.c */, 96297A0816C59EC000E6DCE0 /* module_list.m */, - 96297A1C16C6D20900E6DCE0 /* settings_list.m */, ); path = RetroArch; sourceTree = ""; @@ -807,10 +823,12 @@ 96297A0F16C5AEA100E6DCE0 /* main.m in Sources */, 96297A1116C5AEDE00E6DCE0 /* game_view.m in Sources */, 96297A1316C5AEFD00E6DCE0 /* directory_list.m in Sources */, - 96297A1D16C6D20900E6DCE0 /* settings_list.m in Sources */, 96366C5016C9A4E100D64A22 /* resampler.c in Sources */, 96366C5216C9A4E600D64A22 /* hermite.c in Sources */, 96366C5316C9A7C100D64A22 /* coreaudio.c in Sources */, + 96366C7416CAF62200D64A22 /* button_getter.m in Sources */, + 96366C7516CAF62200D64A22 /* enumeration_list.m in Sources */, + 96366C7616CAF62200D64A22 /* settings_list.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/settings/button_getter.m b/ios/RetroArch/settings/button_getter.m new file mode 100644 index 0000000000..e71fce7bdc --- /dev/null +++ b/ios/RetroArch/settings/button_getter.m @@ -0,0 +1,126 @@ +// +// settings_list.m +// RetroArch +// +// Created by Jason Fetters on 2/8/13. +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +#import "settings.h" + +static const struct +{ + const char* const keyname; + const uint32_t hid_id; +} ios_key_name_map[] = { + { "left", 0x50 }, { "right", 0x4F }, + { "up", 0x52 }, { "down", 0x51 }, + { "enter", 0x28 }, { "kp_enter", 0x58 }, + { "tab", 0x2B }, { "insert", 0x49 }, + { "del", 0x4C }, { "end", 0x4D }, + { "home", 0x4A }, { "rshift", 0xE5 }, + { "shift", 0xE1 }, { "ctrl", 0xE0 }, + { "alt", 0xE2 }, { "space", 0x2C }, + { "escape", 0x29 }, { "backspace", 0x2A }, + { "backquote", 0x35 }, { "pause", 0x48 }, + + + { "add", 0x57 }, { "subtract", 0x56 }, /*kp_minus?*/ + { "multiply", 0x55 }, { "divide", 0x54 }, + { "kp_plus", 0x57 }, { "kp_minus", 0x56 }, + + { "f1", 0x3A }, { "f2", 0x3B }, + { "f3", 0x3C }, { "f4", 0x3D }, + { "f5", 0x3E }, { "f6", 0x3F }, + { "f7", 0x40 }, { "f8", 0x41 }, + { "f9", 0x42 }, { "f10", 0x43 }, + { "f11", 0x44 }, { "f12", 0x45 }, + + { "num0", 0x27 }, { "num1", 0x1E }, + { "num2", 0x1F }, { "num3", 0x20 }, + { "num4", 0x21 }, { "num5", 0x22 }, + { "num6", 0x23 }, { "num7", 0x24 }, + { "num8", 0x25 }, { "num9", 0x26 }, + + { "pageup", 0x48 }, { "pagedown", 0x4E }, + { "keypad0", 0x62 }, { "keypad1", 0x59 }, + { "keypad2", 0x5A }, { "keypad3", 0x5B }, + { "keypad4", 0x5C }, { "keypad5", 0x5D }, + { "keypad6", 0x5E }, { "keypad7", 0x5F }, + { "keypad8", 0x60 }, { "keypad9", 0x61 }, + + /*{ "period", RETROK_PERIOD }, + { "capslock", RETROK_CAPSLOCK }, { "numlock", RETROK_NUMLOCK }, + { "print_screen", RETROK_PRINT }, + { "scroll_lock", RETROK_SCROLLOCK },*/ + + { "a", 0x04 }, { "b", 0x05 }, { "c", 0x06 }, { "d", 0x07 }, + { "e", 0x08 }, { "f", 0x09 }, { "g", 0x0A }, { "h", 0x0B }, + { "i", 0x0C }, { "j", 0x0D }, { "k", 0x0E }, { "l", 0x0F }, + { "m", 0x10 }, { "n", 0x11 }, { "o", 0x12 }, { "p", 0x13 }, + { "q", 0x14 }, { "r", 0x15 }, { "s", 0x16 }, { "t", 0x17 }, + { "u", 0x18 }, { "v", 0x19 }, { "w", 0x1A }, { "x", 0x1B }, + { "y", 0x1C }, { "z", 0x1D }, + + { "nul", 0x00}, +}; + +static const NSString* get_key_config_name(uint32_t hid_id) +{ + for (int i = 0; ios_key_name_map[i].hid_id; i ++) + { + if (hid_id == ios_key_name_map[i].hid_id) + { + return [NSString stringWithUTF8String:ios_key_name_map[i].keyname]; + } + } + + return @"nul"; +} + +@implementation button_getter +{ + button_getter* me; + NSMutableDictionary* value; + UIAlertView* alert; + UITableView* view; +} + +- (id)initWithSetting:(NSMutableDictionary*)setting fromTable:(UITableView*)table +{ + self = [super init]; + + value = setting; + view = table; + me = self; + + alert = [[UIAlertView alloc] initWithTitle:@"RetroArch" + message:[value objectForKey:@"LABEL"] + delegate:self + cancelButtonTitle:@"Cancel" + otherButtonTitles:nil]; + [alert show]; + + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyReleased:) name: GSEventKeyUpNotification object: nil]; + + return self; +} + +- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; + me = nil; +} + +- (void)keyReleased:(NSNotification*) notification +{ + int keycode = [[notification.userInfo objectForKey:@"keycode"] intValue]; + + [value setObject:get_key_config_name(keycode) forKey:@"VALUE"]; + + [alert dismissWithClickedButtonIndex:0 animated:YES]; + [view reloadData]; +} + +@end + diff --git a/ios/RetroArch/settings/enumeration_list.m b/ios/RetroArch/settings/enumeration_list.m new file mode 100644 index 0000000000..7324d44a5e --- /dev/null +++ b/ios/RetroArch/settings/enumeration_list.m @@ -0,0 +1,62 @@ +// +// settings_list.m +// RetroArch +// +// Created by Jason Fetters on 2/8/13. +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +#import "settings.h" + +@implementation enumeration_list +{ + NSMutableDictionary* value; + UITableView* view; +}; + +- (id)initWithSetting:(NSMutableDictionary*)setting fromTable:(UITableView*)table +{ + self = [super initWithStyle:UITableViewStyleGrouped]; + + value = setting; + view = table; + [self setTitle: [value objectForKey:@"LABEL"]]; + return self; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 2; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return (section == 1) ? [[value objectForKey:@"VALUES"] count] : 1; +} + +- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"option"]; + cell = cell ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"option"]; + + if (indexPath.section == 1) + cell.textLabel.text = [[value objectForKey:@"VALUES"] objectAtIndex:indexPath.row]; + else + cell.textLabel.text = @"None"; + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.section == 1) + [value setObject:[[value objectForKey:@"VALUES"] objectAtIndex:indexPath.row] forKey:@"VALUE"]; + else + [value setObject:@"" forKey:@"VALUE"]; + + [view reloadData]; + [[RetroArch_iOS get].navigator popViewControllerAnimated:YES]; +} + +@end + diff --git a/ios/RetroArch/settings/settings.h b/ios/RetroArch/settings/settings.h new file mode 100644 index 0000000000..16cd73a080 --- /dev/null +++ b/ios/RetroArch/settings/settings.h @@ -0,0 +1,15 @@ +// +// settings_list.m +// RetroArch +// +// Created by Jason Fetters on 2/8/13. +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +@interface button_getter : NSObject +- (id)initWithSetting:(NSMutableDictionary*)setting fromTable:(UITableView*)table; +@end + +@interface enumeration_list : UITableViewController +- (id)initWithSetting:(NSMutableDictionary*)setting fromTable:(UITableView*)table; +@end diff --git a/ios/RetroArch/settings_list.m b/ios/RetroArch/settings/settings_list.m similarity index 77% rename from ios/RetroArch/settings_list.m rename to ios/RetroArch/settings/settings_list.m index ad16e5db73..1804a902ca 100644 --- a/ios/RetroArch/settings_list.m +++ b/ios/RetroArch/settings/settings_list.m @@ -7,6 +7,7 @@ // #import +#import "settings.h" #include "config_file.h" static const char* const SETTINGID = "SETTING"; @@ -84,101 +85,6 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam nil]; } -@interface button_getter : NSObject -@end - -@implementation button_getter -{ - button_getter* me; - NSMutableDictionary* value; - UIAlertView* alert; -} - -- (id)initWithSetting:(NSMutableDictionary*)setting -{ - value = setting; - - alert = [[UIAlertView alloc] initWithTitle:@"RetroArch" - message:[value objectForKey:@"LABEL"] - delegate:self - cancelButtonTitle:@"Cancel" - otherButtonTitles:nil]; - [alert show]; - - [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyReleased:) name: GSEventKeyUpNotification object: nil]; - - me = self; - return self; -} - -- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; - me = nil; -} - -- (void)keyReleased:(NSNotification*) notification -{ - [alert dismissWithClickedButtonIndex:0 animated:YES]; -} - -@end - - -@interface enumeration_list : UITableViewController -@end - -@implementation enumeration_list -{ - NSMutableDictionary* value; - UITableView* view; -}; - -- (id)initWithSetting:(NSMutableDictionary*)setting fromTable:(UITableView*)table -{ - self = [super initWithStyle:UITableViewStyleGrouped]; - - value = setting; - view = table; - [self setTitle: [value objectForKey:@"LABEL"]]; - return self; -} - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView -{ - return 2; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -{ - return (section == 1) ? [[value objectForKey:@"VALUES"] count] : 1; -} - -- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath -{ - UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"option"]; - cell = cell ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"option"]; - - if (indexPath.section == 1) - cell.textLabel.text = [[value objectForKey:@"VALUES"] objectAtIndex:indexPath.row]; - else - cell.textLabel.text = @"None"; - - return cell; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath -{ - if (indexPath.section == 1) - [value setObject:[[value objectForKey:@"VALUES"] objectAtIndex:indexPath.row] forKey:@"VALUE"]; - else - [value setObject:@"" forKey:@"VALUE"]; - - [view reloadData]; - [[RetroArch_iOS get].navigator popViewControllerAnimated:YES]; -} - -@end @implementation settings_list { @@ -289,7 +195,7 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam } else if([type isEqualToString:@"C"]) { - [[button_getter alloc] initWithSetting:setting]; + (void)[[button_getter alloc] initWithSetting:setting fromTable:(UITableView*)self.view]; } } From 1ebc0ab81a36f4d220529501ed15941d46c40678 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 12 Feb 2013 17:26:32 -0500 Subject: [PATCH 047/108] ios: Add bt keyboard mapping settings for player 1. --- ios/RetroArch/settings/settings_list.m | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/ios/RetroArch/settings/settings_list.m b/ios/RetroArch/settings/settings_list.m index 1804a902ca..801ad7552c 100644 --- a/ios/RetroArch/settings/settings_list.m +++ b/ios/RetroArch/settings/settings_list.m @@ -118,7 +118,29 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam [NSArray arrayWithObjects:@"Input", subpath_setting(config, @"input_overlay", @"Input Overlay", @"", overlay_path, @"cfg"), nil], - + + [NSArray arrayWithObjects:@"Player 1", + button_setting(config, @"input_player1_up", @"Up", @"up"), + button_setting(config, @"input_player1_down", @"Down", @"down"), + button_setting(config, @"input_player1_left", @"Left", @"left"), + button_setting(config, @"input_player1_right", @"Right", @"right"), + + button_setting(config, @"input_player1_start", @"Start", @"enter"), + button_setting(config, @"input_player1_select", @"Select", @"rshift"), + + button_setting(config, @"input_player1_b", @"B", @"z"), + button_setting(config, @"input_player1_a", @"A", @"x"), + button_setting(config, @"input_player1_x", @"X", @"s"), + button_setting(config, @"input_player1_y", @"Y", @"a"), + + button_setting(config, @"input_player1_l", @"L", @"q"), + button_setting(config, @"input_player1_r", @"R", @"w"), + button_setting(config, @"input_player1_l2", @"L2", @""), + button_setting(config, @"input_player1_r2", @"R2", @""), + button_setting(config, @"input_player1_l3", @"L3", @""), + button_setting(config, @"input_player1_r3", @"R3", @""), + nil], + [NSArray arrayWithObjects:@"System Keys", button_setting(config, @"input_save_state", @"Save State", @"f2"), button_setting(config, @"input_load_state", @"Load State", @"f4"), From 0d99d9fbf8508168644bf70d289ced1d30b3c9cd Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 13 Feb 2013 13:22:47 -0500 Subject: [PATCH 048/108] ios: Start to fix lifecycle management. The home button no longer closes the running game, pressing the exit key returns you to the loader. --- ios/RetroArch/RetroArch-Info.plist | 2 +- ios/RetroArch/RetroArch_iOS.h | 3 +- ios/RetroArch/RetroArch_iOS.m | 25 ++++--- ios/RetroArch/directory_list.m | 5 +- ios/RetroArch/game_view.m | 104 ++++++++++------------------- ios/RetroArch/views.h | 2 +- 6 files changed, 56 insertions(+), 85 deletions(-) diff --git a/ios/RetroArch/RetroArch-Info.plist b/ios/RetroArch/RetroArch-Info.plist index 6a3d2960f5..381fc886b6 100644 --- a/ios/RetroArch/RetroArch-Info.plist +++ b/ios/RetroArch/RetroArch-Info.plist @@ -37,7 +37,7 @@ UIInterfaceOrientationLandscapeRight UIApplicationExitsOnSuspend - + UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index d5eacee460..ced57264bf 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -13,7 +13,8 @@ extern NSString *const GSEventKeyUpNotification; @interface RetroArch_iOS : UIResponder + (RetroArch_iOS*)get; -- (void)game_has_started; +- (void)runGame:(NSString*)path; +- (void)gameHasExited; @property (strong, nonatomic) NSString* system_directory; @property (strong, nonatomic) NSString* config_file_path; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 2f26890426..ed5b6fd67d 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -27,6 +27,20 @@ extern uint32_t ios_current_touch_count; return (RetroArch_iOS*)[[UIApplication sharedApplication] delegate]; } +- (void)runGame:(NSString*)path +{ + self.window.rootViewController = [[game_view alloc] initWithGame:path]; + self.navigator = nil; +} + +- (void)gameHasExited +{ + self.navigator = [[UINavigationController alloc] init]; + [self.navigator pushViewController: [[module_list alloc] init] animated:YES]; + + self.window.rootViewController = self.navigator; +} + - (void)applicationDidFinishLaunching:(UIApplication *)application { // TODO: Relocate this! @@ -77,11 +91,6 @@ extern uint32_t ios_current_touch_count; [self.navigator pushViewController: [[settings_list alloc] init] animated:YES]; } -- (void)game_has_started -{ - self.navigator = nil; -} - - (void)processTouches:(NSArray*)touches { ios_current_touch_count = [touches count]; @@ -123,11 +132,5 @@ extern uint32_t ios_current_touch_count; [self processTouches:[[event allTouches] allObjects]]; } -- (void)applicationWillTerminate:(UIApplication *)application -{ - extern void ios_close_game(); - ios_close_game(); -} - @end diff --git a/ios/RetroArch/directory_list.m b/ios/RetroArch/directory_list.m index de985884a9..f1243428ed 100644 --- a/ios/RetroArch/directory_list.m +++ b/ios/RetroArch/directory_list.m @@ -63,10 +63,7 @@ static BOOL is_directory(NSString* path) } else { - [RetroArch_iOS get].window.rootViewController = [[game_view alloc] init]; - - extern void ios_load_game(const char*); - ios_load_game([path UTF8String]); + [[RetroArch_iOS get] runGame:path]; } } diff --git a/ios/RetroArch/game_view.m b/ios/RetroArch/game_view.m index 850d5463a5..89c43b70be 100644 --- a/ios/RetroArch/game_view.m +++ b/ios/RetroArch/game_view.m @@ -16,76 +16,23 @@ #include "general.h" -static game_view *current_view; static GLKView *gl_view; static float screen_scale; -static bool ra_initialized = false; -static bool ra_done = false; static int frame_skips = 4; static bool is_syncing = true; -void ios_load_game(const char* file_name) -{ - if(!ra_initialized && file_name) - { - [settings_list refresh_config_file]; - - const char* const sd = [[RetroArch_iOS get].system_directory UTF8String]; - const char* const cf =[[RetroArch_iOS get].config_file_path UTF8String]; - const char* const libretro = [[RetroArch_iOS get].module_path UTF8String]; - - bool have_config = 0 == access(cf, R_OK); - - struct rarch_main_wrap main_wrapper = {file_name, sd, sd, have_config ? cf : 0, libretro}; - if (rarch_main_init_wrap(&main_wrapper) == 0) - { - rarch_init_msg_queue(); - ra_initialized = TRUE; - - [[RetroArch_iOS get ]game_has_started]; - [current_view performSelector:@selector(rarch_iterate:) withObject:nil afterDelay:0.2f]; - } - } -} - -void ios_close_game() -{ - if (ra_initialized) - { - rarch_main_deinit(); - rarch_deinit_msg_queue(); - -#ifdef PERF_TEST - rarch_perf_log(); -#endif - - rarch_main_clear_state(); - - ra_done = true; - } - - ra_initialized = false; -} - @implementation game_view { EAGLContext *gl_context; + NSString* game; } -- (id)init +- (id)initWithGame:(NSString*)path { self = [super init]; - - gl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - [EAGLContext setCurrentContext:gl_context]; - - gl_view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) context:gl_context]; - gl_view.multipleTouchEnabled = YES; - self.view = gl_view; - + game = path; screen_scale = [[UIScreen mainScreen] scale]; - current_view = self; - + return self; } @@ -96,20 +43,43 @@ void ios_close_game() gl_view = nil; } - -- (void)rarch_iterate:(id)sender +- (void)loadView { - if (ra_initialized && !ra_done) - { - while (!ra_done && rarch_main_iterate()) - { - while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource); - } + gl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + [EAGLContext setCurrentContext:gl_context]; + + gl_view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) context:gl_context]; + gl_view.multipleTouchEnabled = YES; + self.view = gl_view; + + [self performSelector:@selector(runGame) withObject:nil afterDelay:0.2f]; +} - ios_close_game(); +- (void)runGame +{ + [settings_list refresh_config_file]; + + const char* const sd = [[RetroArch_iOS get].system_directory UTF8String]; + const char* const cf =[[RetroArch_iOS get].config_file_path UTF8String]; + const char* const libretro = [[RetroArch_iOS get].module_path UTF8String]; + + struct rarch_main_wrap main_wrapper = {[game UTF8String], sd, sd, cf, libretro}; + if (rarch_main_init_wrap(&main_wrapper) == 0) + { + rarch_init_msg_queue(); + while (rarch_main_iterate()) + while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource); + rarch_main_deinit(); + rarch_deinit_msg_queue(); - ra_done = true; +#ifdef PERF_TEST + rarch_perf_log(); +#endif + + rarch_main_clear_state(); } + + [[RetroArch_iOS get] gameHasExited]; } @end diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index 19bda460db..bd3a138bfd 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -2,7 +2,7 @@ #import @interface game_view : UIViewController - +- (id)initWithGame:(NSString*)path; @end @interface module_list : UITableViewController From 625c2c6d489bd3174a8e25cd828f1fbba3e96d8a Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 13 Feb 2013 15:46:56 -0500 Subject: [PATCH 049/108] ios: Clean up settings code some; move input settings into sub-pages. --- ios/RetroArch.xcodeproj/project.pbxproj | 4 + ios/RetroArch/RetroArch_iOS.m | 2 +- ios/RetroArch/game_view.m | 2 +- ios/RetroArch/settings/button_getter.m | 16 +- ios/RetroArch/settings/enumeration_list.m | 22 +- ios/RetroArch/settings/settings.h | 26 +- ios/RetroArch/settings/settings_list.m | 291 ++++++++-------------- ios/RetroArch/settings/settings_sublist.m | 173 +++++++++++++ ios/RetroArch/views.h | 14 +- 9 files changed, 330 insertions(+), 220 deletions(-) create mode 100644 ios/RetroArch/settings/settings_sublist.m diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 21cbe0468c..53f51d1bbc 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -26,6 +26,7 @@ 96366C7416CAF62200D64A22 /* button_getter.m in Sources */ = {isa = PBXBuildFile; fileRef = 96366C7016CAF62200D64A22 /* button_getter.m */; }; 96366C7516CAF62200D64A22 /* enumeration_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96366C7116CAF62200D64A22 /* enumeration_list.m */; }; 96366C7616CAF62200D64A22 /* settings_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96366C7316CAF62200D64A22 /* settings_list.m */; }; + 963F5AB216CC14C4009BBD19 /* settings_sublist.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AB116CC14C4009BBD19 /* settings_sublist.m */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -108,6 +109,7 @@ 96366C7116CAF62200D64A22 /* enumeration_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = enumeration_list.m; sourceTree = ""; }; 96366C7216CAF62200D64A22 /* settings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = settings.h; sourceTree = ""; }; 96366C7316CAF62200D64A22 /* settings_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = settings_list.m; sourceTree = ""; }; + 963F5AB116CC14C4009BBD19 /* settings_sublist.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = settings_sublist.m; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -317,6 +319,7 @@ 96366C7116CAF62200D64A22 /* enumeration_list.m */, 96366C7216CAF62200D64A22 /* settings.h */, 96366C7316CAF62200D64A22 /* settings_list.m */, + 963F5AB116CC14C4009BBD19 /* settings_sublist.m */, ); path = settings; sourceTree = ""; @@ -829,6 +832,7 @@ 96366C7416CAF62200D64A22 /* button_getter.m in Sources */, 96366C7516CAF62200D64A22 /* enumeration_list.m in Sources */, 96366C7616CAF62200D64A22 /* settings_list.m in Sources */, + 963F5AB216CC14C4009BBD19 /* settings_sublist.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index ed5b6fd67d..8103fed59a 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -88,7 +88,7 @@ extern uint32_t ios_current_touch_count; - (void)show_settings { - [self.navigator pushViewController: [[settings_list alloc] init] animated:YES]; + [self.navigator pushViewController: [[SettingsList alloc] init] animated:YES]; } - (void)processTouches:(NSArray*)touches diff --git a/ios/RetroArch/game_view.m b/ios/RetroArch/game_view.m index 89c43b70be..c97d993461 100644 --- a/ios/RetroArch/game_view.m +++ b/ios/RetroArch/game_view.m @@ -57,7 +57,7 @@ static bool is_syncing = true; - (void)runGame { - [settings_list refresh_config_file]; + [SettingsList refreshConfigFile]; const char* const sd = [[RetroArch_iOS get].system_directory UTF8String]; const char* const cf =[[RetroArch_iOS get].config_file_path UTF8String]; diff --git a/ios/RetroArch/settings/button_getter.m b/ios/RetroArch/settings/button_getter.m index e71fce7bdc..a96f6c2fef 100644 --- a/ios/RetroArch/settings/button_getter.m +++ b/ios/RetroArch/settings/button_getter.m @@ -65,7 +65,7 @@ static const struct { "nul", 0x00}, }; -static const NSString* get_key_config_name(uint32_t hid_id) +static NSString* get_key_config_name(uint32_t hid_id) { for (int i = 0; ios_key_name_map[i].hid_id; i ++) { @@ -78,15 +78,15 @@ static const NSString* get_key_config_name(uint32_t hid_id) return @"nul"; } -@implementation button_getter +@implementation ButtonGetter { - button_getter* me; - NSMutableDictionary* value; + ButtonGetter* me; + SettingData* value; UIAlertView* alert; UITableView* view; } -- (id)initWithSetting:(NSMutableDictionary*)setting fromTable:(UITableView*)table +- (id)initWithSetting:(SettingData*)setting fromTable:(UITableView*)table { self = [super init]; @@ -95,7 +95,7 @@ static const NSString* get_key_config_name(uint32_t hid_id) me = self; alert = [[UIAlertView alloc] initWithTitle:@"RetroArch" - message:[value objectForKey:@"LABEL"] + message:value.label delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil]; @@ -106,7 +106,7 @@ static const NSString* get_key_config_name(uint32_t hid_id) return self; } -- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex +- (void)alertView:(UIAlertView*)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { [[NSNotificationCenter defaultCenter] removeObserver:self]; me = nil; @@ -116,7 +116,7 @@ static const NSString* get_key_config_name(uint32_t hid_id) { int keycode = [[notification.userInfo objectForKey:@"keycode"] intValue]; - [value setObject:get_key_config_name(keycode) forKey:@"VALUE"]; + value.value = get_key_config_name(keycode); [alert dismissWithClickedButtonIndex:0 animated:YES]; [view reloadData]; diff --git a/ios/RetroArch/settings/enumeration_list.m b/ios/RetroArch/settings/enumeration_list.m index 7324d44a5e..61823d1fc9 100644 --- a/ios/RetroArch/settings/enumeration_list.m +++ b/ios/RetroArch/settings/enumeration_list.m @@ -8,30 +8,30 @@ #import "settings.h" -@implementation enumeration_list +@implementation SettingEnumerationList { - NSMutableDictionary* value; + SettingData* value; UITableView* view; }; -- (id)initWithSetting:(NSMutableDictionary*)setting fromTable:(UITableView*)table +- (id)initWithSetting:(SettingData*)setting fromTable:(UITableView*)table { self = [super initWithStyle:UITableViewStyleGrouped]; value = setting; view = table; - [self setTitle: [value objectForKey:@"LABEL"]]; + [self setTitle: value.label]; return self; } -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView { return 2; } -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section { - return (section == 1) ? [[value objectForKey:@"VALUES"] count] : 1; + return (section == 1) ? [value.subValues count] : 1; } - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath @@ -40,19 +40,19 @@ cell = cell ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"option"]; if (indexPath.section == 1) - cell.textLabel.text = [[value objectForKey:@"VALUES"] objectAtIndex:indexPath.row]; + cell.textLabel.text = [value.subValues objectAtIndex:indexPath.row]; else cell.textLabel.text = @"None"; return cell; } -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == 1) - [value setObject:[[value objectForKey:@"VALUES"] objectAtIndex:indexPath.row] forKey:@"VALUE"]; + value.value = [value.subValues objectAtIndex:indexPath.row]; else - [value setObject:@"" forKey:@"VALUE"]; + value.value = @""; [view reloadData]; [[RetroArch_iOS get].navigator popViewControllerAnimated:YES]; diff --git a/ios/RetroArch/settings/settings.h b/ios/RetroArch/settings/settings.h index 16cd73a080..d57fa970fa 100644 --- a/ios/RetroArch/settings/settings.h +++ b/ios/RetroArch/settings/settings.h @@ -6,10 +6,28 @@ // Copyright (c) 2013 RetroArch. All rights reserved. // -@interface button_getter : NSObject -- (id)initWithSetting:(NSMutableDictionary*)setting fromTable:(UITableView*)table; +#include "conf/config_file.h" + +enum SettingTypes +{ + BooleanSetting, ButtonSetting, EnumerationSetting, FileListSetting, GroupSetting +}; + +@interface SettingData : NSObject +@property enum SettingTypes type; + +@property (strong) NSString* label; +@property (strong) NSString* name; +@property (strong) NSString* value; + +@property (strong) NSString* path; +@property (strong) NSArray* subValues; @end -@interface enumeration_list : UITableViewController -- (id)initWithSetting:(NSMutableDictionary*)setting fromTable:(UITableView*)table; +@interface ButtonGetter : NSObject +- (id)initWithSetting:(SettingData*)setting fromTable:(UITableView*)table; +@end + +@interface SettingEnumerationList : UITableViewController +- (id)initWithSetting:(SettingData*)setting fromTable:(UITableView*)table; @end diff --git a/ios/RetroArch/settings/settings_list.m b/ios/RetroArch/settings/settings_list.m index 801ad7552c..bab96d5694 100644 --- a/ios/RetroArch/settings/settings_list.m +++ b/ios/RetroArch/settings/settings_list.m @@ -10,14 +10,16 @@ #import "settings.h" #include "config_file.h" -static const char* const SETTINGID = "SETTING"; +@implementation SettingData +@end + static NSString* get_value_from_config(config_file_t* config, NSString* name, NSString* defaultValue) { NSString* value = nil; char* v = 0; - if (config_get_string(config, [name UTF8String], &v)) + if (config && config_get_string(config, [name UTF8String], &v)) { value = [[NSString alloc] initWithUTF8String:v]; free(v); @@ -30,44 +32,47 @@ static NSString* get_value_from_config(config_file_t* config, NSString* name, NS return value; } -static NSMutableDictionary* boolean_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue) +static SettingData* boolean_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue) { - NSString* value = get_value_from_config(config, name, defaultValue); - - return [[NSMutableDictionary alloc] initWithObjectsAndKeys: - @"B", @"TYPE", - name, @"NAME", - label, @"LABEL", - value, @"VALUE", - nil]; + SettingData* result = [[SettingData alloc] init]; + result.type = BooleanSetting; + result.label = label; + result.name = name; + result.value = get_value_from_config(config, name, defaultValue); + return result; } -static NSMutableDictionary* button_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue) +static SettingData* button_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue) { - NSString* value = get_value_from_config(config, name, defaultValue); - - return [[NSMutableDictionary alloc] initWithObjectsAndKeys: - @"C", @"TYPE", - name, @"NAME", - label, @"LABEL", - value, @"VALUE", - nil]; + SettingData* result = [[SettingData alloc] init]; + result.type = ButtonSetting; + result.label = label; + result.name = name; + result.value = get_value_from_config(config, name, defaultValue); + return result; } -static NSMutableDictionary* enumeration_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue, NSArray* values) +static SettingData* group_setting(NSString* label, NSArray* settings) { - NSString* value = get_value_from_config(config, name, defaultValue); - - return [[NSMutableDictionary alloc] initWithObjectsAndKeys: - @"E", @"TYPE", - name, @"NAME", - label, @"LABEL", - value, @"VALUE", - values, @"VALUES", - nil]; + SettingData* result = [[SettingData alloc] init]; + result.type = GroupSetting; + result.label = label; + result.subValues = settings; + return result; } -static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue, NSString* path, NSString* extension) +static SettingData* enumeration_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue, NSArray* values) +{ + SettingData* result = [[SettingData alloc] init]; + result.type = EnumerationSetting; + result.label = label; + result.name = name; + result.value = get_value_from_config(config, name, defaultValue); + result.subValues = values; + return result; +} + +static SettingData* subpath_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue, NSString* path, NSString* extension) { NSString* value = get_value_from_config(config, name, defaultValue); value = [value stringByReplacingOccurrencesOfString:path withString:@""]; @@ -75,34 +80,25 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam NSArray* values = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:path error:nil]; values = [values pathsMatchingExtensions:[NSArray arrayWithObject:extension]]; - return [[NSMutableDictionary alloc] initWithObjectsAndKeys: - @"F", @"TYPE", - name, @"NAME", - label, @"LABEL", - value, @"VALUE", - values, @"VALUES", - path, @"PATH", - nil]; + SettingData* result = [[SettingData alloc] init]; + result.type = FileListSetting; + result.label = label; + result.name = name; + result.value = value; + result.subValues = values; + result.path = path; + return result; } - -@implementation settings_list -{ - NSArray* settings; - config_file_t* config; -}; - +@implementation SettingsList - (id)init { - self = [super initWithStyle:UITableViewStyleGrouped]; - - config = config_file_new([[RetroArch_iOS get].config_file_path UTF8String]); - if (!config) config = config_file_new(0); + config_file_t* config = config_file_new([[RetroArch_iOS get].config_file_path UTF8String]); NSString* overlay_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/overlays/"]; NSString* shader_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/shaders/"]; - settings = [NSArray arrayWithObjects: + NSArray* settings = [NSArray arrayWithObjects: [NSArray arrayWithObjects:@"Video", boolean_setting(config, @"video_smooth", @"Smooth Video", @"true"), boolean_setting(config, @"video_crop_overscan", @"Crop Overscan", @"false"), @@ -117,45 +113,46 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam [NSArray arrayWithObjects:@"Input", subpath_setting(config, @"input_overlay", @"Input Overlay", @"", overlay_path, @"cfg"), + group_setting(@"Player 1 Keys", [NSArray arrayWithObjects: + [NSArray arrayWithObjects:@"Player 1", + button_setting(config, @"input_player1_up", @"Up", @"up"), + button_setting(config, @"input_player1_down", @"Down", @"down"), + button_setting(config, @"input_player1_left", @"Left", @"left"), + button_setting(config, @"input_player1_right", @"Right", @"right"), + + button_setting(config, @"input_player1_start", @"Start", @"enter"), + button_setting(config, @"input_player1_select", @"Select", @"rshift"), + + button_setting(config, @"input_player1_b", @"B", @"z"), + button_setting(config, @"input_player1_a", @"A", @"x"), + button_setting(config, @"input_player1_x", @"X", @"s"), + button_setting(config, @"input_player1_y", @"Y", @"a"), + + button_setting(config, @"input_player1_l", @"L", @"q"), + button_setting(config, @"input_player1_r", @"R", @"w"), + button_setting(config, @"input_player1_l2", @"L2", @""), + button_setting(config, @"input_player1_r2", @"R2", @""), + button_setting(config, @"input_player1_l3", @"L3", @""), + button_setting(config, @"input_player1_r3", @"R3", @""), + nil], + nil]), + group_setting(@"System Keys", [NSArray arrayWithObjects: + [NSArray arrayWithObjects:@"System Keys", + button_setting(config, @"input_save_state", @"Save State", @"f2"), + button_setting(config, @"input_load_state", @"Load State", @"f4"), + button_setting(config, @"input_state_slot_increase", @"Next State Slot", @"f7"), + button_setting(config, @"input_state_slot_decrease", @"Previous State Slot", @"f6"), + button_setting(config, @"input_toggle_fast_forward", @"Toggle Fast Forward", @"space"), + button_setting(config, @"input_hold_fast_forward", @"Hold Fast Forward", @"l"), + button_setting(config, @"input_rewind", @"Rewind", @"r"), + button_setting(config, @"input_slowmotion", @"Slow Motion", @"e"), + button_setting(config, @"input_reset", @"Reset", @"h"), + button_setting(config, @"input_exit_emulator", @"Close Game", @"escape"), + nil], + nil]), nil], - [NSArray arrayWithObjects:@"Player 1", - button_setting(config, @"input_player1_up", @"Up", @"up"), - button_setting(config, @"input_player1_down", @"Down", @"down"), - button_setting(config, @"input_player1_left", @"Left", @"left"), - button_setting(config, @"input_player1_right", @"Right", @"right"), - - button_setting(config, @"input_player1_start", @"Start", @"enter"), - button_setting(config, @"input_player1_select", @"Select", @"rshift"), - - button_setting(config, @"input_player1_b", @"B", @"z"), - button_setting(config, @"input_player1_a", @"A", @"x"), - button_setting(config, @"input_player1_x", @"X", @"s"), - button_setting(config, @"input_player1_y", @"Y", @"a"), - - button_setting(config, @"input_player1_l", @"L", @"q"), - button_setting(config, @"input_player1_r", @"R", @"w"), - button_setting(config, @"input_player1_l2", @"L2", @""), - button_setting(config, @"input_player1_r2", @"R2", @""), - button_setting(config, @"input_player1_l3", @"L3", @""), - button_setting(config, @"input_player1_r3", @"R3", @""), - nil], - - [NSArray arrayWithObjects:@"System Keys", - button_setting(config, @"input_save_state", @"Save State", @"f2"), - button_setting(config, @"input_load_state", @"Load State", @"f4"), - button_setting(config, @"input_state_slot_increase", @"Next State Slot", @"f7"), - button_setting(config, @"input_state_slot_decrease", @"Previous State Slot", @"f6"), - button_setting(config, @"input_toggle_fast_forward", @"Toggle Fast Forward", @"space"), - button_setting(config, @"input_hold_fast_forward", @"Hold Fast Forward", @"l"), - button_setting(config, @"input_rewind", @"Rewind", @"r"), - button_setting(config, @"input_slowmotion", @"Slow Motion", @"e"), - button_setting(config, @"input_pause_toogle", @"Pause", @"p"), - button_setting(config, @"input_frame_advance", @"Advance Frame", @"k"), - button_setting(config, @"input_reset", @"Reset", @"h"), - button_setting(config, @"input_exit_emulator", @"Close Game", @"escape"), - nil], - + [NSArray arrayWithObjects:@"Save States", boolean_setting(config, @"rewind_enable", @"Enable Rewinding", @"false"), boolean_setting(config, @"block_sram_overwrite", @"Disable SRAM on Load", @"false"), @@ -164,125 +161,35 @@ static NSMutableDictionary* subpath_setting(config_file_t* config, NSString* nam nil], nil ]; - - [self setTitle:@"RetroArch Settings"]; + + if (config) + config_file_free(config); + + self = [super initWithSettings:settings title:@"RetroArch Settings"]; return self; } - (void)dealloc { - [self write_to_file]; + [self writeToDisk]; } -+ (void)refresh_config_file ++ (void)refreshConfigFile { - [[[settings_list alloc] init] write_to_file]; + [[[SettingsList alloc] init] writeToDisk]; } -- (void)write_to_file +- (void)writeToDisk { + config_file_t* config = config_file_new([[RetroArch_iOS get].config_file_path UTF8String]); + config = config ? config : config_file_new(0); + config_set_string(config, "system_directory", [[RetroArch_iOS get].system_directory UTF8String]); - for (int i = 0; i != [settings count]; i ++) - { - NSArray* group = [settings objectAtIndex:i]; - - for (int j = 1; j < [group count]; j ++) - { - NSMutableDictionary* setting = [group objectAtIndex:j]; - - NSString* name = [setting objectForKey:@"NAME"]; - NSString* value = [setting objectForKey:@"VALUE"]; - - if ([[setting objectForKey:@"TYPE"] isEqualToString:@"F"] && [value length] > 0) - value = [[setting objectForKey:@"PATH"] stringByAppendingPathComponent:value]; - - config_set_string(config, [name UTF8String], [value UTF8String]); - } - } + [self writeSettings:nil toConfig:config]; config_file_write(config, [[RetroArch_iOS get].config_file_path UTF8String]); -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath -{ - NSMutableDictionary* setting = [[settings objectAtIndex:indexPath.section] objectAtIndex:indexPath.row + 1]; - NSString* type = [setting valueForKey:@"TYPE"]; - - if ([type isEqualToString:@"E"] || [type isEqualToString:@"F"]) - { - [[RetroArch_iOS get].navigator - pushViewController:[[enumeration_list alloc] initWithSetting:setting fromTable:(UITableView*)self.view] - animated:YES]; - } - else if([type isEqualToString:@"C"]) - { - (void)[[button_getter alloc] initWithSetting:setting fromTable:(UITableView*)self.view]; - } -} - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView -{ - return [settings count]; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -{ - return [[settings objectAtIndex:section] count] -1; -} - -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section -{ - return [[settings objectAtIndex:section] objectAtIndex:0]; -} - -- (void)handle_boolean_switch:(UISwitch*)swt -{ - NSDictionary* setting = objc_getAssociatedObject(swt, SETTINGID); - [setting setValue: (swt.on ? @"true" : @"false") forKey:@"VALUE"]; -} - -- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath -{ - NSMutableDictionary* setting = [[settings objectAtIndex:indexPath.section] objectAtIndex:indexPath.row + 1]; - UITableViewCell* cell = nil; - - NSString* type = [setting valueForKey:@"TYPE"]; - - if ([type isEqualToString:@"B"]) - { - cell = [self.tableView dequeueReusableCellWithIdentifier:@"boolean"]; - - if (cell == nil) - { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"boolean"]; - - UISwitch* accessory = [[UISwitch alloc] init]; - [accessory addTarget:self action:@selector(handle_boolean_switch:) forControlEvents:UIControlEventValueChanged]; - - cell.accessoryView = accessory; - [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; - } - - UISwitch* swt = (UISwitch*)cell.accessoryView; - swt.on = [[setting valueForKey:@"VALUE"] isEqualToString:@"true"]; - - objc_setAssociatedObject(swt, SETTINGID, setting, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - } - else if ([type isEqualToString:@"E"] || [type isEqualToString:@"F"] || [type isEqualToString:@"C"]) - { - cell = [self.tableView dequeueReusableCellWithIdentifier:@"enumeration"]; - - if (cell == nil) - { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"enumeration"]; - } - } - - cell.textLabel.text = [setting valueForKey:@"LABEL"]; - cell.detailTextLabel.text = [setting valueForKey:@"VALUE"]; - - return cell; + config_file_free(config); } @end diff --git a/ios/RetroArch/settings/settings_sublist.m b/ios/RetroArch/settings/settings_sublist.m new file mode 100644 index 0000000000..b2f836bc90 --- /dev/null +++ b/ios/RetroArch/settings/settings_sublist.m @@ -0,0 +1,173 @@ +// +// settings_list.m +// RetroArch +// +// Created by Jason Fetters on 2/8/13. +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +#import +#import "settings.h" + +static const char* const SETTINGID = "SETTING"; + +@implementation SettingsSubList +{ + NSArray* settings; +}; + +- (id)initWithSettings:(NSArray*)values title:(NSString*)title +{ + self = [super initWithStyle:UITableViewStyleGrouped]; + settings = values; + + [self setTitle:title]; + return self; +} + +- (void)writeSettings:(NSArray*)settingList toConfig:(config_file_t *)config +{ + NSArray* list = settingList ? settingList : settings; + + for (int i = 0; i != [list count]; i ++) + { + NSArray* group = [list objectAtIndex:i]; + + for (int j = 1; j < [group count]; j ++) + { + SettingData* setting = [group objectAtIndex:j]; + + switch (setting.type) + { + case GroupSetting: + [self writeSettings:setting.subValues toConfig:config]; + break; + + case FileListSetting: + if ([setting.value length] > 0) + config_set_string(config, [setting.name UTF8String], [[setting.path stringByAppendingPathComponent:setting.value] UTF8String]); + else + config_set_string(config, [setting.name UTF8String], ""); + break; + + default: + config_set_string(config, [setting.name UTF8String], [setting.value UTF8String]); + break; + } + } + } +} + +- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + SettingData* setting = [[settings objectAtIndex:indexPath.section] objectAtIndex:indexPath.row + 1]; + + switch (setting.type) + { + case EnumerationSetting: + case FileListSetting: + [[RetroArch_iOS get].navigator + pushViewController:[[SettingEnumerationList alloc] initWithSetting:setting fromTable:(UITableView*)self.view] + animated:YES]; + break; + + case ButtonSetting: + (void)[[ButtonGetter alloc] initWithSetting:setting fromTable:(UITableView*)self.view]; + break; + + case GroupSetting: + [[RetroArch_iOS get].navigator + pushViewController:[[SettingsSubList alloc] initWithSettings:setting.subValues title:setting.label] + animated:YES]; + break; + + default: + break; + } +} + +- (void)handle_boolean_switch:(UISwitch*)swt +{ + SettingData* setting = objc_getAssociatedObject(swt, SETTINGID); + setting.value = (swt.on ? @"true" : @"false"); +} + +- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + SettingData* setting = [[settings objectAtIndex:indexPath.section] objectAtIndex:indexPath.row + 1]; + + UITableViewCell* cell = nil; + + switch (setting.type) + { + case BooleanSetting: + { + cell = [self.tableView dequeueReusableCellWithIdentifier:@"boolean"]; + + if (cell == nil) + { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"boolean"]; + + UISwitch* accessory = [[UISwitch alloc] init]; + [accessory addTarget:self action:@selector(handle_boolean_switch:) forControlEvents:UIControlEventValueChanged]; + cell.accessoryView = accessory; + + [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; + } + + UISwitch* swt = (UISwitch*)cell.accessoryView; + swt.on = [setting.value isEqualToString:@"true"]; + objc_setAssociatedObject(swt, SETTINGID, setting, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + break; + + case EnumerationSetting: + case FileListSetting: + case ButtonSetting: + { + cell = [self.tableView dequeueReusableCellWithIdentifier:@"enumeration"]; + + if (cell == nil) + { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"enumeration"]; + } + } + break; + + case GroupSetting: + { + cell = [self.tableView dequeueReusableCellWithIdentifier:@"group"]; + + if (cell == nil) + { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"group"]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + } + } + break; + } + + cell.textLabel.text = setting.label; + cell.detailTextLabel.text = setting.value; + + return cell; +} + +// UITableView item counts +- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView +{ + return [settings count]; +} + +- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section +{ + return [[settings objectAtIndex:section] count] -1; +} + +- (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section +{ + return [[settings objectAtIndex:section] objectAtIndex:0]; +} + + +@end diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index bd3a138bfd..aee66d63f8 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -1,6 +1,8 @@ #import #import +#include "conf/config_file.h" + @interface game_view : UIViewController - (id)initWithGame:(NSString*)path; @end @@ -13,6 +15,12 @@ - (id)initWithPath:(NSString*)path; @end -@interface settings_list : UITableViewController -+ (void)refresh_config_file; -@end \ No newline at end of file + +@interface SettingsSubList : UITableViewController +- (id)initWithSettings:(NSArray*)values title:(NSString*)title; +- (void)writeSettings:(NSArray*)settingList toConfig:(config_file_t*)config; +@end + +@interface SettingsList : SettingsSubList ++ (void)refreshConfigFile; +@end From 1fbe66cad0b6947c5b62dea2f9aae6d653d8bb59 Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 13 Feb 2013 16:26:12 -0500 Subject: [PATCH 050/108] ios: Lifecycle fixes: Fix crash when pressing home button. Add a hack to allow exiting the running game by triple-tapping on the top center of the screen. (Less than 10% from the top, and within the middle 20%) --- ios/RetroArch/RetroArch_iOS.m | 58 +++++++++++++++++++++++++++++------ ios/RetroArch/game_view.m | 32 +++++++++++++++++-- ios/RetroArch/views.h | 5 ++- 3 files changed, 82 insertions(+), 13 deletions(-) diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 8103fed59a..cdbd5b2159 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -21,6 +21,9 @@ extern bool ios_keys[256]; extern uint32_t ios_current_touch_count; @implementation RetroArch_iOS +{ + game_view* game; +} + (RetroArch_iOS*)get { @@ -29,12 +32,15 @@ extern uint32_t ios_current_touch_count; - (void)runGame:(NSString*)path { - self.window.rootViewController = [[game_view alloc] initWithGame:path]; + game = [[game_view alloc] initWithGame:path]; + self.window.rootViewController = game; self.navigator = nil; } - (void)gameHasExited { + game = nil; + self.navigator = [[UINavigationController alloc] init]; [self.navigator pushViewController: [[module_list alloc] init] animated:YES]; @@ -74,6 +80,22 @@ extern uint32_t ios_current_touch_count; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyReleased:) name: GSEventKeyUpNotification object: nil]; } +- (void)applicationWillEnterForeground:(UIApplication *)application +{ + if (game) + { + [game resume]; + } +} + +- (void)applicationDidEnterBackground:(UIApplication *)application +{ + if (game) + { + [game pause]; + } +} + -(void) keyPressed: (NSNotification*) notification { int keycode = [[notification.userInfo objectForKey:@"keycode"] intValue]; @@ -93,18 +115,34 @@ extern uint32_t ios_current_touch_count; - (void)processTouches:(NSArray*)touches { - ios_current_touch_count = [touches count]; - - for(int i = 0; i != [touches count]; i ++) + if (game) { - UITouch *touch = [touches objectAtIndex:i]; - CGPoint coord = [touch locationInView:self.window.rootViewController.view]; - float scale = [[UIScreen mainScreen] scale]; + ios_current_touch_count = [touches count]; + + for(int i = 0; i != [touches count]; i ++) + { + UITouch *touch = [touches objectAtIndex:i]; + CGPoint coord = [touch locationInView:game.view]; + float scale = [[UIScreen mainScreen] scale]; - ios_touches[i].is_down = (touch.phase != UITouchPhaseEnded) && (touch.phase != UITouchPhaseCancelled); + // Exit hack! + if (touch.tapCount == 3) + { + if (coord.y < game.view.bounds.size.height / 10.0f) + { + float tenpct = game.view.bounds.size.width / 10.0f; + if (coord.x >= tenpct * 4 && coord.x <= tenpct * 6) + { + [game exit]; + } + } + } - ios_touches[i].screen_x = coord.x * scale; - ios_touches[i].screen_y = coord.y * scale; + ios_touches[i].is_down = (touch.phase != UITouchPhaseEnded) && (touch.phase != UITouchPhaseCancelled); + + ios_touches[i].screen_x = coord.x * scale; + ios_touches[i].screen_y = coord.y * scale; + } } } diff --git a/ios/RetroArch/game_view.m b/ios/RetroArch/game_view.m index c97d993461..5bb8cf986a 100644 --- a/ios/RetroArch/game_view.m +++ b/ios/RetroArch/game_view.m @@ -21,10 +21,24 @@ static float screen_scale; static int frame_skips = 4; static bool is_syncing = true; +static bool active_iterate() +{ + while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource); + return rarch_main_iterate(); +} + +static bool idle_iterate() +{ + CFRunLoopRunInMode(kCFRunLoopDefaultMode, .5, false); + return true; +} + @implementation game_view { EAGLContext *gl_context; NSString* game; + bool paused; + bool exiting; } - (id)initWithGame:(NSString*)path @@ -36,6 +50,21 @@ static bool is_syncing = true; return self; } +- (void)pause +{ + paused = true; +} + +- (void)resume +{ + paused = false; +} + +- (void)exit +{ + exiting = true; +} + - (void)dealloc { if ([EAGLContext currentContext] == gl_context) [EAGLContext setCurrentContext:nil]; @@ -67,8 +96,7 @@ static bool is_syncing = true; if (rarch_main_init_wrap(&main_wrapper) == 0) { rarch_init_msg_queue(); - while (rarch_main_iterate()) - while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource); + while (!exiting && (paused ? idle_iterate() : active_iterate())); rarch_main_deinit(); rarch_deinit_msg_queue(); diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index aee66d63f8..c9132a2a31 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -4,7 +4,10 @@ #include "conf/config_file.h" @interface game_view : UIViewController -- (id)initWithGame:(NSString*)path; +- (id)initWithGame:(NSString*)path;\ +- (void)pause; +- (void)resume; +- (void)exit; @end @interface module_list : UITableViewController From a4dd4e446318a791c0ce59c7a654ed4111a55610 Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 13 Feb 2013 17:50:21 -0500 Subject: [PATCH 051/108] ios: Some view management cleanup --- ios/RetroArch/RetroArch_iOS.h | 11 +++--- ios/RetroArch/RetroArch_iOS.m | 41 +++++++++++++++++------ ios/RetroArch/directory_list.m | 4 +-- ios/RetroArch/module_list.m | 2 +- ios/RetroArch/settings/enumeration_list.m | 2 +- ios/RetroArch/settings/settings_sublist.m | 8 ++--- 6 files changed, 41 insertions(+), 27 deletions(-) diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index ced57264bf..a185024c3d 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -7,8 +7,8 @@ #import -extern NSString *const GSEventKeyDownNotification; -extern NSString *const GSEventKeyUpNotification; +extern NSString* const GSEventKeyDownNotification; +extern NSString* const GSEventKeyUpNotification; @interface RetroArch_iOS : UIResponder @@ -16,12 +16,13 @@ extern NSString *const GSEventKeyUpNotification; - (void)runGame:(NSString*)path; - (void)gameHasExited; +- (void)pushViewController:(UIViewController*)theView; +- (void)popViewController; + @property (strong, nonatomic) NSString* system_directory; @property (strong, nonatomic) NSString* config_file_path; -@property (strong, nonatomic) UIWindow *window; -@property (strong, nonatomic) NSString *module_path; -@property (strong, nonatomic) UINavigationController *navigator; +@property (strong, nonatomic) NSString* module_path; @property (strong, nonatomic) UIImage* file_icon; @property (strong, nonatomic) UIImage* folder_icon; @property (strong, nonatomic) UIBarButtonItem* settings_button; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index cdbd5b2159..d591ce0f82 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -23,6 +23,9 @@ extern uint32_t ios_current_touch_count; @implementation RetroArch_iOS { game_view* game; + + UIWindow* window; + UINavigationController* navigator; } + (RetroArch_iOS*)get @@ -33,18 +36,34 @@ extern uint32_t ios_current_touch_count; - (void)runGame:(NSString*)path { game = [[game_view alloc] initWithGame:path]; - self.window.rootViewController = game; - self.navigator = nil; + window.rootViewController = game; + navigator = nil; } - (void)gameHasExited { game = nil; - self.navigator = [[UINavigationController alloc] init]; - [self.navigator pushViewController: [[module_list alloc] init] animated:YES]; + navigator = [[UINavigationController alloc] init]; + [navigator pushViewController: [[module_list alloc] init] animated:YES]; - self.window.rootViewController = self.navigator; + window.rootViewController = navigator; +} + +- (void)pushViewController:(UIViewController*)theView +{ + if (navigator != nil) + { + [navigator pushViewController:theView animated:YES]; + } +} + +- (void)popViewController +{ + if (navigator != nil) + { + [navigator popViewControllerAnimated:YES]; + } } - (void)applicationDidFinishLaunching:(UIApplication *)application @@ -68,12 +87,12 @@ extern uint32_t ios_current_touch_count; self.settings_button.action = @selector(show_settings); // Setup window - self.navigator = [[UINavigationController alloc] init]; - [self.navigator pushViewController: [[module_list alloc] init] animated:YES]; + navigator = [[UINavigationController alloc] init]; + [navigator pushViewController: [[module_list alloc] init] animated:YES]; - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - self.window.rootViewController = self.navigator; - [self.window makeKeyAndVisible]; + window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + window.rootViewController = navigator; + [window makeKeyAndVisible]; // Setup keyboard hack [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyPressed:) name: GSEventKeyDownNotification object: nil]; @@ -110,7 +129,7 @@ extern uint32_t ios_current_touch_count; - (void)show_settings { - [self.navigator pushViewController: [[SettingsList alloc] init] animated:YES]; + [self pushViewController:[SettingsList new]]; } - (void)processTouches:(NSArray*)touches diff --git a/ios/RetroArch/directory_list.m b/ios/RetroArch/directory_list.m index f1243428ed..be92a5f04d 100644 --- a/ios/RetroArch/directory_list.m +++ b/ios/RetroArch/directory_list.m @@ -57,9 +57,7 @@ static BOOL is_directory(NSString* path) if(is_directory(path)) { - [[RetroArch_iOS get].navigator - pushViewController:[[directory_list alloc] initWithPath:path] - animated:YES]; + [[RetroArch_iOS get] pushViewController:[[directory_list alloc] initWithPath:path]]; } else { diff --git a/ios/RetroArch/module_list.m b/ios/RetroArch/module_list.m index 758ea06222..3a9a27461c 100644 --- a/ios/RetroArch/module_list.m +++ b/ios/RetroArch/module_list.m @@ -52,7 +52,7 @@ static void display_error_alert(NSString* message) - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [RetroArch_iOS get].module_path = [modules objectAtIndex:indexPath.row]; - [[RetroArch_iOS get].navigator pushViewController:[[directory_list alloc] initWithPath:nil] animated:YES]; + [[RetroArch_iOS get] pushViewController:[[directory_list alloc] initWithPath:nil]]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section diff --git a/ios/RetroArch/settings/enumeration_list.m b/ios/RetroArch/settings/enumeration_list.m index 61823d1fc9..9f368f09db 100644 --- a/ios/RetroArch/settings/enumeration_list.m +++ b/ios/RetroArch/settings/enumeration_list.m @@ -55,7 +55,7 @@ value.value = @""; [view reloadData]; - [[RetroArch_iOS get].navigator popViewControllerAnimated:YES]; + [[RetroArch_iOS get] popViewController]; } @end diff --git a/ios/RetroArch/settings/settings_sublist.m b/ios/RetroArch/settings/settings_sublist.m index b2f836bc90..3c3d2b9aa5 100644 --- a/ios/RetroArch/settings/settings_sublist.m +++ b/ios/RetroArch/settings/settings_sublist.m @@ -66,9 +66,7 @@ static const char* const SETTINGID = "SETTING"; { case EnumerationSetting: case FileListSetting: - [[RetroArch_iOS get].navigator - pushViewController:[[SettingEnumerationList alloc] initWithSetting:setting fromTable:(UITableView*)self.view] - animated:YES]; + [[RetroArch_iOS get] pushViewController:[[SettingEnumerationList alloc] initWithSetting:setting fromTable:(UITableView*)self.view]]; break; case ButtonSetting: @@ -76,9 +74,7 @@ static const char* const SETTINGID = "SETTING"; break; case GroupSetting: - [[RetroArch_iOS get].navigator - pushViewController:[[SettingsSubList alloc] initWithSettings:setting.subValues title:setting.label] - animated:YES]; + [[RetroArch_iOS get] pushViewController:[[SettingsSubList alloc] initWithSettings:setting.subValues title:setting.label]]; break; default: From 566f8ace456013a75e2b085f342c42ecbbe5bec5 Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 13 Feb 2013 18:18:55 -0500 Subject: [PATCH 052/108] ios: When in Rome. --- ios/RetroArch.xcodeproj/project.pbxproj | 56 ++++++++--------- .../{directory_list.m => RADirectoryList.m} | 26 ++++---- ios/RetroArch/{game_view.m => RAGameView.m} | 4 +- .../{module_list.m => RAModuleList.m} | 28 ++++----- ios/RetroArch/RetroArch_iOS.m | 62 +++++++++---------- .../{button_getter.m => RAButtonGetter.m} | 8 +-- ...tion_list.m => RASettingEnumerationList.m} | 6 +- .../{settings_list.m => RASettingsList.m} | 26 ++++---- ...settings_sublist.m => RASettingsSubList.m} | 16 ++--- ios/RetroArch/settings/settings.h | 10 +-- ios/RetroArch/views.h | 10 +-- 11 files changed, 123 insertions(+), 129 deletions(-) rename ios/RetroArch/{directory_list.m => RADirectoryList.m} (77%) rename ios/RetroArch/{game_view.m => RAGameView.m} (98%) rename ios/RetroArch/{module_list.m => RAModuleList.m} (63%) rename ios/RetroArch/settings/{button_getter.m => RAButtonGetter.m} (95%) rename ios/RetroArch/settings/{enumeration_list.m => RASettingEnumerationList.m} (90%) rename ios/RetroArch/settings/{settings_list.m => RASettingsList.m} (86%) rename ios/RetroArch/settings/{settings_sublist.m => RASettingsSubList.m} (84%) diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 53f51d1bbc..26ae9501dd 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -10,11 +10,8 @@ 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */; }; 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; }; 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; }; - 96297A0916C59EC000E6DCE0 /* module_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0816C59EC000E6DCE0 /* module_list.m */; }; 96297A0C16C5AD8D00E6DCE0 /* RetroArch_iOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */; }; 96297A0F16C5AEA100E6DCE0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0E16C5AEA100E6DCE0 /* main.m */; }; - 96297A1116C5AEDE00E6DCE0 /* game_view.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A1016C5AEDE00E6DCE0 /* game_view.m */; }; - 96297A1316C5AEFD00E6DCE0 /* directory_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A1216C5AEFD00E6DCE0 /* directory_list.m */; }; 96297A2416C818FF00E6DCE0 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2216C818FF00E6DCE0 /* Icon-72.png */; }; 96297A2516C818FF00E6DCE0 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2316C818FF00E6DCE0 /* Icon.png */; }; 96297A2716C82FF100E6DCE0 /* overlays in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2616C82FF100E6DCE0 /* overlays */; }; @@ -23,10 +20,13 @@ 96366C5316C9A7C100D64A22 /* coreaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEE816C1DC73009DE44C /* coreaudio.c */; }; 96366C5516C9AC3300D64A22 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5416C9AC3300D64A22 /* CoreAudio.framework */; }; 96366C5916C9ACF500D64A22 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */; }; - 96366C7416CAF62200D64A22 /* button_getter.m in Sources */ = {isa = PBXBuildFile; fileRef = 96366C7016CAF62200D64A22 /* button_getter.m */; }; - 96366C7516CAF62200D64A22 /* enumeration_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96366C7116CAF62200D64A22 /* enumeration_list.m */; }; - 96366C7616CAF62200D64A22 /* settings_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96366C7316CAF62200D64A22 /* settings_list.m */; }; - 963F5AB216CC14C4009BBD19 /* settings_sublist.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AB116CC14C4009BBD19 /* settings_sublist.m */; }; + 963F5AC016CC522F009BBD19 /* RAButtonGetter.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5ABC16CC522F009BBD19 /* RAButtonGetter.m */; }; + 963F5AC116CC522F009BBD19 /* RASettingEnumerationList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5ABD16CC522F009BBD19 /* RASettingEnumerationList.m */; }; + 963F5AC216CC522F009BBD19 /* RASettingsSubList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5ABE16CC522F009BBD19 /* RASettingsSubList.m */; }; + 963F5AC316CC522F009BBD19 /* RASettingsList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5ABF16CC522F009BBD19 /* RASettingsList.m */; }; + 963F5AC716CC523B009BBD19 /* RADirectoryList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC416CC523B009BBD19 /* RADirectoryList.m */; }; + 963F5AC816CC523B009BBD19 /* RAGameView.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC516CC523B009BBD19 /* RAGameView.m */; }; + 963F5AC916CC523B009BBD19 /* RAModuleList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC616CC523B009BBD19 /* RAModuleList.m */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -92,24 +92,24 @@ 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioseagl_ctx.c; sourceTree = ""; }; 962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = ""; }; 962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = ""; }; - 96297A0816C59EC000E6DCE0 /* module_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = module_list.m; sourceTree = ""; }; 96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RetroArch_iOS.h; sourceTree = ""; }; 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RetroArch_iOS.m; sourceTree = ""; }; 96297A0D16C5ADDA00E6DCE0 /* views.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = views.h; sourceTree = ""; }; 96297A0E16C5AEA100E6DCE0 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 96297A1016C5AEDE00E6DCE0 /* game_view.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = game_view.m; sourceTree = ""; }; - 96297A1216C5AEFD00E6DCE0 /* directory_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = directory_list.m; sourceTree = ""; }; 96297A2216C818FF00E6DCE0 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "RetroArch/Icon-72.png"; sourceTree = ""; }; 96297A2316C818FF00E6DCE0 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = RetroArch/Icon.png; sourceTree = ""; }; 96297A2616C82FF100E6DCE0 /* overlays */ = {isa = PBXFileReference; lastKnownFileType = folder; name = overlays; path = ../media/overlays; sourceTree = ""; }; 96366C4F16C9A4E100D64A22 /* resampler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resampler.c; sourceTree = ""; }; 96366C5416C9AC3300D64A22 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; - 96366C7016CAF62200D64A22 /* button_getter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = button_getter.m; sourceTree = ""; }; - 96366C7116CAF62200D64A22 /* enumeration_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = enumeration_list.m; sourceTree = ""; }; 96366C7216CAF62200D64A22 /* settings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = settings.h; sourceTree = ""; }; - 96366C7316CAF62200D64A22 /* settings_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = settings_list.m; sourceTree = ""; }; - 963F5AB116CC14C4009BBD19 /* settings_sublist.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = settings_sublist.m; sourceTree = ""; }; + 963F5ABC16CC522F009BBD19 /* RAButtonGetter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAButtonGetter.m; sourceTree = ""; }; + 963F5ABD16CC522F009BBD19 /* RASettingEnumerationList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RASettingEnumerationList.m; sourceTree = ""; }; + 963F5ABE16CC522F009BBD19 /* RASettingsSubList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RASettingsSubList.m; sourceTree = ""; }; + 963F5ABF16CC522F009BBD19 /* RASettingsList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RASettingsList.m; sourceTree = ""; }; + 963F5AC416CC523B009BBD19 /* RADirectoryList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RADirectoryList.m; sourceTree = ""; }; + 963F5AC516CC523B009BBD19 /* RAGameView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAGameView.m; sourceTree = ""; }; + 963F5AC616CC523B009BBD19 /* RAModuleList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAModuleList.m; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -315,11 +315,11 @@ 96366C6F16CAF62200D64A22 /* settings */ = { isa = PBXGroup; children = ( - 96366C7016CAF62200D64A22 /* button_getter.m */, - 96366C7116CAF62200D64A22 /* enumeration_list.m */, + 963F5ABC16CC522F009BBD19 /* RAButtonGetter.m */, + 963F5ABD16CC522F009BBD19 /* RASettingEnumerationList.m */, + 963F5ABE16CC522F009BBD19 /* RASettingsSubList.m */, + 963F5ABF16CC522F009BBD19 /* RASettingsList.m */, 96366C7216CAF62200D64A22 /* settings.h */, - 96366C7316CAF62200D64A22 /* settings_list.m */, - 963F5AB116CC14C4009BBD19 /* settings_sublist.m */, ); path = settings; sourceTree = ""; @@ -365,9 +365,10 @@ 96AFAE3316C1D4EA009DE44C /* RetroArch */ = { isa = PBXGroup; children = ( + 963F5AC416CC523B009BBD19 /* RADirectoryList.m */, + 963F5AC516CC523B009BBD19 /* RAGameView.m */, + 963F5AC616CC523B009BBD19 /* RAModuleList.m */, 96366C6F16CAF62200D64A22 /* settings */, - 96297A1216C5AEFD00E6DCE0 /* directory_list.m */, - 96297A1016C5AEDE00E6DCE0 /* game_view.m */, 96297A0D16C5ADDA00E6DCE0 /* views.h */, 96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */, 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */, @@ -375,7 +376,6 @@ 96AFAE4F16C1D4EA009DE44C /* ViewController_iPad.xib */, 96AFAE3416C1D4EA009DE44C /* Supporting Files */, 96CF015B16C2F72900ABF9C9 /* ios_input.c */, - 96297A0816C59EC000E6DCE0 /* module_list.m */, ); path = RetroArch; sourceTree = ""; @@ -821,18 +821,18 @@ 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */, 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */, 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */, - 96297A0916C59EC000E6DCE0 /* module_list.m in Sources */, 96297A0C16C5AD8D00E6DCE0 /* RetroArch_iOS.m in Sources */, 96297A0F16C5AEA100E6DCE0 /* main.m in Sources */, - 96297A1116C5AEDE00E6DCE0 /* game_view.m in Sources */, - 96297A1316C5AEFD00E6DCE0 /* directory_list.m in Sources */, 96366C5016C9A4E100D64A22 /* resampler.c in Sources */, 96366C5216C9A4E600D64A22 /* hermite.c in Sources */, 96366C5316C9A7C100D64A22 /* coreaudio.c in Sources */, - 96366C7416CAF62200D64A22 /* button_getter.m in Sources */, - 96366C7516CAF62200D64A22 /* enumeration_list.m in Sources */, - 96366C7616CAF62200D64A22 /* settings_list.m in Sources */, - 963F5AB216CC14C4009BBD19 /* settings_sublist.m in Sources */, + 963F5AC016CC522F009BBD19 /* RAButtonGetter.m in Sources */, + 963F5AC116CC522F009BBD19 /* RASettingEnumerationList.m in Sources */, + 963F5AC216CC522F009BBD19 /* RASettingsSubList.m in Sources */, + 963F5AC316CC522F009BBD19 /* RASettingsList.m in Sources */, + 963F5AC716CC523B009BBD19 /* RADirectoryList.m in Sources */, + 963F5AC816CC523B009BBD19 /* RAGameView.m in Sources */, + 963F5AC916CC523B009BBD19 /* RAModuleList.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/directory_list.m b/ios/RetroArch/RADirectoryList.m similarity index 77% rename from ios/RetroArch/directory_list.m rename to ios/RetroArch/RADirectoryList.m index be92a5f04d..6f59db41a5 100644 --- a/ios/RetroArch/directory_list.m +++ b/ios/RetroArch/RADirectoryList.m @@ -13,11 +13,11 @@ static BOOL is_directory(NSString* path) return result; } -@implementation directory_list +@implementation RADirectoryList { - NSString* directory; - NSArray* list; -}; + NSString* _path; + NSArray* _list; +} - (id)initWithPath:(NSString*)path { @@ -30,12 +30,12 @@ static BOOL is_directory(NSString* path) else path = @"/"; } - directory = path; + _path = path; - list = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directory error:nil]; - list = [directory stringsByAppendingPaths:list]; + _list = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:_path error:nil]; + _list = [_path stringsByAppendingPaths:_list]; - list = [list sortedArrayUsingComparator:^(id left, id right) + _list = [_list sortedArrayUsingComparator:^(id left, id right) { const BOOL left_is_dir = is_directory((NSString*)left); const BOOL right_is_dir = is_directory((NSString*)right); @@ -46,18 +46,18 @@ static BOOL is_directory(NSString* path) }]; self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; - [self setTitle: [directory lastPathComponent]]; + [self setTitle: [_path lastPathComponent]]; return self; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - NSString* path = [list objectAtIndex: indexPath.row]; + NSString* path = [_list objectAtIndex: indexPath.row]; if(is_directory(path)) { - [[RetroArch_iOS get] pushViewController:[[directory_list alloc] initWithPath:path]]; + [[RetroArch_iOS get] pushViewController:[[RADirectoryList alloc] initWithPath:path]]; } else { @@ -67,12 +67,12 @@ static BOOL is_directory(NSString* path) - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return [list count]; + return [_list count]; } - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - NSString* path = [list objectAtIndex: indexPath.row]; + NSString* path = [_list objectAtIndex: indexPath.row]; BOOL isdir = is_directory(path); UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"path"]; diff --git a/ios/RetroArch/game_view.m b/ios/RetroArch/RAGameView.m similarity index 98% rename from ios/RetroArch/game_view.m rename to ios/RetroArch/RAGameView.m index 5bb8cf986a..65044267b5 100644 --- a/ios/RetroArch/game_view.m +++ b/ios/RetroArch/RAGameView.m @@ -33,7 +33,7 @@ static bool idle_iterate() return true; } -@implementation game_view +@implementation RAGameView { EAGLContext *gl_context; NSString* game; @@ -86,7 +86,7 @@ static bool idle_iterate() - (void)runGame { - [SettingsList refreshConfigFile]; + [RASettingsList refreshConfigFile]; const char* const sd = [[RetroArch_iOS get].system_directory UTF8String]; const char* const cf =[[RetroArch_iOS get].config_file_path UTF8String]; diff --git a/ios/RetroArch/module_list.m b/ios/RetroArch/RAModuleList.m similarity index 63% rename from ios/RetroArch/module_list.m rename to ios/RetroArch/RAModuleList.m index 3a9a27461c..c1e4c07d13 100644 --- a/ios/RetroArch/module_list.m +++ b/ios/RetroArch/RAModuleList.m @@ -16,29 +16,27 @@ static void display_error_alert(NSString* message) [alert show]; } -@implementation module_list +@implementation RAModuleList { - NSArray* modules; -}; + NSArray* _modules; +} - (id)init { self = [super initWithStyle:UITableViewStylePlain]; // Get the contents of the modules directory of the bundle. - NSString* module_dir = [NSString stringWithFormat:@"%@/%@", - [[NSBundle mainBundle] bundlePath], - @"modules"]; + NSString* module_dir = [NSString stringWithFormat:@"%@/modules", [[NSBundle mainBundle] bundlePath]]; - modules = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:module_dir error:nil]; + _modules = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:module_dir error:nil]; - if (modules != nil) + if (_modules != nil) { - modules = [module_dir stringsByAppendingPaths:modules]; - modules = [modules pathsMatchingExtensions:[NSArray arrayWithObject:@"dylib"]]; + _modules = [module_dir stringsByAppendingPaths:_modules]; + _modules = [_modules pathsMatchingExtensions:[NSArray arrayWithObject:@"dylib"]]; } - if (modules == nil || [modules count] == 0) + if (_modules == nil || [_modules count] == 0) { display_error_alert(@"No libretro cores were found."); } @@ -51,13 +49,13 @@ static void display_error_alert(NSString* message) - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - [RetroArch_iOS get].module_path = [modules objectAtIndex:indexPath.row]; - [[RetroArch_iOS get] pushViewController:[[directory_list alloc] initWithPath:nil]]; + [RetroArch_iOS get].module_path = [_modules objectAtIndex:indexPath.row]; + [[RetroArch_iOS get] pushViewController:[[RADirectoryList alloc] initWithPath:nil]]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return modules ? [modules count] : 0; + return _modules ? [_modules count] : 0; } - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath @@ -65,7 +63,7 @@ static void display_error_alert(NSString* message) UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"module"]; cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"module"]; - cell.textLabel.text = [[[modules objectAtIndex:indexPath.row] lastPathComponent] stringByDeletingPathExtension]; + cell.textLabel.text = [[[_modules objectAtIndex:indexPath.row] lastPathComponent] stringByDeletingPathExtension]; return cell; } diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index d591ce0f82..9306dba10f 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -22,10 +22,10 @@ extern uint32_t ios_current_touch_count; @implementation RetroArch_iOS { - game_view* game; + RAGameView* _game; - UIWindow* window; - UINavigationController* navigator; + UIWindow* _window; + UINavigationController* _navigator; } + (RetroArch_iOS*)get @@ -35,34 +35,34 @@ extern uint32_t ios_current_touch_count; - (void)runGame:(NSString*)path { - game = [[game_view alloc] initWithGame:path]; - window.rootViewController = game; - navigator = nil; + _game = [[RAGameView alloc] initWithGame:path]; + _window.rootViewController = _game; + _navigator = nil; } - (void)gameHasExited { - game = nil; + _game = nil; - navigator = [[UINavigationController alloc] init]; - [navigator pushViewController: [[module_list alloc] init] animated:YES]; + _navigator = [[UINavigationController alloc] init]; + [_navigator pushViewController: [[RAModuleList alloc] init] animated:YES]; - window.rootViewController = navigator; + _window.rootViewController = _navigator; } - (void)pushViewController:(UIViewController*)theView { - if (navigator != nil) + if (_navigator != nil) { - [navigator pushViewController:theView animated:YES]; + [_navigator pushViewController:theView animated:YES]; } } - (void)popViewController { - if (navigator != nil) + if (_navigator != nil) { - [navigator popViewControllerAnimated:YES]; + [_navigator popViewControllerAnimated:YES]; } } @@ -87,12 +87,12 @@ extern uint32_t ios_current_touch_count; self.settings_button.action = @selector(show_settings); // Setup window - navigator = [[UINavigationController alloc] init]; - [navigator pushViewController: [[module_list alloc] init] animated:YES]; + _navigator = [[UINavigationController alloc] init]; + [_navigator pushViewController: [[RAModuleList alloc] init] animated:YES]; - window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - window.rootViewController = navigator; - [window makeKeyAndVisible]; + _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + _window.rootViewController = _navigator; + [_window makeKeyAndVisible]; // Setup keyboard hack [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyPressed:) name: GSEventKeyDownNotification object: nil]; @@ -101,18 +101,14 @@ extern uint32_t ios_current_touch_count; - (void)applicationWillEnterForeground:(UIApplication *)application { - if (game) - { - [game resume]; - } + if (_game) + [_game resume]; } - (void)applicationDidEnterBackground:(UIApplication *)application { - if (game) - { - [game pause]; - } + if (_game) + [_game pause]; } -(void) keyPressed: (NSNotification*) notification @@ -129,30 +125,30 @@ extern uint32_t ios_current_touch_count; - (void)show_settings { - [self pushViewController:[SettingsList new]]; + [self pushViewController:[RASettingsList new]]; } - (void)processTouches:(NSArray*)touches { - if (game) + if (_game) { ios_current_touch_count = [touches count]; for(int i = 0; i != [touches count]; i ++) { UITouch *touch = [touches objectAtIndex:i]; - CGPoint coord = [touch locationInView:game.view]; + CGPoint coord = [touch locationInView:_game.view]; float scale = [[UIScreen mainScreen] scale]; // Exit hack! if (touch.tapCount == 3) { - if (coord.y < game.view.bounds.size.height / 10.0f) + if (coord.y < _game.view.bounds.size.height / 10.0f) { - float tenpct = game.view.bounds.size.width / 10.0f; + float tenpct = _game.view.bounds.size.width / 10.0f; if (coord.x >= tenpct * 4 && coord.x <= tenpct * 6) { - [game exit]; + [_game exit]; } } } diff --git a/ios/RetroArch/settings/button_getter.m b/ios/RetroArch/settings/RAButtonGetter.m similarity index 95% rename from ios/RetroArch/settings/button_getter.m rename to ios/RetroArch/settings/RAButtonGetter.m index a96f6c2fef..5d174f2701 100644 --- a/ios/RetroArch/settings/button_getter.m +++ b/ios/RetroArch/settings/RAButtonGetter.m @@ -78,15 +78,15 @@ static NSString* get_key_config_name(uint32_t hid_id) return @"nul"; } -@implementation ButtonGetter +@implementation RAButtonGetter { - ButtonGetter* me; - SettingData* value; + RAButtonGetter* me; + RASettingData* value; UIAlertView* alert; UITableView* view; } -- (id)initWithSetting:(SettingData*)setting fromTable:(UITableView*)table +- (id)initWithSetting:(RASettingData*)setting fromTable:(UITableView*)table { self = [super init]; diff --git a/ios/RetroArch/settings/enumeration_list.m b/ios/RetroArch/settings/RASettingEnumerationList.m similarity index 90% rename from ios/RetroArch/settings/enumeration_list.m rename to ios/RetroArch/settings/RASettingEnumerationList.m index 9f368f09db..07fa33e2d3 100644 --- a/ios/RetroArch/settings/enumeration_list.m +++ b/ios/RetroArch/settings/RASettingEnumerationList.m @@ -8,13 +8,13 @@ #import "settings.h" -@implementation SettingEnumerationList +@implementation RASettingEnumerationList { - SettingData* value; + RASettingData* value; UITableView* view; }; -- (id)initWithSetting:(SettingData*)setting fromTable:(UITableView*)table +- (id)initWithSetting:(RASettingData*)setting fromTable:(UITableView*)table { self = [super initWithStyle:UITableViewStyleGrouped]; diff --git a/ios/RetroArch/settings/settings_list.m b/ios/RetroArch/settings/RASettingsList.m similarity index 86% rename from ios/RetroArch/settings/settings_list.m rename to ios/RetroArch/settings/RASettingsList.m index bab96d5694..6fe1034bc0 100644 --- a/ios/RetroArch/settings/settings_list.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -10,7 +10,7 @@ #import "settings.h" #include "config_file.h" -@implementation SettingData +@implementation RASettingData @end @@ -32,9 +32,9 @@ static NSString* get_value_from_config(config_file_t* config, NSString* name, NS return value; } -static SettingData* boolean_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue) +static RASettingData* boolean_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue) { - SettingData* result = [[SettingData alloc] init]; + RASettingData* result = [[RASettingData alloc] init]; result.type = BooleanSetting; result.label = label; result.name = name; @@ -42,9 +42,9 @@ static SettingData* boolean_setting(config_file_t* config, NSString* name, NSStr return result; } -static SettingData* button_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue) +static RASettingData* button_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue) { - SettingData* result = [[SettingData alloc] init]; + RASettingData* result = [[RASettingData alloc] init]; result.type = ButtonSetting; result.label = label; result.name = name; @@ -52,18 +52,18 @@ static SettingData* button_setting(config_file_t* config, NSString* name, NSStri return result; } -static SettingData* group_setting(NSString* label, NSArray* settings) +static RASettingData* group_setting(NSString* label, NSArray* settings) { - SettingData* result = [[SettingData alloc] init]; + RASettingData* result = [[RASettingData alloc] init]; result.type = GroupSetting; result.label = label; result.subValues = settings; return result; } -static SettingData* enumeration_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue, NSArray* values) +static RASettingData* enumeration_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue, NSArray* values) { - SettingData* result = [[SettingData alloc] init]; + RASettingData* result = [[RASettingData alloc] init]; result.type = EnumerationSetting; result.label = label; result.name = name; @@ -72,7 +72,7 @@ static SettingData* enumeration_setting(config_file_t* config, NSString* name, N return result; } -static SettingData* subpath_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue, NSString* path, NSString* extension) +static RASettingData* subpath_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue, NSString* path, NSString* extension) { NSString* value = get_value_from_config(config, name, defaultValue); value = [value stringByReplacingOccurrencesOfString:path withString:@""]; @@ -80,7 +80,7 @@ static SettingData* subpath_setting(config_file_t* config, NSString* name, NSStr NSArray* values = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:path error:nil]; values = [values pathsMatchingExtensions:[NSArray arrayWithObject:extension]]; - SettingData* result = [[SettingData alloc] init]; + RASettingData* result = [[RASettingData alloc] init]; result.type = FileListSetting; result.label = label; result.name = name; @@ -90,7 +90,7 @@ static SettingData* subpath_setting(config_file_t* config, NSString* name, NSStr return result; } -@implementation SettingsList +@implementation RASettingsList - (id)init { config_file_t* config = config_file_new([[RetroArch_iOS get].config_file_path UTF8String]); @@ -176,7 +176,7 @@ static SettingData* subpath_setting(config_file_t* config, NSString* name, NSStr + (void)refreshConfigFile { - [[[SettingsList alloc] init] writeToDisk]; + [[[RASettingsList alloc] init] writeToDisk]; } - (void)writeToDisk diff --git a/ios/RetroArch/settings/settings_sublist.m b/ios/RetroArch/settings/RASettingsSubList.m similarity index 84% rename from ios/RetroArch/settings/settings_sublist.m rename to ios/RetroArch/settings/RASettingsSubList.m index 3c3d2b9aa5..92c573d7b6 100644 --- a/ios/RetroArch/settings/settings_sublist.m +++ b/ios/RetroArch/settings/RASettingsSubList.m @@ -11,7 +11,7 @@ static const char* const SETTINGID = "SETTING"; -@implementation SettingsSubList +@implementation RASettingsSubList { NSArray* settings; }; @@ -35,7 +35,7 @@ static const char* const SETTINGID = "SETTING"; for (int j = 1; j < [group count]; j ++) { - SettingData* setting = [group objectAtIndex:j]; + RASettingData* setting = [group objectAtIndex:j]; switch (setting.type) { @@ -60,21 +60,21 @@ static const char* const SETTINGID = "SETTING"; - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - SettingData* setting = [[settings objectAtIndex:indexPath.section] objectAtIndex:indexPath.row + 1]; + RASettingData* setting = [[settings objectAtIndex:indexPath.section] objectAtIndex:indexPath.row + 1]; switch (setting.type) { case EnumerationSetting: case FileListSetting: - [[RetroArch_iOS get] pushViewController:[[SettingEnumerationList alloc] initWithSetting:setting fromTable:(UITableView*)self.view]]; + [[RetroArch_iOS get] pushViewController:[[RASettingEnumerationList alloc] initWithSetting:setting fromTable:(UITableView*)self.view]]; break; case ButtonSetting: - (void)[[ButtonGetter alloc] initWithSetting:setting fromTable:(UITableView*)self.view]; + (void)[[RAButtonGetter alloc] initWithSetting:setting fromTable:(UITableView*)self.view]; break; case GroupSetting: - [[RetroArch_iOS get] pushViewController:[[SettingsSubList alloc] initWithSettings:setting.subValues title:setting.label]]; + [[RetroArch_iOS get] pushViewController:[[RASettingsSubList alloc] initWithSettings:setting.subValues title:setting.label]]; break; default: @@ -84,13 +84,13 @@ static const char* const SETTINGID = "SETTING"; - (void)handle_boolean_switch:(UISwitch*)swt { - SettingData* setting = objc_getAssociatedObject(swt, SETTINGID); + RASettingData* setting = objc_getAssociatedObject(swt, SETTINGID); setting.value = (swt.on ? @"true" : @"false"); } - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - SettingData* setting = [[settings objectAtIndex:indexPath.section] objectAtIndex:indexPath.row + 1]; + RASettingData* setting = [[settings objectAtIndex:indexPath.section] objectAtIndex:indexPath.row + 1]; UITableViewCell* cell = nil; diff --git a/ios/RetroArch/settings/settings.h b/ios/RetroArch/settings/settings.h index d57fa970fa..a5dfa4d751 100644 --- a/ios/RetroArch/settings/settings.h +++ b/ios/RetroArch/settings/settings.h @@ -13,7 +13,7 @@ enum SettingTypes BooleanSetting, ButtonSetting, EnumerationSetting, FileListSetting, GroupSetting }; -@interface SettingData : NSObject +@interface RASettingData : NSObject @property enum SettingTypes type; @property (strong) NSString* label; @@ -24,10 +24,10 @@ enum SettingTypes @property (strong) NSArray* subValues; @end -@interface ButtonGetter : NSObject -- (id)initWithSetting:(SettingData*)setting fromTable:(UITableView*)table; +@interface RAButtonGetter : NSObject +- (id)initWithSetting:(RASettingData*)setting fromTable:(UITableView*)table; @end -@interface SettingEnumerationList : UITableViewController -- (id)initWithSetting:(SettingData*)setting fromTable:(UITableView*)table; +@interface RASettingEnumerationList : UITableViewController +- (id)initWithSetting:(RASettingData*)setting fromTable:(UITableView*)table; @end diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index c9132a2a31..59d21b1a60 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -3,27 +3,27 @@ #include "conf/config_file.h" -@interface game_view : UIViewController +@interface RAGameView : UIViewController - (id)initWithGame:(NSString*)path;\ - (void)pause; - (void)resume; - (void)exit; @end -@interface module_list : UITableViewController +@interface RAModuleList : UITableViewController @end -@interface directory_list : UITableViewController +@interface RADirectoryList : UITableViewController - (id)initWithPath:(NSString*)path; @end -@interface SettingsSubList : UITableViewController +@interface RASettingsSubList : UITableViewController - (id)initWithSettings:(NSArray*)values title:(NSString*)title; - (void)writeSettings:(NSArray*)settingList toConfig:(config_file_t*)config; @end -@interface SettingsList : SettingsSubList +@interface RASettingsList : RASettingsSubList + (void)refreshConfigFile; @end From 6a77d72966356b74a9564eb42572548c91b469f8 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 14 Feb 2013 21:35:24 -0500 Subject: [PATCH 053/108] ios: Hopefully fix the crash when suspended for real this time. Make many things worse, but will fix them from the working state. --- gfx/context/ioseagl_ctx.c | 6 +- ios/RetroArch.xcodeproj/project.pbxproj | 6 +- ios/RetroArch/RAGameView.m | 157 ++++++++++++++++-------- ios/RetroArch/RetroArch_iOS.h | 2 + ios/RetroArch/RetroArch_iOS.m | 75 +++++------ ios/RetroArch/main.m | 40 +++--- ios/RetroArch/rarch_wrapper.h | 17 +++ ios/RetroArch/views.h | 4 - 8 files changed, 192 insertions(+), 115 deletions(-) create mode 100644 ios/RetroArch/rarch_wrapper.h diff --git a/gfx/context/ioseagl_ctx.c b/gfx/context/ioseagl_ctx.c index 106eb3d242..9c70e3b01f 100644 --- a/gfx/context/ioseagl_ctx.c +++ b/gfx/context/ioseagl_ctx.c @@ -35,7 +35,8 @@ static void gfx_ctx_set_swap_interval(unsigned interval) static void gfx_ctx_destroy(void) { - RARCH_LOG("gfx_ctx_destroy().\n"); + extern void ios_destroy_game_view(); + ios_destroy_game_view(); } static void gfx_ctx_get_video_size(unsigned *width, unsigned *height) @@ -46,7 +47,8 @@ static void gfx_ctx_get_video_size(unsigned *width, unsigned *height) static bool gfx_ctx_init(void) { - return true; + extern bool ios_init_game_view(); + return ios_init_game_view(); } static void gfx_ctx_swap_buffers(void) diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 26ae9501dd..68f3413caa 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -84,6 +84,7 @@ 96AFAFAD16C1EEE9009DE44C /* sinc.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEF716C1DC73009DE44C /* sinc.c */; }; 96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFC916C1FBC0009DE44C /* input_common.c */; }; 96AFAFD716C1FBC0009DE44C /* null.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCD16C1FBC0009DE44C /* null.c */; }; + 96C6A5D216CDB384009E3280 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96C6A5D116CDB384009E3280 /* QuartzCore.framework */; }; 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCE16C1FBC0009DE44C /* overlay.c */; }; 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CF015B16C2F72900ABF9C9 /* ios_input.c */; }; /* End PBXBuildFile section */ @@ -290,6 +291,7 @@ 96AFAFD016C1FBC0009DE44C /* sdl_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_input.c; sourceTree = ""; }; 96AFAFD116C1FBC0009DE44C /* sdl_joypad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_joypad.c; sourceTree = ""; }; 96AFAFD216C1FBC0009DE44C /* x11_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x11_input.c; sourceTree = ""; }; + 96C6A5D116CDB384009E3280 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 96CF015B16C2F72900ABF9C9 /* ios_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ios_input.c; sourceTree = ""; }; /* End PBXFileReference section */ @@ -298,6 +300,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 96C6A5D216CDB384009E3280 /* QuartzCore.framework in Frameworks */, 96366C5916C9ACF500D64A22 /* AudioToolbox.framework in Frameworks */, 96366C5516C9AC3300D64A22 /* CoreAudio.framework in Frameworks */, 96AFAF2216C1DF88009DE44C /* libz.dylib in Frameworks */, @@ -351,6 +354,7 @@ 96AFAE2816C1D4EA009DE44C /* Frameworks */ = { isa = PBXGroup; children = ( + 96C6A5D116CDB384009E3280 /* QuartzCore.framework */, 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */, 96366C5416C9AC3300D64A22 /* CoreAudio.framework */, 96AFAE2916C1D4EA009DE44C /* UIKit.framework */, @@ -981,7 +985,6 @@ "-DHAVE_GLSL", "-DINLINE=inline", "-DLSB_FIRST", - "-DHAVE_THREAD", "-D__LIBRETRO__", "-DRARCH_PERFORMANCE_MODE", "-DPACKAGE_VERSION=\\\"1.0\\\"", @@ -1019,7 +1022,6 @@ "-DHAVE_GLSL", "-DINLINE=inline", "-DLSB_FIRST", - "-DHAVE_THREAD", "-D__LIBRETRO__", "-DRARCH_PERFORMANCE_MODE", "-DPACKAGE_VERSION=\\\"1.0\\\"", diff --git a/ios/RetroArch/RAGameView.m b/ios/RetroArch/RAGameView.m index 65044267b5..a01f857b0e 100644 --- a/ios/RetroArch/RAGameView.m +++ b/ios/RetroArch/RAGameView.m @@ -14,77 +14,71 @@ * If not, see . */ +#import #include "general.h" -static GLKView *gl_view; +static bool _isRunning; + static float screen_scale; static int frame_skips = 4; static bool is_syncing = true; -static bool active_iterate() -{ - while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource); - return rarch_main_iterate(); -} - -static bool idle_iterate() -{ - CFRunLoopRunInMode(kCFRunLoopDefaultMode, .5, false); - return true; -} - @implementation RAGameView { - EAGLContext *gl_context; - NSString* game; - bool paused; - bool exiting; + EAGLContext* _glContext; + CADisplayLink* _timer; } -- (id)initWithGame:(NSString*)path +- (id)init { self = [super init]; - game = path; screen_scale = [[UIScreen mainScreen] scale]; + _glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + [EAGLContext setCurrentContext:_glContext]; + + self.view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) context:_glContext]; + self.view.multipleTouchEnabled = YES; + + _timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(iterate)]; + [_timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + return self; } +- (void)iterate +{ + if (_isRunning) rarch_main_iterate(); +} + +- (void)needsToDie +{ + [_timer invalidate]; + _timer = nil; + + glFinish(); + + GLKView* glview = (GLKView*)self.view; + glview.context = nil; + _glContext = nil; + [EAGLContext setCurrentContext:nil]; +} + - (void)pause { - paused = true; + _timer.paused = true; } - (void)resume { - paused = false; + if (_isRunning) _timer.paused = false; } -- (void)exit -{ - exiting = true; -} +@end -- (void)dealloc -{ - if ([EAGLContext currentContext] == gl_context) [EAGLContext setCurrentContext:nil]; - gl_context = nil; - gl_view = nil; -} +static RAGameView* gameViewer; -- (void)loadView -{ - gl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - [EAGLContext setCurrentContext:gl_context]; - - gl_view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) context:gl_context]; - gl_view.multipleTouchEnabled = YES; - self.view = gl_view; - - [self performSelector:@selector(runGame) withObject:nil afterDelay:0.2f]; -} - -- (void)runGame +void ios_load_game(const char* path) { [RASettingsList refreshConfigFile]; @@ -92,30 +86,86 @@ static bool idle_iterate() const char* const cf =[[RetroArch_iOS get].config_file_path UTF8String]; const char* const libretro = [[RetroArch_iOS get].module_path UTF8String]; - struct rarch_main_wrap main_wrapper = {[game UTF8String], sd, sd, cf, libretro}; + struct rarch_main_wrap main_wrapper = {path, sd, sd, cf, libretro}; if (rarch_main_init_wrap(&main_wrapper) == 0) { rarch_init_msg_queue(); - while (!exiting && (paused ? idle_iterate() : active_iterate())); + _isRunning = true; + } + else + _isRunning = false; +} + +void ios_close_game() +{ + if (_isRunning) + { rarch_main_deinit(); rarch_deinit_msg_queue(); - + #ifdef PERF_TEST rarch_perf_log(); #endif - + rarch_main_clear_state(); + + _isRunning = false; } [[RetroArch_iOS get] gameHasExited]; } -@end +void ios_pause_emulator() +{ + if (gameViewer) + [gameViewer pause]; +} + +void ios_resume_emulator() +{ + if (gameViewer) + [gameViewer resume]; +} + +void ios_suspend_emulator() +{ + if (gameViewer) + uninit_drivers(); +} + +void ios_activate_emulator() +{ + if (!gameViewer) + init_drivers(); +} + +bool ios_init_game_view() +{ + if (!gameViewer) + { + gameViewer = [RAGameView new]; + [[RetroArch_iOS get] setViewer:gameViewer]; + } + + return true; +} + +void ios_destroy_game_view() +{ + if (gameViewer) + { + [gameViewer needsToDie]; + [[RetroArch_iOS get] setViewer:nil]; + gameViewer = nil; + } +} void ios_flip_game_view() { - if (gl_view) + if (gameViewer) { + GLKView* gl_view = (GLKView*)gameViewer.view; + if (--frame_skips < 0) { [gl_view setNeedsDisplay]; @@ -133,8 +183,10 @@ void ios_set_game_view_sync(bool on) void ios_get_game_view_size(unsigned *width, unsigned *height) { - if (gl_view) + if (gameViewer) { + GLKView* gl_view = (GLKView*)gameViewer.view; + *width = gl_view.bounds.size.width * screen_scale; *height = gl_view.bounds.size.height * screen_scale; } @@ -142,8 +194,9 @@ void ios_get_game_view_size(unsigned *width, unsigned *height) void ios_bind_game_view_fbo() { - if (gl_view) + if (gameViewer) { + GLKView* gl_view = (GLKView*)gameViewer.view; [gl_view bindDrawable]; } } diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index a185024c3d..369699a7e0 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -19,6 +19,8 @@ extern NSString* const GSEventKeyUpNotification; - (void)pushViewController:(UIViewController*)theView; - (void)popViewController; +- (void)setViewer:(UIViewController*)theView; + @property (strong, nonatomic) NSString* system_directory; @property (strong, nonatomic) NSString* config_file_path; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 9306dba10f..dcea6e6809 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -6,6 +6,7 @@ // #include +#include "rarch_wrapper.h" #define MAX_TOUCH 16 extern struct @@ -22,8 +23,6 @@ extern uint32_t ios_current_touch_count; @implementation RetroArch_iOS { - RAGameView* _game; - UIWindow* _window; UINavigationController* _navigator; } @@ -35,15 +34,11 @@ extern uint32_t ios_current_touch_count; - (void)runGame:(NSString*)path { - _game = [[RAGameView alloc] initWithGame:path]; - _window.rootViewController = _game; - _navigator = nil; + ios_load_game([path UTF8String]); } - (void)gameHasExited { - _game = nil; - _navigator = [[UINavigationController alloc] init]; [_navigator pushViewController: [[RAModuleList alloc] init] animated:YES]; @@ -53,17 +48,19 @@ extern uint32_t ios_current_touch_count; - (void)pushViewController:(UIViewController*)theView { if (_navigator != nil) - { [_navigator pushViewController:theView animated:YES]; - } } - (void)popViewController { if (_navigator != nil) - { [_navigator popViewControllerAnimated:YES]; - } +} + +- (void)setViewer:(UIViewController*)theView +{ + _navigator = nil; + _window.rootViewController = theView; } - (void)applicationDidFinishLaunching:(UIApplication *)application @@ -99,16 +96,24 @@ extern uint32_t ios_current_touch_count; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyReleased:) name: GSEventKeyUpNotification object: nil]; } +- (void)applicationDidBecomeActive:(UIApplication*)application +{ + ios_resume_emulator(); +} + +- (void)applicationWillResignActive:(UIApplication*)application +{ + ios_pause_emulator(); +} + - (void)applicationWillEnterForeground:(UIApplication *)application { - if (_game) - [_game resume]; + ios_activate_emulator(); } - (void)applicationDidEnterBackground:(UIApplication *)application { - if (_game) - [_game pause]; + ios_suspend_emulator(); } -(void) keyPressed: (NSNotification*) notification @@ -130,34 +135,32 @@ extern uint32_t ios_current_touch_count; - (void)processTouches:(NSArray*)touches { - if (_game) - { - ios_current_touch_count = [touches count]; + ios_current_touch_count = [touches count]; - for(int i = 0; i != [touches count]; i ++) - { - UITouch *touch = [touches objectAtIndex:i]; - CGPoint coord = [touch locationInView:_game.view]; - float scale = [[UIScreen mainScreen] scale]; + UIView* view = _window.rootViewController.view; + + for(int i = 0; i != [touches count]; i ++) + { + UITouch *touch = [touches objectAtIndex:i]; + CGPoint coord = [touch locationInView:view]; + float scale = [[UIScreen mainScreen] scale]; - // Exit hack! - if (touch.tapCount == 3) + // Exit hack! + if (touch.tapCount == 3) + { + if (coord.y < view.bounds.size.height / 10.0f) { - if (coord.y < _game.view.bounds.size.height / 10.0f) + float tenpct = view.bounds.size.width / 10.0f; + if (coord.x >= tenpct * 4 && coord.x <= tenpct * 6) { - float tenpct = _game.view.bounds.size.width / 10.0f; - if (coord.x >= tenpct * 4 && coord.x <= tenpct * 6) - { - [_game exit]; - } + ios_close_game(); } } - - ios_touches[i].is_down = (touch.phase != UITouchPhaseEnded) && (touch.phase != UITouchPhaseCancelled); - - ios_touches[i].screen_x = coord.x * scale; - ios_touches[i].screen_y = coord.y * scale; } + + ios_touches[i].is_down = (touch.phase != UITouchPhaseEnded) && (touch.phase != UITouchPhaseCancelled); + ios_touches[i].screen_x = coord.x * scale; + ios_touches[i].screen_y = coord.y * scale; } } diff --git a/ios/RetroArch/main.m b/ios/RetroArch/main.m index 1a80052609..8ecd7e8bdb 100644 --- a/ios/RetroArch/main.m +++ b/ios/RetroArch/main.m @@ -26,29 +26,31 @@ NSString *const GSEventKeyUpNotification = @"GSEventKeyUpHackNotification"; // Stolen from: http://nacho4d-nacho4d.blogspot.com/2012/01/catching-keyboard-events-in-ios.html - (void)sendEvent:(UIEvent *)event { - [super sendEvent:event]; + [super sendEvent:event]; - if ([event respondsToSelector:@selector(_gsEvent)]) - { - int* eventMem = (int *)(void*)CFBridgingRetain([event performSelector:@selector(_gsEvent)]); - int eventType = eventMem ? eventMem[GSEVENT_TYPE] : 0; + if ([event respondsToSelector:@selector(_gsEvent)]) + { + int* eventMem = (int *)(void*)CFBridgingRetain([event performSelector:@selector(_gsEvent)]); + int eventType = eventMem ? eventMem[GSEVENT_TYPE] : 0; - if (eventMem && (eventType == GSEVENT_TYPE_KEYDOWN || eventType == GSEVENT_TYPE_KEYUP)) - { - // Read keycode from GSEventKey - int tmp = eventMem[GSEVENTKEY_KEYCODE]; - UniChar *keycode = (UniChar *)&tmp; + if (eventMem && (eventType == GSEVENT_TYPE_KEYDOWN || eventType == GSEVENT_TYPE_KEYUP)) + { + // Read keycode from GSEventKey + int tmp = eventMem[GSEVENTKEY_KEYCODE]; + UniChar *keycode = (UniChar *)&tmp; - // Post notification - NSDictionary *inf = [[NSDictionary alloc] initWithObjectsAndKeys: - [NSNumber numberWithShort:keycode[0]], @"keycode", - nil]; + // Post notification + NSDictionary *inf = [[NSDictionary alloc] initWithObjectsAndKeys: + [NSNumber numberWithShort:keycode[0]], @"keycode", + nil]; - [[NSNotificationCenter defaultCenter] - postNotificationName:(eventType == GSEVENT_TYPE_KEYDOWN) ? GSEventKeyDownNotification : GSEventKeyUpNotification - object:nil userInfo:inf]; - } - } + [[NSNotificationCenter defaultCenter] + postNotificationName:(eventType == GSEVENT_TYPE_KEYDOWN) ? GSEventKeyDownNotification : GSEventKeyUpNotification + object:nil userInfo:inf]; + } + + CFBridgingRelease(eventMem); + } } #endif diff --git a/ios/RetroArch/rarch_wrapper.h b/ios/RetroArch/rarch_wrapper.h new file mode 100644 index 0000000000..195c4eca01 --- /dev/null +++ b/ios/RetroArch/rarch_wrapper.h @@ -0,0 +1,17 @@ +#ifndef __IOS_RARCH_WRAPPER_H__ +#define __IOS_RARCH_WRAPPER_H__ + +bool ios_load_game(const char* path); +void ios_close_game(); +void ios_pause_emulator(); +void ios_resume_emulator(); +void ios_suspend_emulator(); +void ios_activate_emulator(); +bool ios_init_game_view(); +void ios_destroy_game_view(); +void ios_flip_game_view(); +void ios_set_game_view_sync(bool on); +void ios_get_game_view_size(unsigned *width, unsigned *height); +void ios_bind_game_view_fbo(); + +#endif diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index 59d21b1a60..cdb31e9ae6 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -4,10 +4,6 @@ #include "conf/config_file.h" @interface RAGameView : UIViewController -- (id)initWithGame:(NSString*)path;\ -- (void)pause; -- (void)resume; -- (void)exit; @end @interface RAModuleList : UITableViewController From 994aa01fcb5ea5ccdcf7b9bbf8f1aa0447266164 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 14 Feb 2013 22:09:18 -0500 Subject: [PATCH 054/108] ios: Remove QuartzCore timer and return to manually calling CFRunLoopRunInMode. --- ios/RetroArch.xcodeproj/project.pbxproj | 4 ---- ios/RetroArch/RAGameView.m | 31 +++++++++++++++++++------ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 68f3413caa..600f53180d 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -84,7 +84,6 @@ 96AFAFAD16C1EEE9009DE44C /* sinc.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEF716C1DC73009DE44C /* sinc.c */; }; 96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFC916C1FBC0009DE44C /* input_common.c */; }; 96AFAFD716C1FBC0009DE44C /* null.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCD16C1FBC0009DE44C /* null.c */; }; - 96C6A5D216CDB384009E3280 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96C6A5D116CDB384009E3280 /* QuartzCore.framework */; }; 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCE16C1FBC0009DE44C /* overlay.c */; }; 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CF015B16C2F72900ABF9C9 /* ios_input.c */; }; /* End PBXBuildFile section */ @@ -291,7 +290,6 @@ 96AFAFD016C1FBC0009DE44C /* sdl_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_input.c; sourceTree = ""; }; 96AFAFD116C1FBC0009DE44C /* sdl_joypad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_joypad.c; sourceTree = ""; }; 96AFAFD216C1FBC0009DE44C /* x11_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x11_input.c; sourceTree = ""; }; - 96C6A5D116CDB384009E3280 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 96CF015B16C2F72900ABF9C9 /* ios_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ios_input.c; sourceTree = ""; }; /* End PBXFileReference section */ @@ -300,7 +298,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 96C6A5D216CDB384009E3280 /* QuartzCore.framework in Frameworks */, 96366C5916C9ACF500D64A22 /* AudioToolbox.framework in Frameworks */, 96366C5516C9AC3300D64A22 /* CoreAudio.framework in Frameworks */, 96AFAF2216C1DF88009DE44C /* libz.dylib in Frameworks */, @@ -354,7 +351,6 @@ 96AFAE2816C1D4EA009DE44C /* Frameworks */ = { isa = PBXGroup; children = ( - 96C6A5D116CDB384009E3280 /* QuartzCore.framework */, 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */, 96366C5416C9AC3300D64A22 /* CoreAudio.framework */, 96AFAE2916C1D4EA009DE44C /* UIKit.framework */, diff --git a/ios/RetroArch/RAGameView.m b/ios/RetroArch/RAGameView.m index a01f857b0e..7ba65a09e1 100644 --- a/ios/RetroArch/RAGameView.m +++ b/ios/RetroArch/RAGameView.m @@ -16,8 +16,10 @@ #import #include "general.h" +#include "rarch_wrapper.h" static bool _isRunning; +static bool _isPaused; static float screen_scale; static int frame_skips = 4; @@ -40,15 +42,23 @@ static bool is_syncing = true; self.view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) context:_glContext]; self.view.multipleTouchEnabled = YES; - _timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(iterate)]; - [_timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; - return self; } - (void)iterate { - if (_isRunning) rarch_main_iterate(); + while (_isRunning && !_isPaused) + { + _isRunning = rarch_main_iterate(); + + if (!_isRunning) + { + ios_close_game(); + return; + } + else + while(!_isPaused && _isRunning && CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource); + } } - (void)needsToDie @@ -66,19 +76,23 @@ static bool is_syncing = true; - (void)pause { - _timer.paused = true; + _isPaused = true; } - (void)resume { - if (_isRunning) _timer.paused = false; + if (_isPaused) + { + _isPaused = false; + [self performSelector:@selector(iterate) withObject:nil afterDelay:.02f]; + } } @end static RAGameView* gameViewer; -void ios_load_game(const char* path) +bool ios_load_game(const char* path) { [RASettingsList refreshConfigFile]; @@ -94,6 +108,8 @@ void ios_load_game(const char* path) } else _isRunning = false; + + return _isRunning; } void ios_close_game() @@ -145,6 +161,7 @@ bool ios_init_game_view() { gameViewer = [RAGameView new]; [[RetroArch_iOS get] setViewer:gameViewer]; + [gameViewer performSelector:@selector(iterate) withObject:nil afterDelay:.02f]; } return true; From 67336b690a588d59fc4a7ed3091d8eedf74591a9 Mon Sep 17 00:00:00 2001 From: meancoot Date: Fri, 15 Feb 2013 18:51:46 -0500 Subject: [PATCH 055/108] ios: Fix empty RAGameView may be displayed when restoring from suspend without a game loaded. --- ios/RetroArch/RAGameView.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ios/RetroArch/RAGameView.m b/ios/RetroArch/RAGameView.m index 7ba65a09e1..b882f49d15 100644 --- a/ios/RetroArch/RAGameView.m +++ b/ios/RetroArch/RAGameView.m @@ -133,25 +133,25 @@ void ios_close_game() void ios_pause_emulator() { - if (gameViewer) + if (_isRunning) [gameViewer pause]; } void ios_resume_emulator() { - if (gameViewer) + if (_isRunning) [gameViewer resume]; } void ios_suspend_emulator() { - if (gameViewer) + if (_isRunning) uninit_drivers(); } void ios_activate_emulator() { - if (!gameViewer) + if (_isRunning) init_drivers(); } From 473e3c34ebc1223841f34a027a02b62efe53b841 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sat, 16 Feb 2013 19:51:55 -0500 Subject: [PATCH 056/108] ios: Add (ugly) overlay bar for a few seconds to indicate how to triple-tap close a game. --- ios/RetroArch/RAGameView.m | 47 ++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/ios/RetroArch/RAGameView.m b/ios/RetroArch/RAGameView.m index b882f49d15..baea3f75ea 100644 --- a/ios/RetroArch/RAGameView.m +++ b/ios/RetroArch/RAGameView.m @@ -14,7 +14,6 @@ * If not, see . */ -#import #include "general.h" #include "rarch_wrapper.h" @@ -28,7 +27,8 @@ static bool is_syncing = true; @implementation RAGameView { EAGLContext* _glContext; - CADisplayLink* _timer; + UIButton* _notifyButton; + UILabel* _notifyLabel; } - (id)init @@ -39,12 +39,48 @@ static bool is_syncing = true; _glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; [EAGLContext setCurrentContext:_glContext]; - self.view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) context:_glContext]; + self.view = [GLKView new]; + ((GLKView*)self.view).context = _glContext; self.view.multipleTouchEnabled = YES; - + return self; } +- (void)viewDidAppear:(BOOL)animated +{ + CGSize size = self.view.bounds.size; + float tenpct = size.width / 10.0f; + + _notifyButton = [[UIButton alloc] initWithFrame:CGRectMake(tenpct * 4.0f, 0, tenpct * 2.0f, size.height / 10.0f)]; + _notifyButton.backgroundColor = [UIColor redColor]; + _notifyButton.opaque = NO; + + _notifyLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height / 10.0f)]; + _notifyLabel.backgroundColor = [UIColor colorWithRed:0.2f green:0.2f blue: 0.5f alpha:0.5f]; + _notifyLabel.text = @"Triple tap to exit."; + _notifyLabel.textAlignment = NSTextAlignmentCenter; + _notifyLabel.opaque = NO; + + [self.view addSubview:_notifyButton]; + [self.view addSubview:_notifyLabel]; + [self performSelector:@selector(hideNotify) withObject:nil afterDelay:3.0f]; +} + +- (void)hideNotify +{ + if (_notifyLabel && _notifyButton) + { + // TODO: Actually removing these views will cause an ugly flash in the game window... + [UIView animateWithDuration:0.2 + animations:^{_notifyButton.alpha = 0.0;} + completion:^(BOOL finished){ _notifyButton.hidden = YES; _notifyButton = nil; }]; + + [UIView animateWithDuration:0.2 + animations:^{_notifyLabel.alpha = 0.0;} + completion:^(BOOL finished){ _notifyLabel.hidden = YES; _notifyLabel = nil; }]; + } +} + - (void)iterate { while (_isRunning && !_isPaused) @@ -63,9 +99,6 @@ static bool is_syncing = true; - (void)needsToDie { - [_timer invalidate]; - _timer = nil; - glFinish(); GLKView* glview = (GLKView*)self.view; From c14b45f957405d2bc0bd1a6aade9daa8615f48e0 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 17 Feb 2013 19:35:43 -0500 Subject: [PATCH 057/108] ios: Add a detail view that can load and display core info from a configuration file. --- ios/RetroArch.xcodeproj/project.pbxproj | 4 ++ ios/RetroArch/RAModuleInfoList.m | 88 +++++++++++++++++++++++++ ios/RetroArch/RAModuleList.m | 38 ++++++++--- ios/RetroArch/views.h | 13 +++- 4 files changed, 133 insertions(+), 10 deletions(-) create mode 100644 ios/RetroArch/RAModuleInfoList.m diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 600f53180d..c476742ef5 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 96096DD816D1ABAF00BF4499 /* RAModuleInfoList.m in Sources */ = {isa = PBXBuildFile; fileRef = 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */; }; 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */; }; 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; }; 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; }; @@ -89,6 +90,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAModuleInfoList.m; sourceTree = ""; }; 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioseagl_ctx.c; sourceTree = ""; }; 962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = ""; }; 962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = ""; }; @@ -365,6 +367,7 @@ 96AFAE3316C1D4EA009DE44C /* RetroArch */ = { isa = PBXGroup; children = ( + 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */, 963F5AC416CC523B009BBD19 /* RADirectoryList.m */, 963F5AC516CC523B009BBD19 /* RAGameView.m */, 963F5AC616CC523B009BBD19 /* RAModuleList.m */, @@ -833,6 +836,7 @@ 963F5AC716CC523B009BBD19 /* RADirectoryList.m in Sources */, 963F5AC816CC523B009BBD19 /* RAGameView.m in Sources */, 963F5AC916CC523B009BBD19 /* RAModuleList.m in Sources */, + 96096DD816D1ABAF00BF4499 /* RAModuleInfoList.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/RAModuleInfoList.m b/ios/RetroArch/RAModuleInfoList.m new file mode 100644 index 0000000000..5f3d05e52c --- /dev/null +++ b/ios/RetroArch/RAModuleInfoList.m @@ -0,0 +1,88 @@ +// +// module_list.m +// RetroArch +// +// Created by Jason Fetters on 2/8/13. +// Copyright (c) 2013 RetroArch. All rights reserved. +// + + +@implementation RAModuleInfo ++ (RAModuleInfo*)moduleWithPath:(NSString*)thePath data:(config_file_t*)theData +{ + RAModuleInfo* new = [RAModuleInfo new]; + + new.path = thePath; + new.data = theData; + return new; +} + +- (void)dealloc +{ + if (self.data) + { + config_file_free(self.data); + } +} + +@end + +static NSString* const labels[3] = {@"Emulator Name", @"Manufacturer", @"Name"}; +static const char* const keys[3] = {"emuname", "manufacturer", "systemname"}; + +static const uint32_t sectionSizes[2] = {1, 2}; +static NSString* const sectionNames[2] = {@"Emulator", @"Hardware"}; + +@implementation RAModuleInfoList +{ + RAModuleInfo* _data; +} + +- (id)initWithModuleInfo:(RAModuleInfo*)info +{ + self = [super initWithStyle:UITableViewStyleGrouped]; + + _data = info; + return self; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView +{ + return sizeof(sectionSizes) / sizeof(sectionSizes[0]); +} + +- (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section +{ + return sectionNames[section]; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return sectionSizes[section]; +} + +- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"datacell"]; + cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"datacell"]; + + uint32_t sectionBase = 0; + for (int i = 0; i != indexPath.section; i ++) + { + sectionBase += sectionSizes[i]; + } + + cell.textLabel.text = labels[sectionBase + indexPath.row]; + + char* text = 0; + if (config_get_string(_data.data, keys[sectionBase + indexPath.row], &text)) + cell.detailTextLabel.text = [NSString stringWithUTF8String:text]; + else + cell.detailTextLabel.text = @"Unspecified"; + + free(text); + + return cell; +} + +@end diff --git a/ios/RetroArch/RAModuleList.m b/ios/RetroArch/RAModuleList.m index c1e4c07d13..30464a75d0 100644 --- a/ios/RetroArch/RAModuleList.m +++ b/ios/RetroArch/RAModuleList.m @@ -18,7 +18,7 @@ static void display_error_alert(NSString* message) @implementation RAModuleList { - NSArray* _modules; + NSMutableArray* _modules; } - (id)init @@ -28,19 +28,30 @@ static void display_error_alert(NSString* message) // Get the contents of the modules directory of the bundle. NSString* module_dir = [NSString stringWithFormat:@"%@/modules", [[NSBundle mainBundle] bundlePath]]; - _modules = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:module_dir error:nil]; + NSArray* moduleList = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:module_dir error:nil]; - if (_modules != nil) + if (moduleList != nil) { - _modules = [module_dir stringsByAppendingPaths:_modules]; - _modules = [_modules pathsMatchingExtensions:[NSArray arrayWithObject:@"dylib"]]; + moduleList = [module_dir stringsByAppendingPaths:moduleList]; + moduleList = [moduleList pathsMatchingExtensions:[NSArray arrayWithObject:@"dylib"]]; } - if (_modules == nil || [_modules count] == 0) + if (moduleList == nil || [moduleList count] == 0) { display_error_alert(@"No libretro cores were found."); } + // Load the modules with their data + _modules = [NSMutableArray arrayWithCapacity:[moduleList count]]; + + for (int i = 0; i != [moduleList count]; i ++) + { + NSString* modulePath = [moduleList objectAtIndex:i]; + + NSString* baseName = [[modulePath stringByDeletingPathExtension] stringByAppendingPathExtension:@"info"]; + [_modules addObject:[RAModuleInfo moduleWithPath:modulePath data:config_file_new([baseName UTF8String])]]; + } + [self setTitle:@"Choose Emulator"]; self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; @@ -49,10 +60,18 @@ static void display_error_alert(NSString* message) - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - [RetroArch_iOS get].module_path = [_modules objectAtIndex:indexPath.row]; + RAModuleInfo* info = (RAModuleInfo*)[_modules objectAtIndex:indexPath.row]; + [RetroArch_iOS get].module_path = info.path; + [[RetroArch_iOS get] pushViewController:[[RADirectoryList alloc] initWithPath:nil]]; } +- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath +{ + RAModuleInfo* info = (RAModuleInfo*)[_modules objectAtIndex:indexPath.row]; + [[RetroArch_iOS get] pushViewController:[[RAModuleInfoList alloc] initWithModuleInfo:info]]; +} + - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return _modules ? [_modules count] : 0; @@ -63,7 +82,10 @@ static void display_error_alert(NSString* message) UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"module"]; cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"module"]; - cell.textLabel.text = [[[_modules objectAtIndex:indexPath.row] lastPathComponent] stringByDeletingPathExtension]; + RAModuleInfo* info = (RAModuleInfo*)[_modules objectAtIndex:indexPath.row]; + cell.textLabel.text = [[info.path lastPathComponent] stringByDeletingPathExtension]; + cell.accessoryType = (info.data) ? UITableViewCellAccessoryDetailDisclosureButton : UITableViewCellAccessoryNone; + return cell; } diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index cdb31e9ae6..ff8a6c5270 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -6,15 +6,24 @@ @interface RAGameView : UIViewController @end -@interface RAModuleList : UITableViewController +@interface RAModuleInfo : NSObject +@property (strong) NSString* path; +@property config_file_t* data; ++ (RAModuleInfo*)moduleWithPath:(NSString*)thePath data:(config_file_t*)theData; +@end + +@interface RAModuleInfoList : UITableViewController +- (id)initWithModuleInfo:(RAModuleInfo*)info; +@end + +@interface RAModuleList : UITableViewController @end @interface RADirectoryList : UITableViewController - (id)initWithPath:(NSString*)path; @end - @interface RASettingsSubList : UITableViewController - (id)initWithSettings:(NSArray*)values title:(NSString*)title; - (void)writeSettings:(NSArray*)settingList toConfig:(config_file_t*)config; From 6fc02c95d3834c56db5e49688da8a98e86b69aef Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 17 Feb 2013 20:28:00 -0500 Subject: [PATCH 058/108] ios: Make it so the triple tap to exit button doesn't actuall prevent triple tapping. --- ios/RetroArch/RAGameView.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ios/RetroArch/RAGameView.m b/ios/RetroArch/RAGameView.m index baea3f75ea..2f3b4f016d 100644 --- a/ios/RetroArch/RAGameView.m +++ b/ios/RetroArch/RAGameView.m @@ -54,12 +54,14 @@ static bool is_syncing = true; _notifyButton = [[UIButton alloc] initWithFrame:CGRectMake(tenpct * 4.0f, 0, tenpct * 2.0f, size.height / 10.0f)]; _notifyButton.backgroundColor = [UIColor redColor]; _notifyButton.opaque = NO; + _notifyButton.userInteractionEnabled = NO; _notifyLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height / 10.0f)]; _notifyLabel.backgroundColor = [UIColor colorWithRed:0.2f green:0.2f blue: 0.5f alpha:0.5f]; _notifyLabel.text = @"Triple tap to exit."; _notifyLabel.textAlignment = NSTextAlignmentCenter; _notifyLabel.opaque = NO; + _notifyLabel.userInteractionEnabled = NO; [self.view addSubview:_notifyButton]; [self.view addSubview:_notifyLabel]; From 6f495c5fcd4161ce0642a4f8bdc188fe7ba231c2 Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 18 Feb 2013 11:57:24 -0500 Subject: [PATCH 059/108] ios: Make settings per module. --- ios/RetroArch/RAGameView.m | 2 +- ios/RetroArch/RAModuleList.m | 1 - ios/RetroArch/RetroArch_iOS.h | 3 ++- ios/RetroArch/RetroArch_iOS.m | 16 ++++++++++++---- ios/RetroArch/settings/RASettingsList.m | 6 +++--- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/ios/RetroArch/RAGameView.m b/ios/RetroArch/RAGameView.m index 2f3b4f016d..a30d8d1929 100644 --- a/ios/RetroArch/RAGameView.m +++ b/ios/RetroArch/RAGameView.m @@ -132,7 +132,7 @@ bool ios_load_game(const char* path) [RASettingsList refreshConfigFile]; const char* const sd = [[RetroArch_iOS get].system_directory UTF8String]; - const char* const cf =[[RetroArch_iOS get].config_file_path UTF8String]; + const char* const cf =[[RetroArch_iOS get].configFilePath UTF8String]; const char* const libretro = [[RetroArch_iOS get].module_path UTF8String]; struct rarch_main_wrap main_wrapper = {path, sd, sd, cf, libretro}; diff --git a/ios/RetroArch/RAModuleList.m b/ios/RetroArch/RAModuleList.m index 30464a75d0..ccc784335c 100644 --- a/ios/RetroArch/RAModuleList.m +++ b/ios/RetroArch/RAModuleList.m @@ -53,7 +53,6 @@ static void display_error_alert(NSString* message) } [self setTitle:@"Choose Emulator"]; - self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; return self; } diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index 369699a7e0..6281a0014f 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -21,8 +21,9 @@ extern NSString* const GSEventKeyUpNotification; - (void)setViewer:(UIViewController*)theView; +- (NSString*)configFilePath; + @property (strong, nonatomic) NSString* system_directory; -@property (strong, nonatomic) NSString* config_file_path; @property (strong, nonatomic) NSString* module_path; @property (strong, nonatomic) UIImage* file_icon; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index dcea6e6809..ba9b859d43 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -63,21 +63,29 @@ extern uint32_t ios_current_touch_count; _window.rootViewController = theView; } +- (NSString*)configFilePath +{ + if (self.module_path) + { + return [NSString stringWithFormat:@"%@/%@.cfg", self.system_directory, [[self.module_path lastPathComponent] stringByDeletingPathExtension]]; + } + + return nil; +} + - (void)applicationDidFinishLaunching:(UIApplication *)application { // TODO: Relocate this! self.system_directory = @"/var/mobile/Library/RetroArch/"; mkdir([self.system_directory UTF8String], 0755); - - self.config_file_path = [self.system_directory stringByAppendingPathComponent:@"retroarch.cfg"]; - + // Load icons self.file_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_file" ofType:@"png"]]; self.folder_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_dir" ofType:@"png"]]; // Load buttons self.settings_button = [[UIBarButtonItem alloc] - initWithTitle:@"Settings" + initWithTitle:@"Module Settings" style:UIBarButtonItemStyleBordered target:nil action:nil]; self.settings_button.target = self; diff --git a/ios/RetroArch/settings/RASettingsList.m b/ios/RetroArch/settings/RASettingsList.m index 6fe1034bc0..c483360903 100644 --- a/ios/RetroArch/settings/RASettingsList.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -93,7 +93,7 @@ static RASettingData* subpath_setting(config_file_t* config, NSString* name, NSS @implementation RASettingsList - (id)init { - config_file_t* config = config_file_new([[RetroArch_iOS get].config_file_path UTF8String]); + config_file_t* config = config_file_new([[RetroArch_iOS get].configFilePath UTF8String]); NSString* overlay_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/overlays/"]; NSString* shader_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/shaders/"]; @@ -181,14 +181,14 @@ static RASettingData* subpath_setting(config_file_t* config, NSString* name, NSS - (void)writeToDisk { - config_file_t* config = config_file_new([[RetroArch_iOS get].config_file_path UTF8String]); + config_file_t* config = config_file_new([[RetroArch_iOS get].configFilePath UTF8String]); config = config ? config : config_file_new(0); config_set_string(config, "system_directory", [[RetroArch_iOS get].system_directory UTF8String]); [self writeSettings:nil toConfig:config]; - config_file_write(config, [[RetroArch_iOS get].config_file_path UTF8String]); + config_file_write(config, [[RetroArch_iOS get].configFilePath UTF8String]); config_file_free(config); } From deb84a84631d516f1694bc46e423117fa152eec8 Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 18 Feb 2013 14:59:43 -0500 Subject: [PATCH 060/108] ios: Clean up Xcode project --- ios/RetroArch.xcodeproj/project.pbxproj | 240 ++---------------- .../en.lproj/ViewController_iPad.xib | 112 -------- .../en.lproj/ViewController_iPhone.xib | 127 --------- 3 files changed, 27 insertions(+), 452 deletions(-) delete mode 100644 ios/RetroArch/en.lproj/ViewController_iPad.xib delete mode 100644 ios/RetroArch/en.lproj/ViewController_iPhone.xib diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index c476742ef5..692bf771cd 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -37,8 +37,6 @@ 96AFAE4016C1D4EA009DE44C /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE3F16C1D4EA009DE44C /* Default.png */; }; 96AFAE4216C1D4EA009DE44C /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4116C1D4EA009DE44C /* Default@2x.png */; }; 96AFAE4416C1D4EA009DE44C /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4316C1D4EA009DE44C /* Default-568h@2x.png */; }; - 96AFAE4E16C1D4EA009DE44C /* ViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4C16C1D4EA009DE44C /* ViewController_iPhone.xib */; }; - 96AFAE5116C1D4EA009DE44C /* ViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4F16C1D4EA009DE44C /* ViewController_iPad.xib */; }; 96AFAECA16C1D9A9009DE44C /* autosave.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAE9D16C1D9A9009DE44C /* autosave.c */; }; 96AFAECB16C1D9A9009DE44C /* cheats.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEA016C1D9A9009DE44C /* cheats.c */; }; 96AFAECC16C1D9A9009DE44C /* command.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEA216C1D9A9009DE44C /* command.c */; }; @@ -59,7 +57,6 @@ 96AFAEDC16C1D9A9009DE44C /* settings.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEC716C1D9A9009DE44C /* settings.c */; }; 96AFAEDD16C1D9A9009DE44C /* thread.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEC816C1D9A9009DE44C /* thread.c */; }; 96AFAEE416C1DBDB009DE44C /* config_file.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEE116C1DBDB009DE44C /* config_file.c */; }; - 96AFAF0B16C1DC73009DE44C /* null.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEEE16C1DC73009DE44C /* null.c */; }; 96AFAF1816C1DC73009DE44C /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEFD16C1DC73009DE44C /* utils.c */; }; 96AFAF2216C1DF88009DE44C /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAF2116C1DF88009DE44C /* libz.dylib */; }; 96AFAF2D16C1DFC8009DE44C /* compat.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF2416C1DFC8009DE44C /* compat.c */; }; @@ -74,7 +71,6 @@ 96AFAF9916C1E00A009DE44C /* image.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF5A16C1E00A009DE44C /* image.c */; }; 96AFAF9A16C1E00A009DE44C /* matrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF5D16C1E00A009DE44C /* matrix.c */; }; 96AFAF9B16C1E00A009DE44C /* matrix_3x3.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF5F16C1E00A009DE44C /* matrix_3x3.c */; }; - 96AFAF9C16C1E00A009DE44C /* null.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF6116C1E00A009DE44C /* null.c */; }; 96AFAF9F16C1E00A009DE44C /* rpng.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF6716C1E00A009DE44C /* rpng.c */; }; 96AFAFA116C1E00A009DE44C /* filter.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF6B16C1E00A009DE44C /* filter.c */; }; 96AFAFA216C1E00A009DE44C /* pixconv.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF6D16C1E00A009DE44C /* pixconv.c */; }; @@ -84,7 +80,6 @@ 96AFAFAC16C1E279009DE44C /* state_tracker.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF7B16C1E00A009DE44C /* state_tracker.c */; }; 96AFAFAD16C1EEE9009DE44C /* sinc.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEF716C1DC73009DE44C /* sinc.c */; }; 96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFC916C1FBC0009DE44C /* input_common.c */; }; - 96AFAFD716C1FBC0009DE44C /* null.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCD16C1FBC0009DE44C /* null.c */; }; 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCE16C1FBC0009DE44C /* overlay.c */; }; 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CF015B16C2F72900ABF9C9 /* ios_input.c */; }; /* End PBXBuildFile section */ @@ -124,8 +119,6 @@ 96AFAE3F16C1D4EA009DE44C /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 96AFAE4116C1D4EA009DE44C /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 96AFAE4316C1D4EA009DE44C /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; - 96AFAE4D16C1D4EA009DE44C /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPhone.xib; sourceTree = ""; }; - 96AFAE5016C1D4EA009DE44C /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPad.xib; sourceTree = ""; }; 96AFAE9D16C1D9A9009DE44C /* autosave.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = autosave.c; path = ../autosave.c; sourceTree = ""; }; 96AFAE9E16C1D9A9009DE44C /* autosave.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = autosave.h; path = ../autosave.h; sourceTree = ""; }; 96AFAE9F16C1D9A9009DE44C /* boolean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = boolean.h; path = ../boolean.h; sourceTree = ""; }; @@ -156,7 +149,6 @@ 96AFAEB816C1D9A9009DE44C /* movie.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = movie.c; path = ../movie.c; sourceTree = ""; }; 96AFAEB916C1D9A9009DE44C /* movie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = movie.h; path = ../movie.h; sourceTree = ""; }; 96AFAEBA16C1D9A9009DE44C /* netplay_compat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = netplay_compat.h; path = ../netplay_compat.h; sourceTree = ""; }; - 96AFAEBB16C1D9A9009DE44C /* netplay.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = netplay.c; path = ../netplay.c; sourceTree = ""; }; 96AFAEBC16C1D9A9009DE44C /* netplay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = netplay.h; path = ../netplay.h; sourceTree = ""; }; 96AFAEBD16C1D9A9009DE44C /* patch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = patch.c; path = ../patch.c; sourceTree = ""; }; 96AFAEBE16C1D9A9009DE44C /* patch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = patch.h; path = ../patch.h; sourceTree = ""; }; @@ -174,74 +166,32 @@ 96AFAEE116C1DBDB009DE44C /* config_file.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = config_file.c; sourceTree = ""; }; 96AFAEE216C1DBDB009DE44C /* config_file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config_file.h; sourceTree = ""; }; 96AFAEE316C1DBDB009DE44C /* config_file_macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config_file_macros.h; sourceTree = ""; }; - 96AFAEE616C1DC73009DE44C /* alsa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alsa.c; sourceTree = ""; }; - 96AFAEE716C1DC73009DE44C /* alsathread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alsathread.c; sourceTree = ""; }; 96AFAEE816C1DC73009DE44C /* coreaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = coreaudio.c; sourceTree = ""; }; - 96AFAEE916C1DC73009DE44C /* dsound.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dsound.c; sourceTree = ""; }; 96AFAEEB16C1DC73009DE44C /* rarch_dsp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rarch_dsp.h; sourceTree = ""; }; 96AFAEEC16C1DC73009DE44C /* hermite.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hermite.c; sourceTree = ""; }; - 96AFAEED16C1DC73009DE44C /* jack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = jack.c; sourceTree = ""; }; - 96AFAEEE16C1DC73009DE44C /* null.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = null.c; sourceTree = ""; }; - 96AFAEEF16C1DC73009DE44C /* openal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = openal.c; sourceTree = ""; }; - 96AFAEF016C1DC73009DE44C /* opensl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = opensl.c; sourceTree = ""; }; - 96AFAEF116C1DC73009DE44C /* oss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = oss.c; sourceTree = ""; }; - 96AFAEF216C1DC73009DE44C /* pulse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pulse.c; sourceTree = ""; }; 96AFAEF316C1DC73009DE44C /* resampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resampler.h; sourceTree = ""; }; - 96AFAEF416C1DC73009DE44C /* roar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = roar.c; sourceTree = ""; }; - 96AFAEF516C1DC73009DE44C /* rsound.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsound.c; sourceTree = ""; }; - 96AFAEF616C1DC73009DE44C /* sdl_audio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_audio.c; sourceTree = ""; }; 96AFAEF716C1DC73009DE44C /* sinc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sinc.c; sourceTree = ""; }; 96AFAEF816C1DC73009DE44C /* sinc_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sinc_neon.S; sourceTree = ""; }; - 96AFAEFA16C1DC73009DE44C /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; - 96AFAEFB16C1DC73009DE44C /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; - 96AFAEFC16C1DC73009DE44C /* snr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = snr.c; sourceTree = ""; }; 96AFAEFD16C1DC73009DE44C /* utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utils.c; sourceTree = ""; }; 96AFAEFE16C1DC73009DE44C /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = ""; }; 96AFAEFF16C1DC73009DE44C /* utils_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = utils_neon.S; sourceTree = ""; }; - 96AFAF0116C1DC73009DE44C /* xaudio-c.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "xaudio-c.cpp"; sourceTree = ""; }; - 96AFAF0216C1DC73009DE44C /* xaudio-c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "xaudio-c.h"; sourceTree = ""; }; - 96AFAF0316C1DC73009DE44C /* xaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xaudio.h; sourceTree = ""; }; - 96AFAF0416C1DC73009DE44C /* xaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xaudio.c; sourceTree = ""; }; 96AFAF2116C1DF88009DE44C /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; 96AFAF2416C1DFC8009DE44C /* compat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = compat.c; sourceTree = ""; }; 96AFAF2516C1DFC8009DE44C /* getopt_rarch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = getopt_rarch.h; sourceTree = ""; }; 96AFAF2616C1DFC8009DE44C /* posix_string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = posix_string.h; sourceTree = ""; }; - 96AFAF2816C1DFC8009DE44C /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; 96AFAF2916C1DFC8009DE44C /* rxml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rxml.c; sourceTree = ""; }; 96AFAF2A16C1DFC8009DE44C /* rxml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rxml.h; sourceTree = ""; }; - 96AFAF2B16C1DFC8009DE44C /* rxml_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rxml_test.c; sourceTree = ""; }; 96AFAF2C16C1DFC8009DE44C /* strl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strl.h; sourceTree = ""; }; - 96AFAF3316C1E00A009DE44C /* androidegl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = androidegl_ctx.c; sourceTree = ""; }; - 96AFAF3416C1E00A009DE44C /* drm_egl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = drm_egl_ctx.c; sourceTree = ""; }; - 96AFAF3516C1E00A009DE44C /* glx_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = glx_ctx.c; sourceTree = ""; }; - 96AFAF3616C1E00A009DE44C /* ps3_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps3_ctx.c; sourceTree = ""; }; - 96AFAF3716C1E00A009DE44C /* sdl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_ctx.c; sourceTree = ""; }; - 96AFAF3816C1E00A009DE44C /* vc_egl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vc_egl_ctx.c; sourceTree = ""; }; - 96AFAF3916C1E00A009DE44C /* wgl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wgl_ctx.c; sourceTree = ""; }; - 96AFAF3A16C1E00A009DE44C /* x11_common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x11_common.c; sourceTree = ""; }; - 96AFAF3B16C1E00A009DE44C /* x11_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = x11_common.h; sourceTree = ""; }; - 96AFAF3C16C1E00A009DE44C /* xdk_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdk_ctx.c; sourceTree = ""; }; - 96AFAF3D16C1E00A009DE44C /* xegl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xegl_ctx.c; sourceTree = ""; }; - 96AFAF3F16C1E00A009DE44C /* config_file.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = config_file.hpp; sourceTree = ""; }; - 96AFAF4016C1E00A009DE44C /* d3d9.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = d3d9.cpp; sourceTree = ""; }; - 96AFAF4116C1E00A009DE44C /* d3d9.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = d3d9.hpp; sourceTree = ""; }; - 96AFAF4216C1E00A009DE44C /* render_chain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = render_chain.cpp; sourceTree = ""; }; - 96AFAF4316C1E00A009DE44C /* render_chain.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = render_chain.hpp; sourceTree = ""; }; 96AFAF4516C1E00A009DE44C /* bitmap.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = bitmap.bin; sourceTree = ""; }; 96AFAF4616C1E00A009DE44C /* bitmap.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = bitmap.bmp; sourceTree = ""; }; 96AFAF4716C1E00A009DE44C /* bitmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bitmap.h; sourceTree = ""; }; 96AFAF4816C1E00A009DE44C /* bitmapfont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bitmapfont.c; sourceTree = ""; }; - 96AFAF4916C1E00A009DE44C /* d3d_font.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = d3d_font.c; sourceTree = ""; }; - 96AFAF4A16C1E00A009DE44C /* d3d_font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = d3d_font.h; sourceTree = ""; }; 96AFAF4B16C1E00A009DE44C /* fonts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fonts.c; sourceTree = ""; }; 96AFAF4C16C1E00A009DE44C /* fonts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fonts.h; sourceTree = ""; }; 96AFAF4D16C1E00A009DE44C /* freetype.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = freetype.c; sourceTree = ""; }; 96AFAF4E16C1E00A009DE44C /* gl_font.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gl_font.c; sourceTree = ""; }; 96AFAF4F16C1E00A009DE44C /* gl_font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gl_font.h; sourceTree = ""; }; 96AFAF5016C1E00A009DE44C /* gl_raster_font.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gl_raster_font.c; sourceTree = ""; }; - 96AFAF5116C1E00A009DE44C /* ps_libdbgfont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps_libdbgfont.c; sourceTree = ""; }; - 96AFAF5216C1E00A009DE44C /* xdk1_xfonts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdk1_xfonts.c; sourceTree = ""; }; - 96AFAF5316C1E00A009DE44C /* xdk360_fonts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xdk360_fonts.cpp; sourceTree = ""; }; 96AFAF5416C1E00A009DE44C /* gfx_common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gfx_common.c; sourceTree = ""; }; 96AFAF5516C1E00A009DE44C /* gfx_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gfx_common.h; sourceTree = ""; }; 96AFAF5616C1E00A009DE44C /* gfx_context.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gfx_context.c; sourceTree = ""; }; @@ -254,13 +204,8 @@ 96AFAF5E16C1E00A009DE44C /* matrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = matrix.h; sourceTree = ""; }; 96AFAF5F16C1E00A009DE44C /* matrix_3x3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = matrix_3x3.c; sourceTree = ""; }; 96AFAF6016C1E00A009DE44C /* matrix_3x3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = matrix_3x3.h; sourceTree = ""; }; - 96AFAF6116C1E00A009DE44C /* null.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = null.c; sourceTree = ""; }; - 96AFAF6316C1E00A009DE44C /* py_state.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = py_state.c; sourceTree = ""; }; - 96AFAF6416C1E00A009DE44C /* py_state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = py_state.h; sourceTree = ""; }; - 96AFAF6616C1E00A009DE44C /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; 96AFAF6716C1E00A009DE44C /* rpng.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpng.c; sourceTree = ""; }; 96AFAF6816C1E00A009DE44C /* rpng.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rpng.h; sourceTree = ""; }; - 96AFAF6916C1E00A009DE44C /* rpng_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpng_test.c; sourceTree = ""; }; 96AFAF6B16C1E00A009DE44C /* filter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = filter.c; sourceTree = ""; }; 96AFAF6C16C1E00A009DE44C /* filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = filter.h; sourceTree = ""; }; 96AFAF6D16C1E00A009DE44C /* pixconv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pixconv.c; sourceTree = ""; }; @@ -269,29 +214,15 @@ 96AFAF7016C1E00A009DE44C /* scaler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scaler.h; sourceTree = ""; }; 96AFAF7116C1E00A009DE44C /* scaler_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = scaler_int.c; sourceTree = ""; }; 96AFAF7216C1E00A009DE44C /* scaler_int.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scaler_int.h; sourceTree = ""; }; - 96AFAF7316C1E00A009DE44C /* sdl_gfx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_gfx.c; sourceTree = ""; }; - 96AFAF7416C1E00A009DE44C /* shader_cg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = shader_cg.c; sourceTree = ""; }; - 96AFAF7516C1E00A009DE44C /* shader_cg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shader_cg.h; sourceTree = ""; }; 96AFAF7616C1E00A009DE44C /* shader_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shader_common.h; sourceTree = ""; }; 96AFAF7716C1E00A009DE44C /* shader_glsl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = shader_glsl.c; sourceTree = ""; }; 96AFAF7816C1E00A009DE44C /* shader_glsl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shader_glsl.h; sourceTree = ""; }; - 96AFAF7916C1E00A009DE44C /* shader_hlsl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = shader_hlsl.c; sourceTree = ""; }; - 96AFAF7A16C1E00A009DE44C /* shader_hlsl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shader_hlsl.h; sourceTree = ""; }; 96AFAF7B16C1E00A009DE44C /* state_tracker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = state_tracker.c; sourceTree = ""; }; 96AFAF7C16C1E00A009DE44C /* state_tracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = state_tracker.h; sourceTree = ""; }; - 96AFAF7D16C1E00A009DE44C /* vg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vg.c; sourceTree = ""; }; - 96AFAF7E16C1E00A009DE44C /* xvideo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xvideo.c; sourceTree = ""; }; - 96AFAFC816C1FBC0009DE44C /* dinput.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dinput.c; sourceTree = ""; }; 96AFAFC916C1FBC0009DE44C /* input_common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = input_common.c; sourceTree = ""; }; 96AFAFCA16C1FBC0009DE44C /* input_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = input_common.h; sourceTree = ""; }; - 96AFAFCB16C1FBC0009DE44C /* linuxraw_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = linuxraw_input.c; sourceTree = ""; }; - 96AFAFCC16C1FBC0009DE44C /* linuxraw_joypad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = linuxraw_joypad.c; sourceTree = ""; }; - 96AFAFCD16C1FBC0009DE44C /* null.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = null.c; sourceTree = ""; }; 96AFAFCE16C1FBC0009DE44C /* overlay.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = overlay.c; sourceTree = ""; }; 96AFAFCF16C1FBC0009DE44C /* overlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = overlay.h; sourceTree = ""; }; - 96AFAFD016C1FBC0009DE44C /* sdl_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_input.c; sourceTree = ""; }; - 96AFAFD116C1FBC0009DE44C /* sdl_joypad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_joypad.c; sourceTree = ""; }; - 96AFAFD216C1FBC0009DE44C /* x11_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x11_input.c; sourceTree = ""; }; 96CF015B16C2F72900ABF9C9 /* ios_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ios_input.c; sourceTree = ""; }; /* End PBXFileReference section */ @@ -319,8 +250,8 @@ children = ( 963F5ABC16CC522F009BBD19 /* RAButtonGetter.m */, 963F5ABD16CC522F009BBD19 /* RASettingEnumerationList.m */, - 963F5ABE16CC522F009BBD19 /* RASettingsSubList.m */, 963F5ABF16CC522F009BBD19 /* RASettingsList.m */, + 963F5ABE16CC522F009BBD19 /* RASettingsSubList.m */, 96366C7216CAF62200D64A22 /* settings.h */, ); path = settings; @@ -367,18 +298,16 @@ 96AFAE3316C1D4EA009DE44C /* RetroArch */ = { isa = PBXGroup; children = ( - 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */, - 963F5AC416CC523B009BBD19 /* RADirectoryList.m */, - 963F5AC516CC523B009BBD19 /* RAGameView.m */, - 963F5AC616CC523B009BBD19 /* RAModuleList.m */, 96366C6F16CAF62200D64A22 /* settings */, - 96297A0D16C5ADDA00E6DCE0 /* views.h */, - 96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */, - 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */, - 96AFAE4C16C1D4EA009DE44C /* ViewController_iPhone.xib */, - 96AFAE4F16C1D4EA009DE44C /* ViewController_iPad.xib */, 96AFAE3416C1D4EA009DE44C /* Supporting Files */, 96CF015B16C2F72900ABF9C9 /* ios_input.c */, + 963F5AC416CC523B009BBD19 /* RADirectoryList.m */, + 963F5AC516CC523B009BBD19 /* RAGameView.m */, + 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */, + 963F5AC616CC523B009BBD19 /* RAModuleList.m */, + 96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */, + 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */, + 96297A0D16C5ADDA00E6DCE0 /* views.h */, ); path = RetroArch; sourceTree = ""; @@ -386,13 +315,13 @@ 96AFAE3416C1D4EA009DE44C /* Supporting Files */ = { isa = PBXGroup; children = ( - 96297A0E16C5AEA100E6DCE0 /* main.m */, - 96AFAE3516C1D4EA009DE44C /* RetroArch-Info.plist */, - 96AFAE3616C1D4EA009DE44C /* InfoPlist.strings */, - 96AFAE3B16C1D4EA009DE44C /* RetroArch-Prefix.pch */, + 96AFAE4316C1D4EA009DE44C /* Default-568h@2x.png */, 96AFAE3F16C1D4EA009DE44C /* Default.png */, 96AFAE4116C1D4EA009DE44C /* Default@2x.png */, - 96AFAE4316C1D4EA009DE44C /* Default-568h@2x.png */, + 96AFAE3616C1D4EA009DE44C /* InfoPlist.strings */, + 96297A0E16C5AEA100E6DCE0 /* main.m */, + 96AFAE3516C1D4EA009DE44C /* RetroArch-Info.plist */, + 96AFAE3B16C1D4EA009DE44C /* RetroArch-Prefix.pch */, ); name = "Supporting Files"; sourceTree = ""; @@ -400,11 +329,11 @@ 96AFAE9C16C1D976009DE44C /* core */ = { isa = PBXGroup; children = ( - 96AFAFC716C1FBB3009DE44C /* input */, - 96AFAF3116C1E00A009DE44C /* gfx */, - 96AFAF2316C1DFC8009DE44C /* compat */, 96AFAEE516C1DC73009DE44C /* audio */, + 96AFAF2316C1DFC8009DE44C /* compat */, 96AFAEE016C1DBDB009DE44C /* conf */, + 96AFAF3116C1E00A009DE44C /* gfx */, + 96AFAFC716C1FBB3009DE44C /* input */, 96AFAE9D16C1D9A9009DE44C /* autosave.c */, 96AFAE9E16C1D9A9009DE44C /* autosave.h */, 96AFAE9F16C1D9A9009DE44C /* boolean.h */, @@ -414,18 +343,18 @@ 96AFAEA316C1D9A9009DE44C /* command.h */, 96AFAEA416C1D9A9009DE44C /* config.def.h */, 96AFAEA516C1D9A9009DE44C /* config.features.h */, - 96AFAEA616C1D9A9009DE44C /* driver_funcs.h */, 96AFAEA716C1D9A9009DE44C /* driver.c */, 96AFAEA816C1D9A9009DE44C /* driver.h */, + 96AFAEA616C1D9A9009DE44C /* driver_funcs.h */, 96AFAEA916C1D9A9009DE44C /* dynamic.c */, 96AFAEAA16C1D9A9009DE44C /* dynamic.h */, 96AFAEAB16C1D9A9009DE44C /* fifo_buffer.c */, 96AFAEAC16C1D9A9009DE44C /* fifo_buffer.h */, + 96AFAEB016C1D9A9009DE44C /* file.c */, + 96AFAEB116C1D9A9009DE44C /* file.h */, 96AFAEAD16C1D9A9009DE44C /* file_extract.c */, 96AFAEAE16C1D9A9009DE44C /* file_extract.h */, 96AFAEAF16C1D9A9009DE44C /* file_path.c */, - 96AFAEB016C1D9A9009DE44C /* file.c */, - 96AFAEB116C1D9A9009DE44C /* file.h */, 96AFAEB216C1D9A9009DE44C /* general.h */, 96AFAEB316C1D9A9009DE44C /* hash.c */, 96AFAEB416C1D9A9009DE44C /* hash.h */, @@ -434,15 +363,14 @@ 96AFAEB716C1D9A9009DE44C /* message.h */, 96AFAEB816C1D9A9009DE44C /* movie.c */, 96AFAEB916C1D9A9009DE44C /* movie.h */, - 96AFAEBA16C1D9A9009DE44C /* netplay_compat.h */, - 96AFAEBB16C1D9A9009DE44C /* netplay.c */, 96AFAEBC16C1D9A9009DE44C /* netplay.h */, + 96AFAEBA16C1D9A9009DE44C /* netplay_compat.h */, 96AFAEBD16C1D9A9009DE44C /* patch.c */, 96AFAEBE16C1D9A9009DE44C /* patch.h */, 96AFAEBF16C1D9A9009DE44C /* performance.c */, 96AFAEC016C1D9A9009DE44C /* performance.h */, - 96AFAEC116C1D9A9009DE44C /* retroarch_logger.h */, 96AFAEC216C1D9A9009DE44C /* retroarch.c */, + 96AFAEC116C1D9A9009DE44C /* retroarch_logger.h */, 96AFAEC316C1D9A9009DE44C /* rewind.c */, 96AFAEC416C1D9A9009DE44C /* rewind.h */, 96AFAEC516C1D9A9009DE44C /* screenshot.c */, @@ -468,31 +396,16 @@ 96AFAEE516C1DC73009DE44C /* audio */ = { isa = PBXGroup; children = ( - 96366C4F16C9A4E100D64A22 /* resampler.c */, - 96AFAEE616C1DC73009DE44C /* alsa.c */, - 96AFAEE716C1DC73009DE44C /* alsathread.c */, - 96AFAEE816C1DC73009DE44C /* coreaudio.c */, - 96AFAEE916C1DC73009DE44C /* dsound.c */, 96AFAEEA16C1DC73009DE44C /* ext */, + 96AFAEE816C1DC73009DE44C /* coreaudio.c */, 96AFAEEC16C1DC73009DE44C /* hermite.c */, - 96AFAEED16C1DC73009DE44C /* jack.c */, - 96AFAEEE16C1DC73009DE44C /* null.c */, - 96AFAEEF16C1DC73009DE44C /* openal.c */, - 96AFAEF016C1DC73009DE44C /* opensl.c */, - 96AFAEF116C1DC73009DE44C /* oss.c */, - 96AFAEF216C1DC73009DE44C /* pulse.c */, + 96366C4F16C9A4E100D64A22 /* resampler.c */, 96AFAEF316C1DC73009DE44C /* resampler.h */, - 96AFAEF416C1DC73009DE44C /* roar.c */, - 96AFAEF516C1DC73009DE44C /* rsound.c */, - 96AFAEF616C1DC73009DE44C /* sdl_audio.c */, 96AFAEF716C1DC73009DE44C /* sinc.c */, 96AFAEF816C1DC73009DE44C /* sinc_neon.S */, - 96AFAEF916C1DC73009DE44C /* test */, 96AFAEFD16C1DC73009DE44C /* utils.c */, 96AFAEFE16C1DC73009DE44C /* utils.h */, 96AFAEFF16C1DC73009DE44C /* utils_neon.S */, - 96AFAF0016C1DC73009DE44C /* xaudio-c */, - 96AFAF0416C1DC73009DE44C /* xaudio.c */, ); name = audio; path = ../audio; @@ -506,33 +419,13 @@ path = ext; sourceTree = ""; }; - 96AFAEF916C1DC73009DE44C /* test */ = { - isa = PBXGroup; - children = ( - 96AFAEFA16C1DC73009DE44C /* main.c */, - 96AFAEFB16C1DC73009DE44C /* Makefile */, - 96AFAEFC16C1DC73009DE44C /* snr.c */, - ); - path = test; - sourceTree = ""; - }; - 96AFAF0016C1DC73009DE44C /* xaudio-c */ = { - isa = PBXGroup; - children = ( - 96AFAF0116C1DC73009DE44C /* xaudio-c.cpp */, - 96AFAF0216C1DC73009DE44C /* xaudio-c.h */, - 96AFAF0316C1DC73009DE44C /* xaudio.h */, - ); - path = "xaudio-c"; - sourceTree = ""; - }; 96AFAF2316C1DFC8009DE44C /* compat */ = { isa = PBXGroup; children = ( + 96AFAF2716C1DFC8009DE44C /* rxml */, 96AFAF2416C1DFC8009DE44C /* compat.c */, 96AFAF2516C1DFC8009DE44C /* getopt_rarch.h */, 96AFAF2616C1DFC8009DE44C /* posix_string.h */, - 96AFAF2716C1DFC8009DE44C /* rxml */, 96AFAF2C16C1DFC8009DE44C /* strl.h */, ); name = compat; @@ -542,10 +435,8 @@ 96AFAF2716C1DFC8009DE44C /* rxml */ = { isa = PBXGroup; children = ( - 96AFAF2816C1DFC8009DE44C /* Makefile */, 96AFAF2916C1DFC8009DE44C /* rxml.c */, 96AFAF2A16C1DFC8009DE44C /* rxml.h */, - 96AFAF2B16C1DFC8009DE44C /* rxml_test.c */, ); path = rxml; sourceTree = ""; @@ -554,8 +445,10 @@ isa = PBXGroup; children = ( 96AFAF3216C1E00A009DE44C /* context */, - 96AFAF3E16C1E00A009DE44C /* d3d9 */, 96AFAF4416C1E00A009DE44C /* fonts */, + 96AFAF5C16C1E00A009DE44C /* math */, + 96AFAF6516C1E00A009DE44C /* rpng */, + 96AFAF6A16C1E00A009DE44C /* scaler */, 96AFAF5416C1E00A009DE44C /* gfx_common.c */, 96AFAF5516C1E00A009DE44C /* gfx_common.h */, 96AFAF5616C1E00A009DE44C /* gfx_context.c */, @@ -564,23 +457,11 @@ 96AFAF5916C1E00A009DE44C /* gl_common.h */, 96AFAF5A16C1E00A009DE44C /* image.c */, 96AFAF5B16C1E00A009DE44C /* image.h */, - 96AFAF5C16C1E00A009DE44C /* math */, - 96AFAF6116C1E00A009DE44C /* null.c */, - 96AFAF6216C1E00A009DE44C /* py_state */, - 96AFAF6516C1E00A009DE44C /* rpng */, - 96AFAF6A16C1E00A009DE44C /* scaler */, - 96AFAF7316C1E00A009DE44C /* sdl_gfx.c */, - 96AFAF7416C1E00A009DE44C /* shader_cg.c */, - 96AFAF7516C1E00A009DE44C /* shader_cg.h */, 96AFAF7616C1E00A009DE44C /* shader_common.h */, 96AFAF7716C1E00A009DE44C /* shader_glsl.c */, 96AFAF7816C1E00A009DE44C /* shader_glsl.h */, - 96AFAF7916C1E00A009DE44C /* shader_hlsl.c */, - 96AFAF7A16C1E00A009DE44C /* shader_hlsl.h */, 96AFAF7B16C1E00A009DE44C /* state_tracker.c */, 96AFAF7C16C1E00A009DE44C /* state_tracker.h */, - 96AFAF7D16C1E00A009DE44C /* vg.c */, - 96AFAF7E16C1E00A009DE44C /* xvideo.c */, ); name = gfx; path = ../gfx; @@ -590,33 +471,10 @@ isa = PBXGroup; children = ( 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */, - 96AFAF3316C1E00A009DE44C /* androidegl_ctx.c */, - 96AFAF3416C1E00A009DE44C /* drm_egl_ctx.c */, - 96AFAF3516C1E00A009DE44C /* glx_ctx.c */, - 96AFAF3616C1E00A009DE44C /* ps3_ctx.c */, - 96AFAF3716C1E00A009DE44C /* sdl_ctx.c */, - 96AFAF3816C1E00A009DE44C /* vc_egl_ctx.c */, - 96AFAF3916C1E00A009DE44C /* wgl_ctx.c */, - 96AFAF3A16C1E00A009DE44C /* x11_common.c */, - 96AFAF3B16C1E00A009DE44C /* x11_common.h */, - 96AFAF3C16C1E00A009DE44C /* xdk_ctx.c */, - 96AFAF3D16C1E00A009DE44C /* xegl_ctx.c */, ); path = context; sourceTree = ""; }; - 96AFAF3E16C1E00A009DE44C /* d3d9 */ = { - isa = PBXGroup; - children = ( - 96AFAF3F16C1E00A009DE44C /* config_file.hpp */, - 96AFAF4016C1E00A009DE44C /* d3d9.cpp */, - 96AFAF4116C1E00A009DE44C /* d3d9.hpp */, - 96AFAF4216C1E00A009DE44C /* render_chain.cpp */, - 96AFAF4316C1E00A009DE44C /* render_chain.hpp */, - ); - path = d3d9; - sourceTree = ""; - }; 96AFAF4416C1E00A009DE44C /* fonts */ = { isa = PBXGroup; children = ( @@ -624,17 +482,12 @@ 96AFAF4616C1E00A009DE44C /* bitmap.bmp */, 96AFAF4716C1E00A009DE44C /* bitmap.h */, 96AFAF4816C1E00A009DE44C /* bitmapfont.c */, - 96AFAF4916C1E00A009DE44C /* d3d_font.c */, - 96AFAF4A16C1E00A009DE44C /* d3d_font.h */, 96AFAF4B16C1E00A009DE44C /* fonts.c */, 96AFAF4C16C1E00A009DE44C /* fonts.h */, 96AFAF4D16C1E00A009DE44C /* freetype.c */, 96AFAF4E16C1E00A009DE44C /* gl_font.c */, 96AFAF4F16C1E00A009DE44C /* gl_font.h */, 96AFAF5016C1E00A009DE44C /* gl_raster_font.c */, - 96AFAF5116C1E00A009DE44C /* ps_libdbgfont.c */, - 96AFAF5216C1E00A009DE44C /* xdk1_xfonts.c */, - 96AFAF5316C1E00A009DE44C /* xdk360_fonts.cpp */, ); path = fonts; sourceTree = ""; @@ -650,22 +503,11 @@ path = math; sourceTree = ""; }; - 96AFAF6216C1E00A009DE44C /* py_state */ = { - isa = PBXGroup; - children = ( - 96AFAF6316C1E00A009DE44C /* py_state.c */, - 96AFAF6416C1E00A009DE44C /* py_state.h */, - ); - path = py_state; - sourceTree = ""; - }; 96AFAF6516C1E00A009DE44C /* rpng */ = { isa = PBXGroup; children = ( - 96AFAF6616C1E00A009DE44C /* Makefile */, 96AFAF6716C1E00A009DE44C /* rpng.c */, 96AFAF6816C1E00A009DE44C /* rpng.h */, - 96AFAF6916C1E00A009DE44C /* rpng_test.c */, ); path = rpng; sourceTree = ""; @@ -688,17 +530,10 @@ 96AFAFC716C1FBB3009DE44C /* input */ = { isa = PBXGroup; children = ( - 96AFAFC816C1FBC0009DE44C /* dinput.c */, 96AFAFC916C1FBC0009DE44C /* input_common.c */, - 96AFAFCB16C1FBC0009DE44C /* linuxraw_input.c */, 96AFAFCA16C1FBC0009DE44C /* input_common.h */, - 96AFAFCC16C1FBC0009DE44C /* linuxraw_joypad.c */, - 96AFAFCD16C1FBC0009DE44C /* null.c */, 96AFAFCE16C1FBC0009DE44C /* overlay.c */, 96AFAFCF16C1FBC0009DE44C /* overlay.h */, - 96AFAFD016C1FBC0009DE44C /* sdl_input.c */, - 96AFAFD116C1FBC0009DE44C /* sdl_joypad.c */, - 96AFAFD216C1FBC0009DE44C /* x11_input.c */, ); name = input; path = ../input; @@ -760,8 +595,6 @@ 96AFAE4016C1D4EA009DE44C /* Default.png in Resources */, 96AFAE4216C1D4EA009DE44C /* Default@2x.png in Resources */, 96AFAE4416C1D4EA009DE44C /* Default-568h@2x.png in Resources */, - 96AFAE4E16C1D4EA009DE44C /* ViewController_iPhone.xib in Resources */, - 96AFAE5116C1D4EA009DE44C /* ViewController_iPad.xib in Resources */, 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */, 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */, 96297A2416C818FF00E6DCE0 /* Icon-72.png in Resources */, @@ -796,7 +629,6 @@ 96AFAEDC16C1D9A9009DE44C /* settings.c in Sources */, 96AFAEDD16C1D9A9009DE44C /* thread.c in Sources */, 96AFAEE416C1DBDB009DE44C /* config_file.c in Sources */, - 96AFAF0B16C1DC73009DE44C /* null.c in Sources */, 96AFAF1816C1DC73009DE44C /* utils.c in Sources */, 96AFAF2D16C1DFC8009DE44C /* compat.c in Sources */, 96AFAF2F16C1DFC8009DE44C /* rxml.c in Sources */, @@ -810,7 +642,6 @@ 96AFAF9916C1E00A009DE44C /* image.c in Sources */, 96AFAF9A16C1E00A009DE44C /* matrix.c in Sources */, 96AFAF9B16C1E00A009DE44C /* matrix_3x3.c in Sources */, - 96AFAF9C16C1E00A009DE44C /* null.c in Sources */, 96AFAF9F16C1E00A009DE44C /* rpng.c in Sources */, 96AFAFA116C1E00A009DE44C /* filter.c in Sources */, 96AFAFA216C1E00A009DE44C /* pixconv.c in Sources */, @@ -820,7 +651,6 @@ 96AFAFAC16C1E279009DE44C /* state_tracker.c in Sources */, 96AFAFAD16C1EEE9009DE44C /* sinc.c in Sources */, 96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */, - 96AFAFD716C1FBC0009DE44C /* null.c in Sources */, 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */, 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */, 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */, @@ -851,22 +681,6 @@ name = InfoPlist.strings; sourceTree = ""; }; - 96AFAE4C16C1D4EA009DE44C /* ViewController_iPhone.xib */ = { - isa = PBXVariantGroup; - children = ( - 96AFAE4D16C1D4EA009DE44C /* en */, - ); - name = ViewController_iPhone.xib; - sourceTree = ""; - }; - 96AFAE4F16C1D4EA009DE44C /* ViewController_iPad.xib */ = { - isa = PBXVariantGroup; - children = ( - 96AFAE5016C1D4EA009DE44C /* en */, - ); - name = ViewController_iPad.xib; - sourceTree = ""; - }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ diff --git a/ios/RetroArch/en.lproj/ViewController_iPad.xib b/ios/RetroArch/en.lproj/ViewController_iPad.xib deleted file mode 100644 index 103cc68cb7..0000000000 --- a/ios/RetroArch/en.lproj/ViewController_iPad.xib +++ /dev/null @@ -1,112 +0,0 @@ - - - - 1536 - 12A206j - 2519 - 1172.1 - 613.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1856 - - - IBProxyObject - IBUIView - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBIPadFramework - - - IBFirstResponder - IBIPadFramework - - - - 274 - {{0, 20}, {768, 1004}} - - - - - 3 - MQA - - 2 - - - - 2 - - IBIPadFramework - - - - - - - view - - - - 3 - - - - - - 0 - - - - - - 1 - - - - - -1 - - - File's Owner - - - -2 - - - - - - - ViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - GLKView - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 3 - - - 0 - IBIPadFramework - YES - 3 - YES - 1856 - - diff --git a/ios/RetroArch/en.lproj/ViewController_iPhone.xib b/ios/RetroArch/en.lproj/ViewController_iPhone.xib deleted file mode 100644 index 6b89ba8f0a..0000000000 --- a/ios/RetroArch/en.lproj/ViewController_iPhone.xib +++ /dev/null @@ -1,127 +0,0 @@ - - - - 1536 - 12A269 - 2835 - 1187 - 624.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1919 - - - IBProxyObject - IBUIView - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - {320, 568} - - - - - 3 - MQA - - 2 - - - NO - - IBUIScreenMetrics - - YES - - - - - - {320, 568} - {568, 320} - - - IBCocoaTouchFramework - Retina 4 Full Screen - 2 - - IBCocoaTouchFramework - - - - - - - view - - - - 3 - - - - - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 2 - - - - - - - ViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - GLKView - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 4 - - - 0 - IBCocoaTouchFramework - YES - 3 - YES - 1919 - - From 2daa926cc117b74591fa73f22d5cae45524ad42f Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 18 Feb 2013 19:09:35 -0500 Subject: [PATCH 061/108] ios: Allow directories to be filtered by regex stored in a '.rafilter' file in the directory. --- ios/RetroArch.xcodeproj/project.pbxproj | 4 ++ ios/RetroArch/RADirectoryFilterList.m | 80 +++++++++++++++++++++++++ ios/RetroArch/RADirectoryList.m | 35 ++++++++++- ios/RetroArch/RAModuleList.m | 14 +---- ios/RetroArch/RetroArch_iOS.h | 2 + ios/RetroArch/RetroArch_iOS.m | 10 ++++ ios/RetroArch/views.h | 7 ++- 7 files changed, 137 insertions(+), 15 deletions(-) create mode 100644 ios/RetroArch/RADirectoryFilterList.m diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 692bf771cd..3ae59b4e56 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -80,6 +80,7 @@ 96AFAFAC16C1E279009DE44C /* state_tracker.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF7B16C1E00A009DE44C /* state_tracker.c */; }; 96AFAFAD16C1EEE9009DE44C /* sinc.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEF716C1DC73009DE44C /* sinc.c */; }; 96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFC916C1FBC0009DE44C /* input_common.c */; }; + 96C19C2216D2F3BA00FE8D5A /* RADirectoryFilterList.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2116D2F3BA00FE8D5A /* RADirectoryFilterList.m */; }; 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCE16C1FBC0009DE44C /* overlay.c */; }; 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CF015B16C2F72900ABF9C9 /* ios_input.c */; }; /* End PBXBuildFile section */ @@ -223,6 +224,7 @@ 96AFAFCA16C1FBC0009DE44C /* input_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = input_common.h; sourceTree = ""; }; 96AFAFCE16C1FBC0009DE44C /* overlay.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = overlay.c; sourceTree = ""; }; 96AFAFCF16C1FBC0009DE44C /* overlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = overlay.h; sourceTree = ""; }; + 96C19C2116D2F3BA00FE8D5A /* RADirectoryFilterList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RADirectoryFilterList.m; sourceTree = ""; }; 96CF015B16C2F72900ABF9C9 /* ios_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ios_input.c; sourceTree = ""; }; /* End PBXFileReference section */ @@ -301,6 +303,7 @@ 96366C6F16CAF62200D64A22 /* settings */, 96AFAE3416C1D4EA009DE44C /* Supporting Files */, 96CF015B16C2F72900ABF9C9 /* ios_input.c */, + 96C19C2116D2F3BA00FE8D5A /* RADirectoryFilterList.m */, 963F5AC416CC523B009BBD19 /* RADirectoryList.m */, 963F5AC516CC523B009BBD19 /* RAGameView.m */, 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */, @@ -667,6 +670,7 @@ 963F5AC816CC523B009BBD19 /* RAGameView.m in Sources */, 963F5AC916CC523B009BBD19 /* RAModuleList.m in Sources */, 96096DD816D1ABAF00BF4499 /* RAModuleInfoList.m in Sources */, + 96C19C2216D2F3BA00FE8D5A /* RADirectoryFilterList.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/RADirectoryFilterList.m b/ios/RetroArch/RADirectoryFilterList.m new file mode 100644 index 0000000000..0e9bf15f27 --- /dev/null +++ b/ios/RetroArch/RADirectoryFilterList.m @@ -0,0 +1,80 @@ +// +// dirlist.m +// RetroArch +// +// Created by Jason Fetters on 2/7/13. +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +@implementation RADirectoryFilterList +{ + NSString* _path; + + config_file_t* _filterList; + unsigned _filterCount; +} + +- (id)initWithPath:(NSString*)path +{ + self = [super initWithStyle:UITableViewStylePlain]; + + _path = path; + _filterList = config_file_new([[path stringByAppendingPathComponent:@".rafilter"] UTF8String]); + + if (!_filterList || !config_get_uint(_filterList, "filter_count", &_filterCount) || _filterCount == 0) + { + [RetroArch_iOS displayErrorMessage:@"No valid filters were found."]; + } + + [self setTitle: [path lastPathComponent]]; + + return self; +} + +- (void)dealloc +{ + if (_filterList) + config_file_free(_filterList); +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (_filterList) + { + NSString* regexKey = [NSString stringWithFormat:@"filter_%d_regex", indexPath.row + 1]; + + char* regex = 0; + if (config_get_string(_filterList, [regexKey UTF8String], ®ex)) + { + NSRegularExpression* expr = [NSRegularExpression regularExpressionWithPattern:[NSString stringWithUTF8String:regex] options:0 error:nil]; + free(regex); + + [[RetroArch_iOS get] pushViewController:[[RADirectoryList alloc] initWithPath:_path filter:expr]]; + } + } +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return _filterCount; +} + +- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + NSString* nameKey = [NSString stringWithFormat:@"filter_%d_name", indexPath.row + 1]; + + char* nameString = 0; + if (_filterList && config_get_string(_filterList, [nameKey UTF8String], &nameString)) + { + nameKey = [NSString stringWithUTF8String:nameString]; + free(nameString); + } + + UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"filter"]; + cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"filter"]; + cell.textLabel.text = nameKey; + + return cell; +} + +@end diff --git a/ios/RetroArch/RADirectoryList.m b/ios/RetroArch/RADirectoryList.m index 6f59db41a5..dc4751d7fb 100644 --- a/ios/RetroArch/RADirectoryList.m +++ b/ios/RetroArch/RADirectoryList.m @@ -6,6 +6,11 @@ // Copyright (c) 2013 RetroArch. All rights reserved. // +static BOOL is_file(NSString* path) +{ + return [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:nil]; +} + static BOOL is_directory(NSString* path) { BOOL result = NO; @@ -19,7 +24,22 @@ static BOOL is_directory(NSString* path) NSArray* _list; } -- (id)initWithPath:(NSString*)path ++ (id)directoryListWithPath:(NSString*)path +{ + if (path && !is_directory(path)) + { + [RetroArch_iOS displayErrorMessage:@"Browsed path is not a directory."]; + path = nil; + } + + if (path && is_file([path stringByAppendingPathComponent:@".rafilter"])) + return [[RADirectoryFilterList alloc] initWithPath:path]; + else + return [[RADirectoryList alloc] initWithPath:path filter:nil]; + +} + +- (id)initWithPath:(NSString*)path filter:(NSRegularExpression*)regex { self = [super initWithStyle:UITableViewStylePlain]; @@ -35,6 +55,17 @@ static BOOL is_directory(NSString* path) _list = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:_path error:nil]; _list = [_path stringsByAppendingPaths:_list]; + if (regex) + { + _list = [_list filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^(id object, NSDictionary* bindings) + { + if (is_directory(object)) + return YES; + + return (BOOL)([regex numberOfMatchesInString:[object lastPathComponent] options:0 range:NSMakeRange(0, [[object lastPathComponent] length])] != 0); + }]]; + } + _list = [_list sortedArrayUsingComparator:^(id left, id right) { const BOOL left_is_dir = is_directory((NSString*)left); @@ -57,7 +88,7 @@ static BOOL is_directory(NSString* path) if(is_directory(path)) { - [[RetroArch_iOS get] pushViewController:[[RADirectoryList alloc] initWithPath:path]]; + [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:path]]; } else { diff --git a/ios/RetroArch/RAModuleList.m b/ios/RetroArch/RAModuleList.m index ccc784335c..c28e8c9c18 100644 --- a/ios/RetroArch/RAModuleList.m +++ b/ios/RetroArch/RAModuleList.m @@ -6,16 +6,6 @@ // Copyright (c) 2013 RetroArch. All rights reserved. // -static void display_error_alert(NSString* message) -{ - UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"RetroArch" - message:message - delegate:nil - cancelButtonTitle:@"OK" - otherButtonTitles:nil]; - [alert show]; -} - @implementation RAModuleList { NSMutableArray* _modules; @@ -38,7 +28,7 @@ static void display_error_alert(NSString* message) if (moduleList == nil || [moduleList count] == 0) { - display_error_alert(@"No libretro cores were found."); + [RetroArch_iOS displayErrorMessage:@"No libretro cores were found."]; } // Load the modules with their data @@ -62,7 +52,7 @@ static void display_error_alert(NSString* message) RAModuleInfo* info = (RAModuleInfo*)[_modules objectAtIndex:indexPath.row]; [RetroArch_iOS get].module_path = info.path; - [[RetroArch_iOS get] pushViewController:[[RADirectoryList alloc] initWithPath:nil]]; + [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:nil]]; } - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index 6281a0014f..015155725b 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -12,6 +12,8 @@ extern NSString* const GSEventKeyUpNotification; @interface RetroArch_iOS : UIResponder ++ (void)displayErrorMessage:(NSString*)message; + + (RetroArch_iOS*)get; - (void)runGame:(NSString*)path; - (void)gameHasExited; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index ba9b859d43..7c80bfdee6 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -27,6 +27,16 @@ extern uint32_t ios_current_touch_count; UINavigationController* _navigator; } ++ (void)displayErrorMessage:(NSString*)message +{ + UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"RetroArch" + message:message + delegate:nil + cancelButtonTitle:@"OK" + otherButtonTitles:nil]; + [alert show]; +} + + (RetroArch_iOS*)get { return (RetroArch_iOS*)[[UIApplication sharedApplication] delegate]; diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index ff8a6c5270..0469354ea9 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -20,10 +20,15 @@ @interface RAModuleList : UITableViewController @end -@interface RADirectoryList : UITableViewController +@interface RADirectoryFilterList : UITableViewController - (id)initWithPath:(NSString*)path; @end +@interface RADirectoryList : UITableViewController ++ (id)directoryListWithPath:(NSString*)path; +- (id)initWithPath:(NSString*)path filter:(NSRegularExpression*)regex; +@end + @interface RASettingsSubList : UITableViewController - (id)initWithSettings:(NSArray*)values title:(NSString*)title; - (void)writeSettings:(NSArray*)settingList toConfig:(config_file_t*)config; From b8f0c35833f98a25e3d31747b56d72d71e9b0fee Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 19 Feb 2013 20:14:25 -0500 Subject: [PATCH 062/108] ios: Add coverart support (iOS 6+ only). --- ios/RetroArch.xcodeproj/project.pbxproj | 22 ++++- ios/RetroArch/RADirectoryFilterList.m | 4 +- ios/RetroArch/RADirectoryGrid.m | 120 ++++++++++++++++++++++++ ios/RetroArch/RADirectoryList.m | 59 +++++++----- ios/RetroArch/browser.h | 10 ++ ios/RetroArch/views.h | 5 +- 6 files changed, 191 insertions(+), 29 deletions(-) create mode 100644 ios/RetroArch/RADirectoryGrid.m create mode 100644 ios/RetroArch/browser.h diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 3ae59b4e56..e7e64056fa 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -81,6 +81,7 @@ 96AFAFAD16C1EEE9009DE44C /* sinc.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEF716C1DC73009DE44C /* sinc.c */; }; 96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFC916C1FBC0009DE44C /* input_common.c */; }; 96C19C2216D2F3BA00FE8D5A /* RADirectoryFilterList.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2116D2F3BA00FE8D5A /* RADirectoryFilterList.m */; }; + 96C19C2416D453BA00FE8D5A /* RADirectoryGrid.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2316D453BA00FE8D5A /* RADirectoryGrid.m */; }; 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCE16C1FBC0009DE44C /* overlay.c */; }; 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CF015B16C2F72900ABF9C9 /* ios_input.c */; }; /* End PBXBuildFile section */ @@ -225,6 +226,9 @@ 96AFAFCE16C1FBC0009DE44C /* overlay.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = overlay.c; sourceTree = ""; }; 96AFAFCF16C1FBC0009DE44C /* overlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = overlay.h; sourceTree = ""; }; 96C19C2116D2F3BA00FE8D5A /* RADirectoryFilterList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RADirectoryFilterList.m; sourceTree = ""; }; + 96C19C2316D453BA00FE8D5A /* RADirectoryGrid.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RADirectoryGrid.m; sourceTree = ""; }; + 96C19C2516D455BE00FE8D5A /* browser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = browser.h; sourceTree = ""; }; + 96C19C2616D455BE00FE8D5A /* rarch_wrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rarch_wrapper.h; sourceTree = ""; }; 96CF015B16C2F72900ABF9C9 /* ios_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ios_input.c; sourceTree = ""; }; /* End PBXFileReference section */ @@ -300,14 +304,14 @@ 96AFAE3316C1D4EA009DE44C /* RetroArch */ = { isa = PBXGroup; children = ( + 96C19C2716D455C600FE8D5A /* Browser */, 96366C6F16CAF62200D64A22 /* settings */, 96AFAE3416C1D4EA009DE44C /* Supporting Files */, 96CF015B16C2F72900ABF9C9 /* ios_input.c */, - 96C19C2116D2F3BA00FE8D5A /* RADirectoryFilterList.m */, - 963F5AC416CC523B009BBD19 /* RADirectoryList.m */, 963F5AC516CC523B009BBD19 /* RAGameView.m */, 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */, 963F5AC616CC523B009BBD19 /* RAModuleList.m */, + 96C19C2616D455BE00FE8D5A /* rarch_wrapper.h */, 96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */, 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */, 96297A0D16C5ADDA00E6DCE0 /* views.h */, @@ -542,6 +546,17 @@ path = ../input; sourceTree = ""; }; + 96C19C2716D455C600FE8D5A /* Browser */ = { + isa = PBXGroup; + children = ( + 96C19C2516D455BE00FE8D5A /* browser.h */, + 96C19C2116D2F3BA00FE8D5A /* RADirectoryFilterList.m */, + 96C19C2316D453BA00FE8D5A /* RADirectoryGrid.m */, + 963F5AC416CC523B009BBD19 /* RADirectoryList.m */, + ); + name = Browser; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -671,6 +686,7 @@ 963F5AC916CC523B009BBD19 /* RAModuleList.m in Sources */, 96096DD816D1ABAF00BF4499 /* RAModuleInfoList.m in Sources */, 96C19C2216D2F3BA00FE8D5A /* RADirectoryFilterList.m in Sources */, + 96C19C2416D453BA00FE8D5A /* RADirectoryGrid.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -788,6 +804,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "RetroArch/RetroArch-Prefix.pch"; INFOPLIST_FILE = "RetroArch/RetroArch-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"", @@ -823,6 +840,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "RetroArch/RetroArch-Prefix.pch"; INFOPLIST_FILE = "RetroArch/RetroArch-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"", diff --git a/ios/RetroArch/RADirectoryFilterList.m b/ios/RetroArch/RADirectoryFilterList.m index 0e9bf15f27..13c133f6bb 100644 --- a/ios/RetroArch/RADirectoryFilterList.m +++ b/ios/RetroArch/RADirectoryFilterList.m @@ -6,6 +6,8 @@ // Copyright (c) 2013 RetroArch. All rights reserved. // +#import "browser.h" + @implementation RADirectoryFilterList { NSString* _path; @@ -49,7 +51,7 @@ NSRegularExpression* expr = [NSRegularExpression regularExpressionWithPattern:[NSString stringWithUTF8String:regex] options:0 error:nil]; free(regex); - [[RetroArch_iOS get] pushViewController:[[RADirectoryList alloc] initWithPath:_path filter:expr]]; + [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:_path filter:expr]]; } } } diff --git a/ios/RetroArch/RADirectoryGrid.m b/ios/RetroArch/RADirectoryGrid.m new file mode 100644 index 0000000000..63fff44843 --- /dev/null +++ b/ios/RetroArch/RADirectoryGrid.m @@ -0,0 +1,120 @@ +// +// dirlist.m +// RetroArch +// +// Created by Jason Fetters on 2/7/13. +// Copyright (c) 2013 RetroArch. All rights reserved. +// + +#import "browser.h" + +@implementation RADirectoryGrid +{ + NSString* _path; + NSArray* _list; + + UIImage* _templateImage; +} + +- (id)initWithPath:(NSString*)path filter:(NSRegularExpression*)regex +{ + UICollectionViewFlowLayout* layout = [UICollectionViewFlowLayout new]; + layout.itemSize = CGSizeMake(175, 248); + self = [super initWithCollectionViewLayout:layout]; + + if (path == nil) + { + if (ra_ios_is_directory(@"/var/mobile/RetroArchGames")) path = @"/var/mobile/RetroArchGames"; + else if (ra_ios_is_directory(@"/var/mobile")) path = @"/var/mobile"; + else path = @"/"; + } + + _path = path; + + NSString* templateName = [NSString stringWithFormat:@"%@/.coverart/template.png", _path]; + _templateImage = [UIImage imageWithContentsOfFile:templateName]; + + if (!_templateImage) + { + [RetroArch_iOS displayErrorMessage:@"Coverart template.png is missing."]; + _templateImage = [RetroArch_iOS get].file_icon; + } + + _list = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:_path error:nil]; + _list = [_path stringsByAppendingPaths:_list]; + + if (regex) + { + _list = [_list filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^(id object, NSDictionary* bindings) + { + if (ra_ios_is_directory(object)) + return YES; + + return (BOOL)([regex numberOfMatchesInString:[object lastPathComponent] options:0 range:NSMakeRange(0, [[object lastPathComponent] length])] != 0); + }]]; + } + + _list = [_list sortedArrayUsingComparator:^(id left, id right) + { + const BOOL left_is_dir = ra_ios_is_directory((NSString*)left); + const BOOL right_is_dir = ra_ios_is_directory((NSString*)right); + + return (left_is_dir != right_is_dir) ? + (left_is_dir ? -1 : 1) : + ([left caseInsensitiveCompare:right]); + }]; + + self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; + [self setTitle: [_path lastPathComponent]]; + + [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"filecell"]; + + return self; +} + +- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView +{ + return 1; +} + +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section +{ + return [_list count]; +} + + +- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath +{ + NSString* path = [_list objectAtIndex: indexPath.row]; + + if(ra_ios_is_directory(path)) + { + [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:path]]; + } + else + { + [[RetroArch_iOS get] runGame:path]; + } +} + +- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath +{ + NSString* path = [_list objectAtIndex: indexPath.row]; + BOOL isdir = ra_ios_is_directory(path); + + UICollectionViewCell* cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"filecell" forIndexPath:indexPath]; + if (isdir) + cell.backgroundView = [[UIImageView alloc] initWithImage:[RetroArch_iOS get].folder_icon]; + else + { + NSString* img = [NSString stringWithFormat:@"%@/.coverart/%@.png", _path, [[path lastPathComponent] stringByDeletingPathExtension]]; + if (ra_ios_is_file(img)) + cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:img]]; + else + cell.backgroundView = [[UIImageView alloc] initWithImage:_templateImage]; + } + + return cell; +} + +@end diff --git a/ios/RetroArch/RADirectoryList.m b/ios/RetroArch/RADirectoryList.m index dc4751d7fb..604d8cb817 100644 --- a/ios/RetroArch/RADirectoryList.m +++ b/ios/RetroArch/RADirectoryList.m @@ -6,18 +6,31 @@ // Copyright (c) 2013 RetroArch. All rights reserved. // -static BOOL is_file(NSString* path) +#import "browser.h" + +BOOL ra_ios_is_file(NSString* path) { return [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:nil]; } -static BOOL is_directory(NSString* path) +BOOL ra_ios_is_directory(NSString* path) { BOOL result = NO; [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&result]; return result; } +static NSString* check_path(NSString* path) +{ + if (path && !ra_ios_is_directory(path)) + { + [RetroArch_iOS displayErrorMessage:@"Browsed path is not a directory."]; + return nil; + } + else + return path; +} + @implementation RADirectoryList { NSString* _path; @@ -26,17 +39,23 @@ static BOOL is_directory(NSString* path) + (id)directoryListWithPath:(NSString*)path { - if (path && !is_directory(path)) - { - [RetroArch_iOS displayErrorMessage:@"Browsed path is not a directory."]; - path = nil; - } + path = check_path(path); - if (path && is_file([path stringByAppendingPathComponent:@".rafilter"])) + if (path && ra_ios_is_file([path stringByAppendingPathComponent:@".rafilter"])) return [[RADirectoryFilterList alloc] initWithPath:path]; else - return [[RADirectoryList alloc] initWithPath:path filter:nil]; - + return [RADirectoryList directoryListWithPath:path filter:nil]; +} + ++ (id)directoryListWithPath:(NSString*)path filter:(NSRegularExpression*)regex +{ + path = check_path(path); + + NSString* coverDir = path ? [path stringByAppendingPathComponent:@".coverart"] : nil; + if (coverDir && ra_ios_is_directory(coverDir) && ra_ios_is_file([coverDir stringByAppendingPathComponent:@"template.png"])) + return [[RADirectoryGrid alloc] initWithPath:path filter:regex]; + else + return [[RADirectoryList alloc] initWithPath:path filter:regex]; } - (id)initWithPath:(NSString*)path filter:(NSRegularExpression*)regex @@ -45,9 +64,9 @@ static BOOL is_directory(NSString* path) if (path == nil) { - if (is_directory(@"/var/mobile/RetroArchGames")) path = @"/var/mobile/RetroArchGames"; - else if (is_directory(@"/var/mobile")) path = @"/var/mobile"; - else path = @"/"; + if (ra_ios_is_directory(@"/var/mobile/RetroArchGames")) path = @"/var/mobile/RetroArchGames"; + else if (ra_ios_is_directory(@"/var/mobile")) path = @"/var/mobile"; + else path = @"/"; } _path = path; @@ -59,7 +78,7 @@ static BOOL is_directory(NSString* path) { _list = [_list filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^(id object, NSDictionary* bindings) { - if (is_directory(object)) + if (ra_ios_is_directory(object)) return YES; return (BOOL)([regex numberOfMatchesInString:[object lastPathComponent] options:0 range:NSMakeRange(0, [[object lastPathComponent] length])] != 0); @@ -68,8 +87,8 @@ static BOOL is_directory(NSString* path) _list = [_list sortedArrayUsingComparator:^(id left, id right) { - const BOOL left_is_dir = is_directory((NSString*)left); - const BOOL right_is_dir = is_directory((NSString*)right); + const BOOL left_is_dir = ra_ios_is_directory((NSString*)left); + const BOOL right_is_dir = ra_ios_is_directory((NSString*)right); return (left_is_dir != right_is_dir) ? (left_is_dir ? -1 : 1) : @@ -86,14 +105,10 @@ static BOOL is_directory(NSString* path) { NSString* path = [_list objectAtIndex: indexPath.row]; - if(is_directory(path)) - { + if(ra_ios_is_directory(path)) [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:path]]; - } else - { [[RetroArch_iOS get] runGame:path]; - } } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section @@ -104,7 +119,7 @@ static BOOL is_directory(NSString* path) - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString* path = [_list objectAtIndex: indexPath.row]; - BOOL isdir = is_directory(path); + BOOL isdir = ra_ios_is_directory(path); UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"path"]; cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"path"]; diff --git a/ios/RetroArch/browser.h b/ios/RetroArch/browser.h new file mode 100644 index 0000000000..9f3697fbb8 --- /dev/null +++ b/ios/RetroArch/browser.h @@ -0,0 +1,10 @@ +extern BOOL ra_ios_is_directory(NSString* path); +extern BOOL ra_ios_is_file(NSString* path); + +@interface RADirectoryGrid : UICollectionViewController +- (id)initWithPath:(NSString*)path filter:(NSRegularExpression*)regex; +@end + +@interface RADirectoryFilterList : UITableViewController +- (id)initWithPath:(NSString*)path; +@end diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index 0469354ea9..897dc8d6fb 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -20,12 +20,9 @@ @interface RAModuleList : UITableViewController @end -@interface RADirectoryFilterList : UITableViewController -- (id)initWithPath:(NSString*)path; -@end - @interface RADirectoryList : UITableViewController + (id)directoryListWithPath:(NSString*)path; ++ (id)directoryListWithPath:(NSString*)path filter:(NSRegularExpression*)regex; - (id)initWithPath:(NSString*)path filter:(NSRegularExpression*)regex; @end From 192f7d56d71d6befcbc467e1a1c36ff1e3f54fd9 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 19 Feb 2013 20:33:36 -0500 Subject: [PATCH 063/108] ios: If a .rafilter file has a single filter it is applied automatically. --- ios/RetroArch/RADirectoryFilterList.m | 40 +++++++++++++++++++++++---- ios/RetroArch/RADirectoryList.m | 8 +++--- ios/RetroArch/browser.h | 4 +++ 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/ios/RetroArch/RADirectoryFilterList.m b/ios/RetroArch/RADirectoryFilterList.m index 13c133f6bb..3afad84303 100644 --- a/ios/RetroArch/RADirectoryFilterList.m +++ b/ios/RetroArch/RADirectoryFilterList.m @@ -16,23 +16,51 @@ unsigned _filterCount; } -- (id)initWithPath:(NSString*)path ++ (RADirectoryFilterList*) directoryFilterListAtPath:(NSString*)path useExpression:(NSRegularExpression**)regex +{ + if (regex) + *regex = nil; + + if (path && ra_ios_is_file([path stringByAppendingPathComponent:@".rafilter"])) + { + config_file_t* configFile = config_file_new([[path stringByAppendingPathComponent:@".rafilter"] UTF8String]); + + unsigned filterCount = 0; + char* regexValue= 0; + + if (configFile && config_get_uint(configFile, "filter_count", &filterCount) && filterCount > 1) + return [[RADirectoryFilterList alloc] initWithPath:path config:configFile]; + else if (regex && filterCount == 1 && config_get_string(configFile, "filter_1_regex", ®exValue)) + *regex = [NSRegularExpression regularExpressionWithPattern:[NSString stringWithUTF8String:regexValue] options:0 error:nil]; + + free(regexValue); + } + + return nil; +} + +- (id)initWithPath:(NSString*)path config:(config_file_t*)config { self = [super initWithStyle:UITableViewStylePlain]; - + _path = path; - _filterList = config_file_new([[path stringByAppendingPathComponent:@".rafilter"] UTF8String]); - + _filterList = config; + if (!_filterList || !config_get_uint(_filterList, "filter_count", &_filterCount) || _filterCount == 0) { [RetroArch_iOS displayErrorMessage:@"No valid filters were found."]; } - + [self setTitle: [path lastPathComponent]]; - + return self; } +- (id)initWithPath:(NSString*)path +{ + return [self initWithPath:path config:config_file_new([[path stringByAppendingPathComponent:@".rafilter"] UTF8String])]; +} + - (void)dealloc { if (_filterList) diff --git a/ios/RetroArch/RADirectoryList.m b/ios/RetroArch/RADirectoryList.m index 604d8cb817..d04c52686a 100644 --- a/ios/RetroArch/RADirectoryList.m +++ b/ios/RetroArch/RADirectoryList.m @@ -41,10 +41,10 @@ static NSString* check_path(NSString* path) { path = check_path(path); - if (path && ra_ios_is_file([path stringByAppendingPathComponent:@".rafilter"])) - return [[RADirectoryFilterList alloc] initWithPath:path]; - else - return [RADirectoryList directoryListWithPath:path filter:nil]; + NSRegularExpression* expr = nil; + RADirectoryFilterList* filterList = [RADirectoryFilterList directoryFilterListAtPath:path useExpression:&expr]; + + return filterList ? filterList : [RADirectoryList directoryListWithPath:path filter:expr]; } + (id)directoryListWithPath:(NSString*)path filter:(NSRegularExpression*)regex diff --git a/ios/RetroArch/browser.h b/ios/RetroArch/browser.h index 9f3697fbb8..464897108d 100644 --- a/ios/RetroArch/browser.h +++ b/ios/RetroArch/browser.h @@ -6,5 +6,9 @@ extern BOOL ra_ios_is_file(NSString* path); @end @interface RADirectoryFilterList : UITableViewController +// Check path to see if a directory filter list is needed. +// If one is not needed useExpression will be set to a default expression to use. ++ (RADirectoryFilterList*) directoryFilterListAtPath:(NSString*)path useExpression:(NSRegularExpression**)regex; + - (id)initWithPath:(NSString*)path; @end From 9ac77f65d15c44e06f25264eb98095c52ca7cab5 Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 20 Feb 2013 19:45:51 -0500 Subject: [PATCH 064/108] ios: Refactor browser code some. --- ios/RetroArch.xcodeproj/project.pbxproj | 4 +++ ios/RetroArch/RADirectoryGrid.m | 47 +++++-------------------- ios/RetroArch/RADirectoryList.m | 46 ++---------------------- ios/RetroArch/browser.h | 2 ++ ios/RetroArch/browser.m | 47 +++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 83 deletions(-) create mode 100644 ios/RetroArch/browser.m diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index e7e64056fa..3c3b249c0e 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -82,6 +82,7 @@ 96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFC916C1FBC0009DE44C /* input_common.c */; }; 96C19C2216D2F3BA00FE8D5A /* RADirectoryFilterList.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2116D2F3BA00FE8D5A /* RADirectoryFilterList.m */; }; 96C19C2416D453BA00FE8D5A /* RADirectoryGrid.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2316D453BA00FE8D5A /* RADirectoryGrid.m */; }; + 96C19C2916D5A56500FE8D5A /* browser.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2816D5A56400FE8D5A /* browser.m */; }; 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCE16C1FBC0009DE44C /* overlay.c */; }; 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CF015B16C2F72900ABF9C9 /* ios_input.c */; }; /* End PBXBuildFile section */ @@ -229,6 +230,7 @@ 96C19C2316D453BA00FE8D5A /* RADirectoryGrid.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RADirectoryGrid.m; sourceTree = ""; }; 96C19C2516D455BE00FE8D5A /* browser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = browser.h; sourceTree = ""; }; 96C19C2616D455BE00FE8D5A /* rarch_wrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rarch_wrapper.h; sourceTree = ""; }; + 96C19C2816D5A56400FE8D5A /* browser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = browser.m; sourceTree = ""; }; 96CF015B16C2F72900ABF9C9 /* ios_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ios_input.c; sourceTree = ""; }; /* End PBXFileReference section */ @@ -550,6 +552,7 @@ isa = PBXGroup; children = ( 96C19C2516D455BE00FE8D5A /* browser.h */, + 96C19C2816D5A56400FE8D5A /* browser.m */, 96C19C2116D2F3BA00FE8D5A /* RADirectoryFilterList.m */, 96C19C2316D453BA00FE8D5A /* RADirectoryGrid.m */, 963F5AC416CC523B009BBD19 /* RADirectoryList.m */, @@ -687,6 +690,7 @@ 96096DD816D1ABAF00BF4499 /* RAModuleInfoList.m in Sources */, 96C19C2216D2F3BA00FE8D5A /* RADirectoryFilterList.m in Sources */, 96C19C2416D453BA00FE8D5A /* RADirectoryGrid.m in Sources */, + 96C19C2916D5A56500FE8D5A /* browser.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/RADirectoryGrid.m b/ios/RetroArch/RADirectoryGrid.m index 63fff44843..1bd0403d3d 100644 --- a/ios/RetroArch/RADirectoryGrid.m +++ b/ios/RetroArch/RADirectoryGrid.m @@ -18,19 +18,9 @@ - (id)initWithPath:(NSString*)path filter:(NSRegularExpression*)regex { - UICollectionViewFlowLayout* layout = [UICollectionViewFlowLayout new]; - layout.itemSize = CGSizeMake(175, 248); - self = [super initWithCollectionViewLayout:layout]; - - if (path == nil) - { - if (ra_ios_is_directory(@"/var/mobile/RetroArchGames")) path = @"/var/mobile/RetroArchGames"; - else if (ra_ios_is_directory(@"/var/mobile")) path = @"/var/mobile"; - else path = @"/"; - } - - _path = path; + _path = path ? path : ra_ios_get_browser_root(); + // Load template image NSString* templateName = [NSString stringWithFormat:@"%@/.coverart/template.png", _path]; _templateImage = [UIImage imageWithContentsOfFile:templateName]; @@ -40,29 +30,12 @@ _templateImage = [RetroArch_iOS get].file_icon; } - _list = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:_path error:nil]; - _list = [_path stringsByAppendingPaths:_list]; - - if (regex) - { - _list = [_list filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^(id object, NSDictionary* bindings) - { - if (ra_ios_is_directory(object)) - return YES; - - return (BOOL)([regex numberOfMatchesInString:[object lastPathComponent] options:0 range:NSMakeRange(0, [[object lastPathComponent] length])] != 0); - }]]; - } - - _list = [_list sortedArrayUsingComparator:^(id left, id right) - { - const BOOL left_is_dir = ra_ios_is_directory((NSString*)left); - const BOOL right_is_dir = ra_ios_is_directory((NSString*)right); - - return (left_is_dir != right_is_dir) ? - (left_is_dir ? -1 : 1) : - ([left caseInsensitiveCompare:right]); - }]; + // + UICollectionViewFlowLayout* layout = [UICollectionViewFlowLayout new]; + layout.itemSize = _templateImage.size; + self = [super initWithCollectionViewLayout:layout]; + + _list = ra_ios_list_directory(_path, regex); self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; [self setTitle: [_path lastPathComponent]]; @@ -88,13 +61,9 @@ NSString* path = [_list objectAtIndex: indexPath.row]; if(ra_ios_is_directory(path)) - { [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:path]]; - } else - { [[RetroArch_iOS get] runGame:path]; - } } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath diff --git a/ios/RetroArch/RADirectoryList.m b/ios/RetroArch/RADirectoryList.m index d04c52686a..439d0e58b9 100644 --- a/ios/RetroArch/RADirectoryList.m +++ b/ios/RetroArch/RADirectoryList.m @@ -8,18 +8,6 @@ #import "browser.h" -BOOL ra_ios_is_file(NSString* path) -{ - return [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:nil]; -} - -BOOL ra_ios_is_directory(NSString* path) -{ - BOOL result = NO; - [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&result]; - return result; -} - static NSString* check_path(NSString* path) { if (path && !ra_ios_is_directory(path)) @@ -62,38 +50,8 @@ static NSString* check_path(NSString* path) { self = [super initWithStyle:UITableViewStylePlain]; - if (path == nil) - { - if (ra_ios_is_directory(@"/var/mobile/RetroArchGames")) path = @"/var/mobile/RetroArchGames"; - else if (ra_ios_is_directory(@"/var/mobile")) path = @"/var/mobile"; - else path = @"/"; - } - - _path = path; - - _list = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:_path error:nil]; - _list = [_path stringsByAppendingPaths:_list]; - - if (regex) - { - _list = [_list filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^(id object, NSDictionary* bindings) - { - if (ra_ios_is_directory(object)) - return YES; - - return (BOOL)([regex numberOfMatchesInString:[object lastPathComponent] options:0 range:NSMakeRange(0, [[object lastPathComponent] length])] != 0); - }]]; - } - - _list = [_list sortedArrayUsingComparator:^(id left, id right) - { - const BOOL left_is_dir = ra_ios_is_directory((NSString*)left); - const BOOL right_is_dir = ra_ios_is_directory((NSString*)right); - - return (left_is_dir != right_is_dir) ? - (left_is_dir ? -1 : 1) : - ([left caseInsensitiveCompare:right]); - }]; + _path = path ? path : ra_ios_get_browser_root(); + _list = ra_ios_list_directory(_path, regex); self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; [self setTitle: [_path lastPathComponent]]; diff --git a/ios/RetroArch/browser.h b/ios/RetroArch/browser.h index 464897108d..d2f648e199 100644 --- a/ios/RetroArch/browser.h +++ b/ios/RetroArch/browser.h @@ -1,5 +1,7 @@ extern BOOL ra_ios_is_directory(NSString* path); extern BOOL ra_ios_is_file(NSString* path); +extern NSArray* ra_ios_list_directory(NSString* path, NSRegularExpression* regex); +extern NSString* ra_ios_get_browser_root(); @interface RADirectoryGrid : UICollectionViewController - (id)initWithPath:(NSString*)path filter:(NSRegularExpression*)regex; diff --git a/ios/RetroArch/browser.m b/ios/RetroArch/browser.m new file mode 100644 index 0000000000..71f11fddf9 --- /dev/null +++ b/ios/RetroArch/browser.m @@ -0,0 +1,47 @@ +BOOL ra_ios_is_file(NSString* path) +{ + return [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:nil]; +} + +BOOL ra_ios_is_directory(NSString* path) +{ + BOOL result = NO; + [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&result]; + return result; +} + +NSArray* ra_ios_list_directory(NSString* path, NSRegularExpression* regex) +{ + NSArray* result = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil]; + result = [path stringsByAppendingPaths:result]; + + if (regex) + { + result = [result filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^(id object, NSDictionary* bindings) + { + if (ra_ios_is_directory(object)) + return YES; + + return (BOOL)([regex numberOfMatchesInString:[object lastPathComponent] options:0 range:NSMakeRange(0, [[object lastPathComponent] length])] != 0); + }]]; + } + + result = [result sortedArrayUsingComparator:^(id left, id right) + { + const BOOL left_is_dir = ra_ios_is_directory((NSString*)left); + const BOOL right_is_dir = ra_ios_is_directory((NSString*)right); + + return (left_is_dir != right_is_dir) ? + (left_is_dir ? -1 : 1) : + ([left caseInsensitiveCompare:right]); + }]; + + return result; +} + +NSString* ra_ios_get_browser_root() +{ + if (ra_ios_is_directory(@"/var/mobile/RetroArchGames")) return @"/var/mobile/RetroArchGames"; + else if (ra_ios_is_directory(@"/var/mobile")) return @"/var/mobile"; + else return @"/"; +} From 1edd531544ed7a7f22959fa889d94e2172ac8a77 Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 20 Feb 2013 19:52:52 -0500 Subject: [PATCH 065/108] ios: Add proper license header to all files. --- gfx/context/ioseagl_ctx.c | 3 +-- ios/RetroArch/RADirectoryFilterList.m | 21 ++++++++++++------ ios/RetroArch/RADirectoryList.m | 21 ++++++++++++------ ios/RetroArch/RAGameView.m | 3 +-- ios/RetroArch/RAModuleInfoList.m | 22 ++++++++++++------- ios/RetroArch/RAModuleList.m | 21 ++++++++++++------ ios/RetroArch/RetroArch_iOS.h | 20 ++++++++++++----- ios/RetroArch/RetroArch_iOS.m | 20 ++++++++++++----- ios/RetroArch/browser.h | 15 +++++++++++++ ios/RetroArch/browser.m | 15 +++++++++++++ ios/RetroArch/ios_input.c | 4 +--- ios/RetroArch/main.m | 20 ++++++++++++----- ios/RetroArch/rarch_wrapper.h | 15 +++++++++++++ ios/RetroArch/settings/RAButtonGetter.m | 21 ++++++++++++------ .../settings/RASettingEnumerationList.m | 21 ++++++++++++------ ios/RetroArch/settings/RASettingsList.m | 21 ++++++++++++------ ios/RetroArch/settings/RASettingsSubList.m | 21 ++++++++++++------ ios/RetroArch/settings/settings.h | 21 ++++++++++++------ ios/RetroArch/views.h | 15 +++++++++++++ 19 files changed, 231 insertions(+), 89 deletions(-) diff --git a/gfx/context/ioseagl_ctx.c b/gfx/context/ioseagl_ctx.c index 9c70e3b01f..1932e1e9d4 100644 --- a/gfx/context/ioseagl_ctx.c +++ b/gfx/context/ioseagl_ctx.c @@ -1,6 +1,5 @@ /* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2013 - Hans-Kristian Arntzen - * Copyright (C) 2011-2013 - Daniel De Matteis + * Copyright (C) 2013 - Jason Fetters * * RetroArch 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 Found- diff --git a/ios/RetroArch/RADirectoryFilterList.m b/ios/RetroArch/RADirectoryFilterList.m index 3afad84303..ef67dc4f29 100644 --- a/ios/RetroArch/RADirectoryFilterList.m +++ b/ios/RetroArch/RADirectoryFilterList.m @@ -1,10 +1,17 @@ -// -// dirlist.m -// RetroArch -// -// Created by Jason Fetters on 2/7/13. -// Copyright (c) 2013 RetroArch. All rights reserved. -// +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ #import "browser.h" diff --git a/ios/RetroArch/RADirectoryList.m b/ios/RetroArch/RADirectoryList.m index 439d0e58b9..9a82d214e7 100644 --- a/ios/RetroArch/RADirectoryList.m +++ b/ios/RetroArch/RADirectoryList.m @@ -1,10 +1,17 @@ -// -// dirlist.m -// RetroArch -// -// Created by Jason Fetters on 2/7/13. -// Copyright (c) 2013 RetroArch. All rights reserved. -// +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ #import "browser.h" diff --git a/ios/RetroArch/RAGameView.m b/ios/RetroArch/RAGameView.m index a30d8d1929..2f62be7087 100644 --- a/ios/RetroArch/RAGameView.m +++ b/ios/RetroArch/RAGameView.m @@ -1,6 +1,5 @@ /* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2013 - Hans-Kristian Arntzen - * Copyright (C) 2011-2013 - Daniel De Matteis + * Copyright (C) 2013 - Jason Fetters * * RetroArch 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 Found- diff --git a/ios/RetroArch/RAModuleInfoList.m b/ios/RetroArch/RAModuleInfoList.m index 5f3d05e52c..a268bfc119 100644 --- a/ios/RetroArch/RAModuleInfoList.m +++ b/ios/RetroArch/RAModuleInfoList.m @@ -1,11 +1,17 @@ -// -// module_list.m -// RetroArch -// -// Created by Jason Fetters on 2/8/13. -// Copyright (c) 2013 RetroArch. All rights reserved. -// - +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ @implementation RAModuleInfo + (RAModuleInfo*)moduleWithPath:(NSString*)thePath data:(config_file_t*)theData diff --git a/ios/RetroArch/RAModuleList.m b/ios/RetroArch/RAModuleList.m index c28e8c9c18..5a91db019f 100644 --- a/ios/RetroArch/RAModuleList.m +++ b/ios/RetroArch/RAModuleList.m @@ -1,10 +1,17 @@ -// -// module_list.m -// RetroArch -// -// Created by Jason Fetters on 2/8/13. -// Copyright (c) 2013 RetroArch. All rights reserved. -// +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ @implementation RAModuleList { diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index 015155725b..eec5fcedf5 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -1,9 +1,17 @@ -// -// AppDelegate.h -// RetroArch -// -// Copyright (c) 2013 RetroArch. All rights reserved. -// +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ #import diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 7c80bfdee6..b22ff1f94f 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -1,9 +1,17 @@ -// -// AppDelegate.m -// RetroArch -// -// Copyright (c) 2013 RetroArch. All rights reserved. -// +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ #include #include "rarch_wrapper.h" diff --git a/ios/RetroArch/browser.h b/ios/RetroArch/browser.h index d2f648e199..ea7b7b74d3 100644 --- a/ios/RetroArch/browser.h +++ b/ios/RetroArch/browser.h @@ -1,3 +1,18 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + extern BOOL ra_ios_is_directory(NSString* path); extern BOOL ra_ios_is_file(NSString* path); extern NSArray* ra_ios_list_directory(NSString* path, NSRegularExpression* regex); diff --git a/ios/RetroArch/browser.m b/ios/RetroArch/browser.m index 71f11fddf9..7785ec952d 100644 --- a/ios/RetroArch/browser.m +++ b/ios/RetroArch/browser.m @@ -1,3 +1,18 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + BOOL ra_ios_is_file(NSString* path) { return [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:nil]; diff --git a/ios/RetroArch/ios_input.c b/ios/RetroArch/ios_input.c index 528089cb4b..4fba92d606 100644 --- a/ios/RetroArch/ios_input.c +++ b/ios/RetroArch/ios_input.c @@ -1,7 +1,5 @@ -// Input Driver Below /* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2013 - Hans-Kristian Arntzen - * Copyright (C) 2011-2013 - Daniel De Matteis + * Copyright (C) 2013 - Jason Fetters * * RetroArch 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 Found- diff --git a/ios/RetroArch/main.m b/ios/RetroArch/main.m index 8ecd7e8bdb..2ba3cc50ca 100644 --- a/ios/RetroArch/main.m +++ b/ios/RetroArch/main.m @@ -1,9 +1,17 @@ -// -// main.m -// RetroArch -// -// Copyright (c) 2013 RetroArch. All rights reserved. -// +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ #import diff --git a/ios/RetroArch/rarch_wrapper.h b/ios/RetroArch/rarch_wrapper.h index 195c4eca01..ed2a31b571 100644 --- a/ios/RetroArch/rarch_wrapper.h +++ b/ios/RetroArch/rarch_wrapper.h @@ -1,3 +1,18 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + #ifndef __IOS_RARCH_WRAPPER_H__ #define __IOS_RARCH_WRAPPER_H__ diff --git a/ios/RetroArch/settings/RAButtonGetter.m b/ios/RetroArch/settings/RAButtonGetter.m index 5d174f2701..cf33276731 100644 --- a/ios/RetroArch/settings/RAButtonGetter.m +++ b/ios/RetroArch/settings/RAButtonGetter.m @@ -1,10 +1,17 @@ -// -// settings_list.m -// RetroArch -// -// Created by Jason Fetters on 2/8/13. -// Copyright (c) 2013 RetroArch. All rights reserved. -// +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ #import "settings.h" diff --git a/ios/RetroArch/settings/RASettingEnumerationList.m b/ios/RetroArch/settings/RASettingEnumerationList.m index 07fa33e2d3..accadfbb53 100644 --- a/ios/RetroArch/settings/RASettingEnumerationList.m +++ b/ios/RetroArch/settings/RASettingEnumerationList.m @@ -1,10 +1,17 @@ -// -// settings_list.m -// RetroArch -// -// Created by Jason Fetters on 2/8/13. -// Copyright (c) 2013 RetroArch. All rights reserved. -// +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ #import "settings.h" diff --git a/ios/RetroArch/settings/RASettingsList.m b/ios/RetroArch/settings/RASettingsList.m index c483360903..39159f50e7 100644 --- a/ios/RetroArch/settings/RASettingsList.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -1,10 +1,17 @@ -// -// settings_list.m -// RetroArch -// -// Created by Jason Fetters on 2/8/13. -// Copyright (c) 2013 RetroArch. All rights reserved. -// +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ #import #import "settings.h" diff --git a/ios/RetroArch/settings/RASettingsSubList.m b/ios/RetroArch/settings/RASettingsSubList.m index 92c573d7b6..d2cf91e266 100644 --- a/ios/RetroArch/settings/RASettingsSubList.m +++ b/ios/RetroArch/settings/RASettingsSubList.m @@ -1,10 +1,17 @@ -// -// settings_list.m -// RetroArch -// -// Created by Jason Fetters on 2/8/13. -// Copyright (c) 2013 RetroArch. All rights reserved. -// +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ #import #import "settings.h" diff --git a/ios/RetroArch/settings/settings.h b/ios/RetroArch/settings/settings.h index a5dfa4d751..c89d5f6226 100644 --- a/ios/RetroArch/settings/settings.h +++ b/ios/RetroArch/settings/settings.h @@ -1,10 +1,17 @@ -// -// settings_list.m -// RetroArch -// -// Created by Jason Fetters on 2/8/13. -// Copyright (c) 2013 RetroArch. All rights reserved. -// +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ #include "conf/config_file.h" diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index 897dc8d6fb..cf02798a75 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -1,3 +1,18 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + #import #import From b36ead4bf874e9e283fbbf5fc846a6771be8e0f3 Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 20 Feb 2013 20:10:44 -0500 Subject: [PATCH 066/108] ios: Disable cover-art views if UICollectionView is not available. --- ios/RetroArch.xcodeproj/project.pbxproj | 4 ++-- ios/RetroArch/RADirectoryList.m | 13 ++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 3c3b249c0e..d2b1116807 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -808,7 +808,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "RetroArch/RetroArch-Prefix.pch"; INFOPLIST_FILE = "RetroArch/RetroArch-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; + IPHONEOS_DEPLOYMENT_TARGET = 6.1; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"", @@ -844,7 +844,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "RetroArch/RetroArch-Prefix.pch"; INFOPLIST_FILE = "RetroArch/RetroArch-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; + IPHONEOS_DEPLOYMENT_TARGET = 6.1; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"", diff --git a/ios/RetroArch/RADirectoryList.m b/ios/RetroArch/RADirectoryList.m index 9a82d214e7..a25cb9c2d3 100644 --- a/ios/RetroArch/RADirectoryList.m +++ b/ios/RetroArch/RADirectoryList.m @@ -46,11 +46,14 @@ static NSString* check_path(NSString* path) { path = check_path(path); - NSString* coverDir = path ? [path stringByAppendingPathComponent:@".coverart"] : nil; - if (coverDir && ra_ios_is_directory(coverDir) && ra_ios_is_file([coverDir stringByAppendingPathComponent:@"template.png"])) - return [[RADirectoryGrid alloc] initWithPath:path filter:regex]; - else - return [[RADirectoryList alloc] initWithPath:path filter:regex]; + if ([UICollectionViewController instancesRespondToSelector:@selector(initWithCollectionViewLayout:)]) + { + NSString* coverDir = path ? [path stringByAppendingPathComponent:@".coverart"] : nil; + if (coverDir && ra_ios_is_directory(coverDir) && ra_ios_is_file([coverDir stringByAppendingPathComponent:@"template.png"])) + return [[RADirectoryGrid alloc] initWithPath:path filter:regex]; + } + + return [[RADirectoryList alloc] initWithPath:path filter:regex]; } - (id)initWithPath:(NSString*)path filter:(NSRegularExpression*)regex From cae85b7401466baf6acc8f790ae690b126eb92f5 Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 20 Feb 2013 23:30:56 -0500 Subject: [PATCH 067/108] ios: Have the list_directory use objects to cache properties about the items. Quite a bit faster too. --- ios/RetroArch/RADirectoryGrid.m | 15 +++---- ios/RetroArch/RADirectoryList.m | 17 ++++---- ios/RetroArch/browser.h | 5 +++ ios/RetroArch/browser.m | 77 +++++++++++++++++++++++++-------- 4 files changed, 78 insertions(+), 36 deletions(-) diff --git a/ios/RetroArch/RADirectoryGrid.m b/ios/RetroArch/RADirectoryGrid.m index 1bd0403d3d..6a6a7cca74 100644 --- a/ios/RetroArch/RADirectoryGrid.m +++ b/ios/RetroArch/RADirectoryGrid.m @@ -58,25 +58,24 @@ - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { - NSString* path = [_list objectAtIndex: indexPath.row]; + RADirectoryItem* path = [_list objectAtIndex: indexPath.row]; - if(ra_ios_is_directory(path)) - [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:path]]; + if(path.isDirectory) + [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:path.path]]; else - [[RetroArch_iOS get] runGame:path]; + [[RetroArch_iOS get] runGame:path.path]; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { - NSString* path = [_list objectAtIndex: indexPath.row]; - BOOL isdir = ra_ios_is_directory(path); + RADirectoryItem* path = [_list objectAtIndex: indexPath.row]; UICollectionViewCell* cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"filecell" forIndexPath:indexPath]; - if (isdir) + if (path.isDirectory) cell.backgroundView = [[UIImageView alloc] initWithImage:[RetroArch_iOS get].folder_icon]; else { - NSString* img = [NSString stringWithFormat:@"%@/.coverart/%@.png", _path, [[path lastPathComponent] stringByDeletingPathExtension]]; + NSString* img = [NSString stringWithFormat:@"%@/.coverart/%@.png", _path, [[path.path lastPathComponent] stringByDeletingPathExtension]]; if (ra_ios_is_file(img)) cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:img]]; else diff --git a/ios/RetroArch/RADirectoryList.m b/ios/RetroArch/RADirectoryList.m index a25cb9c2d3..adda1f5150 100644 --- a/ios/RetroArch/RADirectoryList.m +++ b/ios/RetroArch/RADirectoryList.m @@ -71,12 +71,12 @@ static NSString* check_path(NSString* path) - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - NSString* path = [_list objectAtIndex: indexPath.row]; + RADirectoryItem* path = [_list objectAtIndex: indexPath.row]; - if(ra_ios_is_directory(path)) - [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:path]]; + if(path.isDirectory) + [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:path.path]]; else - [[RetroArch_iOS get] runGame:path]; + [[RetroArch_iOS get] runGame:path.path]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section @@ -86,14 +86,13 @@ static NSString* check_path(NSString* path) - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - NSString* path = [_list objectAtIndex: indexPath.row]; - BOOL isdir = ra_ios_is_directory(path); + RADirectoryItem* path = [_list objectAtIndex: indexPath.row]; UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"path"]; cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"path"]; - cell.textLabel.text = [path lastPathComponent]; - cell.accessoryType = (isdir) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; - cell.imageView.image = (isdir) ? [RetroArch_iOS get].folder_icon : [RetroArch_iOS get].file_icon; + cell.textLabel.text = [path.path lastPathComponent]; + cell.accessoryType = (path.isDirectory) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; + cell.imageView.image = (path.isDirectory) ? [RetroArch_iOS get].folder_icon : [RetroArch_iOS get].file_icon; return cell; } diff --git a/ios/RetroArch/browser.h b/ios/RetroArch/browser.h index ea7b7b74d3..ce66c4c412 100644 --- a/ios/RetroArch/browser.h +++ b/ios/RetroArch/browser.h @@ -18,6 +18,11 @@ extern BOOL ra_ios_is_file(NSString* path); extern NSArray* ra_ios_list_directory(NSString* path, NSRegularExpression* regex); extern NSString* ra_ios_get_browser_root(); +@interface RADirectoryItem : NSObject +@property (strong) NSString* path; +@property bool isDirectory; +@end + @interface RADirectoryGrid : UICollectionViewController - (id)initWithPath:(NSString*)path filter:(NSRegularExpression*)regex; @end diff --git a/ios/RetroArch/browser.m b/ios/RetroArch/browser.m index 7785ec952d..3b39e1c4d0 100644 --- a/ios/RetroArch/browser.m +++ b/ios/RetroArch/browser.m @@ -13,6 +13,25 @@ * If not, see . */ +#include +#include +#import "browser.h" + +@implementation RADirectoryItem ++ (RADirectoryItem*)directoryItemFromPath:(const char*)thePath +{ + RADirectoryItem* result = [RADirectoryItem new]; + result.path = [NSString stringWithUTF8String:thePath]; + + struct stat statbuf; + if (stat(thePath, &statbuf) == 0) + result.isDirectory = S_ISDIR(statbuf.st_mode); + + return result; +} +@end + + BOOL ra_ios_is_file(NSString* path) { return [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:nil]; @@ -27,30 +46,50 @@ BOOL ra_ios_is_directory(NSString* path) NSArray* ra_ios_list_directory(NSString* path, NSRegularExpression* regex) { - NSArray* result = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil]; - result = [path stringsByAppendingPaths:result]; + NSMutableArray* result = [NSMutableArray array]; + + // Build list + char* cpath = malloc([path length] + sizeof(struct dirent)); + sprintf(cpath, "%s/", [path UTF8String]); + size_t cpath_end = strlen(cpath); + + DIR* dir = opendir(cpath); + if (!dir) + return result; - if (regex) + for(struct dirent* item = readdir(dir); item; item = readdir(dir)) { - result = [result filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^(id object, NSDictionary* bindings) - { - if (ra_ios_is_directory(object)) - return YES; - - return (BOOL)([regex numberOfMatchesInString:[object lastPathComponent] options:0 range:NSMakeRange(0, [[object lastPathComponent] length])] != 0); - }]]; + if (strcmp(item->d_name, ".") == 0 || strcmp(item->d_name, "..") == 0) + continue; + + cpath[cpath_end] = 0; + strcat(cpath, item->d_name); + + [result addObject:[RADirectoryItem directoryItemFromPath:cpath]]; } - result = [result sortedArrayUsingComparator:^(id left, id right) - { - const BOOL left_is_dir = ra_ios_is_directory((NSString*)left); - const BOOL right_is_dir = ra_ios_is_directory((NSString*)right); - - return (left_is_dir != right_is_dir) ? - (left_is_dir ? -1 : 1) : - ([left caseInsensitiveCompare:right]); - }]; + closedir(dir); + free(cpath); + // Filter and sort + if (regex) + { + [result filterUsingPredicate:[NSPredicate predicateWithBlock:^(RADirectoryItem* object, NSDictionary* bindings) + { + if (object.isDirectory) + return YES; + + return (BOOL)([regex numberOfMatchesInString:[object.path lastPathComponent] options:0 range:NSMakeRange(0, [[object.path lastPathComponent] length])] != 0); + }]]; + } + + [result sortUsingComparator:^(RADirectoryItem* left, RADirectoryItem* right) + { + return (left.isDirectory != right.isDirectory) ? + (left.isDirectory ? -1 : 1) : + ([left.path caseInsensitiveCompare:right.path]); + }]; + return result; } From 1212116dfb9989332e99891d9bbd4ff154a9a862 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 21 Feb 2013 01:30:28 -0500 Subject: [PATCH 068/108] ios: Some cover view improvements: Don't allocate new views when reusing a cell. If a file item doesn't have an attached image, its filename will be printed in the cell instead. Images maintain aspect ratio when scaled. --- ios/RetroArch/RADirectoryGrid.m | 46 ++++++++++++++++++++++++++------- ios/RetroArch/browser.h | 1 + ios/RetroArch/browser.m | 12 +++++++-- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/ios/RetroArch/RADirectoryGrid.m b/ios/RetroArch/RADirectoryGrid.m index 6a6a7cca74..e209323cd2 100644 --- a/ios/RetroArch/RADirectoryGrid.m +++ b/ios/RetroArch/RADirectoryGrid.m @@ -39,8 +39,10 @@ self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; [self setTitle: [_path lastPathComponent]]; - - [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"filecell"]; + + [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"dircell"]; + [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"textcell"]; + [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"imagecell"]; return self; } @@ -55,7 +57,6 @@ return [_list count]; } - - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { RADirectoryItem* path = [_list objectAtIndex: indexPath.row]; @@ -69,17 +70,42 @@ - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { RADirectoryItem* path = [_list objectAtIndex: indexPath.row]; + UICollectionViewCell* cell = nil; - UICollectionViewCell* cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"filecell" forIndexPath:indexPath]; if (path.isDirectory) - cell.backgroundView = [[UIImageView alloc] initWithImage:[RetroArch_iOS get].folder_icon]; + { + cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"dircell" forIndexPath:indexPath]; + + if (!cell.backgroundView) + { + cell.backgroundView = [[UIImageView alloc] initWithImage:[RetroArch_iOS get].folder_icon]; + ((UIImageView*)cell.backgroundView).contentMode = UIViewContentModeScaleAspectFit; + } + } + else if (path.coverPath) + { + cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"imagecell" forIndexPath:indexPath]; + + if (!cell.backgroundView) + { + cell.backgroundView = [UIImageView new]; + ((UIImageView*)cell.backgroundView).contentMode = UIViewContentModeScaleAspectFit; + } + + ((UIImageView*)cell.backgroundView).image = [UIImage imageWithContentsOfFile:path.coverPath]; + } else { - NSString* img = [NSString stringWithFormat:@"%@/.coverart/%@.png", _path, [[path.path lastPathComponent] stringByDeletingPathExtension]]; - if (ra_ios_is_file(img)) - cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:img]]; - else - cell.backgroundView = [[UIImageView alloc] initWithImage:_templateImage]; + cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"textcell" forIndexPath:indexPath]; + + if (!cell.backgroundView) + { + cell.backgroundView = [UILabel new]; + ((UILabel*)cell.backgroundView).numberOfLines = 0; + ((UILabel*)cell.backgroundView).textAlignment = NSTextAlignmentCenter; + } + + ((UILabel*)cell.backgroundView).text = [path.path lastPathComponent]; } return cell; diff --git a/ios/RetroArch/browser.h b/ios/RetroArch/browser.h index ce66c4c412..05bd932e38 100644 --- a/ios/RetroArch/browser.h +++ b/ios/RetroArch/browser.h @@ -20,6 +20,7 @@ extern NSString* ra_ios_get_browser_root(); @interface RADirectoryItem : NSObject @property (strong) NSString* path; +@property (strong) NSString* coverPath; @property bool isDirectory; @end diff --git a/ios/RetroArch/browser.m b/ios/RetroArch/browser.m index 3b39e1c4d0..dc096da460 100644 --- a/ios/RetroArch/browser.m +++ b/ios/RetroArch/browser.m @@ -18,7 +18,7 @@ #import "browser.h" @implementation RADirectoryItem -+ (RADirectoryItem*)directoryItemFromPath:(const char*)thePath ++ (RADirectoryItem*)directoryItemFromPath:(const char*)thePath checkForCovers:(BOOL)checkCovers { RADirectoryItem* result = [RADirectoryItem new]; result.path = [NSString stringWithUTF8String:thePath]; @@ -26,6 +26,14 @@ struct stat statbuf; if (stat(thePath, &statbuf) == 0) result.isDirectory = S_ISDIR(statbuf.st_mode); + + if (checkCovers && !result.isDirectory) + { + result.coverPath = [NSString stringWithFormat:@"%@/.coverart/%@.png", [result.path stringByDeletingLastPathComponent], [[result.path lastPathComponent] stringByDeletingPathExtension]]; + + if (!ra_ios_is_file(result.coverPath)) + result.coverPath = nil; + } return result; } @@ -65,7 +73,7 @@ NSArray* ra_ios_list_directory(NSString* path, NSRegularExpression* regex) cpath[cpath_end] = 0; strcat(cpath, item->d_name); - [result addObject:[RADirectoryItem directoryItemFromPath:cpath]]; + [result addObject:[RADirectoryItem directoryItemFromPath:cpath checkForCovers:YES]]; } closedir(dir); From 4a076f4717bc131f53489b69b9ad7466293077b6 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 21 Feb 2013 12:37:58 -0500 Subject: [PATCH 069/108] ios: Keep status bar visible while in the browser. Add a couple of missing license headers. --- ios/RetroArch/RADirectoryGrid.m | 21 ++++++++++++++------- ios/RetroArch/RetroArch-Info.plist | 6 +++--- ios/RetroArch/RetroArch-Prefix.pch | 15 +++++++++++++++ ios/RetroArch/RetroArch_iOS.m | 1 + 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/ios/RetroArch/RADirectoryGrid.m b/ios/RetroArch/RADirectoryGrid.m index e209323cd2..675d007d83 100644 --- a/ios/RetroArch/RADirectoryGrid.m +++ b/ios/RetroArch/RADirectoryGrid.m @@ -1,10 +1,17 @@ -// -// dirlist.m -// RetroArch -// -// Created by Jason Fetters on 2/7/13. -// Copyright (c) 2013 RetroArch. All rights reserved. -// +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ #import "browser.h" diff --git a/ios/RetroArch/RetroArch-Info.plist b/ios/RetroArch/RetroArch-Info.plist index 381fc886b6..2abe058713 100644 --- a/ios/RetroArch/RetroArch-Info.plist +++ b/ios/RetroArch/RetroArch-Info.plist @@ -24,20 +24,20 @@ 1.0 LSRequiresIPhoneOS + UIApplicationExitsOnSuspend + UIRequiredDeviceCapabilities armv7 UIStatusBarHidden - + UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - UIApplicationExitsOnSuspend - UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait diff --git a/ios/RetroArch/RetroArch-Prefix.pch b/ios/RetroArch/RetroArch-Prefix.pch index ce1bb8668a..a3670b9763 100644 --- a/ios/RetroArch/RetroArch-Prefix.pch +++ b/ios/RetroArch/RetroArch-Prefix.pch @@ -1,3 +1,18 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + // // Prefix header for all source files of the 'RetroArch' target in the 'RetroArch' project // diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index b22ff1f94f..ea0e438763 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -78,6 +78,7 @@ extern uint32_t ios_current_touch_count; - (void)setViewer:(UIViewController*)theView { _navigator = nil; + [[UIApplication sharedApplication] setStatusBarHidden:theView ? YES : NO withAnimation:UIStatusBarAnimationSlide]; _window.rootViewController = theView; } From 70d0ab91b7ba0d8d13c34594d2f8886a91117560 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 21 Feb 2013 15:37:51 -0500 Subject: [PATCH 070/108] ios: Fix .rafilter files not being closed in certain situations. --- ios/RetroArch/RADirectoryFilterList.m | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/ios/RetroArch/RADirectoryFilterList.m b/ios/RetroArch/RADirectoryFilterList.m index ef67dc4f29..5f9e96f5e4 100644 --- a/ios/RetroArch/RADirectoryFilterList.m +++ b/ios/RetroArch/RADirectoryFilterList.m @@ -32,15 +32,21 @@ { config_file_t* configFile = config_file_new([[path stringByAppendingPathComponent:@".rafilter"] UTF8String]); - unsigned filterCount = 0; - char* regexValue= 0; - - if (configFile && config_get_uint(configFile, "filter_count", &filterCount) && filterCount > 1) - return [[RADirectoryFilterList alloc] initWithPath:path config:configFile]; - else if (regex && filterCount == 1 && config_get_string(configFile, "filter_1_regex", ®exValue)) - *regex = [NSRegularExpression regularExpressionWithPattern:[NSString stringWithUTF8String:regexValue] options:0 error:nil]; - - free(regexValue); + if (configFile) + { + unsigned filterCount = 0; + if (configFile && config_get_uint(configFile, "filter_count", &filterCount) && filterCount > 1) + return [[RADirectoryFilterList alloc] initWithPath:path config:configFile]; + + char* regexValue = 0; + if (regex && filterCount == 1 && config_get_string(configFile, "filter_1_regex", ®exValue)) + { + *regex = [NSRegularExpression regularExpressionWithPattern:[NSString stringWithUTF8String:regexValue] options:0 error:nil]; + free(regexValue); + } + + config_file_free(configFile); + } } return nil; From 5a7cee4e6e03625be3c09cb302679905ffe2e768 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 21 Feb 2013 20:21:46 -0500 Subject: [PATCH 071/108] ios: Immediately hide the exit bar if the device is rotated (after rotation its size would be wrong.) Fix status bar not being visible when a new instance is started. --- ios/RetroArch/RAGameView.m | 6 ++++++ ios/RetroArch/RetroArch_iOS.m | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ios/RetroArch/RAGameView.m b/ios/RetroArch/RAGameView.m index 2f62be7087..1605a48736 100644 --- a/ios/RetroArch/RAGameView.m +++ b/ios/RetroArch/RAGameView.m @@ -82,6 +82,12 @@ static bool is_syncing = true; } } +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration +{ + _notifyButton.alpha = 0.0f; + _notifyLabel.alpha = 0.0f; +} + - (void)iterate { while (_isRunning && !_isPaused) diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index ea0e438763..2271b23247 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -78,7 +78,7 @@ extern uint32_t ios_current_touch_count; - (void)setViewer:(UIViewController*)theView { _navigator = nil; - [[UIApplication sharedApplication] setStatusBarHidden:theView ? YES : NO withAnimation:UIStatusBarAnimationSlide]; + [[UIApplication sharedApplication] setStatusBarHidden:theView ? YES : NO withAnimation:UIStatusBarAnimationNone]; _window.rootViewController = theView; } @@ -110,6 +110,8 @@ extern uint32_t ios_current_touch_count; self.settings_button.target = self; self.settings_button.action = @selector(show_settings); + [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone]; + // Setup window _navigator = [[UINavigationController alloc] init]; [_navigator pushViewController: [[RAModuleList alloc] init] animated:YES]; From b52aff0b8f83812d287d9a8e2dc91f0d9dbdf8d9 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 21 Feb 2013 20:33:05 -0500 Subject: [PATCH 072/108] ios: Use [UIImage imageNamed:] to load file and directory icons. --- ios/RetroArch/RetroArch_iOS.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 2271b23247..4e45931752 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -99,8 +99,8 @@ extern uint32_t ios_current_touch_count; mkdir([self.system_directory UTF8String], 0755); // Load icons - self.file_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_file" ofType:@"png"]]; - self.folder_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_dir" ofType:@"png"]]; + self.file_icon = [UIImage imageNamed:@"ic_file"]; + self.folder_icon = [UIImage imageNamed:@"ic_dir"]; // Load buttons self.settings_button = [[UIBarButtonItem alloc] From be3aa0a063ec0fc45b08a59c360c411876de9422 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 21 Feb 2013 22:16:18 -0500 Subject: [PATCH 073/108] ios: Create an objective-c wrapper around config_file_t, use it to simplify code. --- ios/RetroArch.xcodeproj/project.pbxproj | 6 ++ ios/RetroArch/RAConfig.h | 26 +++++++ ios/RetroArch/RAConfig.m | 89 ++++++++++++++++++++++ ios/RetroArch/RADirectoryFilterList.m | 77 ++++++------------- ios/RetroArch/RADirectoryGrid.m | 17 +---- ios/RetroArch/RADirectoryList.m | 2 +- ios/RetroArch/RAModuleInfoList.m | 25 +----- ios/RetroArch/RAModuleList.m | 2 +- ios/RetroArch/browser.h | 2 - ios/RetroArch/settings/RASettingsList.m | 41 +++------- ios/RetroArch/settings/RASettingsSubList.m | 8 +- ios/RetroArch/settings/settings.h | 2 - ios/RetroArch/views.h | 8 +- 13 files changed, 172 insertions(+), 133 deletions(-) create mode 100644 ios/RetroArch/RAConfig.h create mode 100644 ios/RetroArch/RAConfig.m diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index d2b1116807..fde3e42322 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -83,6 +83,7 @@ 96C19C2216D2F3BA00FE8D5A /* RADirectoryFilterList.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2116D2F3BA00FE8D5A /* RADirectoryFilterList.m */; }; 96C19C2416D453BA00FE8D5A /* RADirectoryGrid.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2316D453BA00FE8D5A /* RADirectoryGrid.m */; }; 96C19C2916D5A56500FE8D5A /* browser.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2816D5A56400FE8D5A /* browser.m */; }; + 96C19C3016D7045700FE8D5A /* RAConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2F16D7045700FE8D5A /* RAConfig.m */; }; 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCE16C1FBC0009DE44C /* overlay.c */; }; 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CF015B16C2F72900ABF9C9 /* ios_input.c */; }; /* End PBXBuildFile section */ @@ -231,6 +232,8 @@ 96C19C2516D455BE00FE8D5A /* browser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = browser.h; sourceTree = ""; }; 96C19C2616D455BE00FE8D5A /* rarch_wrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rarch_wrapper.h; sourceTree = ""; }; 96C19C2816D5A56400FE8D5A /* browser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = browser.m; sourceTree = ""; }; + 96C19C2E16D7045600FE8D5A /* RAConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RAConfig.h; sourceTree = ""; }; + 96C19C2F16D7045700FE8D5A /* RAConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAConfig.m; sourceTree = ""; }; 96CF015B16C2F72900ABF9C9 /* ios_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ios_input.c; sourceTree = ""; }; /* End PBXFileReference section */ @@ -310,6 +313,8 @@ 96366C6F16CAF62200D64A22 /* settings */, 96AFAE3416C1D4EA009DE44C /* Supporting Files */, 96CF015B16C2F72900ABF9C9 /* ios_input.c */, + 96C19C2E16D7045600FE8D5A /* RAConfig.h */, + 96C19C2F16D7045700FE8D5A /* RAConfig.m */, 963F5AC516CC523B009BBD19 /* RAGameView.m */, 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */, 963F5AC616CC523B009BBD19 /* RAModuleList.m */, @@ -691,6 +696,7 @@ 96C19C2216D2F3BA00FE8D5A /* RADirectoryFilterList.m in Sources */, 96C19C2416D453BA00FE8D5A /* RADirectoryGrid.m in Sources */, 96C19C2916D5A56500FE8D5A /* browser.m in Sources */, + 96C19C3016D7045700FE8D5A /* RAConfig.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/RAConfig.h b/ios/RetroArch/RAConfig.h new file mode 100644 index 0000000000..d3f0f41d92 --- /dev/null +++ b/ios/RetroArch/RAConfig.h @@ -0,0 +1,26 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +@interface RAConfig : NSObject +- (id)initWithPath:(NSString*)path; +- (void)writeToFile:(NSString*)path; + +- (int)getIntNamed:(NSString*)name withDefault:(int)def; +- (unsigned)getUintNamed:(NSString*)name withDefault:(unsigned)def; +- (NSString*)getStringNamed:(NSString*)name withDefault:(NSString*)def; + +- (void)putIntNamed:(NSString*)name value:(int)value; +- (void)putStringNamed:(NSString*)name value:(NSString*)value; +@end diff --git a/ios/RetroArch/RAConfig.m b/ios/RetroArch/RAConfig.m new file mode 100644 index 0000000000..1315144b87 --- /dev/null +++ b/ios/RetroArch/RAConfig.m @@ -0,0 +1,89 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#import "RAConfig.h" +#include "conf/config_file.h" + +@implementation RAConfig +{ + config_file_t* _config; +} + +- (id)initWithPath:(NSString*)path +{ + _config = config_file_new([path UTF8String]); + return self; +} + +- (void)dealloc +{ + if (_config) + config_file_free(_config); +} + +- (void)writeToFile:(NSString*)path +{ + if (_config) + config_file_write(_config, [path UTF8String]); +} + +- (int)getIntNamed:(NSString*)name withDefault:(int)def +{ + int result = def; + + if (_config) + config_get_int(_config, [name UTF8String], &result); + + return result; +} + +- (unsigned)getUintNamed:(NSString*)name withDefault:(unsigned)def +{ + unsigned result = def; + + if (_config) + config_get_uint(_config, [name UTF8String], &result); + + return result; +} + +- (NSString*)getStringNamed:(NSString*)name withDefault:(NSString*)def +{ + NSString* result = def; + + if (_config) + { + char* data = 0; + if (config_get_string(_config, [name UTF8String], &data)) + result = [NSString stringWithUTF8String:data]; + free(data); + } + + return result; +} + +- (void)putIntNamed:(NSString*)name value:(int)value +{ + if (_config) + config_set_int(_config, [name UTF8String], value); +} + +- (void)putStringNamed:(NSString*)name value:(NSString*)value +{ + if (_config) + config_set_string(_config, [name UTF8String], [value UTF8String]); +} + +@end diff --git a/ios/RetroArch/RADirectoryFilterList.m b/ios/RetroArch/RADirectoryFilterList.m index 5f9e96f5e4..d4838f4dad 100644 --- a/ios/RetroArch/RADirectoryFilterList.m +++ b/ios/RetroArch/RADirectoryFilterList.m @@ -13,13 +13,14 @@ * If not, see . */ +#import "RAConfig.h" #import "browser.h" @implementation RADirectoryFilterList { NSString* _path; - config_file_t* _filterList; + RAConfig* _filterList; unsigned _filterCount; } @@ -30,92 +31,60 @@ if (path && ra_ios_is_file([path stringByAppendingPathComponent:@".rafilter"])) { - config_file_t* configFile = config_file_new([[path stringByAppendingPathComponent:@".rafilter"] UTF8String]); + RAConfig* configFile = [[RAConfig alloc] initWithPath:[path stringByAppendingPathComponent:@".rafilter"]]; + unsigned filterCount = [configFile getUintNamed:@"filter_count" withDefault:0]; - if (configFile) + if (filterCount > 1) + return [[RADirectoryFilterList alloc] initWithPath:path config:configFile]; + + if (regex && filterCount == 1) { - unsigned filterCount = 0; - if (configFile && config_get_uint(configFile, "filter_count", &filterCount) && filterCount > 1) - return [[RADirectoryFilterList alloc] initWithPath:path config:configFile]; - - char* regexValue = 0; - if (regex && filterCount == 1 && config_get_string(configFile, "filter_1_regex", ®exValue)) - { - *regex = [NSRegularExpression regularExpressionWithPattern:[NSString stringWithUTF8String:regexValue] options:0 error:nil]; - free(regexValue); - } - - config_file_free(configFile); + NSString* expr = [configFile getStringNamed:@"filter_1_regex" withDefault:@".*"]; + *regex = [NSRegularExpression regularExpressionWithPattern:expr options:0 error:nil]; } } return nil; } -- (id)initWithPath:(NSString*)path config:(config_file_t*)config +- (id)initWithPath:(NSString*)path config:(RAConfig*)config { self = [super initWithStyle:UITableViewStylePlain]; _path = path; _filterList = config; + _filterCount = [_filterList getUintNamed:@"filter_count" withDefault:0]; - if (!_filterList || !config_get_uint(_filterList, "filter_count", &_filterCount) || _filterCount == 0) - { + if (_filterCount == 0) [RetroArch_iOS displayErrorMessage:@"No valid filters were found."]; - } [self setTitle: [path lastPathComponent]]; - return self; } -- (id)initWithPath:(NSString*)path -{ - return [self initWithPath:path config:config_file_new([[path stringByAppendingPathComponent:@".rafilter"] UTF8String])]; -} - -- (void)dealloc -{ - if (_filterList) - config_file_free(_filterList); -} - - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - if (_filterList) - { - NSString* regexKey = [NSString stringWithFormat:@"filter_%d_regex", indexPath.row + 1]; - - char* regex = 0; - if (config_get_string(_filterList, [regexKey UTF8String], ®ex)) - { - NSRegularExpression* expr = [NSRegularExpression regularExpressionWithPattern:[NSString stringWithUTF8String:regex] options:0 error:nil]; - free(regex); - - [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:_path filter:expr]]; - } - } + NSString* regex = [NSString stringWithFormat:@"filter_%d_regex", indexPath.row + 1]; + regex = [_filterList getStringNamed:regex withDefault:@".*"]; + + NSRegularExpression* expr = [NSRegularExpression regularExpressionWithPattern:regex options:0 error:nil]; + + [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:_path filter:expr]]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return _filterCount; + return _filterCount ? _filterCount : 1; } - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - NSString* nameKey = [NSString stringWithFormat:@"filter_%d_name", indexPath.row + 1]; - - char* nameString = 0; - if (_filterList && config_get_string(_filterList, [nameKey UTF8String], &nameString)) - { - nameKey = [NSString stringWithUTF8String:nameString]; - free(nameString); - } + NSString* name = [NSString stringWithFormat:@"filter_%d_name", indexPath.row + 1]; + name = [_filterList getStringNamed:name withDefault:@"BAD NAME"]; UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"filter"]; cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"filter"]; - cell.textLabel.text = nameKey; + cell.textLabel.text = name; return cell; } diff --git a/ios/RetroArch/RADirectoryGrid.m b/ios/RetroArch/RADirectoryGrid.m index 675d007d83..b2d45767da 100644 --- a/ios/RetroArch/RADirectoryGrid.m +++ b/ios/RetroArch/RADirectoryGrid.m @@ -13,33 +13,24 @@ * If not, see . */ +#import "RAConfig.h" #import "browser.h" @implementation RADirectoryGrid { NSString* _path; NSArray* _list; - - UIImage* _templateImage; } - (id)initWithPath:(NSString*)path filter:(NSRegularExpression*)regex { _path = path ? path : ra_ios_get_browser_root(); - // Load template image - NSString* templateName = [NSString stringWithFormat:@"%@/.coverart/template.png", _path]; - _templateImage = [UIImage imageWithContentsOfFile:templateName]; - - if (!_templateImage) - { - [RetroArch_iOS displayErrorMessage:@"Coverart template.png is missing."]; - _templateImage = [RetroArch_iOS get].file_icon; - } - // + RAConfig* config = [[RAConfig alloc] initWithPath:[NSString stringWithFormat:@"%@/.coverart/.config", _path]]; + UICollectionViewFlowLayout* layout = [UICollectionViewFlowLayout new]; - layout.itemSize = _templateImage.size; + layout.itemSize = CGSizeMake([config getUintNamed:@"item_width" withDefault:100], [config getUintNamed:@"item_height" withDefault:100]); self = [super initWithCollectionViewLayout:layout]; _list = ra_ios_list_directory(_path, regex); diff --git a/ios/RetroArch/RADirectoryList.m b/ios/RetroArch/RADirectoryList.m index adda1f5150..b4b78bca81 100644 --- a/ios/RetroArch/RADirectoryList.m +++ b/ios/RetroArch/RADirectoryList.m @@ -49,7 +49,7 @@ static NSString* check_path(NSString* path) if ([UICollectionViewController instancesRespondToSelector:@selector(initWithCollectionViewLayout:)]) { NSString* coverDir = path ? [path stringByAppendingPathComponent:@".coverart"] : nil; - if (coverDir && ra_ios_is_directory(coverDir) && ra_ios_is_file([coverDir stringByAppendingPathComponent:@"template.png"])) + if (coverDir && ra_ios_is_directory(coverDir)) return [[RADirectoryGrid alloc] initWithPath:path filter:regex]; } diff --git a/ios/RetroArch/RAModuleInfoList.m b/ios/RetroArch/RAModuleInfoList.m index a268bfc119..c555f4b77f 100644 --- a/ios/RetroArch/RAModuleInfoList.m +++ b/ios/RetroArch/RAModuleInfoList.m @@ -14,7 +14,7 @@ */ @implementation RAModuleInfo -+ (RAModuleInfo*)moduleWithPath:(NSString*)thePath data:(config_file_t*)theData ++ (RAModuleInfo*)moduleWithPath:(NSString*)thePath data:(RAConfig*)theData { RAModuleInfo* new = [RAModuleInfo new]; @@ -22,22 +22,12 @@ new.data = theData; return new; } - -- (void)dealloc -{ - if (self.data) - { - config_file_free(self.data); - } -} - @end static NSString* const labels[3] = {@"Emulator Name", @"Manufacturer", @"Name"}; -static const char* const keys[3] = {"emuname", "manufacturer", "systemname"}; - -static const uint32_t sectionSizes[2] = {1, 2}; +static NSString* const keys[3] = {@"emuname", @"manufacturer", @"systemname"}; static NSString* const sectionNames[2] = {@"Emulator", @"Hardware"}; +static const uint32_t sectionSizes[2] = {1, 2}; @implementation RAModuleInfoList { @@ -79,14 +69,7 @@ static NSString* const sectionNames[2] = {@"Emulator", @"Hardware"}; } cell.textLabel.text = labels[sectionBase + indexPath.row]; - - char* text = 0; - if (config_get_string(_data.data, keys[sectionBase + indexPath.row], &text)) - cell.detailTextLabel.text = [NSString stringWithUTF8String:text]; - else - cell.detailTextLabel.text = @"Unspecified"; - - free(text); + cell.detailTextLabel.text = [_data.data getStringNamed:keys[sectionBase + indexPath.row] withDefault:@"Unspecified"]; return cell; } diff --git a/ios/RetroArch/RAModuleList.m b/ios/RetroArch/RAModuleList.m index 5a91db019f..7b36bef162 100644 --- a/ios/RetroArch/RAModuleList.m +++ b/ios/RetroArch/RAModuleList.m @@ -46,7 +46,7 @@ NSString* modulePath = [moduleList objectAtIndex:i]; NSString* baseName = [[modulePath stringByDeletingPathExtension] stringByAppendingPathExtension:@"info"]; - [_modules addObject:[RAModuleInfo moduleWithPath:modulePath data:config_file_new([baseName UTF8String])]]; + [_modules addObject:[RAModuleInfo moduleWithPath:modulePath data:[[RAConfig alloc] initWithPath:baseName]]]; } [self setTitle:@"Choose Emulator"]; diff --git a/ios/RetroArch/browser.h b/ios/RetroArch/browser.h index 05bd932e38..ffaa75850f 100644 --- a/ios/RetroArch/browser.h +++ b/ios/RetroArch/browser.h @@ -32,6 +32,4 @@ extern NSString* ra_ios_get_browser_root(); // Check path to see if a directory filter list is needed. // If one is not needed useExpression will be set to a default expression to use. + (RADirectoryFilterList*) directoryFilterListAtPath:(NSString*)path useExpression:(NSRegularExpression**)regex; - -- (id)initWithPath:(NSString*)path; @end diff --git a/ios/RetroArch/settings/RASettingsList.m b/ios/RetroArch/settings/RASettingsList.m index 39159f50e7..1b7595fb3d 100644 --- a/ios/RetroArch/settings/RASettingsList.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -15,31 +15,16 @@ #import #import "settings.h" -#include "config_file.h" @implementation RASettingData @end - -static NSString* get_value_from_config(config_file_t* config, NSString* name, NSString* defaultValue) +static NSString* get_value_from_config(RAConfig* config, NSString* name, NSString* defaultValue) { - NSString* value = nil; - - char* v = 0; - if (config && config_get_string(config, [name UTF8String], &v)) - { - value = [[NSString alloc] initWithUTF8String:v]; - free(v); - } - else - { - value = defaultValue; - } - - return value; + return [config getStringNamed:name withDefault:defaultValue]; } -static RASettingData* boolean_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue) +static RASettingData* boolean_setting(RAConfig* config, NSString* name, NSString* label, NSString* defaultValue) { RASettingData* result = [[RASettingData alloc] init]; result.type = BooleanSetting; @@ -49,7 +34,7 @@ static RASettingData* boolean_setting(config_file_t* config, NSString* name, NSS return result; } -static RASettingData* button_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue) +static RASettingData* button_setting(RAConfig* config, NSString* name, NSString* label, NSString* defaultValue) { RASettingData* result = [[RASettingData alloc] init]; result.type = ButtonSetting; @@ -68,7 +53,7 @@ static RASettingData* group_setting(NSString* label, NSArray* settings) return result; } -static RASettingData* enumeration_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue, NSArray* values) +static RASettingData* enumeration_setting(RAConfig* config, NSString* name, NSString* label, NSString* defaultValue, NSArray* values) { RASettingData* result = [[RASettingData alloc] init]; result.type = EnumerationSetting; @@ -79,7 +64,7 @@ static RASettingData* enumeration_setting(config_file_t* config, NSString* name, return result; } -static RASettingData* subpath_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue, NSString* path, NSString* extension) +static RASettingData* subpath_setting(RAConfig* config, NSString* name, NSString* label, NSString* defaultValue, NSString* path, NSString* extension) { NSString* value = get_value_from_config(config, name, defaultValue); value = [value stringByReplacingOccurrencesOfString:path withString:@""]; @@ -100,7 +85,7 @@ static RASettingData* subpath_setting(config_file_t* config, NSString* name, NSS @implementation RASettingsList - (id)init { - config_file_t* config = config_file_new([[RetroArch_iOS get].configFilePath UTF8String]); + RAConfig* config = [[RAConfig alloc] initWithPath:[RetroArch_iOS get].configFilePath]; NSString* overlay_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/overlays/"]; NSString* shader_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/shaders/"]; @@ -168,9 +153,6 @@ static RASettingData* subpath_setting(config_file_t* config, NSString* name, NSS nil], nil ]; - - if (config) - config_file_free(config); self = [super initWithSettings:settings title:@"RetroArch Settings"]; return self; @@ -188,15 +170,12 @@ static RASettingData* subpath_setting(config_file_t* config, NSString* name, NSS - (void)writeToDisk { - config_file_t* config = config_file_new([[RetroArch_iOS get].configFilePath UTF8String]); - config = config ? config : config_file_new(0); - - config_set_string(config, "system_directory", [[RetroArch_iOS get].system_directory UTF8String]); + RAConfig* config = [[RAConfig alloc] initWithPath:[RetroArch_iOS get].configFilePath]; + [config putStringNamed:@"system_directory" value:[RetroArch_iOS get].system_directory]; [self writeSettings:nil toConfig:config]; - config_file_write(config, [[RetroArch_iOS get].configFilePath UTF8String]); - config_file_free(config); + [config writeToFile:[RetroArch_iOS get].configFilePath]; } @end diff --git a/ios/RetroArch/settings/RASettingsSubList.m b/ios/RetroArch/settings/RASettingsSubList.m index d2cf91e266..2ba3baf9ff 100644 --- a/ios/RetroArch/settings/RASettingsSubList.m +++ b/ios/RetroArch/settings/RASettingsSubList.m @@ -32,7 +32,7 @@ static const char* const SETTINGID = "SETTING"; return self; } -- (void)writeSettings:(NSArray*)settingList toConfig:(config_file_t *)config +- (void)writeSettings:(NSArray*)settingList toConfig:(RAConfig*)config { NSArray* list = settingList ? settingList : settings; @@ -52,13 +52,13 @@ static const char* const SETTINGID = "SETTING"; case FileListSetting: if ([setting.value length] > 0) - config_set_string(config, [setting.name UTF8String], [[setting.path stringByAppendingPathComponent:setting.value] UTF8String]); + [config putStringNamed:setting.name value:[setting.path stringByAppendingPathComponent:setting.value]]; else - config_set_string(config, [setting.name UTF8String], ""); + [config putStringNamed:setting.name value:@""]; break; default: - config_set_string(config, [setting.name UTF8String], [setting.value UTF8String]); + [config putStringNamed:setting.name value:setting.value]; break; } } diff --git a/ios/RetroArch/settings/settings.h b/ios/RetroArch/settings/settings.h index c89d5f6226..c1a0d6c811 100644 --- a/ios/RetroArch/settings/settings.h +++ b/ios/RetroArch/settings/settings.h @@ -13,8 +13,6 @@ * If not, see . */ -#include "conf/config_file.h" - enum SettingTypes { BooleanSetting, ButtonSetting, EnumerationSetting, FileListSetting, GroupSetting diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index cf02798a75..698d6c8f7f 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -16,16 +16,16 @@ #import #import -#include "conf/config_file.h" +#import "RAConfig.h" @interface RAGameView : UIViewController @end @interface RAModuleInfo : NSObject @property (strong) NSString* path; -@property config_file_t* data; +@property (strong) RAConfig* data; -+ (RAModuleInfo*)moduleWithPath:(NSString*)thePath data:(config_file_t*)theData; ++ (RAModuleInfo*)moduleWithPath:(NSString*)thePath data:(RAConfig*)theData; @end @interface RAModuleInfoList : UITableViewController @@ -43,7 +43,7 @@ @interface RASettingsSubList : UITableViewController - (id)initWithSettings:(NSArray*)values title:(NSString*)title; -- (void)writeSettings:(NSArray*)settingList toConfig:(config_file_t*)config; +- (void)writeSettings:(NSArray*)settingList toConfig:(RAConfig*)config; @end @interface RASettingsList : RASettingsSubList From c551a6424ed2f03e5fe75cf60b7c67403b1a05f3 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sat, 23 Feb 2013 13:12:47 -0500 Subject: [PATCH 074/108] ios: Refactoring --- ios/RetroArch/RADirectoryFilterList.m | 2 +- ios/RetroArch/RADirectoryGrid.m | 2 +- ios/RetroArch/RADirectoryList.m | 2 +- ios/RetroArch/RAGameView.m | 101 +----------- ios/RetroArch/RAModuleList.m | 4 +- ios/RetroArch/RetroArch_iOS.h | 5 +- ios/RetroArch/RetroArch_iOS.m | 175 ++++++++++++++++----- ios/RetroArch/ios_input.c | 1 + ios/RetroArch/rarch_wrapper.h | 8 +- ios/RetroArch/settings/RASettingsList.m | 2 +- ios/RetroArch/settings/RASettingsSubList.m | 4 +- 11 files changed, 146 insertions(+), 160 deletions(-) diff --git a/ios/RetroArch/RADirectoryFilterList.m b/ios/RetroArch/RADirectoryFilterList.m index d4838f4dad..02fb61dde5 100644 --- a/ios/RetroArch/RADirectoryFilterList.m +++ b/ios/RetroArch/RADirectoryFilterList.m @@ -69,7 +69,7 @@ NSRegularExpression* expr = [NSRegularExpression regularExpressionWithPattern:regex options:0 error:nil]; - [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:_path filter:expr]]; + [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:_path filter:expr] isGame:NO]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section diff --git a/ios/RetroArch/RADirectoryGrid.m b/ios/RetroArch/RADirectoryGrid.m index b2d45767da..d48d9efa2c 100644 --- a/ios/RetroArch/RADirectoryGrid.m +++ b/ios/RetroArch/RADirectoryGrid.m @@ -60,7 +60,7 @@ RADirectoryItem* path = [_list objectAtIndex: indexPath.row]; if(path.isDirectory) - [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:path.path]]; + [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:path.path] isGame:NO]; else [[RetroArch_iOS get] runGame:path.path]; } diff --git a/ios/RetroArch/RADirectoryList.m b/ios/RetroArch/RADirectoryList.m index b4b78bca81..a27a86c636 100644 --- a/ios/RetroArch/RADirectoryList.m +++ b/ios/RetroArch/RADirectoryList.m @@ -74,7 +74,7 @@ static NSString* check_path(NSString* path) RADirectoryItem* path = [_list objectAtIndex: indexPath.row]; if(path.isDirectory) - [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:path.path]]; + [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:path.path] isGame:NO]; else [[RetroArch_iOS get] runGame:path.path]; } diff --git a/ios/RetroArch/RAGameView.m b/ios/RetroArch/RAGameView.m index 1605a48736..5fdc1e9581 100644 --- a/ios/RetroArch/RAGameView.m +++ b/ios/RetroArch/RAGameView.m @@ -16,9 +16,6 @@ #include "general.h" #include "rarch_wrapper.h" -static bool _isRunning; -static bool _isPaused; - static float screen_scale; static int frame_skips = 4; static bool is_syncing = true; @@ -88,22 +85,6 @@ static bool is_syncing = true; _notifyLabel.alpha = 0.0f; } -- (void)iterate -{ - while (_isRunning && !_isPaused) - { - _isRunning = rarch_main_iterate(); - - if (!_isRunning) - { - ios_close_game(); - return; - } - else - while(!_isPaused && _isRunning && CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource); - } -} - - (void)needsToDie { glFinish(); @@ -114,94 +95,16 @@ static bool is_syncing = true; [EAGLContext setCurrentContext:nil]; } -- (void)pause -{ - _isPaused = true; -} - -- (void)resume -{ - if (_isPaused) - { - _isPaused = false; - [self performSelector:@selector(iterate) withObject:nil afterDelay:.02f]; - } -} - @end static RAGameView* gameViewer; -bool ios_load_game(const char* path) -{ - [RASettingsList refreshConfigFile]; - - const char* const sd = [[RetroArch_iOS get].system_directory UTF8String]; - const char* const cf =[[RetroArch_iOS get].configFilePath UTF8String]; - const char* const libretro = [[RetroArch_iOS get].module_path UTF8String]; - - struct rarch_main_wrap main_wrapper = {path, sd, sd, cf, libretro}; - if (rarch_main_init_wrap(&main_wrapper) == 0) - { - rarch_init_msg_queue(); - _isRunning = true; - } - else - _isRunning = false; - - return _isRunning; -} - -void ios_close_game() -{ - if (_isRunning) - { - rarch_main_deinit(); - rarch_deinit_msg_queue(); - -#ifdef PERF_TEST - rarch_perf_log(); -#endif - - rarch_main_clear_state(); - - _isRunning = false; - } - - [[RetroArch_iOS get] gameHasExited]; -} - -void ios_pause_emulator() -{ - if (_isRunning) - [gameViewer pause]; -} - -void ios_resume_emulator() -{ - if (_isRunning) - [gameViewer resume]; -} - -void ios_suspend_emulator() -{ - if (_isRunning) - uninit_drivers(); -} - -void ios_activate_emulator() -{ - if (_isRunning) - init_drivers(); -} - bool ios_init_game_view() { if (!gameViewer) { gameViewer = [RAGameView new]; - [[RetroArch_iOS get] setViewer:gameViewer]; - [gameViewer performSelector:@selector(iterate) withObject:nil afterDelay:.02f]; + [[RetroArch_iOS get] pushViewController:gameViewer isGame:YES]; } return true; @@ -212,7 +115,7 @@ void ios_destroy_game_view() if (gameViewer) { [gameViewer needsToDie]; - [[RetroArch_iOS get] setViewer:nil]; + [[RetroArch_iOS get] popViewController]; gameViewer = nil; } } diff --git a/ios/RetroArch/RAModuleList.m b/ios/RetroArch/RAModuleList.m index 7b36bef162..be37cf1e3e 100644 --- a/ios/RetroArch/RAModuleList.m +++ b/ios/RetroArch/RAModuleList.m @@ -59,13 +59,13 @@ RAModuleInfo* info = (RAModuleInfo*)[_modules objectAtIndex:indexPath.row]; [RetroArch_iOS get].module_path = info.path; - [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:nil]]; + [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:nil] isGame:NO]; } - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath { RAModuleInfo* info = (RAModuleInfo*)[_modules objectAtIndex:indexPath.row]; - [[RetroArch_iOS get] pushViewController:[[RAModuleInfoList alloc] initWithModuleInfo:info]]; + [[RetroArch_iOS get] pushViewController:[[RAModuleInfoList alloc] initWithModuleInfo:info] isGame:NO]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index eec5fcedf5..67a9d8f410 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -24,13 +24,10 @@ extern NSString* const GSEventKeyUpNotification; + (RetroArch_iOS*)get; - (void)runGame:(NSString*)path; -- (void)gameHasExited; -- (void)pushViewController:(UIViewController*)theView; +- (void)pushViewController:(UIViewController*)theView isGame:(BOOL)game; - (void)popViewController; -- (void)setViewer:(UIViewController*)theView; - - (NSString*)configFilePath; @property (strong, nonatomic) NSString* system_directory; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 4e45931752..43c7101896 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -15,6 +15,7 @@ #include #include "rarch_wrapper.h" +#include "general.h" #define MAX_TOUCH 16 extern struct @@ -29,10 +30,49 @@ extern bool ios_keys[256]; extern uint32_t ios_current_touch_count; +@interface RANavigator : UINavigationController +// 0 if no RAGameView is in the navigator +// 1 if a RAGameView is the top +// 2+ if there are views pushed ontop of the RAGameView +@property unsigned gameAndAbove; + +- (void)pushViewController:(UIViewController*)theView isGame:(BOOL)game; +@end + +@implementation RANavigator +- (void)pushViewController:(UIViewController*)theView isGame:(BOOL)game +{ + assert(!game || self.gameAndAbove == 0); + + if (game || self.gameAndAbove) self.gameAndAbove ++; + + [[UIApplication sharedApplication] setStatusBarHidden:game withAnimation:UIStatusBarAnimationNone]; + self.navigationBarHidden = game; + [self pushViewController:theView animated:!(self.gameAndAbove == 1 || self.gameAndAbove == 2)]; +} + +- (UIViewController *)popViewControllerAnimated:(BOOL)animated +{ + const bool poppingFromGame = self.gameAndAbove == 1; + const bool poppingToGame = self.gameAndAbove == 2; + if (self.gameAndAbove) self.gameAndAbove --; + + if (self.gameAndAbove == 1) + [[RetroArch_iOS get] performSelector:@selector(startTimer)]; + + [[UIApplication sharedApplication] setStatusBarHidden:poppingToGame withAnimation:UIStatusBarAnimationNone]; + self.navigationBarHidden = poppingToGame; + return [super popViewControllerAnimated:!poppingToGame && !poppingFromGame]; +} +@end + @implementation RetroArch_iOS { UIWindow* _window; - UINavigationController* _navigator; + RANavigator* _navigator; + NSTimer* _gameTimer; + + bool _isRunning; } + (void)displayErrorMessage:(NSString*)message @@ -50,36 +90,9 @@ extern uint32_t ios_current_touch_count; return (RetroArch_iOS*)[[UIApplication sharedApplication] delegate]; } -- (void)runGame:(NSString*)path +- (void)showSettings { - ios_load_game([path UTF8String]); -} - -- (void)gameHasExited -{ - _navigator = [[UINavigationController alloc] init]; - [_navigator pushViewController: [[RAModuleList alloc] init] animated:YES]; - - _window.rootViewController = _navigator; -} - -- (void)pushViewController:(UIViewController*)theView -{ - if (_navigator != nil) - [_navigator pushViewController:theView animated:YES]; -} - -- (void)popViewController -{ - if (_navigator != nil) - [_navigator popViewControllerAnimated:YES]; -} - -- (void)setViewer:(UIViewController*)theView -{ - _navigator = nil; - [[UIApplication sharedApplication] setStatusBarHidden:theView ? YES : NO withAnimation:UIStatusBarAnimationNone]; - _window.rootViewController = theView; + [self pushViewController:[RASettingsList new] isGame:NO]; } - (NSString*)configFilePath @@ -108,13 +121,13 @@ extern uint32_t ios_current_touch_count; style:UIBarButtonItemStyleBordered target:nil action:nil]; self.settings_button.target = self; - self.settings_button.action = @selector(show_settings); + self.settings_button.action = @selector(showSettings); [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone]; // Setup window - _navigator = [[UINavigationController alloc] init]; - [_navigator pushViewController: [[RAModuleList alloc] init] animated:YES]; + _navigator = [RANavigator new]; + [_navigator pushViewController: [RAModuleList new] animated:YES]; _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; _window.rootViewController = _navigator; @@ -125,26 +138,106 @@ extern uint32_t ios_current_touch_count; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyReleased:) name: GSEventKeyUpNotification object: nil]; } +#pragma mark VIEW MANAGEMENT +- (void)pushViewController:(UIViewController*)theView isGame:(BOOL)game +{ + [_navigator pushViewController:theView isGame:game]; + [self startTimer]; +} + +- (void)popViewController +{ + [_navigator popViewControllerAnimated:YES]; + [self startTimer]; +} + +#pragma mark EMULATION +- (void)runGame:(NSString*)path +{ + [RASettingsList refreshConfigFile]; + + const char* const sd = [[RetroArch_iOS get].system_directory UTF8String]; + const char* const cf =[[RetroArch_iOS get].configFilePath UTF8String]; + const char* const libretro = [[RetroArch_iOS get].module_path UTF8String]; + + struct rarch_main_wrap main_wrapper = {[path UTF8String], sd, sd, cf, libretro}; + if (rarch_main_init_wrap(&main_wrapper) == 0) + { + _isRunning = true; + rarch_init_msg_queue(); + [self startTimer]; + } + else + { + _isRunning = false; + [RetroArch_iOS displayErrorMessage:@"Failed to load game."]; + } +} + +- (void)closeGame +{ + if (_isRunning) + { + rarch_main_deinit(); + rarch_deinit_msg_queue(); + +#ifdef PERF_TEST + rarch_perf_log(); +#endif + + rarch_main_clear_state(); + } + + [self stopTimer]; + _isRunning = false; +} + +- (void)iterate +{ + if (!_isRunning || _navigator.gameAndAbove != 1) + [self stopTimer]; + else if (_isRunning && !rarch_main_iterate()) + [self closeGame]; +} + +- (void)startTimer +{ + if (!_gameTimer) + _gameTimer = [NSTimer scheduledTimerWithTimeInterval:0.001f target:self selector:@selector(iterate) userInfo:nil repeats:YES]; +} + +- (void)stopTimer +{ + if (_gameTimer) + [_gameTimer invalidate]; + + _gameTimer = nil; +} + +#pragma mark LIFE CYCLE - (void)applicationDidBecomeActive:(UIApplication*)application { - ios_resume_emulator(); + [self startTimer]; } - (void)applicationWillResignActive:(UIApplication*)application { - ios_pause_emulator(); + [self stopTimer]; } - (void)applicationWillEnterForeground:(UIApplication *)application { - ios_activate_emulator(); + if (_isRunning) + init_drivers(); } - (void)applicationDidEnterBackground:(UIApplication *)application { - ios_suspend_emulator(); + if (_isRunning) + uninit_drivers(); } +#pragma mark INPUT -(void) keyPressed: (NSNotification*) notification { int keycode = [[notification.userInfo objectForKey:@"keycode"] intValue]; @@ -157,11 +250,6 @@ extern uint32_t ios_current_touch_count; if (keycode < 256) ios_keys[keycode] = false; } -- (void)show_settings -{ - [self pushViewController:[RASettingsList new]]; -} - - (void)processTouches:(NSArray*)touches { ios_current_touch_count = [touches count]; @@ -180,9 +268,10 @@ extern uint32_t ios_current_touch_count; if (coord.y < view.bounds.size.height / 10.0f) { float tenpct = view.bounds.size.width / 10.0f; + if (_navigator.gameAndAbove == 1) if (coord.x >= tenpct * 4 && coord.x <= tenpct * 6) { - ios_close_game(); + [self closeGame]; } } } diff --git a/ios/RetroArch/ios_input.c b/ios/RetroArch/ios_input.c index 4fba92d606..2a29ddd4bc 100644 --- a/ios/RetroArch/ios_input.c +++ b/ios/RetroArch/ios_input.c @@ -244,6 +244,7 @@ static void *ios_input_init(void) { input_init_keyboard_lut(rarch_key_map_hidusage); + ios_current_touch_count = 0; memset(ios_touches, 0, sizeof(ios_touches)); memset(ios_keys, 0, sizeof(ios_keys)); return (void*)-1; diff --git a/ios/RetroArch/rarch_wrapper.h b/ios/RetroArch/rarch_wrapper.h index ed2a31b571..b53bb0a340 100644 --- a/ios/RetroArch/rarch_wrapper.h +++ b/ios/RetroArch/rarch_wrapper.h @@ -16,12 +16,8 @@ #ifndef __IOS_RARCH_WRAPPER_H__ #define __IOS_RARCH_WRAPPER_H__ -bool ios_load_game(const char* path); -void ios_close_game(); -void ios_pause_emulator(); -void ios_resume_emulator(); -void ios_suspend_emulator(); -void ios_activate_emulator(); +// These functions must only be called in gfx/context/ioseagl_ctx.c + bool ios_init_game_view(); void ios_destroy_game_view(); void ios_flip_game_view(); diff --git a/ios/RetroArch/settings/RASettingsList.m b/ios/RetroArch/settings/RASettingsList.m index 1b7595fb3d..bd3588c331 100644 --- a/ios/RetroArch/settings/RASettingsList.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -93,7 +93,7 @@ static RASettingData* subpath_setting(RAConfig* config, NSString* name, NSString NSArray* settings = [NSArray arrayWithObjects: [NSArray arrayWithObjects:@"Video", boolean_setting(config, @"video_smooth", @"Smooth Video", @"true"), - boolean_setting(config, @"video_crop_overscan", @"Crop Overscan", @"false"), + boolean_setting(config, @"video_crop_overscan", @"Crop Overscan", @"true"), subpath_setting(config, @"video_bsnes_shader", @"Shader", @"", shader_path, @"shader"), nil], diff --git a/ios/RetroArch/settings/RASettingsSubList.m b/ios/RetroArch/settings/RASettingsSubList.m index 2ba3baf9ff..b6b6ac0341 100644 --- a/ios/RetroArch/settings/RASettingsSubList.m +++ b/ios/RetroArch/settings/RASettingsSubList.m @@ -73,7 +73,7 @@ static const char* const SETTINGID = "SETTING"; { case EnumerationSetting: case FileListSetting: - [[RetroArch_iOS get] pushViewController:[[RASettingEnumerationList alloc] initWithSetting:setting fromTable:(UITableView*)self.view]]; + [[RetroArch_iOS get] pushViewController:[[RASettingEnumerationList alloc] initWithSetting:setting fromTable:(UITableView*)self.view] isGame:NO]; break; case ButtonSetting: @@ -81,7 +81,7 @@ static const char* const SETTINGID = "SETTING"; break; case GroupSetting: - [[RetroArch_iOS get] pushViewController:[[RASettingsSubList alloc] initWithSettings:setting.subValues title:setting.label]]; + [[RetroArch_iOS get] pushViewController:[[RASettingsSubList alloc] initWithSettings:setting.subValues title:setting.label] isGame:NO]; break; default: From ee871109728b5be1afe16908cd2272684ec6100b Mon Sep 17 00:00:00 2001 From: meancoot Date: Sat, 23 Feb 2013 23:03:59 -0500 Subject: [PATCH 075/108] ios: Refactor input code. Add first draft of pause menu. --- ios/RetroArch.xcodeproj/project.pbxproj | 12 +- ios/RetroArch/PauseView.xib | 375 +++++++++++++++++++ ios/RetroArch/RetroArch_iOS.h | 3 - ios/RetroArch/RetroArch_iOS.m | 101 +++--- ios/RetroArch/{ios_input.c => ios_input.m} | 396 ++++++++++----------- ios/RetroArch/main.m | 11 +- ios/RetroArch/settings/RAButtonGetter.m | 2 + 7 files changed, 617 insertions(+), 283 deletions(-) create mode 100644 ios/RetroArch/PauseView.xib rename ios/RetroArch/{ios_input.c => ios_input.m} (72%) diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index fde3e42322..b19e8900fe 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -28,6 +28,8 @@ 963F5AC716CC523B009BBD19 /* RADirectoryList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC416CC523B009BBD19 /* RADirectoryList.m */; }; 963F5AC816CC523B009BBD19 /* RAGameView.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC516CC523B009BBD19 /* RAGameView.m */; }; 963F5AC916CC523B009BBD19 /* RAModuleList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC616CC523B009BBD19 /* RAModuleList.m */; }; + 965AE29E16D9BF94001D7667 /* ios_input.m in Sources */ = {isa = PBXBuildFile; fileRef = 965AE29D16D9BF94001D7667 /* ios_input.m */; }; + 969EBF6A16D95746003787A2 /* PauseView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 969EBF6916D95746003787A2 /* PauseView.xib */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -85,7 +87,6 @@ 96C19C2916D5A56500FE8D5A /* browser.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2816D5A56400FE8D5A /* browser.m */; }; 96C19C3016D7045700FE8D5A /* RAConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2F16D7045700FE8D5A /* RAConfig.m */; }; 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCE16C1FBC0009DE44C /* overlay.c */; }; - 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CF015B16C2F72900ABF9C9 /* ios_input.c */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -111,6 +112,8 @@ 963F5AC416CC523B009BBD19 /* RADirectoryList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RADirectoryList.m; sourceTree = ""; }; 963F5AC516CC523B009BBD19 /* RAGameView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAGameView.m; sourceTree = ""; }; 963F5AC616CC523B009BBD19 /* RAModuleList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAModuleList.m; sourceTree = ""; }; + 965AE29D16D9BF94001D7667 /* ios_input.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ios_input.m; sourceTree = ""; }; + 969EBF6916D95746003787A2 /* PauseView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PauseView.xib; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -234,7 +237,6 @@ 96C19C2816D5A56400FE8D5A /* browser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = browser.m; sourceTree = ""; }; 96C19C2E16D7045600FE8D5A /* RAConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RAConfig.h; sourceTree = ""; }; 96C19C2F16D7045700FE8D5A /* RAConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAConfig.m; sourceTree = ""; }; - 96CF015B16C2F72900ABF9C9 /* ios_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ios_input.c; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -312,7 +314,6 @@ 96C19C2716D455C600FE8D5A /* Browser */, 96366C6F16CAF62200D64A22 /* settings */, 96AFAE3416C1D4EA009DE44C /* Supporting Files */, - 96CF015B16C2F72900ABF9C9 /* ios_input.c */, 96C19C2E16D7045600FE8D5A /* RAConfig.h */, 96C19C2F16D7045700FE8D5A /* RAConfig.m */, 963F5AC516CC523B009BBD19 /* RAGameView.m */, @@ -321,7 +322,9 @@ 96C19C2616D455BE00FE8D5A /* rarch_wrapper.h */, 96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */, 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */, + 965AE29D16D9BF94001D7667 /* ios_input.m */, 96297A0D16C5ADDA00E6DCE0 /* views.h */, + 969EBF6916D95746003787A2 /* PauseView.xib */, ); path = RetroArch; sourceTree = ""; @@ -625,6 +628,7 @@ 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */, 96297A2416C818FF00E6DCE0 /* Icon-72.png in Resources */, 96297A2516C818FF00E6DCE0 /* Icon.png in Resources */, + 969EBF6A16D95746003787A2 /* PauseView.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -678,7 +682,6 @@ 96AFAFAD16C1EEE9009DE44C /* sinc.c in Sources */, 96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */, 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */, - 96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */, 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */, 96297A0C16C5AD8D00E6DCE0 /* RetroArch_iOS.m in Sources */, 96297A0F16C5AEA100E6DCE0 /* main.m in Sources */, @@ -697,6 +700,7 @@ 96C19C2416D453BA00FE8D5A /* RADirectoryGrid.m in Sources */, 96C19C2916D5A56500FE8D5A /* browser.m in Sources */, 96C19C3016D7045700FE8D5A /* RAConfig.m in Sources */, + 965AE29E16D9BF94001D7667 /* ios_input.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/PauseView.xib b/ios/RetroArch/PauseView.xib new file mode 100644 index 0000000000..80b8172276 --- /dev/null +++ b/ios/RetroArch/PauseView.xib @@ -0,0 +1,375 @@ + + + + 1552 + 12C60 + 3084 + 1187.34 + 625.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 2083 + + + IBNSLayoutConstraint + IBProxyObject + IBUIButton + IBUIView + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + + IBFilesOwner + IBIPadFramework + + + IBFirstResponder + IBIPadFramework + + + + 274 + + + + 292 + {{20, 20}, {728, 44}} + + + + _NS:9 + NO + IBIPadFramework + 0 + 0 + 1 + Return to Loader + + 3 + MQA + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + 3 + MC41AA + + + 2 + 15 + + + Helvetica-Bold + 15 + 16 + + + + + 292 + {{20, 71}, {728, 44}} + + + + _NS:9 + NO + IBIPadFramework + 0 + 0 + 1 + Resume Game + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + {{0, 20}, {768, 1004}} + + + + + 3 + MQA + + 2 + + + + 2 + + IBIPadFramework + + + + + + + closeGamePressed: + + + 7 + + 23 + + + + resumeGamePressed: + + + 7 + + 24 + + + + + + 0 + + + + + + 1 + + + + + 6 + 0 + + 6 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 3 + 0 + + 4 + 1 + + 8 + + 1000 + + 6 + 24 + 3 + + + + 5 + 0 + + 5 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 6 + 0 + + 6 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 5 + 0 + + 5 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 3 + 0 + + 3 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + + + + + -1 + + + File's Owner + + + -2 + + + + + 12 + + + + + 13 + + + + + 14 + + + + + 16 + + + + + 17 + + + + + 20 + + + + + 21 + + + + + 22 + + + + + + + RetroArch_iOS + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + 24 + + + + + NSLayoutConstraint + NSObject + + IBProjectSource + ./Classes/NSLayoutConstraint.h + + + + RetroArch_iOS + UIResponder + + id + id + + + + closeGamePressed: + id + + + resumeGamePressed: + id + + + + IBProjectSource + ./Classes/RetroArch_iOS.h + + + + + 0 + IBIPadFramework + YES + 3 + YES + 2083 + + diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index 67a9d8f410..4b035e82bd 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -15,9 +15,6 @@ #import -extern NSString* const GSEventKeyDownNotification; -extern NSString* const GSEventKeyUpNotification; - @interface RetroArch_iOS : UIResponder + (void)displayErrorMessage:(NSString*)message; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 43c7101896..6ecceb273e 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -17,19 +17,6 @@ #include "rarch_wrapper.h" #include "general.h" -#define MAX_TOUCH 16 -extern struct -{ - bool is_down; - int16_t screen_x, screen_y; - int16_t fixed_x, fixed_y; - int16_t full_x, full_y; -} ios_touches[MAX_TOUCH]; - -extern bool ios_keys[256]; - -extern uint32_t ios_current_touch_count; - @interface RANavigator : UINavigationController // 0 if no RAGameView is in the navigator // 1 if a RAGameView is the top @@ -71,7 +58,9 @@ extern uint32_t ios_current_touch_count; UIWindow* _window; RANavigator* _navigator; NSTimer* _gameTimer; + UIView* _pauseView; + bool _isPaused; bool _isRunning; } @@ -123,6 +112,12 @@ extern uint32_t ios_current_touch_count; self.settings_button.target = self; self.settings_button.action = @selector(showSettings); + // Load pause menu + UINib* xib = [UINib nibWithNibName:@"PauseView" bundle:nil]; + _pauseView = [[xib instantiateWithOwner:self options:nil] lastObject]; + _pauseView.opaque = NO; + _pauseView.alpha = 0.0f; + [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone]; // Setup window @@ -134,21 +129,24 @@ extern uint32_t ios_current_touch_count; [_window makeKeyAndVisible]; // Setup keyboard hack - [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyPressed:) name: GSEventKeyDownNotification object: nil]; - [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyReleased:) name: GSEventKeyUpNotification object: nil]; } #pragma mark VIEW MANAGEMENT - (void)pushViewController:(UIViewController*)theView isGame:(BOOL)game { + if (game) + [theView.view addSubview:_pauseView]; + [_navigator pushViewController:theView isGame:game]; [self startTimer]; } - (void)popViewController { + if (_navigator.gameAndAbove == 1) + [_pauseView removeFromSuperview]; + [_navigator popViewControllerAnimated:YES]; - [self startTimer]; } #pragma mark EMULATION @@ -194,7 +192,7 @@ extern uint32_t ios_current_touch_count; - (void)iterate { - if (!_isRunning || _navigator.gameAndAbove != 1) + if (_isPaused || !_isRunning || _navigator.gameAndAbove != 1) [self stopTimer]; else if (_isRunning && !rarch_main_iterate()) [self closeGame]; @@ -238,72 +236,55 @@ extern uint32_t ios_current_touch_count; } #pragma mark INPUT --(void) keyPressed: (NSNotification*) notification +- (void)touchesBegan:(NSSet*)theTouches withEvent:(UIEvent *)event { - int keycode = [[notification.userInfo objectForKey:@"keycode"] intValue]; - if (keycode < 256) ios_keys[keycode] = true; -} - --(void) keyReleased: (NSNotification*) notification -{ - int keycode = [[notification.userInfo objectForKey:@"keycode"] intValue]; - if (keycode < 256) ios_keys[keycode] = false; -} - -- (void)processTouches:(NSArray*)touches -{ - ios_current_touch_count = [touches count]; - + NSArray* touches = [theTouches allObjects]; UIView* view = _window.rootViewController.view; - for(int i = 0; i != [touches count]; i ++) + const int count = [touches count]; + for(int i = 0; i != count; i ++) { - UITouch *touch = [touches objectAtIndex:i]; + UITouch* touch = [touches objectAtIndex:i]; CGPoint coord = [touch locationInView:view]; - float scale = [[UIScreen mainScreen] scale]; // Exit hack! - if (touch.tapCount == 3) + if (!_isPaused && _navigator.gameAndAbove == 1 && touch.tapCount == 3) { if (coord.y < view.bounds.size.height / 10.0f) { float tenpct = view.bounds.size.width / 10.0f; - if (_navigator.gameAndAbove == 1) if (coord.x >= tenpct * 4 && coord.x <= tenpct * 6) { - [self closeGame]; + _isPaused = true; + _pauseView.frame = CGRectMake(view.bounds.size.width / 2.0f - 100.0f, view.bounds.size.height / 2.0f - 100.0f, 200.0f, 200.0f); + + [UIView animateWithDuration:0.2 + animations:^{_pauseView.alpha = 1.0f;} + completion:^(BOOL finished){}]; } } } - - ios_touches[i].is_down = (touch.phase != UITouchPhaseEnded) && (touch.phase != UITouchPhaseCancelled); - ios_touches[i].screen_x = coord.x * scale; - ios_touches[i].screen_y = coord.y * scale; } } -- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +#pragma mark PAUSE MENU +- (IBAction)closeGamePressed:(id)sender { - [super touchesBegan:touches withEvent:event]; - [self processTouches:[[event allTouches] allObjects]]; + [self closeGame]; + _pauseView = nil; } -- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +- (IBAction)resumeGamePressed:(id)sender { - [super touchesMoved:touches withEvent:event]; - [self processTouches:[[event allTouches] allObjects]]; -} - -- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event -{ - [super touchesEnded:touches withEvent:event]; - [self processTouches:[[event allTouches] allObjects]]; -} - -- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event -{ - [super touchesCancelled:touches withEvent:event]; - [self processTouches:[[event allTouches] allObjects]]; + if (_isPaused) + [UIView animateWithDuration:0.2 + animations:^{_pauseView.alpha = 0.0;} + completion:^(BOOL finished) + { + _isPaused = false; + [self startTimer]; + } + ]; } @end diff --git a/ios/RetroArch/ios_input.c b/ios/RetroArch/ios_input.m similarity index 72% rename from ios/RetroArch/ios_input.c rename to ios/RetroArch/ios_input.m index 2a29ddd4bc..1887539b41 100644 --- a/ios/RetroArch/ios_input.c +++ b/ios/RetroArch/ios_input.m @@ -19,100 +19,189 @@ #include "../../general.h" #include "../../driver.h" -/* - 0x00 Reserved (no event indicated) - 0x01 Keyboard ErrorRollOver - 0x02 Keyboard POSTFail - 0x03 Keyboard ErrorUndefined - 0x2D Keyboard - and (underscore) - 0x2E Keyboard = and + - 0x2F Keyboard [ and { - 0x30 Keyboard ] and } - 0x31 Keyboard \ and | - 0x32 Keyboard Non-US # and ~ - 0x33 Keyboard ; and : - 0x34 Keyboard ' and " - 0x36 Keyboard, and < - 0x37 Keyboard . and > - 0x38 Keyboard / and ? - 0x39 Keyboard Caps Lock - 0x46 Keyboard PrintScreen - 0x47 Keyboard Scroll Lock - 0x4C Keyboard Delete Forward - 0x53 Keypad Num Lock and Clear - 0x63 Keypad . and Delete - 0x64 Keyboard Non-US \ and | - 0x65 Keyboard Application - 0x66 Keyboard Power - 0x67 Keypad = - 0x68 Keyboard F13 - 0x69 Keyboard F14 - 0x6A Keyboard F15 - 0x6B Keyboard F16 - 0x6C Keyboard F17 - 0x6D Keyboard F18 - 0x6E Keyboard F19 - 0x6F Keyboard F20 - 0x70 Keyboard F21 - 0x71 Keyboard F22 - 0x72 Keyboard F23 - 0x73 Keyboard F24 - 0x74 Keyboard Execute - 0x75 Keyboard Help - 0x76 Keyboard Menu - 0x77 Keyboard Select - 0x78 Keyboard Stop - 0x79 Keyboard Again - 0x7A Keyboard Undo - 0x7B Keyboard Cut - 0x7C Keyboard Copy - 0x7D Keyboard Paste - 0x7E Keyboard Find - 0x7F Keyboard Mute - 0x80 Keyboard Volume Up - 0x81 Keyboard Volume Down - 0x82 Keyboard Locking Caps Lock - 0x83 Keyboard Locking Num Lock - 0x84 Keyboard Locking Scroll Lock - 0x85 Keypad Comma - 0x86 Keypad Equal Sign - 0x87 Keyboard International1 - 0x88 Keyboard International2 - 0x89 Keyboard International3 - 0x8A Keyboard International4 - 0x8B Keyboard International5 - 0x8C Keyboard International6 - 0x8D Keyboard International7 - 0x8E Keyboard International8 - 0x8F Keyboard International9 - 0x90 Keyboard LANG1 - 0x91 Keyboard LANG2 - 0x92 Keyboard LANG3 - 0x93 Keyboard LANG4 - 0x94 Keyboard LANG5 - 0x95 Keyboard LANG6 - 0x96 Keyboard LANG7 - 0x97 Keyboard LANG8 - 0x98 Keyboard LANG9 - 0x99 Keyboard Alternate Erase - 0x9A Keyboard SysReq/Attention - 0x9B Keyboard Cancel - 0x9C Keyboard Clear - 0x9D Keyboard Prior - 0x9E Keyboard Return - 0x9F Keyboard Separator - 0xA0 Keyboard Out - 0xA1 Keyboard Oper - 0xA2 Keyboard Clear/Again - 0xA3 Keyboard CrSel/Props - 0xA4 Keyboard ExSel - 0xE3 Keyboard Left GUI - 0xE4 Keyboard RightControl - 0xE6 Keyboard RightAlt - 0xE7 Keyboard Right GUI -*/ +#define MAX_TOUCH 16 +#define MAX_KEYS 256 -// This may be useful for other platforms too +extern NSString* const GSEventKeyDownNotification; +extern NSString* const GSEventKeyUpNotification; +extern NSString* const RATouchNotification; +static const struct rarch_key_map rarch_key_map_hidusage[]; + +struct +{ + bool is_down; + int16_t screen_x, screen_y; + int16_t fixed_x, fixed_y; + int16_t full_x, full_y; +} ios_touches[MAX_TOUCH]; + +uint32_t ios_current_touch_count = 0; + + +// Input responder +static bool ios_keys[MAX_KEYS]; + +@interface RAInputResponder : NSObject +@end + +static RAInputResponder* input_driver; + +@implementation RAInputResponder +-(id)init +{ + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyPressed:) name: GSEventKeyDownNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyReleased:) name: GSEventKeyUpNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleTouches:) name: RATouchNotification object:nil]; + return self; +} + +-(void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +-(void)keyPressed: (NSNotification*)notification +{ + int keycode = [[notification.userInfo objectForKey:@"keycode"] intValue]; + if (keycode < MAX_KEYS) ios_keys[keycode] = true; +} + +-(void)keyReleased: (NSNotification*)notification +{ + int keycode = [[notification.userInfo objectForKey:@"keycode"] intValue]; + if (keycode < MAX_KEYS) ios_keys[keycode] = false; +} + +-(void)handleTouches:(NSNotification*)notification +{ + UIEvent* event = [notification.userInfo objectForKey:@"event"]; + NSArray* touches = [[event allTouches] allObjects]; + + ios_current_touch_count = [touches count]; + + for(int i = 0; i != ios_current_touch_count; i ++) + { + UITouch *touch = [touches objectAtIndex:i]; + CGPoint coord = [touch locationInView:touch.view]; + float scale = [[UIScreen mainScreen] scale]; + + ios_touches[i].is_down = (touch.phase != UITouchPhaseEnded) && (touch.phase != UITouchPhaseCancelled); + ios_touches[i].screen_x = coord.x * scale; + ios_touches[i].screen_y = coord.y * scale; + } +} +@end + +static bool l_ios_is_key_pressed(enum retro_key key) +{ + if ((int)key >= 0 && key < RETROK_LAST) + { + int hidkey = input_translate_rk_to_keysym(key); + return (hidkey < MAX_KEYS) ? ios_keys[hidkey] : false; + } + + return false; +} + +static int16_t l_ios_joypad_device_state(const struct retro_keybind **binds_, + unsigned port_num, unsigned id) +{ + const struct retro_keybind *binds = binds_[port_num]; + if (id < RARCH_BIND_LIST_END) + { + const struct retro_keybind *bind = &binds[id]; + return bind->valid && l_ios_is_key_pressed(bind->key); + } + else + return 0; +} + +static void *ios_input_init(void) +{ + input_init_keyboard_lut(rarch_key_map_hidusage); + + if (!input_driver) + input_driver = [RAInputResponder new]; + + ios_current_touch_count = 0; + memset(ios_touches, 0, sizeof(ios_touches)); + memset(ios_keys, 0, sizeof(ios_keys)); + return (void*)-1; +} + +static void ios_input_free_input(void *data) +{ + (void)data; + input_driver = nil; +} + +static void ios_input_poll(void *data) +{ + for (int i = 0; i != ios_current_touch_count; i ++) + { + input_translate_coord_viewport(ios_touches[i].screen_x, ios_touches[i].screen_y, + &ios_touches[i].fixed_x, &ios_touches[i].fixed_y, + &ios_touches[i].full_x, &ios_touches[i].full_y); + } +} + +static int16_t ios_input_state(void *data, const struct retro_keybind **binds, unsigned port, unsigned device, unsigned index, unsigned id) +{ + switch (device) + { + case RETRO_DEVICE_JOYPAD: + return l_ios_joypad_device_state(binds, port, id); + case RETRO_DEVICE_ANALOG: + return 0; + case RETRO_DEVICE_MOUSE: + return 0; + case RETRO_DEVICE_POINTER: + return 0; + case RARCH_DEVICE_POINTER_SCREEN: + switch (id) + { + case RETRO_DEVICE_ID_POINTER_X: + return (index < ios_current_touch_count) ? ios_touches[index].full_x : 0; + case RETRO_DEVICE_ID_POINTER_Y: + return (index < ios_current_touch_count) ? ios_touches[index].full_y : 0; + case RETRO_DEVICE_ID_POINTER_PRESSED: + return (index < ios_current_touch_count) ? ios_touches[index].is_down : 0; + default: + return 0; + } + case RETRO_DEVICE_KEYBOARD: + return 0; + case RETRO_DEVICE_LIGHTGUN: + return 0; + + default: + return 0; + } +} + +static bool ios_input_key_pressed(void *data, int key) +{ + const struct retro_keybind *binds = g_settings.input.binds[0]; + + if (key >= 0 && key < RARCH_BIND_LIST_END) + { + const struct retro_keybind *bind = &binds[key]; + return l_ios_is_key_pressed(bind->key); + } + + return false; +} + +const input_driver_t input_ios = { + ios_input_init, + ios_input_poll, + ios_input_state, + ios_input_key_pressed, + ios_input_free_input, + "ios_input", +}; + +// Key table static const struct rarch_key_map rarch_key_map_hidusage[] = { { 0x50, RETROK_LEFT }, { 0x4F, RETROK_RIGHT }, @@ -200,124 +289,3 @@ static const struct rarch_key_map rarch_key_map_hidusage[] = { { 0x1D, RETROK_z }, { 0, RETROK_UNKNOWN } }; - -#define MAX_TOUCH 16 -#define MAX_KEYS 256 - -struct -{ - bool is_down; - int16_t screen_x, screen_y; - int16_t fixed_x, fixed_y; - int16_t full_x, full_y; -} ios_touches[MAX_TOUCH]; - -bool ios_keys[MAX_KEYS]; - -uint32_t ios_current_touch_count = 0; - -static bool l_ios_is_key_pressed(enum retro_key key) -{ - if ((int)key >= 0 && key < RETROK_LAST) - { - int hidkey = input_translate_rk_to_keysym(key); - return (hidkey < MAX_KEYS) ? ios_keys[hidkey] : false; - } - - return false; -} - -static int16_t l_ios_joypad_device_state(const struct retro_keybind **binds_, - unsigned port_num, unsigned id) -{ - const struct retro_keybind *binds = binds_[port_num]; - if (id < RARCH_BIND_LIST_END) - { - const struct retro_keybind *bind = &binds[id]; - return bind->valid && l_ios_is_key_pressed(bind->key); - } - else - return 0; -} - -static void *ios_input_init(void) -{ - input_init_keyboard_lut(rarch_key_map_hidusage); - - ios_current_touch_count = 0; - memset(ios_touches, 0, sizeof(ios_touches)); - memset(ios_keys, 0, sizeof(ios_keys)); - return (void*)-1; -} - -static void ios_input_poll(void *data) -{ - for (int i = 0; i != ios_current_touch_count; i ++) - { - input_translate_coord_viewport(ios_touches[i].screen_x, ios_touches[i].screen_y, - &ios_touches[i].fixed_x, &ios_touches[i].fixed_y, - &ios_touches[i].full_x, &ios_touches[i].full_y); - } -} - -static int16_t ios_input_state(void *data, const struct retro_keybind **binds, unsigned port, unsigned device, unsigned index, unsigned id) -{ - switch (device) - { - case RETRO_DEVICE_JOYPAD: - return l_ios_joypad_device_state(binds, port, id); - case RETRO_DEVICE_ANALOG: - return 0; - case RETRO_DEVICE_MOUSE: - return 0; - case RETRO_DEVICE_POINTER: - return 0; - case RARCH_DEVICE_POINTER_SCREEN: - switch (id) - { - case RETRO_DEVICE_ID_POINTER_X: - return (index < ios_current_touch_count) ? ios_touches[index].full_x : 0; - case RETRO_DEVICE_ID_POINTER_Y: - return (index < ios_current_touch_count) ? ios_touches[index].full_y : 0; - case RETRO_DEVICE_ID_POINTER_PRESSED: - return (index < ios_current_touch_count) ? ios_touches[index].is_down : 0; - default: - return 0; - } - case RETRO_DEVICE_KEYBOARD: - return 0; - case RETRO_DEVICE_LIGHTGUN: - return 0; - - default: - return 0; - } -} - -static bool ios_input_key_pressed(void *data, int key) -{ - const struct retro_keybind *binds = g_settings.input.binds[0]; - - if (key >= 0 && key < RARCH_BIND_LIST_END) - { - const struct retro_keybind *bind = &binds[key]; - return l_ios_is_key_pressed(bind->key); - } - - return false; -} - -static void ios_input_free_input(void *data) -{ - (void)data; -} - -const input_driver_t input_ios = { - ios_input_init, - ios_input_poll, - ios_input_state, - ios_input_key_pressed, - ios_input_free_input, - "ios_input", -}; - diff --git a/ios/RetroArch/main.m b/ios/RetroArch/main.m index 2ba3cc50ca..7a65bce6a4 100644 --- a/ios/RetroArch/main.m +++ b/ios/RetroArch/main.m @@ -23,6 +23,7 @@ NSString *const GSEventKeyDownNotification = @"GSEventKeyDownHackNotification"; NSString *const GSEventKeyUpNotification = @"GSEventKeyUpHackNotification"; +NSString *const RATouchNotification = @"RATouchNotification"; @interface RApplication : UIApplication @end @@ -36,11 +37,17 @@ NSString *const GSEventKeyUpNotification = @"GSEventKeyUpHackNotification"; { [super sendEvent:event]; - if ([event respondsToSelector:@selector(_gsEvent)]) + if ([[event allTouches] count]) + { + NSDictionary* inf = [[NSDictionary alloc] initWithObjectsAndKeys: + event, @"event", nil]; + [[NSNotificationCenter defaultCenter] postNotificationName:RATouchNotification object:nil userInfo:inf]; + } + else if ([event respondsToSelector:@selector(_gsEvent)]) { int* eventMem = (int *)(void*)CFBridgingRetain([event performSelector:@selector(_gsEvent)]); int eventType = eventMem ? eventMem[GSEVENT_TYPE] : 0; - + if (eventMem && (eventType == GSEVENT_TYPE_KEYDOWN || eventType == GSEVENT_TYPE_KEYUP)) { // Read keycode from GSEventKey diff --git a/ios/RetroArch/settings/RAButtonGetter.m b/ios/RetroArch/settings/RAButtonGetter.m index cf33276731..00ce7ea536 100644 --- a/ios/RetroArch/settings/RAButtonGetter.m +++ b/ios/RetroArch/settings/RAButtonGetter.m @@ -15,6 +15,8 @@ #import "settings.h" +extern NSString* const GSEventKeyUpNotification; + static const struct { const char* const keyname; From 06659f6e0d1a0d81cf7b3b8130a67fc2cd8e23c6 Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 25 Feb 2013 15:58:16 -0500 Subject: [PATCH 076/108] ios: Refactoring pause menu --- ios/RetroArch.xcodeproj/project.pbxproj | 4 + ios/RetroArch/PauseIndicatorView.xib | 290 ++++++++++++++++++++++++ ios/RetroArch/PauseView.xib | 47 +--- ios/RetroArch/RAGameView.m | 45 ---- ios/RetroArch/RetroArch_iOS.m | 144 +++++++----- 5 files changed, 391 insertions(+), 139 deletions(-) create mode 100644 ios/RetroArch/PauseIndicatorView.xib diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index b19e8900fe..3e284ba004 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -29,6 +29,7 @@ 963F5AC816CC523B009BBD19 /* RAGameView.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC516CC523B009BBD19 /* RAGameView.m */; }; 963F5AC916CC523B009BBD19 /* RAModuleList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC616CC523B009BBD19 /* RAModuleList.m */; }; 965AE29E16D9BF94001D7667 /* ios_input.m in Sources */ = {isa = PBXBuildFile; fileRef = 965AE29D16D9BF94001D7667 /* ios_input.m */; }; + 965AE2A016DA83C1001D7667 /* PauseIndicatorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 965AE29F16DA83C1001D7667 /* PauseIndicatorView.xib */; }; 969EBF6A16D95746003787A2 /* PauseView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 969EBF6916D95746003787A2 /* PauseView.xib */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; @@ -113,6 +114,7 @@ 963F5AC516CC523B009BBD19 /* RAGameView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAGameView.m; sourceTree = ""; }; 963F5AC616CC523B009BBD19 /* RAModuleList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAModuleList.m; sourceTree = ""; }; 965AE29D16D9BF94001D7667 /* ios_input.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ios_input.m; sourceTree = ""; }; + 965AE29F16DA83C1001D7667 /* PauseIndicatorView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PauseIndicatorView.xib; sourceTree = ""; }; 969EBF6916D95746003787A2 /* PauseView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PauseView.xib; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; @@ -325,6 +327,7 @@ 965AE29D16D9BF94001D7667 /* ios_input.m */, 96297A0D16C5ADDA00E6DCE0 /* views.h */, 969EBF6916D95746003787A2 /* PauseView.xib */, + 965AE29F16DA83C1001D7667 /* PauseIndicatorView.xib */, ); path = RetroArch; sourceTree = ""; @@ -629,6 +632,7 @@ 96297A2416C818FF00E6DCE0 /* Icon-72.png in Resources */, 96297A2516C818FF00E6DCE0 /* Icon.png in Resources */, 969EBF6A16D95746003787A2 /* PauseView.xib in Resources */, + 965AE2A016DA83C1001D7667 /* PauseIndicatorView.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/PauseIndicatorView.xib b/ios/RetroArch/PauseIndicatorView.xib new file mode 100644 index 0000000000..b01688c55e --- /dev/null +++ b/ios/RetroArch/PauseIndicatorView.xib @@ -0,0 +1,290 @@ + + + + 1552 + 12C60 + 3084 + 1187.34 + 625.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 2083 + + + IBNSLayoutConstraint + IBProxyObject + IBUIButton + IBUIView + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + + IBFilesOwner + IBIPadFramework + + + IBFirstResponder + IBIPadFramework + + + + 274 + + + + 292 + {768, 1005} + + + + _NS:9 + NO + IBIPadFramework + 0 + 0 + 1 + Pause + + 3 + MQA + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + 3 + MC41AA + + + 2 + 15 + + + Helvetica-Bold + 15 + 16 + + + + {{0, 20}, {768, 1004}} + + + + {250, 250} + + 3 + MQA + + 2 + + + NO + 0.0 + + 2 + + IBIPadFramework + + + + + + + pauseGamePressed: + + + 7 + + 57 + + + + + + 0 + + + + + + 1 + + + + + 4 + 0 + + 4 + 1 + + 0.0 + + 1000 + + 8 + 29 + 3 + + + + 3 + 0 + + 3 + 1 + + 0.0 + + 1000 + + 8 + 29 + 3 + + + + 5 + 0 + + 5 + 1 + + 0.0 + + 1000 + + 8 + 29 + 3 + + + + 6 + 0 + + 6 + 1 + + 0.0 + + 1000 + + 8 + 29 + 3 + + + + + + + -1 + + + File's Owner + + + -2 + + + + + 54 + + + + + + 61 + + + + + 63 + + + + + 69 + + + + + 70 + + + + + + + RetroArch_iOS + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + 70 + + + + + NSLayoutConstraint + NSObject + + IBProjectSource + ./Classes/NSLayoutConstraint.h + + + + RetroArch_iOS + UIResponder + + pauseGamePressed: + id + + + pauseGamePressed: + + pauseGamePressed: + id + + + + IBProjectSource + ./Classes/RetroArch_iOS.h + + + + + 0 + IBIPadFramework + YES + 3 + YES + 2083 + + diff --git a/ios/RetroArch/PauseView.xib b/ios/RetroArch/PauseView.xib index 80b8172276..c98ae28134 100644 --- a/ios/RetroArch/PauseView.xib +++ b/ios/RetroArch/PauseView.xib @@ -41,7 +41,6 @@ 292 {{20, 20}, {728, 44}} - _NS:9 NO @@ -77,8 +76,6 @@ 292 {{20, 71}, {728, 44}} - - _NS:9 NO IBIPadFramework @@ -98,7 +95,6 @@ {{0, 20}, {768, 1004}} - 3 @@ -107,6 +103,8 @@ 2 + NO + 0.0 2 @@ -126,12 +124,12 @@ - resumeGamePressed: + closePauseMenu: 7 - 24 + 25 @@ -329,42 +327,9 @@ - 24 - - - - - NSLayoutConstraint - NSObject - - IBProjectSource - ./Classes/NSLayoutConstraint.h - - - - RetroArch_iOS - UIResponder - - id - id - - - - closeGamePressed: - id - - - resumeGamePressed: - id - - - - IBProjectSource - ./Classes/RetroArch_iOS.h - - - + 25 + 0 IBIPadFramework YES diff --git a/ios/RetroArch/RAGameView.m b/ios/RetroArch/RAGameView.m index 5fdc1e9581..77cdbde6d7 100644 --- a/ios/RetroArch/RAGameView.m +++ b/ios/RetroArch/RAGameView.m @@ -23,8 +23,6 @@ static bool is_syncing = true; @implementation RAGameView { EAGLContext* _glContext; - UIButton* _notifyButton; - UILabel* _notifyLabel; } - (id)init @@ -42,49 +40,6 @@ static bool is_syncing = true; return self; } -- (void)viewDidAppear:(BOOL)animated -{ - CGSize size = self.view.bounds.size; - float tenpct = size.width / 10.0f; - - _notifyButton = [[UIButton alloc] initWithFrame:CGRectMake(tenpct * 4.0f, 0, tenpct * 2.0f, size.height / 10.0f)]; - _notifyButton.backgroundColor = [UIColor redColor]; - _notifyButton.opaque = NO; - _notifyButton.userInteractionEnabled = NO; - - _notifyLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height / 10.0f)]; - _notifyLabel.backgroundColor = [UIColor colorWithRed:0.2f green:0.2f blue: 0.5f alpha:0.5f]; - _notifyLabel.text = @"Triple tap to exit."; - _notifyLabel.textAlignment = NSTextAlignmentCenter; - _notifyLabel.opaque = NO; - _notifyLabel.userInteractionEnabled = NO; - - [self.view addSubview:_notifyButton]; - [self.view addSubview:_notifyLabel]; - [self performSelector:@selector(hideNotify) withObject:nil afterDelay:3.0f]; -} - -- (void)hideNotify -{ - if (_notifyLabel && _notifyButton) - { - // TODO: Actually removing these views will cause an ugly flash in the game window... - [UIView animateWithDuration:0.2 - animations:^{_notifyButton.alpha = 0.0;} - completion:^(BOOL finished){ _notifyButton.hidden = YES; _notifyButton = nil; }]; - - [UIView animateWithDuration:0.2 - animations:^{_notifyLabel.alpha = 0.0;} - completion:^(BOOL finished){ _notifyLabel.hidden = YES; _notifyLabel = nil; }]; - } -} - -- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration -{ - _notifyButton.alpha = 0.0f; - _notifyLabel.alpha = 0.0f; -} - - (void)needsToDie { glFinish(); diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 6ecceb273e..e699adba83 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -17,6 +17,8 @@ #include "rarch_wrapper.h" #include "general.h" +#define ALMOST_INVISIBLE .021f + @interface RANavigator : UINavigationController // 0 if no RAGameView is in the navigator // 1 if a RAGameView is the top @@ -27,6 +29,20 @@ @end @implementation RANavigator +{ + RetroArch_iOS* _delegate; +} + +- (id)initWithAppDelegate:(RetroArch_iOS*)delegate +{ + self = [super init]; + + assert(delegate); + _delegate = delegate; + + return self; +} + - (void)pushViewController:(UIViewController*)theView isGame:(BOOL)game { assert(!game || self.gameAndAbove == 0); @@ -51,6 +67,12 @@ self.navigationBarHidden = poppingToGame; return [super popViewControllerAnimated:!poppingToGame && !poppingFromGame]; } + +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration +{ + [_delegate performSelector:@selector(screenDidRotate) withObject:nil afterDelay:.01f]; +} + @end @implementation RetroArch_iOS @@ -58,7 +80,9 @@ UIWindow* _window; RANavigator* _navigator; NSTimer* _gameTimer; + UIView* _pauseView; + UIView* _pauseIndicatorView; bool _isPaused; bool _isRunning; @@ -79,11 +103,6 @@ return (RetroArch_iOS*)[[UIApplication sharedApplication] delegate]; } -- (void)showSettings -{ - [self pushViewController:[RASettingsList new] isGame:NO]; -} - - (NSString*)configFilePath { if (self.module_path) @@ -115,36 +134,62 @@ // Load pause menu UINib* xib = [UINib nibWithNibName:@"PauseView" bundle:nil]; _pauseView = [[xib instantiateWithOwner:self options:nil] lastObject]; - _pauseView.opaque = NO; - _pauseView.alpha = 0.0f; + + xib = [UINib nibWithNibName:@"PauseIndicatorView" bundle:nil]; + _pauseIndicatorView = [[xib instantiateWithOwner:self options:nil] lastObject]; + // Show status bar [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone]; // Setup window - _navigator = [RANavigator new]; + _navigator = [[RANavigator alloc] initWithAppDelegate:self]; [_navigator pushViewController: [RAModuleList new] animated:YES]; _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; _window.rootViewController = _navigator; [_window makeKeyAndVisible]; - - // Setup keyboard hack } #pragma mark VIEW MANAGEMENT +- (void)screenDidRotate +{ + UIInterfaceOrientation orientation = _navigator.interfaceOrientation; + CGRect screenSize = [[UIScreen mainScreen] bounds]; + + const float width = ((int)orientation < 3) ? CGRectGetWidth(screenSize) : CGRectGetHeight(screenSize); + const float height = ((int)orientation < 3) ? CGRectGetHeight(screenSize) : CGRectGetWidth(screenSize); + + float tenpctw = width / 10.0f; + float tenpcth = height / 10.0f; + + _pauseView.frame = CGRectMake(width / 2.0f - 150.0f, height / 2.0f - 150.0f, 300.0f, 300.0f); + _pauseIndicatorView.frame = CGRectMake(tenpctw * 4.0f, 0.0f, tenpctw * 2.0f, tenpcth); +} + - (void)pushViewController:(UIViewController*)theView isGame:(BOOL)game { - if (game) - [theView.view addSubview:_pauseView]; - [_navigator pushViewController:theView isGame:game]; + + if (game) + { + _pauseIndicatorView.alpha = ALMOST_INVISIBLE; + _pauseIndicatorView.userInteractionEnabled = YES; + + [theView.view addSubview:_pauseView]; + [theView.view addSubview:_pauseIndicatorView]; + } + [self startTimer]; + [self performSelector:@selector(screenDidRotate) withObject:nil afterDelay:.01f]; } - (void)popViewController { if (_navigator.gameAndAbove == 1) + { [_pauseView removeFromSuperview]; + [_pauseIndicatorView removeFromSuperview]; + } [_navigator popViewControllerAnimated:YES]; } @@ -235,50 +280,16 @@ uninit_drivers(); } -#pragma mark INPUT -- (void)touchesBegan:(NSSet*)theTouches withEvent:(UIEvent *)event -{ - NSArray* touches = [theTouches allObjects]; - UIView* view = _window.rootViewController.view; - - const int count = [touches count]; - for(int i = 0; i != count; i ++) - { - UITouch* touch = [touches objectAtIndex:i]; - CGPoint coord = [touch locationInView:view]; - - // Exit hack! - if (!_isPaused && _navigator.gameAndAbove == 1 && touch.tapCount == 3) - { - if (coord.y < view.bounds.size.height / 10.0f) - { - float tenpct = view.bounds.size.width / 10.0f; - if (coord.x >= tenpct * 4 && coord.x <= tenpct * 6) - { - _isPaused = true; - _pauseView.frame = CGRectMake(view.bounds.size.width / 2.0f - 100.0f, view.bounds.size.height / 2.0f - 100.0f, 200.0f, 200.0f); - - [UIView animateWithDuration:0.2 - animations:^{_pauseView.alpha = 1.0f;} - completion:^(BOOL finished){}]; - } - } - } - } -} - #pragma mark PAUSE MENU -- (IBAction)closeGamePressed:(id)sender -{ - [self closeGame]; - _pauseView = nil; -} - -- (IBAction)resumeGamePressed:(id)sender +- (IBAction)closePauseMenu:(id)sender { if (_isPaused) [UIView animateWithDuration:0.2 - animations:^{_pauseView.alpha = 0.0;} + animations:^ + { + _pauseView.alpha = 0.0f; + _pauseIndicatorView.alpha = ALMOST_INVISIBLE; + } completion:^(BOOL finished) { _isPaused = false; @@ -287,5 +298,32 @@ ]; } +- (IBAction)closeGamePressed:(id)sender +{ + [self closePauseMenu:sender]; + [self closeGame]; +} + +- (IBAction)pauseGamePressed:(id)sender +{ + if (_isRunning && !_isPaused && _navigator.gameAndAbove == 1) + { + _isPaused = true; + + [UIView animateWithDuration:0.2 + animations:^ + { + _pauseIndicatorView.alpha = ALMOST_INVISIBLE; + _pauseView.alpha = 1.0f; + } + completion:^(BOOL finished){}]; + } +} + +- (IBAction)showSettings +{ + [self pushViewController:[RASettingsList new] isGame:NO]; +} + @end From 2f25044915d7bd8aa014c5d6cfb109a267e50fb7 Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 25 Feb 2013 16:20:54 -0500 Subject: [PATCH 077/108] ios: More refactoring --- ios/RetroArch/RetroArch_iOS.h | 2 +- ios/RetroArch/RetroArch_iOS.m | 84 +++++++++++++++++++---------------- 2 files changed, 47 insertions(+), 39 deletions(-) diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index 4b035e82bd..c81b2abf7c 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -23,7 +23,7 @@ - (void)runGame:(NSString*)path; - (void)pushViewController:(UIViewController*)theView isGame:(BOOL)game; -- (void)popViewController; +- (UIViewController*)popViewController; - (NSString*)configFilePath; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index e699adba83..24ea59ca2f 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -20,12 +20,6 @@ #define ALMOST_INVISIBLE .021f @interface RANavigator : UINavigationController -// 0 if no RAGameView is in the navigator -// 1 if a RAGameView is the top -// 2+ if there are views pushed ontop of the RAGameView -@property unsigned gameAndAbove; - -- (void)pushViewController:(UIViewController*)theView isGame:(BOOL)game; @end @implementation RANavigator @@ -43,29 +37,14 @@ return self; } -- (void)pushViewController:(UIViewController*)theView isGame:(BOOL)game -{ - assert(!game || self.gameAndAbove == 0); - - if (game || self.gameAndAbove) self.gameAndAbove ++; - - [[UIApplication sharedApplication] setStatusBarHidden:game withAnimation:UIStatusBarAnimationNone]; - self.navigationBarHidden = game; - [self pushViewController:theView animated:!(self.gameAndAbove == 1 || self.gameAndAbove == 2)]; -} - - (UIViewController *)popViewControllerAnimated:(BOOL)animated { - const bool poppingFromGame = self.gameAndAbove == 1; - const bool poppingToGame = self.gameAndAbove == 2; - if (self.gameAndAbove) self.gameAndAbove --; - - if (self.gameAndAbove == 1) - [[RetroArch_iOS get] performSelector:@selector(startTimer)]; + return [_delegate popViewController]; +} - [[UIApplication sharedApplication] setStatusBarHidden:poppingToGame withAnimation:UIStatusBarAnimationNone]; - self.navigationBarHidden = poppingToGame; - return [super popViewControllerAnimated:!poppingToGame && !poppingFromGame]; +- (UIViewController*)reallyPopViewControllerAnimated:(BOOL)animated +{ + return [super popViewControllerAnimated:animated]; } - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration @@ -83,9 +62,16 @@ UIView* _pauseView; UIView* _pauseIndicatorView; + RAGameView* _game; bool _isPaused; bool _isRunning; + + // 0 if no RAGameView is in the navigator + // 1 if a RAGameView is the top + // 2+ if there are views pushed ontop of the RAGameView + unsigned _gameAndAbove; + } + (void)displayErrorMessage:(NSString*)message @@ -106,9 +92,7 @@ - (NSString*)configFilePath { if (self.module_path) - { return [NSString stringWithFormat:@"%@/%@.cfg", self.system_directory, [[self.module_path lastPathComponent] stringByDeletingPathExtension]]; - } return nil; } @@ -168,30 +152,54 @@ - (void)pushViewController:(UIViewController*)theView isGame:(BOOL)game { - [_navigator pushViewController:theView isGame:game]; + assert(!game || _gameAndAbove == 0); + + _gameAndAbove += (game || _gameAndAbove) ? 1 : 0; + + // Update status and navigation bars + [[UIApplication sharedApplication] setStatusBarHidden:game withAnimation:UIStatusBarAnimationNone]; + _navigator.navigationBarHidden = game; + + // + [_navigator pushViewController:theView animated:!(_gameAndAbove == 1 || _gameAndAbove == 2)]; if (game) { + _game = (RAGameView*)theView; + _pauseIndicatorView.alpha = ALMOST_INVISIBLE; _pauseIndicatorView.userInteractionEnabled = YES; [theView.view addSubview:_pauseView]; [theView.view addSubview:_pauseIndicatorView]; + + [self startTimer]; + [self performSelector:@selector(screenDidRotate) withObject:nil afterDelay:.01f]; } - - [self startTimer]; - [self performSelector:@selector(screenDidRotate) withObject:nil afterDelay:.01f]; } -- (void)popViewController +- (UIViewController*)popViewController { - if (_navigator.gameAndAbove == 1) + const bool poppingFromGame = _gameAndAbove == 1; + const bool poppingToGame = _gameAndAbove == 2; + + _gameAndAbove -= (_gameAndAbove) ? 1 : 0; + + if (poppingToGame) + [self startTimer]; + + // Update status and navigation bar + [[UIApplication sharedApplication] setStatusBarHidden:poppingToGame withAnimation:UIStatusBarAnimationNone]; + _navigator.navigationBarHidden = poppingToGame; + + // + if (poppingFromGame) { [_pauseView removeFromSuperview]; [_pauseIndicatorView removeFromSuperview]; } - - [_navigator popViewControllerAnimated:YES]; + + return [_navigator reallyPopViewControllerAnimated:!poppingToGame && !poppingFromGame]; } #pragma mark EMULATION @@ -237,7 +245,7 @@ - (void)iterate { - if (_isPaused || !_isRunning || _navigator.gameAndAbove != 1) + if (_isPaused || !_isRunning || _gameAndAbove != 1) [self stopTimer]; else if (_isRunning && !rarch_main_iterate()) [self closeGame]; @@ -306,7 +314,7 @@ - (IBAction)pauseGamePressed:(id)sender { - if (_isRunning && !_isPaused && _navigator.gameAndAbove == 1) + if (_isRunning && !_isPaused && _gameAndAbove == 1) { _isPaused = true; From 2b07954fac28c97700a5b765f6852a1cae4a2ec6 Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 25 Feb 2013 16:51:51 -0500 Subject: [PATCH 078/108] ios: Add Reset, Save State, Load State and State slot selection to the pause menu. --- ios/RetroArch/PauseIndicatorView.xib | 41 +- ios/RetroArch/PauseView.xib | 700 +++++++++++++++++++++++---- ios/RetroArch/RetroArch_iOS.m | 58 ++- 3 files changed, 659 insertions(+), 140 deletions(-) diff --git a/ios/RetroArch/PauseIndicatorView.xib b/ios/RetroArch/PauseIndicatorView.xib index b01688c55e..78973a1ccb 100644 --- a/ios/RetroArch/PauseIndicatorView.xib +++ b/ios/RetroArch/PauseIndicatorView.xib @@ -41,8 +41,6 @@ 292 {768, 1005} - - _NS:9 NO IBIPadFramework @@ -75,7 +73,6 @@ {{0, 20}, {768, 1004}} - {250, 250} @@ -97,12 +94,12 @@ - pauseGamePressed: + showPauseMenu: 7 - 57 + 71 @@ -247,39 +244,9 @@ - 70 - - - - - NSLayoutConstraint - NSObject - - IBProjectSource - ./Classes/NSLayoutConstraint.h - - - - RetroArch_iOS - UIResponder - - pauseGamePressed: - id - - - pauseGamePressed: - - pauseGamePressed: - id - - - - IBProjectSource - ./Classes/RetroArch_iOS.h - - - + 71 + 0 IBIPadFramework YES diff --git a/ios/RetroArch/PauseView.xib b/ios/RetroArch/PauseView.xib index c98ae28134..f81d6519b1 100644 --- a/ios/RetroArch/PauseView.xib +++ b/ios/RetroArch/PauseView.xib @@ -14,6 +14,7 @@ IBNSLayoutConstraint IBProxyObject IBUIButton + IBUISegmentedControl IBUIView @@ -39,16 +40,16 @@ 292 - {{20, 20}, {728, 44}} + {{160, 237}, {120, 44}} - + _NS:9 NO IBIPadFramework 0 0 1 - Return to Loader + Exit 3 MQA @@ -74,8 +75,10 @@ 292 - {{20, 71}, {728, 44}} + {{20, 20}, {260, 44}} + + _NS:9 NO IBIPadFramework @@ -92,10 +95,154 @@ + + + 292 + {{20, 237}, {120, 44}} + + + + _NS:9 + NO + IBIPadFramework + 0 + 0 + 1 + Reset + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + + 292 + {{20, 186}, {120, 44}} + + + + _NS:9 + NO + IBIPadFramework + 0 + 0 + 1 + Save State + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + + 292 + {{160, 186}, {120, 44}} + + + + _NS:9 + NO + IBIPadFramework + 0 + 0 + 1 + Load State + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + + 292 + {{20, 135}, {260, 44}} + + + + _NS:9 + NO + 1 + IBIPadFramework + 10 + 0 + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + {0, 0} + {0, 0} + {0, 0} + {0, 0} + {0, 0} + {0, 0} + {0, 0} + {0, 0} + {0, 0} + {0, 0} + + + + + + + + + + + + + + - {{0, 20}, {768, 1004}} + {{0, 20}, {300, 300}} - + + 3 MQA @@ -108,6 +255,10 @@ 2 + + IBUISimulatedFreeformSizeMetricsSentinel + Freeform + IBIPadFramework @@ -131,6 +282,42 @@ 25 + + + resetGame: + + + 7 + + 138 + + + + saveState: + + + 7 + + 137 + + + + loadState: + + + 7 + + 136 + + + + chooseState: + + + 13 + + 139 + @@ -144,7 +331,215 @@ 1 + + + 5 + 0 + + 5 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 4 + 0 + + 4 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + 6 + 0 + + 6 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 6 + 0 + + 6 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 11 + 0 + + 11 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 4 + 0 + + 4 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 3 + 0 + + 4 + 1 + + 8 + + 1000 + + 6 + 24 + 3 + + + + 5 + 0 + + 5 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 3 + 0 + + 4 + 1 + + 8 + + 1000 + + 6 + 24 + 3 + + + + 6 + 0 + + 6 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 5 + 0 + + 5 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 6 + 0 + + 6 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 5 + 0 + + 5 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + 6 0 @@ -160,56 +555,8 @@ 29 3 - + - 3 - 0 - - 4 - 1 - - 8 - - 1000 - - 6 - 24 - 3 - - - - 5 - 0 - - 5 - 1 - - 20 - - 1000 - - 8 - 29 - 3 - - - - 6 - 0 - - 6 - 1 - - 20 - - 1000 - - 8 - 29 - 3 - - - 5 0 @@ -225,7 +572,7 @@ 3 - + 3 0 @@ -240,8 +587,12 @@ 29 3 - + + + + + @@ -259,41 +610,160 @@ 12 - - - - 13 - - - - - 14 - - - - - 16 - + 17 + - 20 + 30 + + + + + + 86 + + + + + 7 + 0 + + 0 + 1 + + 120 + + 1000 + + 3 + 9 + 1 + + + + + + 88 + + + + + 89 + + + + + 94 + + + + + 97 + + + + + 98 + + + + + 113 - 21 + 115 - 22 - + 116 + + + + + 118 + + + + + 119 + + + + + 121 + + + + + 122 + + + + + 7 + 0 + + 0 + 1 + + 120 + + 1000 + + 3 + 9 + 1 + + + + + + 125 + + + + + 127 + + + + + 129 + + + + + 130 + + + + + 131 + + + + + 132 + + + + + 133 + + + + + 135 + @@ -304,32 +774,88 @@ UIResponder com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - + - - + + + + + + + + + + + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 25 + 139 + + + + + NSLayoutConstraint + NSObject + + IBProjectSource + ./Classes/NSLayoutConstraint.h + + + + RetroArch_iOS + UIResponder + + IBProjectSource + ./Classes/RetroArch_iOS.h + + + - 0 IBIPadFramework YES diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 24ea59ca2f..2d3282a4e4 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -289,6 +289,48 @@ } #pragma mark PAUSE MENU +- (IBAction)showPauseMenu:(id)sender +{ + if (_isRunning && !_isPaused && _gameAndAbove == 1) + { + _isPaused = true; + + UISegmentedControl* stateSelect = (UISegmentedControl*)[_pauseView viewWithTag:1]; + stateSelect.selectedSegmentIndex = (g_extern.state_slot < 10) ? g_extern.state_slot : -1; + + [UIView animateWithDuration:0.2 + animations:^ + { + _pauseIndicatorView.alpha = ALMOST_INVISIBLE; + _pauseView.alpha = 1.0f; + } + completion:^(BOOL finished){}]; + } +} + +- (IBAction)resetGame:(id)sender +{ + if (_isRunning) rarch_game_reset(); + [self closePauseMenu:sender]; +} + +- (IBAction)loadState:(id)sender +{ + if (_isRunning) rarch_load_state(); + [self closePauseMenu:sender]; +} + +- (IBAction)saveState:(id)sender +{ + if (_isRunning) rarch_save_state(); + [self closePauseMenu:sender]; +} + +- (IBAction)chooseState:(id)sender +{ + g_extern.state_slot = ((UISegmentedControl*)sender).selectedSegmentIndex; +} + - (IBAction)closePauseMenu:(id)sender { if (_isPaused) @@ -312,22 +354,6 @@ [self closeGame]; } -- (IBAction)pauseGamePressed:(id)sender -{ - if (_isRunning && !_isPaused && _gameAndAbove == 1) - { - _isPaused = true; - - [UIView animateWithDuration:0.2 - animations:^ - { - _pauseIndicatorView.alpha = ALMOST_INVISIBLE; - _pauseView.alpha = 1.0f; - } - completion:^(BOOL finished){}]; - } -} - - (IBAction)showSettings { [self pushViewController:[RASettingsList new] isGame:NO]; From d2119b75b1daeeeb6e81a6df8c8d6414eceff3c5 Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 25 Feb 2013 20:51:27 -0500 Subject: [PATCH 079/108] ios: Remove regex filtering of directories. Its use case doesn't really apply to mobile devices. --- ios/RetroArch.xcodeproj/project.pbxproj | 4 -- ios/RetroArch/RADirectoryFilterList.m | 92 ------------------------- ios/RetroArch/RADirectoryGrid.m | 23 +++---- ios/RetroArch/RADirectoryList.m | 44 ++++-------- ios/RetroArch/RAModuleList.m | 4 +- ios/RetroArch/browser.h | 13 ++-- ios/RetroArch/browser.m | 23 +++---- ios/RetroArch/views.h | 6 -- 8 files changed, 42 insertions(+), 167 deletions(-) delete mode 100644 ios/RetroArch/RADirectoryFilterList.m diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 3e284ba004..461c22e844 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -83,7 +83,6 @@ 96AFAFAC16C1E279009DE44C /* state_tracker.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF7B16C1E00A009DE44C /* state_tracker.c */; }; 96AFAFAD16C1EEE9009DE44C /* sinc.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEF716C1DC73009DE44C /* sinc.c */; }; 96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFC916C1FBC0009DE44C /* input_common.c */; }; - 96C19C2216D2F3BA00FE8D5A /* RADirectoryFilterList.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2116D2F3BA00FE8D5A /* RADirectoryFilterList.m */; }; 96C19C2416D453BA00FE8D5A /* RADirectoryGrid.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2316D453BA00FE8D5A /* RADirectoryGrid.m */; }; 96C19C2916D5A56500FE8D5A /* browser.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2816D5A56400FE8D5A /* browser.m */; }; 96C19C3016D7045700FE8D5A /* RAConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2F16D7045700FE8D5A /* RAConfig.m */; }; @@ -232,7 +231,6 @@ 96AFAFCA16C1FBC0009DE44C /* input_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = input_common.h; sourceTree = ""; }; 96AFAFCE16C1FBC0009DE44C /* overlay.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = overlay.c; sourceTree = ""; }; 96AFAFCF16C1FBC0009DE44C /* overlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = overlay.h; sourceTree = ""; }; - 96C19C2116D2F3BA00FE8D5A /* RADirectoryFilterList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RADirectoryFilterList.m; sourceTree = ""; }; 96C19C2316D453BA00FE8D5A /* RADirectoryGrid.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RADirectoryGrid.m; sourceTree = ""; }; 96C19C2516D455BE00FE8D5A /* browser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = browser.h; sourceTree = ""; }; 96C19C2616D455BE00FE8D5A /* rarch_wrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rarch_wrapper.h; sourceTree = ""; }; @@ -564,7 +562,6 @@ children = ( 96C19C2516D455BE00FE8D5A /* browser.h */, 96C19C2816D5A56400FE8D5A /* browser.m */, - 96C19C2116D2F3BA00FE8D5A /* RADirectoryFilterList.m */, 96C19C2316D453BA00FE8D5A /* RADirectoryGrid.m */, 963F5AC416CC523B009BBD19 /* RADirectoryList.m */, ); @@ -700,7 +697,6 @@ 963F5AC816CC523B009BBD19 /* RAGameView.m in Sources */, 963F5AC916CC523B009BBD19 /* RAModuleList.m in Sources */, 96096DD816D1ABAF00BF4499 /* RAModuleInfoList.m in Sources */, - 96C19C2216D2F3BA00FE8D5A /* RADirectoryFilterList.m in Sources */, 96C19C2416D453BA00FE8D5A /* RADirectoryGrid.m in Sources */, 96C19C2916D5A56500FE8D5A /* browser.m in Sources */, 96C19C3016D7045700FE8D5A /* RAConfig.m in Sources */, diff --git a/ios/RetroArch/RADirectoryFilterList.m b/ios/RetroArch/RADirectoryFilterList.m deleted file mode 100644 index 02fb61dde5..0000000000 --- a/ios/RetroArch/RADirectoryFilterList.m +++ /dev/null @@ -1,92 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2013 - Jason Fetters - * - * RetroArch 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 Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch 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 RetroArch. - * If not, see . - */ - -#import "RAConfig.h" -#import "browser.h" - -@implementation RADirectoryFilterList -{ - NSString* _path; - - RAConfig* _filterList; - unsigned _filterCount; -} - -+ (RADirectoryFilterList*) directoryFilterListAtPath:(NSString*)path useExpression:(NSRegularExpression**)regex -{ - if (regex) - *regex = nil; - - if (path && ra_ios_is_file([path stringByAppendingPathComponent:@".rafilter"])) - { - RAConfig* configFile = [[RAConfig alloc] initWithPath:[path stringByAppendingPathComponent:@".rafilter"]]; - unsigned filterCount = [configFile getUintNamed:@"filter_count" withDefault:0]; - - if (filterCount > 1) - return [[RADirectoryFilterList alloc] initWithPath:path config:configFile]; - - if (regex && filterCount == 1) - { - NSString* expr = [configFile getStringNamed:@"filter_1_regex" withDefault:@".*"]; - *regex = [NSRegularExpression regularExpressionWithPattern:expr options:0 error:nil]; - } - } - - return nil; -} - -- (id)initWithPath:(NSString*)path config:(RAConfig*)config -{ - self = [super initWithStyle:UITableViewStylePlain]; - - _path = path; - _filterList = config; - _filterCount = [_filterList getUintNamed:@"filter_count" withDefault:0]; - - if (_filterCount == 0) - [RetroArch_iOS displayErrorMessage:@"No valid filters were found."]; - - [self setTitle: [path lastPathComponent]]; - return self; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath -{ - NSString* regex = [NSString stringWithFormat:@"filter_%d_regex", indexPath.row + 1]; - regex = [_filterList getStringNamed:regex withDefault:@".*"]; - - NSRegularExpression* expr = [NSRegularExpression regularExpressionWithPattern:regex options:0 error:nil]; - - [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:_path filter:expr] isGame:NO]; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -{ - return _filterCount ? _filterCount : 1; -} - -- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath -{ - NSString* name = [NSString stringWithFormat:@"filter_%d_name", indexPath.row + 1]; - name = [_filterList getStringNamed:name withDefault:@"BAD NAME"]; - - UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"filter"]; - cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"filter"]; - cell.textLabel.text = name; - - return cell; -} - -@end diff --git a/ios/RetroArch/RADirectoryGrid.m b/ios/RetroArch/RADirectoryGrid.m index d48d9efa2c..b97ec9ea0c 100644 --- a/ios/RetroArch/RADirectoryGrid.m +++ b/ios/RetroArch/RADirectoryGrid.m @@ -20,24 +20,23 @@ { NSString* _path; NSArray* _list; + RAConfig* _config; } -- (id)initWithPath:(NSString*)path filter:(NSRegularExpression*)regex +- (id)initWithPath:(NSString*)path config:(RAConfig*)config { - _path = path ? path : ra_ios_get_browser_root(); - - // - RAConfig* config = [[RAConfig alloc] initWithPath:[NSString stringWithFormat:@"%@/.coverart/.config", _path]]; + _path = path; + _config = config; + _list = ra_ios_list_directory(_path); - UICollectionViewFlowLayout* layout = [UICollectionViewFlowLayout new]; - layout.itemSize = CGSizeMake([config getUintNamed:@"item_width" withDefault:100], [config getUintNamed:@"item_height" withDefault:100]); - self = [super initWithCollectionViewLayout:layout]; - - _list = ra_ios_list_directory(_path, regex); - self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; [self setTitle: [_path lastPathComponent]]; + // Init collection view + UICollectionViewFlowLayout* layout = [UICollectionViewFlowLayout new]; + layout.itemSize = CGSizeMake([config getUintNamed:@"cover_width" withDefault:100], [config getUintNamed:@"cover_height" withDefault:100]); + self = [super initWithCollectionViewLayout:layout]; + [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"dircell"]; [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"textcell"]; [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"imagecell"]; @@ -60,7 +59,7 @@ RADirectoryItem* path = [_list objectAtIndex: indexPath.row]; if(path.isDirectory) - [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:path.path] isGame:NO]; + [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListOrGridWithPath:path.path] isGame:NO]; else [[RetroArch_iOS get] runGame:path.path]; } diff --git a/ios/RetroArch/RADirectoryList.m b/ios/RetroArch/RADirectoryList.m index a27a86c636..f7f2f97b1e 100644 --- a/ios/RetroArch/RADirectoryList.m +++ b/ios/RetroArch/RADirectoryList.m @@ -15,53 +15,35 @@ #import "browser.h" -static NSString* check_path(NSString* path) -{ - if (path && !ra_ios_is_directory(path)) - { - [RetroArch_iOS displayErrorMessage:@"Browsed path is not a directory."]; - return nil; - } - else - return path; -} - @implementation RADirectoryList { NSString* _path; NSArray* _list; + RAConfig* _config; } -+ (id)directoryListWithPath:(NSString*)path ++ (id)directoryListOrGridWithPath:(NSString*)path { - path = check_path(path); - - NSRegularExpression* expr = nil; - RADirectoryFilterList* filterList = [RADirectoryFilterList directoryFilterListAtPath:path useExpression:&expr]; - - return filterList ? filterList : [RADirectoryList directoryListWithPath:path filter:expr]; -} - -+ (id)directoryListWithPath:(NSString*)path filter:(NSRegularExpression*)regex -{ - path = check_path(path); + path = ra_ios_check_path(path); + RAConfig* config = [[RAConfig alloc] initWithPath:[path stringByAppendingPathComponent:@".raconfig"]]; if ([UICollectionViewController instancesRespondToSelector:@selector(initWithCollectionViewLayout:)]) { - NSString* coverDir = path ? [path stringByAppendingPathComponent:@".coverart"] : nil; - if (coverDir && ra_ios_is_directory(coverDir)) - return [[RADirectoryGrid alloc] initWithPath:path filter:regex]; + NSString* coverDir = [path stringByAppendingPathComponent:@".coverart"]; + if (ra_ios_is_directory(coverDir)) + return [[RADirectoryGrid alloc] initWithPath:path config:config]; } - return [[RADirectoryList alloc] initWithPath:path filter:regex]; + return [[RADirectoryList alloc] initWithPath:path config:config]; } -- (id)initWithPath:(NSString*)path filter:(NSRegularExpression*)regex +- (id)initWithPath:(NSString*)path config:(RAConfig*)config { self = [super initWithStyle:UITableViewStylePlain]; - _path = path ? path : ra_ios_get_browser_root(); - _list = ra_ios_list_directory(_path, regex); + _path = path; + _config = config; + _list = ra_ios_list_directory(_path); self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; [self setTitle: [_path lastPathComponent]]; @@ -74,7 +56,7 @@ static NSString* check_path(NSString* path) RADirectoryItem* path = [_list objectAtIndex: indexPath.row]; if(path.isDirectory) - [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:path.path] isGame:NO]; + [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListOrGridWithPath:path.path] isGame:NO]; else [[RetroArch_iOS get] runGame:path.path]; } diff --git a/ios/RetroArch/RAModuleList.m b/ios/RetroArch/RAModuleList.m index be37cf1e3e..30e633af88 100644 --- a/ios/RetroArch/RAModuleList.m +++ b/ios/RetroArch/RAModuleList.m @@ -13,6 +13,8 @@ * If not, see . */ +#import "browser.h" + @implementation RAModuleList { NSMutableArray* _modules; @@ -59,7 +61,7 @@ RAModuleInfo* info = (RAModuleInfo*)[_modules objectAtIndex:indexPath.row]; [RetroArch_iOS get].module_path = info.path; - [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListWithPath:nil] isGame:NO]; + [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListOrGridWithPath:nil] isGame:NO]; } - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath diff --git a/ios/RetroArch/browser.h b/ios/RetroArch/browser.h index ffaa75850f..85cf74d42e 100644 --- a/ios/RetroArch/browser.h +++ b/ios/RetroArch/browser.h @@ -15,8 +15,8 @@ extern BOOL ra_ios_is_directory(NSString* path); extern BOOL ra_ios_is_file(NSString* path); -extern NSArray* ra_ios_list_directory(NSString* path, NSRegularExpression* regex); -extern NSString* ra_ios_get_browser_root(); +extern NSArray* ra_ios_list_directory(NSString* path); +extern NSString* ra_ios_check_path(NSString* path); @interface RADirectoryItem : NSObject @property (strong) NSString* path; @@ -25,11 +25,10 @@ extern NSString* ra_ios_get_browser_root(); @end @interface RADirectoryGrid : UICollectionViewController -- (id)initWithPath:(NSString*)path filter:(NSRegularExpression*)regex; +- (id)initWithPath:(NSString*)path config:(RAConfig*)config; @end -@interface RADirectoryFilterList : UITableViewController -// Check path to see if a directory filter list is needed. -// If one is not needed useExpression will be set to a default expression to use. -+ (RADirectoryFilterList*) directoryFilterListAtPath:(NSString*)path useExpression:(NSRegularExpression**)regex; +@interface RADirectoryList : UITableViewController ++ (id)directoryListOrGridWithPath:(NSString*)path; +- (id)initWithPath:(NSString*)path config:(RAConfig*)config; @end diff --git a/ios/RetroArch/browser.m b/ios/RetroArch/browser.m index dc096da460..f933658c1e 100644 --- a/ios/RetroArch/browser.m +++ b/ios/RetroArch/browser.m @@ -52,7 +52,7 @@ BOOL ra_ios_is_directory(NSString* path) return result; } -NSArray* ra_ios_list_directory(NSString* path, NSRegularExpression* regex) +NSArray* ra_ios_list_directory(NSString* path) { NSMutableArray* result = [NSMutableArray array]; @@ -79,18 +79,7 @@ NSArray* ra_ios_list_directory(NSString* path, NSRegularExpression* regex) closedir(dir); free(cpath); - // Filter and sort - if (regex) - { - [result filterUsingPredicate:[NSPredicate predicateWithBlock:^(RADirectoryItem* object, NSDictionary* bindings) - { - if (object.isDirectory) - return YES; - - return (BOOL)([regex numberOfMatchesInString:[object.path lastPathComponent] options:0 range:NSMakeRange(0, [[object.path lastPathComponent] length])] != 0); - }]]; - } - + // Sort [result sortUsingComparator:^(RADirectoryItem* left, RADirectoryItem* right) { return (left.isDirectory != right.isDirectory) ? @@ -101,8 +90,14 @@ NSArray* ra_ios_list_directory(NSString* path, NSRegularExpression* regex) return result; } -NSString* ra_ios_get_browser_root() +NSString* ra_ios_check_path(NSString* path) { + if (path && ra_ios_is_directory(path)) + return path; + + if (path) + [RetroArch_iOS displayErrorMessage:@"Browsed path is not a directory."]; + if (ra_ios_is_directory(@"/var/mobile/RetroArchGames")) return @"/var/mobile/RetroArchGames"; else if (ra_ios_is_directory(@"/var/mobile")) return @"/var/mobile"; else return @"/"; diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index 698d6c8f7f..3b6db9cbec 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -35,12 +35,6 @@ @interface RAModuleList : UITableViewController @end -@interface RADirectoryList : UITableViewController -+ (id)directoryListWithPath:(NSString*)path; -+ (id)directoryListWithPath:(NSString*)path filter:(NSRegularExpression*)regex; -- (id)initWithPath:(NSString*)path filter:(NSRegularExpression*)regex; -@end - @interface RASettingsSubList : UITableViewController - (id)initWithSettings:(NSArray*)values title:(NSString*)title; - (void)writeSettings:(NSArray*)settingList toConfig:(RAConfig*)config; From c941caa2ec40425f17aaae3959ff49ccb976a433 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 26 Feb 2013 23:14:27 -0500 Subject: [PATCH 080/108] ios: First revision of WiiMote support (code borrowed from imame4all) --- ios/RetroArch.xcodeproj/project.pbxproj | 58 ++ ios/RetroArch/BTStack/BTDevice.h | 83 ++ ios/RetroArch/BTStack/BTDevice.m | 94 ++ .../BTStack/BTInquiryViewController.h | 94 ++ .../BTStack/BTInquiryViewController.m | 592 ++++++++++++ ios/RetroArch/BTStack/WiiMoteHelper.h | 49 + ios/RetroArch/BTStack/WiiMoteHelper.m | 427 +++++++++ ios/RetroArch/BTStack/btstack/btstack.h | 85 ++ ios/RetroArch/BTStack/btstack/hci_cmds.h | 253 +++++ ios/RetroArch/BTStack/btstack/linked_list.h | 62 ++ ios/RetroArch/BTStack/btstack/run_loop.h | 86 ++ ios/RetroArch/BTStack/btstack/sdp_util.h | 109 +++ ios/RetroArch/BTStack/btstack/utils.h | 115 +++ ios/RetroArch/BTStack/libBTstack.dylib | Bin 0 -> 42320 bytes ios/RetroArch/BTStack/wiimote.c | 890 ++++++++++++++++++ ios/RetroArch/BTStack/wiimote.h | 294 ++++++ ios/RetroArch/PauseView.xib | 158 +++- ios/RetroArch/RetroArch_iOS.m | 9 + ios/RetroArch/ios_input.m | 18 + 19 files changed, 3474 insertions(+), 2 deletions(-) create mode 100644 ios/RetroArch/BTStack/BTDevice.h create mode 100644 ios/RetroArch/BTStack/BTDevice.m create mode 100644 ios/RetroArch/BTStack/BTInquiryViewController.h create mode 100644 ios/RetroArch/BTStack/BTInquiryViewController.m create mode 100644 ios/RetroArch/BTStack/WiiMoteHelper.h create mode 100644 ios/RetroArch/BTStack/WiiMoteHelper.m create mode 100644 ios/RetroArch/BTStack/btstack/btstack.h create mode 100644 ios/RetroArch/BTStack/btstack/hci_cmds.h create mode 100644 ios/RetroArch/BTStack/btstack/linked_list.h create mode 100644 ios/RetroArch/BTStack/btstack/run_loop.h create mode 100644 ios/RetroArch/BTStack/btstack/sdp_util.h create mode 100644 ios/RetroArch/BTStack/btstack/utils.h create mode 100755 ios/RetroArch/BTStack/libBTstack.dylib create mode 100644 ios/RetroArch/BTStack/wiimote.c create mode 100644 ios/RetroArch/BTStack/wiimote.h diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 461c22e844..05944e26d8 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -8,6 +8,11 @@ /* Begin PBXBuildFile section */ 96096DD816D1ABAF00BF4499 /* RAModuleInfoList.m in Sources */ = {isa = PBXBuildFile; fileRef = 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */; }; + 9614C6BB16DD7C00000B36EF /* BTDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6AE16DD7C00000B36EF /* BTDevice.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 9614C6BC16DD7C00000B36EF /* BTInquiryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6B016DD7C00000B36EF /* BTInquiryViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 9614C6BD16DD7C00000B36EF /* libBTstack.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 9614C6B816DD7C00000B36EF /* libBTstack.dylib */; }; + 9614C6BE16DD7C00000B36EF /* WiiMoteHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6BA16DD7C00000B36EF /* WiiMoteHelper.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 9614C6C116DD7D54000B36EF /* wiimote.c in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6BF16DD7D54000B36EF /* wiimote.c */; }; 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */; }; 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; }; 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; }; @@ -91,6 +96,21 @@ /* Begin PBXFileReference section */ 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAModuleInfoList.m; sourceTree = ""; }; + 9614C6AD16DD7C00000B36EF /* BTDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTDevice.h; sourceTree = ""; }; + 9614C6AE16DD7C00000B36EF /* BTDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTDevice.m; sourceTree = ""; }; + 9614C6AF16DD7C00000B36EF /* BTInquiryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTInquiryViewController.h; sourceTree = ""; }; + 9614C6B016DD7C00000B36EF /* BTInquiryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTInquiryViewController.m; sourceTree = ""; }; + 9614C6B216DD7C00000B36EF /* btstack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = btstack.h; sourceTree = ""; }; + 9614C6B316DD7C00000B36EF /* hci_cmds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hci_cmds.h; sourceTree = ""; }; + 9614C6B416DD7C00000B36EF /* linked_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linked_list.h; sourceTree = ""; }; + 9614C6B516DD7C00000B36EF /* run_loop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = run_loop.h; sourceTree = ""; }; + 9614C6B616DD7C00000B36EF /* sdp_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sdp_util.h; sourceTree = ""; }; + 9614C6B716DD7C00000B36EF /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = ""; }; + 9614C6B816DD7C00000B36EF /* libBTstack.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libBTstack.dylib; sourceTree = ""; }; + 9614C6B916DD7C00000B36EF /* WiiMoteHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WiiMoteHelper.h; sourceTree = ""; }; + 9614C6BA16DD7C00000B36EF /* WiiMoteHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WiiMoteHelper.m; sourceTree = ""; }; + 9614C6BF16DD7D54000B36EF /* wiimote.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wiimote.c; sourceTree = ""; }; + 9614C6C016DD7D54000B36EF /* wiimote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wiimote.h; sourceTree = ""; }; 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioseagl_ctx.c; sourceTree = ""; }; 962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = ""; }; 962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = ""; }; @@ -252,12 +272,43 @@ 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */, 96AFAE3016C1D4EA009DE44C /* GLKit.framework in Frameworks */, 96AFAE3216C1D4EA009DE44C /* OpenGLES.framework in Frameworks */, + 9614C6BD16DD7C00000B36EF /* libBTstack.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 9614C6AC16DD7C00000B36EF /* BTStack */ = { + isa = PBXGroup; + children = ( + 9614C6B116DD7C00000B36EF /* btstack */, + 9614C6AD16DD7C00000B36EF /* BTDevice.h */, + 9614C6AE16DD7C00000B36EF /* BTDevice.m */, + 9614C6AF16DD7C00000B36EF /* BTInquiryViewController.h */, + 9614C6B016DD7C00000B36EF /* BTInquiryViewController.m */, + 9614C6B816DD7C00000B36EF /* libBTstack.dylib */, + 9614C6B916DD7C00000B36EF /* WiiMoteHelper.h */, + 9614C6BA16DD7C00000B36EF /* WiiMoteHelper.m */, + 9614C6BF16DD7D54000B36EF /* wiimote.c */, + 9614C6C016DD7D54000B36EF /* wiimote.h */, + ); + path = BTStack; + sourceTree = ""; + }; + 9614C6B116DD7C00000B36EF /* btstack */ = { + isa = PBXGroup; + children = ( + 9614C6B216DD7C00000B36EF /* btstack.h */, + 9614C6B316DD7C00000B36EF /* hci_cmds.h */, + 9614C6B416DD7C00000B36EF /* linked_list.h */, + 9614C6B516DD7C00000B36EF /* run_loop.h */, + 9614C6B616DD7C00000B36EF /* sdp_util.h */, + 9614C6B716DD7C00000B36EF /* utils.h */, + ); + path = btstack; + sourceTree = ""; + }; 96366C6F16CAF62200D64A22 /* settings */ = { isa = PBXGroup; children = ( @@ -311,6 +362,7 @@ 96AFAE3316C1D4EA009DE44C /* RetroArch */ = { isa = PBXGroup; children = ( + 9614C6AC16DD7C00000B36EF /* BTStack */, 96C19C2716D455C600FE8D5A /* Browser */, 96366C6F16CAF62200D64A22 /* settings */, 96AFAE3416C1D4EA009DE44C /* Supporting Files */, @@ -701,6 +753,10 @@ 96C19C2916D5A56500FE8D5A /* browser.m in Sources */, 96C19C3016D7045700FE8D5A /* RAConfig.m in Sources */, 965AE29E16D9BF94001D7667 /* ios_input.m in Sources */, + 9614C6BB16DD7C00000B36EF /* BTDevice.m in Sources */, + 9614C6BC16DD7C00000B36EF /* BTInquiryViewController.m in Sources */, + 9614C6BE16DD7C00000B36EF /* WiiMoteHelper.m in Sources */, + 9614C6C116DD7D54000B36EF /* wiimote.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -822,6 +878,7 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"", + "\"$(SRCROOT)/RetroArch/BTStack\"", ); OTHER_CFLAGS = ( "-DHAVE_RARCH_MAIN_WRAP", @@ -858,6 +915,7 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"", + "\"$(SRCROOT)/RetroArch/BTStack\"", ); OTHER_CFLAGS = ( "-DNS_BLOCK_ASSERTIONS=1", diff --git a/ios/RetroArch/BTStack/BTDevice.h b/ios/RetroArch/BTStack/BTDevice.h new file mode 100644 index 0000000000..43d018cce5 --- /dev/null +++ b/ios/RetroArch/BTStack/BTDevice.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2009 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +// +// BTDevice.h +// BT-Keyboard +// +// Created by Matthias Ringwald on 3/30/09. +// + +#import +#include "btstack/utils.h" + +#define kCODHID 0x2540 +#define kCODZeeMote 0x584 +#define kCODInvalid 0xffff + +typedef enum { + kBluetoothDeviceTypeGeneric = 0, + kBluetoothDeviceTypeHID, + kBluetoothDeviceTypeMobilePhone, + kBluetoothDeviceTypeSmartPhone, + kBluetoothDeviceTypeZeeMote, +} BluetoothDeviceType; + +typedef enum { + kBluetoothConnectionNotConnected = 0, + kBluetoothConnectionRemoteName, + kBluetoothConnectionConnecting, + kBluetoothConnectionConnected +} BluetoothConnectionState; + +@interface BTDevice : NSObject { + bd_addr_t address; + NSString * name; + uint8_t pageScanRepetitionMode; + uint16_t clockOffset; + uint32_t classOfDevice; + BluetoothConnectionState connectionState; +} + +- (void) setAddress:(bd_addr_t *)addr; +- (bd_addr_t *) address; +- (NSString *) toString; ++ (NSString *) stringForAddress:(bd_addr_t *) address; + +@property (readonly) BluetoothDeviceType deviceType; +@property (readonly) NSString * nameOrAddress; +@property (nonatomic, copy) NSString * name; +@property (nonatomic, assign) uint32_t classOfDevice; +@property (nonatomic, assign) uint16_t clockOffset; +@property (nonatomic, assign) uint8_t pageScanRepetitionMode; +@property (nonatomic, assign) BluetoothConnectionState connectionState; + +@end diff --git a/ios/RetroArch/BTStack/BTDevice.m b/ios/RetroArch/BTStack/BTDevice.m new file mode 100644 index 0000000000..57fbc6df17 --- /dev/null +++ b/ios/RetroArch/BTStack/BTDevice.m @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2009 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +// +// BTDevice.m +// +// Created by Matthias Ringwald on 3/30/09. +// + +#import "BTDevice.h" + +@implementation BTDevice + +@synthesize name; +@synthesize classOfDevice; +@synthesize connectionState; +@synthesize pageScanRepetitionMode; +@synthesize clockOffset; + +- (BTDevice *)init { + name = NULL; + bzero(&address, 6); + classOfDevice = kCODInvalid; + connectionState = kBluetoothConnectionNotConnected; + return self; +} + +- (void) setAddress:(bd_addr_t *)newAddr{ + BD_ADDR_COPY( &address, newAddr); +} + +- (bd_addr_t *) address{ + return &address; +} + ++ (NSString *) stringForAddress:(bd_addr_t *) address { + uint8_t * addr = (uint8_t*) address; + return [NSString stringWithFormat:@"%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], + addr[3], addr[4], addr[5]]; +} + +- (NSString *) nameOrAddress{ + if (name) return name; + return [BTDevice stringForAddress:&address]; +} + +- (BluetoothDeviceType) deviceType{ + switch (classOfDevice) { + case kCODHID: + return kBluetoothDeviceTypeHID; + case kCODZeeMote: + return kBluetoothDeviceTypeZeeMote; + default: + return kBluetoothDeviceTypeGeneric; + } +} +- (NSString *) toString{ + return [NSString stringWithFormat:@"Device addr %@ name %@ COD %x", [BTDevice stringForAddress:&address], name, classOfDevice]; +} + +- (void)dealloc { + [name release]; + [super dealloc]; +} + +@end diff --git a/ios/RetroArch/BTStack/BTInquiryViewController.h b/ios/RetroArch/BTStack/BTInquiryViewController.h new file mode 100644 index 0000000000..b8638e142b --- /dev/null +++ b/ios/RetroArch/BTStack/BTInquiryViewController.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2009 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +// +// BTInquiryViewController.h +// +// Created by Matthias Ringwald on 10/8/09. +// + +#import + +#include "btstack/hci_cmds.h" // for HCI_STATE +#include "btstack/utils.h" + +@class BTDevice; +@protocol BTInquiryDelegate; + +typedef enum { + kInquiryInactive, + kInquiryActive, + kInquiryRemoteName +} InquiryState; + +@interface BTInquiryViewController : UITableViewController +{ + NSMutableArray *devices; + HCI_STATE bluetoothState; + InquiryState inquiryState; + UIActivityIndicatorView *deviceActivity; + UIActivityIndicatorView *bluetoothActivity; + UIFont * deviceNameFont; + UIFont * macAddressFont; + id delegate; + bool allowSelection; + bool showIcons; + + // hacks + bool stopRemoteNameGathering; + bool restartInquiry; + BTDevice *remoteNameDevice; // device for which remote name request is pending + BTDevice *remoteDevice; // device for which connection is pending + BTDevice *connectedDevice; // device to which we're connected + bool notifyDelegateOnInquiryStopped; + +} + +- (void) startInquiry; +- (void) stopInquiry; + +- (void) showConnecting:(BTDevice *) device; +- (void) showConnected:(BTDevice *) device; + +- (void) removeDeviceForAddress:(bd_addr_t *)addr; + +@property (nonatomic, assign) bool allowSelection; +@property (nonatomic, assign) bool showIcons; +@property (nonatomic, retain) NSMutableArray *devices; +@property (nonatomic, retain) id delegate; +@end + +@protocol BTInquiryDelegate ++ (void) deviceChoosen:(BTInquiryViewController *) inqView device:(BTDevice*) device; ++ (void) deviceDetected:(BTInquiryViewController *) inqView device:(BTDevice*) device; ++ (void) disconnectDevice:(BTInquiryViewController *) inqView device:(BTDevice*) device; ++ (void) inquiryStopped; +@end diff --git a/ios/RetroArch/BTStack/BTInquiryViewController.m b/ios/RetroArch/BTStack/BTInquiryViewController.m new file mode 100644 index 0000000000..d274a6a7d9 --- /dev/null +++ b/ios/RetroArch/BTStack/BTInquiryViewController.m @@ -0,0 +1,592 @@ +/* + * Copyright (C) 2009 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +// +// BTInquiryViewController.m +// +// Created by Matthias Ringwald on 10/8/09. +// + +#import "BTInquiryViewController.h" +#import "BTDevice.h" +#import + +#include "btstack/btstack.h" +//#include "wiimote.h" + +#define INQUIRY_INTERVAL 3 + +unsigned myosd_num_of_joys = 0; + +static BTInquiryViewController *inqView; +static btstack_packet_handler_t clientHandler; +static uint8_t remoteNameIndex; + +@interface BTInquiryViewController (Private) +- (void) handlePacket:(uint8_t) packet_type channel:(uint16_t) channel packet:(uint8_t*) packet size:(uint16_t) size; +- (BTDevice *) getDeviceForAddress:(bd_addr_t *)addr; +- (void) getNextRemoteName; +- (void) startInquiry; +@end + +static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ + if (inqView) { + [inqView handlePacket:packet_type channel:channel packet:packet size:size]; + } +} + +@implementation BTInquiryViewController + + +@synthesize devices; +@synthesize delegate; +@synthesize allowSelection; +@synthesize showIcons; + +- (id) init { + self = [super initWithStyle:UITableViewStyleGrouped]; + bluetoothState = HCI_STATE_OFF; + inquiryState = kInquiryInactive; + allowSelection = false; + showIcons = false; + remoteDevice = nil; + restartInquiry = true; + notifyDelegateOnInquiryStopped = false; + + macAddressFont = [UIFont fontWithName:@"Courier New" size:[UIFont labelFontSize]]; + deviceNameFont = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]]; + + deviceActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + [deviceActivity startAnimating]; + bluetoothActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + [bluetoothActivity startAnimating]; + + devices = [[NSMutableArray alloc] init]; + inqView = self; + return self; +} + +- (void) myStartInquiry{ + if (inquiryState != kInquiryInactive) { + NSLog(@"Inquiry already active"); + return; + } + NSLog(@"Inquiry started"); + + stopRemoteNameGathering = false; + restartInquiry = true; + + inquiryState = kInquiryActive; + [[self tableView] reloadData]; + + bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0); +} + +- (void) handlePacket:(uint8_t) packet_type channel:(uint16_t) channel packet:(uint8_t*) packet size:(uint16_t) size { + bd_addr_t event_addr; + switch (packet_type) { + + case HCI_EVENT_PACKET: + + switch (packet[0]){ + + case BTSTACK_EVENT_STATE: + { + // bt stack activated + bluetoothState = (HCI_STATE)packet[2]; + [[self tableView] reloadData]; + + // set BT state +/* + if (bluetoothState == HCI_STATE_WORKING) { + [self myStartInquiry]; + } +*/ + break; + } + case BTSTACK_EVENT_POWERON_FAILED: + { + bluetoothState = HCI_STATE_OFF; + [[self tableView] reloadData]; + + UIAlertView* alertView = [[UIAlertView alloc] init]; + alertView.title = @"Bluetooth not accessible!"; + alertView.message = @"Hardware initialization failed!\n" + "Make sure you have turned off Bluetooth in the System Settings."; + NSLog(@"Alert: %@ - %@", alertView.title, alertView.message); + [alertView addButtonWithTitle:@"Dismiss"]; + [alertView show]; + break; + } + case HCI_EVENT_INQUIRY_RESULT: + case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI: + { + int numResponses = packet[2]; + int i; + for (i=0; i adding %@", [dev toString] ); + [devices addObject:dev]; + if (delegate) { + [delegate deviceDetected:self device:dev]; + } + } + + [[inqView tableView] reloadData]; + NSLog(@"bye" ); + break; + } + case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: + { + bt_flip_addr(event_addr, &packet[3]); + BTDevice *dev = [inqView getDeviceForAddress:&event_addr]; + if (!dev) break; + [dev setConnectionState:kBluetoothConnectionNotConnected]; + if (packet[2] == 0) { + [dev setName:[NSString stringWithUTF8String:(const char *) &packet[9]]]; + if (delegate) { + [delegate deviceDetected:self device:dev]; + } + } + [[self tableView] reloadData]; + remoteNameIndex++; + [self getNextRemoteName]; + break; + } + case HCI_EVENT_COMMAND_COMPLETE: + { + if (COMMAND_COMPLETE_EVENT(packet, hci_inquiry_cancel)){ + // inquiry canceled + NSLog(@"Inquiry cancelled successfully"); + inquiryState = kInquiryInactive; + [[self tableView] reloadData]; + if (notifyDelegateOnInquiryStopped){ + notifyDelegateOnInquiryStopped = false; + if (delegate) { + [delegate inquiryStopped]; + } + } + } + if (COMMAND_COMPLETE_EVENT(packet, hci_remote_name_request_cancel)){ + // inquiry canceled + NSLog(@"Remote name request cancelled successfully"); + inquiryState = kInquiryInactive; + [[self tableView] reloadData]; + if (notifyDelegateOnInquiryStopped){ + notifyDelegateOnInquiryStopped = false; + if (delegate) { + [delegate inquiryStopped]; + } + } + } + + break; + } + case HCI_EVENT_INQUIRY_COMPLETE: + { + NSLog(@"Inquiry complete"); + // reset name check + remoteNameIndex = 0; + [self getNextRemoteName]; + break; + } + default: + break; + + // hexdump(packet, size); + //break; + } + + default: + break; + } + // forward to client app + (*clientHandler)(packet_type, channel, packet, size); +} + +- (BTDevice *) getDeviceForAddress:(bd_addr_t *)addr { + uint8_t j; + for (j=0; j<[devices count]; j++){ + BTDevice *dev = [devices objectAtIndex:j]; + if (BD_ADDR_CMP(addr, [dev address]) == 0){ + return dev; + } + } + return nil; +} + + +- (void) removeDeviceForAddress:(bd_addr_t *)addr { + uint8_t j; + for (j=0; j<[devices count]; j++){ + BTDevice *dev = [devices objectAtIndex:j]; + if (BD_ADDR_CMP(addr, [dev address]) == 0){ + NSLog(@"--> removed %@", [dev toString] ); + [devices removeObject:dev]; + [[self tableView] reloadData]; + return; + } + } + +} + +- (void) getNextRemoteName{ + + // stopped? + if (stopRemoteNameGathering) { + inquiryState = kInquiryInactive; + [[self tableView] reloadData]; + + if (notifyDelegateOnInquiryStopped){ + notifyDelegateOnInquiryStopped = false; + if (delegate) { + [delegate inquiryStopped]; + } + } + return; + } + + remoteNameDevice = nil; + + for (remoteNameIndex = 0; remoteNameIndex < [devices count]; remoteNameIndex++){ + BTDevice *dev = [devices objectAtIndex:remoteNameIndex]; + if (![dev name]){ + remoteNameDevice = dev; + break; + } + } + if (remoteNameDevice) { + inquiryState = kInquiryRemoteName; + [remoteNameDevice setConnectionState:kBluetoothConnectionRemoteName]; + bt_send_cmd(&hci_remote_name_request, [remoteNameDevice address], [remoteNameDevice pageScanRepetitionMode], 0, [remoteNameDevice clockOffset] | 0x8000); + } else { + inquiryState = kInquiryInactive; + // inquiry done. + if (restartInquiry) { + [self myStartInquiry]; + } + } + [[self tableView] reloadData]; +} + +- (void) startInquiry { + //static int b = 0; + //if(!b) + //{ + //b=1; + // put into loop + + // @TODO: cannot be called a second time! + clientHandler = bt_register_packet_handler(packet_handler); + + bluetoothState = HCI_STATE_INITIALIZING; + [[self tableView] reloadData]; + + stopRemoteNameGathering = false; + restartInquiry = true; + + bt_send_cmd(&btstack_set_power_mode, HCI_POWER_ON ); + //} +} + +- (void) stopInquiry { + + NSLog(@"stop inquiry called, state %u", inquiryState); + restartInquiry = false; + stopRemoteNameGathering = true; + bool immediateNotify = true; + + switch (inquiryState) { + case kInquiryActive: + // just stop inquiry + immediateNotify = false; + bt_send_cmd(&hci_inquiry_cancel); + break; + case kInquiryInactive: + NSLog(@"stop inquiry called although inquiry inactive?"); + break; + case kInquiryRemoteName: + if (remoteNameDevice) { + // just stop remote name request + immediateNotify = false; + bt_send_cmd(&hci_remote_name_request_cancel, [remoteNameDevice address]); + } + break; + default: + break; + } + if (immediateNotify && delegate){ + [delegate inquiryStopped]; + } else { + notifyDelegateOnInquiryStopped = true; + } +} + +- (void) showConnecting:(BTDevice *) device { + remoteDevice = device; + [[self tableView] reloadData]; +} + +- (void) showConnected:(BTDevice *) device { + connectedDevice = device; + [[self tableView] reloadData]; +} + +/* +- (void)loadView { + + [super loadView]; + +} +*/ +/* +- (void)viewDidLoad { + [super viewDidLoad]; + + // Uncomment the following line to display an Edit button in the navigation bar for this view controller. + //self.navigationItem.rightBarButtonItem = self.editButtonItem; + +} +*/ + +/* +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; +} +*/ +/* +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; +} +*/ +/* +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; +} +*/ +/* +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; +} +*/ + +// Override to allow orientations other than the default portrait orientation. +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + return YES; + //return NO; + //return (interfaceOrientation == UIInterfaceOrientationPortrait); +} + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + +- (void)viewDidUnload { + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + +- (void)dealloc { + // unregister self + bt_register_packet_handler(clientHandler); + // done + [super dealloc]; +} + + +#pragma mark Table view methods + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ + return @"Devices"; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + + +// Customize the number of rows in the table view. +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + int rows = 1; // 1 for status line + if (bluetoothState == HCI_STATE_WORKING) { + rows += [devices count]; + } + return rows; +} + + +// Customize the appearance of table view cells. +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + + static NSString *CellIdentifier = @"Cell"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:/* UITableViewCellStyleDefault = */(UITableViewCellStyle)0 reuseIdentifier:CellIdentifier] autorelease]; + // cell.selectionStyle = UITableViewCellSelectionStyleNone; + } + + // Set up the cell... + NSString *label = nil; + int idx = [indexPath indexAtPosition:1]; + if (bluetoothState != HCI_STATE_WORKING || idx >= [devices count]) { + if (bluetoothState == HCI_STATE_INITIALIZING){ + label = @"Activating BTstack..."; + cell.accessoryView = bluetoothActivity; + } else if (bluetoothState == HCI_STATE_OFF){ + label = @"Bluetooth not accessible!"; + cell.accessoryView = nil; + } else { + if (connectedDevice) { + label = @"Disconnect"; + cell.accessoryView = nil; + } else if (remoteDevice) { + label = @"Connecting..."; + cell.accessoryView = bluetoothActivity; + } else { + switch (inquiryState){ + case kInquiryInactive: + if (myosd_num_of_joys==4) + { + label = @"Maximun devices connected!"; + } + else if ([devices count] > 0){ + label = @"Press here to find more devices..."; + } else { + label = @"Press here to find first device..."; + } + cell.accessoryView = nil; + break; + case kInquiryActive: + //label = @"Searching..."; + label = @"Press 1 and 2 on the WiiMote to sync"; + cell.accessoryView = bluetoothActivity; + break; + case kInquiryRemoteName: + label = @"Query device names..."; + cell.accessoryView = bluetoothActivity; + break; + } + } + } + } else { + BTDevice *dev = [devices objectAtIndex:idx]; + label = [dev nameOrAddress]; + if ([dev name]){ + cell.font = deviceNameFont; + } else { + cell.font = macAddressFont; + } + // pick an icon for the devices + if (showIcons) { + int major = ([dev classOfDevice] & 0x1f00) >> 8; + if (major == 0x01) { + cell.image = [UIImage imageNamed:@"computer.png"]; + } else if (major == 0x02) { + cell.image = [UIImage imageNamed:@"smartphone.png"]; + } else if ( major == 0x05 && ([dev classOfDevice] & 0xff) == 0x40){ + cell.image = [UIImage imageNamed:@"keyboard.png"]; + } else { + cell.image = [UIImage imageNamed:@"bluetooth.png"]; + } + } + switch ([dev connectionState]) { + case kBluetoothConnectionNotConnected: + case kBluetoothConnectionConnected: + cell.accessoryView = nil; + break; + case kBluetoothConnectionConnecting: + case kBluetoothConnectionRemoteName: + cell.accessoryView = deviceActivity; + break; + } + } + cell.text = label; + return cell; +} + + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + NSLog(@"didSelectRowAtIndexPath %@", indexPath); + // Navigation logic may go here. Create and push another view controller. + // AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil]; + // [self.navigationController pushViewController:anotherViewController]; + // [anotherViewController release]; + + // valid selection? + + + int idx = [indexPath indexAtPosition:1]; + //printf("sleccion %d\n",idx); + if (bluetoothState == HCI_STATE_WORKING) { + if (delegate) { + if (idx < [devices count]){ + [delegate deviceChoosen:self device:[devices objectAtIndex:idx]]; + } else if (idx == [devices count]) { + //printf("seleccionado %d %d\n",idx,connectedDevice); + if (connectedDevice) { + // DISCONNECT button + [delegate disconnectDevice:self device:connectedDevice]; + } else if (myosd_num_of_joys<4){ + // Find more devices + [self myStartInquiry]; + } + } + } + } else { + [tableView deselectRowAtIndexPath:indexPath animated:TRUE]; + } + +} + +- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { + if (allowSelection) { + return indexPath; + } + return nil; +} + +@end + diff --git a/ios/RetroArch/BTStack/WiiMoteHelper.h b/ios/RetroArch/BTStack/WiiMoteHelper.h new file mode 100644 index 0000000000..ad263a3ee7 --- /dev/null +++ b/ios/RetroArch/BTStack/WiiMoteHelper.h @@ -0,0 +1,49 @@ +/* + * This file is part of MAME4iOS. + * + * Copyright (C) 2012 David Valdeita (Seleuco) + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * In addition, as a special exception, Seleuco + * gives permission to link the code of this program with + * the MAME library (or with modified versions of MAME that use the + * same license as MAME), and distribute linked combinations including + * the two. You must obey the GNU General Public License in all + * respects for all of the code used other than MAME. If you modify + * this file, you may extend this exception to your version of the + * file, but you are not obligated to do so. If you do not wish to + * do so, delete this exception statement from your version. + */ + + +#import + +#import "BTInquiryViewController.h" + +@interface WiiMoteHelper : NSObject +{ +} + ++ (void)startwiimote:(UIViewController *)controller; ++ (void)endwiimote; ++ (void)cancelWiiMoteSearch; + +@end + + + + + diff --git a/ios/RetroArch/BTStack/WiiMoteHelper.m b/ios/RetroArch/BTStack/WiiMoteHelper.m new file mode 100644 index 0000000000..8898040797 --- /dev/null +++ b/ios/RetroArch/BTStack/WiiMoteHelper.m @@ -0,0 +1,427 @@ +/* + * This file is part of MAME4iOS. + * + * Copyright (C) 2012 David Valdeita (Seleuco) + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * In addition, as a special exception, Seleuco + * gives permission to link the code of this program with + * the MAME library (or with modified versions of MAME that use the + * same license as MAME), and distribute linked combinations including + * the two. You must obey the GNU General Public License in all + * respects for all of the code used other than MAME. If you modify + * this file, you may extend this exception to your version of the + * file, but you are not obligated to do so. If you do not wish to + * do so, delete this exception statement from your version. + */ + +#include +#include +#include + +#include "wiimote.h" + +#import "WiiMoteHelper.h" + +#import "BTDevice.h" +#import "BTInquiryViewController.h" + +#import "btstack/btstack.h" +#import "btstack/run_loop.h" +#import "btstack/hci_cmds.h" + +bool btOK = false; +bool initLoop = false; +BTDevice *device; +uint16_t wiiMoteConHandle = 0; +bool conected = false; +bool activated = false; + +BTInquiryViewController *inqViewControl; + +void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ + bd_addr_t event_addr; + + + switch (packet_type) { + + case L2CAP_DATA_PACKET://0x06 + { + struct wiimote_t *wm = NULL; + + wm = wiimote_get_by_source_cid(channel); + + if(wm!=NULL) + { + + byte* msg = packet + 2; + byte event = packet[1]; + + switch (event) { + case WM_RPT_BTN: + { + /* button */ + wiimote_pressed_buttons(wm, msg); + break; + } + case WM_RPT_READ: + { + /* data read */ + + if(WIIMOTE_DBG)printf("WM_RPT_READ data arrive!\n"); + + wiimote_pressed_buttons(wm, msg); + + byte err = msg[2] & 0x0F; + + if (err == 0x08) + printf("Unable to read data - address does not exist.\n"); + else if (err == 0x07) + printf("Unable to read data - address is for write-only registers.\n"); + else if (err) + printf("Unable to read data - unknown error code %x.\n", err); + + unsigned short offset = BIG_ENDIAN_SHORT(*(unsigned short*)(msg + 3)); + + byte len = ((msg[2] & 0xF0) >> 4) + 1; + + byte *data = (msg + 5); + + if(WIIMOTE_DBG) + { + int i = 0; + printf("Read: 0x%04x ; ",offset); + for (; i < len; ++i) + printf("%x ", data[i]); + printf("\n"); + } + + if(wiimote_handshake(wm,WM_RPT_READ,data,len)) + { + //btUsed = 1; + [inqViewControl showConnected:nil]; + [inqViewControl showConnecting:nil]; + //Create UIAlertView alert + [inqViewControl showConnecting:nil]; + + UIAlertView* alert = + [[UIAlertView alloc] initWithTitle:@"Connection detected!" + message: [NSString stringWithFormat:@"%@ '%@' connection sucessfully completed!", + (wm->exp.type != EXP_NONE ? @"Classic Controller" : @"WiiMote"), + [NSNumber numberWithInt:(wm->unid)+1]] + delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles: nil]; + [alert show]; + //[alert dismissWithClickedButtonIndex:0 animated:TRUE]; + [alert release]; + + if(device!=nil) + { + [device setConnectionState:kBluetoothConnectionConnected]; + device = nil; + } + + } + + return; + } + case WM_RPT_CTRL_STATUS: + { + wiimote_pressed_buttons(wm, msg); + + /* find the battery level and normalize between 0 and 1 */ + if(WIIMOTE_DBG) + { + wm->battery_level = (msg[5] / (float)WM_MAX_BATTERY_CODE); + + printf("BATTERY LEVEL %f\n", wm->battery_level); + } + + //handshake stuff! + if(wiimote_handshake(wm,WM_RPT_CTRL_STATUS,msg,-1)) + { + //btUsed = 1; + [inqViewControl showConnected:nil]; + [inqViewControl showConnecting:nil]; + UIAlertView* alert = + [[UIAlertView alloc] initWithTitle:@"Connection detected!" + message: [NSString stringWithFormat:@"WiiMote '%@' connection sucessfully completed!",[NSNumber numberWithInt:(wm->unid)+1]] + delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles: nil]; + [alert show]; + //[alert dismissWithClickedButtonIndex:0 animated:TRUE]; + [alert release]; + [device setConnectionState:kBluetoothConnectionConnected]; + + if(device!=nil) + { + [device setConnectionState:kBluetoothConnectionConnected]; + device = nil; + } + } + + return; + } + case WM_RPT_BTN_EXP: + { + /* button - expansion */ + wiimote_pressed_buttons(wm, msg); + wiimote_handle_expansion(wm, msg+2); + + break; + } + case WM_RPT_WRITE: + { + /* write feedback - safe to skip */ + break; + } + default: + { + printf("Unknown event, can not handle it [Code 0x%x].", event); + return; + } + } + } + break; + } + case HCI_EVENT_PACKET://0x04 + { + switch (packet[0]){ + + case L2CAP_EVENT_CHANNEL_OPENED: + + // data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16) + if (packet[2] == 0) { + + // inform about new l2cap connection + bt_flip_addr(event_addr, &packet[3]); + uint16_t psm = READ_BT_16(packet, 11); + uint16_t source_cid = READ_BT_16(packet, 13); + wiiMoteConHandle = READ_BT_16(packet, 9); + NSLog(@"Channel successfully opened: handle 0x%02x, psm 0x%02x, source cid 0x%02x, dest cid 0x%02x", + wiiMoteConHandle, psm, source_cid, READ_BT_16(packet, 15)); + + if (psm == 0x13) { + + // interupt channel openedn succesfully, now open control channel, too. + if(WIIMOTE_DBG)printf("open control channel\n"); + bt_send_cmd(&l2cap_create_channel, event_addr, 0x11); + struct wiimote_t *wm = NULL; + wm = &joys[myosd_num_of_joys]; + memset(wm, 0, sizeof(struct wiimote_t)); + wm->unid = myosd_num_of_joys; + wm->i_source_cid = source_cid; + memcpy(&wm->addr,&event_addr,BD_ADDR_LEN); + if(WIIMOTE_DBG)printf("addr %02x:%02x:%02x:%02x:%02x:%02x\n", wm->addr[0], wm->addr[1], wm->addr[2],wm->addr[3], wm->addr[4], wm->addr[5]); + if(WIIMOTE_DBG)printf("saved 0x%02x 0x%02x\n",source_cid,wm->i_source_cid); + wm->exp.type = EXP_NONE; + + } else { + + //inicializamos el wiimote! + struct wiimote_t *wm = NULL; + wm = &joys[myosd_num_of_joys]; + wm->wiiMoteConHandle = wiiMoteConHandle; + wm->c_source_cid = source_cid; + wm->state = WIIMOTE_STATE_CONNECTED; + myosd_num_of_joys++; + if(WIIMOTE_DBG)printf("Devices Number: %d\n",myosd_num_of_joys); + wiimote_handshake(wm,-1,NULL,-1); + } + } + break; + case L2CAP_EVENT_CHANNEL_CLOSED: + { + // data: event (8), len(8), channel (16) + uint16_t source_cid = READ_BT_16(packet, 2); + NSLog(@"Channel successfully closed: cid 0x%02x",source_cid); + + bd_addr_t addr; + int unid = wiimote_remove(source_cid,&addr); + if(unid!=-1) + { + [inqViewControl removeDeviceForAddress:&addr]; + UIAlertView* alert = + [[UIAlertView alloc] initWithTitle:@"Disconnection!" + message:[NSString stringWithFormat:@"WiiMote '%@' disconnection detected.\nIs battery drainned?",[NSNumber numberWithInt:(unid+1)]] + delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles: nil]; + [alert show]; + + [alert release]; + } + + } + break; + + default: + break; + } + break; + } + default: + break; + } +} + +@implementation WiiMoteHelper + ++(void) startwiimote:(UIViewController *)controller{ + + if(!initLoop) + { + run_loop_init(RUN_LOOP_COCOA); + initLoop = true; + } + if(!btOK ) + { + if (bt_open() ){ + // Alert user? + } else { + bt_register_packet_handler(packet_handler); + btOK = true; + } + } + + if (btOK) + { + // create inq controller + if(inqViewControl==nil) + { + inqViewControl = [[BTInquiryViewController alloc] init]; + + struct CGRect rect = controller.view.frame; + + CGFloat navBarWidht = rect.size.width; + CGFloat navBarHeight = 45; + + UINavigationBar *navBar = [ [ UINavigationBar alloc ] initWithFrame: CGRectMake(0, 0, navBarWidht , navBarHeight)]; + [navBar autorelease]; + [navBar setDelegate: inqViewControl ]; + + UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; + [button setFrame:CGRectMake(rect.size.width-70,5,60,35)]; + [button setTitle:@"Done" forState:UIControlStateNormal]; + button.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; + [button addTarget:self action:@selector(cancelWiiMoteSearch) forControlEvents:UIControlEventTouchUpInside]; + + [navBar addSubview:button]; + + UILabel *navLabel = [[UILabel alloc] initWithFrame:CGRectMake(40,0,300, navBarHeight)]; + navLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth; + navLabel.text = @"WiiMote Sync"; + navLabel.backgroundColor = [UIColor clearColor]; + navLabel.textColor = [UIColor blackColor]; + navLabel.font = [UIFont systemFontOfSize: 18]; + navLabel.textAlignment = UITextAlignmentLeft; + [navBar addSubview:navLabel]; + [navLabel release]; + + [[inqViewControl tableView] setTableHeaderView:navBar]; + [navBar release]; + + } + + if(!activated) + { + + + UIAlertView* alertView=[[UIAlertView alloc] initWithTitle:nil + message:@"are you sure you to activate BTstack?" + delegate:self cancelButtonTitle:nil + otherButtonTitles:@"Yes",@"No",nil]; + + [alertView show]; + [alertView release]; + } + + [controller presentModalViewController:inqViewControl animated:YES]; + + } + +} + ++ (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + + if(buttonIndex == 0 ) + { + [inqViewControl setDelegate:self]; + [inqViewControl setAllowSelection:true]; + activated = true; + [inqViewControl startInquiry]; + } + else + { + [inqViewControl dismissModalViewControllerAnimated:YES]; + } +} + ++(void) cancelWiiMoteSearch { + [inqViewControl stopInquiry]; + [inqViewControl dismissModalViewControllerAnimated:YES]; +} + + ++(void) deviceChoosen:(BTInquiryViewController *) inqView device:(BTDevice*) deviceChoosen; +{ + NSLog(@"deviceChoosen %@", [device toString]); +} + ++ (void) deviceDetected:(BTInquiryViewController *) inqView device:(BTDevice*) selectedDevice { + + NSLog(@"deviceDetected %@", [device toString]); + if ([selectedDevice name] && [[selectedDevice name] caseInsensitiveCompare:@"Nintendo RVL-CNT-01"] == NSOrderedSame){ + NSLog(@"WiiMote found with address %@", [BTDevice stringForAddress:[selectedDevice address]]); + device = selectedDevice; + + + [inqViewControl stopInquiry]; + + [inqViewControl showConnecting:device]; + + // connect to device + [device setConnectionState:kBluetoothConnectionConnecting]; + [[inqViewControl tableView] reloadData]; + bt_send_cmd(&l2cap_create_channel, [device address], 0x13); + + + } +} + ++ (void) inquiryStopped{ +} + ++ (void) disconnectDevice:(BTInquiryViewController *) inqView device:(BTDevice*) selectedDevice { +} + ++ (void)endwiimote { + + if(btOK) + { + int i=0; + while(i!=myosd_num_of_joys){ + [inqViewControl removeDeviceForAddress:&joys[i].addr]; + i++; + } + + myosd_num_of_joys=0; + bt_send_cmd(&btstack_set_power_mode, HCI_POWER_OFF ); + bt_close(); + activated= false; + btOK = false; + } +} + +@end + diff --git a/ios/RetroArch/BTStack/btstack/btstack.h b/ios/RetroArch/BTStack/btstack/btstack.h new file mode 100644 index 0000000000..04a2e146f4 --- /dev/null +++ b/ios/RetroArch/BTStack/btstack/btstack.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2009 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * btstack.h + * + * Created by Matthias Ringwald on 7/1/09. + * + * BTstack client API + * + */ + +#pragma once + +#include "hci_cmds.h" +#include "run_loop.h" +#include "utils.h" + +#include + +#if defined __cplusplus +extern "C" { +#endif + +// Default TCP port for BTstack daemon +#define BTSTACK_PORT 13333 + +// UNIX domain socket for BTstack */ +#define BTSTACK_UNIX "/tmp/BTstack" + +// packet handler +typedef void (*btstack_packet_handler_t) (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); + +// optional: if called before bt_open, TCP socket is used instead of local unix socket +// note: address is not copied and must be valid during bt_open +void bt_use_tcp(const char * address, uint16_t port); + +// init BTstack library +int bt_open(); + +// stop using BTstack library +int bt_close(); + +// send hci cmd packet +int bt_send_cmd(const hci_cmd_t *cmd, ...); + +// register packet handler -- channel only valid for l2cap and rfcomm packets +// @returns old packet handler +btstack_packet_handler_t bt_register_packet_handler(btstack_packet_handler_t handler); + +void bt_send_acl(uint8_t * data, uint16_t len); + +void bt_send_l2cap(uint16_t local_cid, uint8_t *data, uint16_t len); + +#if defined __cplusplus +} +#endif diff --git a/ios/RetroArch/BTStack/btstack/hci_cmds.h b/ios/RetroArch/BTStack/btstack/hci_cmds.h new file mode 100644 index 0000000000..cfb36cc7a1 --- /dev/null +++ b/ios/RetroArch/BTStack/btstack/hci_cmds.h @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2009 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * hci_cmds.h + * + * Created by Matthias Ringwald on 7/23/09. + */ + +#pragma once + +#include + +#if defined __cplusplus +extern "C" { +#endif + +/** + * packet types - used in BTstack and over the H4 UART interface + */ +#define HCI_COMMAND_DATA_PACKET 0x01 +#define HCI_ACL_DATA_PACKET 0x02 +#define HCI_SCO_DATA_PACKET 0x03 +#define HCI_EVENT_PACKET 0x04 + +// extension for client/server communication +#define DAEMON_EVENT_PACKET 0x05 + +// L2CAP data +#define L2CAP_DATA_PACKET 0x06 + +// RFCOMM data +#define RFCOMM_DATA_PACKET 0x07 + +// Fixed PSM numbers +#define PSM_SDP 0x01 +#define PSM_RFCOMM 0x03 +#define PSM_HID_CONTROL 0x11 +#define PSM_HID_INTERRUPT 0x13 + +// Events from host controller to host +#define HCI_EVENT_INQUIRY_COMPLETE 0x01 +#define HCI_EVENT_INQUIRY_RESULT 0x02 +#define HCI_EVENT_CONNECTION_COMPLETE 0x03 +#define HCI_EVENT_CONNECTION_REQUEST 0x04 +#define HCI_EVENT_DISCONNECTION_COMPLETE 0x05 +#define HCI_EVENT_AUTHENTICATION_COMPLETE_EVENT 0x06 +#define HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE 0x07 +#define HCI_EVENT_ENCRIPTION_CHANGE 0x08 +#define HCI_EVENT_CHANGE_CONNECTION_LINK_KEY_COMPLETE 0x09 +#define HCI_EVENT_MASTER_LINK_KEY_COMPLETE 0x0A +#define HCI_EVENT_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE 0x0B +#define HCI_EVENT_READ_REMOTE_VERSION_INFORMATION_COMPLETE 0x0C +#define HCI_EVENT_QOS_SETUP_COMPLETE 0x0D +#define HCI_EVENT_COMMAND_COMPLETE 0x0E +#define HCI_EVENT_COMMAND_STATUS 0x0F +#define HCI_EVENT_HARDWARE_ERROR 0x10 +#define HCI_EVENT_FLUSH_OCCURED 0x11 +#define HCI_EVENT_ROLE_CHANGE 0x12 +#define HCI_EVENT_NUMBER_OF_COMPLETED_PACKETS 0x13 +#define HCI_EVENT_MODE_CHANGE_EVENT 0x14 +#define HCI_EVENT_RETURN_LINK_KEYS 0x15 +#define HCI_EVENT_PIN_CODE_REQUEST 0x16 +#define HCI_EVENT_LINK_KEY_REQUEST 0x17 +#define HCI_EVENT_LINK_KEY_NOTIFICATION 0x18 +#define HCI_EVENT_DATA_BUFFER_OVERFLOW 0x1A +#define HCI_EVENT_MAX_SLOTS_CHANGED 0x1B +#define HCI_EVENT_READ_CLOCK_OFFSET_COMPLETE 0x1C +#define HCI_EVENT_PACKET_TYPE_CHANGED 0x1D +#define HCI_EVENT_INQUIRY_RESULT_WITH_RSSI 0x22 +#define HCI_EVENT_EXTENDED_INQUIRY_RESPONSE 0x2F +#define HCI_EVENT_VENDOR_SPECIFIC 0xFF + +// last used HCI_EVENT in 2.1 is 0x3d + +// events 0x50-0x5f are used internally + +// events from BTstack for application/client lib +#define BTSTACK_EVENT_STATE 0x60 + +// data: event(8), len(8), nr hci connections +#define BTSTACK_EVENT_NR_CONNECTIONS_CHANGED 0x61 + +// data: none +#define BTSTACK_EVENT_POWERON_FAILED 0x62 + +// data: majot (8), minor (8), revision(16) +#define BTSTACK_EVENT_VERSION 0x63 + +// data: system bluetooth on/off (bool) +#define BTSTACK_EVENT_SYSTEM_BLUETOOTH_ENABLED 0x64 + +// data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16) +#define L2CAP_EVENT_CHANNEL_OPENED 0x70 + +// data: event (8), len(8), channel (16) +#define L2CAP_EVENT_CHANNEL_CLOSED 0x71 + +// data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16) +#define L2CAP_EVENT_INCOMING_CONNECTION 0x72 + +// data: event(8), len(8), handle(16) +#define L2CAP_EVENT_TIMEOUT_CHECK 0x73 + +// data: event(8), len(8), handle(16) +#define L2CAP_EVENT_CREDITS 0x74 + +// data: event(8), len(8), service_record_handle(32) +#define SDP_SERVICE_REGISTERED 0x80 + + +// last error code in 2.1 is 0x38 - we start with 0x50 for BTstack errors + +#define BTSTACK_CONNECTION_TO_BTDAEMON_FAILED 0x50 +#define BTSTACK_ACTIVATION_FAILED_SYSTEM_BLUETOOTH 0x51 +#define BTSTACK_ACTIVATION_POWERON_FAILED 0x52 +#define BTSTACK_ACTIVATION_FAILED_UNKNOWN 0x53 +#define BTSTACK_NOT_ACTIVATED 0x54 +#define BTSTACK_BUSY 0x55 + +// l2cap errors - enumeration by the command that created them +#define L2CAP_COMMAND_REJECT_REASON_COMMAND_NOT_UNDERSTOOD 0x60 +#define L2CAP_COMMAND_REJECT_REASON_SIGNALING_MTU_EXCEEDED 0x61 +#define L2CAP_COMMAND_REJECT_REASON_INVALID_CID_IN_REQUEST 0x62 + +#define L2CAP_CONNECTION_RESPONSE_RESULT_SUCCESSFUL 0x63 +#define L2CAP_CONNECTION_RESPONSE_RESULT_PENDING 0x64 +#define L2CAP_CONNECTION_RESPONSE_RESULT_REFUSED_PSM 0x65 +#define L2CAP_CONNECTION_RESPONSE_RESULT_REFUSED_SECURITY 0x66 +#define L2CAP_CONNECTION_RESPONSE_RESULT_REFUSED_RESOURCES 0x65 + +#define L2CAP_CONFIG_RESPONSE_RESULT_SUCCESSFUL 0x66 +#define L2CAP_CONFIG_RESPONSE_RESULT_UNACCEPTABLE_PARAMS 0x67 +#define L2CAP_CONFIG_RESPONSE_RESULT_REJECTED 0x68 +#define L2CAP_CONFIG_RESPONSE_RESULT_UNKNOWN_OPTIONS 0x69 + +/** + * Default INQ Mode + */ +#define HCI_INQUIRY_LAP 0x9E8B33L // 0x9E8B33: General/Unlimited Inquiry Access Code (GIAC) +/** + * Hardware state of Bluetooth controller + */ +typedef enum { + HCI_POWER_OFF = 0, + HCI_POWER_ON +} HCI_POWER_MODE; + +/** + * State of BTstack + */ +typedef enum { + HCI_STATE_OFF = 0, + HCI_STATE_INITIALIZING, + HCI_STATE_WORKING, + HCI_STATE_HALTING +} HCI_STATE; + +/** + * compact HCI Command packet description + */ + typedef struct { + uint16_t opcode; + const char *format; +} hci_cmd_t; + + +// HCI Commands - see hci_cmds.c for info on parameters +extern const hci_cmd_t btstack_get_state; +extern const hci_cmd_t btstack_set_power_mode; +extern const hci_cmd_t btstack_set_acl_capture_mode; +extern const hci_cmd_t btstack_get_version; +extern const hci_cmd_t btstack_get_system_bluetooth_enabled; +extern const hci_cmd_t btstack_set_system_bluetooth_enabled; + +extern const hci_cmd_t hci_accept_connection_request; +extern const hci_cmd_t hci_authentication_requested; +extern const hci_cmd_t hci_create_connection; +extern const hci_cmd_t hci_create_connection_cancel; +extern const hci_cmd_t hci_delete_stored_link_key; +extern const hci_cmd_t hci_disconnect; +extern const hci_cmd_t hci_host_buffer_size; +extern const hci_cmd_t hci_inquiry; +extern const hci_cmd_t hci_inquiry_cancel; +extern const hci_cmd_t hci_link_key_request_negative_reply; +extern const hci_cmd_t hci_link_key_request_reply; +extern const hci_cmd_t hci_pin_code_request_reply; +extern const hci_cmd_t hci_pin_code_request_negative_reply; +extern const hci_cmd_t hci_qos_setup; +extern const hci_cmd_t hci_read_bd_addr; +extern const hci_cmd_t hci_read_buffer_size; +extern const hci_cmd_t hci_read_link_policy_settings; +extern const hci_cmd_t hci_read_link_supervision_timeout; +extern const hci_cmd_t hci_remote_name_request; +extern const hci_cmd_t hci_remote_name_request_cancel; +extern const hci_cmd_t hci_reset; +extern const hci_cmd_t hci_role_discovery; +extern const hci_cmd_t hci_set_event_mask; +extern const hci_cmd_t hci_switch_role_command; +extern const hci_cmd_t hci_write_authentication_enable; +extern const hci_cmd_t hci_write_class_of_device; +extern const hci_cmd_t hci_write_extended_inquiry_response; +extern const hci_cmd_t hci_write_inquiry_mode; +extern const hci_cmd_t hci_write_link_policy_settings; +extern const hci_cmd_t hci_write_link_supervision_timeout; +extern const hci_cmd_t hci_write_local_name; +extern const hci_cmd_t hci_write_page_timeout; +extern const hci_cmd_t hci_write_scan_enable; +extern const hci_cmd_t hci_write_simple_pairing_mode; + +extern const hci_cmd_t l2cap_accept_connection; +extern const hci_cmd_t l2cap_create_channel; +extern const hci_cmd_t l2cap_create_channel_mtu; +extern const hci_cmd_t l2cap_decline_connection; +extern const hci_cmd_t l2cap_disconnect; +extern const hci_cmd_t l2cap_register_service; +extern const hci_cmd_t l2cap_unregister_service; + +extern const hci_cmd_t sdp_register_service_record; +extern const hci_cmd_t sdp_unregister_service_record; + + +#if defined __cplusplus +} +#endif diff --git a/ios/RetroArch/BTStack/btstack/linked_list.h b/ios/RetroArch/BTStack/btstack/linked_list.h new file mode 100644 index 0000000000..2518094876 --- /dev/null +++ b/ios/RetroArch/BTStack/btstack/linked_list.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2009 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * linked_list.h + * + * Created by Matthias Ringwald on 7/13/09. + */ + +#pragma once + +#if defined __cplusplus +extern "C" { +#endif + +typedef struct linked_item { + struct linked_item *next; // <-- next element in list, or NULL + void *user_data; // <-- pointer to struct base +} linked_item_t; + +typedef linked_item_t * linked_list_t; + +void linked_item_set_user(linked_item_t *item, void *user_data); // <-- set user data +void * linked_item_get_user(linked_item_t *item); // <-- get user data +int linked_list_empty(linked_list_t * list); +void linked_list_add(linked_list_t * list, linked_item_t *item); // <-- add item to list as first element +void linked_list_add_tail(linked_list_t * list, linked_item_t *item); // <-- add item to list as last element +int linked_list_remove(linked_list_t * list, linked_item_t *item); // <-- remove item from list + +void test_linked_list(); + +#if defined __cplusplus +} +#endif diff --git a/ios/RetroArch/BTStack/btstack/run_loop.h b/ios/RetroArch/BTStack/btstack/run_loop.h new file mode 100644 index 0000000000..ea2673d5d4 --- /dev/null +++ b/ios/RetroArch/BTStack/btstack/run_loop.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2009 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * run_loop.h + * + * Created by Matthias Ringwald on 6/6/09. + */ + +#pragma once + +#include "linked_list.h" + +#include + +#if defined __cplusplus +extern "C" { +#endif + +typedef enum { + RUN_LOOP_POSIX = 1, + RUN_LOOP_COCOA, + RUN_LOOP_EMBEDDED +} RUN_LOOP_TYPE; + +typedef struct data_source { + linked_item_t item; + int fd; // <-- file descriptor to watch or 0 + int (*process)(struct data_source *ds); // <-- do processing +} data_source_t; + +typedef struct timer { + linked_item_t item; + struct timeval timeout; // <-- next timeout + void (*process)(struct timer *ts); // <-- do processing +} timer_source_t; + +// init must be called before any other run_loop call +void run_loop_init(RUN_LOOP_TYPE type); + +// add/remove data_source +void run_loop_add_data_source(data_source_t *dataSource); +int run_loop_remove_data_source(data_source_t *dataSource); + +// set timer based on current time +void run_loop_set_timer(timer_source_t *a, int timeout_in_ms); + +// add/remove timer_source +void run_loop_add_timer(timer_source_t *timer); +int run_loop_remove_timer(timer_source_t *timer); + +// execute configured run_loop +void run_loop_execute(); + +#if defined __cplusplus +} +#endif + diff --git a/ios/RetroArch/BTStack/btstack/sdp_util.h b/ios/RetroArch/BTStack/btstack/sdp_util.h new file mode 100644 index 0000000000..fb91038f2e --- /dev/null +++ b/ios/RetroArch/BTStack/btstack/sdp_util.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2010 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * sdp_util.h + */ + +#pragma once + +#include + +#if defined __cplusplus +extern "C" { +#endif + +typedef enum { + DE_NIL = 0, + DE_UINT, + DE_INT, + DE_UUID, + DE_STRING, + DE_BOOL, + DE_DES, + DE_DEA, + DE_URL +} de_type_t; + +typedef enum { + DE_SIZE_8 = 0, + DE_SIZE_16, + DE_SIZE_32, + DE_SIZE_64, + DE_SIZE_128, + DE_SIZE_VAR_8, + DE_SIZE_VAR_16, + DE_SIZE_VAR_32 +} de_size_t; + +// UNIVERSAL ATTRIBUTE DEFINITIONS +#define SDP_ServiceRecordHandle 0x0000 +#define SDP_ServiceClassIDList 0x0001 +#define SDP_ServiceRecordState 0x0002 +#define SDP_ServiceID 0x0003 +#define SDP_ProtocolDescriptorList 0x0004 +#define SDP_BrowseGroupList 0x0005 +#define SDP_LanguageBaseAttributeIDList 0x0006 +#define SDP_ServiceInfoTimeToLive 0x0007 +#define SDP_ServiceAvailability 0x0008 +#define SDP_BluetoothProfileDescriptorList 0x0009 +#define SDP_DocumentationURL 0x000a +#define SDP_ClientExecutableURL 0x000b +#define SDP_IconURL 0x000c +#define SDP_AdditionalProtocolDescriptorList 0x000d + +// OFFSETS FOR LOCALIZED ATTRIBUTES - SDP_LanguageBaseAttributeIDList +#define SDP_Offest_ServiceName 0x0000 +#define SDP_Offest_ServiceDescription 0x0001 +#define SDP_Offest_ProviderName 0x0002 + + +#pragma mark DateElement +void de_dump_data_element(uint8_t * record); +int de_get_len(uint8_t *header); +de_size_t de_get_size_type(uint8_t *header); +de_type_t de_get_element_type(uint8_t *header); +void de_create_sequence(uint8_t *header); +uint8_t * de_push_sequence(uint8_t *header); +void de_pop_sequence(uint8_t * parent, uint8_t * child); +void de_add_number(uint8_t *seq, de_type_t type, de_size_t size, uint32_t value); +void de_add_data( uint8_t *seq, de_type_t type, uint16_t size, uint8_t *data); + +int de_get_data_size(uint8_t * header); + +#pragma mark SDP +int sdp_append_attributes_in_attributeIDList(uint8_t *record, uint8_t *attributeIDList, uint16_t startIndex, uint16_t maxBytes, uint8_t *buffer); +uint8_t * sdp_get_attribute_value_for_attribute_id(uint8_t * record, uint16_t attributeID); +int sdp_record_matches_service_search_pattern(uint8_t *record, uint8_t *serviceSearchPattern); + +#if defined __cplusplus +} +#endif diff --git a/ios/RetroArch/BTStack/btstack/utils.h b/ios/RetroArch/BTStack/btstack/utils.h new file mode 100644 index 0000000000..39064f370b --- /dev/null +++ b/ios/RetroArch/BTStack/btstack/utils.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2009 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * utils.h + * + * General utility functions + * + * Created by Matthias Ringwald on 7/23/09. + */ + +#pragma once + +#include + +#if defined __cplusplus +extern "C" { +#endif + +/** + * @brief hci connection handle type + */ +typedef uint16_t hci_con_handle_t; + +/** + * @brief Length of a bluetooth device address. + */ +#define BD_ADDR_LEN 6 +typedef uint8_t bd_addr_t[BD_ADDR_LEN]; + +/** + * @brief The link key type + */ +#define LINK_KEY_LEN 16 +typedef uint8_t link_key_t[LINK_KEY_LEN]; + +// helper for BT little endian format +#define READ_BT_16( buffer, pos) ( ((uint16_t) buffer[pos]) | (((uint16_t)buffer[pos+1]) << 8)) +#define READ_BT_24( buffer, pos) ( ((uint32_t) buffer[pos]) | (((uint32_t)buffer[pos+1]) << 8) | (((uint32_t)buffer[pos+2]) << 16)) +#define READ_BT_32( buffer, pos) ( ((uint32_t) buffer[pos]) | (((uint32_t)buffer[pos+1]) << 8) | (((uint32_t)buffer[pos+2]) << 16) | (((uint32_t) buffer[pos+3])) << 24) + +// helper for SDP big endian format +#define READ_NET_16( buffer, pos) ( ((uint16_t) buffer[pos+1]) | (((uint16_t)buffer[pos ]) << 8)) +#define READ_NET_32( buffer, pos) ( ((uint32_t) buffer[pos+3]) | (((uint32_t)buffer[pos+2]) << 8) | (((uint32_t)buffer[pos+1]) << 16) | (((uint32_t) buffer[pos])) << 24) + +// HCI CMD OGF/OCF +#define READ_CMD_OGF(buffer) (buffer[1] >> 2) +#define READ_CMD_OCF(buffer) ((buffer[1] & 0x03) << 8 | buffer[0]) + +// check if command complete event for given command +#define COMMAND_COMPLETE_EVENT(event,cmd) ( event[0] == HCI_EVENT_COMMAND_COMPLETE && READ_BT_16(event,3) == cmd.opcode) + +// ACL Packet +#define READ_ACL_CONNECTION_HANDLE( buffer ) ( READ_BT_16(buffer,0) & 0x0fff) +#define READ_ACL_FLAGS( buffer ) ( buffer[1] >> 4 ) +#define READ_ACL_LENGTH( buffer ) (READ_BT_16(buffer, 2)) + +// L2CAP Packet +#define READ_L2CAP_LENGTH(buffer) ( READ_BT_16(buffer, 4)) +#define READ_L2CAP_CHANNEL_ID(buffer) ( READ_BT_16(buffer, 6)) + +void bt_store_16(uint8_t *buffer, uint16_t pos, uint16_t value); +void bt_store_32(uint8_t *buffer, uint16_t pos, uint32_t value); +void bt_flip_addr(bd_addr_t dest, bd_addr_t src); + +void net_store_16(uint8_t *buffer, uint16_t pos, uint16_t value); +void net_store_32(uint8_t *buffer, uint16_t pos, uint32_t value); + +void hexdump(void *data, int size); +void printUUID(uint8_t *uuid); +void print_bd_addr(bd_addr_t addr); +int sscan_bd_addr(uint8_t * addr_string, bd_addr_t addr); + +uint8_t crc8_check(uint8_t *data, uint16_t len, uint8_t check_sum); +uint8_t crc8_calc(uint8_t *data, uint16_t len); + +#define BD_ADDR_CMP(a,b) memcmp(a,b, BD_ADDR_LEN) +#define BD_ADDR_COPY(dest,src) memcpy(dest,src,BD_ADDR_LEN) + +#ifdef EMBEDDED +void bzero(void *s, uint32_t n); +#endif + +#if defined __cplusplus +} +#endif + diff --git a/ios/RetroArch/BTStack/libBTstack.dylib b/ios/RetroArch/BTStack/libBTstack.dylib new file mode 100755 index 0000000000000000000000000000000000000000..7e3173a4084ea5a9cdf15d77666c309d9c898bb8 GIT binary patch literal 42320 zcmeHweR$MYmH!P1kfs5KlDe3p4kcJZE4L5v6SM9wz{l+VLzXH&z-sXW`eN4 zzkd6K=eeA7-_AYv+;h)8_vM>;>aV|lyHuHf!vIDhtOfEZT~=i(~G*o+O zbSzgYP^c84OQTq5_;kDBbS4!`tPrAJ8Yg4O0ON!%4Hpjv!^uQC*O`7a5=!|XqmzIG z{i7VqKr|Svo3(hBQ;ISqqXN+##V{O!|AN8Dns~(ECf>h(F*8u#!mXMgVmm#DEbFOrs&4&XMRR(<3R! zl!K0cE)7Z2>BQOJV6cAP%{R`en`h@&D-r_;fD0xnJqO)-Bap>#i4#XLuxHfAXT+tM=myO+TJ7uD27Ytor$ z)71J{Ln@S7GxhpZs42QCnYt}Kb#^ipy*}BJz<|Y)i7Cr%jwi#=ruee7$9^46R2H0p zc3!%xIsx6HdSmT}nBaa7WMZ|p;hBiEnSf>iAGP$ue#;JSEAG?Pqb z8gB|Ep!6w+x;IPO=_3a<1`YLZ$7x{R{JuPYFq%q3*y*XWrs^!sdv!kEwZ0imTM-Ti z(^INM(@cNeIwdM;`s>s&!#?FYTj^aW;X~+r0Orh9Y@`kT8{b5ly#;}`9u>H=R~@>cyS4R^W427OEfd(@TNK!c0NAm)w>oftZ(-oGorS8c zOZm2I8lyVfy2hQJ+NAC>CQLlJl=1N~y~P~-z2;Gq<4 z6r&9vV5xs&cWKAQ?&8|*y{%4rLws#rrT(@qwpZq9&$P9%7yG~Cpw-Rx$s@~NfU>2a zP2O-ORh}>3@}SFs2Zi#iUj(^qf?Oit-O7f%LnhrLRa;LXc)Ghxz3TRzv=nGGfEUWG zSo+5HOVEB9>J|9fdNxQsHy^SqxAhmIK4nrEct-PnJ@V?Ra`N|q#yX)v`Pn{R3;CC- z?Y-k{S@3v=lq>YNb&+PVe_b!jylLf&G8s>qQk2nU1DkdGlR=m9Qi)HLc(H%8F30pC zkQrsN{`6@r6ON}3bqZ9v=bb1|oN~Y!WjSdL@k56G$9r*Re4P9=JNzv0@Z%GHeA50< zY2PO_NRM*I8S-(CO|fr#?dEcQ{K+Il`N zeAvE_f3#iBHcHXPNS#kz-`I;Yvg7PyG4!vfV_o-#}@33%+!}Kts2UdPCL19-NomO&h}bHf9>;KluTEVPHr%dB<3kGk&SW zDL0%8Y8e%Q7U$;}%umcqlP2<^E^+?Z`Rh~Ldyjwz%IQIok*o7RIei-Q+RRxyzOEd! zz0Dkuusd3{F4W(Ya2jA+exIe?>M_I zVO*h4#t!uD6Xt-n56Y2))?w5|UJ2&n&Wp3!Zbz`?d+&Wb(a9M&>NyZ}6NY&nNH?=BO*s1G5jM>{qO z<*rcbOYA4*M>&;)U(zW?oO(}w*|!?$yQ{O{r^MR&8$nmg3-Tq@^*g|y*dXd8^(VVF zf%e}EFSH?JownZfH`)r=wpb5zUEPEpX}!NhXp@g|4((w=y8>wy;8W&wwjZ#IuzhVk z%cPti<@~vFSPzW+X(O4=u`TRq>vC<&IP|;H+D`P}@1w2h-+!;ID0(ZmuF>vg*JQt0 zkEsjPd5!^fnB#-AZuXz+e_X~{$342`13mA&qn^Tk==$S?U+O>Cj1T3ZwcoMJq*nyK zxQ0>YrI?d@d{1_@`=9Lc>NWkBBG_>7-qjv>vTKr+4eIJS37b3CNoxunlza;@O)foHm`PPU?+0uPaFxpjKI`YqGJ z>jMA%SQ9_nNuO-4Ed%+8&SZ7LtOLf+@Q!I5nMZC>>HxxSgl!1x5mqDE{@A{2*`q&S zllD1|^aIDC>?n2lE4F+o`j7cSzenrU65);I%b*9hDZ~H6kaex)8!~tpa-|Jm{|kKJ z*WcDtA^ES3)OBF%FrL(%+DDH04sGmyH`arrSd%*tb|SbwqYq^Z(O zZJV{5d-tNv(}BY7J${U7$BSL0Pv4RAp%gNvO%VT4w{3mA9dNj8f35#(=M?2++7}THPpF2E zSJT!t0pYX{`6yrDU)N1uSgsKEf_8)DY2#@-<`tOrU11FhT#oS1sCOCQr3iXtVVCCu3FUzq8ZIfawK+b={PM_V=8APeY$aVyz@CuPo1o-fQ61OLH!0{{H`g z=1ZWNug_c~$D%JB=do;}$Xa4CGf@Zz&MrLvptTL>e$?CeG1a1?{+18 zH~LR+!&fX(Z9OLd=_^jcBbS+T;jdkn^Pg zT3^xV4|#R!TKU+0M;;pcJnfsaD~E>EotdZZ_dM;Jb0?>+r+wwn*nzrbj*Q1bruM9Z zGTZIE#p_x>84@)4olpQ-vk-Idu0690_wQ}-J{-f505#8 zeJS_Qi+aWY@3Y4NU!=9((uKZJ|5HM*5ioA^ppy}oAIuNVzr{{|y(b?>tjDu{Jay2K zgVmEp$YL!HLThH>jUHeT;Gua+9h;+6JK!O}O@LOHteg6*!sDH@C$x1vb}i;pAlzB#Z|&4&yD(u@73uO zZF%r*bc;H(5bK|M(AwB>1DAQ;(t+;jc6nY(I>vtXr2}~kR3=LYTjAr@{tsl^y*hFx zd6Ze+J@VjMlusUbOR9Oqc{}#bJfp&yF!YbUz?U%Z!5j8Wq7&3hYsuW-kAC&B^thW6AL*AJ*1rUJ%C` z2VLM87$1V?bo6@y(pS=?9r(OHmykZ7EbCAw{y;xL_^n5q%Vy@<-Gz2(zi>X*-3mLa z`GbvFC1)IMptEV3IXfUfTM*}dcZ=r7tie17weg+E--)~jXh*-NSSDLjNbblv~DMh&FguxVg6tQ0CzCmOl9*Zh6r-`uM!|h1zoWUI#lyn`QjS z0{FPhw>AfU;=^`c4OJ?OqrSdB;<(@(8n(rZIiaDov73Eh-)R%eAiHhA^?n}mIeOm^B@QAvDhEzL687cS2QlmfIH~00E zjE^(}??|16=nO_)V%M;HgIG*<0pcD0rpwIMOxrW|X zl9St(t8@LcGBacOOz&`>Rf3My1>1LTxd*U*=yQfVWx1|$uCV>1vi8%?avm08?!mv) z_rRQ+*0v9YEvLTNHAm3wC~C_1R_3O207XGnMQxMjB^M$`51;e=fiFg9}b**9^ylR{+x@8J^J|4Ie=Q|sFvwp19w`B`$oMruY>iSuFILEPRMrLROXPcHL z*HQL`w!oF6y(h_zE97+#6r5?mlk!OZTp(?yl~-{d*>L`O$JqGM#`aLodQ4oshMl1;_JMCHs8_sS zcXfgD5c^p@{=_kUGbmHe+wn-Bg7IYk=v&eEw|e2WQH1${wlNm_;M*G>c!x(DYx~c6 zY4I!+nc6t@hWk_Y@v&m)lF)*#{!Ln}%QccZcNletT3J{gFg9Z?j;~5*Pw`~6_ zpyAaO*9YZX+Kqc>%Er|Z#=SbCeNphG^+d*Gx7%8^#-Tvj91KI}w-+I0| zItPAwiqN;cIB%ft*?i+)_qV6tM4zaeRv$*^;oY4-H3RVO-icEl3U5TbV_AWD*5{oI zWb#8fSKyk>F`!=n|Dl}g;3JY}eUJ({L*cxeOq)l(p*Na;%0S^gh1B7k%$L7e^6CG3 z^NTt_4>Y*W@eYkTz&(t8$20+bnt-=moR^p%<=*LufS=AE6}u#Hxq9>V>cZV!5;eMiVu+XTo0Z@V7M$4j;F zGHC!_FP8jDjB(z(JbaysBYdewck5XMF|c50&+SYr=&ZH$K;N8DDoC$XlOr zfL}`)@5Wmao=@=njBn?-R&oDN$o1T=7w19?XBSUoX~XuhZP)+PGQ?Qx_a?Gl7pf0* zJ;i!?csP>}XZ-}Ob9`$=e}%H-o3Xu!^G=So$-b$A?d$5H-2+e5c{|V6zMXq(=jU9* zxL9AVy?}3c%={*eC}-6t!%o3J)Boo5>D<8yDCo)w>kwg5*sB`l-Q0c_tzXPDM! zZ1T*Jhw;9J^Z3M@W}m=0`Y_t!Jmi|mHHq~1$aqdu>IvIk`(uVDt}Q(0;F@*-I{Pr* zxD-0JoNeejI1e;=u$Q3A^A0_aJNmA56W}N5@{0Rv@F9GYFUpxVzR#K``F4%__hF{~ zL*SYH*Y)8Kkmf`F$MslJ-=XK)&miwUyhk@Wy0MpfLHp~DqxJ14VGOOm#&>9ZhZR6s z&P~3-+KawYSJ>x0i0_ej1?D^ZN*l*BMfx5!_G|=w`Vw@fLhJ$eNt6?LEC7%84#msU z5zjkLuWr$PYMTMr4&7=8P0Z;o^t+t?9QolLw(YlRi}Q5g{d&H6!S$2#V$T5cB8h-wT(cFWR^D`L_4oEc$vG*`=p4;+U zfxGEDKyNr_Am4J1IrnC6pLJcx1^%sWm+KzxFUu`W>vJMa+hwM+tcGaQ?Vs(Nm6yE( zqz$2dP-gjT$S*N}ys|ps*pM^H%9YQsJo3T4R9^Ym^A^g6x={fckjMY6ZdgB(eWh;M zzH(3J+RJ23f^(nw)OE(G`>$iowt;VJxy~EEgEoR| zIKGL>yT{}AIMvcN#~Wv3`uyDPGimd=ev&56ZjRFz)xIXu$%9^7(Fbjp{l?d{b<7#q zCvk>szKL<`7P@sEn%VWA>$UHbU2dIhd$8|14}J6UY0k(@o9>-ng>QTBcF2f&?9R(w zINaM02Yv}4&&G=ZkBrZqqjJ8Q_v^+_q0WB$uSQq&+(rB=5~p4l@g4zb+}BYr=5uZK zoN3r|9F*1Tnfr#>%b&Fy+>>cOKpShGe$PAF^apzmGv4rhdf0Xm@+p_|B%kdRQC83w zFE81%7|DP4f3a^EW3I<`JwiR|`L@3x5A@%F&RIHTlX9}k(n7!4kFi)wct%ZpZ`D5B zw_$Dof0VdKCU(!+FsiNRJ)VA98%;V~i+F!#{VK}&i{OiKzSm?~ zm;UIt5(;lUFoD)l9z8CJb?q^ahK#|p!EfOj>0;$+PSab7}38l z^U}PN8-;a>I?b{=9rN!m@Q+ub{xGC5e>hTLnKI`xd4>3f%5ls87G)xT77~P})z9 z%iqEOYX(33HfpB5+XkOwz^C;i${_1}d>VV#)-@gSC0)vU3C84G#-G*ug4-c8@?!Y< z8)rD;)9oGqxc2SHKlvuF)@Ri3d92?{D0Lon>WIFOsSIqewR@Xj z_ju>jim{;V&3wi?0<5FO9l3Xqd{_LPp+-M9pxg$?i(>>|;6Xd@sb6D_4(s`Yd*kDF zZZU6z5Ay=~8^Ggp;PE`s!+i7p*hRSiL$LQP_B@H-ivB_P@PiNf1)@*-eJO46r_e6% zaj9RlO~idNcW9f2fJTAO%sW zrn0{kHedRCka0hB4m1wi^$WD#&oiQ zxU?5{+M9xOwinRlO?%iU9B0~9_TruR=cO&3LJ&&nY$iMLnZ2<~$RhEA==( z>=`-d4t@3R*UeoI*HZ24)EeI4K+C$axa*gvPtUM6#t(TNeIxgG2zU-t@9Y;|lX@;6 z`0ld2(ynh9d%lf!_ZXb7Gen<%pzE74*K)!L^iJjT1h^5;DBI3eZq zI}(h^UOO)#?|U8kzr)!C&ujKc`SU;z_c{7(_WMk$ZR`4orB%DGceSUT#Wv56HnZh{w)suZJ^I{{H?Yu=tqTry)P5~vHvgO8g(swLqK;< zf9MS5r=vWk>T%8qt7mPv`1WJYW&rnNp4I^_1uOzQ1;^j7I4mLk}> z*9zU_Jq727ZGSD~u~zsU0(tX1hH$49as| znSuHjV9od#c%ki8;Olav(PyMD$vo}_^%{oq3z5h1SR!ROe+=(uUR$bB-uCSRXKi7- z-?V))eeSomY_$1e>#qPU%FMgAd{6rPeW%Y{TWq^_ZNY-9?UBg1@4I@)c%{vk_TK5V z=j!3T(%yYedt6&6_xoS#yS5xNH1n=4yH1@xT@78_3xnZ*hgn-{p?gJ$A40qxiqMA8 zXKjHlmf1N3St#lubj_|AM?lY(w|Cjp%?gxr_qls93Jo+0tfoqX}!)_sGg??)h0 zz0W~gv=L(=-(tuY^Gok5+DGGjx1;ZOyY`#iM_>==v%7mG7>MlK;RYViG6sK=dch z-S_fW2-+<7rkuCs^R-JI9klP{^tzhmvs3$(=Ytm0^_y<=lR8ubUYN#yzx*fo325u* zh8JCj`m1%&qaPWJiEA$}6&W?7@6D*=?Z-H@Jq&$z?b&~$9ojSQ;hAUc*?mGgvi=^JHzuChDFu{m2=c>8DPjlHAM-+|-Ygl~)Z#)&$m@0oo_ z1Ma?$)Aj^<&2Ooh=YF5dJbk_`dA#$4eSnS{n)-ZO^0=3F^DMogZo0>2*)vqbw>dB2 z_b%jH&%eN(`YfO8M)t1J*vYP66_~d-E5!BQAesE^I&@e1kglQQrxm4dS{_0i1hvn7Hmg?NmNq_gLw9mr7E7fJsbf|Om*LXgOzb&GDBI-dk`p!E% z?xVSv;@I%pz5r!{H@h|PJE6y&{=gW$w&--wq3`LgaZIQFvp#XYC&zc@&s+MSJqB~U zQ2VJEU;d3jKjde}*3M_z0rTdhv*&#H66A?@>-<|#d{e-2(&NSX?SH2CeB2up1}^T@ z?|_k4En|ki+4VB(vkv(p4gL3VNCWd6{^<-|S3!5gwk*LRspW^~K>P-W{ID+kO0;X} z@eG3UeA=9uc5x3k#{VM5t}idv?vNK<2Ki4zF0Q|cJ@|37k=H*vh)ZkBkG0cQK3vo2 z-;odfy*v0L&iyfE#Bx0Ur(CpboPO%Rnc4B#PIYoyFZ=Aq>pk&WPrTX_pX7;;^Td6g zc#$W53Vn3jKjDdYdg6HR+Nb;hPkgT@-tLL-@Wi)z;u}2iR!= z)Xhj^2B}OZUNudZtD1wlz(|uRi;#!nYR(UUn_1Hw^-pZ^ zr=#&`I1`PKUMAKQO(C(;Pb}Gz0ghyK>#T)0&%61C9EZVBBoZ{G6UmG}*3=x2HboO4 z<6jfaj7OC`byCr$;P#P0eR&1>-ZXUfnY9=EdZb;FeqF;dvs)WAQ?C6Js=gem&!La~2`Y zQnxIuSAP6snvvTTY5$~&Et4z#kRChkk4F>!iPKvAs?rZZw?t>Ka25}&o*1ZEO;M^) zI2>)xD3wlzZ;NL5<68;HAA=nOz+qVu{G4$xbckkEV;fcnrT$l<1SYD4Mz*%Fxp64<)qP zB-k|CL?4#NFdC6)I-H6%XVBO+q9?N(qv6};B~&~F1#S%Thp2++PSE^F*`$jl|KiF1 zTM~LiGf83EZ;F7p)NM+yaLdnIFx$TzdeD-BWGA+O2TkkpSVAX9BRaJ{)DVp$@8+Z* z8WW8}68Lo`E1xvejqK7U$B*_yiS#P;GZkIg5>02){$ygjs@LMcF9m^C7Uz8JE9Vd- zoaUfr!p&-Grm10K^#b$r_D858>lX5pVt zwZa_<{%iFc>T^A*;a@!3GV=c4uRU+;@qZk*@pR&%yHCX~SogKRDsL9Ur*#KYq64^1V+5o4Ym-S@pXuL;vXy+e_CR`_lRG zw?6ys+x~jjI~!j6q%ZpVr~hv5Z@x8S{!6>Ax&GH*tDbe}tJ4?%_y_M@w6A^qhkyRV zNgqA<=+w@Yg`a=<_M$KR=O;#Ndu4UWzrNY@o_pT-*w}ymQ+RaipCj-1%yaYJ_uy}D zp80RTy5Wi)zo?z|!2VkP>|82s^RZv?G5v z7Nug~ixGAsoI-H_EyJN0BZn;0?q^+23QA(-yu|U0nY=h2Rt8e0br@5 zj{sbZ_(+M523&$T?he#az;a0+4xcE3_<4ZLKOd0vN+mu5FphWu_Vvwxg@EMe0zj4< z1DF9E3%D8(7mR8xpkH7GU@PL&0oMaw3CMP?0wmozfGocda0B26C4L?rCbFG^*9{y3 z$Z~}OizI!hz+sZ^2i$~m;{mq-UJSSuZ~`Fts}ML*@&ka|kX{AY23QtHUl9BV6$q6G z)d({YY7y!XDsEKj!fJQK2Jt}&3`$^70)rA5l)#__1|={kfk6ojN?=d|gA(9xw&UKW zXp+E6fdPTl0&4`$6j&>;PT*XD^#T_NTr6;jz@-A035*DA6c`uSEHEQ*wZOFkTLrEc zc$dHp0yhcVB5&P zM+F`ectYSwfv*cZCGbsw3THGNw<3YX0(o}Bbf3U7fnx=Z6X+LMA&|d!&wAAYX9D7l zS5ck7dVz}tE)^IN7#ElkxK`kLfg1#F5x7m@4uQJ_?iRRL;C_Jz1s)c7MBq_@Cj`DO z@J)e5DbtTqfn@^639JxUDX?1LOo4R*>jf?rxKv<7U|e8E;97y}1#S?yMc_7pI|S|$ z*e-Clz&!%@3hWTLU*G|O2L&Dyco>l5iThdgZXoRyN_-peTETY$Uo7}R z;EjS;qTDM=(-?cU+5eCBZk%!XFV1ZKK6TEeiQjZbG z`5k}u{vh!Zr8vJ{61*Dtp9SYQjm1P`ndg8{CeHU5z^@U!6Zi)NKMFh~_^~va5c~x2 zI|M%o{8NIz4*c`LN1m0Ot;-yQ{PFHq<8l0Pwj+W+hq|u_ zJ{IYx1b_Xb=IoR7*Zu>}9no*%8$k2j#L=%>@LVPMGT^rgz65w&@CCr{7JM%7uL|A> z`~Y##&NKz*x$cdE*GC~+!Q;y@_JSWl zdZWc>D%B!*?fY;}D)|0up#Oqb%)t4v;D_F?)T6fim3Wgac>5Jf;W3Hs%MsxJE%;qm zL59OjdIxZP8?MXTg)&nGZwLKa!508uNF1_V23=Yy_+7w1D`mD#RO)`g_h7vCNSV1P z^R(bgfd5|b=YZq8V@-1b@OKJc4EawLyawsKlh$Jje1YK2z*_`w1pYa}TY*0$_-f$4 z6ub>Meppe{sR8}h1mA=73vixI`aYyzA^0Yw-z@l6;0eJG0be8dPT(5_KL8wm2Tapx z2mY|&r+~j8xB~sZ2tEn;MR?1>cKyJo3*Le9iv%Bw^i_g)B7LLa$AEuL@RPvz3LZfD z7l?CSgz(*xq;Ep{TY@(OAA>g8?pENJ3%(lowSu<-zg6(NfUhJDn!Zb5hXp_KUVObG z_z8^rzYD$;>H91mgdPfh6gd74nWn?LkUtB~`;cLc3fJWL$pQ3@G8A?Y=fVSfaV0Do1= z&^LNR(&vH>?>5Ni0pL>w-*PGLKn34ZsnkaVF9n@u!FOH;nb(yBJ_ldu;7JGnXM+!C-Op>BuUF7VC;f2;f7QXqjMnYy@)tSycn6>C z;L{v@hJ(*?@EaWbW(U93!9VKYQ3uaB_<9HbyvFIKDfJBpf7HRBb;|$A!AD(?>*FK` zpW)yiaPX*u|D%I%cJTWh{2LDbZ3q8>ga63Ef9l{*JNU01ywkyd=inzC{B;LcV{&~g zaqtTqyxhSrcJN9EuXgb7L)P?7e}J$D;fDwhBkV~MQlVzeh2UUctjK@^9`AFCIkkX@gJJbrlVJ()T&q_xI7Y!rPI-j3Yw=nb$CQH z8_(bxP(cMFQOE>u;egoJM|l&2t74hPARcAu+)OHjw@hi&Gpd zvmoC;1qUc4$)R|z{Jc6)3Z=r0hK^GLf=NVj1tB;#$&`IR+)gxez zCL#@Znio%|p(((Y$79eI(AKde##ke%=n6g*OZDp+s-(3ZgyXuPj)0w9Bt9)10wXM_ z)tNHPMy6x-BGLkd<;ybQX3lV~0?TNooTN2iqAA#bSBIHo5^5jSkLz@6xl)_}cx9NQ zhB<~Ohw&g7$>3RCuqhdF2s5`iiI;JC($fPr7*2+hcwmdip^k_tS(~h7Z4+`2HEoK# z`?OKMXSKMz9?e77eOHRo&_we;dKM2`l!i~wCd*tll4xmapo+k>Ft4R07O^u=zqoX* z2FhgTU{IcZ>Y5xH!x|qFlNM8?M38Srvx#O_1k-LoYp7T$kxVt2H@upcY&}-UQEE;$ zJJt;CHMgW2ofJ+0GgTeE4$3P>71Y@+m=%dkER0vBm}HU{h2H4d!`G%!P9kp{&yS(> zcr)EMBm0nbfMg5@EU#3GKs2DPl|KUWo474_TXc=78HuH3Dw=p>62{p~WRV*AizQaJ z#8Og4B7K^$L~Y0L5_JW7iWkVKXmeaD_ABJ%HDfgjV^W-vK)*r`ftATLMkK=pnjAx* zFi2P(v?0l+Xcn52@mP2bOY?;<>`&k9bPE>T+hd%-+FW6cwndtfkYgg$lx1_kj6TwV zndBO)n@Pr@))YEygvf={KYBZ@c2g*giNkVftf{c-DHi9Nk0sq?tV+eeL#VGh86)Ht z2**R|bTGLbv*UKWO?R`RtMU9e62;PQMisJ3HzyM`ziinwVDpTj%B2r1KvPfW4=6z? zlZ3I*Vsu+<4y`cn)wA+8rPEMlv9fOQw0;MV)gYFlzb1S}SJPyupf>sa=cLULTN8#y zl;A8e#UoKHo(am^J`>O8IJ3l*%`Qi2>IwyH(pwUFaxmj4ZY~@&I#_F90x2n*N)70f zs(mErZnl_CFveG5a=A-cF2=R2Ihl^F?!PMJl4Vse3GS+3QnIUpiJDcx;Q3aCJ~@^& zMkJ%3`NOvXnwy8&&j#$mAdZ1?fax!2&V^2{G<;M#B-sSL#yRmU)7cV+?`%}F=~T$q zm2Ba@Yg{&&gXHB*$2mcpLn-J$wya4vy4WWX-z(&bYrh!FVAeM_E-F3#K8`JBYOc(@ zI=+&Zl35Q|>jxAUJ_ub}>+RymLkBn#`OduSxZ-*?*qp>h|-pwR36Q zyZ(N#$!tl)R-@VeRn5w5K9r#B1}dSQ#{qK(BELKp?Q3uPQ=ldrPn3SX-YxboB>X`J z;w58e7fPid&ikWfy6+n5~sXXywnm6NtBWoVwZtK7B#Iobp=;2mPDa>-JX=~yP6ub{NzYYB$&NfJoq&qQCNnDcIC zBo>C6$T^RjVLIog(12pd63M<4n7o|Jw!;t8%&x>u&3&ttEsgK6fODG*`-pvs9)+f8 zQ>85QoCRO;N@v#QpY5r5!j$jp0ZTH_rOsID;2_6nRK1n1vjD295M6 zLZ!)9=PUITVzQ)XD4T{krYY%7(k1_~O+Yt{ZuN=4Th)dqv$14_#RB{FmSQm`+{#@ro!u+NB{cHr(f87&DUSv zxA-ToHN3X=V>9mfaO3>-e;W5+S3fl~RJHnr$@?CC>|mGgk{8-9{N`1=##Y?(=}`xY zKd|AQkNoz_H!V)?{ + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * In addition, as a special exception, Seleuco + * gives permission to link the code of this program with + * the MAME library (or with modified versions of MAME that use the + * same license as MAME), and distribute linked combinations including + * the two. You must obey the GNU General Public License in all + * respects for all of the code used other than MAME. If you modify + * this file, you may extend this exception to your version of the + * file, but you are not obligated to do so. If you do not wish to + * do so, delete this exception statement from your version. + */ + +#include +#include +#include +#include +#include + +#include "btstack/btstack.h" +#include "wiimote.h" + +//int num_of_joys = 0; +struct wiimote_t joys[4]; +extern int g_pref_wii_DZ_value; +#define STICK4WAY (myosd_waysStick == 4 && myosd_inGame) +#define STICK2WAY (myosd_waysStick == 2 && myosd_inGame) + +int wiimote_send(struct wiimote_t* wm, byte report_type, byte* msg, int len); +int wiimote_read_data(struct wiimote_t* wm, unsigned int addr, unsigned short len); +int wiimote_write_data(struct wiimote_t* wm, unsigned int addr, byte* data, byte len); +void wiimote_set_leds(struct wiimote_t* wm, int leds); +int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, byte* data, unsigned short len); +void classic_ctrl_event(struct classic_ctrl_t* cc, byte* msg); + +int wiimote_remove(uint16_t source_cid, bd_addr_t *addr){ + + int i = 0; + int unid = -1; + int found = 0; + for(;iaddr[0], wm->addr[1], wm->addr[2],wm->addr[3], wm->addr[4], wm->addr[5]); + memcpy(addr,&(wm->addr),BD_ADDR_LEN); + unid = wm->unid; + continue; + } + if(found) + { + memcpy(&joys[i-1],&joys[i],sizeof(struct wiimote_t )); + joys[i-1].unid = i-1; + struct wiimote_t *wm = NULL; + wm = &joys[i-1]; + if(wm->unid==0) + wiimote_set_leds(wm, WIIMOTE_LED_1); + else if(wm->unid==1) + wiimote_set_leds(wm, WIIMOTE_LED_2); + else if(wm->unid==2) + wiimote_set_leds(wm, WIIMOTE_LED_3); + else if(wm->unid==3) + wiimote_set_leds(wm, WIIMOTE_LED_4); + } + } + if(found) + { + myosd_num_of_joys--; + if(WIIMOTE_DBG)printf("NUM JOYS %d\n",myosd_num_of_joys); + return unid; + } + return unid; +} + +/** + * @brief Find a wiimote_t structure by its source_cid. + * + * @param wm Pointer to a wiimote_t structure. + * @param wiimotes The number of wiimote_t structures in \a wm. + * @param unid The unique identifier to search for. + * + * @return Pointer to a wiimote_t structure, or NULL if not found. + */ + +struct wiimote_t* wiimote_get_by_source_cid(uint16_t source_cid){ + + int i = 0; + + for (; i < myosd_num_of_joys; ++i) { + if(WIIMOTE_DBG)printf("0x%02x 0x%02x\n",joys[i].i_source_cid,source_cid); + if (joys[i].i_source_cid == source_cid) + return &joys[i]; + } + + return NULL; +} + +/** + * @brief Request the wiimote controller status. + * + * @param wm Pointer to a wiimote_t structure. + * + * Controller status includes: battery level, LED status, expansions + */ +void wiimote_status(struct wiimote_t* wm) { + byte buf = 0; + + if (!wm || !WIIMOTE_IS_CONNECTED(wm)) + return; + + if(WIIMOTE_DBG)printf("Requested wiimote status.\n"); + + wiimote_send(wm, WM_CMD_CTRL_STATUS, &buf, 1); +} + +void wiimote_data_report(struct wiimote_t* wm, byte type) { + byte buf[2] = {0x0,0x0}; + + if (!wm || !WIIMOTE_IS_CONNECTED(wm)) + return; + + buf[1] = type; +//CUIDADO es un &buf? + wiimote_send(wm, WM_CMD_REPORT_TYPE, buf, 2); +} + + +/** + * @brief Set the enabled LEDs. + * + * @param wm Pointer to a wiimote_t structure. + * @param leds What LEDs to enable. + * + * \a leds is a bitwise or of WIIMOTE_LED_1, WIIMOTE_LED_2, WIIMOTE_LED_3, or WIIMOTE_LED_4. + */ +void wiimote_set_leds(struct wiimote_t* wm, int leds) { + byte buf; + + if (!wm || !WIIMOTE_IS_CONNECTED(wm)) + return; + + /* remove the lower 4 bits because they control rumble */ + wm->leds = (leds & 0xF0); + + buf = wm->leds; + + wiimote_send(wm, WM_CMD_LED, &buf, 1); +} + +/** + * @brief Find what buttons are pressed. + * + * @param wm Pointer to a wiimote_t structure. + * @param msg The message specified in the event packet. + */ +void wiimote_pressed_buttons(struct wiimote_t* wm, byte* msg) { + short now; + + /* convert to big endian */ + now = BIG_ENDIAN_SHORT(*(short*)msg) & WIIMOTE_BUTTON_ALL; + + /* buttons pressed now */ + wm->btns = now; +} + +/** + * @brief Handle data from the expansion. + * + * @param wm A pointer to a wiimote_t structure. + * @param msg The message specified in the event packet for the expansion. + */ +void wiimote_handle_expansion(struct wiimote_t* wm, byte* msg) { + switch (wm->exp.type) { + case EXP_CLASSIC: + classic_ctrl_event(&wm->exp.classic, msg); + break; + default: + break; + } +} + +/** +* @brief Get initialization data from the wiimote. +* +* @param wm Pointer to a wiimote_t structure. +* @param data unused +* @param len unused +* +* When first called for a wiimote_t structure, a request +* is sent to the wiimote for initialization information. +* This includes factory set accelerometer data. +* The handshake will be concluded when the wiimote responds +* with this data. +*/ +int wiimote_handshake(struct wiimote_t* wm, byte event, byte* data, unsigned short len) { + + if (!wm) return 0; + + while(1) + { + if(WIIMOTE_DBG)printf("Handshake %d\n",wm->handshake_state); + switch (wm->handshake_state) { + case 0://no ha habido nunca handshake, debemos forzar un mensaje de staus para ver que pasa. + { + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE); + wiimote_set_leds(wm, WIIMOTE_LED_NONE); + + /* request the status of the wiimote to see if there is an expansion */ + wiimote_status(wm); + + wm->handshake_state=1; + return 0; + } + case 1://estamos haciendo handshake o bien se necesita iniciar un nuevo handshake ya que se inserta(quita una expansion. + { + int attachment = 0; + + if(event != WM_RPT_CTRL_STATUS) + return 0; + + /* is an attachment connected to the expansion port? */ + if ((data[2] & WM_CTRL_STATUS_BYTE1_ATTACHMENT) == WM_CTRL_STATUS_BYTE1_ATTACHMENT) + { + attachment = 1; + } + + if(WIIMOTE_DBG)printf("attachment %d %d\n",attachment,WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP)); + + /* expansion port */ + if (attachment && !WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP)) { + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_EXP); + + /* send the initialization code for the attachment */ + if(WIIMOTE_DBG)printf("haciendo el handshake de la expansion\n"); + + if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_HANDSHAKE_COMPLETE)) + { + if(WIIMOTE_DBG)printf("rehandshake\n"); + WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE); + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);//forzamos un handshake por si venimos de un hanshake completo + } + + byte buf; + //Old way. initialize the extension was by writing the single encryption byte 0x00 to 0x(4)A40040 + //buf = 0x00; + //wiimote_write_data(wm, WM_EXP_MEM_ENABLE, &buf, 1); + + //NEW WAY 0x55 to 0x(4)A400F0, then writing 0x00 to 0x(4)A400FB. (support clones) + buf = 0x55; + wiimote_write_data(wm, 0x04A400F0, &buf, 1); + usleep(100000); + buf = 0x00; + wiimote_write_data(wm, 0x04A400FB, &buf, 1); + + //check extension type! + usleep(100000); + wiimote_read_data(wm, WM_EXP_MEM_CALIBR+220, 4); + //wiimote_read_data(wm, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN); + + wm->handshake_state = 4; + return 0; + + } else if (!attachment && WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP)) { + /* attachment removed */ + WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP); + wm->exp.type = EXP_NONE; + + if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_HANDSHAKE_COMPLETE)) + { + if(WIIMOTE_DBG)printf("rehandshake\n"); + WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE); + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);//forzamos un handshake por si venimos de un hanshake completo + } + } + + if(!attachment && WIIMOTE_IS_SET(wm,WIIMOTE_STATE_HANDSHAKE)) + { + wm->handshake_state = 2; + continue; + } + + return 0; + } + case 2://find handshake no expansion + { + if(WIIMOTE_DBG)printf("Finalizado HANDSHAKE SIN EXPANSION\n"); + wiimote_data_report(wm,WM_RPT_BTN); + wm->handshake_state = 6; + continue; + } + case 3://find handshake expansion + { + if(WIIMOTE_DBG)printf("Finalizado HANDSHAKE CON EXPANSION\n"); + wiimote_data_report(wm,WM_RPT_BTN_EXP); + wm->handshake_state = 6; + continue; + } + case 4: + { + if(event != WM_RPT_READ) + return 0; + + int id = BIG_ENDIAN_LONG(*(int*)(data)); + + if(WIIMOTE_DBG)printf("Expansion id=0x%04x\n",id); + + if(id!=/*EXP_ID_CODE_CLASSIC_CONTROLLER*/0xa4200101) + { + wm->handshake_state = 2; + //WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP); + continue; + } + else + { + usleep(100000); + wiimote_read_data(wm, WM_EXP_MEM_CALIBR, 16);//pedimos datos de calibracion del JOY! + wm->handshake_state = 5; + } + + return 0; + } + case 5: + { + if(event != WM_RPT_READ) + return 0; + + classic_ctrl_handshake(wm, &wm->exp.classic, data,len); + wm->handshake_state = 3; + continue; + + } + case 6: + { + WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE); + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE); + wm->handshake_state = 1; + if(wm->unid==0) + wiimote_set_leds(wm, WIIMOTE_LED_1); + else if(wm->unid==1) + wiimote_set_leds(wm, WIIMOTE_LED_2); + else if(wm->unid==2) + wiimote_set_leds(wm, WIIMOTE_LED_3); + else if(wm->unid==3) + wiimote_set_leds(wm, WIIMOTE_LED_4); + return 1; + } + default: + { + break; + } + } + } +} + + +/** + * @brief Send a packet to the wiimote. + * + * @param wm Pointer to a wiimote_t structure. + * @param report_type The report type to send (WIIMOTE_CMD_LED, WIIMOTE_CMD_RUMBLE, etc). Found in wiimote.h + * @param msg The payload. + * @param len Length of the payload in bytes. + * + * This function should replace any write()s directly to the wiimote device. + */ +int wiimote_send(struct wiimote_t* wm, byte report_type, byte* msg, int len) { + byte buf[32]; + + buf[0] = WM_SET_REPORT | WM_BT_OUTPUT; + buf[1] = report_type; + + memcpy(buf+2, msg, len); + + if(WIIMOTE_DBG) + { + int x = 2; + printf("[DEBUG] (id %i) SEND: (%x) %.2x ", wm->unid, buf[0], buf[1]); + for (; x < len+2; ++x) + printf("%.2x ", buf[x]); + printf("\n"); + } + + bt_send_l2cap( wm->c_source_cid, buf, len+2); + return 1; +} + +/** + * @brief Read data from the wiimote (event version). + * + * @param wm Pointer to a wiimote_t structure. + * @param addr The address of wiimote memory to read from. + * @param len The length of the block to be read. + * + * The library can only handle one data read request at a time + * because it must keep track of the buffer and other + * events that are specific to that request. So if a request + * has already been made, subsequent requests will be added + * to a pending list and be sent out when the previous + * finishes. + */ +int wiimote_read_data(struct wiimote_t* wm, unsigned int addr, unsigned short len) { + //No puden ser mas de 16 lo leido o vendra en trozos! + + if (!wm || !WIIMOTE_IS_CONNECTED(wm)) + return 0; + if (!len /*|| len > 16*/) + return 0; + + byte buf[6]; + + /* the offset is in big endian */ + *(int*)(buf) = BIG_ENDIAN_LONG(addr); + + /* the length is in big endian */ + *(short*)(buf + 4) = BIG_ENDIAN_SHORT(len); + + if(WIIMOTE_DBG)printf("Request read at address: 0x%x length: %i", addr, len); + wiimote_send(wm, WM_CMD_READ_DATA, buf, 6); + + return 1; +} + +/** + * @brief Write data to the wiimote. + * + * @param wm Pointer to a wiimote_t structure. + * @param addr The address to write to. + * @param data The data to be written to the memory location. + * @param len The length of the block to be written. + */ +int wiimote_write_data(struct wiimote_t* wm, unsigned int addr, byte* data, byte len) { + byte buf[21] = {0}; /* the payload is always 23 */ + + if (!wm || !WIIMOTE_IS_CONNECTED(wm)) + return 0; + if (!data || !len) + return 0; + + if(WIIMOTE_DBG)printf("Writing %i bytes to memory location 0x%x...\n", len, addr); + + if(WIIMOTE_DBG) + { + int i = 0; + printf("Write data is: "); + for (; i < len; ++i) + printf("%x ", data[i]); + printf("\n"); + } + + /* the offset is in big endian */ + *(int*)(buf) = BIG_ENDIAN_LONG(addr); + + /* length */ + *(byte*)(buf + 4) = len; + + /* data */ + memcpy(buf + 5, data, len); + + wiimote_send(wm, WM_CMD_WRITE_DATA, buf, 21); + return 1; +} + + +/////////////////////// CLASSIC ///////////////// + +static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, short now); +void calc_joystick_state(struct joystick_t* js, float x, float y); + +/** + * @brief Handle the handshake data from the classic controller. + * + * @param cc A pointer to a classic_ctrl_t structure. + * @param data The data read in from the device. + * @param len The length of the data block, in bytes. + * + * @return Returns 1 if handshake was successful, 0 if not. + */ +int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, byte* data, unsigned short len) { + int i; + int offset = 0; + + cc->btns = 0; + cc->r_shoulder = 0; + cc->l_shoulder = 0; + + /* decrypt data */ + /* + for (i = 0; i < len; ++i) + data[i] = (data[i] ^ 0x17) + 0x17; + */ + + if(WIIMOTE_DBG) + { + int x = 0; + printf("[DECRIPTED]"); + for (; x < len; x++) + printf("%.2x ", data[x]); + printf("\n"); + } + +/* + if (data[offset] == 0xFF) + { + return 0;//ERROR! + } +*/ + /* joystick stuff */ + if (data[offset] != 0xFF && data[offset] != 0x00) + { + cc->ljs.max.x = data[0 + offset] / 4; + cc->ljs.min.x = data[1 + offset] / 4; + cc->ljs.center.x = data[2 + offset] / 4; + cc->ljs.max.y = data[3 + offset] / 4; + cc->ljs.min.y = data[4 + offset] / 4; + cc->ljs.center.y = data[5 + offset] / 4; + + cc->rjs.max.x = data[6 + offset] / 8; + cc->rjs.min.x = data[7 + offset] / 8; + cc->rjs.center.x = data[8 + offset] / 8; + cc->rjs.max.y = data[9 + offset] / 8; + cc->rjs.min.y = data[10 + offset] / 8; + cc->rjs.center.y = data[11 + offset] / 8; + } + else + { + cc->ljs.max.x = 55; + cc->ljs.min.x = 5; + cc->ljs.center.x = 30; + cc->ljs.max.y = 55; + cc->ljs.min.y = 5; + cc->ljs.center.y = 30; + + cc->rjs.max.x = 30; + cc->rjs.min.x = 0; + cc->rjs.center.x = 15; + cc->rjs.max.y = 30; + cc->rjs.min.y = 0; + cc->rjs.center.y = 15; + } + + /* handshake done */ + wm->exp.type = EXP_CLASSIC; + + return 1; +} + +/** + * @brief Handle classic controller event. + * + * @param cc A pointer to a classic_ctrl_t structure. + * @param msg The message specified in the event packet. + */ +void classic_ctrl_event(struct classic_ctrl_t* cc, byte* msg) { + int i, lx, ly, rx, ry; + byte l, r; + + /* decrypt data */ + /* + for (i = 0; i < 6; ++i) + msg[i] = (msg[i] ^ 0x17) + 0x17; + */ + + classic_ctrl_pressed_buttons(cc, BIG_ENDIAN_SHORT(*(short*)(msg + 4))); + + /* left/right buttons */ + l = (((msg[2] & 0x60) >> 2) | ((msg[3] & 0xE0) >> 5)); + r = (msg[3] & 0x1F); + + /* + * TODO - LR range hardcoded from 0x00 to 0x1F. + * This is probably in the calibration somewhere. + */ + cc->r_shoulder = ((float)r / 0x1F); + cc->l_shoulder = ((float)l / 0x1F); + + /* calculate joystick orientation */ + lx = (msg[0] & 0x3F); + ly = (msg[1] & 0x3F); + rx = ((msg[0] & 0xC0) >> 3) | ((msg[1] & 0xC0) >> 5) | ((msg[2] & 0x80) >> 7); + ry = (msg[2] & 0x1F); + + if(WIIMOTE_DBG) + printf("lx ly rx ry %d %d %d %d\n",lx,ly,rx,ry); + + calc_joystick_state(&cc->ljs, lx, ly); + calc_joystick_state(&cc->rjs, rx, ry); + + /* + printf("classic L button pressed: %f\n", cc->l_shoulder); + printf("classic R button pressed: %f\n", cc->r_shoulder); + printf("classic left joystick angle: %f\n", cc->ljs.ang); + printf("classic left joystick magnitude: %f\n", cc->ljs.mag); + printf("classic right joystick angle: %f\n", cc->rjs.ang); + printf("classic right joystick magnitude: %f\n", cc->rjs.mag); + */ +} + + +/** + * @brief Find what buttons are pressed. + * + * @param cc A pointer to a classic_ctrl_t structure. + * @param msg The message byte specified in the event packet. + */ +static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, short now) { + /* message is inverted (0 is active, 1 is inactive) */ + now = ~now & CLASSIC_CTRL_BUTTON_ALL; + + /* buttons pressed now */ + cc->btns = now; +} + +/** + * @brief Calculate the angle and magnitude of a joystick. + * + * @param js [out] Pointer to a joystick_t structure. + * @param x The raw x-axis value. + * @param y The raw y-axis value. + */ +void calc_joystick_state(struct joystick_t* js, float x, float y) { + float rx, ry, ang; + + /* + * Since the joystick center may not be exactly: + * (min + max) / 2 + * Then the range from the min to the center and the center to the max + * may be different. + * Because of this, depending on if the current x or y value is greater + * or less than the assoicated axis center value, it needs to be interpolated + * between the center and the minimum or maxmimum rather than between + * the minimum and maximum. + * + * So we have something like this: + * (x min) [-1] ---------*------ [0] (x center) [0] -------- [1] (x max) + * Where the * is the current x value. + * The range is therefore -1 to 1, 0 being the exact center rather than + * the middle of min and max. + */ + if (x == js->center.x) + rx = 0; + else if (x >= js->center.x) + rx = ((float)(x - js->center.x) / (float)(js->max.x - js->center.x)); + else + rx = ((float)(x - js->min.x) / (float)(js->center.x - js->min.x)) - 1.0f; + + if (y == js->center.y) + ry = 0; + else if (y >= js->center.y) + ry = ((float)(y - js->center.y) / (float)(js->max.y - js->center.y)); + else + ry = ((float)(y - js->min.y) / (float)(js->center.y - js->min.y)) - 1.0f; + + /* calculate the joystick angle and magnitude */ + ang = RAD_TO_DEGREE(atanf(ry / rx)); + ang -= 90.0f; + if (rx < 0.0f) + ang -= 180.0f; + js->ang = absf(ang); + js->mag = (float) sqrt((rx * rx) + (ry * ry)); + js->rx = rx; + js->ry = ry; + +} + +//////////////////////////////////////////////////////////// + +extern float joy_analog_x[4]; +extern float joy_analog_y[4]; + +int iOS_wiimote_check (struct wiimote_t *wm) +{ + return wm->btns; +} +#if 0 + joy_analog_x[wm->unid]=0.0f; + joy_analog_y[wm->unid]=0.0f; + if (1) { + if (wm->exp.type == EXP_CLASSIC) { + + float deadZone; + + switch(g_pref_wii_DZ_value) + { + case 0: deadZone = 0.12f;break; + case 1: deadZone = 0.15f;break; + case 2: deadZone = 0.17f;break; + case 3: deadZone = 0.2f;break; + case 4: deadZone = 0.3f;break; + case 5: deadZone = 0.4f;break; + } + + //printf("deadzone %f\n",deadZone); + + struct classic_ctrl_t* cc = (classic_ctrl_t*)&wm->exp.classic; + + if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_ZL)) joyExKey |= MYOSD_R1; + if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_B)) joyExKey |= MYOSD_X; + if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_Y)) joyExKey |= MYOSD_A; + if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_A)) joyExKey |= MYOSD_B; + if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_X)) joyExKey |= MYOSD_Y; + if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_ZR)) joyExKey |= MYOSD_L1; + + + if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_UP)){ + if(!STICK2WAY && + !(STICK4WAY && (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_LEFT) || + (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_RIGHT))))) + joyExKey |= MYOSD_UP; + } + if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_DOWN)){ + if(!STICK2WAY && + !(STICK4WAY && (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_LEFT) || + (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_RIGHT))))) + joyExKey |= MYOSD_DOWN; + } + if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_LEFT)) joyExKey |= MYOSD_LEFT; + if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_RIGHT)) joyExKey |= MYOSD_RIGHT; + + + if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_FULL_L)) joyExKey |= MYOSD_L1; + if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_MINUS)) joyExKey |= MYOSD_SELECT; + if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_HOME)) {//myosd_exitGame = 0;usleep(50000); + myosd_exitGame = 1;} + if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_PLUS)) joyExKey |= MYOSD_START; + if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_FULL_R)) joyExKey |= MYOSD_R1; + + if(cc->ljs.mag >= deadZone) + { + joy_analog_x[wm->unid] = ( cc->ljs.rx > 1.0 ) ? 1.0 : ( cc->ljs.rx < -1.0 ) ? -1.0 : cc->ljs.rx; + joy_analog_y[wm->unid] = ( cc->ljs.ry > 1.0 ) ? 1.0 : ( cc->ljs.ry < -1.0 ) ? -1.0 : cc->ljs.ry; + + float v = cc->ljs.ang; + + if(STICK2WAY) + { + if( v < 180){ + joyExKey |= MYOSD_RIGHT; + //printf("Right\n"); + } + else if ( v >= 180){ + joyExKey |= MYOSD_LEFT; + //printf("Left\n"); + } + } + else if(STICK4WAY) + { + if(v >= 315 || v < 45){ + joyExKey |= MYOSD_UP; + //printf("Up\n"); + } + else if (v >= 45 && v < 135){ + joyExKey |= MYOSD_RIGHT; + //printf("Right\n"); + } + else if (v >= 135 && v < 225){ + joyExKey |= MYOSD_DOWN; + //printf("Down\n"); + } + else if (v >= 225 && v < 315){ + joyExKey |= MYOSD_LEFT; + //printf("Left\n"); + } + } + else + { + if( v >= 330 || v < 30){ + joyExKey |= MYOSD_UP; + //printf("Up\n"); + } + else if ( v >= 30 && v <60 ) { + joyExKey |= MYOSD_UP;joyExKey |= MYOSD_RIGHT; + //printf("UpRight\n"); + } + else if ( v >= 60 && v < 120 ){ + joyExKey |= MYOSD_RIGHT; + //printf("Right\n"); + } + else if ( v >= 120 && v < 150 ){ + joyExKey |= MYOSD_RIGHT;joyExKey |= MYOSD_DOWN; + //printf("RightDown\n"); + } + else if ( v >= 150 && v < 210 ){ + joyExKey |= MYOSD_DOWN; + //printf("Down\n"); + } + else if ( v >= 210 && v < 240 ){ + joyExKey |= MYOSD_DOWN;joyExKey |= MYOSD_LEFT; + //printf("DownLeft\n"); + } + else if ( v >= 240 && v < 300 ){ + joyExKey |= MYOSD_LEFT; + //printf("Left\n"); + } + else if ( v >= 300 && v < 330 ){ + joyExKey |= MYOSD_LEFT; + joyExKey |= MYOSD_UP; + //printf("LeftUp\n"); + } + } + } + + if(cc->rjs.mag >= deadZone) + { + float v = cc->rjs.ang; + + if( v >= 330 || v < 30){ + joyExKey |= MYOSD_Y; + //printf("Y\n"); + } + else if ( v >= 30 && v <60 ) { + joyExKey |= MYOSD_Y;joyExKey |= MYOSD_B; + //printf("Y B\n"); + } + else if ( v >= 60 && v < 120 ){ + joyExKey |= MYOSD_B; + //printf("B\n"); + } + else if ( v >= 120 && v < 150 ){ + joyExKey |= MYOSD_B;joyExKey |= MYOSD_X; + //printf("B X\n"); + } + else if ( v >= 150 && v < 210 ){ + joyExKey |= MYOSD_X; + //printf("X\n"); + } + else if ( v >= 210 && v < 240 ){ + joyExKey |= MYOSD_X;joyExKey |= MYOSD_A; + //printf("X A\n"); + } + else if ( v >= 240 && v < 300 ){ + joyExKey |= MYOSD_A; + //printf("A\n"); + } + else if ( v >= 300 && v < 330 ){ + joyExKey |= MYOSD_A;joyExKey |= MYOSD_Y; + //printf("A Y\n"); + } + } +/* + printf("classic L button pressed: %f\n", cc->l_shoulder); + printf("classic R button pressed: %f\n", cc->r_shoulder); + + printf("classic left joystick angle: %f\n", cc->ljs.ang); + printf("classic left joystick magnitude: %f\n", cc->ljs.mag); + printf("classic left joystick rx: %f\n", cc->ljs.rx); + printf("classic left joystick ry: %f\n", cc->ljs.ry); + + printf("classic right joystick angle: %f\n", cc->rjs.ang); + printf("classic right joystick magnitude: %f\n", cc->rjs.mag); + printf("classic right rx: %f\n", cc->rjs.rx); + printf("classic right ry: %f\n", cc->rjs.ry); +*/ + } + return joyExKey; + } else { + joyExKey = 0; + return joyExKey; + } +} +#endif diff --git a/ios/RetroArch/BTStack/wiimote.h b/ios/RetroArch/BTStack/wiimote.h new file mode 100644 index 0000000000..ba58a97659 --- /dev/null +++ b/ios/RetroArch/BTStack/wiimote.h @@ -0,0 +1,294 @@ +/* + * This file is part of iMAME4all. + * + * Copyright (C) 2010 David Valdeita (Seleuco) + * + * based on: + * + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * In addition, as a special exception, Seleuco + * gives permission to link the code of this program with + * the MAME library (or with modified versions of MAME that use the + * same license as MAME), and distribute linked combinations including + * the two. You must obey the GNU General Public License in all + * respects for all of the code used other than MAME. If you modify + * this file, you may extend this exception to your version of the + * file, but you are not obligated to do so. If you do not wish to + * do so, delete this exception statement from your version. + */ + +#ifndef __WIIMOTE_H__ +#define __WIIMOTE_H__ + +#include "btstack/utils.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + typedef unsigned char byte; + typedef char sbyte; + + #define WIIMOTE_PI 3.14159265 + + #define WIIMOTE_DBG 0 + + /* Convert between radians and degrees */ + #define RAD_TO_DEGREE(r) ((r * 180.0f) / WIIMOTE_PI) + #define DEGREE_TO_RAD(d) (d * (WIIMOTE_PI / 180.0f)) + + /* Convert to big endian */ + #define BIG_ENDIAN_LONG(i) (htonl(i)) + #define BIG_ENDIAN_SHORT(i) (htons(i)) + + #define absf(x) ((x >= 0) ? (x) : (x * -1.0f)) + #define diff_f(x, y) ((x >= y) ? (absf(x - y)) : (absf(y - x))) + + /* wiimote state flags*/ + #define WIIMOTE_STATE_DEV_FOUND 0x0001 + #define WIIMOTE_STATE_HANDSHAKE 0x0002 /* actual connection exists but no handshake yet */ + #define WIIMOTE_STATE_HANDSHAKE_COMPLETE 0x0004 + #define WIIMOTE_STATE_CONNECTED 0x0008 + #define WIIMOTE_STATE_EXP 0x0040 + + /* Communication channels */ + #define WM_OUTPUT_CHANNEL 0x11 + #define WM_INPUT_CHANNEL 0x13 + + #define WM_SET_REPORT 0x50 + + /* commands */ + #define WM_CMD_LED 0x11 + #define WM_CMD_REPORT_TYPE 0x12 + #define WM_CMD_RUMBLE 0x13 + #define WM_CMD_IR 0x13 + #define WM_CMD_CTRL_STATUS 0x15 + #define WM_CMD_WRITE_DATA 0x16 + #define WM_CMD_READ_DATA 0x17 + #define WM_CMD_IR_2 0x1A + + /* input report ids */ + #define WM_RPT_CTRL_STATUS 0x20 + #define WM_RPT_READ 0x21 + #define WM_RPT_WRITE 0x22 + #define WM_RPT_BTN 0x30 + #define WM_RPT_BTN_ACC 0x31 + #define WM_RPT_BTN_ACC_IR 0x33 + #define WM_RPT_BTN_EXP 0x34 + #define WM_RPT_BTN_ACC_EXP 0x35 + #define WM_RPT_BTN_IR_EXP 0x36 + #define WM_RPT_BTN_ACC_IR_EXP 0x37 + + #define WM_BT_INPUT 0x01 + #define WM_BT_OUTPUT 0x02 + + /* controller status stuff */ + #define WM_MAX_BATTERY_CODE 0xC8 + + #define EXP_ID_CODE_CLASSIC_CONTROLLER 0x9A1EFDFD + + /* offsets in wiimote memory */ + #define WM_MEM_OFFSET_CALIBRATION 0x16 + #define WM_EXP_MEM_BASE 0x04A40000 + #define WM_EXP_MEM_ENABLE 0x04A40040 + #define WM_EXP_MEM_CALIBR 0x04A40020 + + #define EXP_HANDSHAKE_LEN 224 + + /* controller status flags for the first message byte */ + /* bit 1 is unknown */ + #define WM_CTRL_STATUS_BYTE1_ATTACHMENT 0x02 + #define WM_CTRL_STATUS_BYTE1_SPEAKER_ENABLED 0x04 + #define WM_CTRL_STATUS_BYTE1_IR_ENABLED 0x08 + #define WM_CTRL_STATUS_BYTE1_LED_1 0x10 + #define WM_CTRL_STATUS_BYTE1_LED_2 0x20 + #define WM_CTRL_STATUS_BYTE1_LED_3 0x40 + #define WM_CTRL_STATUS_BYTE1_LED_4 0x80 + + /* led bit masks */ + #define WIIMOTE_LED_NONE 0x00 + #define WIIMOTE_LED_1 0x10 + #define WIIMOTE_LED_2 0x20 + #define WIIMOTE_LED_3 0x40 + #define WIIMOTE_LED_4 0x80 + + /* button codes */ + #define WIIMOTE_BUTTON_TWO 0x0001 + #define WIIMOTE_BUTTON_ONE 0x0002 + #define WIIMOTE_BUTTON_B 0x0004 + #define WIIMOTE_BUTTON_A 0x0008 + #define WIIMOTE_BUTTON_MINUS 0x0010 + #define WIIMOTE_BUTTON_ZACCEL_BIT6 0x0020 + #define WIIMOTE_BUTTON_ZACCEL_BIT7 0x0040 + #define WIIMOTE_BUTTON_HOME 0x0080 + #define WIIMOTE_BUTTON_LEFT 0x0100 + #define WIIMOTE_BUTTON_RIGHT 0x0200 + #define WIIMOTE_BUTTON_DOWN 0x0400 + #define WIIMOTE_BUTTON_UP 0x0800 + #define WIIMOTE_BUTTON_PLUS 0x1000 + #define WIIMOTE_BUTTON_ZACCEL_BIT4 0x2000 + #define WIIMOTE_BUTTON_ZACCEL_BIT5 0x4000 + #define WIIMOTE_BUTTON_UNKNOWN 0x8000 + #define WIIMOTE_BUTTON_ALL 0x1F9F + + /* classic controller button codes */ + #define CLASSIC_CTRL_BUTTON_UP 0x0001 + #define CLASSIC_CTRL_BUTTON_LEFT 0x0002 + #define CLASSIC_CTRL_BUTTON_ZR 0x0004 + #define CLASSIC_CTRL_BUTTON_X 0x0008 + #define CLASSIC_CTRL_BUTTON_A 0x0010 + #define CLASSIC_CTRL_BUTTON_Y 0x0020 + #define CLASSIC_CTRL_BUTTON_B 0x0040 + #define CLASSIC_CTRL_BUTTON_ZL 0x0080 + #define CLASSIC_CTRL_BUTTON_FULL_R 0x0200 + #define CLASSIC_CTRL_BUTTON_PLUS 0x0400 + #define CLASSIC_CTRL_BUTTON_HOME 0x0800 + #define CLASSIC_CTRL_BUTTON_MINUS 0x1000 + #define CLASSIC_CTRL_BUTTON_FULL_L 0x2000 + #define CLASSIC_CTRL_BUTTON_DOWN 0x4000 + #define CLASSIC_CTRL_BUTTON_RIGHT 0x8000 + #define CLASSIC_CTRL_BUTTON_ALL 0xFEFF + + /* expansion codes */ + #define EXP_NONE 0 + #define EXP_CLASSIC 2 + + /** + * @struct vec2b_t + * @brief Unsigned x,y byte vector. + */ + typedef struct vec2b_t { + byte x, y; + } vec2b_t; + + /** + * @struct joystick_t + * @brief Joystick calibration structure. + * + * The angle \a ang is relative to the positive y-axis into quadrant I + * and ranges from 0 to 360 degrees. So if the joystick is held straight + * upwards then angle is 0 degrees. If it is held to the right it is 90, + * down is 180, and left is 270. + * + * The magnitude \a mag is the distance from the center to where the + * joystick is being held. The magnitude ranges from 0 to 1. + * If the joystick is only slightly tilted from the center the magnitude + * will be low, but if it is closer to the outter edge the value will + * be higher. + */ + typedef struct joystick_t { + struct vec2b_t max; /**< maximum joystick values */ + struct vec2b_t min; /**< minimum joystick values */ + struct vec2b_t center; /**< center joystick values */ + + float ang; /**< angle the joystick is being held */ + float mag; /**< magnitude of the joystick (range 0-1) */ + float rx, ry; + } joystick_t; + + /** + * @struct classic_ctrl_t + * @brief Classic controller expansion device. + */ + typedef struct classic_ctrl_t { + short btns; /**< what buttons have just been pressed */ + + float r_shoulder; /**< right shoulder button (range 0-1) */ + float l_shoulder; /**< left shoulder button (range 0-1) */ + + struct joystick_t ljs; /**< left joystick calibration */ + struct joystick_t rjs; /**< right joystick calibration */ + } classic_ctrl_t; + + /** + * @struct expansion_t + * @brief Generic expansion device plugged into wiimote. + */ + typedef struct expansion_t { + int type; /**< type of expansion attached */ + + union { + struct classic_ctrl_t classic; + }; + } expansion_t; + + /** + * @struct wiimote_t + * @brief Wiimote structure. + */ + typedef struct wiimote_t { + int unid; /**< user specified id */ + + uint16_t wiiMoteConHandle; + uint16_t i_source_cid; + uint16_t c_source_cid; + bd_addr_t addr; + + int state; /**< various state flags */ + byte leds; /**< currently lit leds */ + float battery_level; /**< battery level */ + + byte handshake_state; /**< the state of the connection handshake */ + + struct expansion_t exp; /**< wiimote expansion device */ + + unsigned short btns; /**< what buttons have just been pressed */ + } wiimote; + + /** + * @brief Check if a button is pressed. + * @param dev Pointer to a wiimote_t or expansion structure. + * @param button The button you are interested in. + * @return 1 if the button is pressed, 0 if not. + */ + #define IS_PRESSED(dev, button) ((dev->btns & button) == button) + + /* macro to manage states */ + #define WIIMOTE_IS_SET(wm, s) ((wm->state & (s)) == (s)) + #define WIIMOTE_ENABLE_STATE(wm, s) (wm->state |= (s)) + #define WIIMOTE_DISABLE_STATE(wm, s) (wm->state &= ~(s)) + #define WIIMOTE_TOGGLE_STATE(wm, s) ((wm->state & (s)) ? WIIMOTE_DISABLE_STATE(wm, s) : WIIMOTE_ENABLE_STATE(wm, s)) + + #define WIIMOTE_IS_CONNECTED(wm) (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_CONNECTED)) + + extern struct wiimote_t joys[4]; + extern int myosd_num_of_joys; + + +//devuelve un int haciendo polling de lo guardado en el wiimote +int iOS_wiimote_check (struct wiimote_t *wm); +int wiimote_remove(uint16_t source_cid, bd_addr_t *addr); +struct wiimote_t* wiimote_get_by_source_cid(uint16_t source_cid); +int wiimote_handshake(struct wiimote_t* wm, byte event, byte* data, unsigned short len); +void wiimote_status(struct wiimote_t* wm); +void wiimote_data_report(struct wiimote_t* wm, byte type); +void wiimote_pressed_buttons(struct wiimote_t* wm, byte* msg); +void wiimote_handle_expansion(struct wiimote_t* wm, byte* msg); + + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/ios/RetroArch/PauseView.xib b/ios/RetroArch/PauseView.xib index f81d6519b1..070ab1125c 100644 --- a/ios/RetroArch/PauseView.xib +++ b/ios/RetroArch/PauseView.xib @@ -78,7 +78,7 @@ {{20, 20}, {260, 44}} - + _NS:9 NO IBIPadFramework @@ -238,6 +238,29 @@ + + + 292 + {{20, 71}, {260, 44}} + + + + _NS:9 + NO + IBIPadFramework + 0 + 0 + 1 + Connect WiiMotes + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + {{0, 20}, {300, 300}} @@ -318,6 +341,15 @@ 139 + + + conntectWiimotes: + + + 7 + + 147 + @@ -539,6 +571,54 @@ 29 3 + + + 5 + 0 + + 5 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 6 + 0 + + 6 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 3 + 0 + + 4 + 1 + + 8 + + 1000 + + 6 + 24 + 3 + 6 @@ -593,6 +673,7 @@ + @@ -766,6 +847,27 @@ + + 140 + + + + + + 142 + + + + + 143 + + + + + 146 + + + @@ -778,6 +880,9 @@ + + + @@ -815,6 +920,11 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -834,7 +944,7 @@ - 139 + 147 @@ -849,6 +959,50 @@ RetroArch_iOS UIResponder + + id + id + id + id + id + id + id + id + + + + chooseState: + id + + + closeGamePressed: + id + + + closePauseMenu: + id + + + conntectWiimotes: + id + + + loadState: + id + + + resetGame: + id + + + saveState: + id + + + showPauseMenu: + id + + IBProjectSource ./Classes/RetroArch_iOS.h diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 2d3282a4e4..005906567e 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -17,6 +17,9 @@ #include "rarch_wrapper.h" #include "general.h" +#include "BTStack/wiimote.h" +#import "BTStack/WiiMoteHelper.h" + #define ALMOST_INVISIBLE .021f @interface RANavigator : UINavigationController @@ -359,5 +362,11 @@ [self pushViewController:[RASettingsList new] isGame:NO]; } +- (IBAction)conntectWiimotes:(id)sender +{ + [WiiMoteHelper startwiimote:_navigator]; +} + + @end diff --git a/ios/RetroArch/ios_input.m b/ios/RetroArch/ios_input.m index 1887539b41..a83b7cb2cf 100644 --- a/ios/RetroArch/ios_input.m +++ b/ios/RetroArch/ios_input.m @@ -18,6 +18,7 @@ #include "../../performance.h" #include "../../general.h" #include "../../driver.h" +#include "BTStack/wiimote.h" #define MAX_TOUCH 16 #define MAX_KEYS 256 @@ -150,6 +151,23 @@ static int16_t ios_input_state(void *data, const struct retro_keybind **binds, u switch (device) { case RETRO_DEVICE_JOYPAD: + if (myosd_num_of_joys > 0) + { + struct wiimote_t* wm = &joys[0]; + + switch (id) + { + case RETRO_DEVICE_ID_JOYPAD_A: return IS_PRESSED(wm, WIIMOTE_BUTTON_TWO); + case RETRO_DEVICE_ID_JOYPAD_B: return IS_PRESSED(wm, WIIMOTE_BUTTON_ONE); + case RETRO_DEVICE_ID_JOYPAD_START: return IS_PRESSED(wm, WIIMOTE_BUTTON_PLUS); + case RETRO_DEVICE_ID_JOYPAD_SELECT: return IS_PRESSED(wm, WIIMOTE_BUTTON_MINUS); + case RETRO_DEVICE_ID_JOYPAD_UP: return IS_PRESSED(wm, WIIMOTE_BUTTON_UP); + case RETRO_DEVICE_ID_JOYPAD_DOWN: return IS_PRESSED(wm, WIIMOTE_BUTTON_DOWN); + case RETRO_DEVICE_ID_JOYPAD_LEFT: return IS_PRESSED(wm, WIIMOTE_BUTTON_LEFT); + case RETRO_DEVICE_ID_JOYPAD_RIGHT: return IS_PRESSED(wm, WIIMOTE_BUTTON_RIGHT); + } + } + return l_ios_joypad_device_state(binds, port, id); case RETRO_DEVICE_ANALOG: return 0; From fd52e8c5370e9fb467bda702e20a1f9b077a0c5a Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 26 Feb 2013 23:25:42 -0500 Subject: [PATCH 081/108] ios: Add a RetroArch-nobtstack target to the Xcode project, use to build a version that doesn't depend on BTStack. --- ios/RetroArch.xcodeproj/project.pbxproj | 290 ++++++++++++++++++++++++ ios/RetroArch/RetroArch_iOS.m | 4 + ios/RetroArch/ios_input.m | 5 + 3 files changed, 299 insertions(+) diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 05944e26d8..ed8e0023e8 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -13,6 +13,86 @@ 9614C6BD16DD7C00000B36EF /* libBTstack.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 9614C6B816DD7C00000B36EF /* libBTstack.dylib */; }; 9614C6BE16DD7C00000B36EF /* WiiMoteHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6BA16DD7C00000B36EF /* WiiMoteHelper.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 9614C6C116DD7D54000B36EF /* wiimote.c in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6BF16DD7D54000B36EF /* wiimote.c */; }; + 9614C6C416DDC018000B36EF /* autosave.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAE9D16C1D9A9009DE44C /* autosave.c */; }; + 9614C6C516DDC018000B36EF /* cheats.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEA016C1D9A9009DE44C /* cheats.c */; }; + 9614C6C616DDC018000B36EF /* command.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEA216C1D9A9009DE44C /* command.c */; }; + 9614C6C716DDC018000B36EF /* driver.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEA716C1D9A9009DE44C /* driver.c */; }; + 9614C6C816DDC018000B36EF /* dynamic.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEA916C1D9A9009DE44C /* dynamic.c */; }; + 9614C6C916DDC018000B36EF /* fifo_buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEAB16C1D9A9009DE44C /* fifo_buffer.c */; }; + 9614C6CA16DDC018000B36EF /* file_extract.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEAD16C1D9A9009DE44C /* file_extract.c */; }; + 9614C6CB16DDC018000B36EF /* file_path.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEAF16C1D9A9009DE44C /* file_path.c */; }; + 9614C6CC16DDC018000B36EF /* file.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEB016C1D9A9009DE44C /* file.c */; }; + 9614C6CD16DDC018000B36EF /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEB316C1D9A9009DE44C /* hash.c */; }; + 9614C6CE16DDC018000B36EF /* message.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEB616C1D9A9009DE44C /* message.c */; }; + 9614C6CF16DDC018000B36EF /* movie.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEB816C1D9A9009DE44C /* movie.c */; }; + 9614C6D016DDC018000B36EF /* patch.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEBD16C1D9A9009DE44C /* patch.c */; }; + 9614C6D116DDC018000B36EF /* performance.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEBF16C1D9A9009DE44C /* performance.c */; }; + 9614C6D216DDC018000B36EF /* retroarch.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEC216C1D9A9009DE44C /* retroarch.c */; }; + 9614C6D316DDC018000B36EF /* rewind.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEC316C1D9A9009DE44C /* rewind.c */; }; + 9614C6D416DDC018000B36EF /* screenshot.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEC516C1D9A9009DE44C /* screenshot.c */; }; + 9614C6D516DDC018000B36EF /* settings.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEC716C1D9A9009DE44C /* settings.c */; }; + 9614C6D616DDC018000B36EF /* thread.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEC816C1D9A9009DE44C /* thread.c */; }; + 9614C6D716DDC018000B36EF /* config_file.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEE116C1DBDB009DE44C /* config_file.c */; }; + 9614C6D816DDC018000B36EF /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEFD16C1DC73009DE44C /* utils.c */; }; + 9614C6D916DDC018000B36EF /* compat.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF2416C1DFC8009DE44C /* compat.c */; }; + 9614C6DA16DDC018000B36EF /* rxml.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF2916C1DFC8009DE44C /* rxml.c */; }; + 9614C6DB16DDC018000B36EF /* bitmapfont.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF4816C1E00A009DE44C /* bitmapfont.c */; }; + 9614C6DC16DDC018000B36EF /* fonts.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF4B16C1E00A009DE44C /* fonts.c */; }; + 9614C6DD16DDC018000B36EF /* gl_font.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF4E16C1E00A009DE44C /* gl_font.c */; }; + 9614C6DE16DDC018000B36EF /* gl_raster_font.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF5016C1E00A009DE44C /* gl_raster_font.c */; }; + 9614C6DF16DDC018000B36EF /* gfx_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF5416C1E00A009DE44C /* gfx_common.c */; }; + 9614C6E016DDC018000B36EF /* gfx_context.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF5616C1E00A009DE44C /* gfx_context.c */; }; + 9614C6E116DDC018000B36EF /* gl.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF5816C1E00A009DE44C /* gl.c */; }; + 9614C6E216DDC018000B36EF /* image.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF5A16C1E00A009DE44C /* image.c */; }; + 9614C6E316DDC018000B36EF /* matrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF5D16C1E00A009DE44C /* matrix.c */; }; + 9614C6E416DDC018000B36EF /* matrix_3x3.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF5F16C1E00A009DE44C /* matrix_3x3.c */; }; + 9614C6E516DDC018000B36EF /* rpng.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF6716C1E00A009DE44C /* rpng.c */; }; + 9614C6E616DDC018000B36EF /* filter.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF6B16C1E00A009DE44C /* filter.c */; }; + 9614C6E716DDC018000B36EF /* pixconv.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF6D16C1E00A009DE44C /* pixconv.c */; }; + 9614C6E816DDC018000B36EF /* scaler.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF6F16C1E00A009DE44C /* scaler.c */; }; + 9614C6E916DDC018000B36EF /* scaler_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF7116C1E00A009DE44C /* scaler_int.c */; }; + 9614C6EA16DDC018000B36EF /* shader_glsl.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF7716C1E00A009DE44C /* shader_glsl.c */; }; + 9614C6EB16DDC018000B36EF /* state_tracker.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF7B16C1E00A009DE44C /* state_tracker.c */; }; + 9614C6EC16DDC018000B36EF /* sinc.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEF716C1DC73009DE44C /* sinc.c */; }; + 9614C6ED16DDC018000B36EF /* input_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFC916C1FBC0009DE44C /* input_common.c */; }; + 9614C6EE16DDC018000B36EF /* overlay.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCE16C1FBC0009DE44C /* overlay.c */; }; + 9614C6EF16DDC018000B36EF /* ioseagl_ctx.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */; }; + 9614C6F016DDC018000B36EF /* RetroArch_iOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */; }; + 9614C6F116DDC018000B36EF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0E16C5AEA100E6DCE0 /* main.m */; }; + 9614C6F216DDC018000B36EF /* resampler.c in Sources */ = {isa = PBXBuildFile; fileRef = 96366C4F16C9A4E100D64A22 /* resampler.c */; }; + 9614C6F316DDC018000B36EF /* hermite.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEEC16C1DC73009DE44C /* hermite.c */; }; + 9614C6F416DDC018000B36EF /* coreaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEE816C1DC73009DE44C /* coreaudio.c */; }; + 9614C6F516DDC018000B36EF /* RAButtonGetter.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5ABC16CC522F009BBD19 /* RAButtonGetter.m */; }; + 9614C6F616DDC018000B36EF /* RASettingEnumerationList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5ABD16CC522F009BBD19 /* RASettingEnumerationList.m */; }; + 9614C6F716DDC018000B36EF /* RASettingsSubList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5ABE16CC522F009BBD19 /* RASettingsSubList.m */; }; + 9614C6F816DDC018000B36EF /* RASettingsList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5ABF16CC522F009BBD19 /* RASettingsList.m */; }; + 9614C6F916DDC018000B36EF /* RADirectoryList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC416CC523B009BBD19 /* RADirectoryList.m */; }; + 9614C6FA16DDC018000B36EF /* RAGameView.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC516CC523B009BBD19 /* RAGameView.m */; }; + 9614C6FB16DDC018000B36EF /* RAModuleList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC616CC523B009BBD19 /* RAModuleList.m */; }; + 9614C6FC16DDC018000B36EF /* RAModuleInfoList.m in Sources */ = {isa = PBXBuildFile; fileRef = 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */; }; + 9614C6FD16DDC018000B36EF /* RADirectoryGrid.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2316D453BA00FE8D5A /* RADirectoryGrid.m */; }; + 9614C6FE16DDC018000B36EF /* browser.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2816D5A56400FE8D5A /* browser.m */; }; + 9614C6FF16DDC018000B36EF /* RAConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2F16D7045700FE8D5A /* RAConfig.m */; }; + 9614C70016DDC018000B36EF /* ios_input.m in Sources */ = {isa = PBXBuildFile; fileRef = 965AE29D16D9BF94001D7667 /* ios_input.m */; }; + 9614C70616DDC018000B36EF /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */; }; + 9614C70716DDC018000B36EF /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5416C9AC3300D64A22 /* CoreAudio.framework */; }; + 9614C70816DDC018000B36EF /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAF2116C1DF88009DE44C /* libz.dylib */; }; + 9614C70916DDC018000B36EF /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; + 9614C70A16DDC018000B36EF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; + 9614C70B16DDC018000B36EF /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; + 9614C70C16DDC018000B36EF /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2F16C1D4EA009DE44C /* GLKit.framework */; }; + 9614C70D16DDC018000B36EF /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE3116C1D4EA009DE44C /* OpenGLES.framework */; }; + 9614C71016DDC018000B36EF /* overlays in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2616C82FF100E6DCE0 /* overlays */; }; + 9614C71116DDC018000B36EF /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE3616C1D4EA009DE44C /* InfoPlist.strings */; }; + 9614C71216DDC018000B36EF /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE3F16C1D4EA009DE44C /* Default.png */; }; + 9614C71316DDC018000B36EF /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4116C1D4EA009DE44C /* Default@2x.png */; }; + 9614C71416DDC018000B36EF /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4316C1D4EA009DE44C /* Default-568h@2x.png */; }; + 9614C71516DDC018000B36EF /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; }; + 9614C71616DDC018000B36EF /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; }; + 9614C71716DDC018000B36EF /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2216C818FF00E6DCE0 /* Icon-72.png */; }; + 9614C71816DDC018000B36EF /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2316C818FF00E6DCE0 /* Icon.png */; }; + 9614C71916DDC018000B36EF /* PauseView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 969EBF6916D95746003787A2 /* PauseView.xib */; }; + 9614C71A16DDC018000B36EF /* PauseIndicatorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 965AE29F16DA83C1001D7667 /* PauseIndicatorView.xib */; }; 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */; }; 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; }; 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; }; @@ -111,6 +191,8 @@ 9614C6BA16DD7C00000B36EF /* WiiMoteHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WiiMoteHelper.m; sourceTree = ""; }; 9614C6BF16DD7D54000B36EF /* wiimote.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wiimote.c; sourceTree = ""; }; 9614C6C016DD7D54000B36EF /* wiimote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wiimote.h; sourceTree = ""; }; + 9614C71E16DDC018000B36EF /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 9614C71F16DDC018000B36EF /* RetroArch copy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "RetroArch copy-Info.plist"; path = "/Users/jason/Documents/Projects/ios/RetroArch/ios/RetroArch copy-Info.plist"; sourceTree = ""; }; 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioseagl_ctx.c; sourceTree = ""; }; 962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = ""; }; 962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = ""; }; @@ -260,6 +342,21 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 9614C70516DDC018000B36EF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9614C70616DDC018000B36EF /* AudioToolbox.framework in Frameworks */, + 9614C70716DDC018000B36EF /* CoreAudio.framework in Frameworks */, + 9614C70816DDC018000B36EF /* libz.dylib in Frameworks */, + 9614C70916DDC018000B36EF /* UIKit.framework in Frameworks */, + 9614C70A16DDC018000B36EF /* Foundation.framework in Frameworks */, + 9614C70B16DDC018000B36EF /* CoreGraphics.framework in Frameworks */, + 9614C70C16DDC018000B36EF /* GLKit.framework in Frameworks */, + 9614C70D16DDC018000B36EF /* OpenGLES.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 96AFAE2216C1D4EA009DE44C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -334,6 +431,7 @@ 96AFAE3316C1D4EA009DE44C /* RetroArch */, 96AFAE2816C1D4EA009DE44C /* Frameworks */, 96AFAE2616C1D4EA009DE44C /* Products */, + 9614C71F16DDC018000B36EF /* RetroArch copy-Info.plist */, ); sourceTree = ""; }; @@ -341,6 +439,7 @@ isa = PBXGroup; children = ( 96AFAE2516C1D4EA009DE44C /* RetroArch.app */, + 9614C71E16DDC018000B36EF /* RetroArch.app */, ); name = Products; sourceTree = ""; @@ -623,6 +722,23 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 9614C6C216DDC018000B36EF /* RetroArch-nobtstack */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9614C71B16DDC018000B36EF /* Build configuration list for PBXNativeTarget "RetroArch-nobtstack" */; + buildPhases = ( + 9614C6C316DDC018000B36EF /* Sources */, + 9614C70516DDC018000B36EF /* Frameworks */, + 9614C70F16DDC018000B36EF /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "RetroArch-nobtstack"; + productName = RetroArch; + productReference = 9614C71E16DDC018000B36EF /* RetroArch.app */; + productType = "com.apple.product-type.application"; + }; 96AFAE2416C1D4EA009DE44C /* RetroArch */ = { isa = PBXNativeTarget; buildConfigurationList = 96AFAE5416C1D4EA009DE44C /* Build configuration list for PBXNativeTarget "RetroArch" */; @@ -662,11 +778,30 @@ projectRoot = ""; targets = ( 96AFAE2416C1D4EA009DE44C /* RetroArch */, + 9614C6C216DDC018000B36EF /* RetroArch-nobtstack */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 9614C70F16DDC018000B36EF /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9614C71016DDC018000B36EF /* overlays in Resources */, + 9614C71116DDC018000B36EF /* InfoPlist.strings in Resources */, + 9614C71216DDC018000B36EF /* Default.png in Resources */, + 9614C71316DDC018000B36EF /* Default@2x.png in Resources */, + 9614C71416DDC018000B36EF /* Default-568h@2x.png in Resources */, + 9614C71516DDC018000B36EF /* ic_dir.png in Resources */, + 9614C71616DDC018000B36EF /* ic_file.png in Resources */, + 9614C71716DDC018000B36EF /* Icon-72.png in Resources */, + 9614C71816DDC018000B36EF /* Icon.png in Resources */, + 9614C71916DDC018000B36EF /* PauseView.xib in Resources */, + 9614C71A16DDC018000B36EF /* PauseIndicatorView.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 96AFAE2316C1D4EA009DE44C /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -688,6 +823,74 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 9614C6C316DDC018000B36EF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9614C6C416DDC018000B36EF /* autosave.c in Sources */, + 9614C6C516DDC018000B36EF /* cheats.c in Sources */, + 9614C6C616DDC018000B36EF /* command.c in Sources */, + 9614C6C716DDC018000B36EF /* driver.c in Sources */, + 9614C6C816DDC018000B36EF /* dynamic.c in Sources */, + 9614C6C916DDC018000B36EF /* fifo_buffer.c in Sources */, + 9614C6CA16DDC018000B36EF /* file_extract.c in Sources */, + 9614C6CB16DDC018000B36EF /* file_path.c in Sources */, + 9614C6CC16DDC018000B36EF /* file.c in Sources */, + 9614C6CD16DDC018000B36EF /* hash.c in Sources */, + 9614C6CE16DDC018000B36EF /* message.c in Sources */, + 9614C6CF16DDC018000B36EF /* movie.c in Sources */, + 9614C6D016DDC018000B36EF /* patch.c in Sources */, + 9614C6D116DDC018000B36EF /* performance.c in Sources */, + 9614C6D216DDC018000B36EF /* retroarch.c in Sources */, + 9614C6D316DDC018000B36EF /* rewind.c in Sources */, + 9614C6D416DDC018000B36EF /* screenshot.c in Sources */, + 9614C6D516DDC018000B36EF /* settings.c in Sources */, + 9614C6D616DDC018000B36EF /* thread.c in Sources */, + 9614C6D716DDC018000B36EF /* config_file.c in Sources */, + 9614C6D816DDC018000B36EF /* utils.c in Sources */, + 9614C6D916DDC018000B36EF /* compat.c in Sources */, + 9614C6DA16DDC018000B36EF /* rxml.c in Sources */, + 9614C6DB16DDC018000B36EF /* bitmapfont.c in Sources */, + 9614C6DC16DDC018000B36EF /* fonts.c in Sources */, + 9614C6DD16DDC018000B36EF /* gl_font.c in Sources */, + 9614C6DE16DDC018000B36EF /* gl_raster_font.c in Sources */, + 9614C6DF16DDC018000B36EF /* gfx_common.c in Sources */, + 9614C6E016DDC018000B36EF /* gfx_context.c in Sources */, + 9614C6E116DDC018000B36EF /* gl.c in Sources */, + 9614C6E216DDC018000B36EF /* image.c in Sources */, + 9614C6E316DDC018000B36EF /* matrix.c in Sources */, + 9614C6E416DDC018000B36EF /* matrix_3x3.c in Sources */, + 9614C6E516DDC018000B36EF /* rpng.c in Sources */, + 9614C6E616DDC018000B36EF /* filter.c in Sources */, + 9614C6E716DDC018000B36EF /* pixconv.c in Sources */, + 9614C6E816DDC018000B36EF /* scaler.c in Sources */, + 9614C6E916DDC018000B36EF /* scaler_int.c in Sources */, + 9614C6EA16DDC018000B36EF /* shader_glsl.c in Sources */, + 9614C6EB16DDC018000B36EF /* state_tracker.c in Sources */, + 9614C6EC16DDC018000B36EF /* sinc.c in Sources */, + 9614C6ED16DDC018000B36EF /* input_common.c in Sources */, + 9614C6EE16DDC018000B36EF /* overlay.c in Sources */, + 9614C6EF16DDC018000B36EF /* ioseagl_ctx.c in Sources */, + 9614C6F016DDC018000B36EF /* RetroArch_iOS.m in Sources */, + 9614C6F116DDC018000B36EF /* main.m in Sources */, + 9614C6F216DDC018000B36EF /* resampler.c in Sources */, + 9614C6F316DDC018000B36EF /* hermite.c in Sources */, + 9614C6F416DDC018000B36EF /* coreaudio.c in Sources */, + 9614C6F516DDC018000B36EF /* RAButtonGetter.m in Sources */, + 9614C6F616DDC018000B36EF /* RASettingEnumerationList.m in Sources */, + 9614C6F716DDC018000B36EF /* RASettingsSubList.m in Sources */, + 9614C6F816DDC018000B36EF /* RASettingsList.m in Sources */, + 9614C6F916DDC018000B36EF /* RADirectoryList.m in Sources */, + 9614C6FA16DDC018000B36EF /* RAGameView.m in Sources */, + 9614C6FB16DDC018000B36EF /* RAModuleList.m in Sources */, + 9614C6FC16DDC018000B36EF /* RAModuleInfoList.m in Sources */, + 9614C6FD16DDC018000B36EF /* RADirectoryGrid.m in Sources */, + 9614C6FE16DDC018000B36EF /* browser.m in Sources */, + 9614C6FF16DDC018000B36EF /* RAConfig.m in Sources */, + 9614C70016DDC018000B36EF /* ios_input.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 96AFAE2116C1D4EA009DE44C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -774,6 +977,82 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 9614C71C16DDC018000B36EF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LIBRARY = "libstdc++"; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "RetroArch/RetroArch-Prefix.pch"; + INFOPLIST_FILE = "RetroArch copy-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.1; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)\"", + "\"$(SRCROOT)/RetroArch/BTStack\"", + ); + OTHER_CFLAGS = ( + "-DHAVE_RARCH_MAIN_WRAP", + "-DIOS", + "-DHAVE_OPENGL", + "-DHAVE_FBO", + "-DHAVE_OPENGLES", + "-DHAVE_VID_CONTEXT", + "-DHAVE_OPENGLES2", + "-DHAVE_GLSL", + "-DINLINE=inline", + "-DLSB_FIRST", + "-D__LIBRETRO__", + "-DRARCH_PERFORMANCE_MODE", + "-DPACKAGE_VERSION=\\\"1.0\\\"", + "-DHAVE_COREAUDIO", + "-DHAVE_DYNAMIC", + "-DHAVE_OVERLAY", + "-DHAVE_ZLIB", + ); + PRODUCT_NAME = RetroArch; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + 9614C71D16DDC018000B36EF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LIBRARY = "libstdc++"; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "RetroArch/RetroArch-Prefix.pch"; + INFOPLIST_FILE = "RetroArch copy-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.1; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)\"", + "\"$(SRCROOT)/RetroArch/BTStack\"", + ); + OTHER_CFLAGS = ( + "-DNS_BLOCK_ASSERTIONS=1", + "-DNDEBUG", + "-DHAVE_RARCH_MAIN_WRAP", + "-DIOS", + "-DHAVE_OPENGL", + "-DHAVE_FBO", + "-DHAVE_OPENGLES", + "-DHAVE_VID_CONTEXT", + "-DHAVE_OPENGLES2", + "-DHAVE_GLSL", + "-DINLINE=inline", + "-DLSB_FIRST", + "-D__LIBRETRO__", + "-DRARCH_PERFORMANCE_MODE", + "-DPACKAGE_VERSION=\\\"1.0\\\"", + "-DHAVE_COREAUDIO", + "-DHAVE_DYNAMIC", + "-DHAVE_OVERLAY", + "-DHAVE_ZLIB", + ); + PRODUCT_NAME = RetroArch; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; 96AFAE5216C1D4EA009DE44C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -898,6 +1177,7 @@ "-DHAVE_DYNAMIC", "-DHAVE_OVERLAY", "-DHAVE_ZLIB", + "-DWIIMOTE", ); PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; @@ -937,6 +1217,7 @@ "-DHAVE_DYNAMIC", "-DHAVE_OVERLAY", "-DHAVE_ZLIB", + "-DWIIMOTE", ); PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; @@ -946,6 +1227,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 9614C71B16DDC018000B36EF /* Build configuration list for PBXNativeTarget "RetroArch-nobtstack" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9614C71C16DDC018000B36EF /* Debug */, + 9614C71D16DDC018000B36EF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 96AFAE1F16C1D4EA009DE44C /* Build configuration list for PBXProject "RetroArch" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 005906567e..39b087b972 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -17,8 +17,10 @@ #include "rarch_wrapper.h" #include "general.h" +#ifdef WIIMOTE #include "BTStack/wiimote.h" #import "BTStack/WiiMoteHelper.h" +#endif #define ALMOST_INVISIBLE .021f @@ -364,7 +366,9 @@ - (IBAction)conntectWiimotes:(id)sender { +#ifdef WIIMOTE [WiiMoteHelper startwiimote:_navigator]; +#endif } diff --git a/ios/RetroArch/ios_input.m b/ios/RetroArch/ios_input.m index a83b7cb2cf..723b64c91b 100644 --- a/ios/RetroArch/ios_input.m +++ b/ios/RetroArch/ios_input.m @@ -18,7 +18,10 @@ #include "../../performance.h" #include "../../general.h" #include "../../driver.h" + +#ifdef WIIMOTE #include "BTStack/wiimote.h" +#endif #define MAX_TOUCH 16 #define MAX_KEYS 256 @@ -151,6 +154,7 @@ static int16_t ios_input_state(void *data, const struct retro_keybind **binds, u switch (device) { case RETRO_DEVICE_JOYPAD: +#ifdef WIIMOTE if (myosd_num_of_joys > 0) { struct wiimote_t* wm = &joys[0]; @@ -167,6 +171,7 @@ static int16_t ios_input_state(void *data, const struct retro_keybind **binds, u case RETRO_DEVICE_ID_JOYPAD_RIGHT: return IS_PRESSED(wm, WIIMOTE_BUTTON_RIGHT); } } +#endif return l_ios_joypad_device_state(binds, port, id); case RETRO_DEVICE_ANALOG: From b89208f7fb9dd2da598fe1f3a226ca2049f9ae8d Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 27 Feb 2013 00:45:28 -0500 Subject: [PATCH 082/108] ios: Move wiimote connection widget into settings menu. --- ios/RetroArch/PauseView.xib | 82 ++----------------------- ios/RetroArch/RAModuleInfoList.m | 1 + ios/RetroArch/RAModuleList.m | 2 +- ios/RetroArch/RetroArch-Prefix.pch | 2 +- ios/RetroArch/RetroArch_iOS.h | 4 +- ios/RetroArch/RetroArch_iOS.m | 26 +------- ios/RetroArch/settings/RASettingsList.m | 76 ++++++++++++++++++++--- ios/RetroArch/views.h | 1 + 8 files changed, 82 insertions(+), 112 deletions(-) diff --git a/ios/RetroArch/PauseView.xib b/ios/RetroArch/PauseView.xib index 070ab1125c..238b0695a3 100644 --- a/ios/RetroArch/PauseView.xib +++ b/ios/RetroArch/PauseView.xib @@ -42,7 +42,7 @@ 292 {{160, 237}, {120, 44}} - + _NS:9 NO IBIPadFramework @@ -77,7 +77,6 @@ 292 {{20, 20}, {260, 44}} - _NS:9 NO @@ -100,7 +99,6 @@ 292 {{20, 237}, {120, 44}} - _NS:9 NO @@ -123,7 +121,6 @@ 292 {{20, 186}, {120, 44}} - _NS:9 NO @@ -146,7 +143,6 @@ 292 {{160, 186}, {120, 44}} - _NS:9 NO @@ -169,7 +165,6 @@ 292 {{20, 135}, {260, 44}} - _NS:9 NO @@ -243,7 +238,6 @@ 292 {{20, 71}, {260, 44}} - _NS:9 NO @@ -251,7 +245,7 @@ 0 0 1 - Connect WiiMotes + Settings 1 @@ -264,7 +258,6 @@ {{0, 20}, {300, 300}} - 3 @@ -343,12 +336,12 @@ - conntectWiimotes: + showSettings 7 - 147 + 148 @@ -944,72 +937,9 @@ - 147 - - - - - NSLayoutConstraint - NSObject - - IBProjectSource - ./Classes/NSLayoutConstraint.h - - - - RetroArch_iOS - UIResponder - - id - id - id - id - id - id - id - id - - - - chooseState: - id - - - closeGamePressed: - id - - - closePauseMenu: - id - - - conntectWiimotes: - id - - - loadState: - id - - - resetGame: - id - - - saveState: - id - - - showPauseMenu: - id - - - - IBProjectSource - ./Classes/RetroArch_iOS.h - - - + 148 + 0 IBIPadFramework YES diff --git a/ios/RetroArch/RAModuleInfoList.m b/ios/RetroArch/RAModuleInfoList.m index c555f4b77f..3419b8f5e7 100644 --- a/ios/RetroArch/RAModuleInfoList.m +++ b/ios/RetroArch/RAModuleInfoList.m @@ -19,6 +19,7 @@ RAModuleInfo* new = [RAModuleInfo new]; new.path = thePath; + new.configPath = [NSString stringWithFormat:@"%@/%@.cfg", [RetroArch_iOS get].system_directory, [[thePath lastPathComponent] stringByDeletingPathExtension]]; new.data = theData; return new; } diff --git a/ios/RetroArch/RAModuleList.m b/ios/RetroArch/RAModuleList.m index 30e633af88..63d265934a 100644 --- a/ios/RetroArch/RAModuleList.m +++ b/ios/RetroArch/RAModuleList.m @@ -59,7 +59,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { RAModuleInfo* info = (RAModuleInfo*)[_modules objectAtIndex:indexPath.row]; - [RetroArch_iOS get].module_path = info.path; + [RetroArch_iOS get].moduleInfo = info; [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListOrGridWithPath:nil] isGame:NO]; } diff --git a/ios/RetroArch/RetroArch-Prefix.pch b/ios/RetroArch/RetroArch-Prefix.pch index a3670b9763..ca2c72fb32 100644 --- a/ios/RetroArch/RetroArch-Prefix.pch +++ b/ios/RetroArch/RetroArch-Prefix.pch @@ -26,6 +26,6 @@ #ifdef __OBJC__ #import #import - #import "RetroArch_iOS.h" #import "views.h" + #import "RetroArch_iOS.h" #endif diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index c81b2abf7c..233cb78500 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -25,11 +25,9 @@ - (void)pushViewController:(UIViewController*)theView isGame:(BOOL)game; - (UIViewController*)popViewController; -- (NSString*)configFilePath; +@property (strong, nonatomic) RAModuleInfo* moduleInfo; @property (strong, nonatomic) NSString* system_directory; - -@property (strong, nonatomic) NSString* module_path; @property (strong, nonatomic) UIImage* file_icon; @property (strong, nonatomic) UIImage* folder_icon; @property (strong, nonatomic) UIBarButtonItem* settings_button; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 39b087b972..5730a38ef7 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -17,11 +17,6 @@ #include "rarch_wrapper.h" #include "general.h" -#ifdef WIIMOTE -#include "BTStack/wiimote.h" -#import "BTStack/WiiMoteHelper.h" -#endif - #define ALMOST_INVISIBLE .021f @interface RANavigator : UINavigationController @@ -94,14 +89,6 @@ return (RetroArch_iOS*)[[UIApplication sharedApplication] delegate]; } -- (NSString*)configFilePath -{ - if (self.module_path) - return [NSString stringWithFormat:@"%@/%@.cfg", self.system_directory, [[self.module_path lastPathComponent] stringByDeletingPathExtension]]; - - return nil; -} - - (void)applicationDidFinishLaunching:(UIApplication *)application { // TODO: Relocate this! @@ -213,8 +200,8 @@ [RASettingsList refreshConfigFile]; const char* const sd = [[RetroArch_iOS get].system_directory UTF8String]; - const char* const cf =[[RetroArch_iOS get].configFilePath UTF8String]; - const char* const libretro = [[RetroArch_iOS get].module_path UTF8String]; + const char* const cf =[[RetroArch_iOS get].moduleInfo.configPath UTF8String]; + const char* const libretro = [[RetroArch_iOS get].moduleInfo.path UTF8String]; struct rarch_main_wrap main_wrapper = {[path UTF8String], sd, sd, cf, libretro}; if (rarch_main_init_wrap(&main_wrapper) == 0) @@ -339,7 +326,7 @@ - (IBAction)closePauseMenu:(id)sender { if (_isPaused) - [UIView animateWithDuration:0.2 + [UIView animateWithDuration:0.2 animations:^ { _pauseView.alpha = 0.0f; @@ -364,13 +351,6 @@ [self pushViewController:[RASettingsList new] isGame:NO]; } -- (IBAction)conntectWiimotes:(id)sender -{ -#ifdef WIIMOTE - [WiiMoteHelper startwiimote:_navigator]; -#endif -} - @end diff --git a/ios/RetroArch/settings/RASettingsList.m b/ios/RetroArch/settings/RASettingsList.m index bd3588c331..8b93ad7164 100644 --- a/ios/RetroArch/settings/RASettingsList.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -16,6 +16,11 @@ #import #import "settings.h" +#ifdef WIIMOTE +#include "BTStack/wiimote.h" +#import "BTStack/WiiMoteHelper.h" +#endif + @implementation RASettingData @end @@ -83,9 +88,14 @@ static RASettingData* subpath_setting(RAConfig* config, NSString* name, NSString } @implementation RASettingsList ++ (void)refreshConfigFile +{ + [[[RASettingsList alloc] init] writeToDisk]; +} + - (id)init { - RAConfig* config = [[RAConfig alloc] initWithPath:[RetroArch_iOS get].configFilePath]; + RAConfig* config = [[RAConfig alloc] initWithPath:[RetroArch_iOS get].moduleInfo.configPath]; NSString* overlay_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/overlays/"]; NSString* shader_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/shaders/"]; @@ -163,19 +173,69 @@ static RASettingData* subpath_setting(RAConfig* config, NSString* name, NSString [self writeToDisk]; } -+ (void)refreshConfigFile -{ - [[[RASettingsList alloc] init] writeToDisk]; -} - - (void)writeToDisk { - RAConfig* config = [[RAConfig alloc] initWithPath:[RetroArch_iOS get].configFilePath]; + RAConfig* config = [[RAConfig alloc] initWithPath:[RetroArch_iOS get].moduleInfo.configPath]; [config putStringNamed:@"system_directory" value:[RetroArch_iOS get].system_directory]; [self writeSettings:nil toConfig:config]; - [config writeToFile:[RetroArch_iOS get].configFilePath]; + [config writeToFile:[RetroArch_iOS get].moduleInfo.configPath]; +} + +// Override tableView methods to add General section at top. +- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.section == 0) + { + if (indexPath.row == 0) + [[RetroArch_iOS get] pushViewController:[[RAModuleInfoList alloc] initWithModuleInfo:[RetroArch_iOS get].moduleInfo] isGame:NO]; +#ifdef WIIMOTE + else if(indexPath.row == 1) + [WiiMoteHelper startwiimote:_navigator]; +#endif + } + else + [super tableView:tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section - 1]]; +} + +- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.section == 0) + { + UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"general"]; + cell = cell ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"general"]; + + cell.textLabel.text = (indexPath.row == 0) ? @"Module Info" : @"Connect WiiMotes"; + return cell; + } + else + return [super tableView:tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section - 1]]; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView +{ + return [super numberOfSectionsInTableView:tableView] + 1; +} + +- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section +{ + if (section == 0) +#ifdef WIIMOTE + return 2; +#else + return 1; +#endif + + return [super tableView:tableView numberOfRowsInSection:section - 1] ; +} + +- (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section +{ + if (section == 0) + return @"General"; + + return [super tableView:tableView titleForHeaderInSection:section - 1]; } @end diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index 3b6db9cbec..119213864f 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -23,6 +23,7 @@ @interface RAModuleInfo : NSObject @property (strong) NSString* path; +@property (strong) NSString* configPath; @property (strong) RAConfig* data; + (RAModuleInfo*)moduleWithPath:(NSString*)thePath data:(RAConfig*)theData; From bd088a333259d2a4031b174a2a0667eae2872d17 Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 27 Feb 2013 01:23:49 -0500 Subject: [PATCH 083/108] ios: Move core selection to after game selection. Click the disclosure button to access core settings. (A method to allow core suggestions will be added later) --- ios/RetroArch/RADirectoryGrid.m | 3 +-- ios/RetroArch/RADirectoryList.m | 3 +-- ios/RetroArch/RAModuleList.m | 17 ++++++++--------- ios/RetroArch/RetroArch_iOS.h | 4 +++- ios/RetroArch/RetroArch_iOS.m | 23 ++++++++++++++--------- ios/RetroArch/settings/RASettingsList.m | 9 +-------- ios/RetroArch/views.h | 1 + 7 files changed, 29 insertions(+), 31 deletions(-) diff --git a/ios/RetroArch/RADirectoryGrid.m b/ios/RetroArch/RADirectoryGrid.m index b97ec9ea0c..0e0e87f4cc 100644 --- a/ios/RetroArch/RADirectoryGrid.m +++ b/ios/RetroArch/RADirectoryGrid.m @@ -29,7 +29,6 @@ _config = config; _list = ra_ios_list_directory(_path); - self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; [self setTitle: [_path lastPathComponent]]; // Init collection view @@ -61,7 +60,7 @@ if(path.isDirectory) [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListOrGridWithPath:path.path] isGame:NO]; else - [[RetroArch_iOS get] runGame:path.path]; + [[RetroArch_iOS get] pushViewController:[[RAModuleList alloc] initWithGame:path.path] isGame:NO]; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath diff --git a/ios/RetroArch/RADirectoryList.m b/ios/RetroArch/RADirectoryList.m index f7f2f97b1e..3b2376902c 100644 --- a/ios/RetroArch/RADirectoryList.m +++ b/ios/RetroArch/RADirectoryList.m @@ -45,7 +45,6 @@ _config = config; _list = ra_ios_list_directory(_path); - self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button; [self setTitle: [_path lastPathComponent]]; return self; @@ -58,7 +57,7 @@ if(path.isDirectory) [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListOrGridWithPath:path.path] isGame:NO]; else - [[RetroArch_iOS get] runGame:path.path]; + [[RetroArch_iOS get] pushViewController:[[RAModuleList alloc] initWithGame:path.path] isGame:NO]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section diff --git a/ios/RetroArch/RAModuleList.m b/ios/RetroArch/RAModuleList.m index 63d265934a..e54ae1010f 100644 --- a/ios/RetroArch/RAModuleList.m +++ b/ios/RetroArch/RAModuleList.m @@ -18,11 +18,13 @@ @implementation RAModuleList { NSMutableArray* _modules; + NSString* _game; } -- (id)init +- (id)initWithGame:(NSString*)path { - self = [super initWithStyle:UITableViewStylePlain]; + self = [super initWithStyle:UITableViewStyleGrouped]; + _game = path; // Get the contents of the modules directory of the bundle. NSString* module_dir = [NSString stringWithFormat:@"%@/modules", [[NSBundle mainBundle] bundlePath]]; @@ -58,16 +60,14 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - RAModuleInfo* info = (RAModuleInfo*)[_modules objectAtIndex:indexPath.row]; - [RetroArch_iOS get].moduleInfo = info; - - [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListOrGridWithPath:nil] isGame:NO]; + [RetroArch_iOS get].moduleInfo = (RAModuleInfo*)[_modules objectAtIndex:indexPath.row];; + [[RetroArch_iOS get] runGame:_game]; } - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath { - RAModuleInfo* info = (RAModuleInfo*)[_modules objectAtIndex:indexPath.row]; - [[RetroArch_iOS get] pushViewController:[[RAModuleInfoList alloc] initWithModuleInfo:info] isGame:NO]; + [RetroArch_iOS get].moduleInfo = (RAModuleInfo*)[_modules objectAtIndex:indexPath.row]; + [[RetroArch_iOS get] showSettings]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section @@ -84,7 +84,6 @@ cell.textLabel.text = [[info.path lastPathComponent] stringByDeletingPathExtension]; cell.accessoryType = (info.data) ? UITableViewCellAccessoryDetailDisclosureButton : UITableViewCellAccessoryNone; - return cell; } diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index 233cb78500..1cc9b380c0 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -25,11 +25,13 @@ - (void)pushViewController:(UIViewController*)theView isGame:(BOOL)game; - (UIViewController*)popViewController; +- (IBAction)showSettings; +- (IBAction)showWiiRemoteConfig; + @property (strong, nonatomic) RAModuleInfo* moduleInfo; @property (strong, nonatomic) NSString* system_directory; @property (strong, nonatomic) UIImage* file_icon; @property (strong, nonatomic) UIImage* folder_icon; -@property (strong, nonatomic) UIBarButtonItem* settings_button; @end diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 5730a38ef7..7d65312d86 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -16,6 +16,13 @@ #include #include "rarch_wrapper.h" #include "general.h" +#import "browser.h" + +#ifdef WIIMOTE +#include "BTStack/wiimote.h" +#import "BTStack/WiiMoteHelper.h" +#endif + #define ALMOST_INVISIBLE .021f @@ -99,14 +106,6 @@ self.file_icon = [UIImage imageNamed:@"ic_file"]; self.folder_icon = [UIImage imageNamed:@"ic_dir"]; - // Load buttons - self.settings_button = [[UIBarButtonItem alloc] - initWithTitle:@"Module Settings" - style:UIBarButtonItemStyleBordered - target:nil action:nil]; - self.settings_button.target = self; - self.settings_button.action = @selector(showSettings); - // Load pause menu UINib* xib = [UINib nibWithNibName:@"PauseView" bundle:nil]; _pauseView = [[xib instantiateWithOwner:self options:nil] lastObject]; @@ -119,7 +118,7 @@ // Setup window _navigator = [[RANavigator alloc] initWithAppDelegate:self]; - [_navigator pushViewController: [RAModuleList new] animated:YES]; + [_navigator pushViewController: [RADirectoryList directoryListOrGridWithPath:nil] animated:YES]; _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; _window.rootViewController = _navigator; @@ -351,6 +350,12 @@ [self pushViewController:[RASettingsList new] isGame:NO]; } +- (IBAction)showWiiRemoteConfig +{ +#ifdef WIIMOTE + [WiiMoteHelper startwiimote:_navigator]; +#endif +} @end diff --git a/ios/RetroArch/settings/RASettingsList.m b/ios/RetroArch/settings/RASettingsList.m index 8b93ad7164..282f2cba98 100644 --- a/ios/RetroArch/settings/RASettingsList.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -16,11 +16,6 @@ #import #import "settings.h" -#ifdef WIIMOTE -#include "BTStack/wiimote.h" -#import "BTStack/WiiMoteHelper.h" -#endif - @implementation RASettingData @end @@ -190,10 +185,8 @@ static RASettingData* subpath_setting(RAConfig* config, NSString* name, NSString { if (indexPath.row == 0) [[RetroArch_iOS get] pushViewController:[[RAModuleInfoList alloc] initWithModuleInfo:[RetroArch_iOS get].moduleInfo] isGame:NO]; -#ifdef WIIMOTE else if(indexPath.row == 1) - [WiiMoteHelper startwiimote:_navigator]; -#endif + [[RetroArch_iOS get] showWiiRemoteConfig]; } else [super tableView:tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section - 1]]; diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index 119213864f..19b4cfb0ed 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -34,6 +34,7 @@ @end @interface RAModuleList : UITableViewController +- (id)initWithGame:(NSString*)path; @end @interface RASettingsSubList : UITableViewController From f73511baa0c8798e45c1f6bdf1b4e649274f72a8 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 28 Feb 2013 18:38:49 -0500 Subject: [PATCH 084/108] ios: Update WiiMote code using newer features from BTstack. Probably some bugs, so I recommend sticking with the nobtstack builds for now. --- ios/RetroArch.xcodeproj/project.pbxproj | 20 +- ios/RetroArch/BTStack/BTDevice.h | 25 +- ios/RetroArch/BTStack/BTDevice.m | 53 +- ...ntroller.h => BTDiscoveryViewController.h} | 65 +- .../BTStack/BTDiscoveryViewController.m | 351 +++++++++++ .../BTStack/BTInquiryViewController.m | 592 ------------------ ios/RetroArch/BTStack/BTstackManager.h | 188 ++++++ ios/RetroArch/BTStack/BTstackManager.m | 590 +++++++++++++++++ ios/RetroArch/BTStack/WiiMoteHelper.h | 17 +- ios/RetroArch/BTStack/WiiMoteHelper.m | 588 +++++++---------- ios/RetroArch/BTStack/btstack/btstack.h | 5 +- ios/RetroArch/BTStack/btstack/hci_cmds.h | 151 ++++- ios/RetroArch/BTStack/btstack/linked_list.h | 3 +- ios/RetroArch/BTStack/btstack/run_loop.h | 56 +- ios/RetroArch/BTStack/btstack/sdp_util.h | 37 +- ios/RetroArch/BTStack/btstack/utils.h | 28 +- ios/RetroArch/BTStack/wiimote.c | 202 +----- ios/RetroArch/BTStack/wiimote.h | 2 - ios/RetroArch/RetroArch_iOS.m | 2 +- ios/RetroArch/ios_input.m | 8 +- 20 files changed, 1695 insertions(+), 1288 deletions(-) rename ios/RetroArch/BTStack/{BTInquiryViewController.h => BTDiscoveryViewController.h} (55%) create mode 100644 ios/RetroArch/BTStack/BTDiscoveryViewController.m delete mode 100644 ios/RetroArch/BTStack/BTInquiryViewController.m create mode 100644 ios/RetroArch/BTStack/BTstackManager.h create mode 100644 ios/RetroArch/BTStack/BTstackManager.m diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index ed8e0023e8..1b23d66ec3 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -8,10 +8,11 @@ /* Begin PBXBuildFile section */ 96096DD816D1ABAF00BF4499 /* RAModuleInfoList.m in Sources */ = {isa = PBXBuildFile; fileRef = 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */; }; + 960DB2C416E0193D00F977E3 /* BTstackManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 960DB2C216E0193D00F977E3 /* BTstackManager.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 960DB2C716E0197600F977E3 /* BTDiscoveryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 960DB2C616E0197600F977E3 /* BTDiscoveryViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 9614C6BB16DD7C00000B36EF /* BTDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6AE16DD7C00000B36EF /* BTDevice.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 9614C6BC16DD7C00000B36EF /* BTInquiryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6B016DD7C00000B36EF /* BTInquiryViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 9614C6BD16DD7C00000B36EF /* libBTstack.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 9614C6B816DD7C00000B36EF /* libBTstack.dylib */; }; - 9614C6BE16DD7C00000B36EF /* WiiMoteHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6BA16DD7C00000B36EF /* WiiMoteHelper.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 9614C6BE16DD7C00000B36EF /* WiiMoteHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6BA16DD7C00000B36EF /* WiiMoteHelper.m */; }; 9614C6C116DD7D54000B36EF /* wiimote.c in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6BF16DD7D54000B36EF /* wiimote.c */; }; 9614C6C416DDC018000B36EF /* autosave.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAE9D16C1D9A9009DE44C /* autosave.c */; }; 9614C6C516DDC018000B36EF /* cheats.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEA016C1D9A9009DE44C /* cheats.c */; }; @@ -176,10 +177,12 @@ /* Begin PBXFileReference section */ 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAModuleInfoList.m; sourceTree = ""; }; + 960DB2C216E0193D00F977E3 /* BTstackManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTstackManager.m; sourceTree = ""; }; + 960DB2C316E0193D00F977E3 /* BTstackManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTstackManager.h; sourceTree = ""; }; + 960DB2C516E0197500F977E3 /* BTDiscoveryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTDiscoveryViewController.h; sourceTree = ""; }; + 960DB2C616E0197600F977E3 /* BTDiscoveryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTDiscoveryViewController.m; sourceTree = ""; }; 9614C6AD16DD7C00000B36EF /* BTDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTDevice.h; sourceTree = ""; }; 9614C6AE16DD7C00000B36EF /* BTDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTDevice.m; sourceTree = ""; }; - 9614C6AF16DD7C00000B36EF /* BTInquiryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTInquiryViewController.h; sourceTree = ""; }; - 9614C6B016DD7C00000B36EF /* BTInquiryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTInquiryViewController.m; sourceTree = ""; }; 9614C6B216DD7C00000B36EF /* btstack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = btstack.h; sourceTree = ""; }; 9614C6B316DD7C00000B36EF /* hci_cmds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hci_cmds.h; sourceTree = ""; }; 9614C6B416DD7C00000B36EF /* linked_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linked_list.h; sourceTree = ""; }; @@ -382,8 +385,10 @@ 9614C6B116DD7C00000B36EF /* btstack */, 9614C6AD16DD7C00000B36EF /* BTDevice.h */, 9614C6AE16DD7C00000B36EF /* BTDevice.m */, - 9614C6AF16DD7C00000B36EF /* BTInquiryViewController.h */, - 9614C6B016DD7C00000B36EF /* BTInquiryViewController.m */, + 960DB2C516E0197500F977E3 /* BTDiscoveryViewController.h */, + 960DB2C616E0197600F977E3 /* BTDiscoveryViewController.m */, + 960DB2C216E0193D00F977E3 /* BTstackManager.m */, + 960DB2C316E0193D00F977E3 /* BTstackManager.h */, 9614C6B816DD7C00000B36EF /* libBTstack.dylib */, 9614C6B916DD7C00000B36EF /* WiiMoteHelper.h */, 9614C6BA16DD7C00000B36EF /* WiiMoteHelper.m */, @@ -957,9 +962,10 @@ 96C19C3016D7045700FE8D5A /* RAConfig.m in Sources */, 965AE29E16D9BF94001D7667 /* ios_input.m in Sources */, 9614C6BB16DD7C00000B36EF /* BTDevice.m in Sources */, - 9614C6BC16DD7C00000B36EF /* BTInquiryViewController.m in Sources */, 9614C6BE16DD7C00000B36EF /* WiiMoteHelper.m in Sources */, 9614C6C116DD7D54000B36EF /* wiimote.c in Sources */, + 960DB2C416E0193D00F977E3 /* BTstackManager.m in Sources */, + 960DB2C716E0197600F977E3 /* BTDiscoveryViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/BTStack/BTDevice.h b/ios/RetroArch/BTStack/BTDevice.h index 43d018cce5..aa404ef6be 100644 --- a/ios/RetroArch/BTStack/BTDevice.h +++ b/ios/RetroArch/BTStack/BTDevice.h @@ -31,7 +31,6 @@ // // BTDevice.h -// BT-Keyboard // // Created by Matthias Ringwald on 3/30/09. // @@ -59,25 +58,35 @@ typedef enum { } BluetoothConnectionState; @interface BTDevice : NSObject { - bd_addr_t address; + + bd_addr_t _address; + NSString * name; + uint32_t classOfDevice; + uint8_t pageScanRepetitionMode; uint16_t clockOffset; - uint32_t classOfDevice; - BluetoothConnectionState connectionState; + + uint8_t rssi; + + // deprecated + BluetoothConnectionState connectionState; } -- (void) setAddress:(bd_addr_t *)addr; -- (bd_addr_t *) address; +- (void) setAddress:(bd_addr_t*)addr; +- (BOOL) setAddressFromString:(NSString *) addressString; +- (bd_addr_t*) address; - (NSString *) toString; -+ (NSString *) stringForAddress:(bd_addr_t *) address; - +- (NSString *) addressString; ++ (NSString *) stringForAddress:(bd_addr_t*) address; ++ (BOOL) address:(bd_addr_t *) address fromString:(NSString *) addressString; @property (readonly) BluetoothDeviceType deviceType; @property (readonly) NSString * nameOrAddress; @property (nonatomic, copy) NSString * name; @property (nonatomic, assign) uint32_t classOfDevice; @property (nonatomic, assign) uint16_t clockOffset; @property (nonatomic, assign) uint8_t pageScanRepetitionMode; +@property (nonatomic, assign) uint8_t rssi; @property (nonatomic, assign) BluetoothConnectionState connectionState; @end diff --git a/ios/RetroArch/BTStack/BTDevice.m b/ios/RetroArch/BTStack/BTDevice.m index 57fbc6df17..dbb14ebbb6 100644 --- a/ios/RetroArch/BTStack/BTDevice.m +++ b/ios/RetroArch/BTStack/BTDevice.m @@ -44,32 +44,67 @@ @synthesize connectionState; @synthesize pageScanRepetitionMode; @synthesize clockOffset; +@synthesize rssi; - (BTDevice *)init { name = NULL; - bzero(&address, 6); + memset(&_address, 0, 6); classOfDevice = kCODInvalid; connectionState = kBluetoothConnectionNotConnected; return self; } -- (void) setAddress:(bd_addr_t *)newAddr{ - BD_ADDR_COPY( &address, newAddr); +- (void) setAddress:(bd_addr_t*)newAddr{ + BD_ADDR_COPY( &_address, newAddr); } -- (bd_addr_t *) address{ - return &address; +- (BOOL) setAddressFromString:(NSString *) addressString{ + return [BTDevice address:&_address fromString:addressString]; } -+ (NSString *) stringForAddress:(bd_addr_t *) address { - uint8_t * addr = (uint8_t*) address; +- (bd_addr_t*) address{ + return &_address; +} + ++ (NSString *) stringForAddress:(bd_addr_t*) address { + uint8_t *addr = (uint8_t*) *address; return [NSString stringWithFormat:@"%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]]; } ++ (BOOL) address:(bd_addr_t *)address fromString:(NSString *) addressString{ + // support both : and - or NOTHING as separator + addressString = [addressString stringByReplacingOccurrencesOfString:@":" withString:@""]; + addressString = [addressString stringByReplacingOccurrencesOfString:@"-" withString:@""]; + if ([addressString length] != 12) return NO; + + unsigned int bd_addr_buffer[BD_ADDR_LEN]; //for sscanf, integer needed + // reset result buffer + int i; + for (i = 0; i < BD_ADDR_LEN; i++) { + bd_addr_buffer[i] = 0; + } + + // parse + int result = sscanf([addressString UTF8String], "%2x%2x%2x%2x%2x%2x", &bd_addr_buffer[0], &bd_addr_buffer[1], &bd_addr_buffer[2], + &bd_addr_buffer[3], &bd_addr_buffer[4], &bd_addr_buffer[5]); + // store + if (result == 6){ + for (i = 0; i < BD_ADDR_LEN; i++) { + (*address)[i] = (uint8_t) bd_addr_buffer[i]; + } + return YES; + } + return NO; +} + - (NSString *) nameOrAddress{ if (name) return name; - return [BTDevice stringForAddress:&address]; + return [self addressString]; +} + +- (NSString *) addressString{ + return [BTDevice stringForAddress:&_address]; } - (BluetoothDeviceType) deviceType{ @@ -83,7 +118,7 @@ } } - (NSString *) toString{ - return [NSString stringWithFormat:@"Device addr %@ name %@ COD %x", [BTDevice stringForAddress:&address], name, classOfDevice]; + return [NSString stringWithFormat:@"Device addr %@ name %@ COD %x", [BTDevice stringForAddress:&_address], name, classOfDevice]; } - (void)dealloc { diff --git a/ios/RetroArch/BTStack/BTInquiryViewController.h b/ios/RetroArch/BTStack/BTDiscoveryViewController.h similarity index 55% rename from ios/RetroArch/BTStack/BTInquiryViewController.h rename to ios/RetroArch/BTStack/BTDiscoveryViewController.h index b8638e142b..ab030db32a 100644 --- a/ios/RetroArch/BTStack/BTInquiryViewController.h +++ b/ios/RetroArch/BTStack/BTDiscoveryViewController.h @@ -28,20 +28,11 @@ * SUCH DAMAGE. * */ - -// -// BTInquiryViewController.h -// -// Created by Matthias Ringwald on 10/8/09. -// - #import +#import "BTstackManager.h" -#include "btstack/hci_cmds.h" // for HCI_STATE -#include "btstack/utils.h" - -@class BTDevice; -@protocol BTInquiryDelegate; +@class BTstackManager; +@protocol BTDiscoveryDelegate; typedef enum { kInquiryInactive, @@ -49,46 +40,28 @@ typedef enum { kInquiryRemoteName } InquiryState; -@interface BTInquiryViewController : UITableViewController +@interface BTDiscoveryViewController : UITableViewController { - NSMutableArray *devices; - HCI_STATE bluetoothState; - InquiryState inquiryState; + BTstackManager *bt; + NSObject * _delegate; UIActivityIndicatorView *deviceActivity; UIActivityIndicatorView *bluetoothActivity; UIFont * deviceNameFont; UIFont * macAddressFont; - id delegate; - bool allowSelection; - bool showIcons; - - // hacks - bool stopRemoteNameGathering; - bool restartInquiry; - BTDevice *remoteNameDevice; // device for which remote name request is pending - BTDevice *remoteDevice; // device for which connection is pending - BTDevice *connectedDevice; // device to which we're connected - bool notifyDelegateOnInquiryStopped; - + InquiryState inquiryState; + int remoteNameIndex; + BOOL showIcons; + int connectingIndex; + NSString *customActivityText; } - -- (void) startInquiry; -- (void) stopInquiry; - -- (void) showConnecting:(BTDevice *) device; -- (void) showConnected:(BTDevice *) device; - -- (void) removeDeviceForAddress:(bd_addr_t *)addr; - -@property (nonatomic, assign) bool allowSelection; -@property (nonatomic, assign) bool showIcons; -@property (nonatomic, retain) NSMutableArray *devices; -@property (nonatomic, retain) id delegate; +-(void) markConnecting:(int)index; // use -1 for no connection active +@property (nonatomic, assign) NSObject * delegate; +@property (nonatomic, assign) BOOL showIcons; +@property (nonatomic, retain) NSString *customActivityText; @end -@protocol BTInquiryDelegate -+ (void) deviceChoosen:(BTInquiryViewController *) inqView device:(BTDevice*) device; -+ (void) deviceDetected:(BTInquiryViewController *) inqView device:(BTDevice*) device; -+ (void) disconnectDevice:(BTInquiryViewController *) inqView device:(BTDevice*) device; -+ (void) inquiryStopped; +@protocol BTDiscoveryDelegate +@optional +-(BOOL) discoveryView:(BTDiscoveryViewController*)discoveryView willSelectDeviceAtIndex:(int)deviceIndex; // returns NO to ignore selection +-(void) statusCellSelectedDiscoveryView:(BTDiscoveryViewController*)discoveryView; @end diff --git a/ios/RetroArch/BTStack/BTDiscoveryViewController.m b/ios/RetroArch/BTStack/BTDiscoveryViewController.m new file mode 100644 index 0000000000..e79986c010 --- /dev/null +++ b/ios/RetroArch/BTStack/BTDiscoveryViewController.m @@ -0,0 +1,351 @@ +/* + * Copyright (C) 2009 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#import "BTDiscoveryViewController.h" +#import "BTDevice.h" + +// fix compare for 3.0 +#ifndef __IPHONE_3_0 +#define __IPHONE_3_0 30000 +#endif + +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_0 +// SDK 30 defines missing in SDK 20 +@interface UITableViewCell (NewIn30) +- (id)initWithStyle:(int)style reuseIdentifier:(NSString *)reuseIdentifier; +@end +#endif +@interface UIDevice (privateAPI) +-(BOOL) isWildcat; +@end + +@implementation BTDiscoveryViewController +@synthesize showIcons; +@synthesize delegate = _delegate; +@synthesize customActivityText; + +- (id) init { + self = [super initWithStyle:UITableViewStyleGrouped]; + macAddressFont = [UIFont fontWithName:@"Courier New" size:[UIFont labelFontSize]]; + deviceNameFont = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]]; + inquiryState = kInquiryInactive; + connectingIndex = -1; + + deviceActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + [deviceActivity startAnimating]; + bluetoothActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + [bluetoothActivity startAnimating]; + + bt = [BTstackManager sharedInstance]; + _delegate = nil; + return self; +} + +-(void) reload{ + [[self tableView] reloadData]; +} + +/* +- (id)initWithStyle:(UITableViewStyle)style { + // Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad. + if (self = [super initWithStyle:style]) { + } + return self; +} +*/ + +/* +- (void)viewDidLoad { + [super viewDidLoad]; + + // Uncomment the following line to display an Edit button in the navigation bar for this view controller. + // self.navigationItem.rightBarButtonItem = self.editButtonItem; +} +*/ + +/* +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; +} +*/ +/* +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; +} +*/ +/* +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; +} +*/ +/* +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; +} +*/ + +/* +// Override to allow orientations other than the default portrait orientation. +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Return YES for supported orientations + return (interfaceOrientation == UIInterfaceOrientationPortrait); +} + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + */ + + +// BTstackManagerListenerDelegate +-(void) activatedBTstackManager:(BTstackManager*) manager{ + [self reload]; +} +-(void) btstackManager:(BTstackManager*)manager activationFailed:(BTstackError)error { + [self reload]; +} +-(void) discoveryInquiryBTstackManager:(BTstackManager*) manager { + inquiryState = kInquiryActive; + [self reload]; +} +-(void) btstackManager:(BTstackManager*)manager discoveryQueryRemoteName:(int)deviceIndex { + inquiryState = kInquiryRemoteName; + remoteNameIndex = deviceIndex; + [self reload]; +} +-(void) discoveryStoppedBTstackManager:(BTstackManager*) manager { + inquiryState = kInquiryInactive; + [self reload]; +} +-(void) btstackManager:(BTstackManager*)manager deviceInfo:(BTDevice*)device { + [self reload]; +} + +-(void) markConnecting:(int)index; { + connectingIndex = index; + [self reload]; +} + +-(void) setCustomActivityText:(NSString*) text{ + [text retain]; + [customActivityText release]; + customActivityText = text; + [self reload]; +} + +// MARK: Table view methods + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ + return @"Devices"; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +// Customize the number of rows in the table view. +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return 1 + [bt numberOfDevicesFound]; +} + + +// Customize the appearance of table view cells. +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + + static NSString *CellIdentifier = @"Cell"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) { +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_3_0 + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; +#else + cell = [[[UITableViewCell alloc] initWithFrame:CGRectNull reuseIdentifier:(NSString *)CellIdentifier] autorelease]; +#endif + } + + // Set up the cell... + NSString *theLabel = nil; + UIImage *theImage = nil; + UIFont *theFont = nil; + + int idx = [indexPath indexAtPosition:1]; + if (idx >= [bt numberOfDevicesFound]) { + if (customActivityText) { + theLabel = customActivityText; + cell.accessoryView = bluetoothActivity; + } else if ([bt isActivating]){ + theLabel = @"Activating BTstack..."; + cell.accessoryView = bluetoothActivity; + } else if (![bt isActive]){ + theLabel = @"Bluetooth not accessible!"; + cell.accessoryView = nil; + } else { + +#if 0 + if (connectedDevice) { + theLabel = @"Disconnect"; + cell.accessoryView = nil; + } +#endif + + if (connectingIndex >= 0) { + theLabel = @"Connecting..."; + cell.accessoryView = bluetoothActivity; + } else { + switch (inquiryState){ + case kInquiryInactive: + if ([bt numberOfDevicesFound] > 0){ + theLabel = @"Find more devices..."; + } else { + theLabel = @"Find devices..."; + } + cell.accessoryView = nil; + break; + case kInquiryActive: + theLabel = @"Searching..."; + cell.accessoryView = bluetoothActivity; + break; + case kInquiryRemoteName: + theLabel = @"Query device names..."; + cell.accessoryView = bluetoothActivity; + break; + } + } + } + } else { + + BTDevice *dev = [bt deviceAtIndex:idx]; + + // pick font + theLabel = [dev nameOrAddress]; + if ([dev name]){ + theFont = deviceNameFont; + } else { + theFont = macAddressFont; + } + + // pick an icon for the devices + if (showIcons) { + NSString *imageName = @"bluetooth.png"; + // check major device class + switch (([dev classOfDevice] & 0x1f00) >> 8) { + case 0x01: + imageName = @"computer.png"; + break; + case 0x02: + imageName = @"smartphone.png"; + break; + case 0x05: + switch ([dev classOfDevice] & 0xff){ + case 0x40: + imageName = @"keyboard.png"; + break; + case 0x80: + imageName = @"mouse.png"; + break; + case 0xc0: + imageName = @"keyboard.png"; + break; + default: + imageName = @"HID.png"; + break; + } + } + +#ifdef LASER_KB + if ([dev name] && [[dev name] isEqualToString:@"CL800BT"]){ + imageName = @"keyboard.png"; + } + + if ([dev name] && [[dev name] isEqualToString:@"CL850"]){ + imageName = @"keyboard.png"; + } + + // Celluon CL800BT, CL850 have 00-0b-24-aa-bb-cc, COD 0x400210 + uint8_t *addr = (uint8_t *) [dev address]; + if (addr[0] == 0x00 && addr[1] == 0x0b && addr[2] == 0x24){ + imageName = @"keyboard.png"; + } +#endif + theImage = [UIImage imageNamed:imageName]; + } + + // set accessory view + if (idx == connectingIndex){ + cell.accessoryView = deviceActivity; + } else { + cell.accessoryView = nil; + } + } +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_3_0 + if (theLabel) cell.textLabel.text = theLabel; + if (theFont) cell.textLabel.font = theFont; + if (theImage) cell.imageView.image = theImage; +#else + if (theLabel) cell.text = theLabel; + if (theFont) cell.font = theFont; + if (theImage) cell.image = theImage; +#endif + return cell; +} + + +- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { + if (!_delegate) return nil; + int index = [indexPath indexAtPosition:1]; + if (index >= [bt numberOfDevicesFound]){ + if ([_delegate respondsToSelector:@selector(statusCellSelectedDiscoveryView:)]){ + [_delegate statusCellSelectedDiscoveryView:self]; + return nil; + } + } + if ([_delegate respondsToSelector:@selector(discoveryView:willSelectDeviceAtIndex:)] && [_delegate discoveryView:self willSelectDeviceAtIndex:index]){ + return indexPath; + } + return nil; +} + +// Override to allow orientations other than the default portrait orientation. +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + UIDevice * uiDevice = [UIDevice currentDevice]; + return [uiDevice respondsToSelector:@selector(isWildcat)] && [uiDevice isWildcat]; +} + +- (void)dealloc { + [super dealloc]; +} + + +@end + diff --git a/ios/RetroArch/BTStack/BTInquiryViewController.m b/ios/RetroArch/BTStack/BTInquiryViewController.m deleted file mode 100644 index d274a6a7d9..0000000000 --- a/ios/RetroArch/BTStack/BTInquiryViewController.m +++ /dev/null @@ -1,592 +0,0 @@ -/* - * Copyright (C) 2009 by Matthias Ringwald - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS - * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -// -// BTInquiryViewController.m -// -// Created by Matthias Ringwald on 10/8/09. -// - -#import "BTInquiryViewController.h" -#import "BTDevice.h" -#import - -#include "btstack/btstack.h" -//#include "wiimote.h" - -#define INQUIRY_INTERVAL 3 - -unsigned myosd_num_of_joys = 0; - -static BTInquiryViewController *inqView; -static btstack_packet_handler_t clientHandler; -static uint8_t remoteNameIndex; - -@interface BTInquiryViewController (Private) -- (void) handlePacket:(uint8_t) packet_type channel:(uint16_t) channel packet:(uint8_t*) packet size:(uint16_t) size; -- (BTDevice *) getDeviceForAddress:(bd_addr_t *)addr; -- (void) getNextRemoteName; -- (void) startInquiry; -@end - -static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ - if (inqView) { - [inqView handlePacket:packet_type channel:channel packet:packet size:size]; - } -} - -@implementation BTInquiryViewController - - -@synthesize devices; -@synthesize delegate; -@synthesize allowSelection; -@synthesize showIcons; - -- (id) init { - self = [super initWithStyle:UITableViewStyleGrouped]; - bluetoothState = HCI_STATE_OFF; - inquiryState = kInquiryInactive; - allowSelection = false; - showIcons = false; - remoteDevice = nil; - restartInquiry = true; - notifyDelegateOnInquiryStopped = false; - - macAddressFont = [UIFont fontWithName:@"Courier New" size:[UIFont labelFontSize]]; - deviceNameFont = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]]; - - deviceActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; - [deviceActivity startAnimating]; - bluetoothActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; - [bluetoothActivity startAnimating]; - - devices = [[NSMutableArray alloc] init]; - inqView = self; - return self; -} - -- (void) myStartInquiry{ - if (inquiryState != kInquiryInactive) { - NSLog(@"Inquiry already active"); - return; - } - NSLog(@"Inquiry started"); - - stopRemoteNameGathering = false; - restartInquiry = true; - - inquiryState = kInquiryActive; - [[self tableView] reloadData]; - - bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0); -} - -- (void) handlePacket:(uint8_t) packet_type channel:(uint16_t) channel packet:(uint8_t*) packet size:(uint16_t) size { - bd_addr_t event_addr; - switch (packet_type) { - - case HCI_EVENT_PACKET: - - switch (packet[0]){ - - case BTSTACK_EVENT_STATE: - { - // bt stack activated - bluetoothState = (HCI_STATE)packet[2]; - [[self tableView] reloadData]; - - // set BT state -/* - if (bluetoothState == HCI_STATE_WORKING) { - [self myStartInquiry]; - } -*/ - break; - } - case BTSTACK_EVENT_POWERON_FAILED: - { - bluetoothState = HCI_STATE_OFF; - [[self tableView] reloadData]; - - UIAlertView* alertView = [[UIAlertView alloc] init]; - alertView.title = @"Bluetooth not accessible!"; - alertView.message = @"Hardware initialization failed!\n" - "Make sure you have turned off Bluetooth in the System Settings."; - NSLog(@"Alert: %@ - %@", alertView.title, alertView.message); - [alertView addButtonWithTitle:@"Dismiss"]; - [alertView show]; - break; - } - case HCI_EVENT_INQUIRY_RESULT: - case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI: - { - int numResponses = packet[2]; - int i; - for (i=0; i adding %@", [dev toString] ); - [devices addObject:dev]; - if (delegate) { - [delegate deviceDetected:self device:dev]; - } - } - - [[inqView tableView] reloadData]; - NSLog(@"bye" ); - break; - } - case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: - { - bt_flip_addr(event_addr, &packet[3]); - BTDevice *dev = [inqView getDeviceForAddress:&event_addr]; - if (!dev) break; - [dev setConnectionState:kBluetoothConnectionNotConnected]; - if (packet[2] == 0) { - [dev setName:[NSString stringWithUTF8String:(const char *) &packet[9]]]; - if (delegate) { - [delegate deviceDetected:self device:dev]; - } - } - [[self tableView] reloadData]; - remoteNameIndex++; - [self getNextRemoteName]; - break; - } - case HCI_EVENT_COMMAND_COMPLETE: - { - if (COMMAND_COMPLETE_EVENT(packet, hci_inquiry_cancel)){ - // inquiry canceled - NSLog(@"Inquiry cancelled successfully"); - inquiryState = kInquiryInactive; - [[self tableView] reloadData]; - if (notifyDelegateOnInquiryStopped){ - notifyDelegateOnInquiryStopped = false; - if (delegate) { - [delegate inquiryStopped]; - } - } - } - if (COMMAND_COMPLETE_EVENT(packet, hci_remote_name_request_cancel)){ - // inquiry canceled - NSLog(@"Remote name request cancelled successfully"); - inquiryState = kInquiryInactive; - [[self tableView] reloadData]; - if (notifyDelegateOnInquiryStopped){ - notifyDelegateOnInquiryStopped = false; - if (delegate) { - [delegate inquiryStopped]; - } - } - } - - break; - } - case HCI_EVENT_INQUIRY_COMPLETE: - { - NSLog(@"Inquiry complete"); - // reset name check - remoteNameIndex = 0; - [self getNextRemoteName]; - break; - } - default: - break; - - // hexdump(packet, size); - //break; - } - - default: - break; - } - // forward to client app - (*clientHandler)(packet_type, channel, packet, size); -} - -- (BTDevice *) getDeviceForAddress:(bd_addr_t *)addr { - uint8_t j; - for (j=0; j<[devices count]; j++){ - BTDevice *dev = [devices objectAtIndex:j]; - if (BD_ADDR_CMP(addr, [dev address]) == 0){ - return dev; - } - } - return nil; -} - - -- (void) removeDeviceForAddress:(bd_addr_t *)addr { - uint8_t j; - for (j=0; j<[devices count]; j++){ - BTDevice *dev = [devices objectAtIndex:j]; - if (BD_ADDR_CMP(addr, [dev address]) == 0){ - NSLog(@"--> removed %@", [dev toString] ); - [devices removeObject:dev]; - [[self tableView] reloadData]; - return; - } - } - -} - -- (void) getNextRemoteName{ - - // stopped? - if (stopRemoteNameGathering) { - inquiryState = kInquiryInactive; - [[self tableView] reloadData]; - - if (notifyDelegateOnInquiryStopped){ - notifyDelegateOnInquiryStopped = false; - if (delegate) { - [delegate inquiryStopped]; - } - } - return; - } - - remoteNameDevice = nil; - - for (remoteNameIndex = 0; remoteNameIndex < [devices count]; remoteNameIndex++){ - BTDevice *dev = [devices objectAtIndex:remoteNameIndex]; - if (![dev name]){ - remoteNameDevice = dev; - break; - } - } - if (remoteNameDevice) { - inquiryState = kInquiryRemoteName; - [remoteNameDevice setConnectionState:kBluetoothConnectionRemoteName]; - bt_send_cmd(&hci_remote_name_request, [remoteNameDevice address], [remoteNameDevice pageScanRepetitionMode], 0, [remoteNameDevice clockOffset] | 0x8000); - } else { - inquiryState = kInquiryInactive; - // inquiry done. - if (restartInquiry) { - [self myStartInquiry]; - } - } - [[self tableView] reloadData]; -} - -- (void) startInquiry { - //static int b = 0; - //if(!b) - //{ - //b=1; - // put into loop - - // @TODO: cannot be called a second time! - clientHandler = bt_register_packet_handler(packet_handler); - - bluetoothState = HCI_STATE_INITIALIZING; - [[self tableView] reloadData]; - - stopRemoteNameGathering = false; - restartInquiry = true; - - bt_send_cmd(&btstack_set_power_mode, HCI_POWER_ON ); - //} -} - -- (void) stopInquiry { - - NSLog(@"stop inquiry called, state %u", inquiryState); - restartInquiry = false; - stopRemoteNameGathering = true; - bool immediateNotify = true; - - switch (inquiryState) { - case kInquiryActive: - // just stop inquiry - immediateNotify = false; - bt_send_cmd(&hci_inquiry_cancel); - break; - case kInquiryInactive: - NSLog(@"stop inquiry called although inquiry inactive?"); - break; - case kInquiryRemoteName: - if (remoteNameDevice) { - // just stop remote name request - immediateNotify = false; - bt_send_cmd(&hci_remote_name_request_cancel, [remoteNameDevice address]); - } - break; - default: - break; - } - if (immediateNotify && delegate){ - [delegate inquiryStopped]; - } else { - notifyDelegateOnInquiryStopped = true; - } -} - -- (void) showConnecting:(BTDevice *) device { - remoteDevice = device; - [[self tableView] reloadData]; -} - -- (void) showConnected:(BTDevice *) device { - connectedDevice = device; - [[self tableView] reloadData]; -} - -/* -- (void)loadView { - - [super loadView]; - -} -*/ -/* -- (void)viewDidLoad { - [super viewDidLoad]; - - // Uncomment the following line to display an Edit button in the navigation bar for this view controller. - //self.navigationItem.rightBarButtonItem = self.editButtonItem; - -} -*/ - -/* -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; -} -*/ -/* -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; -} -*/ -/* -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; -} -*/ -/* -- (void)viewDidDisappear:(BOOL)animated { - [super viewDidDisappear:animated]; -} -*/ - -// Override to allow orientations other than the default portrait orientation. -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - return YES; - //return NO; - //return (interfaceOrientation == UIInterfaceOrientationPortrait); -} - -- (void)didReceiveMemoryWarning { - // Releases the view if it doesn't have a superview. - [super didReceiveMemoryWarning]; - - // Release any cached data, images, etc that aren't in use. -} - -- (void)viewDidUnload { - // Release any retained subviews of the main view. - // e.g. self.myOutlet = nil; -} - -- (void)dealloc { - // unregister self - bt_register_packet_handler(clientHandler); - // done - [super dealloc]; -} - - -#pragma mark Table view methods - -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ - return @"Devices"; -} - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 1; -} - - -// Customize the number of rows in the table view. -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - int rows = 1; // 1 for status line - if (bluetoothState == HCI_STATE_WORKING) { - rows += [devices count]; - } - return rows; -} - - -// Customize the appearance of table view cells. -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - - static NSString *CellIdentifier = @"Cell"; - - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; - if (cell == nil) { - cell = [[[UITableViewCell alloc] initWithStyle:/* UITableViewCellStyleDefault = */(UITableViewCellStyle)0 reuseIdentifier:CellIdentifier] autorelease]; - // cell.selectionStyle = UITableViewCellSelectionStyleNone; - } - - // Set up the cell... - NSString *label = nil; - int idx = [indexPath indexAtPosition:1]; - if (bluetoothState != HCI_STATE_WORKING || idx >= [devices count]) { - if (bluetoothState == HCI_STATE_INITIALIZING){ - label = @"Activating BTstack..."; - cell.accessoryView = bluetoothActivity; - } else if (bluetoothState == HCI_STATE_OFF){ - label = @"Bluetooth not accessible!"; - cell.accessoryView = nil; - } else { - if (connectedDevice) { - label = @"Disconnect"; - cell.accessoryView = nil; - } else if (remoteDevice) { - label = @"Connecting..."; - cell.accessoryView = bluetoothActivity; - } else { - switch (inquiryState){ - case kInquiryInactive: - if (myosd_num_of_joys==4) - { - label = @"Maximun devices connected!"; - } - else if ([devices count] > 0){ - label = @"Press here to find more devices..."; - } else { - label = @"Press here to find first device..."; - } - cell.accessoryView = nil; - break; - case kInquiryActive: - //label = @"Searching..."; - label = @"Press 1 and 2 on the WiiMote to sync"; - cell.accessoryView = bluetoothActivity; - break; - case kInquiryRemoteName: - label = @"Query device names..."; - cell.accessoryView = bluetoothActivity; - break; - } - } - } - } else { - BTDevice *dev = [devices objectAtIndex:idx]; - label = [dev nameOrAddress]; - if ([dev name]){ - cell.font = deviceNameFont; - } else { - cell.font = macAddressFont; - } - // pick an icon for the devices - if (showIcons) { - int major = ([dev classOfDevice] & 0x1f00) >> 8; - if (major == 0x01) { - cell.image = [UIImage imageNamed:@"computer.png"]; - } else if (major == 0x02) { - cell.image = [UIImage imageNamed:@"smartphone.png"]; - } else if ( major == 0x05 && ([dev classOfDevice] & 0xff) == 0x40){ - cell.image = [UIImage imageNamed:@"keyboard.png"]; - } else { - cell.image = [UIImage imageNamed:@"bluetooth.png"]; - } - } - switch ([dev connectionState]) { - case kBluetoothConnectionNotConnected: - case kBluetoothConnectionConnected: - cell.accessoryView = nil; - break; - case kBluetoothConnectionConnecting: - case kBluetoothConnectionRemoteName: - cell.accessoryView = deviceActivity; - break; - } - } - cell.text = label; - return cell; -} - - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - NSLog(@"didSelectRowAtIndexPath %@", indexPath); - // Navigation logic may go here. Create and push another view controller. - // AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil]; - // [self.navigationController pushViewController:anotherViewController]; - // [anotherViewController release]; - - // valid selection? - - - int idx = [indexPath indexAtPosition:1]; - //printf("sleccion %d\n",idx); - if (bluetoothState == HCI_STATE_WORKING) { - if (delegate) { - if (idx < [devices count]){ - [delegate deviceChoosen:self device:[devices objectAtIndex:idx]]; - } else if (idx == [devices count]) { - //printf("seleccionado %d %d\n",idx,connectedDevice); - if (connectedDevice) { - // DISCONNECT button - [delegate disconnectDevice:self device:connectedDevice]; - } else if (myosd_num_of_joys<4){ - // Find more devices - [self myStartInquiry]; - } - } - } - } else { - [tableView deselectRowAtIndexPath:indexPath animated:TRUE]; - } - -} - -- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { - if (allowSelection) { - return indexPath; - } - return nil; -} - -@end - diff --git a/ios/RetroArch/BTStack/BTstackManager.h b/ios/RetroArch/BTStack/BTstackManager.h new file mode 100644 index 0000000000..cb1c4d8545 --- /dev/null +++ b/ios/RetroArch/BTStack/BTstackManager.h @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2009 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#pragma once + +#import +#import +#import "btstack/btstack.h" + +#define PREFS_REMOTE_NAME @"RemoteName" +#define PREFS_LINK_KEY @"LinkKey" +#define BTstackManagerID @"ch.ringwald.btstack" + +@class BTDevice; + +/* + * Information on devices is stored in a system-wide plist + * it is maintained by BTstackManager + * this includes the link keys + */ + +// TODO enumerate BTstackError type +typedef int BTstackError; + +typedef enum { + kDeactivated = 1, + kW4SysBTState, + kW4SysBTDisabled, + kW4Activated, + kActivated, + kW4Deactivated, + kSleeping, +#if 0 + kW4DisoveryStopped, + kW4AuthenticationEnableCommand +#endif +} ManagerState; + +typedef enum { + kInactive = 1, + kW4InquiryMode, + kInquiry, + kRemoteName, + // stopping + kW4InquiryModeBeforeStop, + kW4InquiryStop, + kW4RemoteNameBeforeStop, +} DiscoveryState; + +@protocol BTstackManagerDelegate; +@protocol BTstackManagerListener; + +@interface BTstackManager : NSObject { +@private + NSObject* _delegate; + NSMutableArray *discoveredDevices; + NSMutableSet *listeners; + BOOL connectedToDaemon; + ManagerState state; + DiscoveryState discoveryState; + int discoveryDeviceIndex; +#if 0 + // current connection - kind a ugly + uint8_t connType; // 0 = L2CAP, 1 = RFCOMM + bd_addr_t connAddr; + uint16_t connPSM; + uint16_t connChan; + uint8_t connAuth; +#endif +} + +// shared instance ++(BTstackManager *) sharedInstance; + +// listeners +-(void) addListener:(id)listener; +-(void) removeListener:(id)listener; + +// Activation +-(BTstackError) activate; +-(BTstackError) deactivate; +-(BOOL) isActivating; +-(BOOL) isActive; + +// Discovery +-(BTstackError) startDiscovery; +-(BTstackError) stopDiscovery; +-(int) numberOfDevicesFound; +-(BTDevice*) deviceAtIndex:(int)index; +-(BOOL) isDiscoveryActive; + +// Link Key Management +-(void) dropLinkKeyForAddress:(bd_addr_t*) address; + +// Connections +-(BTstackError) createL2CAPChannelAtAddress:(bd_addr_t*) address withPSM:(uint16_t)psm authenticated:(BOOL)authentication; +-(BTstackError) closeL2CAPChannelWithID:(uint16_t) channelID; +-(BTstackError) sendL2CAPPacketForChannelID:(uint16_t)channelID; + +-(BTstackError) createRFCOMMConnectionAtAddress:(bd_addr_t*) address withChannel:(uint16_t)channel authenticated:(BOOL)authentication; +-(BTstackError) closeRFCOMMConnectionWithID:(uint16_t) connectionID; +-(BTstackError) sendRFCOMMPacketForChannelID:(uint16_t)connectionID; + + +// TODO add l2cap and rfcomm incoming commands +@property (nonatomic, assign) NSObject* delegate; +@property (nonatomic, retain) NSMutableArray *discoveredDevices; +@property (nonatomic, retain) NSMutableSet *listeners; +@end + + +@protocol BTstackManagerDelegate +@optional + +// Activation callbacks +-(BOOL) disableSystemBluetoothBTstackManager:(BTstackManager*) manager; // default: YES + +// Connection events +-(NSString*) btstackManager:(BTstackManager*) manager pinForAddress:(bd_addr_t)addr; // default: "0000" + +// direct access +-(void) btstackManager:(BTstackManager*) manager + handlePacketWithType:(uint8_t) packet_type + forChannel:(uint16_t) channel + andData:(uint8_t *)packet + withLen:(uint16_t) size; +@end + + +@protocol BTstackManagerListener +@optional + +// Activation events +-(void) activatedBTstackManager:(BTstackManager*) manager; +-(void) btstackManager:(BTstackManager*)manager activationFailed:(BTstackError)error; +-(void) deactivatedBTstackManager:(BTstackManager*) manager; + +// Power management events +-(void) sleepModeEnterBTstackManager:(BTstackManager*) manager; +-(void) sleepModeExtitBTstackManager:(BTstackManager*) manager; + +// Discovery events: general +-(void) btstackManager:(BTstackManager*)manager deviceInfo:(BTDevice*)device; +-(void) btstackManager:(BTstackManager*)manager discoveryQueryRemoteName:(int)deviceIndex; +-(void) discoveryStoppedBTstackManager:(BTstackManager*) manager; +-(void) discoveryInquiryBTstackManager:(BTstackManager*) manager; + +// Connection +-(void) l2capChannelCreatedAtAddress:(bd_addr_t)addr withPSM:(uint16_t)psm asID:(uint16_t)channelID; +-(void) l2capChannelCreateFailedAtAddress:(bd_addr_t)addr withPSM:(uint16_t)psm error:(BTstackError)error; +-(void) l2capChannelClosedForChannelID:(uint16_t)channelID; +-(void) l2capDataReceivedForChannelID:(uint16_t)channelID withData:(uint8_t *)packet ofLen:(uint16_t)size; + +-(void) rfcommConnectionCreatedAtAddress:(bd_addr_t)addr forChannel:(uint16_t)channel asID:(uint16_t)connectionID; +-(void) rfcommConnectionCreateFailedAtAddress:(bd_addr_t)addr forChannel:(uint16_t)channel error:(BTstackError)error; +-(void) rfcommConnectionClosedForConnectionID:(uint16_t)connectionID; +-(void) rfcommDataReceivedForConnectionID:(uint16_t)connectionID withData:(uint8_t *)packet ofLen:(uint16_t)size; + +// TODO add l2cap and rfcomm incoming events +@end diff --git a/ios/RetroArch/BTStack/BTstackManager.m b/ios/RetroArch/BTStack/BTstackManager.m new file mode 100644 index 0000000000..301f5be4b8 --- /dev/null +++ b/ios/RetroArch/BTStack/BTstackManager.m @@ -0,0 +1,590 @@ +/* + * Copyright (C) 2009 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#import "BTstackManager.h" + +#import "btstack/btstack.h" +#import "BTDevice.h" + +#define INQUIRY_INTERVAL 3 + +static BTstackManager * btstackManager = nil; + +@interface BTstackManager (privat) +- (void)handlePacketWithType:(uint8_t) packet_type forChannel:(uint16_t) channel andData:(uint8_t *)packet withLen:(uint16_t) size; +@end + +// needed for libBTstack +static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ + [btstackManager handlePacketWithType:packet_type forChannel:channel andData:packet withLen:size]; +} + +@implementation BTstackManager + +@synthesize delegate = _delegate; +@synthesize listeners; +@synthesize discoveredDevices; + +-(BTstackManager *) init { + self = [super init]; + if (!self) return self; + + state = kDeactivated; + discoveryState = kInactive; + connectedToDaemon = NO; + + // device discovery + [self setDiscoveredDevices: [[NSMutableArray alloc] init]]; + + // delegate and listener + _delegate = nil; + [self setListeners:[[NSMutableSet alloc] init]]; + + // Use Cocoa run loop + run_loop_init(RUN_LOOP_COCOA); + + // our packet handler + bt_register_packet_handler(packet_handler); + + return self; +} + ++(BTstackManager *) sharedInstance { + if (!btstackManager) { + btstackManager = [[BTstackManager alloc] init]; + } + return btstackManager; +} + +// listeners +-(void) addListener:(id)listener{ + [listeners addObject:listener]; +} + +-(void) removeListener:(id)listener{ + [listeners removeObject:listener]; +} + +// send events +-(void) sendActivated { + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(activatedBTstackManager:)]){ + [listener activatedBTstackManager:self]; + } + } +} +-(void) sendActivationFailed:(BTstackError)error { + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(btstackManager:activationFailed:)]){ + [listener btstackManager:self activationFailed:error]; + } + } +} +-(void) sendDeactivated { + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(deactivatedBTstackManager:)]){ + [listener deactivatedBTstackManager:self]; + } + } +} +-(void) sendSleepEnter { + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(sleepModeEnterBTstackManager:)]){ + [listener sleepModeEnterBTstackManager:self]; + } + } +} +-(void) sendSleepExit { + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(sleepModeExtitBTstackManager:)]){ + [listener sleepModeExtitBTstackManager:self]; + } + } +} +-(void) sendDiscoveryStoppedEvent { + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(discoveryStoppedBTstackManager:)]){ + [listener discoveryStoppedBTstackManager:self]; + } + } +} +-(void) sendDiscoveryInquiry{ + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(discoveryInquiryBTstackManager:)]){ + [listener discoveryInquiryBTstackManager:self]; + } + } +} +-(void) sendDiscoveryQueryRemoteName:(int)index { + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(btstackManager:discoveryQueryRemoteName:)]){ + [listener btstackManager:self discoveryQueryRemoteName:index]; + } + } +} +-(void) sendDeviceInfo:(BTDevice*) device{ + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(btstackManager:deviceInfo:)]){ + [listener btstackManager:self deviceInfo:device]; + } + } +} + + +// Activation +-(BTstackError) activate { + + BTstackError err = 0; + if (!connectedToDaemon) { + err = bt_open(); + if (err) return BTSTACK_CONNECTION_TO_BTDAEMON_FAILED; + } + connectedToDaemon = YES; + + // check system BT + state = kW4SysBTState; + bt_send_cmd(&btstack_get_system_bluetooth_enabled); + + return err; +} + +-(BTstackError) deactivate { + if (!connectedToDaemon) return BTSTACK_CONNECTION_TO_BTDAEMON_FAILED; + state = kW4Deactivated; + bt_send_cmd(&btstack_set_power_mode, HCI_POWER_OFF); + return 0; +} + +-(BOOL) isActive { + return state == kActivated; +} + +-(BOOL) isActivating { + switch (state){ + case kW4SysBTState: + case kW4SysBTDisabled: + case kW4Activated: + return YES; + default: + return NO; + } +} +-(BOOL) isDiscoveryActive { + return state == kActivated && (discoveryState != kInactive); +} + +// Discovery +-(BTstackError) startDiscovery { + if (state < kActivated) return BTSTACK_NOT_ACTIVATED; + + discoveryState = kW4InquiryMode; + bt_send_cmd(&hci_write_inquiry_mode, 0x01); // with RSSI + return 0; +}; + +-(BTstackError) stopDiscovery{ + if (state < kActivated) return BTSTACK_NOT_ACTIVATED; + switch (discoveryState){ + case kInactive: + [self sendDiscoveryStoppedEvent]; + break; + case kW4InquiryMode: + discoveryState = kW4InquiryModeBeforeStop; + break; + case kInquiry: + discoveryState = kW4InquiryStop; + bt_send_cmd(&hci_inquiry_cancel); + break; + case kRemoteName: { + discoveryState = kW4RemoteNameBeforeStop; + BTDevice *device = [discoveredDevices objectAtIndex:discoveryDeviceIndex]; + bt_send_cmd(&hci_remote_name_request_cancel, [device address]); + break; + } + default: + NSLog(@"[BTstackManager stopDiscovery] invalid discoveryState %u", discoveryState); + [self sendDiscoveryStoppedEvent]; + break; + } + return 0; +}; + +-(int) numberOfDevicesFound{ + return [discoveredDevices count]; +}; + +-(BTDevice*) deviceAtIndex:(int)index{ + return (BTDevice*) [discoveredDevices objectAtIndex:index]; +}; + +-(BTDevice*) deviceForAddress:(bd_addr_t*) address{ + for (BTDevice *device in discoveredDevices){ + // NSLog(@"compare %@ to %@", [BTDevice stringForAddress:address], [device addressString]); + if ( BD_ADDR_CMP(address, [device address]) == 0){ + return device; + } + } + return nil; +} + +- (void) activationHandleEvent:(uint8_t *)packet withLen:(uint16_t) size { + switch (state) { + + case kW4SysBTState: + case kW4SysBTDisabled: + + // BTSTACK_EVENT_SYSTEM_BLUETOOTH_ENABLED + if ( packet[0] == BTSTACK_EVENT_SYSTEM_BLUETOOTH_ENABLED){ + if (packet[2]){ + // system bt on - first time try to disable it + if ( state == kW4SysBTState) { + if (_delegate == nil + || ![_delegate respondsToSelector:@selector(disableSystemBluetoothBTstackManager:)] + || [_delegate disableSystemBluetoothBTstackManager:self]){ + state = kW4SysBTDisabled; + bt_send_cmd(&btstack_set_system_bluetooth_enabled, 0); + } else { + state = kDeactivated; + [self sendActivationFailed:BTSTACK_ACTIVATION_FAILED_SYSTEM_BLUETOOTH]; + } + } else { + state = kDeactivated; + [self sendActivationFailed:BTSTACK_ACTIVATION_FAILED_UNKNOWN]; + } + } else { + state = kW4Activated; + bt_send_cmd(&btstack_set_power_mode, HCI_POWER_ON); + } + } + break; + + case kW4Activated: + switch (packet[0]){ + case BTSTACK_EVENT_STATE: + if (packet[2] == HCI_STATE_WORKING) { + state = kActivated; + [self sendActivated]; + } + break; + case BTSTACK_EVENT_POWERON_FAILED: + state = kDeactivated; + [self sendActivationFailed:BTSTACK_ACTIVATION_POWERON_FAILED]; + break; + + default: + break; + } + break; + + case kW4Deactivated: + if (packet[0] != BTSTACK_EVENT_STATE && packet[2] == HCI_STATE_OFF){ + state = kDeactivated; + [self sendDeactivated]; + } + break; + + case kActivated: + if (packet[0] != BTSTACK_EVENT_STATE && packet[2] == HCI_STATE_FALLING_ASLEEP){ + state = kSleeping; + [self sendSleepEnter]; + } + break; + + case kSleeping: + if (packet[0] != BTSTACK_EVENT_STATE && packet[2] == HCI_STATE_WORKING){ + state = kActivated; + [self sendSleepExit]; + } + break; + + default: + break; + } +} + +-(void) discoveryRemoteName{ + BOOL found = NO; + while ( discoveryDeviceIndex < [discoveredDevices count]){ + BTDevice *device = [discoveredDevices objectAtIndex:discoveryDeviceIndex]; + if (device.name) { + discoveryDeviceIndex ++; + continue; + } + bt_send_cmd(&hci_remote_name_request, [device address], device.pageScanRepetitionMode, + 0, device.clockOffset | 0x8000); + [self sendDiscoveryQueryRemoteName:discoveryDeviceIndex]; + found = YES; + break; + } + if (!found) { + // printf("Queried all devices, restart.\n"); + discoveryState = kInquiry; + bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0); + [self sendDiscoveryInquiry]; + } +} + +- (NSString *) createRemoteNameFromRemoteNameEvent:(uint8_t *) packet { + // get lenght: first null byte or max 248 chars + int nameLen = 0; + while (nameLen < 248 && packet[9+nameLen]) nameLen++; + // Bluetooth specification mandates UTF-8 encoding... + NSString *name = [[NSString alloc] initWithBytes:&packet[9] length:nameLen encoding:NSUTF8StringEncoding]; + // but fallback to latin-1 for non-standard products like old Microsoft Wireless Presenter + if (!name){ + name = [[NSString alloc] initWithBytes:&packet[9] length:nameLen encoding:NSISOLatin1StringEncoding]; + } + return name; +} + +- (void) handleRemoteNameCached: (uint8_t *) packet { + bd_addr_t addr; + bt_flip_addr(addr, &packet[3]); + // NSLog(@"Get remote name done for %@", [BTDevice stringForAddress:&addr]); + BTDevice* device = [self deviceForAddress:&addr]; + if (!device) return; + + [device setName:[self createRemoteNameFromRemoteNameEvent:packet]]; + [self sendDeviceInfo:device]; +} + +- (void) handleRemoteName: (uint8_t *) packet { + bd_addr_t addr; + bt_flip_addr(addr, &packet[3]); + // NSLog(@"Get remote name done for %@", [BTDevice stringForAddress:&addr]); + BTDevice* device = [self deviceForAddress:&addr]; + if (!device) return; + + [device setName:[self createRemoteNameFromRemoteNameEvent:packet]]; + [self sendDeviceInfo:device]; + + discoveryDeviceIndex++; + [self discoveryRemoteName]; +} + +-(void) discoveryHandleEvent:(uint8_t *)packet withLen:(uint16_t) size { + bd_addr_t addr; + int i; + int numResponses; + + switch (discoveryState) { + + case kInactive: + break; + + case kW4InquiryMode: + if (packet[0] == HCI_EVENT_COMMAND_COMPLETE && COMMAND_COMPLETE_EVENT(packet, hci_write_inquiry_mode) ) { + discoveryState = kInquiry; + bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0); + [self sendDiscoveryInquiry]; + } + break; + + case kInquiry: + + switch (packet[0]){ + case HCI_EVENT_INQUIRY_RESULT: + numResponses = packet[2]; + for (i=0; i -#import "BTInquiryViewController.h" - -@interface WiiMoteHelper : NSObject -{ -} - -+ (void)startwiimote:(UIViewController *)controller; -+ (void)endwiimote; -+ (void)cancelWiiMoteSearch; +#import "BTDiscoveryViewController.h" +@interface WiiMoteHelper : NSObject ++ (WiiMoteHelper*)get; +- (void)showDiscovery; @end - - - - diff --git a/ios/RetroArch/BTStack/WiiMoteHelper.m b/ios/RetroArch/BTStack/WiiMoteHelper.m index 8898040797..83ce023447 100644 --- a/ios/RetroArch/BTStack/WiiMoteHelper.m +++ b/ios/RetroArch/BTStack/WiiMoteHelper.m @@ -37,391 +37,241 @@ #import "WiiMoteHelper.h" #import "BTDevice.h" -#import "BTInquiryViewController.h" +#import "BTstackManager.h" +#import "BTDiscoveryViewController.h" #import "btstack/btstack.h" #import "btstack/run_loop.h" #import "btstack/hci_cmds.h" -bool btOK = false; -bool initLoop = false; -BTDevice *device; -uint16_t wiiMoteConHandle = 0; -bool conected = false; -bool activated = false; - -BTInquiryViewController *inqViewControl; - -void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ - bd_addr_t event_addr; - - - switch (packet_type) { - - case L2CAP_DATA_PACKET://0x06 - { - struct wiimote_t *wm = NULL; - - wm = wiimote_get_by_source_cid(channel); - - if(wm!=NULL) - { - - byte* msg = packet + 2; - byte event = packet[1]; - - switch (event) { - case WM_RPT_BTN: - { - /* button */ - wiimote_pressed_buttons(wm, msg); - break; - } - case WM_RPT_READ: - { - /* data read */ - - if(WIIMOTE_DBG)printf("WM_RPT_READ data arrive!\n"); - - wiimote_pressed_buttons(wm, msg); - - byte err = msg[2] & 0x0F; - - if (err == 0x08) - printf("Unable to read data - address does not exist.\n"); - else if (err == 0x07) - printf("Unable to read data - address is for write-only registers.\n"); - else if (err) - printf("Unable to read data - unknown error code %x.\n", err); - - unsigned short offset = BIG_ENDIAN_SHORT(*(unsigned short*)(msg + 3)); - - byte len = ((msg[2] & 0xF0) >> 4) + 1; - - byte *data = (msg + 5); - - if(WIIMOTE_DBG) - { - int i = 0; - printf("Read: 0x%04x ; ",offset); - for (; i < len; ++i) - printf("%x ", data[i]); - printf("\n"); - } - - if(wiimote_handshake(wm,WM_RPT_READ,data,len)) - { - //btUsed = 1; - [inqViewControl showConnected:nil]; - [inqViewControl showConnecting:nil]; - //Create UIAlertView alert - [inqViewControl showConnecting:nil]; - - UIAlertView* alert = - [[UIAlertView alloc] initWithTitle:@"Connection detected!" - message: [NSString stringWithFormat:@"%@ '%@' connection sucessfully completed!", - (wm->exp.type != EXP_NONE ? @"Classic Controller" : @"WiiMote"), - [NSNumber numberWithInt:(wm->unid)+1]] - delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles: nil]; - [alert show]; - //[alert dismissWithClickedButtonIndex:0 animated:TRUE]; - [alert release]; - - if(device!=nil) - { - [device setConnectionState:kBluetoothConnectionConnected]; - device = nil; - } - - } - - return; - } - case WM_RPT_CTRL_STATUS: - { - wiimote_pressed_buttons(wm, msg); - - /* find the battery level and normalize between 0 and 1 */ - if(WIIMOTE_DBG) - { - wm->battery_level = (msg[5] / (float)WM_MAX_BATTERY_CODE); - - printf("BATTERY LEVEL %f\n", wm->battery_level); - } - - //handshake stuff! - if(wiimote_handshake(wm,WM_RPT_CTRL_STATUS,msg,-1)) - { - //btUsed = 1; - [inqViewControl showConnected:nil]; - [inqViewControl showConnecting:nil]; - UIAlertView* alert = - [[UIAlertView alloc] initWithTitle:@"Connection detected!" - message: [NSString stringWithFormat:@"WiiMote '%@' connection sucessfully completed!",[NSNumber numberWithInt:(wm->unid)+1]] - delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles: nil]; - [alert show]; - //[alert dismissWithClickedButtonIndex:0 animated:TRUE]; - [alert release]; - [device setConnectionState:kBluetoothConnectionConnected]; - - if(device!=nil) - { - [device setConnectionState:kBluetoothConnectionConnected]; - device = nil; - } - } - - return; - } - case WM_RPT_BTN_EXP: - { - /* button - expansion */ - wiimote_pressed_buttons(wm, msg); - wiimote_handle_expansion(wm, msg+2); - - break; - } - case WM_RPT_WRITE: - { - /* write feedback - safe to skip */ - break; - } - default: - { - printf("Unknown event, can not handle it [Code 0x%x].", event); - return; - } - } - } - break; - } - case HCI_EVENT_PACKET://0x04 - { - switch (packet[0]){ - - case L2CAP_EVENT_CHANNEL_OPENED: - - // data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16) - if (packet[2] == 0) { - - // inform about new l2cap connection - bt_flip_addr(event_addr, &packet[3]); - uint16_t psm = READ_BT_16(packet, 11); - uint16_t source_cid = READ_BT_16(packet, 13); - wiiMoteConHandle = READ_BT_16(packet, 9); - NSLog(@"Channel successfully opened: handle 0x%02x, psm 0x%02x, source cid 0x%02x, dest cid 0x%02x", - wiiMoteConHandle, psm, source_cid, READ_BT_16(packet, 15)); - - if (psm == 0x13) { - - // interupt channel openedn succesfully, now open control channel, too. - if(WIIMOTE_DBG)printf("open control channel\n"); - bt_send_cmd(&l2cap_create_channel, event_addr, 0x11); - struct wiimote_t *wm = NULL; - wm = &joys[myosd_num_of_joys]; - memset(wm, 0, sizeof(struct wiimote_t)); - wm->unid = myosd_num_of_joys; - wm->i_source_cid = source_cid; - memcpy(&wm->addr,&event_addr,BD_ADDR_LEN); - if(WIIMOTE_DBG)printf("addr %02x:%02x:%02x:%02x:%02x:%02x\n", wm->addr[0], wm->addr[1], wm->addr[2],wm->addr[3], wm->addr[4], wm->addr[5]); - if(WIIMOTE_DBG)printf("saved 0x%02x 0x%02x\n",source_cid,wm->i_source_cid); - wm->exp.type = EXP_NONE; - - } else { - - //inicializamos el wiimote! - struct wiimote_t *wm = NULL; - wm = &joys[myosd_num_of_joys]; - wm->wiiMoteConHandle = wiiMoteConHandle; - wm->c_source_cid = source_cid; - wm->state = WIIMOTE_STATE_CONNECTED; - myosd_num_of_joys++; - if(WIIMOTE_DBG)printf("Devices Number: %d\n",myosd_num_of_joys); - wiimote_handshake(wm,-1,NULL,-1); - } - } - break; - case L2CAP_EVENT_CHANNEL_CLOSED: - { - // data: event (8), len(8), channel (16) - uint16_t source_cid = READ_BT_16(packet, 2); - NSLog(@"Channel successfully closed: cid 0x%02x",source_cid); - - bd_addr_t addr; - int unid = wiimote_remove(source_cid,&addr); - if(unid!=-1) - { - [inqViewControl removeDeviceForAddress:&addr]; - UIAlertView* alert = - [[UIAlertView alloc] initWithTitle:@"Disconnection!" - message:[NSString stringWithFormat:@"WiiMote '%@' disconnection detected.\nIs battery drainned?",[NSNumber numberWithInt:(unid+1)]] - delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles: nil]; - [alert show]; - - [alert release]; - } - - } - break; - - default: - break; - } - break; - } - default: - break; - } -} +static BTDevice *device; +static uint16_t wiiMoteConHandle = 0; +static bool btOK; +static WiiMoteHelper* instance; @implementation WiiMoteHelper - -+(void) startwiimote:(UIViewController *)controller{ - - if(!initLoop) - { - run_loop_init(RUN_LOOP_COCOA); - initLoop = true; - } - if(!btOK ) - { - if (bt_open() ){ - // Alert user? - } else { - bt_register_packet_handler(packet_handler); - btOK = true; - } - } - - if (btOK) - { - // create inq controller - if(inqViewControl==nil) - { - inqViewControl = [[BTInquiryViewController alloc] init]; - - struct CGRect rect = controller.view.frame; - - CGFloat navBarWidht = rect.size.width; - CGFloat navBarHeight = 45; - - UINavigationBar *navBar = [ [ UINavigationBar alloc ] initWithFrame: CGRectMake(0, 0, navBarWidht , navBarHeight)]; - [navBar autorelease]; - [navBar setDelegate: inqViewControl ]; - - UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; - [button setFrame:CGRectMake(rect.size.width-70,5,60,35)]; - [button setTitle:@"Done" forState:UIControlStateNormal]; - button.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; - [button addTarget:self action:@selector(cancelWiiMoteSearch) forControlEvents:UIControlEventTouchUpInside]; - - [navBar addSubview:button]; - - UILabel *navLabel = [[UILabel alloc] initWithFrame:CGRectMake(40,0,300, navBarHeight)]; - navLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth; - navLabel.text = @"WiiMote Sync"; - navLabel.backgroundColor = [UIColor clearColor]; - navLabel.textColor = [UIColor blackColor]; - navLabel.font = [UIFont systemFontOfSize: 18]; - navLabel.textAlignment = UITextAlignmentLeft; - [navBar addSubview:navLabel]; - [navLabel release]; - - [[inqViewControl tableView] setTableHeaderView:navBar]; - [navBar release]; - - } - - if(!activated) - { - - - UIAlertView* alertView=[[UIAlertView alloc] initWithTitle:nil - message:@"are you sure you to activate BTstack?" - delegate:self cancelButtonTitle:nil - otherButtonTitles:@"Yes",@"No",nil]; - - [alertView show]; - [alertView release]; - } - - [controller presentModalViewController:inqViewControl animated:YES]; - - } - -} - -+ (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex ++ (WiiMoteHelper*)get { - - if(buttonIndex == 0 ) - { - [inqViewControl setDelegate:self]; - [inqViewControl setAllowSelection:true]; - activated = true; - [inqViewControl startInquiry]; - } - else - { - [inqViewControl dismissModalViewControllerAnimated:YES]; - } + if (!instance) + { + instance = [WiiMoteHelper new]; + } + + return instance; } -+(void) cancelWiiMoteSearch { - [inqViewControl stopInquiry]; - [inqViewControl dismissModalViewControllerAnimated:YES]; -} - - -+(void) deviceChoosen:(BTInquiryViewController *) inqView device:(BTDevice*) deviceChoosen; +- (id)init { - NSLog(@"deviceChoosen %@", [device toString]); + if (!btOK) + { + BTstackManager* bt = [BTstackManager sharedInstance]; + [bt setDelegate:self]; + [bt addListener:self]; + + btOK = [bt activate] == 0; + } + + return self; } -+ (void) deviceDetected:(BTInquiryViewController *) inqView device:(BTDevice*) selectedDevice { +- (void)dealloc +{ + // TODO: Any other cleanup needed + [[BTstackManager sharedInstance] deactivate]; +} - NSLog(@"deviceDetected %@", [device toString]); - if ([selectedDevice name] && [[selectedDevice name] caseInsensitiveCompare:@"Nintendo RVL-CNT-01"] == NSOrderedSame){ - NSLog(@"WiiMote found with address %@", [BTDevice stringForAddress:[selectedDevice address]]); - device = selectedDevice; - +- (void)showDiscovery +{ + BTDiscoveryViewController* vc = [BTDiscoveryViewController new]; + [vc setDelegate:self]; + + [[BTstackManager sharedInstance] addListener:vc]; + + [[RetroArch_iOS get] pushViewController:vc isGame:NO]; +} + +// BTStackManagerListener +-(void) activatedBTstackManager:(BTstackManager*) manager +{ + [[BTstackManager sharedInstance] startDiscovery]; +} + +-(void) btstackManager:(BTstackManager*)manager deviceInfo:(BTDevice*)newDevice +{ + if ([newDevice name] && [[newDevice name] hasPrefix:@"Nintendo RVL-CNT-01"]) + { + device = newDevice; + [[BTstackManager sharedInstance] stopDiscovery]; + } +} + +-(void) discoveryStoppedBTstackManager:(BTstackManager*) manager +{ + bt_send_cmd(&hci_write_authentication_enable, 0); +} + +// BTStackManagerDelegate +-(void) btstackManager:(BTstackManager*) manager + handlePacketWithType:(uint8_t) packet_type + forChannel:(uint16_t) channel + andData:(uint8_t *)packet + withLen:(uint16_t) size +{ + bd_addr_t event_addr; + + switch (packet_type) + { + case L2CAP_DATA_PACKET://0x06 + { + struct wiimote_t *wm = wiimote_get_by_source_cid(channel); - [inqViewControl stopInquiry]; + if (wm != NULL) + { + byte* msg = packet + 2; + byte event = packet[1]; + + switch (event) + { + case WM_RPT_BTN: + { + wiimote_pressed_buttons(wm, msg); + break; + } + + case WM_RPT_READ: + { + /* data read */ + wiimote_pressed_buttons(wm, msg); + + byte len = ((msg[2] & 0xF0) >> 4) + 1; + byte *data = (msg + 5); + + if(wiimote_handshake(wm, WM_RPT_READ, data, len)) + { + if (device != nil) + { + [device setConnectionState:kBluetoothConnectionConnected]; + device = nil; + } + } + + return; + } + + case WM_RPT_CTRL_STATUS: + { + wiimote_pressed_buttons(wm, msg); + + //handshake stuff! + if(wiimote_handshake(wm,WM_RPT_CTRL_STATUS,msg,-1)) + { + [device setConnectionState:kBluetoothConnectionConnected]; + + if (device != nil) + { + [device setConnectionState:kBluetoothConnectionConnected]; + device = nil; + } + } + + return; + } + + case WM_RPT_BTN_EXP: + { + /* button - expansion */ + wiimote_pressed_buttons(wm, msg); + wiimote_handle_expansion(wm, msg+2); + + break; + } - [inqViewControl showConnecting:device]; + case WM_RPT_WRITE: + { + /* write feedback - safe to skip */ + break; + } - // connect to device - [device setConnectionState:kBluetoothConnectionConnecting]; - [[inqViewControl tableView] reloadData]; - bt_send_cmd(&l2cap_create_channel, [device address], 0x13); - - - } + default: + { + printf("Unknown event, can not handle it [Code 0x%x].", event); + return; + } + } + } + break; + } + + case HCI_EVENT_PACKET://0x04 + { + switch (packet[0]) + { + case HCI_EVENT_COMMAND_COMPLETE: + { + if (COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable)) + bt_send_cmd(&l2cap_create_channel, [device address], PSM_HID_INTERRUPT); + break; + } + + case HCI_EVENT_PIN_CODE_REQUEST: + { + bt_flip_addr(event_addr, &packet[2]); + if (BD_ADDR_CMP([device address], event_addr)) break; + + // inform about pin code request + NSLog(@"HCI_EVENT_PIN_CODE_REQUEST\n"); + bt_send_cmd(&hci_pin_code_request_reply, event_addr, 6, &packet[2]); // use inverse bd_addr as PIN + break; + } + + case L2CAP_EVENT_CHANNEL_OPENED: + { + // data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16) + if (packet[2] == 0) + { + // inform about new l2cap connection + bt_flip_addr(event_addr, &packet[3]); + uint16_t psm = READ_BT_16(packet, 11); + uint16_t source_cid = READ_BT_16(packet, 13); + wiiMoteConHandle = READ_BT_16(packet, 9); + + if (psm == 0x13) + { + // interupt channel openedn succesfully, now open control channel, too. + bt_send_cmd(&l2cap_create_channel, event_addr, 0x11); + struct wiimote_t *wm = &joys[myosd_num_of_joys]; + memset(wm, 0, sizeof(struct wiimote_t)); + wm->unid = myosd_num_of_joys; + wm->i_source_cid = source_cid; + memcpy(&wm->addr,&event_addr,BD_ADDR_LEN); + wm->exp.type = EXP_NONE; + } + else + { + //inicializamos el wiimote! + struct wiimote_t *wm = &joys[myosd_num_of_joys]; + wm->wiiMoteConHandle = wiiMoteConHandle; + wm->c_source_cid = source_cid; + wm->state = WIIMOTE_STATE_CONNECTED; + myosd_num_of_joys++; + wiimote_handshake(wm,-1,NULL,-1); + } + } + + break; + } + + case L2CAP_EVENT_CHANNEL_CLOSED: + { + // data: event (8), len(8), channel (16) + uint16_t source_cid = READ_BT_16(packet, 2); + + bd_addr_t addr; + wiimote_remove(source_cid,&addr); + break; + } + } + } + } } - -+ (void) inquiryStopped{ -} - -+ (void) disconnectDevice:(BTInquiryViewController *) inqView device:(BTDevice*) selectedDevice { -} - -+ (void)endwiimote { - - if(btOK) - { - int i=0; - while(i!=myosd_num_of_joys){ - [inqViewControl removeDeviceForAddress:&joys[i].addr]; - i++; - } - - myosd_num_of_joys=0; - bt_send_cmd(&btstack_set_power_mode, HCI_POWER_OFF ); - bt_close(); - activated= false; - btOK = false; - } -} - @end - diff --git a/ios/RetroArch/BTStack/btstack/btstack.h b/ios/RetroArch/BTStack/btstack/btstack.h index 04a2e146f4..03c02a0fb2 100644 --- a/ios/RetroArch/BTStack/btstack/btstack.h +++ b/ios/RetroArch/BTStack/btstack/btstack.h @@ -64,10 +64,10 @@ typedef void (*btstack_packet_handler_t) (uint8_t packet_type, uint16_t channel, void bt_use_tcp(const char * address, uint16_t port); // init BTstack library -int bt_open(); +int bt_open(void); // stop using BTstack library -int bt_close(); +int bt_close(void); // send hci cmd packet int bt_send_cmd(const hci_cmd_t *cmd, ...); @@ -79,6 +79,7 @@ btstack_packet_handler_t bt_register_packet_handler(btstack_packet_handler_t han void bt_send_acl(uint8_t * data, uint16_t len); void bt_send_l2cap(uint16_t local_cid, uint8_t *data, uint16_t len); +void bt_send_rfcomm(uint16_t rfcom_cid, uint8_t *data, uint16_t len); #if defined __cplusplus } diff --git a/ios/RetroArch/BTStack/btstack/hci_cmds.h b/ios/RetroArch/BTStack/btstack/hci_cmds.h index cfb36cc7a1..a6e6bf4ea9 100644 --- a/ios/RetroArch/BTStack/btstack/hci_cmds.h +++ b/ios/RetroArch/BTStack/btstack/hci_cmds.h @@ -53,13 +53,23 @@ extern "C" { // extension for client/server communication #define DAEMON_EVENT_PACKET 0x05 - + // L2CAP data #define L2CAP_DATA_PACKET 0x06 // RFCOMM data -#define RFCOMM_DATA_PACKET 0x07 +#define RFCOMM_DATA_PACKET 0x07 +// Attribute protocol data +#define ATT_DATA_PACKET 0x08 + +// Security Manager protocol data +#define SM_DATA_PACKET 0x09 + +// debug log messages +#define LOG_MESSAGE_PACKET 0xfc + + // Fixed PSM numbers #define PSM_SDP 0x01 #define PSM_RFCOMM 0x03 @@ -74,7 +84,7 @@ extern "C" { #define HCI_EVENT_DISCONNECTION_COMPLETE 0x05 #define HCI_EVENT_AUTHENTICATION_COMPLETE_EVENT 0x06 #define HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE 0x07 -#define HCI_EVENT_ENCRIPTION_CHANGE 0x08 +#define HCI_EVENT_ENCRYPTION_CHANGE 0x08 #define HCI_EVENT_CHANGE_CONNECTION_LINK_KEY_COMPLETE 0x09 #define HCI_EVENT_MASTER_LINK_KEY_COMPLETE 0x0A #define HCI_EVENT_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE 0x0B @@ -97,12 +107,21 @@ extern "C" { #define HCI_EVENT_PACKET_TYPE_CHANGED 0x1D #define HCI_EVENT_INQUIRY_RESULT_WITH_RSSI 0x22 #define HCI_EVENT_EXTENDED_INQUIRY_RESPONSE 0x2F +#define HCI_EVENT_LE_META 0x3E #define HCI_EVENT_VENDOR_SPECIFIC 0xFF +#define HCI_SUBEVENT_LE_CONNECTION_COMPLETE 0x01 +#define HCI_SUBEVENT_LE_ADVERTISING_REPORT 0x02 +#define HCI_SUBEVENT_LE_CONNECTION_UPDATE_COMPLETE 0x03 +#define HCI_SUBEVENT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 +#define HCI_SUBEVENT_LE_LONG_TERM_KEY_REQUEST 0x05 + // last used HCI_EVENT in 2.1 is 0x3d // events 0x50-0x5f are used internally +// BTSTACK DAEMON EVENTS + // events from BTstack for application/client lib #define BTSTACK_EVENT_STATE 0x60 @@ -118,25 +137,61 @@ extern "C" { // data: system bluetooth on/off (bool) #define BTSTACK_EVENT_SYSTEM_BLUETOOTH_ENABLED 0x64 -// data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16) +// data: event (8), len(8), status (8) == 0, address (48), name (1984 bits = 248 bytes) +#define BTSTACK_EVENT_REMOTE_NAME_CACHED 0x65 + +// data: discoverable enabled (bool) +#define BTSTACK_EVENT_DISCOVERABLE_ENABLED 0x66 + +// L2CAP EVENTS + +// data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16), local_mtu(16), remote_mtu(16) #define L2CAP_EVENT_CHANNEL_OPENED 0x70 // data: event (8), len(8), channel (16) #define L2CAP_EVENT_CHANNEL_CLOSED 0x71 -// data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16) +// data: event (8), len(8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16) #define L2CAP_EVENT_INCOMING_CONNECTION 0x72 // data: event(8), len(8), handle(16) #define L2CAP_EVENT_TIMEOUT_CHECK 0x73 -// data: event(8), len(8), handle(16) +// data: event(8), len(8), local_cid(16), credits(8) #define L2CAP_EVENT_CREDITS 0x74 -// data: event(8), len(8), service_record_handle(32) -#define SDP_SERVICE_REGISTERED 0x80 +// data: event(8), len(8), status (8), psm (16) +#define L2CAP_EVENT_SERVICE_REGISTERED 0x75 +// RFCOMM EVENTS + +// data: event(8), len(8), status (8), address (48), handle (16), server channel(8), rfcomm_cid(16), max frame size(16) +#define RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE 0x80 + +// data: event(8), len(8), rfcomm_cid(16) +#define RFCOMM_EVENT_CHANNEL_CLOSED 0x81 + +// data: event (8), len(8), address(48), channel (8), rfcomm_cid (16) +#define RFCOMM_EVENT_INCOMING_CONNECTION 0x82 + +// data: event (8), len(8), rfcommid (16), ... +#define RFCOMM_EVENT_REMOTE_LINE_STATUS 0x83 + +// data: event(8), len(8), rfcomm_cid(16), credits(8) +#define RFCOMM_EVENT_CREDITS 0x84 + +// data: event(8), len(8), status (8), rfcomm server channel id (8) +#define RFCOMM_EVENT_SERVICE_REGISTERED 0x85 + +// data: event(8), len(8), status (8), rfcomm server channel id (8) +#define RFCOMM_EVENT_PERSISTENT_CHANNEL 0x86 + + +// data: event(8), len(8), status(8), service_record_handle(32) +#define SDP_SERVICE_REGISTERED 0x90 + + // last error code in 2.1 is 0x38 - we start with 0x50 for BTstack errors #define BTSTACK_CONNECTION_TO_BTDAEMON_FAILED 0x50 @@ -145,6 +200,8 @@ extern "C" { #define BTSTACK_ACTIVATION_FAILED_UNKNOWN 0x53 #define BTSTACK_NOT_ACTIVATED 0x54 #define BTSTACK_BUSY 0x55 +#define BTSTACK_MEMORY_ALLOC_FAILED 0x56 +#define BTSTACK_ACL_BUFFERS_FULL 0x57 // l2cap errors - enumeration by the command that created them #define L2CAP_COMMAND_REJECT_REASON_COMMAND_NOT_UNDERSTOOD 0x60 @@ -161,7 +218,14 @@ extern "C" { #define L2CAP_CONFIG_RESPONSE_RESULT_UNACCEPTABLE_PARAMS 0x67 #define L2CAP_CONFIG_RESPONSE_RESULT_REJECTED 0x68 #define L2CAP_CONFIG_RESPONSE_RESULT_UNKNOWN_OPTIONS 0x69 +#define L2CAP_SERVICE_ALREADY_REGISTERED 0x6a + +#define RFCOMM_MULTIPLEXER_STOPPED 0x70 +#define RFCOMM_CHANNEL_ALREADY_REGISTERED 0x71 +#define RFCOMM_NO_OUTGOING_CREDITS 0x72 +#define SDP_HANDLE_ALREADY_REGISTERED 0x80 + /** * Default INQ Mode */ @@ -171,7 +235,8 @@ extern "C" { */ typedef enum { HCI_POWER_OFF = 0, - HCI_POWER_ON + HCI_POWER_ON, + HCI_POWER_SLEEP } HCI_POWER_MODE; /** @@ -181,7 +246,9 @@ typedef enum { HCI_STATE_OFF = 0, HCI_STATE_INITIALIZING, HCI_STATE_WORKING, - HCI_STATE_HALTING + HCI_STATE_HALTING, + HCI_STATE_SLEEPING, + HCI_STATE_FALLING_ASLEEP } HCI_STATE; /** @@ -200,9 +267,12 @@ extern const hci_cmd_t btstack_set_acl_capture_mode; extern const hci_cmd_t btstack_get_version; extern const hci_cmd_t btstack_get_system_bluetooth_enabled; extern const hci_cmd_t btstack_set_system_bluetooth_enabled; - +extern const hci_cmd_t btstack_set_discoverable; +extern const hci_cmd_t btstack_set_bluetooth_enabled; // only used by btstack config + extern const hci_cmd_t hci_accept_connection_request; extern const hci_cmd_t hci_authentication_requested; +extern const hci_cmd_t hci_change_connection_link_key; extern const hci_cmd_t hci_create_connection; extern const hci_cmd_t hci_create_connection_cancel; extern const hci_cmd_t hci_delete_stored_link_key; @@ -217,25 +287,64 @@ extern const hci_cmd_t hci_pin_code_request_negative_reply; extern const hci_cmd_t hci_qos_setup; extern const hci_cmd_t hci_read_bd_addr; extern const hci_cmd_t hci_read_buffer_size; +extern const hci_cmd_t hci_read_le_host_supported; extern const hci_cmd_t hci_read_link_policy_settings; extern const hci_cmd_t hci_read_link_supervision_timeout; +extern const hci_cmd_t hci_read_local_supported_features; +extern const hci_cmd_t hci_read_num_broadcast_retransmissions; +extern const hci_cmd_t hci_reject_connection_request; extern const hci_cmd_t hci_remote_name_request; extern const hci_cmd_t hci_remote_name_request_cancel; extern const hci_cmd_t hci_reset; extern const hci_cmd_t hci_role_discovery; extern const hci_cmd_t hci_set_event_mask; +extern const hci_cmd_t hci_set_connection_encryption; +extern const hci_cmd_t hci_sniff_mode; extern const hci_cmd_t hci_switch_role_command; extern const hci_cmd_t hci_write_authentication_enable; extern const hci_cmd_t hci_write_class_of_device; extern const hci_cmd_t hci_write_extended_inquiry_response; extern const hci_cmd_t hci_write_inquiry_mode; +extern const hci_cmd_t hci_write_le_host_supported; extern const hci_cmd_t hci_write_link_policy_settings; extern const hci_cmd_t hci_write_link_supervision_timeout; extern const hci_cmd_t hci_write_local_name; +extern const hci_cmd_t hci_write_num_broadcast_retransmissions; extern const hci_cmd_t hci_write_page_timeout; extern const hci_cmd_t hci_write_scan_enable; extern const hci_cmd_t hci_write_simple_pairing_mode; +extern const hci_cmd_t hci_le_add_device_to_whitelist; +extern const hci_cmd_t hci_le_clear_white_list; +extern const hci_cmd_t hci_le_connection_update; +extern const hci_cmd_t hci_le_create_connection; +extern const hci_cmd_t hci_le_create_connection_cancel; +extern const hci_cmd_t hci_le_encrypt; +extern const hci_cmd_t hci_le_long_term_key_negative_reply; +extern const hci_cmd_t hci_le_long_term_key_request_reply; +extern const hci_cmd_t hci_le_rand; +extern const hci_cmd_t hci_le_read_advertising_channel_tx_power; +extern const hci_cmd_t hci_le_read_buffer_size ; +extern const hci_cmd_t hci_le_read_channel_map; +extern const hci_cmd_t hci_le_read_remote_used_features; +extern const hci_cmd_t hci_le_read_supported_features; +extern const hci_cmd_t hci_le_read_supported_states; +extern const hci_cmd_t hci_le_read_white_list_size; +extern const hci_cmd_t hci_le_receiver_test; +extern const hci_cmd_t hci_le_remove_device_from_whitelist; +extern const hci_cmd_t hci_le_set_advertise_enable; +extern const hci_cmd_t hci_le_set_advertising_data; +extern const hci_cmd_t hci_le_set_advertising_parameters; +extern const hci_cmd_t hci_le_set_event_mask; +extern const hci_cmd_t hci_le_set_host_channel_classification; +extern const hci_cmd_t hci_le_set_random_address; +extern const hci_cmd_t hci_le_set_scan_enable; +extern const hci_cmd_t hci_le_set_scan_parameters; +extern const hci_cmd_t hci_le_set_scan_response_data; +extern const hci_cmd_t hci_le_start_encryption; +extern const hci_cmd_t hci_le_test_end; +extern const hci_cmd_t hci_le_transmitter_test; + extern const hci_cmd_t l2cap_accept_connection; extern const hci_cmd_t l2cap_create_channel; extern const hci_cmd_t l2cap_create_channel_mtu; @@ -247,7 +356,25 @@ extern const hci_cmd_t l2cap_unregister_service; extern const hci_cmd_t sdp_register_service_record; extern const hci_cmd_t sdp_unregister_service_record; - +// accept connection @param bd_addr(48), rfcomm_cid (16) +extern const hci_cmd_t rfcomm_accept_connection; +// create rfcomm channel: @param bd_addr(48), channel (8) +extern const hci_cmd_t rfcomm_create_channel; +// create rfcomm channel: @param bd_addr(48), channel (8), mtu (16), credits (8) +extern const hci_cmd_t rfcomm_create_channel_with_initial_credits; +// decline rfcomm disconnect,@param bd_addr(48), rfcomm cid (16), reason(8) +extern const hci_cmd_t rfcomm_decline_connection; +// disconnect rfcomm disconnect, @param rfcomm_cid(8), reason(8) +extern const hci_cmd_t rfcomm_disconnect; +// register rfcomm service: @param channel(8), mtu (16) +extern const hci_cmd_t rfcomm_register_service; +// register rfcomm service: @param channel(8), mtu (16), initial credits (8) +extern const hci_cmd_t rfcomm_register_service_with_initial_credits; +// unregister rfcomm service, @param service_channel(16) +extern const hci_cmd_t rfcomm_unregister_service; +// request persisten rfcomm channel for service name: serive name (char*) +extern const hci_cmd_t rfcomm_persistent_channel_for_service; + #if defined __cplusplus } #endif diff --git a/ios/RetroArch/BTStack/btstack/linked_list.h b/ios/RetroArch/BTStack/btstack/linked_list.h index 2518094876..d9d4fba554 100644 --- a/ios/RetroArch/BTStack/btstack/linked_list.h +++ b/ios/RetroArch/BTStack/btstack/linked_list.h @@ -54,8 +54,9 @@ int linked_list_empty(linked_list_t * list); void linked_list_add(linked_list_t * list, linked_item_t *item); // <-- add item to list as first element void linked_list_add_tail(linked_list_t * list, linked_item_t *item); // <-- add item to list as last element int linked_list_remove(linked_list_t * list, linked_item_t *item); // <-- remove item from list +linked_item_t * linked_list_get_last_item(linked_list_t * list); // <-- find the last item in the list -void test_linked_list(); +void test_linked_list(void); #if defined __cplusplus } diff --git a/ios/RetroArch/BTStack/btstack/run_loop.h b/ios/RetroArch/BTStack/btstack/run_loop.h index ea2673d5d4..5ff6a9c76f 100644 --- a/ios/RetroArch/BTStack/btstack/run_loop.h +++ b/ios/RetroArch/BTStack/btstack/run_loop.h @@ -37,9 +37,16 @@ #pragma once +//#include "config.h" +#define HAVE_TIME + #include "linked_list.h" +#include + +#ifdef HAVE_TIME #include +#endif #if defined __cplusplus extern "C" { @@ -59,27 +66,56 @@ typedef struct data_source { typedef struct timer { linked_item_t item; +#ifdef HAVE_TIME struct timeval timeout; // <-- next timeout +#endif +#ifdef HAVE_TICK + uint32_t timeout; // timeout in system ticks +#endif void (*process)(struct timer *ts); // <-- do processing } timer_source_t; -// init must be called before any other run_loop call -void run_loop_init(RUN_LOOP_TYPE type); -// add/remove data_source -void run_loop_add_data_source(data_source_t *dataSource); -int run_loop_remove_data_source(data_source_t *dataSource); +// Set timer based on current time in milliseconds. +void run_loop_set_timer(timer_source_t *a, uint32_t timeout_in_ms); -// set timer based on current time -void run_loop_set_timer(timer_source_t *a, int timeout_in_ms); +// Set callback that will be executed when timer expires. +void run_loop_set_timer_handler(timer_source_t *ts, void (*process)(timer_source_t *_ts)); -// add/remove timer_source +// Add/Remove timer source. void run_loop_add_timer(timer_source_t *timer); int run_loop_remove_timer(timer_source_t *timer); -// execute configured run_loop -void run_loop_execute(); +// Init must be called before any other run_loop call. +// Use RUN_LOOP_EMBEDDED for embedded devices. +void run_loop_init(RUN_LOOP_TYPE type); +// Set data source callback. +void run_loop_set_data_source_handler(data_source_t *ds, int (*process)(data_source_t *_ds)); + + +// Add/Remove data source. +void run_loop_add_data_source(data_source_t *dataSource); +int run_loop_remove_data_source(data_source_t *dataSource); + + +// Execute configured run loop. This function does not return. +void run_loop_execute(void); + +// hack to fix HCI timer handling +#ifdef HAVE_TICK +// Sets how many miliseconds has one tick. +uint32_t embedded_ticks_for_ms(uint32_t time_in_ms); +// Queries the current time in ticks. +uint32_t embedded_get_ticks(void); +#endif +#ifdef EMBEDDED +// Sets an internal flag that is checked in the critical section +// just before entering sleep mode. Has to be called by the interupt +// handler of a data source to signal the run loop that a new data +// is available. +void embedded_trigger(void); +#endif #if defined __cplusplus } #endif diff --git a/ios/RetroArch/BTStack/btstack/sdp_util.h b/ios/RetroArch/BTStack/btstack/sdp_util.h index fb91038f2e..0ebb219766 100644 --- a/ios/RetroArch/BTStack/btstack/sdp_util.h +++ b/ios/RetroArch/BTStack/btstack/sdp_util.h @@ -79,30 +79,59 @@ typedef enum { #define SDP_ClientExecutableURL 0x000b #define SDP_IconURL 0x000c #define SDP_AdditionalProtocolDescriptorList 0x000d +#define SDP_SupportedFormatsList 0x0303 + +// SERVICE CLASSES +#define SDP_OBEXObjectPush 0x1105 +#define SDP_OBEXFileTransfer 0x1106 +#define SDP_PublicBrowseGroup 0x1002 + +// PROTOCOLS +#define SDP_SDPProtocol 0x0001 +#define SDP_UDPProtocol 0x0002 +#define SDP_RFCOMMProtocol 0x0003 +#define SDP_OBEXProtocol 0x0008 +#define SDP_L2CAPProtocol 0x0100 // OFFSETS FOR LOCALIZED ATTRIBUTES - SDP_LanguageBaseAttributeIDList #define SDP_Offest_ServiceName 0x0000 #define SDP_Offest_ServiceDescription 0x0001 #define SDP_Offest_ProviderName 0x0002 +// OBEX +#define SDP_vCard_2_1 0x01 +#define SDP_vCard_3_0 0x02 +#define SDP_vCal_1_0 0x03 +#define SDP_iCal_2_0 0x04 +#define SDP_vNote 0x05 +#define SDP_vMessage 0x06 +#define SDP_OBEXFileTypeAny 0xFF -#pragma mark DateElement +// MARK: DateElement void de_dump_data_element(uint8_t * record); int de_get_len(uint8_t *header); de_size_t de_get_size_type(uint8_t *header); de_type_t de_get_element_type(uint8_t *header); +int de_get_header_size(uint8_t * header); void de_create_sequence(uint8_t *header); +void de_store_descriptor_with_len(uint8_t * header, de_type_t type, de_size_t size, uint32_t len); uint8_t * de_push_sequence(uint8_t *header); void de_pop_sequence(uint8_t * parent, uint8_t * child); void de_add_number(uint8_t *seq, de_type_t type, de_size_t size, uint32_t value); void de_add_data( uint8_t *seq, de_type_t type, uint16_t size, uint8_t *data); int de_get_data_size(uint8_t * header); +void de_add_uuid128(uint8_t * seq, uint8_t * uuid); -#pragma mark SDP -int sdp_append_attributes_in_attributeIDList(uint8_t *record, uint8_t *attributeIDList, uint16_t startIndex, uint16_t maxBytes, uint8_t *buffer); +// MARK: SDP +uint16_t sdp_append_attributes_in_attributeIDList(uint8_t *record, uint8_t *attributeIDList, uint16_t startOffset, uint16_t maxBytes, uint8_t *buffer); uint8_t * sdp_get_attribute_value_for_attribute_id(uint8_t * record, uint16_t attributeID); -int sdp_record_matches_service_search_pattern(uint8_t *record, uint8_t *serviceSearchPattern); +uint8_t sdp_set_attribute_value_for_attribute_id(uint8_t * record, uint16_t attributeID, uint32_t value); +int sdp_record_matches_service_search_pattern(uint8_t *record, uint8_t *serviceSearchPattern); +int spd_get_filtered_size(uint8_t *record, uint8_t *attributeIDList); +int sdp_filter_attributes_in_attributeIDList(uint8_t *record, uint8_t *attributeIDList, uint16_t startOffset, uint16_t maxBytes, uint16_t *usedBytes, uint8_t *buffer); + +void sdp_create_spp_service(uint8_t *service, int service_id, const char *name); #if defined __cplusplus } diff --git a/ios/RetroArch/BTStack/btstack/utils.h b/ios/RetroArch/BTStack/btstack/utils.h index 39064f370b..3fea5d5158 100644 --- a/ios/RetroArch/BTStack/btstack/utils.h +++ b/ios/RetroArch/BTStack/btstack/utils.h @@ -39,12 +39,13 @@ #pragma once -#include #if defined __cplusplus extern "C" { #endif - + +#include + /** * @brief hci connection handle type */ @@ -62,6 +63,13 @@ typedef uint8_t bd_addr_t[BD_ADDR_LEN]; #define LINK_KEY_LEN 16 typedef uint8_t link_key_t[LINK_KEY_LEN]; +/** + * @brief The device name type + */ +#define DEVICE_NAME_LEN 248 +typedef uint8_t device_name_t[DEVICE_NAME_LEN+1]; + + // helper for BT little endian format #define READ_BT_16( buffer, pos) ( ((uint16_t) buffer[pos]) | (((uint16_t)buffer[pos+1]) << 8)) #define READ_BT_24( buffer, pos) ( ((uint32_t) buffer[pos]) | (((uint32_t)buffer[pos+1]) << 8) | (((uint32_t)buffer[pos+2]) << 16)) @@ -77,6 +85,10 @@ typedef uint8_t link_key_t[LINK_KEY_LEN]; // check if command complete event for given command #define COMMAND_COMPLETE_EVENT(event,cmd) ( event[0] == HCI_EVENT_COMMAND_COMPLETE && READ_BT_16(event,3) == cmd.opcode) +#define COMMAND_STATUS_EVENT(event,cmd) ( event[0] == HCI_EVENT_COMMAND_STATUS && READ_BT_16(event,4) == cmd.opcode) + +// Code+Len=2, Pkts+Opcode=3; total=5 +#define OFFSET_OF_DATA_IN_COMMAND_COMPLETE 5 // ACL Packet #define READ_ACL_CONNECTION_HANDLE( buffer ) ( READ_BT_16(buffer,0) & 0x0fff) @@ -96,19 +108,19 @@ void net_store_32(uint8_t *buffer, uint16_t pos, uint32_t value); void hexdump(void *data, int size); void printUUID(uint8_t *uuid); -void print_bd_addr(bd_addr_t addr); -int sscan_bd_addr(uint8_t * addr_string, bd_addr_t addr); +// @deprecated please use more convenient bd_addr_to_str +void print_bd_addr( bd_addr_t addr); +char * bd_addr_to_str(bd_addr_t addr); + +int sscan_bd_addr(uint8_t * addr_string, bd_addr_t addr); + uint8_t crc8_check(uint8_t *data, uint16_t len, uint8_t check_sum); uint8_t crc8_calc(uint8_t *data, uint16_t len); #define BD_ADDR_CMP(a,b) memcmp(a,b, BD_ADDR_LEN) #define BD_ADDR_COPY(dest,src) memcpy(dest,src,BD_ADDR_LEN) -#ifdef EMBEDDED -void bzero(void *s, uint32_t n); -#endif - #if defined __cplusplus } #endif diff --git a/ios/RetroArch/BTStack/wiimote.c b/ios/RetroArch/BTStack/wiimote.c index 9a6576989f..6f468e648b 100644 --- a/ios/RetroArch/BTStack/wiimote.c +++ b/ios/RetroArch/BTStack/wiimote.c @@ -47,7 +47,7 @@ #include "btstack/btstack.h" #include "wiimote.h" -//int num_of_joys = 0; +int myosd_num_of_joys = 0; struct wiimote_t joys[4]; extern int g_pref_wii_DZ_value; #define STICK4WAY (myosd_waysStick == 4 && myosd_inGame) @@ -506,7 +506,6 @@ void calc_joystick_state(struct joystick_t* js, float x, float y); * @return Returns 1 if handshake was successful, 0 if not. */ int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, byte* data, unsigned short len) { - int i; int offset = 0; cc->btns = 0; @@ -581,7 +580,7 @@ int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, byte * @param msg The message specified in the event packet. */ void classic_ctrl_event(struct classic_ctrl_t* cc, byte* msg) { - int i, lx, ly, rx, ry; + int lx, ly, rx, ry; byte l, r; /* decrypt data */ @@ -691,200 +690,3 @@ void calc_joystick_state(struct joystick_t* js, float x, float y) { js->ry = ry; } - -//////////////////////////////////////////////////////////// - -extern float joy_analog_x[4]; -extern float joy_analog_y[4]; - -int iOS_wiimote_check (struct wiimote_t *wm) -{ - return wm->btns; -} -#if 0 - joy_analog_x[wm->unid]=0.0f; - joy_analog_y[wm->unid]=0.0f; - if (1) { - if (wm->exp.type == EXP_CLASSIC) { - - float deadZone; - - switch(g_pref_wii_DZ_value) - { - case 0: deadZone = 0.12f;break; - case 1: deadZone = 0.15f;break; - case 2: deadZone = 0.17f;break; - case 3: deadZone = 0.2f;break; - case 4: deadZone = 0.3f;break; - case 5: deadZone = 0.4f;break; - } - - //printf("deadzone %f\n",deadZone); - - struct classic_ctrl_t* cc = (classic_ctrl_t*)&wm->exp.classic; - - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_ZL)) joyExKey |= MYOSD_R1; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_B)) joyExKey |= MYOSD_X; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_Y)) joyExKey |= MYOSD_A; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_A)) joyExKey |= MYOSD_B; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_X)) joyExKey |= MYOSD_Y; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_ZR)) joyExKey |= MYOSD_L1; - - - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_UP)){ - if(!STICK2WAY && - !(STICK4WAY && (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_LEFT) || - (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_RIGHT))))) - joyExKey |= MYOSD_UP; - } - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_DOWN)){ - if(!STICK2WAY && - !(STICK4WAY && (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_LEFT) || - (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_RIGHT))))) - joyExKey |= MYOSD_DOWN; - } - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_LEFT)) joyExKey |= MYOSD_LEFT; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_RIGHT)) joyExKey |= MYOSD_RIGHT; - - - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_FULL_L)) joyExKey |= MYOSD_L1; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_MINUS)) joyExKey |= MYOSD_SELECT; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_HOME)) {//myosd_exitGame = 0;usleep(50000); - myosd_exitGame = 1;} - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_PLUS)) joyExKey |= MYOSD_START; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_FULL_R)) joyExKey |= MYOSD_R1; - - if(cc->ljs.mag >= deadZone) - { - joy_analog_x[wm->unid] = ( cc->ljs.rx > 1.0 ) ? 1.0 : ( cc->ljs.rx < -1.0 ) ? -1.0 : cc->ljs.rx; - joy_analog_y[wm->unid] = ( cc->ljs.ry > 1.0 ) ? 1.0 : ( cc->ljs.ry < -1.0 ) ? -1.0 : cc->ljs.ry; - - float v = cc->ljs.ang; - - if(STICK2WAY) - { - if( v < 180){ - joyExKey |= MYOSD_RIGHT; - //printf("Right\n"); - } - else if ( v >= 180){ - joyExKey |= MYOSD_LEFT; - //printf("Left\n"); - } - } - else if(STICK4WAY) - { - if(v >= 315 || v < 45){ - joyExKey |= MYOSD_UP; - //printf("Up\n"); - } - else if (v >= 45 && v < 135){ - joyExKey |= MYOSD_RIGHT; - //printf("Right\n"); - } - else if (v >= 135 && v < 225){ - joyExKey |= MYOSD_DOWN; - //printf("Down\n"); - } - else if (v >= 225 && v < 315){ - joyExKey |= MYOSD_LEFT; - //printf("Left\n"); - } - } - else - { - if( v >= 330 || v < 30){ - joyExKey |= MYOSD_UP; - //printf("Up\n"); - } - else if ( v >= 30 && v <60 ) { - joyExKey |= MYOSD_UP;joyExKey |= MYOSD_RIGHT; - //printf("UpRight\n"); - } - else if ( v >= 60 && v < 120 ){ - joyExKey |= MYOSD_RIGHT; - //printf("Right\n"); - } - else if ( v >= 120 && v < 150 ){ - joyExKey |= MYOSD_RIGHT;joyExKey |= MYOSD_DOWN; - //printf("RightDown\n"); - } - else if ( v >= 150 && v < 210 ){ - joyExKey |= MYOSD_DOWN; - //printf("Down\n"); - } - else if ( v >= 210 && v < 240 ){ - joyExKey |= MYOSD_DOWN;joyExKey |= MYOSD_LEFT; - //printf("DownLeft\n"); - } - else if ( v >= 240 && v < 300 ){ - joyExKey |= MYOSD_LEFT; - //printf("Left\n"); - } - else if ( v >= 300 && v < 330 ){ - joyExKey |= MYOSD_LEFT; - joyExKey |= MYOSD_UP; - //printf("LeftUp\n"); - } - } - } - - if(cc->rjs.mag >= deadZone) - { - float v = cc->rjs.ang; - - if( v >= 330 || v < 30){ - joyExKey |= MYOSD_Y; - //printf("Y\n"); - } - else if ( v >= 30 && v <60 ) { - joyExKey |= MYOSD_Y;joyExKey |= MYOSD_B; - //printf("Y B\n"); - } - else if ( v >= 60 && v < 120 ){ - joyExKey |= MYOSD_B; - //printf("B\n"); - } - else if ( v >= 120 && v < 150 ){ - joyExKey |= MYOSD_B;joyExKey |= MYOSD_X; - //printf("B X\n"); - } - else if ( v >= 150 && v < 210 ){ - joyExKey |= MYOSD_X; - //printf("X\n"); - } - else if ( v >= 210 && v < 240 ){ - joyExKey |= MYOSD_X;joyExKey |= MYOSD_A; - //printf("X A\n"); - } - else if ( v >= 240 && v < 300 ){ - joyExKey |= MYOSD_A; - //printf("A\n"); - } - else if ( v >= 300 && v < 330 ){ - joyExKey |= MYOSD_A;joyExKey |= MYOSD_Y; - //printf("A Y\n"); - } - } -/* - printf("classic L button pressed: %f\n", cc->l_shoulder); - printf("classic R button pressed: %f\n", cc->r_shoulder); - - printf("classic left joystick angle: %f\n", cc->ljs.ang); - printf("classic left joystick magnitude: %f\n", cc->ljs.mag); - printf("classic left joystick rx: %f\n", cc->ljs.rx); - printf("classic left joystick ry: %f\n", cc->ljs.ry); - - printf("classic right joystick angle: %f\n", cc->rjs.ang); - printf("classic right joystick magnitude: %f\n", cc->rjs.mag); - printf("classic right rx: %f\n", cc->rjs.rx); - printf("classic right ry: %f\n", cc->rjs.ry); -*/ - } - return joyExKey; - } else { - joyExKey = 0; - return joyExKey; - } -} -#endif diff --git a/ios/RetroArch/BTStack/wiimote.h b/ios/RetroArch/BTStack/wiimote.h index ba58a97659..43f52002f3 100644 --- a/ios/RetroArch/BTStack/wiimote.h +++ b/ios/RetroArch/BTStack/wiimote.h @@ -276,8 +276,6 @@ extern "C" { extern int myosd_num_of_joys; -//devuelve un int haciendo polling de lo guardado en el wiimote -int iOS_wiimote_check (struct wiimote_t *wm); int wiimote_remove(uint16_t source_cid, bd_addr_t *addr); struct wiimote_t* wiimote_get_by_source_cid(uint16_t source_cid); int wiimote_handshake(struct wiimote_t* wm, byte event, byte* data, unsigned short len); diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 7d65312d86..cc9febac1e 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -353,7 +353,7 @@ - (IBAction)showWiiRemoteConfig { #ifdef WIIMOTE - [WiiMoteHelper startwiimote:_navigator]; + [[WiiMoteHelper get] showDiscovery]; #endif } diff --git a/ios/RetroArch/ios_input.m b/ios/RetroArch/ios_input.m index 723b64c91b..2e77d11166 100644 --- a/ios/RetroArch/ios_input.m +++ b/ios/RetroArch/ios_input.m @@ -165,10 +165,10 @@ static int16_t ios_input_state(void *data, const struct retro_keybind **binds, u case RETRO_DEVICE_ID_JOYPAD_B: return IS_PRESSED(wm, WIIMOTE_BUTTON_ONE); case RETRO_DEVICE_ID_JOYPAD_START: return IS_PRESSED(wm, WIIMOTE_BUTTON_PLUS); case RETRO_DEVICE_ID_JOYPAD_SELECT: return IS_PRESSED(wm, WIIMOTE_BUTTON_MINUS); - case RETRO_DEVICE_ID_JOYPAD_UP: return IS_PRESSED(wm, WIIMOTE_BUTTON_UP); - case RETRO_DEVICE_ID_JOYPAD_DOWN: return IS_PRESSED(wm, WIIMOTE_BUTTON_DOWN); - case RETRO_DEVICE_ID_JOYPAD_LEFT: return IS_PRESSED(wm, WIIMOTE_BUTTON_LEFT); - case RETRO_DEVICE_ID_JOYPAD_RIGHT: return IS_PRESSED(wm, WIIMOTE_BUTTON_RIGHT); + case RETRO_DEVICE_ID_JOYPAD_UP: return IS_PRESSED(wm, WIIMOTE_BUTTON_RIGHT); + case RETRO_DEVICE_ID_JOYPAD_DOWN: return IS_PRESSED(wm, WIIMOTE_BUTTON_LEFT); + case RETRO_DEVICE_ID_JOYPAD_LEFT: return IS_PRESSED(wm, WIIMOTE_BUTTON_UP); + case RETRO_DEVICE_ID_JOYPAD_RIGHT: return IS_PRESSED(wm, WIIMOTE_BUTTON_DOWN); } } #endif From b9dcfca07124d64f6ed4badbd4f16e8c507039b4 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 28 Feb 2013 20:15:10 -0500 Subject: [PATCH 085/108] ios: Add a Stop Bluetooth button to the navigation bar. --- ios/RetroArch/BTStack/WiiMoteHelper.h | 1 + ios/RetroArch/BTStack/WiiMoteHelper.m | 43 ++++++++++++++++++--------- ios/RetroArch/RetroArch_iOS.m | 22 +++++++++++++- 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/ios/RetroArch/BTStack/WiiMoteHelper.h b/ios/RetroArch/BTStack/WiiMoteHelper.h index 8964b5d61b..eef5dd6036 100644 --- a/ios/RetroArch/BTStack/WiiMoteHelper.h +++ b/ios/RetroArch/BTStack/WiiMoteHelper.h @@ -35,6 +35,7 @@ @interface WiiMoteHelper : NSObject + (WiiMoteHelper*)get; ++ (void)stopBluetooth; - (void)showDiscovery; @end diff --git a/ios/RetroArch/BTStack/WiiMoteHelper.m b/ios/RetroArch/BTStack/WiiMoteHelper.m index 83ce023447..1332a81762 100644 --- a/ios/RetroArch/BTStack/WiiMoteHelper.m +++ b/ios/RetroArch/BTStack/WiiMoteHelper.m @@ -44,10 +44,11 @@ #import "btstack/run_loop.h" #import "btstack/hci_cmds.h" -static BTDevice *device; -static uint16_t wiiMoteConHandle = 0; -static bool btOK; +static BTDiscoveryViewController* discoveryView; static WiiMoteHelper* instance; +static BTDevice *device; +static bool btOK; + @implementation WiiMoteHelper + (WiiMoteHelper*)get @@ -60,6 +61,23 @@ static WiiMoteHelper* instance; return instance; } ++ (void)stopBluetooth +{ + instance = nil; + myosd_num_of_joys = 0; + + if (btOK) + { + BTstackManager* bt = [BTstackManager sharedInstance]; + + [bt removeListener:discoveryView]; + discoveryView = nil; + + [[BTstackManager sharedInstance] deactivate]; + btOK = false; + } +} + - (id)init { if (!btOK) @@ -74,20 +92,17 @@ static WiiMoteHelper* instance; return self; } -- (void)dealloc -{ - // TODO: Any other cleanup needed - [[BTstackManager sharedInstance] deactivate]; -} - - (void)showDiscovery { - BTDiscoveryViewController* vc = [BTDiscoveryViewController new]; - [vc setDelegate:self]; + if (!discoveryView) + { + discoveryView = [BTDiscoveryViewController new]; + [discoveryView setDelegate:self]; - [[BTstackManager sharedInstance] addListener:vc]; + [[BTstackManager sharedInstance] addListener:discoveryView]; + } - [[RetroArch_iOS get] pushViewController:vc isGame:NO]; + [[RetroArch_iOS get] pushViewController:discoveryView isGame:NO]; } // BTStackManagerListener @@ -233,7 +248,7 @@ static WiiMoteHelper* instance; bt_flip_addr(event_addr, &packet[3]); uint16_t psm = READ_BT_16(packet, 11); uint16_t source_cid = READ_BT_16(packet, 13); - wiiMoteConHandle = READ_BT_16(packet, 9); + uint16_t wiiMoteConHandle = READ_BT_16(packet, 9); if (psm == 0x13) { diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index cc9febac1e..6b5467dc84 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -26,7 +26,7 @@ #define ALMOST_INVISIBLE .021f -@interface RANavigator : UINavigationController +@interface RANavigator : UINavigationController @end @implementation RANavigator @@ -37,6 +37,7 @@ - (id)initWithAppDelegate:(RetroArch_iOS*)delegate { self = [super init]; + self.delegate = self; assert(delegate); _delegate = delegate; @@ -59,6 +60,18 @@ [_delegate performSelector:@selector(screenDidRotate) withObject:nil afterDelay:.01f]; } +- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated +{ +#ifdef WIIMOTE + UIBarButtonItem* bbi = [[UIBarButtonItem alloc] + initWithTitle:@"Stop Bluetooth" + style:UIBarButtonItemStyleBordered + target:[RetroArch_iOS get] + action:@selector(stopBluetooth)]; + navigationController.topViewController.navigationItem.rightBarButtonItem = bbi; +#endif +} + @end @implementation RetroArch_iOS @@ -357,5 +370,12 @@ #endif } +- (IBAction)stopBluetooth +{ +#ifdef WIIMOTE + [WiiMoteHelper stopBluetooth]; +#endif +} + @end From 1178d82b5c02f1201771058f07ac5d80c20204a1 Mon Sep 17 00:00:00 2001 From: meancoot Date: Fri, 1 Mar 2013 19:02:55 -0500 Subject: [PATCH 086/108] ios: Don't show the 'Stop Bluetooth' button unless BTStack is running. --- ios/RetroArch/BTStack/WiiMoteHelper.h | 1 + ios/RetroArch/BTStack/WiiMoteHelper.m | 5 +++++ ios/RetroArch/RetroArch_iOS.m | 13 +++++++------ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/ios/RetroArch/BTStack/WiiMoteHelper.h b/ios/RetroArch/BTStack/WiiMoteHelper.h index eef5dd6036..37a63fb567 100644 --- a/ios/RetroArch/BTStack/WiiMoteHelper.h +++ b/ios/RetroArch/BTStack/WiiMoteHelper.h @@ -35,6 +35,7 @@ @interface WiiMoteHelper : NSObject + (WiiMoteHelper*)get; ++ (BOOL)isBluetoothRunning; + (void)stopBluetooth; - (void)showDiscovery; @end diff --git a/ios/RetroArch/BTStack/WiiMoteHelper.m b/ios/RetroArch/BTStack/WiiMoteHelper.m index 1332a81762..8fd79831f6 100644 --- a/ios/RetroArch/BTStack/WiiMoteHelper.m +++ b/ios/RetroArch/BTStack/WiiMoteHelper.m @@ -61,6 +61,11 @@ static bool btOK; return instance; } ++ (BOOL)isBluetoothRunning +{ + return btOK; +} + + (void)stopBluetooth { instance = nil; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 6b5467dc84..a8da608770 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -63,12 +63,12 @@ - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { #ifdef WIIMOTE - UIBarButtonItem* bbi = [[UIBarButtonItem alloc] - initWithTitle:@"Stop Bluetooth" - style:UIBarButtonItemStyleBordered - target:[RetroArch_iOS get] - action:@selector(stopBluetooth)]; - navigationController.topViewController.navigationItem.rightBarButtonItem = bbi; + navigationController.topViewController.navigationItem.rightBarButtonItem = (![WiiMoteHelper isBluetoothRunning]) ? nil : + [[UIBarButtonItem alloc] + initWithTitle:@"Stop Bluetooth" + style:UIBarButtonItemStyleBordered + target:[RetroArch_iOS get] + action:@selector(stopBluetooth)]; #endif } @@ -374,6 +374,7 @@ { #ifdef WIIMOTE [WiiMoteHelper stopBluetooth]; + [_navigator.topViewController.navigationItem setRightBarButtonItem:nil animated:YES]; #endif } From efa0e6be31fd9d069d891aed5c00797e323afed1 Mon Sep 17 00:00:00 2001 From: meancoot Date: Fri, 1 Mar 2013 19:08:43 -0500 Subject: [PATCH 087/108] ios: Rework RAModuleList so the name of the loaded game is displayed. --- ios/RetroArch/RAModuleList.m | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ios/RetroArch/RAModuleList.m b/ios/RetroArch/RAModuleList.m index e54ae1010f..14509497da 100644 --- a/ios/RetroArch/RAModuleList.m +++ b/ios/RetroArch/RAModuleList.m @@ -53,8 +53,7 @@ [_modules addObject:[RAModuleInfo moduleWithPath:modulePath data:[[RAConfig alloc] initWithPath:baseName]]]; } - [self setTitle:@"Choose Emulator"]; - + [self setTitle:[_game lastPathComponent]]; return self; } @@ -75,6 +74,11 @@ return _modules ? [_modules count] : 0; } +- (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section +{ + return @"Choose Emulator"; +} + - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"module"]; From 32e73b49131a17bd6469aac68859e6e556cab73d Mon Sep 17 00:00:00 2001 From: meancoot Date: Fri, 1 Mar 2013 21:01:52 -0500 Subject: [PATCH 088/108] ios: Add method for emulator cores to specify likely support level by inspecting file extensions. --- ios/RetroArch/RAModuleInfoList.m | 16 ++++++++ ios/RetroArch/RAModuleList.m | 63 +++++++++++++++++++++++--------- ios/RetroArch/views.h | 3 ++ 3 files changed, 64 insertions(+), 18 deletions(-) diff --git a/ios/RetroArch/RAModuleInfoList.m b/ios/RetroArch/RAModuleInfoList.m index 3419b8f5e7..8572567941 100644 --- a/ios/RetroArch/RAModuleInfoList.m +++ b/ios/RetroArch/RAModuleInfoList.m @@ -21,8 +21,24 @@ new.path = thePath; new.configPath = [NSString stringWithFormat:@"%@/%@.cfg", [RetroArch_iOS get].system_directory, [[thePath lastPathComponent] stringByDeletingPathExtension]]; new.data = theData; + + new.recommendedExtensions = [[theData getStringNamed:@"recommended_extensions" withDefault:@""] componentsSeparatedByString:@"|"]; + new.suggestedExtensions = [[theData getStringNamed:@"suggested_extensions" withDefault:@""] componentsSeparatedByString:@"|"]; return new; } + +- (unsigned)supportLevelOfPath:(NSString*)thePath +{ + NSString* ext = [thePath pathExtension]; + + if ([self.recommendedExtensions containsObject:ext]) + return 0; + else if([self.suggestedExtensions containsObject:ext]) + return 1; + + return 2; +} + @end static NSString* const labels[3] = {@"Emulator Name", @"Manufacturer", @"Name"}; diff --git a/ios/RetroArch/RAModuleList.m b/ios/RetroArch/RAModuleList.m index 14509497da..0894f1560e 100644 --- a/ios/RetroArch/RAModuleList.m +++ b/ios/RetroArch/RAModuleList.m @@ -17,7 +17,11 @@ @implementation RAModuleList { - NSMutableArray* _modules; + NSMutableArray* _modules[3]; + + unsigned _sectionCount; + unsigned _sectionMap[3]; + NSString* _game; } @@ -43,48 +47,71 @@ } // Load the modules with their data - _modules = [NSMutableArray arrayWithCapacity:[moduleList count]]; + _modules[0] = [NSMutableArray array]; + _modules[1] = [NSMutableArray array]; + _modules[2] = [NSMutableArray array]; for (int i = 0; i != [moduleList count]; i ++) { NSString* modulePath = [moduleList objectAtIndex:i]; - NSString* baseName = [[modulePath stringByDeletingPathExtension] stringByAppendingPathExtension:@"info"]; - [_modules addObject:[RAModuleInfo moduleWithPath:modulePath data:[[RAConfig alloc] initWithPath:baseName]]]; + + RAModuleInfo* module = [RAModuleInfo moduleWithPath:modulePath data:[[RAConfig alloc] initWithPath:baseName]]; + [_modules[[module supportLevelOfPath:_game]] addObject:module]; } + for (int i = 0; i != 3; i ++) + if ([_modules[i] count]) + { + _sectionMap[_sectionCount] = i; + _sectionCount ++; + } + [self setTitle:[_game lastPathComponent]]; return self; } +- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView +{ + return _sectionCount; +} + +- (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section +{ + switch (_sectionMap[section]) + { + case 0: return @"Recommended Emulators"; + case 1: return @"Suggested Emulators"; + default: return @"Other Emulators"; + } +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return _modules[section] ? [_modules[_sectionMap[section]] count] : 0; +} + - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - [RetroArch_iOS get].moduleInfo = (RAModuleInfo*)[_modules objectAtIndex:indexPath.row];; + unsigned section = _sectionMap[indexPath.section]; + [RetroArch_iOS get].moduleInfo = (RAModuleInfo*)[_modules[section] objectAtIndex:indexPath.row];; [[RetroArch_iOS get] runGame:_game]; } - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath { - [RetroArch_iOS get].moduleInfo = (RAModuleInfo*)[_modules objectAtIndex:indexPath.row]; + unsigned section = _sectionMap[indexPath.section]; + [RetroArch_iOS get].moduleInfo = (RAModuleInfo*)[_modules[section] objectAtIndex:indexPath.row]; [[RetroArch_iOS get] showSettings]; } -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -{ - return _modules ? [_modules count] : 0; -} - -- (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section -{ - return @"Choose Emulator"; -} - - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"module"]; cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"module"]; - - RAModuleInfo* info = (RAModuleInfo*)[_modules objectAtIndex:indexPath.row]; + + unsigned section = _sectionMap[indexPath.section]; + RAModuleInfo* info = (RAModuleInfo*)[_modules[section] objectAtIndex:indexPath.row]; cell.textLabel.text = [[info.path lastPathComponent] stringByDeletingPathExtension]; cell.accessoryType = (info.data) ? UITableViewCellAccessoryDetailDisclosureButton : UITableViewCellAccessoryNone; diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index 19b4cfb0ed..033fda5369 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -25,8 +25,11 @@ @property (strong) NSString* path; @property (strong) NSString* configPath; @property (strong) RAConfig* data; +@property (strong) NSArray* recommendedExtensions; +@property (strong) NSArray* suggestedExtensions; + (RAModuleInfo*)moduleWithPath:(NSString*)thePath data:(RAConfig*)theData; +- (unsigned)supportLevelOfPath:(NSString*)thePath; @end @interface RAModuleInfoList : UITableViewController From 55a8333ac2f2ce236f36849736a0123bd3bbb752 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sat, 2 Mar 2013 15:24:03 -0500 Subject: [PATCH 089/108] ios: Start to add wiimote remapping support. --- ios/RetroArch/settings/RAButtonGetter.m | 83 +++++++++++++++++----- ios/RetroArch/settings/RASettingsList.m | 5 +- ios/RetroArch/settings/RASettingsSubList.m | 23 ++++-- ios/RetroArch/settings/settings.h | 1 + 4 files changed, 85 insertions(+), 27 deletions(-) diff --git a/ios/RetroArch/settings/RAButtonGetter.m b/ios/RetroArch/settings/RAButtonGetter.m index 00ce7ea536..adfbde97f6 100644 --- a/ios/RetroArch/settings/RAButtonGetter.m +++ b/ios/RetroArch/settings/RAButtonGetter.m @@ -15,6 +15,10 @@ #import "settings.h" +#ifdef WIIMOTE +# include "../BTStack/wiimote.h" +#endif + extern NSString* const GSEventKeyUpNotification; static const struct @@ -89,46 +93,87 @@ static NSString* get_key_config_name(uint32_t hid_id) @implementation RAButtonGetter { - RAButtonGetter* me; - RASettingData* value; - UIAlertView* alert; - UITableView* view; + RAButtonGetter* _me; + RASettingData* _value; + UIAlertView* _alert; + UITableView* _view; + bool _finished; +#ifdef WIIMOTE + NSTimer* _btTimer; +#endif } - (id)initWithSetting:(RASettingData*)setting fromTable:(UITableView*)table { self = [super init]; - value = setting; - view = table; - me = self; + _value = setting; + _view = table; + _me = self; - alert = [[UIAlertView alloc] initWithTitle:@"RetroArch" - message:value.label + _alert = [[UIAlertView alloc] initWithTitle:@"RetroArch" + message:_value.label delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil]; - [alert show]; + [_alert show]; - [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyReleased:) name: GSEventKeyUpNotification object: nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(keyReleased:) name: GSEventKeyUpNotification object: nil]; + +#ifdef WIIMOTE + _btTimer = [NSTimer scheduledTimerWithTimeInterval:.05f target:self selector:@selector(checkWiiMote) userInfo:nil repeats:YES]; +#endif return self; } -- (void)alertView:(UIAlertView*)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex +- (void)finish { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - me = nil; + if (!_finished) + { + _finished = true; + +#ifdef WIIMOTE + [_btTimer invalidate]; +#endif + + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [_alert dismissWithClickedButtonIndex:0 animated:YES]; + [_view reloadData]; + + _me = nil; + } } +- (void)alertView:(UIAlertView*)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex +{ + [self finish]; +} + +#ifdef WIIMOTE +- (void)checkWiiMote +{ + for (int i = 0; i != myosd_num_of_joys; i ++) + { + for (int j = 0; j != sizeof(joys[i].btns) * 8; j ++) + { + if (joys[i].btns & (1 << j)) + { + _value.msubValues[1] = [NSString stringWithFormat:@"%d", j]; + [self finish]; + return; + } + } + } +} +#endif + - (void)keyReleased:(NSNotification*) notification { int keycode = [[notification.userInfo objectForKey:@"keycode"] intValue]; - - value.value = get_key_config_name(keycode); - - [alert dismissWithClickedButtonIndex:0 animated:YES]; - [view reloadData]; + _value.msubValues[0] = get_key_config_name(keycode); + + [self finish]; } @end diff --git a/ios/RetroArch/settings/RASettingsList.m b/ios/RetroArch/settings/RASettingsList.m index 282f2cba98..35d05de819 100644 --- a/ios/RetroArch/settings/RASettingsList.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -40,7 +40,10 @@ static RASettingData* button_setting(RAConfig* config, NSString* name, NSString* result.type = ButtonSetting; result.label = label; result.name = name; - result.value = get_value_from_config(config, name, defaultValue); + result.msubValues = [NSMutableArray arrayWithObjects: + get_value_from_config(config, name, defaultValue), + get_value_from_config(config, [name stringByAppendingString:@"_btn"], @""), + nil]; return result; } diff --git a/ios/RetroArch/settings/RASettingsSubList.m b/ios/RetroArch/settings/RASettingsSubList.m index b6b6ac0341..7bfe88638c 100644 --- a/ios/RetroArch/settings/RASettingsSubList.m +++ b/ios/RetroArch/settings/RASettingsSubList.m @@ -56,7 +56,14 @@ static const char* const SETTINGID = "SETTING"; else [config putStringNamed:setting.name value:@""]; break; - + + case ButtonSetting: + if (setting.msubValues[0] && [setting.msubValues[0] length]) + [config putStringNamed:setting.name value:setting.msubValues[0]]; + if (setting.msubValues[1] && [setting.msubValues[1] length]) + [config putStringNamed:[setting.name stringByAppendingString:@"_btn"] value:setting.msubValues[1]]; + break; + default: [config putStringNamed:setting.name value:setting.value]; break; @@ -129,11 +136,7 @@ static const char* const SETTINGID = "SETTING"; case ButtonSetting: { cell = [self.tableView dequeueReusableCellWithIdentifier:@"enumeration"]; - - if (cell == nil) - { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"enumeration"]; - } + cell = cell ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"enumeration"]; } break; @@ -151,7 +154,13 @@ static const char* const SETTINGID = "SETTING"; } cell.textLabel.text = setting.label; - cell.detailTextLabel.text = setting.value; + + if (setting.type != ButtonSetting) + cell.detailTextLabel.text = setting.value; + else + cell.detailTextLabel.text = [NSString stringWithFormat:@"[KB:%@] [JS:%@]", + [setting.msubValues[0] length] ? setting.msubValues[0] : @"N/A", + [setting.msubValues[1] length] ? setting.msubValues[1] : @"N/A"]; return cell; } diff --git a/ios/RetroArch/settings/settings.h b/ios/RetroArch/settings/settings.h index c1a0d6c811..c1b4e0f27b 100644 --- a/ios/RetroArch/settings/settings.h +++ b/ios/RetroArch/settings/settings.h @@ -27,6 +27,7 @@ enum SettingTypes @property (strong) NSString* path; @property (strong) NSArray* subValues; +@property (strong) NSMutableArray* msubValues; @end @interface RAButtonGetter : NSObject From 08e6634eefee954c1bf119274e18fe281afc527d Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 3 Mar 2013 18:50:38 -0500 Subject: [PATCH 090/108] ios: Clean up input code; make wiimote remapping work. --- ios/RetroArch.xcodeproj/project.pbxproj | 160 +++++---- ios/RetroArch/RetroArch_iOS.m | 3 +- ios/RetroArch/{ => input}/BTStack/BTDevice.h | 0 ios/RetroArch/{ => input}/BTStack/BTDevice.m | 0 .../BTStack/BTDiscoveryViewController.h | 0 .../BTStack/BTDiscoveryViewController.m | 0 .../{ => input}/BTStack/BTstackManager.h | 0 .../{ => input}/BTStack/BTstackManager.m | 0 .../{ => input}/BTStack/WiiMoteHelper.h | 0 .../{ => input}/BTStack/WiiMoteHelper.m | 0 .../{ => input}/BTStack/btstack/btstack.h | 0 .../{ => input}/BTStack/btstack/hci_cmds.h | 0 .../{ => input}/BTStack/btstack/linked_list.h | 0 .../{ => input}/BTStack/btstack/run_loop.h | 0 .../{ => input}/BTStack/btstack/sdp_util.h | 0 .../{ => input}/BTStack/btstack/utils.h | 0 .../{ => input}/BTStack/libBTstack.dylib | Bin ios/RetroArch/{ => input}/BTStack/wiimote.c | 0 ios/RetroArch/{ => input}/BTStack/wiimote.h | 0 ios/RetroArch/input/RAInputResponder.h | 32 ++ ios/RetroArch/input/RAInputResponder.m | 94 ++++++ ios/RetroArch/input/ios_input.m | 198 +++++++++++ ios/RetroArch/input/ios_joypad.m | 68 ++++ ios/RetroArch/ios_input.m | 314 ------------------ ios/RetroArch/settings/RAButtonGetter.m | 2 +- 25 files changed, 484 insertions(+), 387 deletions(-) rename ios/RetroArch/{ => input}/BTStack/BTDevice.h (100%) rename ios/RetroArch/{ => input}/BTStack/BTDevice.m (100%) rename ios/RetroArch/{ => input}/BTStack/BTDiscoveryViewController.h (100%) rename ios/RetroArch/{ => input}/BTStack/BTDiscoveryViewController.m (100%) rename ios/RetroArch/{ => input}/BTStack/BTstackManager.h (100%) rename ios/RetroArch/{ => input}/BTStack/BTstackManager.m (100%) rename ios/RetroArch/{ => input}/BTStack/WiiMoteHelper.h (100%) rename ios/RetroArch/{ => input}/BTStack/WiiMoteHelper.m (100%) rename ios/RetroArch/{ => input}/BTStack/btstack/btstack.h (100%) rename ios/RetroArch/{ => input}/BTStack/btstack/hci_cmds.h (100%) rename ios/RetroArch/{ => input}/BTStack/btstack/linked_list.h (100%) rename ios/RetroArch/{ => input}/BTStack/btstack/run_loop.h (100%) rename ios/RetroArch/{ => input}/BTStack/btstack/sdp_util.h (100%) rename ios/RetroArch/{ => input}/BTStack/btstack/utils.h (100%) rename ios/RetroArch/{ => input}/BTStack/libBTstack.dylib (100%) rename ios/RetroArch/{ => input}/BTStack/wiimote.c (100%) rename ios/RetroArch/{ => input}/BTStack/wiimote.h (100%) create mode 100644 ios/RetroArch/input/RAInputResponder.h create mode 100644 ios/RetroArch/input/RAInputResponder.m create mode 100644 ios/RetroArch/input/ios_input.m create mode 100644 ios/RetroArch/input/ios_joypad.m delete mode 100644 ios/RetroArch/ios_input.m diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 1b23d66ec3..ce99c09df0 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -8,12 +8,6 @@ /* Begin PBXBuildFile section */ 96096DD816D1ABAF00BF4499 /* RAModuleInfoList.m in Sources */ = {isa = PBXBuildFile; fileRef = 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */; }; - 960DB2C416E0193D00F977E3 /* BTstackManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 960DB2C216E0193D00F977E3 /* BTstackManager.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 960DB2C716E0197600F977E3 /* BTDiscoveryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 960DB2C616E0197600F977E3 /* BTDiscoveryViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 9614C6BB16DD7C00000B36EF /* BTDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6AE16DD7C00000B36EF /* BTDevice.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 9614C6BD16DD7C00000B36EF /* libBTstack.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 9614C6B816DD7C00000B36EF /* libBTstack.dylib */; }; - 9614C6BE16DD7C00000B36EF /* WiiMoteHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6BA16DD7C00000B36EF /* WiiMoteHelper.m */; }; - 9614C6C116DD7D54000B36EF /* wiimote.c in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6BF16DD7D54000B36EF /* wiimote.c */; }; 9614C6C416DDC018000B36EF /* autosave.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAE9D16C1D9A9009DE44C /* autosave.c */; }; 9614C6C516DDC018000B36EF /* cheats.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEA016C1D9A9009DE44C /* cheats.c */; }; 9614C6C616DDC018000B36EF /* command.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEA216C1D9A9009DE44C /* command.c */; }; @@ -74,7 +68,6 @@ 9614C6FD16DDC018000B36EF /* RADirectoryGrid.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2316D453BA00FE8D5A /* RADirectoryGrid.m */; }; 9614C6FE16DDC018000B36EF /* browser.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2816D5A56400FE8D5A /* browser.m */; }; 9614C6FF16DDC018000B36EF /* RAConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2F16D7045700FE8D5A /* RAConfig.m */; }; - 9614C70016DDC018000B36EF /* ios_input.m in Sources */ = {isa = PBXBuildFile; fileRef = 965AE29D16D9BF94001D7667 /* ios_input.m */; }; 9614C70616DDC018000B36EF /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */; }; 9614C70716DDC018000B36EF /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5416C9AC3300D64A22 /* CoreAudio.framework */; }; 9614C70816DDC018000B36EF /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAF2116C1DF88009DE44C /* libz.dylib */; }; @@ -114,8 +107,18 @@ 963F5AC716CC523B009BBD19 /* RADirectoryList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC416CC523B009BBD19 /* RADirectoryList.m */; }; 963F5AC816CC523B009BBD19 /* RAGameView.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC516CC523B009BBD19 /* RAGameView.m */; }; 963F5AC916CC523B009BBD19 /* RAModuleList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC616CC523B009BBD19 /* RAModuleList.m */; }; - 965AE29E16D9BF94001D7667 /* ios_input.m in Sources */ = {isa = PBXBuildFile; fileRef = 965AE29D16D9BF94001D7667 /* ios_input.m */; }; 965AE2A016DA83C1001D7667 /* PauseIndicatorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 965AE29F16DA83C1001D7667 /* PauseIndicatorView.xib */; }; + 966B9C8A16E40D44005B61E1 /* ios_input.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C8616E40D44005B61E1 /* ios_input.m */; }; + 966B9C8B16E40D44005B61E1 /* ios_joypad.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C8716E40D44005B61E1 /* ios_joypad.m */; }; + 966B9C8C16E40D44005B61E1 /* RAInputResponder.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C8916E40D44005B61E1 /* RAInputResponder.m */; }; + 966B9C8D16E40EFC005B61E1 /* RAInputResponder.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C8916E40D44005B61E1 /* RAInputResponder.m */; }; + 966B9C8E16E40F00005B61E1 /* ios_input.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C8616E40D44005B61E1 /* ios_input.m */; }; + 966B9CA216E418B7005B61E1 /* BTDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C9116E418B7005B61E1 /* BTDevice.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 966B9CA316E418B7005B61E1 /* BTDiscoveryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C9316E418B7005B61E1 /* BTDiscoveryViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 966B9CA416E418B7005B61E1 /* BTstackManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C9C16E418B7005B61E1 /* BTstackManager.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 966B9CA516E418B7005B61E1 /* libBTstack.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 966B9C9D16E418B7005B61E1 /* libBTstack.dylib */; }; + 966B9CA616E418B7005B61E1 /* wiimote.c in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C9E16E418B7005B61E1 /* wiimote.c */; }; + 966B9CA716E418B7005B61E1 /* WiiMoteHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9CA116E418B7005B61E1 /* WiiMoteHelper.m */; }; 969EBF6A16D95746003787A2 /* PauseView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 969EBF6916D95746003787A2 /* PauseView.xib */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; @@ -177,23 +180,6 @@ /* Begin PBXFileReference section */ 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAModuleInfoList.m; sourceTree = ""; }; - 960DB2C216E0193D00F977E3 /* BTstackManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTstackManager.m; sourceTree = ""; }; - 960DB2C316E0193D00F977E3 /* BTstackManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTstackManager.h; sourceTree = ""; }; - 960DB2C516E0197500F977E3 /* BTDiscoveryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTDiscoveryViewController.h; sourceTree = ""; }; - 960DB2C616E0197600F977E3 /* BTDiscoveryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTDiscoveryViewController.m; sourceTree = ""; }; - 9614C6AD16DD7C00000B36EF /* BTDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTDevice.h; sourceTree = ""; }; - 9614C6AE16DD7C00000B36EF /* BTDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTDevice.m; sourceTree = ""; }; - 9614C6B216DD7C00000B36EF /* btstack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = btstack.h; sourceTree = ""; }; - 9614C6B316DD7C00000B36EF /* hci_cmds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hci_cmds.h; sourceTree = ""; }; - 9614C6B416DD7C00000B36EF /* linked_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linked_list.h; sourceTree = ""; }; - 9614C6B516DD7C00000B36EF /* run_loop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = run_loop.h; sourceTree = ""; }; - 9614C6B616DD7C00000B36EF /* sdp_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sdp_util.h; sourceTree = ""; }; - 9614C6B716DD7C00000B36EF /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = ""; }; - 9614C6B816DD7C00000B36EF /* libBTstack.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libBTstack.dylib; sourceTree = ""; }; - 9614C6B916DD7C00000B36EF /* WiiMoteHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WiiMoteHelper.h; sourceTree = ""; }; - 9614C6BA16DD7C00000B36EF /* WiiMoteHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WiiMoteHelper.m; sourceTree = ""; }; - 9614C6BF16DD7D54000B36EF /* wiimote.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wiimote.c; sourceTree = ""; }; - 9614C6C016DD7D54000B36EF /* wiimote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wiimote.h; sourceTree = ""; }; 9614C71E16DDC018000B36EF /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 9614C71F16DDC018000B36EF /* RetroArch copy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "RetroArch copy-Info.plist"; path = "/Users/jason/Documents/Projects/ios/RetroArch/ios/RetroArch copy-Info.plist"; sourceTree = ""; }; 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioseagl_ctx.c; sourceTree = ""; }; @@ -217,8 +203,28 @@ 963F5AC416CC523B009BBD19 /* RADirectoryList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RADirectoryList.m; sourceTree = ""; }; 963F5AC516CC523B009BBD19 /* RAGameView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAGameView.m; sourceTree = ""; }; 963F5AC616CC523B009BBD19 /* RAModuleList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAModuleList.m; sourceTree = ""; }; - 965AE29D16D9BF94001D7667 /* ios_input.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ios_input.m; sourceTree = ""; }; 965AE29F16DA83C1001D7667 /* PauseIndicatorView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PauseIndicatorView.xib; sourceTree = ""; }; + 966B9C8616E40D44005B61E1 /* ios_input.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ios_input.m; sourceTree = ""; }; + 966B9C8716E40D44005B61E1 /* ios_joypad.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ios_joypad.m; sourceTree = ""; }; + 966B9C8816E40D44005B61E1 /* RAInputResponder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RAInputResponder.h; sourceTree = ""; }; + 966B9C8916E40D44005B61E1 /* RAInputResponder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAInputResponder.m; sourceTree = ""; }; + 966B9C9016E418B7005B61E1 /* BTDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTDevice.h; sourceTree = ""; }; + 966B9C9116E418B7005B61E1 /* BTDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTDevice.m; sourceTree = ""; }; + 966B9C9216E418B7005B61E1 /* BTDiscoveryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTDiscoveryViewController.h; sourceTree = ""; }; + 966B9C9316E418B7005B61E1 /* BTDiscoveryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTDiscoveryViewController.m; sourceTree = ""; }; + 966B9C9516E418B7005B61E1 /* btstack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = btstack.h; sourceTree = ""; }; + 966B9C9616E418B7005B61E1 /* hci_cmds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hci_cmds.h; sourceTree = ""; }; + 966B9C9716E418B7005B61E1 /* linked_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linked_list.h; sourceTree = ""; }; + 966B9C9816E418B7005B61E1 /* run_loop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = run_loop.h; sourceTree = ""; }; + 966B9C9916E418B7005B61E1 /* sdp_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sdp_util.h; sourceTree = ""; }; + 966B9C9A16E418B7005B61E1 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = ""; }; + 966B9C9B16E418B7005B61E1 /* BTstackManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTstackManager.h; sourceTree = ""; }; + 966B9C9C16E418B7005B61E1 /* BTstackManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTstackManager.m; sourceTree = ""; }; + 966B9C9D16E418B7005B61E1 /* libBTstack.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libBTstack.dylib; sourceTree = ""; }; + 966B9C9E16E418B7005B61E1 /* wiimote.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wiimote.c; sourceTree = ""; }; + 966B9C9F16E418B7005B61E1 /* wiimote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wiimote.h; sourceTree = ""; }; + 966B9CA016E418B7005B61E1 /* WiiMoteHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WiiMoteHelper.h; sourceTree = ""; }; + 966B9CA116E418B7005B61E1 /* WiiMoteHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WiiMoteHelper.m; sourceTree = ""; }; 969EBF6916D95746003787A2 /* PauseView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PauseView.xib; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; @@ -372,45 +378,13 @@ 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */, 96AFAE3016C1D4EA009DE44C /* GLKit.framework in Frameworks */, 96AFAE3216C1D4EA009DE44C /* OpenGLES.framework in Frameworks */, - 9614C6BD16DD7C00000B36EF /* libBTstack.dylib in Frameworks */, + 966B9CA516E418B7005B61E1 /* libBTstack.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 9614C6AC16DD7C00000B36EF /* BTStack */ = { - isa = PBXGroup; - children = ( - 9614C6B116DD7C00000B36EF /* btstack */, - 9614C6AD16DD7C00000B36EF /* BTDevice.h */, - 9614C6AE16DD7C00000B36EF /* BTDevice.m */, - 960DB2C516E0197500F977E3 /* BTDiscoveryViewController.h */, - 960DB2C616E0197600F977E3 /* BTDiscoveryViewController.m */, - 960DB2C216E0193D00F977E3 /* BTstackManager.m */, - 960DB2C316E0193D00F977E3 /* BTstackManager.h */, - 9614C6B816DD7C00000B36EF /* libBTstack.dylib */, - 9614C6B916DD7C00000B36EF /* WiiMoteHelper.h */, - 9614C6BA16DD7C00000B36EF /* WiiMoteHelper.m */, - 9614C6BF16DD7D54000B36EF /* wiimote.c */, - 9614C6C016DD7D54000B36EF /* wiimote.h */, - ); - path = BTStack; - sourceTree = ""; - }; - 9614C6B116DD7C00000B36EF /* btstack */ = { - isa = PBXGroup; - children = ( - 9614C6B216DD7C00000B36EF /* btstack.h */, - 9614C6B316DD7C00000B36EF /* hci_cmds.h */, - 9614C6B416DD7C00000B36EF /* linked_list.h */, - 9614C6B516DD7C00000B36EF /* run_loop.h */, - 9614C6B616DD7C00000B36EF /* sdp_util.h */, - 9614C6B716DD7C00000B36EF /* utils.h */, - ); - path = btstack; - sourceTree = ""; - }; 96366C6F16CAF62200D64A22 /* settings */ = { isa = PBXGroup; children = ( @@ -423,6 +397,50 @@ path = settings; sourceTree = ""; }; + 966B9C8516E40D44005B61E1 /* input */ = { + isa = PBXGroup; + children = ( + 966B9C8F16E418B7005B61E1 /* BTStack */, + 966B9C8616E40D44005B61E1 /* ios_input.m */, + 966B9C8716E40D44005B61E1 /* ios_joypad.m */, + 966B9C8816E40D44005B61E1 /* RAInputResponder.h */, + 966B9C8916E40D44005B61E1 /* RAInputResponder.m */, + ); + path = input; + sourceTree = ""; + }; + 966B9C8F16E418B7005B61E1 /* BTStack */ = { + isa = PBXGroup; + children = ( + 966B9C9016E418B7005B61E1 /* BTDevice.h */, + 966B9C9116E418B7005B61E1 /* BTDevice.m */, + 966B9C9216E418B7005B61E1 /* BTDiscoveryViewController.h */, + 966B9C9316E418B7005B61E1 /* BTDiscoveryViewController.m */, + 966B9C9416E418B7005B61E1 /* btstack */, + 966B9C9B16E418B7005B61E1 /* BTstackManager.h */, + 966B9C9C16E418B7005B61E1 /* BTstackManager.m */, + 966B9C9D16E418B7005B61E1 /* libBTstack.dylib */, + 966B9C9E16E418B7005B61E1 /* wiimote.c */, + 966B9C9F16E418B7005B61E1 /* wiimote.h */, + 966B9CA016E418B7005B61E1 /* WiiMoteHelper.h */, + 966B9CA116E418B7005B61E1 /* WiiMoteHelper.m */, + ); + path = BTStack; + sourceTree = ""; + }; + 966B9C9416E418B7005B61E1 /* btstack */ = { + isa = PBXGroup; + children = ( + 966B9C9516E418B7005B61E1 /* btstack.h */, + 966B9C9616E418B7005B61E1 /* hci_cmds.h */, + 966B9C9716E418B7005B61E1 /* linked_list.h */, + 966B9C9816E418B7005B61E1 /* run_loop.h */, + 966B9C9916E418B7005B61E1 /* sdp_util.h */, + 966B9C9A16E418B7005B61E1 /* utils.h */, + ); + path = btstack; + sourceTree = ""; + }; 96AFAE1A16C1D4EA009DE44C = { isa = PBXGroup; children = ( @@ -466,7 +484,7 @@ 96AFAE3316C1D4EA009DE44C /* RetroArch */ = { isa = PBXGroup; children = ( - 9614C6AC16DD7C00000B36EF /* BTStack */, + 966B9C8516E40D44005B61E1 /* input */, 96C19C2716D455C600FE8D5A /* Browser */, 96366C6F16CAF62200D64A22 /* settings */, 96AFAE3416C1D4EA009DE44C /* Supporting Files */, @@ -478,7 +496,6 @@ 96C19C2616D455BE00FE8D5A /* rarch_wrapper.h */, 96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */, 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */, - 965AE29D16D9BF94001D7667 /* ios_input.m */, 96297A0D16C5ADDA00E6DCE0 /* views.h */, 969EBF6916D95746003787A2 /* PauseView.xib */, 965AE29F16DA83C1001D7667 /* PauseIndicatorView.xib */, @@ -892,7 +909,8 @@ 9614C6FD16DDC018000B36EF /* RADirectoryGrid.m in Sources */, 9614C6FE16DDC018000B36EF /* browser.m in Sources */, 9614C6FF16DDC018000B36EF /* RAConfig.m in Sources */, - 9614C70016DDC018000B36EF /* ios_input.m in Sources */, + 966B9C8D16E40EFC005B61E1 /* RAInputResponder.m in Sources */, + 966B9C8E16E40F00005B61E1 /* ios_input.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -960,12 +978,14 @@ 96C19C2416D453BA00FE8D5A /* RADirectoryGrid.m in Sources */, 96C19C2916D5A56500FE8D5A /* browser.m in Sources */, 96C19C3016D7045700FE8D5A /* RAConfig.m in Sources */, - 965AE29E16D9BF94001D7667 /* ios_input.m in Sources */, - 9614C6BB16DD7C00000B36EF /* BTDevice.m in Sources */, - 9614C6BE16DD7C00000B36EF /* WiiMoteHelper.m in Sources */, - 9614C6C116DD7D54000B36EF /* wiimote.c in Sources */, - 960DB2C416E0193D00F977E3 /* BTstackManager.m in Sources */, - 960DB2C716E0197600F977E3 /* BTDiscoveryViewController.m in Sources */, + 966B9C8A16E40D44005B61E1 /* ios_input.m in Sources */, + 966B9C8B16E40D44005B61E1 /* ios_joypad.m in Sources */, + 966B9C8C16E40D44005B61E1 /* RAInputResponder.m in Sources */, + 966B9CA216E418B7005B61E1 /* BTDevice.m in Sources */, + 966B9CA316E418B7005B61E1 /* BTDiscoveryViewController.m in Sources */, + 966B9CA416E418B7005B61E1 /* BTstackManager.m in Sources */, + 966B9CA616E418B7005B61E1 /* wiimote.c in Sources */, + 966B9CA716E418B7005B61E1 /* WiiMoteHelper.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1163,7 +1183,7 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"", - "\"$(SRCROOT)/RetroArch/BTStack\"", + "\"$(SRCROOT)/RetroArch/input/BTStack\"", ); OTHER_CFLAGS = ( "-DHAVE_RARCH_MAIN_WRAP", @@ -1201,7 +1221,7 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"", - "\"$(SRCROOT)/RetroArch/BTStack\"", + "\"$(SRCROOT)/RetroArch/input/BTStack\"", ); OTHER_CFLAGS = ( "-DNS_BLOCK_ASSERTIONS=1", diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index a8da608770..873e6fb049 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -19,8 +19,7 @@ #import "browser.h" #ifdef WIIMOTE -#include "BTStack/wiimote.h" -#import "BTStack/WiiMoteHelper.h" +#import "input/BTStack/WiiMoteHelper.h" #endif diff --git a/ios/RetroArch/BTStack/BTDevice.h b/ios/RetroArch/input/BTStack/BTDevice.h similarity index 100% rename from ios/RetroArch/BTStack/BTDevice.h rename to ios/RetroArch/input/BTStack/BTDevice.h diff --git a/ios/RetroArch/BTStack/BTDevice.m b/ios/RetroArch/input/BTStack/BTDevice.m similarity index 100% rename from ios/RetroArch/BTStack/BTDevice.m rename to ios/RetroArch/input/BTStack/BTDevice.m diff --git a/ios/RetroArch/BTStack/BTDiscoveryViewController.h b/ios/RetroArch/input/BTStack/BTDiscoveryViewController.h similarity index 100% rename from ios/RetroArch/BTStack/BTDiscoveryViewController.h rename to ios/RetroArch/input/BTStack/BTDiscoveryViewController.h diff --git a/ios/RetroArch/BTStack/BTDiscoveryViewController.m b/ios/RetroArch/input/BTStack/BTDiscoveryViewController.m similarity index 100% rename from ios/RetroArch/BTStack/BTDiscoveryViewController.m rename to ios/RetroArch/input/BTStack/BTDiscoveryViewController.m diff --git a/ios/RetroArch/BTStack/BTstackManager.h b/ios/RetroArch/input/BTStack/BTstackManager.h similarity index 100% rename from ios/RetroArch/BTStack/BTstackManager.h rename to ios/RetroArch/input/BTStack/BTstackManager.h diff --git a/ios/RetroArch/BTStack/BTstackManager.m b/ios/RetroArch/input/BTStack/BTstackManager.m similarity index 100% rename from ios/RetroArch/BTStack/BTstackManager.m rename to ios/RetroArch/input/BTStack/BTstackManager.m diff --git a/ios/RetroArch/BTStack/WiiMoteHelper.h b/ios/RetroArch/input/BTStack/WiiMoteHelper.h similarity index 100% rename from ios/RetroArch/BTStack/WiiMoteHelper.h rename to ios/RetroArch/input/BTStack/WiiMoteHelper.h diff --git a/ios/RetroArch/BTStack/WiiMoteHelper.m b/ios/RetroArch/input/BTStack/WiiMoteHelper.m similarity index 100% rename from ios/RetroArch/BTStack/WiiMoteHelper.m rename to ios/RetroArch/input/BTStack/WiiMoteHelper.m diff --git a/ios/RetroArch/BTStack/btstack/btstack.h b/ios/RetroArch/input/BTStack/btstack/btstack.h similarity index 100% rename from ios/RetroArch/BTStack/btstack/btstack.h rename to ios/RetroArch/input/BTStack/btstack/btstack.h diff --git a/ios/RetroArch/BTStack/btstack/hci_cmds.h b/ios/RetroArch/input/BTStack/btstack/hci_cmds.h similarity index 100% rename from ios/RetroArch/BTStack/btstack/hci_cmds.h rename to ios/RetroArch/input/BTStack/btstack/hci_cmds.h diff --git a/ios/RetroArch/BTStack/btstack/linked_list.h b/ios/RetroArch/input/BTStack/btstack/linked_list.h similarity index 100% rename from ios/RetroArch/BTStack/btstack/linked_list.h rename to ios/RetroArch/input/BTStack/btstack/linked_list.h diff --git a/ios/RetroArch/BTStack/btstack/run_loop.h b/ios/RetroArch/input/BTStack/btstack/run_loop.h similarity index 100% rename from ios/RetroArch/BTStack/btstack/run_loop.h rename to ios/RetroArch/input/BTStack/btstack/run_loop.h diff --git a/ios/RetroArch/BTStack/btstack/sdp_util.h b/ios/RetroArch/input/BTStack/btstack/sdp_util.h similarity index 100% rename from ios/RetroArch/BTStack/btstack/sdp_util.h rename to ios/RetroArch/input/BTStack/btstack/sdp_util.h diff --git a/ios/RetroArch/BTStack/btstack/utils.h b/ios/RetroArch/input/BTStack/btstack/utils.h similarity index 100% rename from ios/RetroArch/BTStack/btstack/utils.h rename to ios/RetroArch/input/BTStack/btstack/utils.h diff --git a/ios/RetroArch/BTStack/libBTstack.dylib b/ios/RetroArch/input/BTStack/libBTstack.dylib similarity index 100% rename from ios/RetroArch/BTStack/libBTstack.dylib rename to ios/RetroArch/input/BTStack/libBTstack.dylib diff --git a/ios/RetroArch/BTStack/wiimote.c b/ios/RetroArch/input/BTStack/wiimote.c similarity index 100% rename from ios/RetroArch/BTStack/wiimote.c rename to ios/RetroArch/input/BTStack/wiimote.c diff --git a/ios/RetroArch/BTStack/wiimote.h b/ios/RetroArch/input/BTStack/wiimote.h similarity index 100% rename from ios/RetroArch/BTStack/wiimote.h rename to ios/RetroArch/input/BTStack/wiimote.h diff --git a/ios/RetroArch/input/RAInputResponder.h b/ios/RetroArch/input/RAInputResponder.h new file mode 100644 index 0000000000..3ad909f25f --- /dev/null +++ b/ios/RetroArch/input/RAInputResponder.h @@ -0,0 +1,32 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +// Input responder +#define MAX_TOUCHES 16 +#define MAX_KEYS 256 + +typedef struct touch_data +{ + bool is_down; + int16_t screen_x, screen_y; + int16_t fixed_x, fixed_y; + int16_t full_x, full_y; +} touch_data_t; + +@interface RAInputResponder : NSObject +- (void)poll; +- (bool)isKeyPressed:(unsigned)index; +- (const touch_data_t*)getTouchDataAtIndex:(unsigned)index; +@end diff --git a/ios/RetroArch/input/RAInputResponder.m b/ios/RetroArch/input/RAInputResponder.m new file mode 100644 index 0000000000..5951a17813 --- /dev/null +++ b/ios/RetroArch/input/RAInputResponder.m @@ -0,0 +1,94 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#import "RAInputResponder.h" +#include "input/input_common.h" + +extern NSString* const GSEventKeyDownNotification; +extern NSString* const GSEventKeyUpNotification; +extern NSString* const RATouchNotification; + +@implementation RAInputResponder +{ + unsigned _touchCount; + touch_data_t _touches[MAX_TOUCHES]; + bool _keys[MAX_KEYS]; +} + +-(id)init +{ + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyPressed:) name: GSEventKeyDownNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyReleased:) name: GSEventKeyUpNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleTouches:) name: RATouchNotification object:nil]; + return self; +} + +-(void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)poll +{ + for (int i = 0; i != _touchCount; i ++) + { + input_translate_coord_viewport(_touches[i].screen_x, _touches[i].screen_y, + &_touches[i].fixed_x, &_touches[i].fixed_y, + &_touches[i].full_x, &_touches[i].full_y); + } +} + +- (bool)isKeyPressed:(unsigned)index +{ + return (index < MAX_KEYS) ? _keys[index] : NO; +} + +- (const touch_data_t*)getTouchDataAtIndex:(unsigned)index +{ + return (index < MAX_TOUCHES && _touches[index].is_down) ? &_touches[index] : 0; +} + +// Response handlers +- (void)keyPressed:(NSNotification*)notification +{ + int keycode = [[notification.userInfo objectForKey:@"keycode"] intValue]; + if (keycode < MAX_KEYS) _keys[keycode] = true; +} + +- (void)keyReleased:(NSNotification*)notification +{ + int keycode = [[notification.userInfo objectForKey:@"keycode"] intValue]; + if (keycode < MAX_KEYS) _keys[keycode] = false; +} + +- (void)handleTouches:(NSNotification*)notification +{ + UIEvent* event = [notification.userInfo objectForKey:@"event"]; + NSArray* touches = [[event allTouches] allObjects]; + + _touchCount = [touches count]; + + for(int i = 0; i != _touchCount; i ++) + { + UITouch *touch = [touches objectAtIndex:i]; + CGPoint coord = [touch locationInView:touch.view]; + float scale = [[UIScreen mainScreen] scale]; + + _touches[i].is_down = (touch.phase != UITouchPhaseEnded) && (touch.phase != UITouchPhaseCancelled); + _touches[i].screen_x = coord.x * scale; + _touches[i].screen_y = coord.y * scale; + } +} +@end diff --git a/ios/RetroArch/input/ios_input.m b/ios/RetroArch/input/ios_input.m new file mode 100644 index 0000000000..01a4664d20 --- /dev/null +++ b/ios/RetroArch/input/ios_input.m @@ -0,0 +1,198 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#import "RAInputResponder.h" + +#include +#include "input/input_common.h" +#include "general.h" +#include "driver.h" + +#ifdef WIIMOTE +extern const rarch_joypad_driver_t ios_joypad; +static const rarch_joypad_driver_t* const g_joydriver = &ios_joypad; +#else +static const rarch_joypad_driver_t* const g_joydriver = 0; +#endif + +static const struct rarch_key_map rarch_key_map_hidusage[]; + +static RAInputResponder* g_input_driver; + +// Non-exported helpers +static bool ios_key_pressed(enum retro_key key) +{ + if ((int)key >= 0 && key < RETROK_LAST) + { + return [g_input_driver isKeyPressed:input_translate_rk_to_keysym(key)]; + } + + return false; +} + +static bool ios_is_pressed(unsigned port_num, const struct retro_keybind *key) +{ + return ios_key_pressed(key->key) || input_joypad_pressed(g_joydriver, port_num, key); +} + +// Exported input driver +static void *ios_input_init(void) +{ + input_init_keyboard_lut(rarch_key_map_hidusage); + g_input_driver = [RAInputResponder new]; + return (void*)-1; +} + +static void ios_input_poll(void *data) +{ + [g_input_driver poll]; + input_joypad_poll(g_joydriver); +} + +static int16_t ios_input_state(void *data, const struct retro_keybind **binds, unsigned port, unsigned device, unsigned index, unsigned id) +{ + switch (device) + { + case RETRO_DEVICE_JOYPAD: + return (id < RARCH_BIND_LIST_END) ? ios_is_pressed(port, &binds[port][id]) : false; + + case RARCH_DEVICE_POINTER_SCREEN: + { + const touch_data_t* touch = [g_input_driver getTouchDataAtIndex:index]; + + switch (id) + { + case RETRO_DEVICE_ID_POINTER_X: return touch ? touch->full_x : 0; + case RETRO_DEVICE_ID_POINTER_Y: return touch ? touch->full_y : 0; + case RETRO_DEVICE_ID_POINTER_PRESSED: return touch ? 1 : 0; + } + + return 0; + } + + default: + return 0; + } +} + +static bool ios_bind_button_pressed(void *data, int key) +{ + const struct retro_keybind *binds = g_settings.input.binds[0]; + return (key >= 0 && key < RARCH_BIND_LIST_END) ? ios_is_pressed(0, &binds[key]) : false; +} + +static void ios_input_free_input(void *data) +{ + (void)data; + g_input_driver = nil; +} + +const input_driver_t input_ios = { + ios_input_init, + ios_input_poll, + ios_input_state, + ios_bind_button_pressed, + ios_input_free_input, + "ios_input", +}; + +// Key table +static const struct rarch_key_map rarch_key_map_hidusage[] = { + { 0x50, RETROK_LEFT }, + { 0x4F, RETROK_RIGHT }, + { 0x52, RETROK_UP }, + { 0x51, RETROK_DOWN }, + { 0x28, RETROK_RETURN }, + { 0x2B, RETROK_TAB }, + { 0x49, RETROK_INSERT }, + { 0x4C, RETROK_DELETE }, + { 0xE5, RETROK_RSHIFT }, + { 0xE1, RETROK_LSHIFT }, + { 0xE0, RETROK_LCTRL }, + { 0x4D, RETROK_END }, + { 0x4A, RETROK_HOME }, + { 0x4E, RETROK_PAGEDOWN }, + { 0x4B, RETROK_PAGEUP }, + { 0xE2, RETROK_LALT }, + { 0x2C, RETROK_SPACE }, + { 0x29, RETROK_ESCAPE }, + { 0x2A, RETROK_BACKSPACE }, + { 0x58, RETROK_KP_ENTER }, + { 0x57, RETROK_KP_PLUS }, + { 0x56, RETROK_KP_MINUS }, + { 0x55, RETROK_KP_MULTIPLY }, + { 0x54, RETROK_KP_DIVIDE }, + { 0x35, RETROK_BACKQUOTE }, + { 0x48, RETROK_PAUSE }, + { 0x62, RETROK_KP0 }, + { 0x59, RETROK_KP1 }, + { 0x5A, RETROK_KP2 }, + { 0x5B, RETROK_KP3 }, + { 0x5C, RETROK_KP4 }, + { 0x5D, RETROK_KP5 }, + { 0x5E, RETROK_KP6 }, + { 0x5F, RETROK_KP7 }, + { 0x60, RETROK_KP8 }, + { 0x61, RETROK_KP9 }, + { 0x27, RETROK_0 }, + { 0x1E, RETROK_1 }, + { 0x1F, RETROK_2 }, + { 0x20, RETROK_3 }, + { 0x21, RETROK_4 }, + { 0x22, RETROK_5 }, + { 0x23, RETROK_6 }, + { 0x24, RETROK_7 }, + { 0x25, RETROK_8 }, + { 0x26, RETROK_9 }, + { 0x3A, RETROK_F1 }, + { 0x3B, RETROK_F2 }, + { 0x3C, RETROK_F3 }, + { 0x3D, RETROK_F4 }, + { 0x3E, RETROK_F5 }, + { 0x3F, RETROK_F6 }, + { 0x40, RETROK_F7 }, + { 0x41, RETROK_F8 }, + { 0x42, RETROK_F9 }, + { 0x43, RETROK_F10 }, + { 0x44, RETROK_F11 }, + { 0x45, RETROK_F12 }, + { 0x04, RETROK_a }, + { 0x05, RETROK_b }, + { 0x06, RETROK_c }, + { 0x07, RETROK_d }, + { 0x08, RETROK_e }, + { 0x09, RETROK_f }, + { 0x0A, RETROK_g }, + { 0x0B, RETROK_h }, + { 0x0C, RETROK_i }, + { 0x0D, RETROK_j }, + { 0x0E, RETROK_k }, + { 0x0F, RETROK_l }, + { 0x10, RETROK_m }, + { 0x11, RETROK_n }, + { 0x12, RETROK_o }, + { 0x13, RETROK_p }, + { 0x14, RETROK_q }, + { 0x15, RETROK_r }, + { 0x16, RETROK_s }, + { 0x17, RETROK_t }, + { 0x18, RETROK_u }, + { 0x19, RETROK_v }, + { 0x1A, RETROK_w }, + { 0x1B, RETROK_x }, + { 0x1C, RETROK_y }, + { 0x1D, RETROK_z }, + { 0, RETROK_UNKNOWN } +}; diff --git a/ios/RetroArch/input/ios_joypad.m b/ios/RetroArch/input/ios_joypad.m new file mode 100644 index 0000000000..674eacfac0 --- /dev/null +++ b/ios/RetroArch/input/ios_joypad.m @@ -0,0 +1,68 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#include "input/input_common.h" +#include "BTStack/wiimote.h" +#include "general.h" + +static uint32_t g_buttons[MAX_PLAYERS]; + +static bool ios_joypad_init(void) +{ + return true; +} + +static bool ios_joypad_query_pad(unsigned pad) +{ + return pad < MAX_PLAYERS; +} + +static void ios_joypad_destroy(void) +{ +} + +static bool ios_joypad_button(unsigned port, uint16_t joykey) +{ + if (joykey == NO_BTN) + return false; + + // Check hat. + if (GET_HAT_DIR(joykey)) + return false; + else // Check the button + return (port < MAX_PLAYERS && joykey < 32) ? (g_buttons[port] & (1 << joykey)) != 0 : false; +} + +static int16_t ios_joypad_axis(unsigned port, uint32_t joyaxis) +{ + return 0; +} + +static void ios_joypad_poll(void) +{ + for (int i = 0; i != MAX_PLAYERS; i ++) + g_buttons[i] = (i < myosd_num_of_joys) ? joys[i].btns : 0; +} + +const rarch_joypad_driver_t ios_joypad = { + ios_joypad_init, + ios_joypad_query_pad, + ios_joypad_destroy, + ios_joypad_button, + ios_joypad_axis, + ios_joypad_poll, + "ios", +}; + diff --git a/ios/RetroArch/ios_input.m b/ios/RetroArch/ios_input.m deleted file mode 100644 index 2e77d11166..0000000000 --- a/ios/RetroArch/ios_input.m +++ /dev/null @@ -1,314 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2013 - Jason Fetters - * - * RetroArch 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 Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch 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 RetroArch. - * If not, see . - */ - -#include -#include "../../input/input_common.h" -#include "../../performance.h" -#include "../../general.h" -#include "../../driver.h" - -#ifdef WIIMOTE -#include "BTStack/wiimote.h" -#endif - -#define MAX_TOUCH 16 -#define MAX_KEYS 256 - -extern NSString* const GSEventKeyDownNotification; -extern NSString* const GSEventKeyUpNotification; -extern NSString* const RATouchNotification; -static const struct rarch_key_map rarch_key_map_hidusage[]; - -struct -{ - bool is_down; - int16_t screen_x, screen_y; - int16_t fixed_x, fixed_y; - int16_t full_x, full_y; -} ios_touches[MAX_TOUCH]; - -uint32_t ios_current_touch_count = 0; - - -// Input responder -static bool ios_keys[MAX_KEYS]; - -@interface RAInputResponder : NSObject -@end - -static RAInputResponder* input_driver; - -@implementation RAInputResponder --(id)init -{ - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyPressed:) name: GSEventKeyDownNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyReleased:) name: GSEventKeyUpNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleTouches:) name: RATouchNotification object:nil]; - return self; -} - --(void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - --(void)keyPressed: (NSNotification*)notification -{ - int keycode = [[notification.userInfo objectForKey:@"keycode"] intValue]; - if (keycode < MAX_KEYS) ios_keys[keycode] = true; -} - --(void)keyReleased: (NSNotification*)notification -{ - int keycode = [[notification.userInfo objectForKey:@"keycode"] intValue]; - if (keycode < MAX_KEYS) ios_keys[keycode] = false; -} - --(void)handleTouches:(NSNotification*)notification -{ - UIEvent* event = [notification.userInfo objectForKey:@"event"]; - NSArray* touches = [[event allTouches] allObjects]; - - ios_current_touch_count = [touches count]; - - for(int i = 0; i != ios_current_touch_count; i ++) - { - UITouch *touch = [touches objectAtIndex:i]; - CGPoint coord = [touch locationInView:touch.view]; - float scale = [[UIScreen mainScreen] scale]; - - ios_touches[i].is_down = (touch.phase != UITouchPhaseEnded) && (touch.phase != UITouchPhaseCancelled); - ios_touches[i].screen_x = coord.x * scale; - ios_touches[i].screen_y = coord.y * scale; - } -} -@end - -static bool l_ios_is_key_pressed(enum retro_key key) -{ - if ((int)key >= 0 && key < RETROK_LAST) - { - int hidkey = input_translate_rk_to_keysym(key); - return (hidkey < MAX_KEYS) ? ios_keys[hidkey] : false; - } - - return false; -} - -static int16_t l_ios_joypad_device_state(const struct retro_keybind **binds_, - unsigned port_num, unsigned id) -{ - const struct retro_keybind *binds = binds_[port_num]; - if (id < RARCH_BIND_LIST_END) - { - const struct retro_keybind *bind = &binds[id]; - return bind->valid && l_ios_is_key_pressed(bind->key); - } - else - return 0; -} - -static void *ios_input_init(void) -{ - input_init_keyboard_lut(rarch_key_map_hidusage); - - if (!input_driver) - input_driver = [RAInputResponder new]; - - ios_current_touch_count = 0; - memset(ios_touches, 0, sizeof(ios_touches)); - memset(ios_keys, 0, sizeof(ios_keys)); - return (void*)-1; -} - -static void ios_input_free_input(void *data) -{ - (void)data; - input_driver = nil; -} - -static void ios_input_poll(void *data) -{ - for (int i = 0; i != ios_current_touch_count; i ++) - { - input_translate_coord_viewport(ios_touches[i].screen_x, ios_touches[i].screen_y, - &ios_touches[i].fixed_x, &ios_touches[i].fixed_y, - &ios_touches[i].full_x, &ios_touches[i].full_y); - } -} - -static int16_t ios_input_state(void *data, const struct retro_keybind **binds, unsigned port, unsigned device, unsigned index, unsigned id) -{ - switch (device) - { - case RETRO_DEVICE_JOYPAD: -#ifdef WIIMOTE - if (myosd_num_of_joys > 0) - { - struct wiimote_t* wm = &joys[0]; - - switch (id) - { - case RETRO_DEVICE_ID_JOYPAD_A: return IS_PRESSED(wm, WIIMOTE_BUTTON_TWO); - case RETRO_DEVICE_ID_JOYPAD_B: return IS_PRESSED(wm, WIIMOTE_BUTTON_ONE); - case RETRO_DEVICE_ID_JOYPAD_START: return IS_PRESSED(wm, WIIMOTE_BUTTON_PLUS); - case RETRO_DEVICE_ID_JOYPAD_SELECT: return IS_PRESSED(wm, WIIMOTE_BUTTON_MINUS); - case RETRO_DEVICE_ID_JOYPAD_UP: return IS_PRESSED(wm, WIIMOTE_BUTTON_RIGHT); - case RETRO_DEVICE_ID_JOYPAD_DOWN: return IS_PRESSED(wm, WIIMOTE_BUTTON_LEFT); - case RETRO_DEVICE_ID_JOYPAD_LEFT: return IS_PRESSED(wm, WIIMOTE_BUTTON_UP); - case RETRO_DEVICE_ID_JOYPAD_RIGHT: return IS_PRESSED(wm, WIIMOTE_BUTTON_DOWN); - } - } -#endif - - return l_ios_joypad_device_state(binds, port, id); - case RETRO_DEVICE_ANALOG: - return 0; - case RETRO_DEVICE_MOUSE: - return 0; - case RETRO_DEVICE_POINTER: - return 0; - case RARCH_DEVICE_POINTER_SCREEN: - switch (id) - { - case RETRO_DEVICE_ID_POINTER_X: - return (index < ios_current_touch_count) ? ios_touches[index].full_x : 0; - case RETRO_DEVICE_ID_POINTER_Y: - return (index < ios_current_touch_count) ? ios_touches[index].full_y : 0; - case RETRO_DEVICE_ID_POINTER_PRESSED: - return (index < ios_current_touch_count) ? ios_touches[index].is_down : 0; - default: - return 0; - } - case RETRO_DEVICE_KEYBOARD: - return 0; - case RETRO_DEVICE_LIGHTGUN: - return 0; - - default: - return 0; - } -} - -static bool ios_input_key_pressed(void *data, int key) -{ - const struct retro_keybind *binds = g_settings.input.binds[0]; - - if (key >= 0 && key < RARCH_BIND_LIST_END) - { - const struct retro_keybind *bind = &binds[key]; - return l_ios_is_key_pressed(bind->key); - } - - return false; -} - -const input_driver_t input_ios = { - ios_input_init, - ios_input_poll, - ios_input_state, - ios_input_key_pressed, - ios_input_free_input, - "ios_input", -}; - -// Key table -static const struct rarch_key_map rarch_key_map_hidusage[] = { - { 0x50, RETROK_LEFT }, - { 0x4F, RETROK_RIGHT }, - { 0x52, RETROK_UP }, - { 0x51, RETROK_DOWN }, - { 0x28, RETROK_RETURN }, - { 0x2B, RETROK_TAB }, - { 0x49, RETROK_INSERT }, - { 0x4C, RETROK_DELETE }, - { 0xE5, RETROK_RSHIFT }, - { 0xE1, RETROK_LSHIFT }, - { 0xE0, RETROK_LCTRL }, - { 0x4D, RETROK_END }, - { 0x4A, RETROK_HOME }, - { 0x4E, RETROK_PAGEDOWN }, - { 0x4B, RETROK_PAGEUP }, - { 0xE2, RETROK_LALT }, - { 0x2C, RETROK_SPACE }, - { 0x29, RETROK_ESCAPE }, - { 0x2A, RETROK_BACKSPACE }, - { 0x58, RETROK_KP_ENTER }, - { 0x57, RETROK_KP_PLUS }, - { 0x56, RETROK_KP_MINUS }, - { 0x55, RETROK_KP_MULTIPLY }, - { 0x54, RETROK_KP_DIVIDE }, - { 0x35, RETROK_BACKQUOTE }, - { 0x48, RETROK_PAUSE }, - { 0x62, RETROK_KP0 }, - { 0x59, RETROK_KP1 }, - { 0x5A, RETROK_KP2 }, - { 0x5B, RETROK_KP3 }, - { 0x5C, RETROK_KP4 }, - { 0x5D, RETROK_KP5 }, - { 0x5E, RETROK_KP6 }, - { 0x5F, RETROK_KP7 }, - { 0x60, RETROK_KP8 }, - { 0x61, RETROK_KP9 }, - { 0x27, RETROK_0 }, - { 0x1E, RETROK_1 }, - { 0x1F, RETROK_2 }, - { 0x20, RETROK_3 }, - { 0x21, RETROK_4 }, - { 0x22, RETROK_5 }, - { 0x23, RETROK_6 }, - { 0x24, RETROK_7 }, - { 0x25, RETROK_8 }, - { 0x26, RETROK_9 }, - { 0x3A, RETROK_F1 }, - { 0x3B, RETROK_F2 }, - { 0x3C, RETROK_F3 }, - { 0x3D, RETROK_F4 }, - { 0x3E, RETROK_F5 }, - { 0x3F, RETROK_F6 }, - { 0x40, RETROK_F7 }, - { 0x41, RETROK_F8 }, - { 0x42, RETROK_F9 }, - { 0x43, RETROK_F10 }, - { 0x44, RETROK_F11 }, - { 0x45, RETROK_F12 }, - { 0x04, RETROK_a }, - { 0x05, RETROK_b }, - { 0x06, RETROK_c }, - { 0x07, RETROK_d }, - { 0x08, RETROK_e }, - { 0x09, RETROK_f }, - { 0x0A, RETROK_g }, - { 0x0B, RETROK_h }, - { 0x0C, RETROK_i }, - { 0x0D, RETROK_j }, - { 0x0E, RETROK_k }, - { 0x0F, RETROK_l }, - { 0x10, RETROK_m }, - { 0x11, RETROK_n }, - { 0x12, RETROK_o }, - { 0x13, RETROK_p }, - { 0x14, RETROK_q }, - { 0x15, RETROK_r }, - { 0x16, RETROK_s }, - { 0x17, RETROK_t }, - { 0x18, RETROK_u }, - { 0x19, RETROK_v }, - { 0x1A, RETROK_w }, - { 0x1B, RETROK_x }, - { 0x1C, RETROK_y }, - { 0x1D, RETROK_z }, - { 0, RETROK_UNKNOWN } -}; diff --git a/ios/RetroArch/settings/RAButtonGetter.m b/ios/RetroArch/settings/RAButtonGetter.m index adfbde97f6..ba9582626c 100644 --- a/ios/RetroArch/settings/RAButtonGetter.m +++ b/ios/RetroArch/settings/RAButtonGetter.m @@ -16,7 +16,7 @@ #import "settings.h" #ifdef WIIMOTE -# include "../BTStack/wiimote.h" +# include "../input/BTStack/wiimote.h" #endif extern NSString* const GSEventKeyUpNotification; From 89c3120d7176de5400746b75e55f7baf4202687f Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 3 Mar 2013 19:15:58 -0500 Subject: [PATCH 091/108] ios: Reorganize project files --- ios/{RetroArch => Assets}/Default-568h@2x.png | Bin ios/{RetroArch => Assets}/Default.png | Bin ios/{RetroArch => Assets}/Default@2x.png | Bin ios/{RetroArch => Assets}/Icon-72.png | Bin ios/{RetroArch => Assets}/Icon.png | Bin .../PauseIndicatorView.xib | 0 ios/{RetroArch => Assets}/PauseView.xib | 0 ios/RetroArch.xcodeproj/project.pbxproj | 181 +++++++++--------- ios/RetroArch/RetroArch_iOS.m | 3 +- ios/RetroArch/{ => browser}/RADirectoryGrid.m | 0 ios/RetroArch/{ => browser}/RADirectoryList.m | 0 ios/RetroArch/{ => browser}/RAModuleList.m | 0 ios/RetroArch/{ => browser}/browser.h | 4 + ios/RetroArch/{ => browser}/browser.m | 0 ios/RetroArch/settings/settings.h | 9 + ios/RetroArch/views.h | 13 -- 16 files changed, 109 insertions(+), 101 deletions(-) rename ios/{RetroArch => Assets}/Default-568h@2x.png (100%) rename ios/{RetroArch => Assets}/Default.png (100%) rename ios/{RetroArch => Assets}/Default@2x.png (100%) rename ios/{RetroArch => Assets}/Icon-72.png (100%) rename ios/{RetroArch => Assets}/Icon.png (100%) rename ios/{RetroArch => Assets}/PauseIndicatorView.xib (100%) rename ios/{RetroArch => Assets}/PauseView.xib (100%) rename ios/RetroArch/{ => browser}/RADirectoryGrid.m (100%) rename ios/RetroArch/{ => browser}/RADirectoryList.m (100%) rename ios/RetroArch/{ => browser}/RAModuleList.m (100%) rename ios/RetroArch/{ => browser}/browser.h (93%) rename ios/RetroArch/{ => browser}/browser.m (100%) diff --git a/ios/RetroArch/Default-568h@2x.png b/ios/Assets/Default-568h@2x.png similarity index 100% rename from ios/RetroArch/Default-568h@2x.png rename to ios/Assets/Default-568h@2x.png diff --git a/ios/RetroArch/Default.png b/ios/Assets/Default.png similarity index 100% rename from ios/RetroArch/Default.png rename to ios/Assets/Default.png diff --git a/ios/RetroArch/Default@2x.png b/ios/Assets/Default@2x.png similarity index 100% rename from ios/RetroArch/Default@2x.png rename to ios/Assets/Default@2x.png diff --git a/ios/RetroArch/Icon-72.png b/ios/Assets/Icon-72.png similarity index 100% rename from ios/RetroArch/Icon-72.png rename to ios/Assets/Icon-72.png diff --git a/ios/RetroArch/Icon.png b/ios/Assets/Icon.png similarity index 100% rename from ios/RetroArch/Icon.png rename to ios/Assets/Icon.png diff --git a/ios/RetroArch/PauseIndicatorView.xib b/ios/Assets/PauseIndicatorView.xib similarity index 100% rename from ios/RetroArch/PauseIndicatorView.xib rename to ios/Assets/PauseIndicatorView.xib diff --git a/ios/RetroArch/PauseView.xib b/ios/Assets/PauseView.xib similarity index 100% rename from ios/RetroArch/PauseView.xib rename to ios/Assets/PauseView.xib diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index ce99c09df0..daee2b6237 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -61,12 +61,8 @@ 9614C6F616DDC018000B36EF /* RASettingEnumerationList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5ABD16CC522F009BBD19 /* RASettingEnumerationList.m */; }; 9614C6F716DDC018000B36EF /* RASettingsSubList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5ABE16CC522F009BBD19 /* RASettingsSubList.m */; }; 9614C6F816DDC018000B36EF /* RASettingsList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5ABF16CC522F009BBD19 /* RASettingsList.m */; }; - 9614C6F916DDC018000B36EF /* RADirectoryList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC416CC523B009BBD19 /* RADirectoryList.m */; }; 9614C6FA16DDC018000B36EF /* RAGameView.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC516CC523B009BBD19 /* RAGameView.m */; }; - 9614C6FB16DDC018000B36EF /* RAModuleList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC616CC523B009BBD19 /* RAModuleList.m */; }; 9614C6FC16DDC018000B36EF /* RAModuleInfoList.m in Sources */ = {isa = PBXBuildFile; fileRef = 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */; }; - 9614C6FD16DDC018000B36EF /* RADirectoryGrid.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2316D453BA00FE8D5A /* RADirectoryGrid.m */; }; - 9614C6FE16DDC018000B36EF /* browser.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2816D5A56400FE8D5A /* browser.m */; }; 9614C6FF16DDC018000B36EF /* RAConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2F16D7045700FE8D5A /* RAConfig.m */; }; 9614C70616DDC018000B36EF /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */; }; 9614C70716DDC018000B36EF /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5416C9AC3300D64A22 /* CoreAudio.framework */; }; @@ -78,22 +74,13 @@ 9614C70D16DDC018000B36EF /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE3116C1D4EA009DE44C /* OpenGLES.framework */; }; 9614C71016DDC018000B36EF /* overlays in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2616C82FF100E6DCE0 /* overlays */; }; 9614C71116DDC018000B36EF /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE3616C1D4EA009DE44C /* InfoPlist.strings */; }; - 9614C71216DDC018000B36EF /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE3F16C1D4EA009DE44C /* Default.png */; }; - 9614C71316DDC018000B36EF /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4116C1D4EA009DE44C /* Default@2x.png */; }; - 9614C71416DDC018000B36EF /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4316C1D4EA009DE44C /* Default-568h@2x.png */; }; 9614C71516DDC018000B36EF /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; }; 9614C71616DDC018000B36EF /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; }; - 9614C71716DDC018000B36EF /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2216C818FF00E6DCE0 /* Icon-72.png */; }; - 9614C71816DDC018000B36EF /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2316C818FF00E6DCE0 /* Icon.png */; }; - 9614C71916DDC018000B36EF /* PauseView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 969EBF6916D95746003787A2 /* PauseView.xib */; }; - 9614C71A16DDC018000B36EF /* PauseIndicatorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 965AE29F16DA83C1001D7667 /* PauseIndicatorView.xib */; }; 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */; }; 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; }; 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; }; 96297A0C16C5AD8D00E6DCE0 /* RetroArch_iOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */; }; 96297A0F16C5AEA100E6DCE0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0E16C5AEA100E6DCE0 /* main.m */; }; - 96297A2416C818FF00E6DCE0 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2216C818FF00E6DCE0 /* Icon-72.png */; }; - 96297A2516C818FF00E6DCE0 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2316C818FF00E6DCE0 /* Icon.png */; }; 96297A2716C82FF100E6DCE0 /* overlays in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2616C82FF100E6DCE0 /* overlays */; }; 96366C5016C9A4E100D64A22 /* resampler.c in Sources */ = {isa = PBXBuildFile; fileRef = 96366C4F16C9A4E100D64A22 /* resampler.c */; }; 96366C5216C9A4E600D64A22 /* hermite.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEEC16C1DC73009DE44C /* hermite.c */; }; @@ -104,10 +91,7 @@ 963F5AC116CC522F009BBD19 /* RASettingEnumerationList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5ABD16CC522F009BBD19 /* RASettingEnumerationList.m */; }; 963F5AC216CC522F009BBD19 /* RASettingsSubList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5ABE16CC522F009BBD19 /* RASettingsSubList.m */; }; 963F5AC316CC522F009BBD19 /* RASettingsList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5ABF16CC522F009BBD19 /* RASettingsList.m */; }; - 963F5AC716CC523B009BBD19 /* RADirectoryList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC416CC523B009BBD19 /* RADirectoryList.m */; }; 963F5AC816CC523B009BBD19 /* RAGameView.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC516CC523B009BBD19 /* RAGameView.m */; }; - 963F5AC916CC523B009BBD19 /* RAModuleList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC616CC523B009BBD19 /* RAModuleList.m */; }; - 965AE2A016DA83C1001D7667 /* PauseIndicatorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 965AE29F16DA83C1001D7667 /* PauseIndicatorView.xib */; }; 966B9C8A16E40D44005B61E1 /* ios_input.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C8616E40D44005B61E1 /* ios_input.m */; }; 966B9C8B16E40D44005B61E1 /* ios_joypad.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C8716E40D44005B61E1 /* ios_joypad.m */; }; 966B9C8C16E40D44005B61E1 /* RAInputResponder.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C8916E40D44005B61E1 /* RAInputResponder.m */; }; @@ -119,16 +103,34 @@ 966B9CA516E418B7005B61E1 /* libBTstack.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 966B9C9D16E418B7005B61E1 /* libBTstack.dylib */; }; 966B9CA616E418B7005B61E1 /* wiimote.c in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C9E16E418B7005B61E1 /* wiimote.c */; }; 966B9CA716E418B7005B61E1 /* WiiMoteHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9CA116E418B7005B61E1 /* WiiMoteHelper.m */; }; - 969EBF6A16D95746003787A2 /* PauseView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 969EBF6916D95746003787A2 /* PauseView.xib */; }; + 966B9CAE16E41C07005B61E1 /* browser.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9CAA16E41C07005B61E1 /* browser.m */; }; + 966B9CAF16E41C07005B61E1 /* browser.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9CAA16E41C07005B61E1 /* browser.m */; }; + 966B9CB016E41C07005B61E1 /* RADirectoryGrid.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9CAB16E41C07005B61E1 /* RADirectoryGrid.m */; }; + 966B9CB116E41C07005B61E1 /* RADirectoryGrid.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9CAB16E41C07005B61E1 /* RADirectoryGrid.m */; }; + 966B9CB216E41C07005B61E1 /* RADirectoryList.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9CAC16E41C07005B61E1 /* RADirectoryList.m */; }; + 966B9CB316E41C07005B61E1 /* RADirectoryList.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9CAC16E41C07005B61E1 /* RADirectoryList.m */; }; + 966B9CB416E41C07005B61E1 /* RAModuleList.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9CAD16E41C07005B61E1 /* RAModuleList.m */; }; + 966B9CB516E41C07005B61E1 /* RAModuleList.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9CAD16E41C07005B61E1 /* RAModuleList.m */; }; + 966B9CBD16E41E7A005B61E1 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CB816E41E7A005B61E1 /* Default-568h@2x.png */; }; + 966B9CBE16E41E7A005B61E1 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CB816E41E7A005B61E1 /* Default-568h@2x.png */; }; + 966B9CBF16E41E7A005B61E1 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CB916E41E7A005B61E1 /* Default.png */; }; + 966B9CC016E41E7A005B61E1 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CB916E41E7A005B61E1 /* Default.png */; }; + 966B9CC116E41E7A005B61E1 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CBA16E41E7A005B61E1 /* Default@2x.png */; }; + 966B9CC216E41E7A005B61E1 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CBA16E41E7A005B61E1 /* Default@2x.png */; }; + 966B9CC316E41E7A005B61E1 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CBB16E41E7A005B61E1 /* Icon-72.png */; }; + 966B9CC416E41E7A005B61E1 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CBB16E41E7A005B61E1 /* Icon-72.png */; }; + 966B9CC516E41E7A005B61E1 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CBC16E41E7A005B61E1 /* Icon.png */; }; + 966B9CC616E41E7A005B61E1 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CBC16E41E7A005B61E1 /* Icon.png */; }; + 966B9CC916E41EC1005B61E1 /* PauseView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CC716E41EC1005B61E1 /* PauseView.xib */; }; + 966B9CCA16E41EC1005B61E1 /* PauseView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CC716E41EC1005B61E1 /* PauseView.xib */; }; + 966B9CCB16E41EC1005B61E1 /* PauseIndicatorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CC816E41EC1005B61E1 /* PauseIndicatorView.xib */; }; + 966B9CCC16E41EC1005B61E1 /* PauseIndicatorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CC816E41EC1005B61E1 /* PauseIndicatorView.xib */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; 96AFAE3016C1D4EA009DE44C /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2F16C1D4EA009DE44C /* GLKit.framework */; }; 96AFAE3216C1D4EA009DE44C /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE3116C1D4EA009DE44C /* OpenGLES.framework */; }; 96AFAE3816C1D4EA009DE44C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE3616C1D4EA009DE44C /* InfoPlist.strings */; }; - 96AFAE4016C1D4EA009DE44C /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE3F16C1D4EA009DE44C /* Default.png */; }; - 96AFAE4216C1D4EA009DE44C /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4116C1D4EA009DE44C /* Default@2x.png */; }; - 96AFAE4416C1D4EA009DE44C /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 96AFAE4316C1D4EA009DE44C /* Default-568h@2x.png */; }; 96AFAECA16C1D9A9009DE44C /* autosave.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAE9D16C1D9A9009DE44C /* autosave.c */; }; 96AFAECB16C1D9A9009DE44C /* cheats.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEA016C1D9A9009DE44C /* cheats.c */; }; 96AFAECC16C1D9A9009DE44C /* command.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEA216C1D9A9009DE44C /* command.c */; }; @@ -172,8 +174,6 @@ 96AFAFAC16C1E279009DE44C /* state_tracker.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF7B16C1E00A009DE44C /* state_tracker.c */; }; 96AFAFAD16C1EEE9009DE44C /* sinc.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEF716C1DC73009DE44C /* sinc.c */; }; 96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFC916C1FBC0009DE44C /* input_common.c */; }; - 96C19C2416D453BA00FE8D5A /* RADirectoryGrid.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2316D453BA00FE8D5A /* RADirectoryGrid.m */; }; - 96C19C2916D5A56500FE8D5A /* browser.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2816D5A56400FE8D5A /* browser.m */; }; 96C19C3016D7045700FE8D5A /* RAConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 96C19C2F16D7045700FE8D5A /* RAConfig.m */; }; 96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCE16C1FBC0009DE44C /* overlay.c */; }; /* End PBXBuildFile section */ @@ -183,15 +183,13 @@ 9614C71E16DDC018000B36EF /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 9614C71F16DDC018000B36EF /* RetroArch copy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "RetroArch copy-Info.plist"; path = "/Users/jason/Documents/Projects/ios/RetroArch/ios/RetroArch copy-Info.plist"; sourceTree = ""; }; 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioseagl_ctx.c; sourceTree = ""; }; - 962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = ""; }; - 962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = ""; }; + 962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = ""; }; + 962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = ""; }; 96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RetroArch_iOS.h; sourceTree = ""; }; 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RetroArch_iOS.m; sourceTree = ""; }; 96297A0D16C5ADDA00E6DCE0 /* views.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = views.h; sourceTree = ""; }; 96297A0E16C5AEA100E6DCE0 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 96297A2216C818FF00E6DCE0 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "RetroArch/Icon-72.png"; sourceTree = ""; }; - 96297A2316C818FF00E6DCE0 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = RetroArch/Icon.png; sourceTree = ""; }; - 96297A2616C82FF100E6DCE0 /* overlays */ = {isa = PBXFileReference; lastKnownFileType = folder; name = overlays; path = ../media/overlays; sourceTree = ""; }; + 96297A2616C82FF100E6DCE0 /* overlays */ = {isa = PBXFileReference; lastKnownFileType = folder; name = overlays; path = ../../media/overlays; sourceTree = ""; }; 96366C4F16C9A4E100D64A22 /* resampler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resampler.c; sourceTree = ""; }; 96366C5416C9AC3300D64A22 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; @@ -200,10 +198,7 @@ 963F5ABD16CC522F009BBD19 /* RASettingEnumerationList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RASettingEnumerationList.m; sourceTree = ""; }; 963F5ABE16CC522F009BBD19 /* RASettingsSubList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RASettingsSubList.m; sourceTree = ""; }; 963F5ABF16CC522F009BBD19 /* RASettingsList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RASettingsList.m; sourceTree = ""; }; - 963F5AC416CC523B009BBD19 /* RADirectoryList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RADirectoryList.m; sourceTree = ""; }; 963F5AC516CC523B009BBD19 /* RAGameView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAGameView.m; sourceTree = ""; }; - 963F5AC616CC523B009BBD19 /* RAModuleList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAModuleList.m; sourceTree = ""; }; - 965AE29F16DA83C1001D7667 /* PauseIndicatorView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PauseIndicatorView.xib; sourceTree = ""; }; 966B9C8616E40D44005B61E1 /* ios_input.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ios_input.m; sourceTree = ""; }; 966B9C8716E40D44005B61E1 /* ios_joypad.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ios_joypad.m; sourceTree = ""; }; 966B9C8816E40D44005B61E1 /* RAInputResponder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RAInputResponder.h; sourceTree = ""; }; @@ -225,7 +220,18 @@ 966B9C9F16E418B7005B61E1 /* wiimote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wiimote.h; sourceTree = ""; }; 966B9CA016E418B7005B61E1 /* WiiMoteHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WiiMoteHelper.h; sourceTree = ""; }; 966B9CA116E418B7005B61E1 /* WiiMoteHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WiiMoteHelper.m; sourceTree = ""; }; - 969EBF6916D95746003787A2 /* PauseView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PauseView.xib; sourceTree = ""; }; + 966B9CA916E41C07005B61E1 /* browser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = browser.h; sourceTree = ""; }; + 966B9CAA16E41C07005B61E1 /* browser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = browser.m; sourceTree = ""; }; + 966B9CAB16E41C07005B61E1 /* RADirectoryGrid.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RADirectoryGrid.m; sourceTree = ""; }; + 966B9CAC16E41C07005B61E1 /* RADirectoryList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RADirectoryList.m; sourceTree = ""; }; + 966B9CAD16E41C07005B61E1 /* RAModuleList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAModuleList.m; sourceTree = ""; }; + 966B9CB816E41E7A005B61E1 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; + 966B9CB916E41E7A005B61E1 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 966B9CBA16E41E7A005B61E1 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; + 966B9CBB16E41E7A005B61E1 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 966B9CBC16E41E7A005B61E1 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 966B9CC716E41EC1005B61E1 /* PauseView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PauseView.xib; sourceTree = ""; }; + 966B9CC816E41EC1005B61E1 /* PauseIndicatorView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PauseIndicatorView.xib; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -235,9 +241,6 @@ 96AFAE3516C1D4EA009DE44C /* RetroArch-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RetroArch-Info.plist"; sourceTree = ""; }; 96AFAE3716C1D4EA009DE44C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 96AFAE3B16C1D4EA009DE44C /* RetroArch-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RetroArch-Prefix.pch"; sourceTree = ""; }; - 96AFAE3F16C1D4EA009DE44C /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; - 96AFAE4116C1D4EA009DE44C /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; - 96AFAE4316C1D4EA009DE44C /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 96AFAE9D16C1D9A9009DE44C /* autosave.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = autosave.c; path = ../autosave.c; sourceTree = ""; }; 96AFAE9E16C1D9A9009DE44C /* autosave.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = autosave.h; path = ../autosave.h; sourceTree = ""; }; 96AFAE9F16C1D9A9009DE44C /* boolean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = boolean.h; path = ../boolean.h; sourceTree = ""; }; @@ -342,10 +345,7 @@ 96AFAFCA16C1FBC0009DE44C /* input_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = input_common.h; sourceTree = ""; }; 96AFAFCE16C1FBC0009DE44C /* overlay.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = overlay.c; sourceTree = ""; }; 96AFAFCF16C1FBC0009DE44C /* overlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = overlay.h; sourceTree = ""; }; - 96C19C2316D453BA00FE8D5A /* RADirectoryGrid.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RADirectoryGrid.m; sourceTree = ""; }; - 96C19C2516D455BE00FE8D5A /* browser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = browser.h; sourceTree = ""; }; 96C19C2616D455BE00FE8D5A /* rarch_wrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rarch_wrapper.h; sourceTree = ""; }; - 96C19C2816D5A56400FE8D5A /* browser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = browser.m; sourceTree = ""; }; 96C19C2E16D7045600FE8D5A /* RAConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RAConfig.h; sourceTree = ""; }; 96C19C2F16D7045700FE8D5A /* RAConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAConfig.m; sourceTree = ""; }; /* End PBXFileReference section */ @@ -441,20 +441,44 @@ path = btstack; sourceTree = ""; }; - 96AFAE1A16C1D4EA009DE44C = { + 966B9CA816E41C07005B61E1 /* browser */ = { + isa = PBXGroup; + children = ( + 966B9CA916E41C07005B61E1 /* browser.h */, + 966B9CAA16E41C07005B61E1 /* browser.m */, + 966B9CAB16E41C07005B61E1 /* RADirectoryGrid.m */, + 966B9CAC16E41C07005B61E1 /* RADirectoryList.m */, + 966B9CAD16E41C07005B61E1 /* RAModuleList.m */, + ); + path = browser; + sourceTree = ""; + }; + 966B9CB716E41E7A005B61E1 /* Assets */ = { isa = PBXGroup; children = ( 96297A2616C82FF100E6DCE0 /* overlays */, - 96297A2216C818FF00E6DCE0 /* Icon-72.png */, - 96297A2316C818FF00E6DCE0 /* Icon.png */, + 966B9CB816E41E7A005B61E1 /* Default-568h@2x.png */, + 966B9CB916E41E7A005B61E1 /* Default.png */, + 966B9CBA16E41E7A005B61E1 /* Default@2x.png */, 962979F416C43B9500E6DCE0 /* ic_dir.png */, 962979F516C43B9500E6DCE0 /* ic_file.png */, - 96AFAF2116C1DF88009DE44C /* libz.dylib */, - 96AFAE9C16C1D976009DE44C /* core */, + 966B9CBB16E41E7A005B61E1 /* Icon-72.png */, + 966B9CBC16E41E7A005B61E1 /* Icon.png */, + 966B9CC716E41EC1005B61E1 /* PauseView.xib */, + 966B9CC816E41EC1005B61E1 /* PauseIndicatorView.xib */, + ); + path = Assets; + sourceTree = ""; + }; + 96AFAE1A16C1D4EA009DE44C = { + isa = PBXGroup; + children = ( 96AFAE3316C1D4EA009DE44C /* RetroArch */, + 96AFAE9C16C1D976009DE44C /* core */, + 966B9CB716E41E7A005B61E1 /* Assets */, 96AFAE2816C1D4EA009DE44C /* Frameworks */, 96AFAE2616C1D4EA009DE44C /* Products */, - 9614C71F16DDC018000B36EF /* RetroArch copy-Info.plist */, + 96AFAE3416C1D4EA009DE44C /* Supporting Files */, ); sourceTree = ""; }; @@ -470,6 +494,7 @@ 96AFAE2816C1D4EA009DE44C /* Frameworks */ = { isa = PBXGroup; children = ( + 96AFAF2116C1DF88009DE44C /* libz.dylib */, 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */, 96366C5416C9AC3300D64A22 /* CoreAudio.framework */, 96AFAE2916C1D4EA009DE44C /* UIKit.framework */, @@ -484,21 +509,18 @@ 96AFAE3316C1D4EA009DE44C /* RetroArch */ = { isa = PBXGroup; children = ( + 966B9CA816E41C07005B61E1 /* browser */, 966B9C8516E40D44005B61E1 /* input */, - 96C19C2716D455C600FE8D5A /* Browser */, 96366C6F16CAF62200D64A22 /* settings */, - 96AFAE3416C1D4EA009DE44C /* Supporting Files */, + 96297A0E16C5AEA100E6DCE0 /* main.m */, 96C19C2E16D7045600FE8D5A /* RAConfig.h */, 96C19C2F16D7045700FE8D5A /* RAConfig.m */, 963F5AC516CC523B009BBD19 /* RAGameView.m */, 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */, - 963F5AC616CC523B009BBD19 /* RAModuleList.m */, 96C19C2616D455BE00FE8D5A /* rarch_wrapper.h */, 96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */, 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */, 96297A0D16C5ADDA00E6DCE0 /* views.h */, - 969EBF6916D95746003787A2 /* PauseView.xib */, - 965AE29F16DA83C1001D7667 /* PauseIndicatorView.xib */, ); path = RetroArch; sourceTree = ""; @@ -506,15 +528,13 @@ 96AFAE3416C1D4EA009DE44C /* Supporting Files */ = { isa = PBXGroup; children = ( - 96AFAE4316C1D4EA009DE44C /* Default-568h@2x.png */, - 96AFAE3F16C1D4EA009DE44C /* Default.png */, - 96AFAE4116C1D4EA009DE44C /* Default@2x.png */, + 9614C71F16DDC018000B36EF /* RetroArch copy-Info.plist */, 96AFAE3616C1D4EA009DE44C /* InfoPlist.strings */, - 96297A0E16C5AEA100E6DCE0 /* main.m */, 96AFAE3516C1D4EA009DE44C /* RetroArch-Info.plist */, 96AFAE3B16C1D4EA009DE44C /* RetroArch-Prefix.pch */, ); name = "Supporting Files"; + path = RetroArch; sourceTree = ""; }; 96AFAE9C16C1D976009DE44C /* core */ = { @@ -730,17 +750,6 @@ path = ../input; sourceTree = ""; }; - 96C19C2716D455C600FE8D5A /* Browser */ = { - isa = PBXGroup; - children = ( - 96C19C2516D455BE00FE8D5A /* browser.h */, - 96C19C2816D5A56400FE8D5A /* browser.m */, - 96C19C2316D453BA00FE8D5A /* RADirectoryGrid.m */, - 963F5AC416CC523B009BBD19 /* RADirectoryList.m */, - ); - name = Browser; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -812,15 +821,15 @@ files = ( 9614C71016DDC018000B36EF /* overlays in Resources */, 9614C71116DDC018000B36EF /* InfoPlist.strings in Resources */, - 9614C71216DDC018000B36EF /* Default.png in Resources */, - 9614C71316DDC018000B36EF /* Default@2x.png in Resources */, - 9614C71416DDC018000B36EF /* Default-568h@2x.png in Resources */, 9614C71516DDC018000B36EF /* ic_dir.png in Resources */, 9614C71616DDC018000B36EF /* ic_file.png in Resources */, - 9614C71716DDC018000B36EF /* Icon-72.png in Resources */, - 9614C71816DDC018000B36EF /* Icon.png in Resources */, - 9614C71916DDC018000B36EF /* PauseView.xib in Resources */, - 9614C71A16DDC018000B36EF /* PauseIndicatorView.xib in Resources */, + 966B9CBE16E41E7A005B61E1 /* Default-568h@2x.png in Resources */, + 966B9CC016E41E7A005B61E1 /* Default.png in Resources */, + 966B9CC216E41E7A005B61E1 /* Default@2x.png in Resources */, + 966B9CC416E41E7A005B61E1 /* Icon-72.png in Resources */, + 966B9CC616E41E7A005B61E1 /* Icon.png in Resources */, + 966B9CCA16E41EC1005B61E1 /* PauseView.xib in Resources */, + 966B9CCC16E41EC1005B61E1 /* PauseIndicatorView.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -830,15 +839,15 @@ files = ( 96297A2716C82FF100E6DCE0 /* overlays in Resources */, 96AFAE3816C1D4EA009DE44C /* InfoPlist.strings in Resources */, - 96AFAE4016C1D4EA009DE44C /* Default.png in Resources */, - 96AFAE4216C1D4EA009DE44C /* Default@2x.png in Resources */, - 96AFAE4416C1D4EA009DE44C /* Default-568h@2x.png in Resources */, 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */, 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */, - 96297A2416C818FF00E6DCE0 /* Icon-72.png in Resources */, - 96297A2516C818FF00E6DCE0 /* Icon.png in Resources */, - 969EBF6A16D95746003787A2 /* PauseView.xib in Resources */, - 965AE2A016DA83C1001D7667 /* PauseIndicatorView.xib in Resources */, + 966B9CBD16E41E7A005B61E1 /* Default-568h@2x.png in Resources */, + 966B9CBF16E41E7A005B61E1 /* Default.png in Resources */, + 966B9CC116E41E7A005B61E1 /* Default@2x.png in Resources */, + 966B9CC316E41E7A005B61E1 /* Icon-72.png in Resources */, + 966B9CC516E41E7A005B61E1 /* Icon.png in Resources */, + 966B9CC916E41EC1005B61E1 /* PauseView.xib in Resources */, + 966B9CCB16E41EC1005B61E1 /* PauseIndicatorView.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -902,15 +911,15 @@ 9614C6F616DDC018000B36EF /* RASettingEnumerationList.m in Sources */, 9614C6F716DDC018000B36EF /* RASettingsSubList.m in Sources */, 9614C6F816DDC018000B36EF /* RASettingsList.m in Sources */, - 9614C6F916DDC018000B36EF /* RADirectoryList.m in Sources */, 9614C6FA16DDC018000B36EF /* RAGameView.m in Sources */, - 9614C6FB16DDC018000B36EF /* RAModuleList.m in Sources */, 9614C6FC16DDC018000B36EF /* RAModuleInfoList.m in Sources */, - 9614C6FD16DDC018000B36EF /* RADirectoryGrid.m in Sources */, - 9614C6FE16DDC018000B36EF /* browser.m in Sources */, 9614C6FF16DDC018000B36EF /* RAConfig.m in Sources */, 966B9C8D16E40EFC005B61E1 /* RAInputResponder.m in Sources */, 966B9C8E16E40F00005B61E1 /* ios_input.m in Sources */, + 966B9CAF16E41C07005B61E1 /* browser.m in Sources */, + 966B9CB116E41C07005B61E1 /* RADirectoryGrid.m in Sources */, + 966B9CB316E41C07005B61E1 /* RADirectoryList.m in Sources */, + 966B9CB516E41C07005B61E1 /* RAModuleList.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -971,12 +980,8 @@ 963F5AC116CC522F009BBD19 /* RASettingEnumerationList.m in Sources */, 963F5AC216CC522F009BBD19 /* RASettingsSubList.m in Sources */, 963F5AC316CC522F009BBD19 /* RASettingsList.m in Sources */, - 963F5AC716CC523B009BBD19 /* RADirectoryList.m in Sources */, 963F5AC816CC523B009BBD19 /* RAGameView.m in Sources */, - 963F5AC916CC523B009BBD19 /* RAModuleList.m in Sources */, 96096DD816D1ABAF00BF4499 /* RAModuleInfoList.m in Sources */, - 96C19C2416D453BA00FE8D5A /* RADirectoryGrid.m in Sources */, - 96C19C2916D5A56500FE8D5A /* browser.m in Sources */, 96C19C3016D7045700FE8D5A /* RAConfig.m in Sources */, 966B9C8A16E40D44005B61E1 /* ios_input.m in Sources */, 966B9C8B16E40D44005B61E1 /* ios_joypad.m in Sources */, @@ -986,6 +991,10 @@ 966B9CA416E418B7005B61E1 /* BTstackManager.m in Sources */, 966B9CA616E418B7005B61E1 /* wiimote.c in Sources */, 966B9CA716E418B7005B61E1 /* WiiMoteHelper.m in Sources */, + 966B9CAE16E41C07005B61E1 /* browser.m in Sources */, + 966B9CB016E41C07005B61E1 /* RADirectoryGrid.m in Sources */, + 966B9CB216E41C07005B61E1 /* RADirectoryList.m in Sources */, + 966B9CB416E41C07005B61E1 /* RAModuleList.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1014,7 +1023,6 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"", - "\"$(SRCROOT)/RetroArch/BTStack\"", ); OTHER_CFLAGS = ( "-DHAVE_RARCH_MAIN_WRAP", @@ -1051,7 +1059,6 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"", - "\"$(SRCROOT)/RetroArch/BTStack\"", ); OTHER_CFLAGS = ( "-DNS_BLOCK_ASSERTIONS=1", diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 873e6fb049..d0713e6d6b 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -16,7 +16,8 @@ #include #include "rarch_wrapper.h" #include "general.h" -#import "browser.h" +#import "browser/browser.h" +#import "settings/settings.h" #ifdef WIIMOTE #import "input/BTStack/WiiMoteHelper.h" diff --git a/ios/RetroArch/RADirectoryGrid.m b/ios/RetroArch/browser/RADirectoryGrid.m similarity index 100% rename from ios/RetroArch/RADirectoryGrid.m rename to ios/RetroArch/browser/RADirectoryGrid.m diff --git a/ios/RetroArch/RADirectoryList.m b/ios/RetroArch/browser/RADirectoryList.m similarity index 100% rename from ios/RetroArch/RADirectoryList.m rename to ios/RetroArch/browser/RADirectoryList.m diff --git a/ios/RetroArch/RAModuleList.m b/ios/RetroArch/browser/RAModuleList.m similarity index 100% rename from ios/RetroArch/RAModuleList.m rename to ios/RetroArch/browser/RAModuleList.m diff --git a/ios/RetroArch/browser.h b/ios/RetroArch/browser/browser.h similarity index 93% rename from ios/RetroArch/browser.h rename to ios/RetroArch/browser/browser.h index 85cf74d42e..0e4acad2e4 100644 --- a/ios/RetroArch/browser.h +++ b/ios/RetroArch/browser/browser.h @@ -32,3 +32,7 @@ extern NSString* ra_ios_check_path(NSString* path); + (id)directoryListOrGridWithPath:(NSString*)path; - (id)initWithPath:(NSString*)path config:(RAConfig*)config; @end + +@interface RAModuleList : UITableViewController +- (id)initWithGame:(NSString*)path; +@end diff --git a/ios/RetroArch/browser.m b/ios/RetroArch/browser/browser.m similarity index 100% rename from ios/RetroArch/browser.m rename to ios/RetroArch/browser/browser.m diff --git a/ios/RetroArch/settings/settings.h b/ios/RetroArch/settings/settings.h index c1b4e0f27b..2349bafb7b 100644 --- a/ios/RetroArch/settings/settings.h +++ b/ios/RetroArch/settings/settings.h @@ -37,3 +37,12 @@ enum SettingTypes @interface RASettingEnumerationList : UITableViewController - (id)initWithSetting:(RASettingData*)setting fromTable:(UITableView*)table; @end + +@interface RASettingsSubList : UITableViewController +- (id)initWithSettings:(NSArray*)values title:(NSString*)title; +- (void)writeSettings:(NSArray*)settingList toConfig:(RAConfig*)config; +@end + +@interface RASettingsList : RASettingsSubList ++ (void)refreshConfigFile; +@end diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index 033fda5369..58121ec0e0 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -35,16 +35,3 @@ @interface RAModuleInfoList : UITableViewController - (id)initWithModuleInfo:(RAModuleInfo*)info; @end - -@interface RAModuleList : UITableViewController -- (id)initWithGame:(NSString*)path; -@end - -@interface RASettingsSubList : UITableViewController -- (id)initWithSettings:(NSArray*)values title:(NSString*)title; -- (void)writeSettings:(NSArray*)settingList toConfig:(RAConfig*)config; -@end - -@interface RASettingsList : RASettingsSubList -+ (void)refreshConfigFile; -@end From 3f1f548e9f3a7147032a33f8c5251e82e9fad1ca Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 3 Mar 2013 20:11:17 -0500 Subject: [PATCH 092/108] ios: Add 'keycode.h' which defines names for USB hid key symbols; use it to remove magic numbers in keyboard code. --- ios/RetroArch/input/ios_input.m | 171 ++++++++++++------------ ios/RetroArch/input/keycode.h | 156 +++++++++++++++++++++ ios/RetroArch/settings/RAButtonGetter.m | 86 ++++++------ 3 files changed, 285 insertions(+), 128 deletions(-) create mode 100644 ios/RetroArch/input/keycode.h diff --git a/ios/RetroArch/input/ios_input.m b/ios/RetroArch/input/ios_input.m index 01a4664d20..badc1b74bd 100644 --- a/ios/RetroArch/input/ios_input.m +++ b/ios/RetroArch/input/ios_input.m @@ -109,90 +109,93 @@ const input_driver_t input_ios = { }; // Key table +#include "keycode.h" static const struct rarch_key_map rarch_key_map_hidusage[] = { - { 0x50, RETROK_LEFT }, - { 0x4F, RETROK_RIGHT }, - { 0x52, RETROK_UP }, - { 0x51, RETROK_DOWN }, - { 0x28, RETROK_RETURN }, - { 0x2B, RETROK_TAB }, - { 0x49, RETROK_INSERT }, - { 0x4C, RETROK_DELETE }, - { 0xE5, RETROK_RSHIFT }, - { 0xE1, RETROK_LSHIFT }, - { 0xE0, RETROK_LCTRL }, - { 0x4D, RETROK_END }, - { 0x4A, RETROK_HOME }, - { 0x4E, RETROK_PAGEDOWN }, - { 0x4B, RETROK_PAGEUP }, - { 0xE2, RETROK_LALT }, - { 0x2C, RETROK_SPACE }, - { 0x29, RETROK_ESCAPE }, - { 0x2A, RETROK_BACKSPACE }, - { 0x58, RETROK_KP_ENTER }, - { 0x57, RETROK_KP_PLUS }, - { 0x56, RETROK_KP_MINUS }, - { 0x55, RETROK_KP_MULTIPLY }, - { 0x54, RETROK_KP_DIVIDE }, - { 0x35, RETROK_BACKQUOTE }, - { 0x48, RETROK_PAUSE }, - { 0x62, RETROK_KP0 }, - { 0x59, RETROK_KP1 }, - { 0x5A, RETROK_KP2 }, - { 0x5B, RETROK_KP3 }, - { 0x5C, RETROK_KP4 }, - { 0x5D, RETROK_KP5 }, - { 0x5E, RETROK_KP6 }, - { 0x5F, RETROK_KP7 }, - { 0x60, RETROK_KP8 }, - { 0x61, RETROK_KP9 }, - { 0x27, RETROK_0 }, - { 0x1E, RETROK_1 }, - { 0x1F, RETROK_2 }, - { 0x20, RETROK_3 }, - { 0x21, RETROK_4 }, - { 0x22, RETROK_5 }, - { 0x23, RETROK_6 }, - { 0x24, RETROK_7 }, - { 0x25, RETROK_8 }, - { 0x26, RETROK_9 }, - { 0x3A, RETROK_F1 }, - { 0x3B, RETROK_F2 }, - { 0x3C, RETROK_F3 }, - { 0x3D, RETROK_F4 }, - { 0x3E, RETROK_F5 }, - { 0x3F, RETROK_F6 }, - { 0x40, RETROK_F7 }, - { 0x41, RETROK_F8 }, - { 0x42, RETROK_F9 }, - { 0x43, RETROK_F10 }, - { 0x44, RETROK_F11 }, - { 0x45, RETROK_F12 }, - { 0x04, RETROK_a }, - { 0x05, RETROK_b }, - { 0x06, RETROK_c }, - { 0x07, RETROK_d }, - { 0x08, RETROK_e }, - { 0x09, RETROK_f }, - { 0x0A, RETROK_g }, - { 0x0B, RETROK_h }, - { 0x0C, RETROK_i }, - { 0x0D, RETROK_j }, - { 0x0E, RETROK_k }, - { 0x0F, RETROK_l }, - { 0x10, RETROK_m }, - { 0x11, RETROK_n }, - { 0x12, RETROK_o }, - { 0x13, RETROK_p }, - { 0x14, RETROK_q }, - { 0x15, RETROK_r }, - { 0x16, RETROK_s }, - { 0x17, RETROK_t }, - { 0x18, RETROK_u }, - { 0x19, RETROK_v }, - { 0x1A, RETROK_w }, - { 0x1B, RETROK_x }, - { 0x1C, RETROK_y }, - { 0x1D, RETROK_z }, + { KEY_Left, RETROK_LEFT }, + { KEY_Right, RETROK_RIGHT }, + { KEY_Up, RETROK_UP }, + { KEY_Down, RETROK_DOWN }, + { KEY_Enter, RETROK_RETURN }, + { KEY_Tab, RETROK_TAB }, + { KEY_Insert, RETROK_INSERT }, + { KEY_Delete, RETROK_DELETE }, + { KEY_RightShift, RETROK_RSHIFT }, + { KEY_LeftShift, RETROK_LSHIFT }, + { KEY_RightControl, RETROK_RCTRL }, + { KEY_LeftControl, RETROK_LCTRL }, + { KEY_End, RETROK_END }, + { KEY_Home, RETROK_HOME }, + { KEY_PageDown, RETROK_PAGEDOWN }, + { KEY_PageUp, RETROK_PAGEUP }, + { KEY_RightAlt, RETROK_RALT }, + { KEY_LeftAlt, RETROK_LALT }, + { KEY_Space, RETROK_SPACE }, + { KEY_Escape, RETROK_ESCAPE }, + { KEY_Delete, RETROK_BACKSPACE }, + { KP_Enter, RETROK_KP_ENTER }, + { KP_Add, RETROK_KP_PLUS }, + { KP_Subtract, RETROK_KP_MINUS }, + { KP_Multiply, RETROK_KP_MULTIPLY }, + { KP_Divide, RETROK_KP_DIVIDE }, + { KEY_Grave, RETROK_BACKQUOTE }, + { KEY_Pause, RETROK_PAUSE }, + { KP_0, RETROK_KP0 }, + { KP_1, RETROK_KP1 }, + { KP_2, RETROK_KP2 }, + { KP_3, RETROK_KP3 }, + { KP_4, RETROK_KP4 }, + { KP_5, RETROK_KP5 }, + { KP_6, RETROK_KP6 }, + { KP_7, RETROK_KP7 }, + { KP_8, RETROK_KP8 }, + { KP_9, RETROK_KP9 }, + { KEY_0, RETROK_0 }, + { KEY_1, RETROK_1 }, + { KEY_2, RETROK_2 }, + { KEY_3, RETROK_3 }, + { KEY_4, RETROK_4 }, + { KEY_5, RETROK_5 }, + { KEY_6, RETROK_6 }, + { KEY_7, RETROK_7 }, + { KEY_8, RETROK_8 }, + { KEY_9, RETROK_9 }, + { KEY_F1, RETROK_F1 }, + { KEY_F2, RETROK_F2 }, + { KEY_F3, RETROK_F3 }, + { KEY_F4, RETROK_F4 }, + { KEY_F5, RETROK_F5 }, + { KEY_F6, RETROK_F6 }, + { KEY_F7, RETROK_F7 }, + { KEY_F8, RETROK_F8 }, + { KEY_F9, RETROK_F9 }, + { KEY_F10, RETROK_F10 }, + { KEY_F11, RETROK_F11 }, + { KEY_F12, RETROK_F12 }, + { KEY_A, RETROK_a }, + { KEY_B, RETROK_b }, + { KEY_C, RETROK_c }, + { KEY_D, RETROK_d }, + { KEY_E, RETROK_e }, + { KEY_F, RETROK_f }, + { KEY_G, RETROK_g }, + { KEY_H, RETROK_h }, + { KEY_I, RETROK_i }, + { KEY_J, RETROK_j }, + { KEY_K, RETROK_k }, + { KEY_L, RETROK_l }, + { KEY_M, RETROK_m }, + { KEY_N, RETROK_n }, + { KEY_O, RETROK_o }, + { KEY_P, RETROK_p }, + { KEY_Q, RETROK_q }, + { KEY_R, RETROK_r }, + { KEY_S, RETROK_s }, + { KEY_T, RETROK_t }, + { KEY_U, RETROK_u }, + { KEY_V, RETROK_v }, + { KEY_W, RETROK_w }, + { KEY_X, RETROK_x }, + { KEY_Y, RETROK_y }, + { KEY_Z, RETROK_z }, { 0, RETROK_UNKNOWN } }; diff --git a/ios/RetroArch/input/keycode.h b/ios/RetroArch/input/keycode.h new file mode 100644 index 0000000000..e24fe023d4 --- /dev/null +++ b/ios/RetroArch/input/keycode.h @@ -0,0 +1,156 @@ +/* +Taken from https://github.com/depp/keycode, distributed with the following license: + +Copyright 2011-2012 Dietrich Epp +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* This file is automatically generated by keycode.py. */ +#ifndef KEYCODE_KEYCODE_H +#define KEYCODE_KEYCODE_H +enum { + KEY_A = 4, + KEY_B = 5, + KEY_C = 6, + KEY_D = 7, + KEY_E = 8, + KEY_F = 9, + KEY_G = 10, + KEY_H = 11, + KEY_I = 12, + KEY_J = 13, + KEY_K = 14, + KEY_L = 15, + KEY_M = 16, + KEY_N = 17, + KEY_O = 18, + KEY_P = 19, + KEY_Q = 20, + KEY_R = 21, + KEY_S = 22, + KEY_T = 23, + KEY_U = 24, + KEY_V = 25, + KEY_W = 26, + KEY_X = 27, + KEY_Y = 28, + KEY_Z = 29, + KEY_1 = 30, + KEY_2 = 31, + KEY_3 = 32, + KEY_4 = 33, + KEY_5 = 34, + KEY_6 = 35, + KEY_7 = 36, + KEY_8 = 37, + KEY_9 = 38, + KEY_0 = 39, + KEY_Enter = 40, + KEY_Escape = 41, + KEY_Delete = 42, + KEY_Tab = 43, + KEY_Space = 44, + KEY_Minus = 45, + KEY_Equals = 46, + KEY_LeftBracket = 47, + KEY_RightBracket = 48, + KEY_Backslash = 49, + KEY_Semicolon = 51, + KEY_Quote = 52, + KEY_Grave = 53, + KEY_Comma = 54, + KEY_Period = 55, + KEY_Slash = 56, + KEY_CapsLock = 57, + KEY_F1 = 58, + KEY_F2 = 59, + KEY_F3 = 60, + KEY_F4 = 61, + KEY_F5 = 62, + KEY_F6 = 63, + KEY_F7 = 64, + KEY_F8 = 65, + KEY_F9 = 66, + KEY_F10 = 67, + KEY_F11 = 68, + KEY_F12 = 69, + KEY_PrintScreen = 70, + KEY_ScrollLock = 71, + KEY_Pause = 72, + KEY_Insert = 73, + KEY_Home = 74, + KEY_PageUp = 75, + KEY_DeleteForward = 76, + KEY_End = 77, + KEY_PageDown = 78, + KEY_Right = 79, + KEY_Left = 80, + KEY_Down = 81, + KEY_Up = 82, + KP_NumLock = 83, + KP_Divide = 84, + KP_Multiply = 85, + KP_Subtract = 86, + KP_Add = 87, + KP_Enter = 88, + KP_1 = 89, + KP_2 = 90, + KP_3 = 91, + KP_4 = 92, + KP_5 = 93, + KP_6 = 94, + KP_7 = 95, + KP_8 = 96, + KP_9 = 97, + KP_0 = 98, + KP_Point = 99, + KEY_NonUSBackslash = 100, + KP_Equals = 103, + KEY_F13 = 104, + KEY_F14 = 105, + KEY_F15 = 106, + KEY_F16 = 107, + KEY_F17 = 108, + KEY_F18 = 109, + KEY_F19 = 110, + KEY_F20 = 111, + KEY_F21 = 112, + KEY_F22 = 113, + KEY_F23 = 114, + KEY_F24 = 115, + KEY_Help = 117, + KEY_Menu = 118, + KEY_LeftControl = 224, + KEY_LeftShift = 225, + KEY_LeftAlt = 226, + KEY_LeftGUI = 227, + KEY_RightControl = 228, + KEY_RightShift = 229, + KEY_RightAlt = 230, + KEY_RightGUI = 231 +}; +#endif diff --git a/ios/RetroArch/settings/RAButtonGetter.m b/ios/RetroArch/settings/RAButtonGetter.m index ba9582626c..e1b9ed6543 100644 --- a/ios/RetroArch/settings/RAButtonGetter.m +++ b/ios/RetroArch/settings/RAButtonGetter.m @@ -14,6 +14,7 @@ */ #import "settings.h" +#include "../input/keycode.h" #ifdef WIIMOTE # include "../input/BTStack/wiimote.h" @@ -26,54 +27,51 @@ static const struct const char* const keyname; const uint32_t hid_id; } ios_key_name_map[] = { - { "left", 0x50 }, { "right", 0x4F }, - { "up", 0x52 }, { "down", 0x51 }, - { "enter", 0x28 }, { "kp_enter", 0x58 }, - { "tab", 0x2B }, { "insert", 0x49 }, - { "del", 0x4C }, { "end", 0x4D }, - { "home", 0x4A }, { "rshift", 0xE5 }, - { "shift", 0xE1 }, { "ctrl", 0xE0 }, - { "alt", 0xE2 }, { "space", 0x2C }, - { "escape", 0x29 }, { "backspace", 0x2A }, - { "backquote", 0x35 }, { "pause", 0x48 }, + { "left", KEY_Left }, { "right", KEY_Right }, + { "up", KEY_Up }, { "down", KEY_Down }, + { "enter", KEY_Enter }, { "kp_enter", KP_Enter }, + { "space", KEY_Space }, { "tab", KEY_Tab }, + { "shift", KEY_LeftShift }, { "rshift", KEY_RightShift }, + { "ctrl", KEY_LeftControl }, { "alt", KEY_LeftAlt }, + { "escape", KEY_Escape }, { "backspace", KEY_DeleteForward }, + { "backquote", KEY_Grave }, { "pause", KEY_Pause }, + { "f1", KEY_F1 }, { "f2", KEY_F2 }, + { "f3", KEY_F3 }, { "f4", KEY_F4 }, + { "f5", KEY_F5 }, { "f6", KEY_F6 }, + { "f7", KEY_F7 }, { "f8", KEY_F8 }, + { "f9", KEY_F9 }, { "f10", KEY_F10 }, + { "f11", KEY_F11 }, { "f12", KEY_F12 }, + + { "num0", KEY_0 }, { "num1", KEY_1 }, + { "num2", KEY_2 }, { "num3", KEY_3 }, + { "num4", KEY_4 }, { "num5", KEY_5 }, + { "num6", KEY_6 }, { "num7", KEY_7 }, + { "num8", KEY_8 }, { "num9", KEY_9 }, - { "add", 0x57 }, { "subtract", 0x56 }, /*kp_minus?*/ - { "multiply", 0x55 }, { "divide", 0x54 }, - { "kp_plus", 0x57 }, { "kp_minus", 0x56 }, - - { "f1", 0x3A }, { "f2", 0x3B }, - { "f3", 0x3C }, { "f4", 0x3D }, - { "f5", 0x3E }, { "f6", 0x3F }, - { "f7", 0x40 }, { "f8", 0x41 }, - { "f9", 0x42 }, { "f10", 0x43 }, - { "f11", 0x44 }, { "f12", 0x45 }, - - { "num0", 0x27 }, { "num1", 0x1E }, - { "num2", 0x1F }, { "num3", 0x20 }, - { "num4", 0x21 }, { "num5", 0x22 }, - { "num6", 0x23 }, { "num7", 0x24 }, - { "num8", 0x25 }, { "num9", 0x26 }, + { "insert", KEY_Insert }, { "del", KEY_DeleteForward }, + { "home", KEY_Home }, { "end", KEY_End }, + { "pageup", KEY_PageUp }, { "pagedown", KEY_PageDown }, - { "pageup", 0x48 }, { "pagedown", 0x4E }, - { "keypad0", 0x62 }, { "keypad1", 0x59 }, - { "keypad2", 0x5A }, { "keypad3", 0x5B }, - { "keypad4", 0x5C }, { "keypad5", 0x5D }, - { "keypad6", 0x5E }, { "keypad7", 0x5F }, - { "keypad8", 0x60 }, { "keypad9", 0x61 }, + { "add", KP_Add }, { "subtract", KP_Subtract }, + { "multiply", KP_Multiply }, { "divide", KP_Divide }, + { "keypad0", KP_0 }, { "keypad1", KP_1 }, + { "keypad2", KP_2 }, { "keypad3", KP_3 }, + { "keypad4", KP_4 }, { "keypad5", KP_5 }, + { "keypad6", KP_6 }, { "keypad7", KP_7 }, + { "keypad8", KP_8 }, { "keypad9", KP_9 }, - /*{ "period", RETROK_PERIOD }, - { "capslock", RETROK_CAPSLOCK }, { "numlock", RETROK_NUMLOCK }, - { "print_screen", RETROK_PRINT }, - { "scroll_lock", RETROK_SCROLLOCK },*/ - - { "a", 0x04 }, { "b", 0x05 }, { "c", 0x06 }, { "d", 0x07 }, - { "e", 0x08 }, { "f", 0x09 }, { "g", 0x0A }, { "h", 0x0B }, - { "i", 0x0C }, { "j", 0x0D }, { "k", 0x0E }, { "l", 0x0F }, - { "m", 0x10 }, { "n", 0x11 }, { "o", 0x12 }, { "p", 0x13 }, - { "q", 0x14 }, { "r", 0x15 }, { "s", 0x16 }, { "t", 0x17 }, - { "u", 0x18 }, { "v", 0x19 }, { "w", 0x1A }, { "x", 0x1B }, - { "y", 0x1C }, { "z", 0x1D }, + { "period", KEY_Period }, { "capslock", KEY_CapsLock }, + { "numlock", KP_NumLock }, { "print", KEY_PrintScreen }, + { "scroll_lock", KEY_ScrollLock }, + + { "a", KEY_A }, { "b", KEY_B }, { "c", KEY_C }, { "d", KEY_D }, + { "e", KEY_E }, { "f", KEY_F }, { "g", KEY_G }, { "h", KEY_H }, + { "i", KEY_I }, { "j", KEY_J }, { "k", KEY_K }, { "l", KEY_L }, + { "m", KEY_M }, { "n", KEY_N }, { "o", KEY_O }, { "p", KEY_P }, + { "q", KEY_Q }, { "r", KEY_R }, { "s", KEY_S }, { "t", KEY_T }, + { "u", KEY_U }, { "v", KEY_V }, { "w", KEY_W }, { "x", KEY_X }, + { "y", KEY_Y }, { "z", KEY_Z }, { "nul", 0x00}, }; From bda93007bcd563af05d3d114e2bda3d3f5b128b7 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 3 Mar 2013 21:38:44 -0500 Subject: [PATCH 093/108] ios: Small fixes --- ios/RetroArch.xcodeproj/project.pbxproj | 2 ++ ios/RetroArch/main.m | 5 +---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index daee2b6237..9527517a9e 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -199,6 +199,7 @@ 963F5ABE16CC522F009BBD19 /* RASettingsSubList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RASettingsSubList.m; sourceTree = ""; }; 963F5ABF16CC522F009BBD19 /* RASettingsList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RASettingsList.m; sourceTree = ""; }; 963F5AC516CC523B009BBD19 /* RAGameView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAGameView.m; sourceTree = ""; }; + 9664F4A116E4409100FB28F9 /* keycode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keycode.h; sourceTree = ""; }; 966B9C8616E40D44005B61E1 /* ios_input.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ios_input.m; sourceTree = ""; }; 966B9C8716E40D44005B61E1 /* ios_joypad.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ios_joypad.m; sourceTree = ""; }; 966B9C8816E40D44005B61E1 /* RAInputResponder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RAInputResponder.h; sourceTree = ""; }; @@ -403,6 +404,7 @@ 966B9C8F16E418B7005B61E1 /* BTStack */, 966B9C8616E40D44005B61E1 /* ios_input.m */, 966B9C8716E40D44005B61E1 /* ios_joypad.m */, + 9664F4A116E4409100FB28F9 /* keycode.h */, 966B9C8816E40D44005B61E1 /* RAInputResponder.h */, 966B9C8916E40D44005B61E1 /* RAInputResponder.m */, ); diff --git a/ios/RetroArch/main.m b/ios/RetroArch/main.m index 7a65bce6a4..faf433bb63 100644 --- a/ios/RetroArch/main.m +++ b/ios/RetroArch/main.m @@ -30,9 +30,6 @@ NSString *const RATouchNotification = @"RATouchNotification"; @implementation RApplication -#define HWKB_HACK -#ifdef HWKB_HACK // Disabled pending further testing -// Stolen from: http://nacho4d-nacho4d.blogspot.com/2012/01/catching-keyboard-events-in-ios.html - (void)sendEvent:(UIEvent *)event { [super sendEvent:event]; @@ -43,6 +40,7 @@ NSString *const RATouchNotification = @"RATouchNotification"; event, @"event", nil]; [[NSNotificationCenter defaultCenter] postNotificationName:RATouchNotification object:nil userInfo:inf]; } + // Stolen from: http://nacho4d-nacho4d.blogspot.com/2012/01/catching-keyboard-events-in-ios.html else if ([event respondsToSelector:@selector(_gsEvent)]) { int* eventMem = (int *)(void*)CFBridgingRetain([event performSelector:@selector(_gsEvent)]); @@ -67,7 +65,6 @@ NSString *const RATouchNotification = @"RATouchNotification"; CFBridgingRelease(eventMem); } } -#endif @end From e058034a24ec11c1429c8be7e37b30cc2b98dea4 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 3 Mar 2013 23:28:22 -0500 Subject: [PATCH 094/108] (iOS) Make pause button briefly visible when game starts (again), and give it an image background. I took ps_next.png from the overlays dir and flipped it, 'cause I'm lazy. --- ios/Assets/PauseIndicatorView.xib | 52 +++++++++++++----------- ios/Assets/ic_pause.png | Bin 0 -> 2885 bytes ios/RetroArch.xcodeproj/project.pbxproj | 6 +++ ios/RetroArch/RetroArch_iOS.m | 27 ++++++------ 4 files changed, 49 insertions(+), 36 deletions(-) create mode 100644 ios/Assets/ic_pause.png diff --git a/ios/Assets/PauseIndicatorView.xib b/ios/Assets/PauseIndicatorView.xib index 78973a1ccb..36e8e50925 100644 --- a/ios/Assets/PauseIndicatorView.xib +++ b/ios/Assets/PauseIndicatorView.xib @@ -42,12 +42,15 @@ {768, 1005} _NS:9 + + 3 + MCAwAA + NO + 5 IBIPadFramework 0 0 - 1 - Pause 3 MQA @@ -56,9 +59,10 @@ 1 MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA - - 3 - MC41AA + + + NSImage + ic_pause.png 2 @@ -75,13 +79,7 @@ {250, 250} - - 3 - MQA - - 2 - - + NO 0.0 @@ -114,21 +112,21 @@ 1 - + - 4 + 10 0 - 4 + 10 1 0.0 1000 - 8 - 29 - 3 + 5 + 22 + 2 @@ -215,8 +213,8 @@ - 70 - + 72 + @@ -227,30 +225,36 @@ UIResponder com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - + - + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 71 + 72 0 IBIPadFramework YES 3 + + ic_pause.png + {100, 40} + YES 2083 diff --git a/ios/Assets/ic_pause.png b/ios/Assets/ic_pause.png new file mode 100644 index 0000000000000000000000000000000000000000..b024ca8713f557033cd710001b7f920b7316dc8c GIT binary patch literal 2885 zcmV-L3%c})P)Z(`oeP6xms_GuMVHhqqg3IM% z^dNc>{bmdx4VRaf`>U#|nkyXN)1n z5kZAv_>i#&A%`i+@wT+I_!}D=rS5-(*b(df+8}ns5Y-4gG1W0nXe}V?g$6FzkdYn{ z?dXD+GBMsfJnpp^o9Uwzl%KXV1Ft z-o4vMeSAJ&!IC9QhMT1Dp_dD!xZl2gOMOX*kfLLZ;y=MY4Y48vQ(;n(^6}$G)@77B z$YwkUz!8u!{P^+Xo;!E$G=Ts&Bl9fdJ!lp&wUag(R~8)-E02ktkRiAVj*=?8f4|Z1_q)7aubYv1mhqlON`k?e)}5FU zJM=42aFtYTKtwN#5GgQIRu(3iM&G}GAN%m(gPN;tbu)QMGAaN#fv*=bL;;PIde&iG z+!IfcY8g$58L>mB`f`_;It~;kLWH>lQt)7kzI^$TW!ahn637s*u%j#GBrFF=aT7CQ z2R-!xu49~FLINS$w8cu&h=Ry)=hLT8S;jU@GZ~U1LlnvpQWRDuW(h|m(9^=thPeV) z?9fwbz*LxxJ$UdST31(>K%(C0FXj71hUkzBq!24&2Aw#d1xFoQQP)a)16Rn9H1_)S z>y9T+o^Z;_l$WGLhFF(HQiz#{SP?Vig%H7#sblCyh~`4lNSI~XdG6dfGM;x)12bfsfRHI=R!)|Tqs2(j*TW!R8W1jeulYX|G}lE3+IPnry>8IQ-^ zjLbWQERaIa;D(ha2I3vWQ1En8QA2A|U$je~Xu}s)|=z2O5qE|5UB8P+69{f?uEQdnClc zODv|JJ$u%A;lc%WmJTl=5LCF|WPpSK*7(7hGiP=%GS9LUNudq{C51A4#D*A|c3HTY z*FAa%?khlC&a;I18&rz6CK=JBW>k zJ9A(|eK=rQrpI2%K;0hqA-v}lEJ9wqc+q<3&>_x|eD9uWAQ>T$@jo1)D}aOy0%?y< zWNh5Hk)U!=#F!^RPM%_y#luMUMN-%|b)YVY)G5^vAST2H0xYchBg_pa=(E1*C9KEM z!>FDgWo2c7ix)4JO`JH9fN*)&pV39bgFJ7-39S#nG!h`5PdNpWfw~^Nee)CW1q&9m zZr;4PE)WRFvXad_c(D8T?b}y^C1<#_w6uNDph2CGt31U?E?%v=FvS^Drc5bVzI=Jq z^b`)X9;b5$IRw%F=+PtZ!i5WeAkaH?LKMi_W57W~S5Z=guxbyaxTa2>T6p>L<&wg} zLb^LUPKFfL3-IOA;lqc+w{PEW4u`|))E4EAfh#Bw;`{ykw;x{6ykWzJ+F&rKrX@5` z1|wC21uugFd-v`w#q^a|TwL5)P*4zs{!*u#d=kR<-qWT{%UivAbt~%gB^PBUYl|BT zipc!=^Xu;2yVqcLzyZfTRlmuQ!FH(-qT1m{R$1;{yLJuQvSmvcWy#FJO2Kd6z75~K zdw1E58#mhW^78m{$%WUjl$vNLDS z6p;*gUY}DDmd-9L4nnZy$B-dIKAMX3MGE_mz?N1#%YGs+`UoLPOxg*dRGXKuNZi_Y z<;s)~%vQB*N*$GMb><8}J(5;hr#ILgV)B+iNhb zkPI>0sXArQqx?H|>=^p^@#6xtVf}7F_Z&=%21dGP)~s3e+qP|^mndDkHTqLP(8E`+ zUNz>;n^%Lpj3^;r^_eUg6q~e%urfmrq!?qyj0s)3bZO{_5hJKnpL6inuU~zT<)J(? zFt5Ch-k>_e51tXUC(a*CB^>}(jCKTA+96fMa+<@`7?3_>^9Z?I@u*R3%2$1`AB6a@ zVZ)>!O=LorZG(6{>%;S`=K1sI+;_0gl*ypf` z;T&uMi@ZIE;v$2oMAl_qKxZm>-b*F)C0pc6+L!JDJiLR;mM!}RPj7}olrJ_Z8DzG< zil#&eJK=~kJJVBR#*7(7STzmC>V{KSU!<5KtVCp41<3TmexQ92^uW)bKf_p+ zeZP70CYRlmDSD<%26auD5Y_k(De98)5Oq@M#(hp-Z2XS|k`V+MAqO&qkUlqmz1iBE zTlUsY-LttQ6=HN_)cjtvW=#zg=Z9;2r%gjFg^~Z)0(GYi5!yuCXd|x0Gc4O|nDpDu z0eOh@rcGZgk}1KMG-*=asZ*zh;p=&pH}MBS?sr|~{;zJ~xh!Bnn2J>1{H(p;h!GLNQz-4L?A`c_~6>p&()Rj6H(FWQ=n{X|IO4-_F zy=6acrykPcA$s?AZ-KILlz9&xJXp4B)v6LKH~FBKU42>xgx-Ie@+5+wN3cu|96frp zZtdE&KVVA?woqpobZPMlUFWm|VjC@TS{&!RyK?2q&-iGJh882rhtZaCx?)+%i&s#$ z;&<=fxv4XC$2A8Qbx*rj=(eWaLlT5{8DJHWEEM_n@84evLrbvH<2`x{y@r7XGiEXn zU>OuVxsG5X={k1oSl#;d>uaGh&%qLOq8)!r!M{p~D6JbL#!Q|(IfRi{I%m$DLhi;< zSC+`kXMz~^BYn{$Lfpk)yLPPsN9eV9R!|>(zm@jsiSq3sBZNq&PQ>89cj0yG)|FsG z35O}**DPEBaPK1LRcxLPf`kB($8&yq1W%n~SjILUIB=k@s;Y_`+KdyyJ{dAfNLQC# zze0|9%;?dh12|SM#35b5$dMyM@EVf9^CV7ZeBZ)6L6wj&jYy%E+Us()M8Zh|KZr2i zym`}xL(xVY(>LIgPc?1Y_0r^JB%3utda{myj2kyDgcH|%yq}2RpT8j-!w^WWe7Fc9 zG2%Ts=qR>=coe-rmf9X{>SFjuY#ZLcwBW0dCVa@&CIiB1ndMB*5u)Qka!J=s2?jTDvI)h1FY=Yv0`ck j8SU6l#Bz-U-RA!T=flI-s0QP!00000NkvXXu0mjfbuW4? literal 0 HcmV?d00001 diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 9527517a9e..fbde213b57 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -125,6 +125,8 @@ 966B9CCA16E41EC1005B61E1 /* PauseView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CC716E41EC1005B61E1 /* PauseView.xib */; }; 966B9CCB16E41EC1005B61E1 /* PauseIndicatorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CC816E41EC1005B61E1 /* PauseIndicatorView.xib */; }; 966B9CCC16E41EC1005B61E1 /* PauseIndicatorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CC816E41EC1005B61E1 /* PauseIndicatorView.xib */; }; + 967D646F16E45428006BA1F2 /* ic_pause.png in Resources */ = {isa = PBXBuildFile; fileRef = 967D646E16E45428006BA1F2 /* ic_pause.png */; }; + 967D647016E45428006BA1F2 /* ic_pause.png in Resources */ = {isa = PBXBuildFile; fileRef = 967D646E16E45428006BA1F2 /* ic_pause.png */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -233,6 +235,7 @@ 966B9CBC16E41E7A005B61E1 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; 966B9CC716E41EC1005B61E1 /* PauseView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PauseView.xib; sourceTree = ""; }; 966B9CC816E41EC1005B61E1 /* PauseIndicatorView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PauseIndicatorView.xib; sourceTree = ""; }; + 967D646E16E45428006BA1F2 /* ic_pause.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ic_pause.png; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -464,6 +467,7 @@ 966B9CBA16E41E7A005B61E1 /* Default@2x.png */, 962979F416C43B9500E6DCE0 /* ic_dir.png */, 962979F516C43B9500E6DCE0 /* ic_file.png */, + 967D646E16E45428006BA1F2 /* ic_pause.png */, 966B9CBB16E41E7A005B61E1 /* Icon-72.png */, 966B9CBC16E41E7A005B61E1 /* Icon.png */, 966B9CC716E41EC1005B61E1 /* PauseView.xib */, @@ -832,6 +836,7 @@ 966B9CC616E41E7A005B61E1 /* Icon.png in Resources */, 966B9CCA16E41EC1005B61E1 /* PauseView.xib in Resources */, 966B9CCC16E41EC1005B61E1 /* PauseIndicatorView.xib in Resources */, + 967D647016E45428006BA1F2 /* ic_pause.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -850,6 +855,7 @@ 966B9CC516E41E7A005B61E1 /* Icon.png in Resources */, 966B9CC916E41EC1005B61E1 /* PauseView.xib in Resources */, 966B9CCB16E41EC1005B61E1 /* PauseIndicatorView.xib in Resources */, + 967D646F16E45428006BA1F2 /* ic_pause.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index d0713e6d6b..c57a186f73 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -152,6 +152,17 @@ _pauseView.frame = CGRectMake(width / 2.0f - 150.0f, height / 2.0f - 150.0f, 300.0f, 300.0f); _pauseIndicatorView.frame = CGRectMake(tenpctw * 4.0f, 0.0f, tenpctw * 2.0f, tenpcth); + _pauseIndicatorView.hidden = NO; + + [self performSelector:@selector(hidePauseButton) withObject:self afterDelay:3.0f]; +} + +- (void)hidePauseButton +{ + [UIView animateWithDuration:0.2 + animations:^ { _pauseIndicatorView.alpha = ALMOST_INVISIBLE; } + completion:^(BOOL finished) { } + ]; } - (void)pushViewController:(UIViewController*)theView isGame:(BOOL)game @@ -171,8 +182,8 @@ { _game = (RAGameView*)theView; - _pauseIndicatorView.alpha = ALMOST_INVISIBLE; - _pauseIndicatorView.userInteractionEnabled = YES; + _pauseIndicatorView.alpha = 1.0f; + _pauseIndicatorView.hidden = YES; [theView.view addSubview:_pauseView]; [theView.view addSubview:_pauseIndicatorView]; @@ -303,11 +314,7 @@ stateSelect.selectedSegmentIndex = (g_extern.state_slot < 10) ? g_extern.state_slot : -1; [UIView animateWithDuration:0.2 - animations:^ - { - _pauseIndicatorView.alpha = ALMOST_INVISIBLE; - _pauseView.alpha = 1.0f; - } + animations:^ { _pauseView.alpha = 1.0f; } completion:^(BOOL finished){}]; } } @@ -339,11 +346,7 @@ { if (_isPaused) [UIView animateWithDuration:0.2 - animations:^ - { - _pauseView.alpha = 0.0f; - _pauseIndicatorView.alpha = ALMOST_INVISIBLE; - } + animations:^ { _pauseView.alpha = 0.0f; } completion:^(BOOL finished) { _isPaused = false; From 9914dff82a00f1c70ca810595f63cbaad56f5081 Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 4 Mar 2013 01:14:26 -0500 Subject: [PATCH 095/108] (iOS) Handle general options on settings menu better --- ios/RetroArch/settings/RASettingsList.m | 87 ++++++++-------------- ios/RetroArch/settings/RASettingsSubList.m | 19 ++++- ios/RetroArch/settings/settings.h | 3 +- 3 files changed, 47 insertions(+), 62 deletions(-) diff --git a/ios/RetroArch/settings/RASettingsList.m b/ios/RetroArch/settings/RASettingsList.m index 35d05de819..5bd63316aa 100644 --- a/ios/RetroArch/settings/RASettingsList.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -26,7 +26,7 @@ static NSString* get_value_from_config(RAConfig* config, NSString* name, NSStrin static RASettingData* boolean_setting(RAConfig* config, NSString* name, NSString* label, NSString* defaultValue) { - RASettingData* result = [[RASettingData alloc] init]; + RASettingData* result = [RASettingData new]; result.type = BooleanSetting; result.label = label; result.name = name; @@ -36,7 +36,7 @@ static RASettingData* boolean_setting(RAConfig* config, NSString* name, NSString static RASettingData* button_setting(RAConfig* config, NSString* name, NSString* label, NSString* defaultValue) { - RASettingData* result = [[RASettingData alloc] init]; + RASettingData* result = [RASettingData new]; result.type = ButtonSetting; result.label = label; result.name = name; @@ -49,7 +49,7 @@ static RASettingData* button_setting(RAConfig* config, NSString* name, NSString* static RASettingData* group_setting(NSString* label, NSArray* settings) { - RASettingData* result = [[RASettingData alloc] init]; + RASettingData* result = [RASettingData new]; result.type = GroupSetting; result.label = label; result.subValues = settings; @@ -58,7 +58,7 @@ static RASettingData* group_setting(NSString* label, NSArray* settings) static RASettingData* enumeration_setting(RAConfig* config, NSString* name, NSString* label, NSString* defaultValue, NSArray* values) { - RASettingData* result = [[RASettingData alloc] init]; + RASettingData* result = [RASettingData new]; result.type = EnumerationSetting; result.label = label; result.name = name; @@ -75,7 +75,7 @@ static RASettingData* subpath_setting(RAConfig* config, NSString* name, NSString NSArray* values = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:path error:nil]; values = [values pathsMatchingExtensions:[NSArray arrayWithObject:extension]]; - RASettingData* result = [[RASettingData alloc] init]; + RASettingData* result = [RASettingData new]; result.type = FileListSetting; result.label = label; result.name = name; @@ -85,6 +85,14 @@ static RASettingData* subpath_setting(RAConfig* config, NSString* name, NSString return result; } +static RASettingData* custom_action(NSString* action) +{ + RASettingData* result = [RASettingData new]; + result.type = CustomAction; + result.label = action; + return result; +} + @implementation RASettingsList + (void)refreshConfigFile { @@ -99,6 +107,13 @@ static RASettingData* subpath_setting(RAConfig* config, NSString* name, NSString NSString* shader_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/shaders/"]; NSArray* settings = [NSArray arrayWithObjects: + [NSArray arrayWithObjects:@"General", + custom_action(@"Module Info"), +#ifdef WIIMOTE + custom_action(@"Connect WiiMotes"); +#endif + nil], + [NSArray arrayWithObjects:@"Video", boolean_setting(config, @"video_smooth", @"Smooth Video", @"true"), boolean_setting(config, @"video_crop_overscan", @"Crop Overscan", @"true"), @@ -171,6 +186,15 @@ static RASettingData* subpath_setting(RAConfig* config, NSString* name, NSString [self writeToDisk]; } +- (void)handleCustomAction:(NSString*)action +{ + if ([@"Module Info" isEqualToString:action]) + [[RetroArch_iOS get] pushViewController:[[RAModuleInfoList alloc] initWithModuleInfo:[RetroArch_iOS get].moduleInfo] isGame:NO]; + else if([@"Connect WiiMotes" isEqualToString:action]) + [[RetroArch_iOS get] showWiiRemoteConfig]; +} + + - (void)writeToDisk { RAConfig* config = [[RAConfig alloc] initWithPath:[RetroArch_iOS get].moduleInfo.configPath]; @@ -181,57 +205,4 @@ static RASettingData* subpath_setting(RAConfig* config, NSString* name, NSString [config writeToFile:[RetroArch_iOS get].moduleInfo.configPath]; } -// Override tableView methods to add General section at top. -- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath -{ - if (indexPath.section == 0) - { - if (indexPath.row == 0) - [[RetroArch_iOS get] pushViewController:[[RAModuleInfoList alloc] initWithModuleInfo:[RetroArch_iOS get].moduleInfo] isGame:NO]; - else if(indexPath.row == 1) - [[RetroArch_iOS get] showWiiRemoteConfig]; - } - else - [super tableView:tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section - 1]]; -} - -- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath -{ - if (indexPath.section == 0) - { - UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"general"]; - cell = cell ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"general"]; - - cell.textLabel.text = (indexPath.row == 0) ? @"Module Info" : @"Connect WiiMotes"; - return cell; - } - else - return [super tableView:tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section - 1]]; -} - -- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView -{ - return [super numberOfSectionsInTableView:tableView] + 1; -} - -- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section -{ - if (section == 0) -#ifdef WIIMOTE - return 2; -#else - return 1; -#endif - - return [super tableView:tableView numberOfRowsInSection:section - 1] ; -} - -- (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section -{ - if (section == 0) - return @"General"; - - return [super tableView:tableView titleForHeaderInSection:section - 1]; -} - @end diff --git a/ios/RetroArch/settings/RASettingsSubList.m b/ios/RetroArch/settings/RASettingsSubList.m index 7bfe88638c..bd326e2872 100644 --- a/ios/RetroArch/settings/RASettingsSubList.m +++ b/ios/RetroArch/settings/RASettingsSubList.m @@ -32,6 +32,11 @@ static const char* const SETTINGID = "SETTING"; return self; } +- (void)handleCustomAction:(NSString*)action +{ + +} + - (void)writeSettings:(NSArray*)settingList toConfig:(RAConfig*)config { NSArray* list = settingList ? settingList : settings; @@ -45,7 +50,7 @@ static const char* const SETTINGID = "SETTING"; RASettingData* setting = [group objectAtIndex:j]; switch (setting.type) - { + { case GroupSetting: [self writeSettings:setting.subValues toConfig:config]; break; @@ -64,6 +69,9 @@ static const char* const SETTINGID = "SETTING"; [config putStringNamed:[setting.name stringByAppendingString:@"_btn"] value:setting.msubValues[1]]; break; + case CustomAction: + break; + default: [config putStringNamed:setting.name value:setting.value]; break; @@ -91,12 +99,16 @@ static const char* const SETTINGID = "SETTING"; [[RetroArch_iOS get] pushViewController:[[RASettingsSubList alloc] initWithSettings:setting.subValues title:setting.label] isGame:NO]; break; + case CustomAction: + [self handleCustomAction:setting.label]; + break; + default: break; } } -- (void)handle_boolean_switch:(UISwitch*)swt +- (void)handleBooleanSwitch:(UISwitch*)swt { RASettingData* setting = objc_getAssociatedObject(swt, SETTINGID); setting.value = (swt.on ? @"true" : @"false"); @@ -119,7 +131,7 @@ static const char* const SETTINGID = "SETTING"; cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"boolean"]; UISwitch* accessory = [[UISwitch alloc] init]; - [accessory addTarget:self action:@selector(handle_boolean_switch:) forControlEvents:UIControlEventValueChanged]; + [accessory addTarget:self action:@selector(handleBooleanSwitch:) forControlEvents:UIControlEventValueChanged]; cell.accessoryView = accessory; [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; @@ -134,6 +146,7 @@ static const char* const SETTINGID = "SETTING"; case EnumerationSetting: case FileListSetting: case ButtonSetting: + case CustomAction: { cell = [self.tableView dequeueReusableCellWithIdentifier:@"enumeration"]; cell = cell ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"enumeration"]; diff --git a/ios/RetroArch/settings/settings.h b/ios/RetroArch/settings/settings.h index 2349bafb7b..748edc4e85 100644 --- a/ios/RetroArch/settings/settings.h +++ b/ios/RetroArch/settings/settings.h @@ -15,7 +15,7 @@ enum SettingTypes { - BooleanSetting, ButtonSetting, EnumerationSetting, FileListSetting, GroupSetting + BooleanSetting, ButtonSetting, EnumerationSetting, FileListSetting, GroupSetting, CustomAction }; @interface RASettingData : NSObject @@ -40,6 +40,7 @@ enum SettingTypes @interface RASettingsSubList : UITableViewController - (id)initWithSettings:(NSArray*)values title:(NSString*)title; +- (void)handleCustomAction:(NSString*)action; - (void)writeSettings:(NSArray*)settingList toConfig:(RAConfig*)config; @end From e4596f20b9324f6631bcf9196fe07a89e2aa46d5 Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 4 Mar 2013 01:21:45 -0500 Subject: [PATCH 096/108] (iOS) Allow a custom display name to specified in a libretro core's info file. --- ios/RetroArch/RAModuleInfoList.m | 1 + ios/RetroArch/browser/RAModuleList.m | 2 +- ios/RetroArch/views.h | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ios/RetroArch/RAModuleInfoList.m b/ios/RetroArch/RAModuleInfoList.m index 8572567941..af3d0764d7 100644 --- a/ios/RetroArch/RAModuleInfoList.m +++ b/ios/RetroArch/RAModuleInfoList.m @@ -18,6 +18,7 @@ { RAModuleInfo* new = [RAModuleInfo new]; + new.displayName = [theData getStringNamed:@"display_name" withDefault:[[thePath lastPathComponent] stringByDeletingPathExtension]]; new.path = thePath; new.configPath = [NSString stringWithFormat:@"%@/%@.cfg", [RetroArch_iOS get].system_directory, [[thePath lastPathComponent] stringByDeletingPathExtension]]; new.data = theData; diff --git a/ios/RetroArch/browser/RAModuleList.m b/ios/RetroArch/browser/RAModuleList.m index 0894f1560e..3af24127e6 100644 --- a/ios/RetroArch/browser/RAModuleList.m +++ b/ios/RetroArch/browser/RAModuleList.m @@ -112,7 +112,7 @@ unsigned section = _sectionMap[indexPath.section]; RAModuleInfo* info = (RAModuleInfo*)[_modules[section] objectAtIndex:indexPath.row]; - cell.textLabel.text = [[info.path lastPathComponent] stringByDeletingPathExtension]; + cell.textLabel.text = info.displayName; cell.accessoryType = (info.data) ? UITableViewCellAccessoryDetailDisclosureButton : UITableViewCellAccessoryNone; return cell; diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index 58121ec0e0..71174e8e75 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -22,6 +22,7 @@ @end @interface RAModuleInfo : NSObject +@property (strong) NSString* displayName; @property (strong) NSString* path; @property (strong) NSString* configPath; @property (strong) RAConfig* data; From 6d94f278d40db2f507f12f777c6b1af97dbdb8d7 Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 4 Mar 2013 01:37:00 -0500 Subject: [PATCH 097/108] (iOS) Some style cleanups to the settings code. --- ios/RetroArch/settings/RAButtonGetter.m | 4 --- .../settings/RASettingEnumerationList.m | 27 ++++++-------- ios/RetroArch/settings/RASettingsList.m | 36 +++++++------------ ios/RetroArch/settings/RASettingsSubList.m | 1 - ios/RetroArch/settings/settings.h | 2 ++ 5 files changed, 26 insertions(+), 44 deletions(-) diff --git a/ios/RetroArch/settings/RAButtonGetter.m b/ios/RetroArch/settings/RAButtonGetter.m index e1b9ed6543..3db1f41eb8 100644 --- a/ios/RetroArch/settings/RAButtonGetter.m +++ b/ios/RetroArch/settings/RAButtonGetter.m @@ -79,12 +79,8 @@ static const struct static NSString* get_key_config_name(uint32_t hid_id) { for (int i = 0; ios_key_name_map[i].hid_id; i ++) - { if (hid_id == ios_key_name_map[i].hid_id) - { return [NSString stringWithUTF8String:ios_key_name_map[i].keyname]; - } - } return @"nul"; } diff --git a/ios/RetroArch/settings/RASettingEnumerationList.m b/ios/RetroArch/settings/RASettingEnumerationList.m index accadfbb53..96d51e0a5e 100644 --- a/ios/RetroArch/settings/RASettingEnumerationList.m +++ b/ios/RetroArch/settings/RASettingEnumerationList.m @@ -17,17 +17,18 @@ @implementation RASettingEnumerationList { - RASettingData* value; - UITableView* view; + RASettingData* _value; + UITableView* _view; }; - (id)initWithSetting:(RASettingData*)setting fromTable:(UITableView*)table { self = [super initWithStyle:UITableViewStyleGrouped]; - value = setting; - view = table; - [self setTitle: value.label]; + _value = setting; + _view = table; + + [self setTitle: _value.label]; return self; } @@ -38,30 +39,24 @@ - (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section { - return (section == 1) ? [value.subValues count] : 1; + return (section == 1) ? [_value.subValues count] : 1; } - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"option"]; cell = cell ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"option"]; - - if (indexPath.section == 1) - cell.textLabel.text = [value.subValues objectAtIndex:indexPath.row]; - else - cell.textLabel.text = @"None"; + + cell.textLabel.text = (indexPath.section == 1) ? [_value.subValues objectAtIndex:indexPath.row] : @"None"; return cell; } - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - if (indexPath.section == 1) - value.value = [value.subValues objectAtIndex:indexPath.row]; - else - value.value = @""; + _value.value = (indexPath.section == 1) ? [_value.subValues objectAtIndex:indexPath.row] : @""; - [view reloadData]; + [_view reloadData]; [[RetroArch_iOS get] popViewController]; } diff --git a/ios/RetroArch/settings/RASettingsList.m b/ios/RetroArch/settings/RASettingsList.m index 5bd63316aa..42354c863c 100644 --- a/ios/RetroArch/settings/RASettingsList.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -17,6 +17,13 @@ #import "settings.h" @implementation RASettingData +- (id)initWithType:(enum SettingTypes)aType label:(NSString*)aLabel name:(NSString*)aName +{ + self.type = aType; + self.label = aLabel; + self.name = aName; + return self; +} @end static NSString* get_value_from_config(RAConfig* config, NSString* name, NSString* defaultValue) @@ -26,20 +33,14 @@ static NSString* get_value_from_config(RAConfig* config, NSString* name, NSStrin static RASettingData* boolean_setting(RAConfig* config, NSString* name, NSString* label, NSString* defaultValue) { - RASettingData* result = [RASettingData new]; - result.type = BooleanSetting; - result.label = label; - result.name = name; + RASettingData* result = [[RASettingData alloc] initWithType:BooleanSetting label:label name:name]; result.value = get_value_from_config(config, name, defaultValue); return result; } static RASettingData* button_setting(RAConfig* config, NSString* name, NSString* label, NSString* defaultValue) { - RASettingData* result = [RASettingData new]; - result.type = ButtonSetting; - result.label = label; - result.name = name; + RASettingData* result = [[RASettingData alloc] initWithType:ButtonSetting label:label name:name]; result.msubValues = [NSMutableArray arrayWithObjects: get_value_from_config(config, name, defaultValue), get_value_from_config(config, [name stringByAppendingString:@"_btn"], @""), @@ -49,19 +50,14 @@ static RASettingData* button_setting(RAConfig* config, NSString* name, NSString* static RASettingData* group_setting(NSString* label, NSArray* settings) { - RASettingData* result = [RASettingData new]; - result.type = GroupSetting; - result.label = label; + RASettingData* result = [[RASettingData alloc] initWithType:GroupSetting label:label name:nil]; result.subValues = settings; return result; } static RASettingData* enumeration_setting(RAConfig* config, NSString* name, NSString* label, NSString* defaultValue, NSArray* values) { - RASettingData* result = [RASettingData new]; - result.type = EnumerationSetting; - result.label = label; - result.name = name; + RASettingData* result = [[RASettingData alloc] initWithType:EnumerationSetting label:label name:name]; result.value = get_value_from_config(config, name, defaultValue); result.subValues = values; return result; @@ -75,10 +71,7 @@ static RASettingData* subpath_setting(RAConfig* config, NSString* name, NSString NSArray* values = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:path error:nil]; values = [values pathsMatchingExtensions:[NSArray arrayWithObject:extension]]; - RASettingData* result = [RASettingData new]; - result.type = FileListSetting; - result.label = label; - result.name = name; + RASettingData* result = [[RASettingData alloc] initWithType:FileListSetting label:label name:name]; result.value = value; result.subValues = values; result.path = path; @@ -87,10 +80,7 @@ static RASettingData* subpath_setting(RAConfig* config, NSString* name, NSString static RASettingData* custom_action(NSString* action) { - RASettingData* result = [RASettingData new]; - result.type = CustomAction; - result.label = action; - return result; + return [[RASettingData alloc] initWithType:CustomAction label:action name:nil]; } @implementation RASettingsList diff --git a/ios/RetroArch/settings/RASettingsSubList.m b/ios/RetroArch/settings/RASettingsSubList.m index bd326e2872..c7b2ae2825 100644 --- a/ios/RetroArch/settings/RASettingsSubList.m +++ b/ios/RetroArch/settings/RASettingsSubList.m @@ -194,5 +194,4 @@ static const char* const SETTINGID = "SETTING"; return [[settings objectAtIndex:section] objectAtIndex:0]; } - @end diff --git a/ios/RetroArch/settings/settings.h b/ios/RetroArch/settings/settings.h index 748edc4e85..9c7b18e5da 100644 --- a/ios/RetroArch/settings/settings.h +++ b/ios/RetroArch/settings/settings.h @@ -28,6 +28,8 @@ enum SettingTypes @property (strong) NSString* path; @property (strong) NSArray* subValues; @property (strong) NSMutableArray* msubValues; + +- (id)initWithType:(enum SettingTypes)aType label:(NSString*)aLabel name:(NSString*)aName; @end @interface RAButtonGetter : NSObject From 30209b3ca9fdd4148e08c64981366fc4cdbc9516 Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 4 Mar 2013 05:03:13 -0500 Subject: [PATCH 098/108] (iOS) In module's .info file consolodate suggested_extension and recommended_extensions into supported_extensions. It occured to me that all three sections would never be used at the same time. --- ios/RetroArch/RAModuleInfoList.m | 14 ++----- ios/RetroArch/browser/RAModuleList.m | 56 +++++++++++++--------------- ios/RetroArch/views.h | 5 +-- 3 files changed, 31 insertions(+), 44 deletions(-) diff --git a/ios/RetroArch/RAModuleInfoList.m b/ios/RetroArch/RAModuleInfoList.m index af3d0764d7..3ad1ba2c89 100644 --- a/ios/RetroArch/RAModuleInfoList.m +++ b/ios/RetroArch/RAModuleInfoList.m @@ -23,21 +23,13 @@ new.configPath = [NSString stringWithFormat:@"%@/%@.cfg", [RetroArch_iOS get].system_directory, [[thePath lastPathComponent] stringByDeletingPathExtension]]; new.data = theData; - new.recommendedExtensions = [[theData getStringNamed:@"recommended_extensions" withDefault:@""] componentsSeparatedByString:@"|"]; - new.suggestedExtensions = [[theData getStringNamed:@"suggested_extensions" withDefault:@""] componentsSeparatedByString:@"|"]; + new.supportedExtensions = [[theData getStringNamed:@"supported_extensions" withDefault:@""] componentsSeparatedByString:@"|"]; return new; } -- (unsigned)supportLevelOfPath:(NSString*)thePath +- (bool)supportsFileAtPath:(NSString*)path { - NSString* ext = [thePath pathExtension]; - - if ([self.recommendedExtensions containsObject:ext]) - return 0; - else if([self.suggestedExtensions containsObject:ext]) - return 1; - - return 2; + return [self.supportedExtensions containsObject:[[path pathExtension] lowercaseString]]; } @end diff --git a/ios/RetroArch/browser/RAModuleList.m b/ios/RetroArch/browser/RAModuleList.m index 3af24127e6..0430803900 100644 --- a/ios/RetroArch/browser/RAModuleList.m +++ b/ios/RetroArch/browser/RAModuleList.m @@ -17,10 +17,8 @@ @implementation RAModuleList { - NSMutableArray* _modules[3]; - - unsigned _sectionCount; - unsigned _sectionMap[3]; + NSMutableArray* _supported; + NSMutableArray* _other; NSString* _game; } @@ -47,9 +45,8 @@ } // Load the modules with their data - _modules[0] = [NSMutableArray array]; - _modules[1] = [NSMutableArray array]; - _modules[2] = [NSMutableArray array]; + _supported = [NSMutableArray array]; + _other = [NSMutableArray array]; for (int i = 0; i != [moduleList count]; i ++) { @@ -57,51 +54,49 @@ NSString* baseName = [[modulePath stringByDeletingPathExtension] stringByAppendingPathExtension:@"info"]; RAModuleInfo* module = [RAModuleInfo moduleWithPath:modulePath data:[[RAConfig alloc] initWithPath:baseName]]; - [_modules[[module supportLevelOfPath:_game]] addObject:module]; + + if ([module supportsFileAtPath:_game]) + [_supported addObject:module]; + else + [_other addObject:module]; } - - for (int i = 0; i != 3; i ++) - if ([_modules[i] count]) - { - _sectionMap[_sectionCount] = i; - _sectionCount ++; - } - + [self setTitle:[_game lastPathComponent]]; return self; } - (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView { - return _sectionCount; + return _supported.count ? 2 : 1; } - (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section { - switch (_sectionMap[section]) - { - case 0: return @"Recommended Emulators"; - case 1: return @"Suggested Emulators"; - default: return @"Other Emulators"; - } + if (_supported.count) + return (section == 0) ? @"Suggested Emulators" : @"Other Emulators"; + + return @"All Emulators"; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return _modules[section] ? [_modules[_sectionMap[section]] count] : 0; + NSMutableArray* sectionData = (_supported.count && section == 0) ? _supported : _other; + return sectionData.count; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - unsigned section = _sectionMap[indexPath.section]; - [RetroArch_iOS get].moduleInfo = (RAModuleInfo*)[_modules[section] objectAtIndex:indexPath.row];; + NSMutableArray* sectionData = (_supported.count && indexPath.section == 0) ? _supported : _other; + [RetroArch_iOS get].moduleInfo = (RAModuleInfo*)sectionData[indexPath.row]; + [[RetroArch_iOS get] runGame:_game]; } - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath { - unsigned section = _sectionMap[indexPath.section]; - [RetroArch_iOS get].moduleInfo = (RAModuleInfo*)[_modules[section] objectAtIndex:indexPath.row]; + NSMutableArray* sectionData = (_supported.count && indexPath.section == 0) ? _supported : _other; + [RetroArch_iOS get].moduleInfo = (RAModuleInfo*)sectionData[indexPath.row]; + [[RetroArch_iOS get] showSettings]; } @@ -110,8 +105,9 @@ UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"module"]; cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"module"]; - unsigned section = _sectionMap[indexPath.section]; - RAModuleInfo* info = (RAModuleInfo*)[_modules[section] objectAtIndex:indexPath.row]; + NSMutableArray* sectionData = (_supported.count && indexPath.section == 0) ? _supported : _other; + RAModuleInfo* info = (RAModuleInfo*)sectionData[indexPath.row]; + cell.textLabel.text = info.displayName; cell.accessoryType = (info.data) ? UITableViewCellAccessoryDetailDisclosureButton : UITableViewCellAccessoryNone; diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index 71174e8e75..06efbe1fed 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -26,11 +26,10 @@ @property (strong) NSString* path; @property (strong) NSString* configPath; @property (strong) RAConfig* data; -@property (strong) NSArray* recommendedExtensions; -@property (strong) NSArray* suggestedExtensions; +@property (strong) NSArray* supportedExtensions; + (RAModuleInfo*)moduleWithPath:(NSString*)thePath data:(RAConfig*)theData; -- (unsigned)supportLevelOfPath:(NSString*)thePath; +- (bool)supportsFileAtPath:(NSString*)path; @end @interface RAModuleInfoList : UITableViewController From 735bbdd013f62852f4d792827a8c320dc0200685 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 5 Mar 2013 00:14:26 -0500 Subject: [PATCH 099/108] (iOS) Major refactoring and simplification of UI logic --- ios/RetroArch/RAGameView.m | 155 +++++--- ios/RetroArch/RetroArch_iOS.h | 7 +- ios/RetroArch/RetroArch_iOS.m | 347 ++++++------------ ios/RetroArch/browser/RADirectoryGrid.m | 6 +- ios/RetroArch/browser/RADirectoryList.m | 6 +- ios/RetroArch/input/BTStack/WiiMoteHelper.m | 2 +- .../settings/RASettingEnumerationList.m | 2 +- ios/RetroArch/settings/RASettingsList.m | 5 +- ios/RetroArch/settings/RASettingsSubList.m | 4 +- ios/RetroArch/views.h | 3 + 10 files changed, 228 insertions(+), 309 deletions(-) diff --git a/ios/RetroArch/RAGameView.m b/ios/RetroArch/RAGameView.m index 77cdbde6d7..22f1d67860 100644 --- a/ios/RetroArch/RAGameView.m +++ b/ios/RetroArch/RAGameView.m @@ -16,102 +16,157 @@ #include "general.h" #include "rarch_wrapper.h" -static float screen_scale; -static int frame_skips = 4; -static bool is_syncing = true; +static const float ALMOST_INVISIBLE = .021f; +static float g_screen_scale; +static int g_frame_skips = 4; +static bool g_is_syncing = true; +static RAGameView* g_instance; @implementation RAGameView { EAGLContext* _glContext; + + UIView* _pauseView; + UIView* _pauseIndicatorView; +} + ++ (RAGameView*)get +{ + if (!g_instance) + g_instance = [RAGameView new]; + + return g_instance; } - (id)init { self = [super init]; - screen_scale = [[UIScreen mainScreen] scale]; - - _glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - [EAGLContext setCurrentContext:_glContext]; + + UINib* xib = [UINib nibWithNibName:@"PauseView" bundle:nil]; + _pauseView = [[xib instantiateWithOwner:[RetroArch_iOS get] options:nil] lastObject]; + xib = [UINib nibWithNibName:@"PauseIndicatorView" bundle:nil]; + _pauseIndicatorView = [[xib instantiateWithOwner:[RetroArch_iOS get] options:nil] lastObject]; + self.view = [GLKView new]; - ((GLKView*)self.view).context = _glContext; self.view.multipleTouchEnabled = YES; + [self.view addSubview:_pauseView]; + [self.view addSubview:_pauseIndicatorView]; return self; } -- (void)needsToDie +// Driver +- (void)driverInit +{ + g_screen_scale = [[UIScreen mainScreen] scale]; + + _glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + [EAGLContext setCurrentContext:_glContext]; + ((GLKView*)self.view).context = _glContext; + + // Show pause button for a few seconds, so people know it's there + _pauseIndicatorView.alpha = 1.0f; + [self performSelector:@selector(hidePauseButton) withObject:self afterDelay:3.0f]; +} + +- (void)driverQuit { glFinish(); - GLKView* glview = (GLKView*)self.view; - glview.context = nil; - _glContext = nil; + ((GLKView*)self.view).context = nil; [EAGLContext setCurrentContext:nil]; + _glContext = nil; +} + +- (void)flip +{ + if (--g_frame_skips < 0) + { + [self.view setNeedsDisplay]; + [(GLKView*)self.view bindDrawable]; + g_frame_skips = g_is_syncing ? 0 : 3; + } +} + +// Pause Menus +- (void)viewWillLayoutSubviews +{ + UIInterfaceOrientation orientation = self.interfaceOrientation; + CGRect screenSize = [[UIScreen mainScreen] bounds]; + + const float width = ((int)orientation < 3) ? CGRectGetWidth(screenSize) : CGRectGetHeight(screenSize); + const float height = ((int)orientation < 3) ? CGRectGetHeight(screenSize) : CGRectGetWidth(screenSize); + + float tenpctw = width / 10.0f; + float tenpcth = height / 10.0f; + + _pauseView.frame = CGRectMake(width / 2.0f - 150.0f, height / 2.0f - 150.0f, 300.0f, 300.0f); + _pauseIndicatorView.frame = CGRectMake(tenpctw * 4.0f, 0.0f, tenpctw * 2.0f, tenpcth); +} + +- (void)openPauseMenu +{ + // Setup save state selector + UISegmentedControl* stateSelect = (UISegmentedControl*)[_pauseView viewWithTag:1]; + stateSelect.selectedSegmentIndex = (g_extern.state_slot < 10) ? g_extern.state_slot : -1; + + // + [UIView animateWithDuration:0.2 + animations:^ { _pauseView.alpha = 1.0f; } + completion:^(BOOL finished){}]; +} + +- (void)closePauseMenu +{ + [UIView animateWithDuration:0.2 + animations:^ { _pauseView.alpha = 0.0f; } + completion:^(BOOL finished) { } + ]; +} + +- (void)hidePauseButton +{ + [UIView animateWithDuration:0.2 + animations:^ { _pauseIndicatorView.alpha = ALMOST_INVISIBLE; } + completion:^(BOOL finished) { } + ]; } @end -static RAGameView* gameViewer; - bool ios_init_game_view() { - if (!gameViewer) - { - gameViewer = [RAGameView new]; - [[RetroArch_iOS get] pushViewController:gameViewer isGame:YES]; - } - + [RAGameView.get driverInit]; return true; } void ios_destroy_game_view() { - if (gameViewer) - { - [gameViewer needsToDie]; - [[RetroArch_iOS get] popViewController]; - gameViewer = nil; - } + [RAGameView.get driverQuit]; } void ios_flip_game_view() { - if (gameViewer) - { - GLKView* gl_view = (GLKView*)gameViewer.view; - - if (--frame_skips < 0) - { - [gl_view setNeedsDisplay]; - [gl_view bindDrawable]; - frame_skips = is_syncing ? 0 : 3; - } - } + [RAGameView.get flip]; } void ios_set_game_view_sync(bool on) { - is_syncing = on; - frame_skips = on ? 0 : 3; + g_is_syncing = on; + g_frame_skips = on ? 0 : 3; } void ios_get_game_view_size(unsigned *width, unsigned *height) { - if (gameViewer) - { - GLKView* gl_view = (GLKView*)gameViewer.view; + *width = RAGameView.get.view.bounds.size.width * g_screen_scale; + *width = *width ? *width : 640; - *width = gl_view.bounds.size.width * screen_scale; - *height = gl_view.bounds.size.height * screen_scale; - } + *height = RAGameView.get.view.bounds.size.height * g_screen_scale; + *height = *height ? *height : 480; } void ios_bind_game_view_fbo() { - if (gameViewer) - { - GLKView* gl_view = (GLKView*)gameViewer.view; - [gl_view bindDrawable]; - } + [(GLKView*)RAGameView.get.view bindDrawable]; } diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index 1cc9b380c0..a20f498594 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -15,23 +15,18 @@ #import -@interface RetroArch_iOS : UIResponder +@interface RetroArch_iOS : UINavigationController + (void)displayErrorMessage:(NSString*)message; + (RetroArch_iOS*)get; - (void)runGame:(NSString*)path; -- (void)pushViewController:(UIViewController*)theView isGame:(BOOL)game; -- (UIViewController*)popViewController; - - (IBAction)showSettings; - (IBAction)showWiiRemoteConfig; @property (strong, nonatomic) RAModuleInfo* moduleInfo; @property (strong, nonatomic) NSString* system_directory; -@property (strong, nonatomic) UIImage* file_icon; -@property (strong, nonatomic) UIImage* folder_icon; @end diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index c57a186f73..4c63795d12 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -23,75 +23,14 @@ #import "input/BTStack/WiiMoteHelper.h" #endif - -#define ALMOST_INVISIBLE .021f - -@interface RANavigator : UINavigationController -@end - -@implementation RANavigator -{ - RetroArch_iOS* _delegate; -} - -- (id)initWithAppDelegate:(RetroArch_iOS*)delegate -{ - self = [super init]; - self.delegate = self; - - assert(delegate); - _delegate = delegate; - - return self; -} - -- (UIViewController *)popViewControllerAnimated:(BOOL)animated -{ - return [_delegate popViewController]; -} - -- (UIViewController*)reallyPopViewControllerAnimated:(BOOL)animated -{ - return [super popViewControllerAnimated:animated]; -} - -- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration -{ - [_delegate performSelector:@selector(screenDidRotate) withObject:nil afterDelay:.01f]; -} - -- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated -{ -#ifdef WIIMOTE - navigationController.topViewController.navigationItem.rightBarButtonItem = (![WiiMoteHelper isBluetoothRunning]) ? nil : - [[UIBarButtonItem alloc] - initWithTitle:@"Stop Bluetooth" - style:UIBarButtonItemStyleBordered - target:[RetroArch_iOS get] - action:@selector(stopBluetooth)]; -#endif -} - -@end - @implementation RetroArch_iOS { UIWindow* _window; - RANavigator* _navigator; NSTimer* _gameTimer; - - UIView* _pauseView; - UIView* _pauseIndicatorView; - RAGameView* _game; + bool _isGameTop; bool _isPaused; bool _isRunning; - - // 0 if no RAGameView is in the navigator - // 1 if a RAGameView is the top - // 2+ if there are views pushed ontop of the RAGameView - unsigned _gameAndAbove; - } + (void)displayErrorMessage:(NSString*)message @@ -109,178 +48,22 @@ return (RetroArch_iOS*)[[UIApplication sharedApplication] delegate]; } +// UIApplicationDelegate - (void)applicationDidFinishLaunching:(UIApplication *)application { // TODO: Relocate this! self.system_directory = @"/var/mobile/Library/RetroArch/"; mkdir([self.system_directory UTF8String], 0755); - // Load icons - self.file_icon = [UIImage imageNamed:@"ic_file"]; - self.folder_icon = [UIImage imageNamed:@"ic_dir"]; - - // Load pause menu - UINib* xib = [UINib nibWithNibName:@"PauseView" bundle:nil]; - _pauseView = [[xib instantiateWithOwner:self options:nil] lastObject]; - - xib = [UINib nibWithNibName:@"PauseIndicatorView" bundle:nil]; - _pauseIndicatorView = [[xib instantiateWithOwner:self options:nil] lastObject]; - - // Show status bar - [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone]; - // Setup window - _navigator = [[RANavigator alloc] initWithAppDelegate:self]; - [_navigator pushViewController: [RADirectoryList directoryListOrGridWithPath:nil] animated:YES]; + self.delegate = self; + [self pushViewController:[RADirectoryList directoryListOrGridWithPath:nil] animated:YES]; _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - _window.rootViewController = _navigator; + _window.rootViewController = self; [_window makeKeyAndVisible]; } -#pragma mark VIEW MANAGEMENT -- (void)screenDidRotate -{ - UIInterfaceOrientation orientation = _navigator.interfaceOrientation; - CGRect screenSize = [[UIScreen mainScreen] bounds]; - - const float width = ((int)orientation < 3) ? CGRectGetWidth(screenSize) : CGRectGetHeight(screenSize); - const float height = ((int)orientation < 3) ? CGRectGetHeight(screenSize) : CGRectGetWidth(screenSize); - - float tenpctw = width / 10.0f; - float tenpcth = height / 10.0f; - - _pauseView.frame = CGRectMake(width / 2.0f - 150.0f, height / 2.0f - 150.0f, 300.0f, 300.0f); - _pauseIndicatorView.frame = CGRectMake(tenpctw * 4.0f, 0.0f, tenpctw * 2.0f, tenpcth); - _pauseIndicatorView.hidden = NO; - - [self performSelector:@selector(hidePauseButton) withObject:self afterDelay:3.0f]; -} - -- (void)hidePauseButton -{ - [UIView animateWithDuration:0.2 - animations:^ { _pauseIndicatorView.alpha = ALMOST_INVISIBLE; } - completion:^(BOOL finished) { } - ]; -} - -- (void)pushViewController:(UIViewController*)theView isGame:(BOOL)game -{ - assert(!game || _gameAndAbove == 0); - - _gameAndAbove += (game || _gameAndAbove) ? 1 : 0; - - // Update status and navigation bars - [[UIApplication sharedApplication] setStatusBarHidden:game withAnimation:UIStatusBarAnimationNone]; - _navigator.navigationBarHidden = game; - - // - [_navigator pushViewController:theView animated:!(_gameAndAbove == 1 || _gameAndAbove == 2)]; - - if (game) - { - _game = (RAGameView*)theView; - - _pauseIndicatorView.alpha = 1.0f; - _pauseIndicatorView.hidden = YES; - - [theView.view addSubview:_pauseView]; - [theView.view addSubview:_pauseIndicatorView]; - - [self startTimer]; - [self performSelector:@selector(screenDidRotate) withObject:nil afterDelay:.01f]; - } -} - -- (UIViewController*)popViewController -{ - const bool poppingFromGame = _gameAndAbove == 1; - const bool poppingToGame = _gameAndAbove == 2; - - _gameAndAbove -= (_gameAndAbove) ? 1 : 0; - - if (poppingToGame) - [self startTimer]; - - // Update status and navigation bar - [[UIApplication sharedApplication] setStatusBarHidden:poppingToGame withAnimation:UIStatusBarAnimationNone]; - _navigator.navigationBarHidden = poppingToGame; - - // - if (poppingFromGame) - { - [_pauseView removeFromSuperview]; - [_pauseIndicatorView removeFromSuperview]; - } - - return [_navigator reallyPopViewControllerAnimated:!poppingToGame && !poppingFromGame]; -} - -#pragma mark EMULATION -- (void)runGame:(NSString*)path -{ - [RASettingsList refreshConfigFile]; - - const char* const sd = [[RetroArch_iOS get].system_directory UTF8String]; - const char* const cf =[[RetroArch_iOS get].moduleInfo.configPath UTF8String]; - const char* const libretro = [[RetroArch_iOS get].moduleInfo.path UTF8String]; - - struct rarch_main_wrap main_wrapper = {[path UTF8String], sd, sd, cf, libretro}; - if (rarch_main_init_wrap(&main_wrapper) == 0) - { - _isRunning = true; - rarch_init_msg_queue(); - [self startTimer]; - } - else - { - _isRunning = false; - [RetroArch_iOS displayErrorMessage:@"Failed to load game."]; - } -} - -- (void)closeGame -{ - if (_isRunning) - { - rarch_main_deinit(); - rarch_deinit_msg_queue(); - -#ifdef PERF_TEST - rarch_perf_log(); -#endif - - rarch_main_clear_state(); - } - - [self stopTimer]; - _isRunning = false; -} - -- (void)iterate -{ - if (_isPaused || !_isRunning || _gameAndAbove != 1) - [self stopTimer]; - else if (_isRunning && !rarch_main_iterate()) - [self closeGame]; -} - -- (void)startTimer -{ - if (!_gameTimer) - _gameTimer = [NSTimer scheduledTimerWithTimeInterval:0.001f target:self selector:@selector(iterate) userInfo:nil repeats:YES]; -} - -- (void)stopTimer -{ - if (_gameTimer) - [_gameTimer invalidate]; - - _gameTimer = nil; -} - -#pragma mark LIFE CYCLE - (void)applicationDidBecomeActive:(UIApplication*)application { [self startTimer]; @@ -303,19 +86,105 @@ uninit_drivers(); } +// UINavigationControllerDelegate +- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated +{ + _isGameTop = [viewController isKindOfClass:[RAGameView class]]; + [[UIApplication sharedApplication] setStatusBarHidden:_isGameTop withAnimation:UIStatusBarAnimationNone]; + self.navigationBarHidden = _isGameTop; + + if (_isGameTop) + [self startTimer]; + +#ifdef WIIMOTE + navigationController.topViewController.navigationItem.rightBarButtonItem = (![WiiMoteHelper isBluetoothRunning]) ? nil : + [[UIBarButtonItem alloc] + initWithTitle:@"Stop Bluetooth" + style:UIBarButtonItemStyleBordered + target:[RetroArch_iOS get] + action:@selector(stopBluetooth)]; +#endif +} + +// UINavigationController: Never animate when pushing onto, or popping, an RAGameView +- (void)pushViewController:(UIViewController*)theView animated:(BOOL)animated +{ + [super pushViewController:theView animated:animated && !_isGameTop]; +} + +- (UIViewController*)popViewControllerAnimated:(BOOL)animated +{ + return [super popViewControllerAnimated:animated && !_isGameTop]; +} + +#pragma mark EMULATION +- (void)runGame:(NSString*)path +{ + [RASettingsList refreshConfigFile]; + + const char* const sd = [[RetroArch_iOS get].system_directory UTF8String]; + const char* const cf =[[RetroArch_iOS get].moduleInfo.configPath UTF8String]; + const char* const libretro = [[RetroArch_iOS get].moduleInfo.path UTF8String]; + + struct rarch_main_wrap main_wrapper = {[path UTF8String], sd, sd, cf, libretro}; + if (rarch_main_init_wrap(&main_wrapper) == 0) + { + rarch_init_msg_queue(); + + [self pushViewController:RAGameView.get animated:NO]; + _isRunning = true; + } + else + { + _isRunning = false; + [RetroArch_iOS displayErrorMessage:@"Failed to load game."]; + } +} + +- (void)closeGame +{ + if (_isRunning) + { + _isRunning = false; + + rarch_main_deinit(); + rarch_deinit_msg_queue(); + rarch_main_clear_state(); + + [self popToViewController:[RAGameView get] animated:NO]; + [self popViewControllerAnimated:NO]; + } +} + +- (void)iterate +{ + if (_isPaused || !_isRunning || !_isGameTop) + [self stopTimer]; + else if (_isRunning && !rarch_main_iterate()) + [self closeGame]; +} + +- (void)startTimer +{ + if (!_gameTimer) + _gameTimer = [NSTimer scheduledTimerWithTimeInterval:0.001f target:self selector:@selector(iterate) userInfo:nil repeats:YES]; +} + +- (void)stopTimer +{ + if (_gameTimer) + [_gameTimer invalidate]; + + _gameTimer = nil; +} + #pragma mark PAUSE MENU - (IBAction)showPauseMenu:(id)sender { - if (_isRunning && !_isPaused && _gameAndAbove == 1) + if (_isRunning && !_isPaused && _isGameTop) { _isPaused = true; - - UISegmentedControl* stateSelect = (UISegmentedControl*)[_pauseView viewWithTag:1]; - stateSelect.selectedSegmentIndex = (g_extern.state_slot < 10) ? g_extern.state_slot : -1; - - [UIView animateWithDuration:0.2 - animations:^ { _pauseView.alpha = 1.0f; } - completion:^(BOOL finished){}]; + [[RAGameView get] openPauseMenu]; } } @@ -344,15 +213,13 @@ - (IBAction)closePauseMenu:(id)sender { + [[RAGameView get] closePauseMenu]; + if (_isPaused) - [UIView animateWithDuration:0.2 - animations:^ { _pauseView.alpha = 0.0f; } - completion:^(BOOL finished) - { - _isPaused = false; - [self startTimer]; - } - ]; + { + _isPaused = false; + [self startTimer]; + } } - (IBAction)closeGamePressed:(id)sender @@ -363,7 +230,7 @@ - (IBAction)showSettings { - [self pushViewController:[RASettingsList new] isGame:NO]; + [self pushViewController:[RASettingsList new] animated:YES]; } - (IBAction)showWiiRemoteConfig @@ -377,7 +244,7 @@ { #ifdef WIIMOTE [WiiMoteHelper stopBluetooth]; - [_navigator.topViewController.navigationItem setRightBarButtonItem:nil animated:YES]; + [self.topViewController.navigationItem setRightBarButtonItem:nil animated:YES]; #endif } diff --git a/ios/RetroArch/browser/RADirectoryGrid.m b/ios/RetroArch/browser/RADirectoryGrid.m index 0e0e87f4cc..03d7f86331 100644 --- a/ios/RetroArch/browser/RADirectoryGrid.m +++ b/ios/RetroArch/browser/RADirectoryGrid.m @@ -58,9 +58,9 @@ RADirectoryItem* path = [_list objectAtIndex: indexPath.row]; if(path.isDirectory) - [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListOrGridWithPath:path.path] isGame:NO]; + [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListOrGridWithPath:path.path] animated:YES]; else - [[RetroArch_iOS get] pushViewController:[[RAModuleList alloc] initWithGame:path.path] isGame:NO]; + [[RetroArch_iOS get] pushViewController:[[RAModuleList alloc] initWithGame:path.path] animated:YES]; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath @@ -74,7 +74,7 @@ if (!cell.backgroundView) { - cell.backgroundView = [[UIImageView alloc] initWithImage:[RetroArch_iOS get].folder_icon]; + cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ic_dir"]]; ((UIImageView*)cell.backgroundView).contentMode = UIViewContentModeScaleAspectFit; } } diff --git a/ios/RetroArch/browser/RADirectoryList.m b/ios/RetroArch/browser/RADirectoryList.m index 3b2376902c..57dff2cf8b 100644 --- a/ios/RetroArch/browser/RADirectoryList.m +++ b/ios/RetroArch/browser/RADirectoryList.m @@ -55,9 +55,9 @@ RADirectoryItem* path = [_list objectAtIndex: indexPath.row]; if(path.isDirectory) - [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListOrGridWithPath:path.path] isGame:NO]; + [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListOrGridWithPath:path.path] animated:YES]; else - [[RetroArch_iOS get] pushViewController:[[RAModuleList alloc] initWithGame:path.path] isGame:NO]; + [[RetroArch_iOS get] pushViewController:[[RAModuleList alloc] initWithGame:path.path] animated:YES]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section @@ -73,7 +73,7 @@ cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"path"]; cell.textLabel.text = [path.path lastPathComponent]; cell.accessoryType = (path.isDirectory) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; - cell.imageView.image = (path.isDirectory) ? [RetroArch_iOS get].folder_icon : [RetroArch_iOS get].file_icon; + cell.imageView.image = [UIImage imageNamed:(path.isDirectory) ? @"ic_dir" : @"ic_file"]; return cell; } diff --git a/ios/RetroArch/input/BTStack/WiiMoteHelper.m b/ios/RetroArch/input/BTStack/WiiMoteHelper.m index 8fd79831f6..08f27bf5e4 100644 --- a/ios/RetroArch/input/BTStack/WiiMoteHelper.m +++ b/ios/RetroArch/input/BTStack/WiiMoteHelper.m @@ -107,7 +107,7 @@ static bool btOK; [[BTstackManager sharedInstance] addListener:discoveryView]; } - [[RetroArch_iOS get] pushViewController:discoveryView isGame:NO]; + [[RetroArch_iOS get] pushViewController:discoveryView animated:YES]; } // BTStackManagerListener diff --git a/ios/RetroArch/settings/RASettingEnumerationList.m b/ios/RetroArch/settings/RASettingEnumerationList.m index 96d51e0a5e..54266e3c9c 100644 --- a/ios/RetroArch/settings/RASettingEnumerationList.m +++ b/ios/RetroArch/settings/RASettingEnumerationList.m @@ -57,7 +57,7 @@ _value.value = (indexPath.section == 1) ? [_value.subValues objectAtIndex:indexPath.row] : @""; [_view reloadData]; - [[RetroArch_iOS get] popViewController]; + [[RetroArch_iOS get] popViewControllerAnimated:YES]; } @end diff --git a/ios/RetroArch/settings/RASettingsList.m b/ios/RetroArch/settings/RASettingsList.m index 42354c863c..d994859d6e 100644 --- a/ios/RetroArch/settings/RASettingsList.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -100,7 +100,7 @@ static RASettingData* custom_action(NSString* action) [NSArray arrayWithObjects:@"General", custom_action(@"Module Info"), #ifdef WIIMOTE - custom_action(@"Connect WiiMotes"); + custom_action(@"Connect WiiMotes"), #endif nil], @@ -157,7 +157,6 @@ static RASettingData* custom_action(NSString* action) nil]), nil], - [NSArray arrayWithObjects:@"Save States", boolean_setting(config, @"rewind_enable", @"Enable Rewinding", @"false"), boolean_setting(config, @"block_sram_overwrite", @"Disable SRAM on Load", @"false"), @@ -179,7 +178,7 @@ static RASettingData* custom_action(NSString* action) - (void)handleCustomAction:(NSString*)action { if ([@"Module Info" isEqualToString:action]) - [[RetroArch_iOS get] pushViewController:[[RAModuleInfoList alloc] initWithModuleInfo:[RetroArch_iOS get].moduleInfo] isGame:NO]; + [[RetroArch_iOS get] pushViewController:[[RAModuleInfoList alloc] initWithModuleInfo:[RetroArch_iOS get].moduleInfo] animated:YES]; else if([@"Connect WiiMotes" isEqualToString:action]) [[RetroArch_iOS get] showWiiRemoteConfig]; } diff --git a/ios/RetroArch/settings/RASettingsSubList.m b/ios/RetroArch/settings/RASettingsSubList.m index c7b2ae2825..5dfe672b64 100644 --- a/ios/RetroArch/settings/RASettingsSubList.m +++ b/ios/RetroArch/settings/RASettingsSubList.m @@ -88,7 +88,7 @@ static const char* const SETTINGID = "SETTING"; { case EnumerationSetting: case FileListSetting: - [[RetroArch_iOS get] pushViewController:[[RASettingEnumerationList alloc] initWithSetting:setting fromTable:(UITableView*)self.view] isGame:NO]; + [[RetroArch_iOS get] pushViewController:[[RASettingEnumerationList alloc] initWithSetting:setting fromTable:(UITableView*)self.view] animated:YES]; break; case ButtonSetting: @@ -96,7 +96,7 @@ static const char* const SETTINGID = "SETTING"; break; case GroupSetting: - [[RetroArch_iOS get] pushViewController:[[RASettingsSubList alloc] initWithSettings:setting.subValues title:setting.label] isGame:NO]; + [[RetroArch_iOS get] pushViewController:[[RASettingsSubList alloc] initWithSettings:setting.subValues title:setting.label] animated:YES]; break; case CustomAction: diff --git a/ios/RetroArch/views.h b/ios/RetroArch/views.h index 06efbe1fed..b475d4d689 100644 --- a/ios/RetroArch/views.h +++ b/ios/RetroArch/views.h @@ -19,6 +19,9 @@ #import "RAConfig.h" @interface RAGameView : UIViewController ++ (RAGameView*)get; +- (void)openPauseMenu; +- (void)closePauseMenu; @end @interface RAModuleInfo : NSObject From 3fd2db88e853c3daf9084078f8d715fd81731d21 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 5 Mar 2013 20:04:56 -0500 Subject: [PATCH 100/108] (iOS) Fix issue where new config files would not be generated. (Every version since be3aa0a063ec0fc45b08a59c360c411876de9422 was broken...) --- ios/RetroArch/RAConfig.m | 1 + ios/RetroArch/settings/RASettingsList.m | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ios/RetroArch/RAConfig.m b/ios/RetroArch/RAConfig.m index 1315144b87..71866b7e03 100644 --- a/ios/RetroArch/RAConfig.m +++ b/ios/RetroArch/RAConfig.m @@ -24,6 +24,7 @@ - (id)initWithPath:(NSString*)path { _config = config_file_new([path UTF8String]); + _config = _config ? _config : config_file_new(0); return self; } diff --git a/ios/RetroArch/settings/RASettingsList.m b/ios/RetroArch/settings/RASettingsList.m index d994859d6e..fd9b31d095 100644 --- a/ios/RetroArch/settings/RASettingsList.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -86,7 +86,7 @@ static RASettingData* custom_action(NSString* action) @implementation RASettingsList + (void)refreshConfigFile { - [[[RASettingsList alloc] init] writeToDisk]; + (void)[[RASettingsList alloc] init]; } - (id)init From dbc3e3f7ffecadd7417773322414cf62641a55b8 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 5 Mar 2013 20:28:59 -0500 Subject: [PATCH 101/108] (iOS) Fix broken multi-touch code. --- ios/RetroArch/input/RAInputResponder.h | 1 - ios/RetroArch/input/RAInputResponder.m | 15 +++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ios/RetroArch/input/RAInputResponder.h b/ios/RetroArch/input/RAInputResponder.h index 3ad909f25f..b02b07fed3 100644 --- a/ios/RetroArch/input/RAInputResponder.h +++ b/ios/RetroArch/input/RAInputResponder.h @@ -19,7 +19,6 @@ typedef struct touch_data { - bool is_down; int16_t screen_x, screen_y; int16_t fixed_x, fixed_y; int16_t full_x, full_y; diff --git a/ios/RetroArch/input/RAInputResponder.m b/ios/RetroArch/input/RAInputResponder.m index 5951a17813..98af742500 100644 --- a/ios/RetroArch/input/RAInputResponder.m +++ b/ios/RetroArch/input/RAInputResponder.m @@ -57,7 +57,7 @@ extern NSString* const RATouchNotification; - (const touch_data_t*)getTouchDataAtIndex:(unsigned)index { - return (index < MAX_TOUCHES && _touches[index].is_down) ? &_touches[index] : 0; + return (index < _touchCount) ? &_touches[index] : 0; } // Response handlers @@ -77,18 +77,21 @@ extern NSString* const RATouchNotification; { UIEvent* event = [notification.userInfo objectForKey:@"event"]; NSArray* touches = [[event allTouches] allObjects]; + const int numTouches = [touches count]; - _touchCount = [touches count]; + _touchCount = 0; - for(int i = 0; i != _touchCount; i ++) + for(int i = 0; i != numTouches && _touchCount != MAX_TOUCHES; i ++) { UITouch *touch = [touches objectAtIndex:i]; CGPoint coord = [touch locationInView:touch.view]; float scale = [[UIScreen mainScreen] scale]; - _touches[i].is_down = (touch.phase != UITouchPhaseEnded) && (touch.phase != UITouchPhaseCancelled); - _touches[i].screen_x = coord.x * scale; - _touches[i].screen_y = coord.y * scale; + if (touch.phase != UITouchPhaseEnded && touch.phase != UITouchPhaseCancelled) + { + _touches[_touchCount ].screen_x = coord.x * scale; + _touches[_touchCount ++].screen_y = coord.y * scale; + } } } @end From 92d0cac17a9780131c5a8a59d1ac5eae172f7a49 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 5 Mar 2013 20:45:15 -0500 Subject: [PATCH 102/108] (iOS) Add Classic Controller support. --- ios/RetroArch/input/ios_joypad.m | 9 ++++++++- ios/RetroArch/settings/RAButtonGetter.m | 7 +++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/ios/RetroArch/input/ios_joypad.m b/ios/RetroArch/input/ios_joypad.m index 674eacfac0..929544a380 100644 --- a/ios/RetroArch/input/ios_joypad.m +++ b/ios/RetroArch/input/ios_joypad.m @@ -53,7 +53,14 @@ static int16_t ios_joypad_axis(unsigned port, uint32_t joyaxis) static void ios_joypad_poll(void) { for (int i = 0; i != MAX_PLAYERS; i ++) - g_buttons[i] = (i < myosd_num_of_joys) ? joys[i].btns : 0; + { + g_buttons[i] = 0; + if (i < myosd_num_of_joys) + { + g_buttons[i] = joys[i].btns; + g_buttons[i] |= (joys[i].exp.type == EXP_CLASSIC) ? (joys[i].exp.classic.btns << 16) : 0; + } + } } const rarch_joypad_driver_t ios_joypad = { diff --git a/ios/RetroArch/settings/RAButtonGetter.m b/ios/RetroArch/settings/RAButtonGetter.m index 3db1f41eb8..bddaaabe73 100644 --- a/ios/RetroArch/settings/RAButtonGetter.m +++ b/ios/RetroArch/settings/RAButtonGetter.m @@ -149,9 +149,12 @@ static NSString* get_key_config_name(uint32_t hid_id) { for (int i = 0; i != myosd_num_of_joys; i ++) { - for (int j = 0; j != sizeof(joys[i].btns) * 8; j ++) + uint32_t buttons = joys[i].btns; + buttons |= (joys[i].exp.type == EXP_CLASSIC) ? (joys[i].exp.classic.btns << 16) : 0; + + for (int j = 0; j != sizeof(buttons) * 8; j ++) { - if (joys[i].btns & (1 << j)) + if (buttons & (1 << j)) { _value.msubValues[1] = [NSString stringWithFormat:@"%d", j]; [self finish]; From 5365eec24d60db2a26c744b36d9513349aa89724 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 5 Mar 2013 20:57:26 -0500 Subject: [PATCH 103/108] (iOS) Change some config file handling: Don't require a config file. Don't load then write the config file every time a game is loaded (just to make sure it's there). --- ios/RetroArch/RetroArch_iOS.m | 8 ++++---- ios/RetroArch/settings/RASettingsList.m | 20 +++----------------- ios/RetroArch/settings/settings.h | 1 - 3 files changed, 7 insertions(+), 22 deletions(-) diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 4c63795d12..d9cd1cb0fc 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -120,11 +120,11 @@ #pragma mark EMULATION - (void)runGame:(NSString*)path { - [RASettingsList refreshConfigFile]; - + assert(self.moduleInfo); + const char* const sd = [[RetroArch_iOS get].system_directory UTF8String]; - const char* const cf =[[RetroArch_iOS get].moduleInfo.configPath UTF8String]; - const char* const libretro = [[RetroArch_iOS get].moduleInfo.path UTF8String]; + const char* const cf = (ra_ios_is_file(self.moduleInfo.configPath)) ? [self.moduleInfo.configPath UTF8String] : 0; + const char* const libretro = [self.moduleInfo.path UTF8String]; struct rarch_main_wrap main_wrapper = {[path UTF8String], sd, sd, cf, libretro}; if (rarch_main_init_wrap(&main_wrapper) == 0) diff --git a/ios/RetroArch/settings/RASettingsList.m b/ios/RetroArch/settings/RASettingsList.m index fd9b31d095..6f6cfe2092 100644 --- a/ios/RetroArch/settings/RASettingsList.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -84,11 +84,6 @@ static RASettingData* custom_action(NSString* action) } @implementation RASettingsList -+ (void)refreshConfigFile -{ - (void)[[RASettingsList alloc] init]; -} - - (id)init { RAConfig* config = [[RAConfig alloc] initWithPath:[RetroArch_iOS get].moduleInfo.configPath]; @@ -172,7 +167,9 @@ static RASettingData* custom_action(NSString* action) - (void)dealloc { - [self writeToDisk]; + RAConfig* config = [[RAConfig alloc] initWithPath:[RetroArch_iOS get].moduleInfo.configPath]; + [self writeSettings:nil toConfig:config]; + [config writeToFile:[RetroArch_iOS get].moduleInfo.configPath]; } - (void)handleCustomAction:(NSString*)action @@ -183,15 +180,4 @@ static RASettingData* custom_action(NSString* action) [[RetroArch_iOS get] showWiiRemoteConfig]; } - -- (void)writeToDisk -{ - RAConfig* config = [[RAConfig alloc] initWithPath:[RetroArch_iOS get].moduleInfo.configPath]; - [config putStringNamed:@"system_directory" value:[RetroArch_iOS get].system_directory]; - - [self writeSettings:nil toConfig:config]; - - [config writeToFile:[RetroArch_iOS get].moduleInfo.configPath]; -} - @end diff --git a/ios/RetroArch/settings/settings.h b/ios/RetroArch/settings/settings.h index 9c7b18e5da..2b7dd8634f 100644 --- a/ios/RetroArch/settings/settings.h +++ b/ios/RetroArch/settings/settings.h @@ -47,5 +47,4 @@ enum SettingTypes @end @interface RASettingsList : RASettingsSubList -+ (void)refreshConfigFile; @end From 14e80352e7bf9531394f0379b55918bbd5516f01 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 5 Mar 2013 22:17:40 -0500 Subject: [PATCH 104/108] (iOS) Add directory 'ios/modules' which will be copied into the final app bundle. Populate it with module info files for all tested cores. If you place the built dylib files in here they will be copied into the bundle too. --- ios/RetroArch.xcodeproj/project.pbxproj | 6 ++++++ ios/modules/desmume_libretro.info | 5 +++++ ios/modules/example.info | 17 +++++++++++++++++ ios/modules/gambatte_libretro.info | 5 +++++ ios/modules/genesis_plus_gx_libretro.info | 6 ++++++ ios/modules/nestopia_libretro.info | 6 ++++++ ios/modules/nxengine_libretro.info | 3 +++ ios/modules/prboom_libretro.info | 3 +++ ios/modules/snes9x_next_libretro.info | 5 +++++ ios/modules/stella_libretro.info | 6 ++++++ ios/modules/tyrquake_libretro.info | 3 +++ ios/modules/vba_next_libretro.info | 5 +++++ 12 files changed, 70 insertions(+) create mode 100644 ios/modules/desmume_libretro.info create mode 100644 ios/modules/example.info create mode 100644 ios/modules/gambatte_libretro.info create mode 100644 ios/modules/genesis_plus_gx_libretro.info create mode 100644 ios/modules/nestopia_libretro.info create mode 100644 ios/modules/nxengine_libretro.info create mode 100644 ios/modules/prboom_libretro.info create mode 100644 ios/modules/snes9x_next_libretro.info create mode 100644 ios/modules/stella_libretro.info create mode 100644 ios/modules/tyrquake_libretro.info create mode 100644 ios/modules/vba_next_libretro.info diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index fbde213b57..6605fe6611 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -127,6 +127,8 @@ 966B9CCC16E41EC1005B61E1 /* PauseIndicatorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CC816E41EC1005B61E1 /* PauseIndicatorView.xib */; }; 967D646F16E45428006BA1F2 /* ic_pause.png in Resources */ = {isa = PBXBuildFile; fileRef = 967D646E16E45428006BA1F2 /* ic_pause.png */; }; 967D647016E45428006BA1F2 /* ic_pause.png in Resources */ = {isa = PBXBuildFile; fileRef = 967D646E16E45428006BA1F2 /* ic_pause.png */; }; + 967D647516E6EA04006BA1F2 /* modules in Resources */ = {isa = PBXBuildFile; fileRef = 967D647416E6EA04006BA1F2 /* modules */; }; + 967D647616E6EA04006BA1F2 /* modules in Resources */ = {isa = PBXBuildFile; fileRef = 967D647416E6EA04006BA1F2 /* modules */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -236,6 +238,7 @@ 966B9CC716E41EC1005B61E1 /* PauseView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PauseView.xib; sourceTree = ""; }; 966B9CC816E41EC1005B61E1 /* PauseIndicatorView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PauseIndicatorView.xib; sourceTree = ""; }; 967D646E16E45428006BA1F2 /* ic_pause.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ic_pause.png; sourceTree = ""; }; + 967D647416E6EA04006BA1F2 /* modules */ = {isa = PBXFileReference; lastKnownFileType = folder; path = modules; sourceTree = SOURCE_ROOT; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -461,6 +464,7 @@ 966B9CB716E41E7A005B61E1 /* Assets */ = { isa = PBXGroup; children = ( + 967D647416E6EA04006BA1F2 /* modules */, 96297A2616C82FF100E6DCE0 /* overlays */, 966B9CB816E41E7A005B61E1 /* Default-568h@2x.png */, 966B9CB916E41E7A005B61E1 /* Default.png */, @@ -837,6 +841,7 @@ 966B9CCA16E41EC1005B61E1 /* PauseView.xib in Resources */, 966B9CCC16E41EC1005B61E1 /* PauseIndicatorView.xib in Resources */, 967D647016E45428006BA1F2 /* ic_pause.png in Resources */, + 967D647616E6EA04006BA1F2 /* modules in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -856,6 +861,7 @@ 966B9CC916E41EC1005B61E1 /* PauseView.xib in Resources */, 966B9CCB16E41EC1005B61E1 /* PauseIndicatorView.xib in Resources */, 967D646F16E45428006BA1F2 /* ic_pause.png in Resources */, + 967D647516E6EA04006BA1F2 /* modules in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/modules/desmume_libretro.info b/ios/modules/desmume_libretro.info new file mode 100644 index 0000000000..4ec998c734 --- /dev/null +++ b/ios/modules/desmume_libretro.info @@ -0,0 +1,5 @@ +display_name = "Nintendo DS" +recommended_extensions = "nds" +emuname = "DeSmuME" +manufacturer = "Nintendo" +systemname = "Nintendo DS" diff --git a/ios/modules/example.info b/ios/modules/example.info new file mode 100644 index 0000000000..d6174f49f1 --- /dev/null +++ b/ios/modules/example.info @@ -0,0 +1,17 @@ +## All data is optional, but helps improve user experience. + +# Name displayed when the user is selecting an emulator. +# display_name = "NES / Famicom" + +# List of supported extensions. +# supported_extensions = "nes|fds" + +# Name the emulator core. +# emuname = "Nestopia" + +# The developer of the emulated device. +# manufacturer = "Nintendo" + +# The name of the emulated device. +# systemname = "Nintendo Entertainment System" + diff --git a/ios/modules/gambatte_libretro.info b/ios/modules/gambatte_libretro.info new file mode 100644 index 0000000000..f5ee6ae08f --- /dev/null +++ b/ios/modules/gambatte_libretro.info @@ -0,0 +1,5 @@ +display_name = "Game Boy / Game Boy Color" +supported_extensions = "gb|gbc|dmg" +emuname = "gambatte" +manufacturer = "Nintendo" +systemname = "Game Boy Color" diff --git a/ios/modules/genesis_plus_gx_libretro.info b/ios/modules/genesis_plus_gx_libretro.info new file mode 100644 index 0000000000..f9d3ce29f7 --- /dev/null +++ b/ios/modules/genesis_plus_gx_libretro.info @@ -0,0 +1,6 @@ +display_name = "Sega (MS/GG/MD/CD)" +supported_extensions = "md|smd|gen|sms|gg|sg|bin|cue|ios" +emuname = "Genesis Plus GX" +manufacturer = "Sega" +systemname = "Sega (Various)" + diff --git a/ios/modules/nestopia_libretro.info b/ios/modules/nestopia_libretro.info new file mode 100644 index 0000000000..cd3f8750c4 --- /dev/null +++ b/ios/modules/nestopia_libretro.info @@ -0,0 +1,6 @@ +display_name = "NES / Famicom" +supported_extensions = "nes|fds" +emuname = "Nestopia" +manufacturer = "Nintendo" +systemname = "Nintendo Entertainment System" + diff --git a/ios/modules/nxengine_libretro.info b/ios/modules/nxengine_libretro.info new file mode 100644 index 0000000000..997b771c86 --- /dev/null +++ b/ios/modules/nxengine_libretro.info @@ -0,0 +1,3 @@ +display_name = "NXEngine (Cave Story)" +supported_extensions = "exe" +emuname = "NXEngine" diff --git a/ios/modules/prboom_libretro.info b/ios/modules/prboom_libretro.info new file mode 100644 index 0000000000..a1012b43ef --- /dev/null +++ b/ios/modules/prboom_libretro.info @@ -0,0 +1,3 @@ +display_name = "PrBoom (DOOM)" +supported_extensions = "wad|iwad" +emuname = "prboom" diff --git a/ios/modules/snes9x_next_libretro.info b/ios/modules/snes9x_next_libretro.info new file mode 100644 index 0000000000..0c4577ef7e --- /dev/null +++ b/ios/modules/snes9x_next_libretro.info @@ -0,0 +1,5 @@ +display_name = "SNES / Super Famicom" +supported_extensions = "smc|fig|sfc|gd3|gd7|dx2|bsx|swc" +emuname = "SNES9x Next" +manufacturer = "Nintendo" +systemname = "Super Nintendo Entertainment System" diff --git a/ios/modules/stella_libretro.info b/ios/modules/stella_libretro.info new file mode 100644 index 0000000000..99b8e27eea --- /dev/null +++ b/ios/modules/stella_libretro.info @@ -0,0 +1,6 @@ +display_name = "Atari 2600" +supported_extensions = "a26|bin" +emuname = "Stella" +manufacturer = "Atari" +systemname = "Atari 2600" + diff --git a/ios/modules/tyrquake_libretro.info b/ios/modules/tyrquake_libretro.info new file mode 100644 index 0000000000..cf2cd27b91 --- /dev/null +++ b/ios/modules/tyrquake_libretro.info @@ -0,0 +1,3 @@ +display_name = "TyrQuake" +supported_extensions = "pak" +emuname = "prboom" diff --git a/ios/modules/vba_next_libretro.info b/ios/modules/vba_next_libretro.info new file mode 100644 index 0000000000..359e618080 --- /dev/null +++ b/ios/modules/vba_next_libretro.info @@ -0,0 +1,5 @@ +display_name = "Game Boy Advance" +supported_extensions = "gba" +emuname = "VBA Next" +manufacturer = "Nintendo" +systemname = "Game Boy Advance" From 5310067cc5db3d277cb4028e193e12862164eb1a Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 6 Mar 2013 12:15:26 -0500 Subject: [PATCH 105/108] (iOS) Rework BTstack handling: No more BTDiscoveryView, just press the 'Start Bluetooth' button in the upper right corner and sync the wii remote. Add a per module setting to enable bluetooth as soon as a game starts. Stop bluetooth whenever a game is closed. --- ios/RetroArch.xcodeproj/project.pbxproj | 6 - ios/RetroArch/RAConfig.h | 1 + ios/RetroArch/RAConfig.m | 10 + ios/RetroArch/RetroArch_iOS.h | 1 - ios/RetroArch/RetroArch_iOS.m | 41 +- .../input/BTStack/BTDiscoveryViewController.h | 67 ---- .../input/BTStack/BTDiscoveryViewController.m | 351 ------------------ ios/RetroArch/input/BTStack/WiiMoteHelper.h | 7 +- ios/RetroArch/input/BTStack/WiiMoteHelper.m | 68 +--- ios/RetroArch/settings/RASettingsList.m | 6 +- 10 files changed, 65 insertions(+), 493 deletions(-) delete mode 100644 ios/RetroArch/input/BTStack/BTDiscoveryViewController.h delete mode 100644 ios/RetroArch/input/BTStack/BTDiscoveryViewController.m diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 6605fe6611..e87846a05f 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -98,7 +98,6 @@ 966B9C8D16E40EFC005B61E1 /* RAInputResponder.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C8916E40D44005B61E1 /* RAInputResponder.m */; }; 966B9C8E16E40F00005B61E1 /* ios_input.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C8616E40D44005B61E1 /* ios_input.m */; }; 966B9CA216E418B7005B61E1 /* BTDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C9116E418B7005B61E1 /* BTDevice.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 966B9CA316E418B7005B61E1 /* BTDiscoveryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C9316E418B7005B61E1 /* BTDiscoveryViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 966B9CA416E418B7005B61E1 /* BTstackManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C9C16E418B7005B61E1 /* BTstackManager.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 966B9CA516E418B7005B61E1 /* libBTstack.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 966B9C9D16E418B7005B61E1 /* libBTstack.dylib */; }; 966B9CA616E418B7005B61E1 /* wiimote.c in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C9E16E418B7005B61E1 /* wiimote.c */; }; @@ -210,8 +209,6 @@ 966B9C8916E40D44005B61E1 /* RAInputResponder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAInputResponder.m; sourceTree = ""; }; 966B9C9016E418B7005B61E1 /* BTDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTDevice.h; sourceTree = ""; }; 966B9C9116E418B7005B61E1 /* BTDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTDevice.m; sourceTree = ""; }; - 966B9C9216E418B7005B61E1 /* BTDiscoveryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTDiscoveryViewController.h; sourceTree = ""; }; - 966B9C9316E418B7005B61E1 /* BTDiscoveryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTDiscoveryViewController.m; sourceTree = ""; }; 966B9C9516E418B7005B61E1 /* btstack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = btstack.h; sourceTree = ""; }; 966B9C9616E418B7005B61E1 /* hci_cmds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hci_cmds.h; sourceTree = ""; }; 966B9C9716E418B7005B61E1 /* linked_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linked_list.h; sourceTree = ""; }; @@ -422,8 +419,6 @@ children = ( 966B9C9016E418B7005B61E1 /* BTDevice.h */, 966B9C9116E418B7005B61E1 /* BTDevice.m */, - 966B9C9216E418B7005B61E1 /* BTDiscoveryViewController.h */, - 966B9C9316E418B7005B61E1 /* BTDiscoveryViewController.m */, 966B9C9416E418B7005B61E1 /* btstack */, 966B9C9B16E418B7005B61E1 /* BTstackManager.h */, 966B9C9C16E418B7005B61E1 /* BTstackManager.m */, @@ -1001,7 +996,6 @@ 966B9C8B16E40D44005B61E1 /* ios_joypad.m in Sources */, 966B9C8C16E40D44005B61E1 /* RAInputResponder.m in Sources */, 966B9CA216E418B7005B61E1 /* BTDevice.m in Sources */, - 966B9CA316E418B7005B61E1 /* BTDiscoveryViewController.m in Sources */, 966B9CA416E418B7005B61E1 /* BTstackManager.m in Sources */, 966B9CA616E418B7005B61E1 /* wiimote.c in Sources */, 966B9CA716E418B7005B61E1 /* WiiMoteHelper.m in Sources */, diff --git a/ios/RetroArch/RAConfig.h b/ios/RetroArch/RAConfig.h index d3f0f41d92..b19742ffcf 100644 --- a/ios/RetroArch/RAConfig.h +++ b/ios/RetroArch/RAConfig.h @@ -17,6 +17,7 @@ - (id)initWithPath:(NSString*)path; - (void)writeToFile:(NSString*)path; +- (bool)getBoolNamed:(NSString*)name withDefault:(bool)def; - (int)getIntNamed:(NSString*)name withDefault:(int)def; - (unsigned)getUintNamed:(NSString*)name withDefault:(unsigned)def; - (NSString*)getStringNamed:(NSString*)name withDefault:(NSString*)def; diff --git a/ios/RetroArch/RAConfig.m b/ios/RetroArch/RAConfig.m index 71866b7e03..76947fb901 100644 --- a/ios/RetroArch/RAConfig.m +++ b/ios/RetroArch/RAConfig.m @@ -40,6 +40,16 @@ config_file_write(_config, [path UTF8String]); } +- (bool)getBoolNamed:(NSString*)name withDefault:(bool)def +{ + bool result = def; + + if (_config) + config_get_bool(_config, [name UTF8String], &result); + + return result; +} + - (int)getIntNamed:(NSString*)name withDefault:(int)def { int result = def; diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index a20f498594..aa026b7011 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -23,7 +23,6 @@ - (void)runGame:(NSString*)path; - (IBAction)showSettings; -- (IBAction)showWiiRemoteConfig; @property (strong, nonatomic) RAModuleInfo* moduleInfo; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index d9cd1cb0fc..f54967c61a 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -96,14 +96,7 @@ if (_isGameTop) [self startTimer]; -#ifdef WIIMOTE - navigationController.topViewController.navigationItem.rightBarButtonItem = (![WiiMoteHelper isBluetoothRunning]) ? nil : - [[UIBarButtonItem alloc] - initWithTitle:@"Stop Bluetooth" - style:UIBarButtonItemStyleBordered - target:[RetroArch_iOS get] - action:@selector(stopBluetooth)]; -#endif + self.topViewController.navigationItem.rightBarButtonItem = [self createBluetoothButton]; } // UINavigationController: Never animate when pushing onto, or popping, an RAGameView @@ -131,6 +124,12 @@ { rarch_init_msg_queue(); + // Read load time settings + RAConfig* conf = [[RAConfig alloc] initWithPath:self.moduleInfo.configPath]; + if ([conf getBoolNamed:@"ios_auto_bluetooth" withDefault:false]) + [self startBluetooth]; + + // [self pushViewController:RAGameView.get animated:NO]; _isRunning = true; } @@ -151,6 +150,10 @@ rarch_deinit_msg_queue(); rarch_main_clear_state(); + // Stop bluetooth (might be annoying but forgetting could eat battery of device AND wiimote) + [self stopBluetooth]; + + // [self popToViewController:[RAGameView get] animated:NO]; [self popViewControllerAnimated:NO]; } @@ -233,10 +236,26 @@ [self pushViewController:[RASettingsList new] animated:YES]; } -- (IBAction)showWiiRemoteConfig +#pragma MARK Bluetooth Helpers +- (UIBarButtonItem*)createBluetoothButton { #ifdef WIIMOTE - [[WiiMoteHelper get] showDiscovery]; + const bool isBTOn = [WiiMoteHelper isBluetoothRunning]; + return [[UIBarButtonItem alloc] + initWithTitle:isBTOn ? @"Stop Bluetooth" : @"Start Bluetooth" + style:UIBarButtonItemStyleBordered + target:[RetroArch_iOS get] + action:isBTOn ? @selector(stopBluetooth) : @selector(startBluetooth)]; +#else + return nil; +#endif +} + +- (IBAction)startBluetooth +{ +#ifdef WIIMOTE + [WiiMoteHelper startBluetooth]; + [self.topViewController.navigationItem setRightBarButtonItem:[self createBluetoothButton] animated:YES]; #endif } @@ -244,7 +263,7 @@ { #ifdef WIIMOTE [WiiMoteHelper stopBluetooth]; - [self.topViewController.navigationItem setRightBarButtonItem:nil animated:YES]; + [self.topViewController.navigationItem setRightBarButtonItem:[self createBluetoothButton] animated:YES]; #endif } diff --git a/ios/RetroArch/input/BTStack/BTDiscoveryViewController.h b/ios/RetroArch/input/BTStack/BTDiscoveryViewController.h deleted file mode 100644 index ab030db32a..0000000000 --- a/ios/RetroArch/input/BTStack/BTDiscoveryViewController.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2009 by Matthias Ringwald - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS - * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ -#import -#import "BTstackManager.h" - -@class BTstackManager; -@protocol BTDiscoveryDelegate; - -typedef enum { - kInquiryInactive, - kInquiryActive, - kInquiryRemoteName -} InquiryState; - -@interface BTDiscoveryViewController : UITableViewController -{ - BTstackManager *bt; - NSObject * _delegate; - UIActivityIndicatorView *deviceActivity; - UIActivityIndicatorView *bluetoothActivity; - UIFont * deviceNameFont; - UIFont * macAddressFont; - InquiryState inquiryState; - int remoteNameIndex; - BOOL showIcons; - int connectingIndex; - NSString *customActivityText; -} --(void) markConnecting:(int)index; // use -1 for no connection active -@property (nonatomic, assign) NSObject * delegate; -@property (nonatomic, assign) BOOL showIcons; -@property (nonatomic, retain) NSString *customActivityText; -@end - -@protocol BTDiscoveryDelegate -@optional --(BOOL) discoveryView:(BTDiscoveryViewController*)discoveryView willSelectDeviceAtIndex:(int)deviceIndex; // returns NO to ignore selection --(void) statusCellSelectedDiscoveryView:(BTDiscoveryViewController*)discoveryView; -@end diff --git a/ios/RetroArch/input/BTStack/BTDiscoveryViewController.m b/ios/RetroArch/input/BTStack/BTDiscoveryViewController.m deleted file mode 100644 index e79986c010..0000000000 --- a/ios/RetroArch/input/BTStack/BTDiscoveryViewController.m +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (C) 2009 by Matthias Ringwald - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS - * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#import "BTDiscoveryViewController.h" -#import "BTDevice.h" - -// fix compare for 3.0 -#ifndef __IPHONE_3_0 -#define __IPHONE_3_0 30000 -#endif - -#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_0 -// SDK 30 defines missing in SDK 20 -@interface UITableViewCell (NewIn30) -- (id)initWithStyle:(int)style reuseIdentifier:(NSString *)reuseIdentifier; -@end -#endif -@interface UIDevice (privateAPI) --(BOOL) isWildcat; -@end - -@implementation BTDiscoveryViewController -@synthesize showIcons; -@synthesize delegate = _delegate; -@synthesize customActivityText; - -- (id) init { - self = [super initWithStyle:UITableViewStyleGrouped]; - macAddressFont = [UIFont fontWithName:@"Courier New" size:[UIFont labelFontSize]]; - deviceNameFont = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]]; - inquiryState = kInquiryInactive; - connectingIndex = -1; - - deviceActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; - [deviceActivity startAnimating]; - bluetoothActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; - [bluetoothActivity startAnimating]; - - bt = [BTstackManager sharedInstance]; - _delegate = nil; - return self; -} - --(void) reload{ - [[self tableView] reloadData]; -} - -/* -- (id)initWithStyle:(UITableViewStyle)style { - // Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad. - if (self = [super initWithStyle:style]) { - } - return self; -} -*/ - -/* -- (void)viewDidLoad { - [super viewDidLoad]; - - // Uncomment the following line to display an Edit button in the navigation bar for this view controller. - // self.navigationItem.rightBarButtonItem = self.editButtonItem; -} -*/ - -/* -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; -} -*/ -/* -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; -} -*/ -/* -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; -} -*/ -/* -- (void)viewDidDisappear:(BOOL)animated { - [super viewDidDisappear:animated]; -} -*/ - -/* -// Override to allow orientations other than the default portrait orientation. -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - // Return YES for supported orientations - return (interfaceOrientation == UIInterfaceOrientationPortrait); -} - -- (void)didReceiveMemoryWarning { - // Releases the view if it doesn't have a superview. - [super didReceiveMemoryWarning]; - - // Release any cached data, images, etc that aren't in use. -} - */ - - -// BTstackManagerListenerDelegate --(void) activatedBTstackManager:(BTstackManager*) manager{ - [self reload]; -} --(void) btstackManager:(BTstackManager*)manager activationFailed:(BTstackError)error { - [self reload]; -} --(void) discoveryInquiryBTstackManager:(BTstackManager*) manager { - inquiryState = kInquiryActive; - [self reload]; -} --(void) btstackManager:(BTstackManager*)manager discoveryQueryRemoteName:(int)deviceIndex { - inquiryState = kInquiryRemoteName; - remoteNameIndex = deviceIndex; - [self reload]; -} --(void) discoveryStoppedBTstackManager:(BTstackManager*) manager { - inquiryState = kInquiryInactive; - [self reload]; -} --(void) btstackManager:(BTstackManager*)manager deviceInfo:(BTDevice*)device { - [self reload]; -} - --(void) markConnecting:(int)index; { - connectingIndex = index; - [self reload]; -} - --(void) setCustomActivityText:(NSString*) text{ - [text retain]; - [customActivityText release]; - customActivityText = text; - [self reload]; -} - -// MARK: Table view methods - -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ - return @"Devices"; -} - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 1; -} - -// Customize the number of rows in the table view. -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return 1 + [bt numberOfDevicesFound]; -} - - -// Customize the appearance of table view cells. -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - - static NSString *CellIdentifier = @"Cell"; - - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; - if (cell == nil) { -#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_3_0 - cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; -#else - cell = [[[UITableViewCell alloc] initWithFrame:CGRectNull reuseIdentifier:(NSString *)CellIdentifier] autorelease]; -#endif - } - - // Set up the cell... - NSString *theLabel = nil; - UIImage *theImage = nil; - UIFont *theFont = nil; - - int idx = [indexPath indexAtPosition:1]; - if (idx >= [bt numberOfDevicesFound]) { - if (customActivityText) { - theLabel = customActivityText; - cell.accessoryView = bluetoothActivity; - } else if ([bt isActivating]){ - theLabel = @"Activating BTstack..."; - cell.accessoryView = bluetoothActivity; - } else if (![bt isActive]){ - theLabel = @"Bluetooth not accessible!"; - cell.accessoryView = nil; - } else { - -#if 0 - if (connectedDevice) { - theLabel = @"Disconnect"; - cell.accessoryView = nil; - } -#endif - - if (connectingIndex >= 0) { - theLabel = @"Connecting..."; - cell.accessoryView = bluetoothActivity; - } else { - switch (inquiryState){ - case kInquiryInactive: - if ([bt numberOfDevicesFound] > 0){ - theLabel = @"Find more devices..."; - } else { - theLabel = @"Find devices..."; - } - cell.accessoryView = nil; - break; - case kInquiryActive: - theLabel = @"Searching..."; - cell.accessoryView = bluetoothActivity; - break; - case kInquiryRemoteName: - theLabel = @"Query device names..."; - cell.accessoryView = bluetoothActivity; - break; - } - } - } - } else { - - BTDevice *dev = [bt deviceAtIndex:idx]; - - // pick font - theLabel = [dev nameOrAddress]; - if ([dev name]){ - theFont = deviceNameFont; - } else { - theFont = macAddressFont; - } - - // pick an icon for the devices - if (showIcons) { - NSString *imageName = @"bluetooth.png"; - // check major device class - switch (([dev classOfDevice] & 0x1f00) >> 8) { - case 0x01: - imageName = @"computer.png"; - break; - case 0x02: - imageName = @"smartphone.png"; - break; - case 0x05: - switch ([dev classOfDevice] & 0xff){ - case 0x40: - imageName = @"keyboard.png"; - break; - case 0x80: - imageName = @"mouse.png"; - break; - case 0xc0: - imageName = @"keyboard.png"; - break; - default: - imageName = @"HID.png"; - break; - } - } - -#ifdef LASER_KB - if ([dev name] && [[dev name] isEqualToString:@"CL800BT"]){ - imageName = @"keyboard.png"; - } - - if ([dev name] && [[dev name] isEqualToString:@"CL850"]){ - imageName = @"keyboard.png"; - } - - // Celluon CL800BT, CL850 have 00-0b-24-aa-bb-cc, COD 0x400210 - uint8_t *addr = (uint8_t *) [dev address]; - if (addr[0] == 0x00 && addr[1] == 0x0b && addr[2] == 0x24){ - imageName = @"keyboard.png"; - } -#endif - theImage = [UIImage imageNamed:imageName]; - } - - // set accessory view - if (idx == connectingIndex){ - cell.accessoryView = deviceActivity; - } else { - cell.accessoryView = nil; - } - } -#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_3_0 - if (theLabel) cell.textLabel.text = theLabel; - if (theFont) cell.textLabel.font = theFont; - if (theImage) cell.imageView.image = theImage; -#else - if (theLabel) cell.text = theLabel; - if (theFont) cell.font = theFont; - if (theImage) cell.image = theImage; -#endif - return cell; -} - - -- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { - if (!_delegate) return nil; - int index = [indexPath indexAtPosition:1]; - if (index >= [bt numberOfDevicesFound]){ - if ([_delegate respondsToSelector:@selector(statusCellSelectedDiscoveryView:)]){ - [_delegate statusCellSelectedDiscoveryView:self]; - return nil; - } - } - if ([_delegate respondsToSelector:@selector(discoveryView:willSelectDeviceAtIndex:)] && [_delegate discoveryView:self willSelectDeviceAtIndex:index]){ - return indexPath; - } - return nil; -} - -// Override to allow orientations other than the default portrait orientation. -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - UIDevice * uiDevice = [UIDevice currentDevice]; - return [uiDevice respondsToSelector:@selector(isWildcat)] && [uiDevice isWildcat]; -} - -- (void)dealloc { - [super dealloc]; -} - - -@end - diff --git a/ios/RetroArch/input/BTStack/WiiMoteHelper.h b/ios/RetroArch/input/BTStack/WiiMoteHelper.h index 37a63fb567..9e5aba6184 100644 --- a/ios/RetroArch/input/BTStack/WiiMoteHelper.h +++ b/ios/RetroArch/input/BTStack/WiiMoteHelper.h @@ -31,12 +31,11 @@ #import -#import "BTDiscoveryViewController.h" +#import "BTstackManager.h" -@interface WiiMoteHelper : NSObject -+ (WiiMoteHelper*)get; +@interface WiiMoteHelper : NSObject ++ (void)startBluetooth; + (BOOL)isBluetoothRunning; + (void)stopBluetooth; -- (void)showDiscovery; @end diff --git a/ios/RetroArch/input/BTStack/WiiMoteHelper.m b/ios/RetroArch/input/BTStack/WiiMoteHelper.m index 08f27bf5e4..e337f6262a 100644 --- a/ios/RetroArch/input/BTStack/WiiMoteHelper.m +++ b/ios/RetroArch/input/BTStack/WiiMoteHelper.m @@ -38,27 +38,24 @@ #import "BTDevice.h" #import "BTstackManager.h" -#import "BTDiscoveryViewController.h" -#import "btstack/btstack.h" -#import "btstack/run_loop.h" -#import "btstack/hci_cmds.h" - -static BTDiscoveryViewController* discoveryView; static WiiMoteHelper* instance; static BTDevice *device; static bool btOK; - @implementation WiiMoteHelper -+ (WiiMoteHelper*)get ++ (void)startBluetooth { - if (!instance) - { - instance = [WiiMoteHelper new]; - } + instance = instance ? instance : [WiiMoteHelper new]; - return instance; + if (!btOK) + { + BTstackManager* bt = [BTstackManager sharedInstance]; + [bt setDelegate:instance]; + [bt addListener:instance]; + + btOK = [bt activate] == 0; + } } + (BOOL)isBluetoothRunning @@ -68,46 +65,19 @@ static bool btOK; + (void)stopBluetooth { - instance = nil; myosd_num_of_joys = 0; if (btOK) { BTstackManager* bt = [BTstackManager sharedInstance]; - - [bt removeListener:discoveryView]; - discoveryView = nil; - - [[BTstackManager sharedInstance] deactivate]; + + [bt deactivate]; + [bt setDelegate:nil]; + [bt removeListener:instance]; btOK = false; } -} - -- (id)init -{ - if (!btOK) - { - BTstackManager* bt = [BTstackManager sharedInstance]; - [bt setDelegate:self]; - [bt addListener:self]; - - btOK = [bt activate] == 0; - } - return self; -} - -- (void)showDiscovery -{ - if (!discoveryView) - { - discoveryView = [BTDiscoveryViewController new]; - [discoveryView setDelegate:self]; - - [[BTstackManager sharedInstance] addListener:discoveryView]; - } - - [[RetroArch_iOS get] pushViewController:discoveryView animated:YES]; + instance = nil; } // BTStackManagerListener @@ -132,10 +102,10 @@ static bool btOK; // BTStackManagerDelegate -(void) btstackManager:(BTstackManager*) manager - handlePacketWithType:(uint8_t) packet_type - forChannel:(uint16_t) channel - andData:(uint8_t *)packet - withLen:(uint16_t) size + handlePacketWithType:(uint8_t)packet_type + forChannel:(uint16_t)channel + andData:(uint8_t*)packet + withLen:(uint16_t)size { bd_addr_t event_addr; diff --git a/ios/RetroArch/settings/RASettingsList.m b/ios/RetroArch/settings/RASettingsList.m index 6f6cfe2092..7cf9e3ff15 100644 --- a/ios/RetroArch/settings/RASettingsList.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -92,10 +92,10 @@ static RASettingData* custom_action(NSString* action) NSString* shader_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/shaders/"]; NSArray* settings = [NSArray arrayWithObjects: - [NSArray arrayWithObjects:@"General", + [NSArray arrayWithObjects:@"Frontend", custom_action(@"Module Info"), #ifdef WIIMOTE - custom_action(@"Connect WiiMotes"), + boolean_setting(config, @"ios_auto_bluetooth", @"Auto Enable Bluetooth", @"false"), #endif nil], @@ -176,8 +176,6 @@ static RASettingData* custom_action(NSString* action) { if ([@"Module Info" isEqualToString:action]) [[RetroArch_iOS get] pushViewController:[[RAModuleInfoList alloc] initWithModuleInfo:[RetroArch_iOS get].moduleInfo] animated:YES]; - else if([@"Connect WiiMotes" isEqualToString:action]) - [[RetroArch_iOS get] showWiiRemoteConfig]; } @end From ac9b75a87188882ec02af53d41cc347874277aa3 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sat, 9 Mar 2013 21:19:11 -0500 Subject: [PATCH 106/108] (iOS) Make settings changes take place even while the game is running. --- ios/RetroArch/RetroArch_iOS.h | 1 + ios/RetroArch/RetroArch_iOS.m | 16 +++++++++++++++- ios/RetroArch/settings/RASettingsList.m | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/ios/RetroArch/RetroArch_iOS.h b/ios/RetroArch/RetroArch_iOS.h index aa026b7011..08bae16b3d 100644 --- a/ios/RetroArch/RetroArch_iOS.h +++ b/ios/RetroArch/RetroArch_iOS.h @@ -21,6 +21,7 @@ + (RetroArch_iOS*)get; - (void)runGame:(NSString*)path; +- (void)refreshConfig; - (IBAction)showSettings; diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index f54967c61a..7e9040d922 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -159,6 +159,20 @@ } } +- (void)refreshConfig +{ + // Need to clear these otherwise stale versions may be used! + memset(g_settings.input.overlay, 0, sizeof(g_settings.input.overlay)); + memset(g_settings.video.bsnes_shader_path, 0, sizeof(g_settings.video.bsnes_shader_path)); + + if (_isRunning) + { + uninit_drivers(); + config_load(); + init_drivers(); + } +} + - (void)iterate { if (_isPaused || !_isRunning || !_isGameTop) @@ -236,7 +250,7 @@ [self pushViewController:[RASettingsList new] animated:YES]; } -#pragma MARK Bluetooth Helpers +#pragma mark Bluetooth Helpers - (UIBarButtonItem*)createBluetoothButton { #ifdef WIIMOTE diff --git a/ios/RetroArch/settings/RASettingsList.m b/ios/RetroArch/settings/RASettingsList.m index 7cf9e3ff15..5eda933dda 100644 --- a/ios/RetroArch/settings/RASettingsList.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -170,6 +170,7 @@ static RASettingData* custom_action(NSString* action) RAConfig* config = [[RAConfig alloc] initWithPath:[RetroArch_iOS get].moduleInfo.configPath]; [self writeSettings:nil toConfig:config]; [config writeToFile:[RetroArch_iOS get].moduleInfo.configPath]; + [[RetroArch_iOS get] refreshConfig]; } - (void)handleCustomAction:(NSString*)action From e9497abc6173a8b17b08885575e16d8437b6e192 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 10 Mar 2013 00:05:19 -0500 Subject: [PATCH 107/108] (iOS) Add (hacky) aspect ratio setting. --- ios/RetroArch/RAConfig.h | 1 + ios/RetroArch/RAConfig.m | 47 +++++++++------------- ios/RetroArch/settings/RASettingsList.m | 23 +++++++++++ ios/RetroArch/settings/RASettingsSubList.m | 12 ++++++ ios/RetroArch/settings/settings.h | 3 +- 5 files changed, 57 insertions(+), 29 deletions(-) diff --git a/ios/RetroArch/RAConfig.h b/ios/RetroArch/RAConfig.h index b19742ffcf..91f301d959 100644 --- a/ios/RetroArch/RAConfig.h +++ b/ios/RetroArch/RAConfig.h @@ -20,6 +20,7 @@ - (bool)getBoolNamed:(NSString*)name withDefault:(bool)def; - (int)getIntNamed:(NSString*)name withDefault:(int)def; - (unsigned)getUintNamed:(NSString*)name withDefault:(unsigned)def; +- (double)getDoubleNamed:(NSString*)name withDefault:(double)def; - (NSString*)getStringNamed:(NSString*)name withDefault:(NSString*)def; - (void)putIntNamed:(NSString*)name value:(int)value; diff --git a/ios/RetroArch/RAConfig.m b/ios/RetroArch/RAConfig.m index 76947fb901..b0b0bc62db 100644 --- a/ios/RetroArch/RAConfig.m +++ b/ios/RetroArch/RAConfig.m @@ -30,43 +30,39 @@ - (void)dealloc { - if (_config) - config_file_free(_config); + config_file_free(_config); } - (void)writeToFile:(NSString*)path { - if (_config) - config_file_write(_config, [path UTF8String]); + config_file_write(_config, [path UTF8String]); } - (bool)getBoolNamed:(NSString*)name withDefault:(bool)def { bool result = def; - - if (_config) - config_get_bool(_config, [name UTF8String], &result); - + config_get_bool(_config, [name UTF8String], &result); return result; } - (int)getIntNamed:(NSString*)name withDefault:(int)def { int result = def; - - if (_config) - config_get_int(_config, [name UTF8String], &result); - + config_get_int(_config, [name UTF8String], &result); return result; } - (unsigned)getUintNamed:(NSString*)name withDefault:(unsigned)def { unsigned result = def; - - if (_config) - config_get_uint(_config, [name UTF8String], &result); - + config_get_uint(_config, [name UTF8String], &result); + return result; +} + +- (double)getDoubleNamed:(NSString*)name withDefault:(double)def +{ + double result = def; + config_get_double(_config, [name UTF8String], &result); return result; } @@ -74,27 +70,22 @@ { NSString* result = def; - if (_config) - { - char* data = 0; - if (config_get_string(_config, [name UTF8String], &data)) - result = [NSString stringWithUTF8String:data]; - free(data); - } - + char* data = 0; + if (config_get_string(_config, [name UTF8String], &data)) + result = [NSString stringWithUTF8String:data]; + free(data); + return result; } - (void)putIntNamed:(NSString*)name value:(int)value { - if (_config) - config_set_int(_config, [name UTF8String], value); + config_set_int(_config, [name UTF8String], value); } - (void)putStringNamed:(NSString*)name value:(NSString*)value { - if (_config) - config_set_string(_config, [name UTF8String], [value UTF8String]); + config_set_string(_config, [name UTF8String], [value UTF8String]); } @end diff --git a/ios/RetroArch/settings/RASettingsList.m b/ios/RetroArch/settings/RASettingsList.m index 5eda933dda..81ff39a2c7 100644 --- a/ios/RetroArch/settings/RASettingsList.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -78,6 +78,27 @@ static RASettingData* subpath_setting(RAConfig* config, NSString* name, NSString return result; } +static RASettingData* aspect_setting(RAConfig* config, NSString* label) +{ + // Why does this need to be so difficult? + + RASettingData* result = [[RASettingData alloc] initWithType:AspectSetting label:label name:@"fram"]; + result.subValues = [NSArray arrayWithObjects:@"Fill Screen", @"Game Aspect", @"Pixel Aspect", @"4:3", @"16:9", nil]; + + bool videoForceAspect = [config getBoolNamed:@"video_force_aspect" withDefault:true]; + bool videoAspectAuto = [config getBoolNamed:@"video_aspect_ratio_auto" withDefault:false]; + double videoAspect = [config getDoubleNamed:@"video_aspect_ratio" withDefault:0.0]; + + if (!videoForceAspect) + result.value = @"Fill Screen"; + else if (videoAspect < 0.0) + result.value = videoAspectAuto ? @"Game Aspect" : @"Pixel Aspect"; + else + result.value = (videoAspect < 1.5) ? @"4:3" : @"16:9"; + + return result; +} + static RASettingData* custom_action(NSString* action) { return [[RASettingData alloc] initWithType:CustomAction label:action name:nil]; @@ -103,6 +124,8 @@ static RASettingData* custom_action(NSString* action) boolean_setting(config, @"video_smooth", @"Smooth Video", @"true"), boolean_setting(config, @"video_crop_overscan", @"Crop Overscan", @"true"), subpath_setting(config, @"video_bsnes_shader", @"Shader", @"", shader_path, @"shader"), + aspect_setting(config, @"Aspect Ratio"), + boolean_setting(config, @"video_scale_integer", @"Integer Scaling", @"false"), nil], [NSArray arrayWithObjects:@"Audio", diff --git a/ios/RetroArch/settings/RASettingsSubList.m b/ios/RetroArch/settings/RASettingsSubList.m index 5dfe672b64..12f642398c 100644 --- a/ios/RetroArch/settings/RASettingsSubList.m +++ b/ios/RetroArch/settings/RASettingsSubList.m @@ -69,6 +69,16 @@ static const char* const SETTINGID = "SETTING"; [config putStringNamed:[setting.name stringByAppendingString:@"_btn"] value:setting.msubValues[1]]; break; + case AspectSetting: + [config putStringNamed:@"video_force_aspect" value:[@"Fill Screen" isEqualToString:setting.value] ? @"false" : @"true"]; + [config putStringNamed:@"video_aspect_ratio_auto" value:[@"Game Aspect" isEqualToString:setting.value] ? @"true" : @"false"]; + [config putStringNamed:@"video_aspect_ratio" value:@"-1.0"]; + if([@"4:3" isEqualToString:setting.value]) + [config putStringNamed:@"video_aspect_ratio" value:@"1.33333333"]; + else if([@"16:9" isEqualToString:setting.value]) + [config putStringNamed:@"video_aspect_ratio" value:@"1.777777777"]; + break; + case CustomAction: break; @@ -88,6 +98,7 @@ static const char* const SETTINGID = "SETTING"; { case EnumerationSetting: case FileListSetting: + case AspectSetting: [[RetroArch_iOS get] pushViewController:[[RASettingEnumerationList alloc] initWithSetting:setting fromTable:(UITableView*)self.view] animated:YES]; break; @@ -147,6 +158,7 @@ static const char* const SETTINGID = "SETTING"; case FileListSetting: case ButtonSetting: case CustomAction: + case AspectSetting: { cell = [self.tableView dequeueReusableCellWithIdentifier:@"enumeration"]; cell = cell ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"enumeration"]; diff --git a/ios/RetroArch/settings/settings.h b/ios/RetroArch/settings/settings.h index 2b7dd8634f..b95f70a3f4 100644 --- a/ios/RetroArch/settings/settings.h +++ b/ios/RetroArch/settings/settings.h @@ -15,7 +15,8 @@ enum SettingTypes { - BooleanSetting, ButtonSetting, EnumerationSetting, FileListSetting, GroupSetting, CustomAction + BooleanSetting, ButtonSetting, EnumerationSetting, FileListSetting, + GroupSetting, AspectSetting, CustomAction }; @interface RASettingData : NSObject From debf31b7a40ca00e18fedd02886a8eb123989c68 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 10 Mar 2013 13:53:09 -0400 Subject: [PATCH 108/108] (iOS) Various: Re-add default config generation code, if a config file didn't exist it would not be possible to change settings while running. Sort emulator core list. Add .info files for more emulators. --- ios/RetroArch/RetroArch_iOS.m | 2 ++ ios/RetroArch/browser/RAModuleList.m | 13 ++++++++++++- ios/RetroArch/settings/RASettingsList.m | 10 ++++++++-- ios/RetroArch/settings/RASettingsSubList.m | 1 + ios/RetroArch/settings/settings.h | 1 + ios/modules/mednafen_ngp_libretro.info | 6 ++++++ ios/modules/mednafen_pce_fast_libretro.info | 6 ++++++ ios/modules/mednafen_psx_libretro.info | 6 ++++++ ios/modules/mednafen_vb_libretro.info | 6 ++++++ ios/modules/mednafen_wswan_libretro.info | 6 ++++++ 10 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 ios/modules/mednafen_ngp_libretro.info create mode 100644 ios/modules/mednafen_pce_fast_libretro.info create mode 100644 ios/modules/mednafen_psx_libretro.info create mode 100644 ios/modules/mednafen_vb_libretro.info create mode 100644 ios/modules/mednafen_wswan_libretro.info diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 7e9040d922..a40f382d3a 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -114,6 +114,8 @@ - (void)runGame:(NSString*)path { assert(self.moduleInfo); + + [RASettingsList refreshConfigFile]; const char* const sd = [[RetroArch_iOS get].system_directory UTF8String]; const char* const cf = (ra_ios_is_file(self.moduleInfo.configPath)) ? [self.moduleInfo.configPath UTF8String] : 0; diff --git a/ios/RetroArch/browser/RAModuleList.m b/ios/RetroArch/browser/RAModuleList.m index 0430803900..deac9a8c13 100644 --- a/ios/RetroArch/browser/RAModuleList.m +++ b/ios/RetroArch/browser/RAModuleList.m @@ -60,7 +60,18 @@ else [_other addObject:module]; } - + + // Sort + [_supported sortUsingComparator:^(RAModuleInfo* left, RAModuleInfo* right) + { + return [left.displayName caseInsensitiveCompare:right.displayName]; + }]; + + [_other sortUsingComparator:^(RAModuleInfo* left, RAModuleInfo* right) + { + return [left.displayName caseInsensitiveCompare:right.displayName]; + }]; + [self setTitle:[_game lastPathComponent]]; return self; } diff --git a/ios/RetroArch/settings/RASettingsList.m b/ios/RetroArch/settings/RASettingsList.m index 81ff39a2c7..ccca49d031 100644 --- a/ios/RetroArch/settings/RASettingsList.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -105,6 +105,11 @@ static RASettingData* custom_action(NSString* action) } @implementation RASettingsList ++ (void)refreshConfigFile +{ + (void)[[RASettingsList alloc] init]; +} + - (id)init { RAConfig* config = [[RAConfig alloc] initWithPath:[RetroArch_iOS get].moduleInfo.configPath]; @@ -123,9 +128,9 @@ static RASettingData* custom_action(NSString* action) [NSArray arrayWithObjects:@"Video", boolean_setting(config, @"video_smooth", @"Smooth Video", @"true"), boolean_setting(config, @"video_crop_overscan", @"Crop Overscan", @"true"), - subpath_setting(config, @"video_bsnes_shader", @"Shader", @"", shader_path, @"shader"), - aspect_setting(config, @"Aspect Ratio"), boolean_setting(config, @"video_scale_integer", @"Integer Scaling", @"false"), + aspect_setting(config, @"Aspect Ratio"), + subpath_setting(config, @"video_bsnes_shader", @"Shader", @"", shader_path, @"shader"), nil], [NSArray arrayWithObjects:@"Audio", @@ -191,6 +196,7 @@ static RASettingData* custom_action(NSString* action) - (void)dealloc { RAConfig* config = [[RAConfig alloc] initWithPath:[RetroArch_iOS get].moduleInfo.configPath]; + [config putStringNamed:@"system_directory" value:[RetroArch_iOS get].system_directory]; [self writeSettings:nil toConfig:config]; [config writeToFile:[RetroArch_iOS get].moduleInfo.configPath]; [[RetroArch_iOS get] refreshConfig]; diff --git a/ios/RetroArch/settings/RASettingsSubList.m b/ios/RetroArch/settings/RASettingsSubList.m index 12f642398c..bd7b512091 100644 --- a/ios/RetroArch/settings/RASettingsSubList.m +++ b/ios/RetroArch/settings/RASettingsSubList.m @@ -162,6 +162,7 @@ static const char* const SETTINGID = "SETTING"; { cell = [self.tableView dequeueReusableCellWithIdentifier:@"enumeration"]; cell = cell ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"enumeration"]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; } break; diff --git a/ios/RetroArch/settings/settings.h b/ios/RetroArch/settings/settings.h index b95f70a3f4..94a9c522c8 100644 --- a/ios/RetroArch/settings/settings.h +++ b/ios/RetroArch/settings/settings.h @@ -48,4 +48,5 @@ enum SettingTypes @end @interface RASettingsList : RASettingsSubList ++ (void)refreshConfigFile; @end diff --git a/ios/modules/mednafen_ngp_libretro.info b/ios/modules/mednafen_ngp_libretro.info new file mode 100644 index 0000000000..6c6f672b99 --- /dev/null +++ b/ios/modules/mednafen_ngp_libretro.info @@ -0,0 +1,6 @@ +display_name = "Neo Geo Pocket (Color)" +supported_extensions = "ngp|ngc" +emuname = "Mednafen Neopop" +manufacturer = "SNK" +systemname = "Neo Geo Pocket (Color)" + diff --git a/ios/modules/mednafen_pce_fast_libretro.info b/ios/modules/mednafen_pce_fast_libretro.info new file mode 100644 index 0000000000..22279a08e4 --- /dev/null +++ b/ios/modules/mednafen_pce_fast_libretro.info @@ -0,0 +1,6 @@ +display_name = "PC Engine/TurboGrafx-16" +supported_extensions = "pce|sgx|cue" +emuname = "Mednafen PCE Fast" +manufacturer = "NEC" +systemname = "PC Engine/TurboGrafx-16" + diff --git a/ios/modules/mednafen_psx_libretro.info b/ios/modules/mednafen_psx_libretro.info new file mode 100644 index 0000000000..5d1b2d54e0 --- /dev/null +++ b/ios/modules/mednafen_psx_libretro.info @@ -0,0 +1,6 @@ +display_name = "PlayStation" +supported_extensions = "cue|toc" +emuname = "Mednafen PSX" +manufacturer = "Sony" +systemname = "PlayStation" + diff --git a/ios/modules/mednafen_vb_libretro.info b/ios/modules/mednafen_vb_libretro.info new file mode 100644 index 0000000000..e889dd6390 --- /dev/null +++ b/ios/modules/mednafen_vb_libretro.info @@ -0,0 +1,6 @@ +display_name = "Virtual Boy" +supported_extensions = "vb|vboy|bin" +emuname = "Mednafen VB" +manufacturer = "Nintendo" +systemname = "Virtual Boy" + diff --git a/ios/modules/mednafen_wswan_libretro.info b/ios/modules/mednafen_wswan_libretro.info new file mode 100644 index 0000000000..29b02a79ac --- /dev/null +++ b/ios/modules/mednafen_wswan_libretro.info @@ -0,0 +1,6 @@ +display_name = "WonderSwan (Color)" +supported_extensions = "ws|wsc" +emuname = "Mednafen WonderSwan" +manufacturer = "Bandai" +systemname = "WonderSwan (Color)" +