Thursday, June 4, 2009

Repairing my Creative Zen Vision:M 60GB (not Flex related)


I've spent many hours this year trying to fix my Creative Zen Vision:M 60GB. It died in January after I connected it to my laptop to charge it up (using a cheap adapter that I bought on ebay). Ever since it wouldn't turn on, just had a solid blue light (or a blinking blue light when it was plugged in to the computer or wall charger). And it was not recognized by the computer either.

My first thought was that the motherboard had died (probably because of my cheap usb adapter cable), but motherboards are quite expensive to replace, so instead I bought a new battery (off ebay too!) just to make sure. When the battery arrived I installed it and nothing changed - exactly the same scenario. So then I went back on ebay and bought a motherboard (not as expensive as I thought - only $20 USD plus shipping). The motherboard arrived this week and I took the old one out and put the new one in. See below for links on how to disassemble the ZVM. It isn't that difficult as long as you have a tiny Phillips screw driver, and steady hands.

After the new motherboard was installed I first connected it to the computer with the real cables that came with the player and charged it up. The computer instantly recognized mp3 player, and installed the drivers for it. But when I went to the properties in Windows Explorer it said it was only 50mb (instead of 60gb!). After searching google it appears that many other people have had this scenario. The reason for it is the firmware isn't correctly loaded, or is out of date, or the hard drive is faulty.

When I turned on the mp3 player the screen then showed an error message saying incorrect firmware version (0.0.15) and gave me the option to clean , format, reload firmware, and reboot. Cleaning did nothing - the screen said "scan disk..." forever. So I tried to reload the firmware. I downloaded the latest version from the Creative support website (linked at the top) and ran the exe (version 1.21.02), but every time it said "Your player is not connected. Please connect your player." even though my player was connected AND was recognized by Windows Explorer. A few people mention that this error happens on Windows XP when you have Windows Media Player 11 installed, so I rolled back to Windows Media Player 10 and still the same problem.

So, next step was to find a way to get the firmware onto the player with out using Creative's default firmware updater. I came across a support forum on www.epizenter.net mentioning that some people had hacked/cracked the Zen Vision:M firmware and had been able to change the fonts, colors, themes etc. So after days of searching I finally found some tools which helped me fix my zen. I haven't been able to find an original version of my 60gb firmware, so instead I'm using a modified version that uses a different font (Comic Sans MS). It works, so I don't care :)

Here are the steps I followed:
  1. Download the hacked Firmware Updater (it is for the ZVM 30gb but also works with the 60gb)
  2. Download the modified firmware nk.bin and put it in this directory (on Windows) C:\CtJbFW\newbin
  3. Connect your zen, and run the updater. All being well it will update the firmware and reboot your zen and it will work!


Links:
I've recently bought the new Creative Zen X-Fi2 mp3 player, with the touchscreen interface. At first it was a little sluggish (the touchscreen), but Creative has released a few patches that greatly improve the performance.






Wednesday, May 27, 2009

Blogger source code syntax highlighting

If you've read my last few blog posts you might have noticed that my code snippets now have syntax highlighting that looks similar to Flex Builder.

I've found many people asking how to get syntax highlighting to work on source code that is pasted into Blogger. Most solutions use CSS and Javascript to accomplish that with varying levels of success. I've chosen to go a different route and am using a parser to turn ActionScript text into html which I then paste right into a blog post (under "Edit Html").

I'm using a slightly modified version of this amazing free parser called Java2Html created by Markus Gebhard (GNU License). It is a Java Swing application (or Applet) that takes in input text and outputs html which you can easily copy and paste into a blog. The original version (which I believe is last updated in 2006) has three different style options - Eclipse, Kawa, and Monochrome. I've added a fourth option FlexBuilder that uses the default syntax highlighting styles found in ActionScript.

If you want to try out my version, I've posted the applet here: java2html

