Showing posts with label command line. Show all posts
Showing posts with label command line. Show all posts

Friday, July 26, 2013

Upgrading a Project to a New Version of Cocos2D

A short video tutorial on this subject, since I just had to do this job myself and its not entirely obvious how to go about doing it, or how to solve some of the problems that can occur.


To check out the project used in this tutorial have a look at my earlier tutorials on Lua (linked in the panel on the right) and you'll find a reference to the GitHub repo where you can download the source.

Just to help Google searches finding this post:

  • CTFontManagerRegisterFontsForURL link error?
    • you need to add CoreText framework as this is a new dependency for Cocos
  • CCFontDefinition symbols not found link error?
    • you need to "add files" and re-add the cocos2D libs directory
    • there are some new .m files which are in the distro but not added to your project
Link errors when upgrading Cocos2D are probably due to these issues - new files and dependencies.

See my video above for how to fix 'em!

Tuesday, May 28, 2013

Avoiding Name Collision for your Sprites

In Cocos2D when sprite sheets are imported the sprites within them come in as - for example - "alarm-clock.png" where this was the original name of the image, before it was composited into the sheet.

I believe Unity and other programs that use TexturePacker work a similar way.

So where is the problem?

Well, what if you have two different alarm clocks?  Or two different images for the same clock?

Collision avoidance!
Even if you have different sprite sheets, all images go into the same name space and because you are not using any kind of directory structure - that was all lost when it was imported into Texture Packer - then you have an issue with name collision.

You have to start prefixing the alarm clock with "blue-alarm-clock.png" or "alarm-clock-1.png" but then it becomes a tussle to figure out what the original clock was, maybe still just named without any prefix.

It becomes very easy for one sprite in your game to wind up being substituted in for another without you realising it and unless you test every branch of the game, you might not notice until its too late and the game has shipped already!

Here's a quick way to disambiguate your images for your sprites, that uses the command line on the mac: embed the sha1sum signature of the image into the filename.  That way as long as the image is different it will have a different file name from any other image sprite file in your game guaranteed.

The key to it is the shasum command which is installed in Mac by default.  If your version of MacOS doesnt' have "shasum" you will probably find that an equivalent tool is installed that you can use - try md5sum or similar.  Same if you're on Windows using Cygwin or minGW-sys.

Here's the code we're going to use, laid out on different lines:

