UDP6Client

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>

//Based on www.abc.se/~m6695/udp.html


void error(char *msg)
{
    perror(msg);
    exit(0);
}

int main(int argc, char *argv[])
{
    int sockfd, portno;
    struct hostent *server;
    char bufferStore[256];
    char bufferSend[256] = "This is a string from client!";
    struct sockaddr_in6 serv_addr;
    int slen = sizeof(struct sockaddr_in6);
    int n;
    

    
    if (argc < 3)
    {
        //fprintf(stderr, "Usage: %s  \n", argv[0]);
        //exit(0);
    }
    portno = 2100;//atoi(argv[2]);
    
    printf("\nIPv6 UDP Client Started...\n");
    
    sockfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
    if (sockfd < 0)
        error("ERROR opening socket");
    
    //server = gethostbyname2(argv[1],AF_INET6);
    server = gethostbyname2("localhost",AF_INET6);


    if (server == NULL)
    {
        fprintf(stderr, "ERROR, no such host\n");
        exit(0);
    }
    
    memset((char *) &serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin6_family = AF_INET6;
    serv_addr.sin6_port = htons(portno);
    serv_addr.sin6_flowinfo = 0;
    memmove((char *) &serv_addr.sin6_addr.s6_addr, (char *) server->h_addr, server->h_length);
    
    n = sendto(sockfd, bufferSend, strlen(bufferSend)+1, 0, (struct sockaddr *) &serv_addr, slen);
    if (n < 0)
    {
        error("ERROR writing to socket");
    }
    printf("\nString sent to server...\n");
    
    
    int shouldReceiveData = 1;
    if (shouldReceiveData==1)
    {
        printf("reading from server\n");
        //struct sockaddr_in6 si_other;  //so we can get server data?
        n = recvfrom(sockfd, bufferStore, 255, 0,  (struct sockaddr *) &serv_addr, &slen);
        if (n < 0)
        {
            error("ERROR reading from socket");
        }
        //inet_ntop(AF_INET6, &(serv_addr.sin6_addr),client_addr_ipv6, 100);
        printf("Message from Server: %s\n", bufferStore);
    }
    
    printf("closing socket\n");
    close(sockfd);
    
    printf("exiting\n");
    
    return 0;
}

UDP6Server

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>

#include <arpa/inet.h>

 

//Based on www.abc.se/~m6695/udp.html

void error(char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
    int sockfd, portno;
    socklen_t clilen;
    char bufferStore[256];
    char bufferSend[256] = "A string from server!";
    struct sockaddr_in6 si_servr, si_other;
    int slen=sizeof(struct sockaddr_in6);
    int n;
    char client_addr_ipv6[100];
    
    
    /*
    if (argc < 2)
    {
        fprintf(stderr, "Usage: %s \n", argv[0]);
        exit(0);
    }
    */
    
    printf("\nIPv6 UDP Server Started...\n");
    
    sockfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
    if (sockfd < 0)
    {
        error("ERROR opening socket");
    }
    
    bzero((char *) &si_servr, sizeof(si_servr));
    portno = 2100;//atoi(argv[1]);
    
    si_servr.sin6_family = AF_INET6;
    si_servr.sin6_addr = in6addr_any;
    si_servr.sin6_port = htons(portno);
    si_servr.sin6_flowinfo = 0;
    
    
    if (bind(sockfd, (struct sockaddr *) &si_servr, sizeof(si_servr)) < 0)
    {
        error("ERROR on binding");
    }
    
    
    n = recvfrom(sockfd, bufferStore, 255, 0, (struct sockaddr *) &si_other, &slen);
    if (n < 0)
    {
        error("ERROR reading from socket");
    }
    
    inet_ntop(AF_INET6, &(si_other.sin6_addr),client_addr_ipv6, 100);
    printf("Incoming connection from client having address: %s\n",client_addr_ipv6);
    
    printf("Message from client: %s\n", bufferStore);
    
    int sendToClient = 1;
    
    if (sendToClient == 1)
    {
        n = sendto(sockfd, bufferSend, strlen(bufferSend)+1, 0, (struct sockaddr *) &si_other, slen);
        if (n < 0)
        {
            error("ERROR writing to socket");
        }
        printf("\nString sent to client...\n");
    }
    printf("closing socket\n");
    close(sockfd);
    
    printf("exiting\n");
    return 0;
}

Windows 10 – OSX – it’s like the stars have aligned

Windows 10 for OSX (O.S. Ten)

To the chagrin of radical Operating System fanatics, even as an Apple developer, I still keep a foot in the Windows world. It’s where a lot of my mouse jockeying skills are their sharpest. There hasn’t been a copy of Windows running at my desk, other than XP for some time. With the official demise of Windows XP being announced by Microsoft for some time. It was inevitable that a new flavor of Microsoft would work it’s way into the mix.

Today was all about installing Windows 10 on an A Mac Book Pro, using virtualization. It was not the simple point and click process it should have been, but I will chalk that one up to still using Parallels 10 instead of 11.

In case there is another person out there that might be thinking about the same process, and for my own documentation, this was the process I used.

PROCEED AT YOU OWN RISK – IT IS NOT UNCOMMON FOR SOMEONE TO TRY AND FOLLOW IN MY FOOTSTEPS AND END UP FORMATTING THEIR WHOLE MAC BOOK PRO (I’ll say it is unlikely, given it’s in a virtualized enviro)

First, the ingredients:

1 MacBook Pro (Retina, 15-inch, Early 2013) OSX El Capitan.

1 Windows 10 Microsoft usb installation stick (not an ISO, the legitimate one that comes from M.S.)

1 Parallels 10 virtualization software (already installed on the MAC)

This is the link that you would hope explains how to do it. It’s close, but a few things seemed to be slightly off.

http://kb.parallels.com/en/123364

Before you do step 1 (see link above) install your usb install stick in the left side port of your Mac Book Pro, It might not matter, but it seems it may have mattered in my particular case. Make sure the Mac sees the usb stick by checking if it appears in finder

So, In my particular case when you get to step 2 (see tutorial link above) you will need to bypass the locate manually step and just select Continue without a source.

When you get to the customize settings portion of that linked tutorial, I had to Select and move External Device in the boot order setting as the first item, and then the normal boot disk (Hard Disk 1, in my case) second, and turn off all the other check boxes. After you have checked the External disk (the usb install stick) you need to also select it from the pull down. The pull down was beneath the Boot order container and labeled External boot device:. From that pull down, I had two options, Windows 10 and then another option (which is also on the install disk) choose that, in my case it was called KDI-MSFT windows 10 (disk2).

Close the customize settings and proceed with the install as in the linked tutorial above, I selected the 64 bit version. If you are lucky in these sort of things, it will appear to install. However, once installed it will seem like it is installing again, don’t let it.

Here is where you break from the linked tutorial again. You need to stop the virtual machine, and click the gear icon in parallels to bring up the custom settings dialogue. This time, uncheck the external device option, make sure your normal boot drive is first, and launch the windows 10 virtual machine again. If you are lucky you will be in the home stretch of installing and running windows 10.

Assuming it all worked out for you, you will be prompted to enter your software key, and presented a sign up, and the normal windows 10 stuff. I did have to adjust windows 10 to the correct native display resolution. And the second time I booted I had to alter the memory settings to be at 16gb, but that’s about it. Parallels had some other tips on memory, but I didn’t have to use them. Kudos to the Parallels team for getting that help link in the right place though.

IF you did all this, and it didn’t work out for you. There are a few failed attempts, that may have helped me get to the final success. At one point I selected the Use EFI Boot check box, as an option on External boot device. I can honestly say, I don’t recall seeing the secondary option KDI-MSFT Windows 10 (disk) option until after I tried installing with the Use EFI Boot option, which seemed to get the installer stuck in an utter failure. At which point I had to delete the windows 10 VM and restart the process again, as described above.

Pan Your Mouse like CAD

Sometimes your have to re-discover things done by so many others in the past. Writing things in a portable language cuts down on some of that. This is a way to zoom around the mouse. It’s written in psuedo code using a mix of straight c, objective-c, and has OpenGL in mind.

-(void) mouseJunkForWeb:(float) someZoomAmountDelta
{
        float somethingYouKnow = 0;
        float somethingElseYouKnow = 0;
        VixScene *scene=[vixOGLView scene];
        //not using conten frame just the winframe
        GLfloat screenWidth=somethingYouKnow;
        GLfloat screenHeight=somethingYouKnow;
        
        GLfloat preZScale = getTheCurrentZoomScale();
        
        GLfloat panPosXYZ[3] ={somethingElseYouKnow,somethingElseYouKnow,somethingElseYouKnow};
    
        
        //Panning is usually not to complex mine ends up being something like this
        //Keep in mind I set up my viewport so the origin is center screen
        GLfloat OriginXDistToCenterScreen = panPosXYZ[0] = the3DXpos/getTheCurrentZoomScale();
        GLfloat OriginYDistToCenterScreen = panPosXYZ[1] = the3DYpos/getTheCurrentZoomScale();
        
        //do your normal zoom routine - such as glScale()
        zoomYour3D(someZoomAmountDelta);
        GLfloat postZScale = getTheCurrentZoomScale();
        
        //mouse dist to centerscreen
        GLfloat MouseXDistToCenter = mouseX - (screenWidth/2);
        GLfloat MouseYDistToCenter = mouseY - (screenHeight/2);
        
        GLfloat MouseXDistToOrigin = MouseXDistToCenter-OriginXDistToCenterScreen;
        GLfloat MouseYDistToOrigin = MouseYDistToCenter-OriginYDistToCenterScreen;
        //NSLog(@"mxdto:%1.1f mydto:%1.1f",mxdto, mydto);
        
        GLfloat scaleXoff = MouseXDistToOrigin;
        GLfloat scaleYoff = MouseYDistToOrigin;
        
        scaleXoff*=postZScale/preZScale;  
        scaleYoff*=postZScale/preZScale;
        
        //subtract original base unit value before scale
        scaleXoff-=MouseXDistToOrigin;
        scaleYoff-=MouseYDistToOrigin;
        
        GLfloat finalX = OriginXDistToCenterScreen-(scaleXoff);
        GLfloat finalY = OriginYDistToCenterScreen-(scaleYoff);
        
        if(scene.perspective!=0)
        {
            NSBeep();
            return;
        }
        
        panPosXYZ[0] = finalX;
        panPosXYZ[1] = finalY;
        
        panYour3D(panPos[0],panPos[1],panPos[2]]);
}

