iOSUtil.mm 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "iOSUtil.h"
  23. #include "io/stream.h"
  24. #include "io/fileStream.h"
  25. #include "io/memstream.h"
  26. #include "graphics/gPalette.h"
  27. #include "graphics/gBitmap.h"
  28. #include "memory/frameAllocator.h"
  29. #include "console/console.h"
  30. #include "platformiOS/platformiOS.h"
  31. #import <UIKit/UIGraphics.h>
  32. #import <UIKit/UIKit.h>
  33. //For networking bsd and IP
  34. #import <netinet/in.h>
  35. #import <sys/types.h>
  36. #import <sys/socket.h>
  37. #import <ifaddrs.h>
  38. #import <arpa/inet.h>
  39. //Luma: Orientation support
  40. int giOSGameCurrentOrientation = UIDeviceOrientationLandscapeRight;
  41. TCPObject* gpTCPObject = NULL;
  42. char gszTCPAddress[256];
  43. //-----------------------------------------------------------------------------
  44. void Platform::outputDebugString( const char *string )
  45. {
  46. fprintf(stderr, "%s", string);
  47. fprintf(stderr, "\n" );
  48. fflush(stderr);
  49. }
  50. //--------------------------------------
  51. bool GBitmap::readPNGiPhone(Stream& io_rStream)
  52. {
  53. int filesize = io_rStream.getStreamSize();
  54. U8 *buff = new U8[filesize+1024];
  55. CGDataProviderRef data_provider = CGDataProviderCreateWithData(nil, buff, filesize, nil);
  56. CGImageRef apple_image = CGImageCreateWithPNGDataProvider(data_provider, nil, false, kCGRenderingIntentDefault);
  57. // Choose alpha strategy based on whether the source image has alpha or not.
  58. int width = CGImageGetWidth(apple_image);
  59. int height = CGImageGetHeight(apple_image);
  60. U32 rowBytes = width * 4;
  61. // Set up the row pointers...
  62. AssertISV(width <= 1024, "Error, cannot load images wider than 1024 pixels!");
  63. AssertISV(height <= 1024, "Error, cannot load images taller than 1024 pixels!");
  64. BitmapFormat format = RGBA;
  65. // actually allocate the bitmap space...
  66. allocateBitmap(width, height,
  67. false, // don't extrude miplevels...
  68. format); // use determined format...
  69. U8 *pBase = (U8*)getBits();
  70. CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB();
  71. CGContextRef texture_context = CGBitmapContextCreate(pBase, width, height, 8, rowBytes, color_space, kCGImageAlphaPremultipliedLast);
  72. CGContextDrawImage(texture_context, CGRectMake(0.0, 0.0, width, height), apple_image);
  73. CGImageRelease(apple_image);
  74. CGDataProviderRelease(data_provider);
  75. delete [] buff;
  76. return true;
  77. }
  78. //Luma: Orientation support
  79. int _iOSGameGetOrientation()
  80. {
  81. return giOSGameCurrentOrientation;
  82. }
  83. void _iOSGameSetCurrentOrientation(int iOrientation)
  84. {
  85. giOSGameCurrentOrientation = iOrientation;
  86. }
  87. S32 _iOSGetPortraitTouchoffset()
  88. {
  89. // NOTE: This needs to be changed to acount for different retina sizes, but I am not sure what is going on with it yet
  90. S32 offset = 0;
  91. S32 deviceType = Con::getIntVariable("$pref::iOS::DeviceType");
  92. bool retinaEnabled = Con::getBoolVariable("$pref::iOS::RetinaEnabled");
  93. if (deviceType == 2)
  94. offset = 500;
  95. else if (deviceType == 1)
  96. offset = retinaEnabled ? 500 : 250;
  97. else
  98. offset = retinaEnabled ? 320 : 160;
  99. return offset;
  100. }
  101. //Luma: Ability to get the Local IP (Internal IP) for an iOS as opposed to it's External one
  102. void _iOSGetLocalIP(unsigned char *pcIPString)
  103. {
  104. int a,b,c,d ;
  105. struct ifaddrs* interface;
  106. char* addr;
  107. if (getifaddrs(&interface) == 0)
  108. {
  109. struct ifaddrs* allInterfaces = interface;
  110. while (interface != NULL)
  111. {
  112. const struct sockaddr_in* address = (const struct sockaddr_in*) interface->ifa_addr;
  113. addr = inet_ntoa(address->sin_addr);
  114. if ((address->sin_family == AF_INET) && (strcmp(addr, "127.0.0.1" )))
  115. {
  116. break;
  117. }
  118. interface = interface->ifa_next;
  119. }
  120. freeifaddrs(allInterfaces);
  121. }
  122. if(interface)
  123. {
  124. sscanf( addr, "%i.%i.%i.%i", &a, &b, &c, &d);
  125. }
  126. else
  127. {
  128. a = 0;
  129. b = 0;
  130. c = 0;
  131. d = 0;
  132. }
  133. pcIPString[0] = (unsigned char)a;
  134. pcIPString[1] = (unsigned char)b;
  135. pcIPString[2] = (unsigned char)c;
  136. pcIPString[3] = (unsigned char)d;
  137. }
  138. //Luma: Make sure that the iOS Radio is on before connection via TCP... NOTE: sometimes the Radio wont be ready for immediate use after this is processed... need to see why
  139. static void TCPObjectConnectCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *dataIn, void *info)
  140. {
  141. if(type == kCFSocketConnectCallBack)
  142. {
  143. if(dataIn)
  144. {
  145. SInt32 error = *((SInt32*)dataIn);
  146. Con::printf("Error connecting with CFSocker: Error code %d\n",error);
  147. }
  148. }
  149. //regardless, we want to connect to the TCPObject if we opened the socket or not so that it can continue its process properly
  150. if(gpTCPObject)
  151. {
  152. gpTCPObject->connect(gszTCPAddress);
  153. gpTCPObject = NULL;
  154. }
  155. }
  156. //Luma: Make sure that the iOS Radio is on before connection via TCP... NOTE: sometimes the Radio wont be ready for immediate use after this is processed... need to see why
  157. CFSocketRef CreateCFSocketToURLAndPort(const char *ipAddress, U16 port)
  158. {
  159. CFSocketContext context;
  160. context.version = 0;
  161. context.info = NULL;
  162. context.retain = NULL;
  163. context.release = NULL;
  164. context.copyDescription = NULL;
  165. CFSocketRef socket = CFSocketCreate(kCFAllocatorDefault,
  166. PF_INET,
  167. SOCK_STREAM,
  168. IPPROTO_TCP,
  169. kCFSocketConnectCallBack,
  170. TCPObjectConnectCallback,
  171. &context);
  172. struct sockaddr_in addr4;
  173. memset(&addr4, 0, sizeof(addr4));
  174. addr4.sin_family = AF_INET;
  175. addr4.sin_len = sizeof(addr4);
  176. addr4.sin_port = htons(port);
  177. inet_aton(ipAddress, &addr4.sin_addr);
  178. NSData *address = [NSData dataWithBytes:&addr4 length:sizeof(addr4)];
  179. CFSocketConnectToAddress(socket, (__bridge CFDataRef)address, -1);
  180. CFRunLoopSourceRef source;
  181. source = CFSocketCreateRunLoopSource(NULL, socket, 1);
  182. CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
  183. CFRelease(source);
  184. return socket;
  185. }
  186. //Luma: Make sure that the iOS Radio is on before connection via TCP... NOTE: sometimes the Radio wont be ready for immediate use after this is processed... need to see why
  187. void OpeniOSNetworkingAndConnectToTCPObject(TCPObject *psTCPObject, const char *pcAddress)
  188. {
  189. char remoteAddr[256];
  190. //store TCPObject and Port in globals
  191. gpTCPObject = psTCPObject;
  192. if(psTCPObject)
  193. {
  194. dStrcpy(gszTCPAddress, pcAddress);
  195. }
  196. //break up url / port to pass in
  197. dStrcpy(remoteAddr, pcAddress);
  198. U16 port = 80;
  199. char *portString = dStrchr(remoteAddr, ':');
  200. if(portString)
  201. {
  202. *portString++ = 0;
  203. port = dAtoi(portString);
  204. }
  205. //call socket create function
  206. CreateCFSocketToURLAndPort(remoteAddr, port);
  207. }
  208. //Luma: ability to quickly tell if this is an iPhone or an iTouch
  209. bool IsDeviceiPhone(void)
  210. {
  211. NSString* tmp;
  212. tmp = [[UIDevice currentDevice] model];
  213. if([[[UIDevice currentDevice] model] isEqualToString: @"iPhone"])
  214. {
  215. return true;
  216. }
  217. return false;
  218. }
  219. ConsoleFunction(IsDeviceiPhone, bool, 1, 1, "Returns TRUE if the device is an iPhone, and FALSE if it is an iPod Touch.\n\n")
  220. {
  221. return IsDeviceiPhone();
  222. }
  223. ConsoleFunction(OpeniOSRadio, void, 2, 2, "Forces open the iOS radio if given a Torque formatted IP:port combo (255.255.255.255:65535)\n\n")
  224. {
  225. if(IsDeviceiPhone())
  226. {
  227. //don't do anything if we are already doing it with a valid TCPObject (we don't want to overwrite it, and if it is already occurring, then we don't need to do it anyways!)
  228. if(!gpTCPObject)
  229. {
  230. OpeniOSNetworkingAndConnectToTCPObject(NULL, argv[1]);
  231. }
  232. }
  233. }