for f in sprites/*.png; do 
    g=$(shasum $f)
    h=${g:0:7};
    b=$(basename $f .png) 
    d=$(dirname $f)
    echo mv -v $f $d/$b-$h.png
done

What this is doing is getting the variable "f" to take on the string value of every file name in your sprites directory that ends with ".png", each time through the "for" loop.  Inside the loop, we store into variable "g" the sha1sum of the file which is a long string that looks like this:

~/Documents/Artwork/seperations-game-ready/main-room sez$ shasum sprites/alarm-clock.png 
1dcd66fcb214b1875ebd28cff83dedf83960707  sprites/alarm-clock.png

Since we only need a few characters from the long sha1 string, the next line is getting a substring of our g variable taking the first 7 characters only.  That also conveniently ignores the trailing filename which is repeated.

Finally we use the basename and dirname built-in bash functions to get the parts of the file name that we need, so we can stitch it back together in the move command.

Note that as per my usual practice I use "echo" so that instead of the move actually executing it just prints out what it would do.

Now we can run this command by opening a Terminal session, changing directory to the directory containing our sprites directory, then run it all on one line like this:

for f in sprites/*.png; do g=$(shasum $f); h=${g:0:7}; b=$(basename $f .png); d=$(dirname $f); echo mv -v $f $d/$b-$h.png; done

You should be able to copy the above line from your browser and paste it into your Terminal session as one single line, with no wrapping.  It's for that reason that I have used the (otherwise horrible) 1-letter variable names.

Where I have "sprites" as the directory name substitute in your own directory name if needed.

Carefully inspect the output of the echo'ed out move commands and if necessary, up-arrow and edit the command until it works the way you like.

Then finally up-arrow, arrow back and remove the "echo" and press enter to execute it for real.

If the command works, then you should see the "mv -v" spit out a line for each file looking like this:

sprites/alarm-clock.png -> sprites/alarm-clock-1dcd66f.png

If you had 10 sprites you should see 10 lines like that you should now be able to check your sprites directory and find a nice list of completely distinctively named files, guaranteed not to collide.

Happy spriting!

Friday, May 3, 2013

Trimming Transparency Follow-up: Cropping

Just a really quick follow-up to my recent post about trimming your static images.  I got some great thoughtful comments on my G+ account regarding this and it got me thinking - I needed to clarify how you could use this same technique not just for static images but also for animation sprite sheets.

I posted an update section on that recent post, but I'll repeat it here:
Update: I realised that this post could confuse people into thinking that your sprite sheets of animations could be processed this way. This won't work. I know I said these images are coming out of my animation program but that is because they are stills that I use for the various static poses, and since I use AnimeStudio for all my character art I have to get the sprites looking consistent, so that means whether animated or still I need to use the same program.
Why not? When you trim off the transparency close to the colored pixel content that means the position of the character in the frame will change from frame to frame giving a jittery effect. Definitely not what you want for your animations. But for static poses this technique works just fine.
OK - so how could you use ImageMagick to trim your animated sprite frames?  There's two comments to make before we dive into the script I came up with to help with this:

  • First - do you really need to trim them?  TexturePacker makes a good job of ridding yourself of these extra transparent pixels, and if you already have a way of hit-testing that won't be compromised by the extra alpha may not be a problem.  Thanks to +Krzysztof Bielawski for highlighting this.
  • Second - lets use the word crop to refer to the process of cutting off unwanted parts of the image to precise pixel dimensions
    • Trimming refers to getting rid of all alpha transparency regardless of where that happens to be pixel-addressing-wise.
If your game doesn't require hit testing your animated sprites in that way - maybe you just use a simple radius test - then there's no point in worrying about this trimming probably.

If we do decide to go ahead with this lets get terminology right - ImageMagick uses these terms and from my graphics work I follow the same approach.  Trim means cutting away unwanted stuff (no matter what the dimensions) and cropping is like guillotine - once you position the bounds to the pixel that is where the cut falls.

OK - so we're going to crop?  Here is how to do it:

convert my_sprite_0001.png -crop \
    '309x518+65+238' +repage my_sprite_cropped_0001.png

By referring to my recent post, you can find out how to install ImageMagick, and what the "convert" command-line here is doing.  As before the repage is recalculating the page meta-data after the crop command.

What's new is the -crop and the strange expression in quotes.  '309x518+65+238'

The first two numbers (seperated by the "x" character) are the width and height of the area to be cropped out.  This area needs to be as large as the union of the bounding rectangles of all the sprites in your animation sequence.

The second two numbers represent the offset into your source image (my_sprite_0001.png in the above) as an x, y coordinate pair - with the top-left of the image as the origin.

Note that Cocos2D and many other OpenGL based game kits use the bottom-left as the origin - and mathematical co-ordinate systems do this too.  Take a bit of care to make sure this is right.

Wait: what?  Union of the bounding rectangles?  Yup - this just means that whatever rectangle you choose as your crop is going to be the same size and position for every crop operation done on your folder of images.  This means that in order to avoid cutting off any part of one of the animation frames it will need to be equal to all of the rectangles that would have been used in a trim operation, all overlaid over each other - this "rectangle summing" is called the "union".

In practice I found the easiest way to do this is to find a large image, say the "contact pose" - see my early "rushy animation tut" post - and put a box around that with my image editor (I use GiMP, but you might use photoshop) and check the dimensions and offset.

Then I run my crop script using those dimensions, and check the result using Preview - if an image in the sequence got some part cropped off I can open that in my image editor and adjust those dimensions.

Checking the crop by using the Preview program on Mac
Here's an example of the script running, copied straight out of my Terminal session. Just after the script does its processing I run Mac's Preview program on all the images by using the "open" command:

~/Documents/Art/animations sez$ ./cropdir.sh walk-cycle-side-12fps-fresh 309 518 65 238
About to make cropped copies of the files in walk-cycle-side-12fps-fresh and place into walk-cycle-side-12fps-fresh-converted-1367637222
The resulting cropped copies will be 309w x 518h and at offset 65, 238 in
the image.

Continue (y/n) ?  [N]: >Y
   walk-cycle-side-12fps-fresh/walk-side_00001.png    -- cropped to -->   walk-cycle-side-12fps-fresh-converted-1367637222/walk-side_00001.png
   walk-cycle-side-12fps-fresh/walk-side_00003.png    -- cropped to -->   walk-cycle-side-12fps-fresh-converted-1367637222/walk-side_00003.png
   //.... more
   walk-cycle-side-12fps-fresh/walk-side_00047.png    -- cropped to -->   walk-cycle-side-12fps-fresh-converted-1367637222/walk-side_00047.png
   walk-cycle-side-12fps-fresh/walk-side_00049.png    -- cropped to -->   walk-cycle-side-12fps-fresh-converted-1367637222/walk-side_00049.png
~/Documents/Art/animations sez$ 
~/Documents/Art/animations sez$ open walk-cycle-side-12fps-fresh-converted-1367637222/*

And this is a complete listing of the script I use. As before - caveat emptor, backup before use, all care, no responsibility.

#!/bin/bash

# Copyright Sarah Smith - http://indiegamecodingconfessions.blogspot.com

# ImageMagick is from http://www.imagemagick.org

# This script is placed in the public domain - feel free to use it how you
# want, though a link to this blog would be nice.  :-)

if [ $# != 5 ]; then
    echo "Usage: $0 <dirname> <width> <height> <x-offset> <y-offset>"
    exit 1
fi

# Halt execution the second a command fails
set -e

# Uncomment this line to get debugging info
# set -x

UNIQ_NM=$(date "+%s")
DESTDIR="$1-converted-$UNIQ_NM"

echo "About to make cropped copies of the files in $1 and place into $DESTDIR"
echo "The resulting cropped copies will be $2w x $3h and at offset $4, $5 in"
echo "the image."
echo ""
echo -n "Continue (y/n) ?  [N]: >"

read goahead

if [ "x$goahead"="xy" -o "x$goahead"="xY" ]; then

    mkdir $DESTDIR
    GEOMETRY="$2x$3+$4+$5"

    for fn in $1/*; do
        DESTNAME=$DESTDIR/$(basename $fn)
        convert $fn -crop $GEOMETRY +repage $DESTNAME
        echo "   $fn    -- cropped to -->   $DESTNAME"
    done

fi

And you can download this script from my Dropbox.  As in my previous post, just chmod it to executable and run it from the command line as above.

Happy image hacking!

Thursday, May 2, 2013

Trimming Transparency from Images

When you export images from some programs, you wind up in some cases with the actual content as a small area of coloured pixels in a sea of alpha transparent nothing.

This happens to me when I'm animating my character around and I'm doing so against a background that is say 1024x768 where the actual character's image is a tiny percentage of that size.

A 1024x768 png from my animation program
This is completely to be expected - the designers of your other programs always have to assume that your export is intended to be the size of your original canvas; but when you have dozens or maybe even hundreds of frames of animation all with wasted transparent pixels, removing it all by hand using GiMP or Photoshop is agonizing.

When you're using TexturePacker or ZwopTex your transparent pixels are probably removed nicely for you when the sprites are stored, but still they can mess up your hit testing and on-screen positioning for your game.

The image content I want with extra transparent pixels cropped away
Here is a way to crop those transparent pixels automatically in large batches, and the program to do it is free.

OK, this is what you need - the ImageMagick program from ImageMagick.org - a fantastic and very powerful set of command line tools.

I'm on MacOSX Mountain Lion and found this great installer which the guys at Cactus Labs have put together - it was just case of clicking through and it all just worked!

Once you have ImageMagick installed check that it is working by opening up a command line - on MacOSX, just do <command>-<space> to access Spotlight and type "Term" and you should be able to hit enter on the first match to get the Terminal.app program running.  Then at the command prompt type:   convert -version


~/MyArtWork sez$ convert -version
Version: ImageMagick 6.8.4-8 2013-04-08 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2013 ImageMagick Studio LLC
Features: DPC OpenMP
Delegates: bzlib jng jp2 jpeg lcms png tiff xml zlib

That shows that the ImageMagick command line tool called "convert" is up and running. The script I'm about to show you won't work if this command is not available.  If you had a Terminal running when you installed ImageMagick you may need to close and re-open it to get this to work.

Now the basic technique is to use two commands that convert knows about:
From the command line the trim command looks like this:

convert my_image.png -trim +repage my_image_trimmed.png

The trim command is what does all the work - it samples the image at the corners and assumes those pixels are what the background of your image is.  Then it crops in the image as small as it can on all four sides - providing that the only pixels it is throwing away are that background color it sampled.  It works with all colours of background, not just alpha transparent (which ImageMagick calls the colour name "none").

Now there's a trick here - what if one some of your frames the sprite just happens to be touching in the corner where the sample is made?  Oops - that will mess up ImageMagick's trim!  To counter this problem, first we add a border of transparent pixels around the image so that when it comes time to run the trim, we can be sure no valuable pixels will get sampled by mistake.  That is where the border command to convert comes in.

The whole script looks like this:
!/bin/bash

# Copyright Sarah Smith
# http://indiegamecodingconfessions.blogspot.com
# ImageMagick is from http://www.imagemagick.org
# Back up your work before running this script!
# This script is placed in the public domain
# Feel free to use it how you want, though a 
# link to this blog would be nice.  :-)

if [ $# != 1 ]; then
    echo "Usage: $0 <dirname>"
    exit 1
fi

# Halt execution the second a command fails
set -e

# Uncomment this line to get debugging info
# set -x

UNIQ_NM=$(date "+%s")
DESTDIR="$1-converted-$UNIQ_NM"
mkdir $DESTDIR

for fn in $1/*; do
    TMPDESTNAME=$DESTDIR/tmp-$(basename $fn)
    DESTNAME=$DESTDIR/$(basename $fn)
    convert $fn -bordercolor none -border 3x3 $TMPDESTNAME
    convert $TMPDESTNAME -trim +repage $DESTNAME
    rm -f $TMPDESTNAME
    echo "   $fn    -- trimmed to -->   $DESTNAME"
done

How to use the script.
  • First save all your work somewhere, make sure its backed up!
  • In a terminal, cd into the directory where your artwork is
    • you backed up this directory didn't you?
  • Download the script trimdir.sh as a file to your computer.  Try this drop box link.
    • save it into that same directory where your art is
  • Make the script executable, and run it like this:
~/Documents/my_art$ trimdir.sh my_directory_of_sprites

...where "my_directory_of_sprites" is the name of a directory containing sprites you want to trim.  The script will create an output directory and put the trimmed versions of all the files in there.

Word of warning - this script is just my own hacking so use at your own risk - and back up before you start!  See my earlier post about backups!  The script tries to avoid doing anything destructive, and never replaces the files you specify, only placing the cropped versions into a new directory.  But like all scripts with great power comes great responsibility!

Also click the topic label "command line" below for more posts about the command line, or search for tutorials on it on the web if you're not comfortable with the command line or Terminal usage.

Here's an example of me running the script on a directory called "static-poses":

~/Documents/AG-Art/erin-animations sez$ ./trimdir.sh static-poses

   static-poses/back-quarter.png    -- trimmed to -->   static-poses-converted-1367477342/back-quarter.png

   static-poses/back.png    -- trimmed to -->   static-poses-converted-1367477342/back.png

   static-poses/front-quarter.png    -- trimmed to -->   static-poses-converted-1367477342/front-quarter.png

   static-poses/front.png    -- trimmed to -->   static-poses-converted-1367477342/front.png

   static-poses/side.png    -- trimmed to -->   static-poses-converted-1367477342/side.png

Of course ImageMagick is capable of so much more than this. Please let me know if you use this technique, or my script and how it worked out for you. Have fun hacking your sprites!

Update:  I realised that this post could confuse people into thinking that your sprite sheets of animations could be processed  this way.  This won't work.  I know I said these images are coming out of my animation program but that is because they are stills that I use for the various static poses, and since I use AnimeStudio for all my character art I have to get the sprites looking consistent, so that means whether animated or still I need to use the same program.

Why not?  When you trim off the transparency close to the colored pixel content that means the position of the character in the frame will change from frame to frame giving a jittery effect.  Definitely not what you want for your animations.  But for static poses this technique works just fine.

Friday, April 26, 2013

Nice iOS Snippet for sayin' "Hi Mom!"

Just a quick one from the forge: when debugging my iOS code for my game I like to use the "Hi Mom!" method.

Image of elderly lady in a hat - original source seems to be Huff Post (after some Google Image searching)
Hi Mom!  (Photo credit: Huffington Post)
What's that you say?  "Hi Mom"....?

This is when you have lots of places where your code prints out something - Hi Mom is fine, tho' you often want something more informative - but the key is it prints out on the console, and you can trace its execution by checking these points, and the data output at those times.  It's the best debugging technique I know.

It's the traditional "printf" style of debugging as some call it.  An elite coder friend who coined the term did it I think because "Hi Mom" is really quick and memorable - it highlights the fact that when you're doing this kind of debugging you want a quick edit-compile-run loop so lots of typing is a pain.  And "Hi Mom" is short.  It's just flagging that you reached that point.

It seems pretty obvious perhaps, but in these days of high-powered IDE's (like XCode) and symbolic debuggers that lead you by the nose through your code as it runs, it might seem that Hi Mom is a bit past it and long in the tooth.  Far from the truth!

It might also seem like hard work - writing more code to debug the code I've already got?  Wrong again!

Symbolic debuggers are a pain sometimes - they don't always work especially if your bug has messed up the stack.  Getting a breakpoint just where and when you need it is not always straight forward.  Getting information about the variables you want to see in the right format doesn't always come easy either.  When code is multi-threaded or backgrounding, or you have to interact with the UI using the debugger is not always convenient.

So Hi Mom has some mileage here, even in these days of magic IDE's.

What about all that work typing tho' - especially when Objective-C does not give you a nice __FILE__ or __LINE__ macro to use like C++ does?

Here's a nice snippet I came up with that I'm using a lot - its a macro which uses a bit of token pasting:

#define MARK(object) NSLog(@"%@::%@ MARK - %s: %@", \
        NSStringFromClass([self class]), \
        NSStringFromSelector(_cmd), #object, object)

It gives me output that looks like this:
2013-04-26 22:21:31.994 Ethex2080[24072:c07]\
 UIStateManager::graphSearchFromNode:toNode: MARK - nodeStart: Location #501

Breaking this down:

  • The time stamp and binary name come from NSLog
  • the class name and method name come from the two "NSStringFrom..." functions
  • MARK (my version of "Hi Mom!") tells me its from a "MARK" macro call 
    • so I can see from the console what it is, if I have forgotten to remove one
  • The string nodeStart: is the name of the variable 
    • (from a c-pre-processor token paste, the #object) and 
  • then the results of calling the -(NSString *)description function on that variable.

In fact I put it in my global project declarations file which is one of the headers which gets included in my precompiled header.  That way its always available in any code I write in the project, without having to go hunting for the include or import:

//
// Prefix.pch

#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>

#import "cocos2d.h"

#import "Ethex2080Utils.h"
#endif

Now in my code that I'm debugging I can quickly drop in a statement like this:

- (void)doSomethingWeird:(NSArray *)someStuff
{
    MARK(someStuff);

    // rest of stuff
}

This gives me a nice debug line with
  • the name of the class
  • the name of the function that is running
  • the name of a key variable I'm dumping
  • the description (dump) of that variable
Benefits are:
  • ultra quick to type - no need to type the name of the variable even
  • easy to find and remove before I do my git commit
  • being a macro it can capture the name of the function (a debug function could not)
Feel free to use this if it helps (I hereby place this snippet in the public domain) and good luck as you "Hi Mom" your way to bug-free code!

Sunday, March 24, 2013

Exporting layers from Gimp as PNG files

Gimp for MacOSX is now a "native" (-ish) application, and is a great graphics tool for game developers - especially those who can't afford Photoshop.  I've always used it and wouldn't go for PhotoShop as I know GiMP so well now.

You can create animations in layers and Gimp allows you to preview your animations when you've done them as a bunch of layers, by simply invoking the handy "Animation" option in the menu:  "Filters" > "Animation" > "Playback..." - very nice.

But now how do you export those layers as a collection of separate PNG's so you can import them via TexturePacker into your game?

It turns out there is a handy Gimp plug-in to help you - but installing it is not for the faint-hearted.

Installing Plug-ins for GiMP on Mac OSX

On Windows or Linux the process is comparatively easy and is described in a nice tutorial.  If that article happens to be unavailable the GiMP registry lists a number of others.  On MacOSX where normally things "just work" for some reason its a lot more obscure.

The first insight is to know how to find your plugin folders.  Use the Preferences menu in GiMP to find the Folders item and choose "Plugins":


I didn't use the one for just my user name because I wanted the changes in GiMP to be available to anyone using the GiMP install on this computer.  Also it saves me a step as I don't have to create that folder.  I used the GiMP internal folders.  It also has the advantage that if I copy that GiMP to another machine, its plugins go with it.  Nice.

The second thing to know is that there is a laundry list of different types of things that you can install into GiMP, and this makes things more complex for the GiMP automation newbie.  You have "scripts" which are small helpers that can automate what GiMP already knows how to do.  Then you have "plugins" which are larger actual programs which extend GiMP's functionality.  And then there is modules, brushes and the list goes on.

Confusingly enough scripts are written in scheme, but if you want to write a script in python, that is considered a plugin.  Why?  Because the GiMP authors decided it would be so.  In any case if you want to install the export_layers Python script, you have to install it in the plugins folder.

Also since it is a plugin, it has to "look" like the other plugins which maybe complied C program binaries and so on - in other words it has to be executable.  If it isn't then it won't show up when you restart GiMP.  And also - note - restarting GiMP is required, since this is a "plugin": you cannot get it to show up by selecting the "Refresh" option from the script-fu menu in GiMP.

So first step - shut down GiMP.

On MacOSX using the Terminal its then an easy 3 step process:

cd ~/Desktop
curl -O http://gimp-registry.fargonauten.de/files/export_layers-0.6.py.txt
chmod a+x export_layers-0.6.py.txt
mv export_layers-0.6.py.txt /Applications/Gimp.app/Contents/Resources/lib/gimp/2.0/plug-ins/export_layers

If you have problems using the Terminal I really strongly suggest that you start getting over them.  Seriously.  You're missing out on a lot of what Mac has to offer - all the power of Unix just a few keystrokes away.  It's much faster and much easier to capture the process to repeat or modify it.  In some cases the Terminal is the only way to do things.

I use a mixture of UI dragging-and-dropping and always have the Terminal handy to do things that the Terminal is great for.  If your Terminal is not already running, type <cmd>-<space> in Finder and then type "Term" to get hold of it with Spotlight, then press Enter.  With your fingers on the keyboard you're ready for the Terminal to do your bidding.

Let me demystify the above a bit for those of you not keen on the Terminal:

  • First I change directory to the Mac desktop - we're going to temporarily store the downloaded plug-in there. 
  • Next we use the curl command that downloads stuff
    • I use the -O (that's a capital Oh) to say that the output file should be named 
      • curl will call it after what ever it was on the server I got it from.  
    • Try typing "man curl" to find out more about curl - its a handy tool
  • Then the script has to be made executable with the chmod command
    • if you've managed to get the Python script in the right folder but it still does not appear in GiMP - you probably missed this step.
  • Finally copy the script into place.

To do most of all this graphically is possible, but its a pain.  You'll need to
  • Go to the export_layers plugin web page and right-click on the link to download it to your Desktop.
  • Now you'll need to make the file executable
    • I know of no way to do that apart from the command line - so you'll need to open the Terminal for that.  
    • See the above "chmod" command, and first cd to wherever you downloaded the file to.
  • Click on the downloaded file and rename it to export_layers
  • Now go back to Finder and open two windows.
  • In one, navigate to your Gimp program in the Applications folder, right-click and
    • choose "Show Package Contents"
    • the Finder window will change to a view of the inside of the GiMP application bundle.
  • Navigate down to through these folders
    • Contents > Resources > lib > gimp > 2.0 > plug-ins
  • In the other window navigate to your desktop
  • Drag-n-drop the executable export_layers into place in the plug-ins folder in the other Finder window
Now when you restart GiMP you will find that you have a new menu option under the "File" menu with "Export Layers" > "as PNG" which will do what you need. Note you may find some oddness/bugginess with where it drops the generated files. If that happens, use Spotlight to find them - in my case they were dropped into my home folder.

Bonus Content

There are a bunch of Mac file name changer apps out there. If you're a Terminal master you don't need 'em.

After running the file export my original sprite sheet called "process-working.xcf" had resulted in a bunch of weirdly named files as a result of the Export Layers command. The names were like "process-working_xcf-working-1.png" - where the first part was the file name and the second parts were all the layer names.

for f in *; do g=${f#process-working_xcf-}; do mv -v $f $g; done

This command will strip off the leading characters "process-working_xcf-" part and just leave the layer names. The -v just gives verbose output so you can see what it's doing. You'll need to cd into the directory where the files are located before running it.

This is using the Terminal (well, the Bash shell's) ability to do substring mangling. To find out more at the Terminal, type "man bash" and then a forward slash "/" and then "substr". Press enter a few times until it gets to the stuff with the curly braces. As explained there you can use the % instead of # do strip stuff off the end of the string instead of the beginning. For more complex things you can go from just using to f and g, to h and j as well - and so on - successively picking apart the string as you go.

When experimenting with this stuff it pays to preview your command before you run it. You can do that by prefixing it with "echo" like this:

for f in *; do g=${f#process-working_xcf-}; do echo mv -v $f $g; done

Then you'll get a nice listing of all the "mv" commands that would be run, and you can inspect them to make sure your substring mangling did what you expected. Have fun!

Tuesday, February 12, 2013

Poser 9 and Mountain Lion - Serial Reg Failboat

Here's a quick brain dump of a few findings and fixings after a frustrating day trying to get Poser 9 working properly on my MacBook Pro running Mountain Lion.  If you are just here for my fixes scroll to the bottom.

I bought Poser 9 when it was on sale by Smith Micro, some time ago.  I've been using Manga Studio for quite a while for my line work and cartoon style drawing.  I needed a good animation product and bought Anime Studio recently as well.  Both of those Smith Micro products are great and get a lot of use.

However I had not really needed Poser - I just bought it because it was cheap enough on the special deal Smith Micro was offering.  Its normally quite pricey - and I had a plan to use the modelling tools in it to basically give me a pose-able artists dummy that I could use to draw from.

Anyway I pulled out the DVD from its case, checked out the ReadMe - which did not mention any of the known issues with Lion listed on the Poser site.  I installed, and before the UI came up I got the "Please enter your Poser Serial Number" dialog.  Filled that out, and then - first problem - no content library.

Instead there is a weird message saying that I had to install Flash from Adobe before I could use the content library!!  Gaah!  I absolutely do not want to have Flash on my laptop, but apparently if I want to use Poser there is no choice.  Sigh.  What I had always done on Mac is use Chrome for those annoying sites that require flash, and had a nice Flash-free browsing experience for general web-use with Safari.

I quit out of Poser, and ranted and raved and shook my tiny fist at the air.  Poser has Flash!?!?  I hate Flash!!  You might not have realised it if you're a long time Poser user.  Try right clicking on the Poser Library and you'll see something like the dialog to the right.

Why they feel the need to embed Flash in their UI I don't know.  I guess its using the so called "Flex" programming system.  It seems (based on a bit of inspection) that Poser was originally written with wxWidgets and some other fairly arcane technologies - so maybe they though Flex might save some development time.

I checked the Smith Micro website and found that there was an update - the SR1.3 update for Poser 9.  It was 114MB in size and took a while to download.  But maybe this would fix some of the issues!

Nah.  Still needed Flash - and weird - I had to do the registration again too.

So then I installed Flash from Adobe's website, and also before doing anything else, the "ClickToPlugin" extension for Safari, which blocks all attempts by web-pages to load flash or other browser annoyances.

Since later versions of Safari do not support the old faithful "ClickToFlash" add-on, the baton has been picked up by the fantastic author of ClickToPlugin.  Same great features but it now also works not just for flash but also Java, and a range of other noxious things that are trying to make your Safari slow, unstable and annoying.  I also love how it blocks flash movie players and subs in the Safari native HTML5 media player instead.  Very nice - means that those YouTube embeds now play just how you'd like without using an instance of Flash.

Note that if you "always use Firefox" or whatever, fine, but you should consider using a flash blocker for Safari anyway - its just so much more secure.  I bet that you'll find yourself viewing web-pages through Safari quite a bit because of its integration with programs on the Mac.  Its also faster and more lightweight than Chrome (my default browser of choice when I know I have to use Flash on Mac) for most usages.

Anyway.  With Flash on-board, and feeling a bit dirty - I fired up Poser 9 again.  Guess what I get another "Please enter your Poser Serial Number" dialog.  Filled that out, and then - just for giggles - quit out again - started up Poser - you guessed it - "Please enter your Poser Serial Number" dialog again!  Something was defeating the Poser serial number registration process.

I googled around a lot, checked forums, and even sent in a support request via the Smith Micro support on-line form.  The response was fairly lack-lustre:
Thank you for contacting Support. This is a Permission Issue.
Try this...
Create a new user account on your system with Admin Rights. Reboot and Log In to that new user account. Launch and activate Poser.
This will resolve the issue with having to activate on each launch, even after rebooting and returning to your normal user account, but also indicates that your user account is corrupted. If that does resolve the issue, you can either start using the new user account, or try to repair your current user account permissions using Disk Tools.
Well, my user account already had Admin Rights.  And I did not want to create a new user id.  But this got me thinking - Poser is probably trying to persist the registration of the Serial Number somewhere, and having trouble.

I fired up XCodes "Instruments" app which allows me to trace the execution of programs, and ran Poser under its watchful eye.  I used a File System monitor so I could check for attempts to open a file that failed.  Sure enough - I saw it attempt to open the following file:

/Users/Shared/Library/Application Support/Poser/9/PoserReg.dta

Somehow when "Installing for all users of this Mac" Poser had set up a lot of files under the "Shared" user.  The known issue web page about Lion (which I later discovered by Googling for the above path)  had a sort of fix for this issue - but it talked about the "root" user, not the "Shared" user.

To fix the issue I opened up my trusty Terminal and typed the following at the command line:

sudo mkdir -p /Users/Shared/Library/Application\ Support/Poser/9/
find /Users/Shared/Library/Application\ Support -exec sudo chown sez \{} \;

Now, one more Poser 9 registration and the issue was fixed.  I gave the Smith Micro support guy the information so maybe it will filter back through their knowledge base.

There are still a number of really annoying issues with Poser 9 on Mountain Lion - as described on the known issues page, and the most irritating is the one where you cannot use the color palette controls for any of the materials.  Instead you have to use the tiny button at the top right to open the Mac native color picker, which does work.  Another one is the "flashing black" library - I guess another issue with Flash.  As per a hint I found for a similar issue with Poser 2012, docking and undocking the library (drag by its bar at the top of its window) seems to fix the issue for that session.

So if you have Poser 9, and are about to install on your MacBook (which does not have Flash installed) your recipe becomes
  • start the download of the SR3.1 update from the Poser updates page
  • download the Flash player from Adobe
  • create the /User/Shared/Application Support/Poser/9 folder
  • install Flash (and I recommend a Flash blocker for Safari or your browser of choice)
  • Now finally install and register Poser 9 using your Serial number
  • Prepare for color picker, library and other frustrations
Note that for the 3rd step you can just use the Finder if you're not comfortable with the command line.

Good luck with Poser!