3D Studio Max vs. 3D Studio (DOS)

There is a long history behind the 3DStudio 3ds file format. Internally, we STILL use this format in the development pipeline. We take advantage of the reset xform option within max to simplify mesh data and key frame animation is supported externally from the .3ds file through a custom max script tool. Here it is:


-- Created: Nov 17 2015 		
-- Last Updated:
-- Oct 2 2014
-- Author :  Victor Gerth
-- Version:  3ds max 8
--
-- 
-- description: 
--
--		Dump out animation data (keyframes)
--    
--***********************************************************************************************
-- MODIFY THIS AT YOUR OWN RISK
--***********************************************************************************************


 
--***********************************************************************************************
--***********************************************************************************************
-- Initialize some global variables
--***********************************************************************************************
--***********************************************************************************************



statusprompt="2015 V Gerth Anim Out Utility"
displayTempPrompt statusprompt 0

surfaceverts=0
userObj = undefined
--userObj = selectByName title:"Pick A Surface" filter:geom_filt single:true




--***********************************************************************************************
--FUNCTIONS
--***********************************************************************************************
fn geom_filt o = superclassof o == Geometryclass 

fn distancefrom posa posb = sqrt(((posa.x-posb.x)*(posa.x-posb.x))+((posa.y-posb.y)*(posa.y-posb.y))+((posa.z-posb.z)*(posa.z-posb.z)))

