iOSUtil.mm 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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. S32 offset = 0;
  90. S32 deviceType = Con::getIntVariable("$pref::iOS::DeviceType");
  91. bool retinaEnabled = Con::getBoolVariable("$pref::iOS::RetinaEnabled");
  92. if (deviceType == 2)
  93. offset = 500;
  94. else if (deviceType == 1)
  95. offset = retinaEnabled ? 500 : 250;
  96. else
  97. offset = retinaEnabled ? 320 : 160;
  98. return offset;
  99. }
  100. //Luma: Ability to get the Local IP (Internal IP) for an iOS as opposed to it's External one
  101. void _iOSGetLocalIP(unsigned char *pcIPString)
  102. {
  103. int a,b,c,d ;
  104. struct ifaddrs* interface;
  105. char* addr;
  106. if (getifaddrs(&interface) == 0)
  107. {
  108. struct ifaddrs* allInterfaces = interface;
  109. while (interface != NULL)
  110. {
  111. const struct sockaddr_in* address = (const struct sockaddr_in*) interface->ifa_addr;
  112. addr = inet_ntoa(address->sin_addr);
  113. if ((address->sin_family == AF_INET) && (strcmp(addr, "127.0.0.1" )))
  114. {
  115. break;
  116. }
  117. interface = interface->ifa_next;
  118. }
  119. freeifaddrs(allInterfaces);
  120. }
  121. if(interface)
  122. {
  123. sscanf( addr, "%i.%i.%i.%i", &a, &b, &c, &d);
  124. }
  125. else
  126. {
  127. a = 0;
  128. b = 0;
  129. c = 0;
  130. d = 0;
  131. }
  132. pcIPString[0] = (unsigned char)a;
  133. pcIPString[1] = (unsigned char)b;
  134. pcIPString[2] = (unsigned char)c;
  135. pcIPString[3] = (unsigned char)d;
  136. }
  137. //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
  138. static void TCPObjectConnectCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *dataIn, void *info)
  139. {
  140. if(type == kCFSocketConnectCallBack)
  141. {
  142. if(dataIn)
  143. {
  144. SInt32 error = *((SInt32*)dataIn);
  145. Con::printf("Error connecting with CFSocker: Error code %d\n",error);
  146. }
  147. }
  148. //regardless, we want to connect to the TCPObject if we opened the socket or not so that it can continue its process properly
  149. if(gpTCPObject)
  150. {
  151. gpTCPObject->connect(gszTCPAddress);
  152. gpTCPObject = NULL;
  153. }
  154. }
  155. //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
  156. CFSocketRef CreateCFSocketToURLAndPort(const char *ipAddress, U16 port)
  157. {
  158. CFSocketContext context;
  159. context.version = 0;
  160. context.info = NULL;
  161. context.retain = NULL;
  162. context.release = NULL;
  163. context.copyDescription = NULL;
  164. CFSocketRef socket = CFSocketCreate(kCFAllocatorDefault,
  165. PF_INET,
  166. SOCK_STREAM,
  167. IPPROTO_TCP,
  168. kCFSocketConnectCallBack,
  169. TCPObjectConnectCallback,
  170. &context);
  171. struct sockaddr_in addr4;
  172. memset(&addr4, 0, sizeof(addr4));
  173. addr4.sin_family = AF_INET;
  174. addr4.sin_len = sizeof(addr4);
  175. addr4.sin_port = htons(port);
  176. inet_aton(ipAddress, &addr4.sin_addr);
  177. NSData *address = [NSData dataWithBytes:&addr4 length:sizeof(addr4)];
  178. CFSocketConnectToAddress(socket, (__bridge CFDataRef)address, -1);
  179. CFRunLoopSourceRef source;
  180. source = CFSocketCreateRunLoopSource(NULL, socket, 1);
  181. CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
  182. CFRelease(source);
  183. return socket;
  184. }
  185. //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
  186. void OpeniOSNetworkingAndConnectToTCPObject(TCPObject *psTCPObject, const char *pcAddress)
  187. {
  188. char remoteAddr[256];
  189. //store TCPObject and Port in globals
  190. gpTCPObject = psTCPObject;
  191. if(psTCPObject)
  192. {
  193. dStrcpy(gszTCPAddress, pcAddress);
  194. }
  195. //break up url / port to pass in
  196. dStrcpy(remoteAddr, pcAddress);
  197. U16 port = 80;
  198. char *portString = dStrchr(remoteAddr, ':');
  199. if(portString)
  200. {
  201. *portString++ = 0;
  202. port = dAtoi(portString);
  203. }
  204. //call socket create function
  205. CreateCFSocketToURLAndPort(remoteAddr, port);
  206. }
  207. //Luma: ability to quickly tell if this is an iPhone or an iTouch
  208. bool IsDeviceiPhone(void)
  209. {
  210. NSString* tmp;
  211. tmp = [[UIDevice currentDevice] model];
  212. if([[[UIDevice currentDevice] model] isEqualToString: @"iPhone"])
  213. {
  214. return true;
  215. }
  216. return false;
  217. }
  218. ConsoleFunction(IsDeviceiPhone, bool, 1, 1, "Returns TRUE if the device is an iPhone, and FALSE if it is an iPod Touch.\n\n")
  219. {
  220. return IsDeviceiPhone();
  221. }
  222. 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")
  223. {
  224. if(IsDeviceiPhone())
  225. {
  226. //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!)
  227. if(!gpTCPObject)
  228. {
  229. OpeniOSNetworkingAndConnectToTCPObject(NULL, argv[1]);
  230. }
  231. }
  232. }