void iphoneMainMenu() { if ( !btnResumeGame.texture ) { // initial setup #ifdef IPAD SetButtonPics( &btnResumeGame, "iphone/resume_game.tga", "Resume Game", 216, 338 ); SetButtonPics( &btnNewGame, "iphone/new_game.tga", "New Game", 446, 338 ); SetButtonPics( &btnWWW, "iphone/website.tga", "Website", 676, 338 ); SetButtonPics( &btnMultiplayer, "iphone/multiplay.tga", "Multiplayer", 347-17, 568 ); SetButtonPics( &btnControls, "iphone/controls.tga", "Options", 545+17, 568 ); SetButtonPics( &btnLabel1, "iphone/label1.tga", "", 0, 20 ); SetButtonPics( &btnLabel2, "iphone/label2.tga", "", 256, 20 ); SetButtonPics( &btnLabel3, "iphone/label3.tga", "", 512, 20 ); SetButtonPics( &btnLabel4, "iphone/label4.tga", "", 768, 20 ); btnLabel1.buttonFlags = BF_INACTIVE; btnLabel2.buttonFlags = BF_INACTIVE; btnLabel3.buttonFlags = BF_INACTIVE; btnLabel4.buttonFlags = BF_INACTIVE; #else SetButtonPics( &btnResumeGame, "iphone/resume_game.tga", "Resume Game", 16, 4 ); SetButtonPics( &btnNewGame, "iphone/new_game.tga", "New Game", 176, 4 ); SetButtonPics( &btnDemo, "iphone/demo.tga", "Demos", 336, 4 ); SetButtonPics( &btnMultiplayer, "iphone/multiplay.tga", "Multiplayer", 16, 168 ); SetButtonPics( &btnWWW, "iphone/website.tga", "Website", 176, 168 ); SetButtonPics( &btnControls, "iphone/controls.tga", "Options", 336, 168 ); #endif } #ifdef IPAD HandleButton(&btnLabel1); HandleButton(&btnLabel2); HandleButton(&btnLabel3); HandleButton(&btnLabel4); #endif if ( netgame ) { // disable buttons if we are already in a netgame btnNewGame.buttonFlags = BF_INACTIVE | BF_TRANSPARENT; btnMultiplayer.buttonFlags = BF_INACTIVE | BF_TRANSPARENT; btnWWW.buttonFlags = BF_INACTIVE | BF_TRANSPARENT; #ifndef IPAD btnDemo.buttonFlags = BF_INACTIVE | BF_TRANSPARENT; #endif } if ( HandleButton( &btnResumeGame ) ) { ResumeGame(); } if ( HandleButton( &btnNewGame ) ) { menuState = IPM_MAPS; } if ( HandleButton( &btnControls ) ) { menuState = IPM_CONTROLS; } if ( !NetworkAvailable() ) { // disable multiplayer if we don't have a good device //btnMultiplayer.buttonFlags = BF_INACTIVE | BF_TRANSPARENT; btnMultiplayer.buttonFlags = BF_TRANSPARENT; } else if ( netgame ) { // disable multiplayer if we are already in a netgame btnMultiplayer.buttonFlags = BF_INACTIVE | BF_TRANSPARENT; } else if ( NetworkServerAvailable() ) { // blink the multiplayer button if a local server is available btnMultiplayer.buttonFlags = BF_GLOW; } else { btnMultiplayer.buttonFlags = 0; } if ( HandleButton( &btnMultiplayer )) { if (NetworkAvailable()) { // get the address for the local service, which may // start up a bluetooth personal area network boolean serverResolved = ResolveNetworkServer( &netServer.address ); // open our socket now that the network interfaces have been configured // Explicitly open on interface 1, which is en0. If bluetooth ever starts // working better, we can handle multiple interfaces. if ( gameSocket <= 0 ) { gameSocket = UDPSocket( "en0", DOOM_PORT ); } // get the address for the local service if ( !serverResolved ) { // nobody else is acting as a server, so start one here RegisterGameService(); SetupEmptyNetGame(); } menuState = IPM_MULTIPLAYER; } else { SysShowAlert("Attention:", "Multiplayer requires a WiFi connection that doesn't block UDP port 14666"); } } // draw the available interfaces over the blinking net button if ( NetworkServerAvailable() ) { iphoneCenterText( btnMultiplayer.x + btnMultiplayer.drawWidth / 2, btnMultiplayer.y + btnMultiplayer.drawHeight/2, 0.75, NetworkServerTransport() ); } if ( HandleButton( &btnWWW ) ) { // menuState = IPM_PACKET_TEST; // !@# debug SysIPhoneOpenURL( "http://doomsday.generalarcade.com/" ); } #ifndef IPAD if ( HandleButton( &btnDemo ) ) { StartDemoGame( btnDemo.twoFingerPress ); } if ( btnDemo.twoFingerPress ) { strcpy( timeDemoResultString, "TIMEDEMO" ); } // draw the timedemo results on top of the button if ( timeDemoResultString[0] ) { iphoneCenterText( btnDemo.x + btnDemo.drawWidth / 2, btnDemo.y + btnDemo.drawHeight/2, 0.75, timeDemoResultString ); } #endif }
boolean ResolveNetworkServer( struct sockaddr *addr ) { if ( !NetworkServerAvailable() ) { return false; } gotServerAddress = false; DNSServiceRef resolveRef; // An unconnected bluetooth service will report an interfaceIndex of -1, so if // we have a wifi link with an interfaceIndex > 0, use that // explicitly. service_t *service = NULL; for ( int i = 0 ; i < MAX_SERVICE_INTEFACES ; i++ ) { if ( serviceInterfaces[i].interfaceIndex > 0 ) { service = &serviceInterfaces[i]; char interfaceName[IF_NAMESIZE]; if_indextoname( service->interfaceIndex, interfaceName ); printf( "explicitly resolving server on interface %i = %s\n", service->interfaceIndex, interfaceName ); break; } } if ( !service ) { #if 0 // don't support bluetooth now // settle for the unconnected bluetooth service for ( int i = 0 ; i < MAX_SERVICE_INTEFACES ; i++ ) { if ( serviceInterfaces[i].interfaceIndex != 0 ) { service = &serviceInterfaces[i]; break; } } #endif if ( !service ) { printf( "No serviceInterface current.\n" ); return false; } } // look up the name for this service DNSServiceErrorType err = DNSServiceResolve ( &resolveRef, kDNSServiceFlagsForceMulticast, // always on local link service->interfaceIndex > 0 ? service->interfaceIndex : 0, // don't use -1 for bluetooth service->browseName, service->browseRegtype, service->browseDomain, DNSServiceResolveReplyCallback, NULL /* context */ ); if ( err != kDNSServiceErr_NoError ) { printf( "DNSServiceResolve error\n" ); } else { // We can get two callbacks when both wifi and bluetooth are enabled callbackFlags = 0; do { err = DNSServiceProcessResult( resolveRef ); if ( err != kDNSServiceErr_NoError ) { printf( "DNSServiceProcessResult error\n" ); } } while ( callbackFlags & kDNSServiceFlagsMoreComing ); DNSServiceRefDeallocate( resolveRef ); } if ( gotServerAddress ) { *addr = resolvedServerAddress; return true; } return false; }