fn dumpAdata obj =
(
	statusprompt="2015 V Gerth Anim Out Utility"
	local tm = 
	tm.translation = obj.transform

)

fn DumpXForms obj =
(
	-- output node transform properties
	format "%:\t%\n" "transform" obj.transform
	format "%:\t%\n" "position " obj.pos
	format "%:\t%\n" "rotation " obj.rotation
	-- output node's pivot point location
	format "%:\t%\n" "pivot " obj.pivot
	-- output object offsets
	format "%:\t%\n" "objectoffsetpos " obj.objectoffsetpos
	format "%:\t%\n" "objectoffsetrot " obj.objectoffsetrot
	format "%:\t%\n" "objectoffsetscale" obj.objectoffsetscale
	-- output object transform
	format "%:\t%\n" "objecttransform " obj.objecttransform
	-- output vertex position in local and world coordinates
	format "%:\t%\n" "vert 1 (local) " (in coordsys local getvert obj 1)
	format "%:\t%\n" "vert 1 (world1) " (in coordsys world getvert obj 1)
	-- calculate and output vertex position in world coordinates
	local v_pos=(in coordsys local getvert obj 1)* obj.objecttransform
	format "%:\t%\n" "vert 1 (world2) " v_pos
)





--***********************************************************************************************
--***********************************************************************************************
--***********************************************************************************************