Here are some of the options you can use (in the panel on the right side):
  • Style - choose one of the 4 code styles (use FlexBuilder for ActionScript)
  • Line numbers - shows line numbers in the html
  • Table border - draws a 2 pixel gray border around the code block
  • Background color - if checked then a white background color is set on the code block
  • Include <html> and <body> tags - if false then the output html doesn't inclde the <html> and <body> tags, only the content.
  • Use <br> at the end of lines - if false then the html won't contain <br> tags
  • Include new lines ("\n") - if false then the html won't contain new line characters. Turn this off if you want to paste your code into Blogger since it treats new lines as breaks!
  • CSS Class - by default the code block is wrapped inside a <div class="java"> tag. This option configures the class="java" part.

  • Again I can't take much credit for this. All I've really done is add a few of the options mentioned above and changed the parser slightly to work with ActionScript keywords (such as function, var, etc).

    Here is an example of a very simple code snippet with and without styling:
    private function get string():String {
    var str:String = "String";
    return str;
    }
    private function get string():String {
        var str:String = "String";
        return str;

                

    One more thing, I haven't tested the various Target options, I only use the default "XHTML 1.0 Transitional (inlined fonts)".

    Tuesday, May 26, 2009

    Sorting string characters alphabetically

    In Java if you want to sort the characters in a String alphabetically it is very easy:
    String test = "sorting";
    char[] chars = test.toCharArray();
    Arrays.sort(chars);
    System.out.println(new String(chars))// prints out "ginorst"

    But how can we do this in Flex/ActionScript? Perhaps there is an easier way than this, but here are my utility functions that sorts the characters in a String by putting each character into an array, sorting the array, then joining the array back into a String.
    /**
     * Converts the string's characters into an array.
     @param string the string to convert into an array
     @param unique if true then only unique characters are added to the array
     @param ignoreCase only applies if the unique property is set to true
     */
    public static function toCharArray(string:String, unique:Boolean = false
           ignoreCase:Boolean = false):Array {
        var array:Array = new Array();
        if ((string != null&& (string.length > 0)) {
            // for tracking unique letters
            var seen:Object = new Object();
            // add each character to the array
            for (var i:int = 0; i < string.length; i++) {
                var char:String = string.charAt(i);
                if (unique) {
                    // unique characters only, possibly ignoring case 
                    // use the character code as the key (could just use the letter too) 
                    var key:String = (ignoreCase ? char.toUpperCase() : char);
                    key = key.charCodeAt(0).toString(10);
                    if (!seen.hasOwnProperty(key)) {
                        seen[keytrue;
                        array.push(char);
                    }
                else {
                    array.push(char);
                }
            }
        }
        return array;
    }

    /**
     * Sorts the characters in the string alphabetically. 
     @param ignoreCase if false (default) upper case letters come first then lowercase
     @param descending if true then the String is sorted in reverse
     @param unique if true then only unique characters are sorted and returned
     */
    public static function sort(string:String, ignoreCase:Boolean = false
                descending:Boolean = false, unique:Boolean = false):String {
        // no point in sorting
        if ((string == null|| (string.length <= 1)) {
            return string;
        }
        var chars:Array = toCharArray(string, unique, ignoreCase);
        var options:uint = 0;
        if (ignoreCase) {
            options = options | Array.CASEINSENSITIVE;
        }
        if (descending) {
            options = options | Array.DESCENDING;
        }
        chars.sort(function(s1:String, s2:String):int {
            return ObjectUtil.stringCompare(s1, s2, ignoreCase);
        }, options);
        
        var sorted:String = chars.join("");
        return sorted;
    }

    Feel free to comment if you know of a simpler way to sort characters in a String.

    Wednesday, May 20, 2009

    Using Flex and AMFPHP without a services-config.xml file

    I've been working a bit with amfphp, sending data between Flex and PHP using the RemoteObject class. Initially I put the generic services-config.xml file in my application's src directory:
    <services-config>
    <services>
    <service id="amfphp-flashremoting-service"
    class="flex.messaging.services.RemotingService"
    messageTypes="flex.messaging.messages.RemotingMessage">
    <destination id="amfphp">
    <channels>
    <channel ref="my-amfphp"/>
    </channels>
    <properties>
    <source>*</source>
    </properties>
    </destination>
    </service>
    </services>
    <channels>
    <channel-definition id="my-amfphp" class="mx.messaging.channels.AMFChannel">
    <endpoint uri="http://localhost/amfphp/gateway.php"
    class="flex.messaging.endpoints.AMFEndpoint"/>
    </channel-definition>
    </channels>
    </services-config>
    And changed my project properties to add this line to the Flex Compiler page:
    -services services-config.xml

    But I just came across this post which shows how to get around having to have an XML file by defining the channel at runtime.

    So here is my simplified Flex code:
    import mx.rpc.events.ResultEvent;
    import mx.rpc.events.FaultEvent;
    import mx.rpc.remoting.RemoteObject;
    import mx.messaging.ChannelSet;
    import mx.messaging.channels.AMFChannel;


    var url:String = "http://localhost/amfphp/gateway.php";
    var channel:AMFChannel = new AMFChannel("my-amfphp", url);
    var channelSet:ChannelSet = new ChannelSet();
    channelSet.addChannel(channel);
    var ro:RemoteObject = new RemoteObject("amfphp");
    ro.channelSet = channelSet;
    // Specify the PHP class
    ro.source = "TestService";
    ro.addEventListener(FaultEvent.FAULT, function(event:FaultEvent):void {
        trace("Fault: " + event.fault);
    });
    ro.addEventListener(ResultEvent.RESULT, function(event:ResultEvent):void {
        trace("Result: " + event.result);
    });
    // the TestService class must have a public helloWorld function
    ro.helloWorld();

    You could also do the same in MXML:
    <mx:ChannelSet id="channelSet">
    <mx:channels>
    <mx:AMFChannel uri="http://localhost/amfphp/gateway.php"/>
    </mx:channels>
    </mx:ChannelSet>
    <mx:RemoteObject source="TestService" destination="amfphp"
    channelSet="{channelSet}" id="remoteObject"
    fault="trace('Fault: '+event.fault)"
    result="trace('Result: '+event.result)"/>

    And the corresponding PHP code (put the php file inside your webroot/amfphp/services directory):
    <?php
    class TestService {
        public function helloWorld() {
            return "Hello from PHP";
        }
    }
    ?>

    So what are the benefits of this approach? Well, I'm not sure. In my case it was better because I have one logging class that does all the remoting, and is used by many different Flex applications. So instead of having to duplicate the services-config.xml file in every flex application this way I could define my endpoint url (http://localhost/amfphp/gateway.php) in one place.

    Here is another site that is useful when getting started with amfphp:
  • amfphp video tutorials
  • Wednesday, April 29, 2009

    FlashVars - passing parameters into Flash/Flex

    I'm sure most people are familiar with how to pass parameters into Flex using FlashVars. If you edit your project's html-template/index.template.html file and add in the flashVars parameter into the JavaScript like this:

    ...
    } else if (hasRequestedVersion) {
    // if we've detected an acceptable version
    // embed the Flash Content SWF when all tests are passed
    AC_FL_RunContent(
    "src", "FlashVarsTest",
    "width", "100%",
    "height", "100%",
    "align", "middle",
    "id", "FlashVarsTest",
    "quality", "high",
    "bgcolor", "#ffffff",
    "name", "FlashVarsTest",
    "allowScriptAccess","always",
    "type", "application/x-shockwave-flash",
    "flashVars", "hello=world&another=one",
    "pluginspage", "http://www.adobe.com/go/getflashplayer"
    );
    }...

    This adds two parameters which can be accessed from inside Flex using the Application.application.parameters variable. E.g. Application.application.parameters.hello gives you the value "world".

    But if you don't want to use JavaScript (which I wouldn't recommend, but is necessary in a few cases) then you can use the old loading method (also included in the index.template.html file) like this. The important thing to note is that Internet Explorer loads the parameters in differently than all other browsers (that I've tested).

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
    id="FlashVarsTest" width="100%" height="100%"
    codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
    <param name="movie" value="FlashVarsTest.swf" />
    <param name="quality" value="high" />
    <param name="bgcolor" value="#ffffff" />
    <param name="flashVars" value="FlashParameters=Internet Explorer only"/>
    <param name="allowScriptAccess" value="always" />
    <embed src="FlashVarsTest.swf" quality="high" bgcolor="#ffffff"
    width="100%" height="100%" name="FlashVarsTest" align="middle"
    play="true"
    loop="false"
    allowScriptAccess="always"
    type="application/x-shockwave-flash"
    flashVars="FlashParameters=FireFox,Safari,Chrome"
    pluginspage="http://www.adobe.com/go/getflashplayer">
    </embed>
    </object>
    And the same thing applies to the other tags: bgcolor, width, height. Internet Explorer reads in the values that are in the <object> tag, while all other browsers (FireFox, Chrome, Safari, ...) read in the values from inside the <embed> tag. So you have to make sure to duplicate all the values.