rollout AnimOutUtility "Anim Out utility" 
(
	edittext lblWhatMesh "Active Selection" text:"Pick A Mesh" align:#Center width:100 readOnly:TRUE labelOnTop:TRUE
	button PickAMesh "Pick Object(s)"
	
	button DumpIt "Dump Anim Data" 	
	checkbox checkfileout "Write to file" checked:on align:#Center

	button quitplug "Quit" width:50 height:50 pos:[150-25,200]

	
	
	on PickAMesh pressed do
	(
		userObj =selectByName title:"Pick A Mesh" filter:geom_filt single:false
		if userObj == undefined do
		(
			--messageBox "Pick a Mesh Object First"
			--format "single object:\n"
			return 0
		)
		lblWhatMesh.text = userObj[1].name
		local childArray = undefined
		for obj in 1 to userObj.count do
		(
			childArray = userObj[obj].children
			if childArray.count > 0 then
			(
				for child in 1 to childArray.count do
				(
					format "childIDX:%\n" child 
					format "children:%\n" childArray[child].name
				)
			)
			else
			(
				format "childIDX:-1\n"
				format "children:-1\n" 
			)
		)
		
		--for t in 0 to 20 do
		--(
		--	sliderTime = t
		--	format "pivot:%\n" userObj[1].pivot
		--)
		sliderTime = 0
	)
	
	on DumpIt pressed do
	(
		if userObj[1] == undefined do
		(
			messageBox "Pick a Mesh(es) First"
			return 0
			--userObj =selectByName title:"Pick A Mesh" filter:geom_filt single:true
			--lblWhatMesh.text = userObj.name
		)
		local out_name
		local out_file
	
		if checkfileout.checked do
		(
			local meshesWithAnim = 0
			for obj in 1 to userObj.count do
			(
				local meshKeys = 0
				meshKeys += numKeys userObj[obj].position.controller
				meshKeys += numKeys userObj[obj].rotation.controller
				meshKeys += numKeys userObj[obj].scale.controller
				if (meshKeys > 0 ) do
				(
 					meshesWithAnim += 1
 				)
			)		
		
			out_name = ((GetDir #export)+"/"+userObj[1].name+".vxa")
			out_file = createfile out_name
			format "meshes:%\n" meshesWithAnim to:out_file
		)
		


		
		for obj in 1 to userObj.count do
		(
			-- assign the type of controller we want tcb
			userObj[obj].position.controller = tcb_position();
			userObj[obj].rotation.controller = tcb_rotation();
			userObj[obj].scale.controller = tcb_scale();
			
			local posKeys = numKeys userObj[obj].position.controller
			local rotKeys = numKeys userObj[obj].rotation.controller
			local scaKeys = numKeys userObj[obj].scale.controller

			sortKeys userObj[obj].position.controller
			sortKeys userObj[obj].rotation.controller
			sortKeys userObj[obj].scale.controller

		
			--statusprompt="Anim Data for="+ userObj.name as String
			
			if (posKeys + rotKeys + scaKeys >= 1) do
			(
				format "Animdata for:%\n" userObj[obj].name
				if checkfileout.checked do format "Animdata for:%\n" userObj[obj].name to:out_file
				format "*********** pos keys:%\n" posKeys
				if checkfileout.checked do format "*********** pos keys:%\n" posKeys to:out_file
				format "*********** rot keys:%\n" rotKeys
				if checkfileout.checked do format "*********** rot keys:%\n" rotKeys to:out_file
				format "*********** sca keys:%\n" scaKeys
				if checkfileout.checked do format "*********** sca keys:%\n" scaKeys to:out_file
			)

			--.pivot : Point3 -- node's pivot point position
			--.objectOffsetPos : Point3
			--.objectOffsetRot : Quat
			--.objectOffsetScale : Point3
			--Node geometry's position, rotation, and scale offset from the pivot in world coordinates.
			--format "objectOffsetPos:%\n" userObj[obj].objectOffsetPos
			--format "objectOffsetRot:%\n" userObj[obj].objectOffsetRot
			--format "objectOffsetScale:%\n" userObj[obj].objectOffsetScale
			
	

			for i in 1 to posKeys do
			(
				local posKeyTime = getKeyTime userObj[obj].position.controller i
				format "pos key:%\n" i
				
				if checkfileout.checked do format "pos key:%\n" i to:out_file  
	 			local posKey = getKey userObj[obj].position.controller i
				
				--rather than decypher tcb just use the rotation reported at the keyframe
				sliderTime = posKeyTime
				local posResult = 
				--in coordsys world userObj[obj].pos 
				local kpivot = in coordsys world userObj[obj].pivot

				format "Time:%\n %\n pivot:%\n" posKeyTime posResult kpivot 
				--userObj[obj].pos
				if checkfileout.checked do format "Time:%\n %\n pivot:%\n" posKeyTime posKey.value kpivot to:out_file

				format "ConInOut[%, %, %]\n" posKey.continuity posKey.easeTo posKey.easeFrom
				if checkfileout.checked do format "ConInOut[%, %, %]\n" posKey.continuity posKey.easeTo posKey.easeFrom to:out_file
				
				--format " Time:%\n Val:%\n" posKeyTime posKey.value
				--if checkfileout.checked do format " Time:%\n Val:%\n" posKeyTime posKey.value to:out_file
				
				--ADD THE EASE TO AND EASE FROM  AND CONTINUITY HERE
			)
			for i in 1 to rotKeys do
			(
				local rotKeyTime = getKeyTime userObj[obj].rotation.controller i
				local rotKey = getKey userObj[obj].rotation.controller i
				 format "rot key:%\n" i
				 if checkfileout.checked do format "rot key:%\n" i to:out_file 

				 --rather than decypher tcb just use the rotation reported at the keyframe
				 sliderTime = rotKeyTime 
				 local rotResult = in coordsys world userObj[obj].rotation
				 local kpivot = in coordsys world userObj[obj].pivot
				 format "Time:%\n %\n pivot:%\n" rotKeyTime rotResult kpivot
				 --format "W:%\n" rotResult.w
				 --userObj[obj].rotation
				 if checkfileout.checked do format "Time:%\n %\n pivot:%\n" rotKeyTime userObj[obj].rotation kpivot to:out_file

				format "ConInOut[%, %, %]\n" rotKey.continuity rotKey.easeTo rotKey.easeFrom
				if checkfileout.checked do format "ConInOut[%, %, %]\n" rotKey.continuity rotKey.easeTo rotKey.easeFrom to:out_file

	 			 --format " Time:%\n Val:%\n" rotKeyTime rotKey.value
	  			 --if checkfileout.checked do format " Time:%\n Val:%\n" rotKeyTime rotKey.value to:out_file


				--ADD THE EASE TO AND EASE FROM  AND CONTINUITY HERE

	
			)
			for i in 1 to scaKeys do
			(
				local scaKeyTime = getKeyTime userObj[obj].scale.controller i
				local scaKey = getKey userObj[obj].scale.controller i
				 format "sca key:%\n" i
				 if checkfileout.checked do format "sca key:%\n" i to:out_file
				sliderTime = scaKeyTime 
				local posResult = in coordsys world userObj[obj].pos 
				local kpivot = in coordsys world userObj[obj].pivot
 
	 			 format " Time:%\n Val:%\n pivot:%\n" scaKeyTime scaKey.value kpivot
	  			 if checkfileout.checked do format " Time:%\n Val:%\n pivot:%\n" scaKeyTime scaKey.value kpivot to:out_file
	 			 --format "sca key:% YVal:%\n" i scaKey.y_rotation
	 			 --format "sca key:% ZVal:%\n" i scaKey.z_rotation
				 
				 format "ConInOut[%, %, %]\n" scaKey.continuity scaKey.easeTo scaKey.easeFrom
				 if checkfileout.checked do format "ConInOut[%, %, %]\n" scaKey.continuity scaKey.easeTo scaKey.easeFrom to:out_file


				 
 				 --ADD THE EASE TO AND EASE FROM  AND CONTINUITY HERE
	
			)
			--DumpXForms userObj[1] 
		)--end loop through meshes
		
		if checkfileout.checked do
		(
			format " :finish\n" to:out_file
			close out_file
			edit out_name
		)
		
  	  	removeTempPrompt()
    )

	
	on quitplug pressed do
	(
		removeTempPrompt()
		DestroyDialog AnimOutUtility 
	)
	



) -- end rollout


-- create the rollout window and add the  rollout
if AnimOutUtility != undefined do
				 (

				 )		
 CreateDialog  AnimOutUtility width:300 height:300 pos:[100,100]
	



Keep the pivots orientated to the world on frame zero (very much reminiscent of 3D Studio DOS), some of the data is unused, in particular its much easier and faster to use the final transform from max rather than traverse the mesh hierarchy. CrLazy people keyframe Position Rotation and Scale on every frame where a keyframe exists.

CABasicAnimation CAAnimationGroup animationDidStop

Couldn’t find this on the interwebbernet, except for a web blog saying it isn’t do-able. They even had referances to the API! (which doesn’t actually say you can’t do it). You can see how it drove some people off the deep end trying all kinds of different ways, writing blocks, their own class, inventing a new language, etc…

JUST USE THE ONE IN THE API!

Here you go. It works.
(I changed a few names to make it easier to understand, so hopefully it still works)
Remember in the delegate you will want to parse through a groups individual animations, and tag those animations if you want to do something in the delegate.

- (void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    if (anim.class == [CAAnimationGroup class])
    {
        NSLog(@"Animat group stops");
        CAAnimationGroup * someGroup = (CAAnimationGroup *) anim;
        for (CAAnimation * foo in someGroup.animations)
        {
            NSString * theAnimGroupName = [foo valueForKey:@"GroupName"];
            if([theAnimGroupName isEqualToString:@"InAGroup"])
            {
                NSLog(@"Group stops");
            }
        }
    }
    else
    {
        NSLog(@" some animation stopped");
        NSString * theAnimName = [anim valueForKey:@“BasicName"];
        if([theAnimName isEqualToString:@"loading"])
        {
            NSLog(@" loading stopped");
        }
    }
}

-(void)spriteScaleUpAndFadeGroup
{
    CAAnimationGroup *someGroup = [CAAnimationGroup animation];
    someGroup.delegate = self;
    someGroup.duration = 1.5;
    someGroup.repeatCount = 1;
    
    CABasicAnimation *someAlpha;	
    someAlpha=[CABasicAnimation animationWithKeyPath:@"opacity"];
    someAlpha.fromValue=[NSNumber numberWithFloat:1.0];
    someAlpha.toValue=[NSNumber numberWithFloat:0.0];

    
    CABasicAnimation *someScale;	
    someScale=[CABasicAnimation animationWithKeyPath:@"transform.scale"];
    someScale.fromValue=[NSNumber numberWithFloat:1.0];
    someScale.toValue=[NSNumber numberWithFloat:4.0];
    someScale.removedOnCompletion = YES;
    [someScale setValue:@"InAGroup" forKey:@"AnimationGroupName"];
    
    someGroup.animations = [NSArray arrayWithObjects: someScale,someAlpha,nil];
    [someImageView.layer addAnimation:someGroup forKey:@"AnimationGroupName"];
}

-(void) spriteLoadingScreenMenu
{
    [someImageView setHidden:NO];
    CABasicAnimation *someRot;	
    someRot=[CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    someRot.duration=1;
    someRot.repeatCount=120;
    someRot.autoreverses=NO;
    someRot.fromValue=[NSNumber numberWithFloat:0.0];
    someRot.toValue=[NSNumber numberWithFloat:(3.14*2)];
    someRot.fillMode = kCAFillModeForwards;
    someRot.delegate = self;
    [someRot setValue:@"loading" forKey:@“BasicName"];
    
    //we want the spin in the middle
    someImageView.layer.anchorPoint = CGPointMake(.5,.5);
    [someImageView.layer addAnimation:someRot forKey:nil];
    
    //changing anchor point offsets the sprite location so we translate it
    CATransform3D tPos = CATransform3DMakeTranslation(someImageView.bounds.size.width/2, 	someImageView.bounds.size.height/2, 0);
    [someImageView.layer setTransform:tPos];
}

googling for this?

NSDictionary *opts = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:(NSApplicationPresentationAutoHideMenuBar|NSApplicationPresentationAutoHideDock)], NSFullScreenModeApplicationPresentationOptions,
nil];

[self enterFullScreenMode: [NSScreen mainScreen] withOptions:opts ];

Mid 2015 update

It’s been over a year since we posted anything on our site regarding what is in the future of Airborne Games.  You may have noticed we’ve phased out all except one of our products and haven’t released any of our products that have been in development. You might see this as a sign of the end of Airborne Games.

Well, not exactly.  First, let’s address our MX title.  We got it to playable state, complete with levels and a fully functional editor. But honestly, we didn’t find it a fun and entertaining gaming experience.  Not to mention, although I’m mentioning it right now, we were not happy with the sound fx.  Yes we had BMX bikes, scooters, skateboards, and plans for snowboarding.  For a minute, we kept looking at this one local guy on wheelchair, and started thinking we could probably work that in too. But ultimately, what good would all that be if it just wasn’t that fun? Many say we are foolish for not just cashing in on the scooter mania that is ravaging the skateparks of America as we speak. They are probably right, cash is king and nothing else matters right? However, why would we want to get stuck maintaining a product we don’t feel good about in the first place?  That’s not the direction we have to go right now, so we won’t.  Enough about that.

We are a  little excited about the potential of the AppleTV to behave like a console system. The merger of iOS, OSX, and AppleTV developer ecosystems is interesting as well.  We’ve noticed mobile device users with their mobile device no more than a foot from their face.  Our president has been using computers for over 30 years, and still doesn’t wear glasses (for now).  We think its kind of important to keep our game interfaces a little further out of our customers faces.  So while we named the company around the idea of games streamed to your mobile device thru the air, we are actually pushing towards big screens wi-fi or wired. So look for that next.

Business wise, Airborne Games is a privately owned company, founded on a $99 developer fee and a used computer, and that’s all it takes, and it’s pretty rad! (Except for all the federal, state, and city taxes and or licenses, usually county as well but Las Vegas and Nevada have their own rules) We are truly a small business in a multi-billion dollar industry. We can’t afford to (nor do we want to) move to another country just so our bottom line goes up.  We answer to the biggest and most powerful government in the world and its system designed for businesses with 1,000,000 times our our operating cost. But, we believe in the American Dream without compromise, and we will bet on it, all in, time and time again.