My PS-3 controller article was featured on HackerNews, and later picked up by LifeHacker. I consider that as a step in the right direction. According to Google Analytics: I had a peak of close to 300 visits on the day the article was published on LifeHacker.
This is not surprising of course, Lifehacker is a behemoth compared to my blog. I also gained quite a bit of followers as well. This achievement motivates me to continue posting good content on the web.
I would actually also like to thank Myplanet Digital, the awesome place I work at, for letting me do some of this on company time, and constantly encouraging me and all the other developers to do awesome things every day.
Oh and I migrated the blog to Octopress and I am hosting the site on Heroku, everything about this just feels right in my gut. I am really diggin’ my version controlled posts from this day on.
Picture this: after hours of web browsing, your body is contorted in various unnatural positions over time: your legs up on the table or you’re lying on the bed sideways with the laptop rotated sideways as well. Does that sound familiar?
For me it does.
Of course, I am not proud of my posture after sitting at the screen for four hours straight, but I soon realized that it was a result of my body’s pursuit of comfort, while being dependent on the keyboard and mouse.
All I want is to kick back and relax on my lounge chair, but with a laptop on my lap, that means my body has little to no degrees of freedom.
“Are you telling me that there is only one way to lay in my chair?” /r/firstworldproblems.
Okay, it may be somewhat bearable with a laptop, but what about all the other folks who own a desktop?
And then I came up with the idea to use a PS3 controller for day to day casual web browsing. Why not? the analog sticks will be perfect for emulating the mouse, and the other keys will be mapped to my most common keyboard shortcuts.
Here is how it looks:
Step 1: Get MotionInJoy
The PS3 controller did not seem to come with its native drivers, and the only way to make it work with my computer was with the MotionInJoy Application.
What’s cool about MotionInJoy is that it has multiple profiles, even including X-box 360 mode.
Some of their own instructions were wrong and ultimately misleading, and the change to Mandarin was just a silly thing to do. Disregard everything between 1:50 and 2:35, instead connect your controller via USB, and click the “Driver Manager” tab, then click “Install all”.
Pressing “Load Driver” will NOT work as they suggested. The rest should be correct.
When in doubt, the vibration test is your friend. To make sure your bluetooth drivers are supported by the app, feature 39 must be working (under Bluetooth Pair->Supports Feature).
Step 2: Get JoyToKey
Next I used JoyToKey in order to map the keys that I wanted onto the controller. This video should help you understand how to do most of it. The main caveat is this: the exact names of the buttons in JoyToKey may not exactly correspond to the key numbers in your controller settings. As you can see from my demo video above, the corresponding keys in JoyToKey will light up in yellow when the key is pressed.
EDIT: I have received some questions about what the specific mapping I used, here it is:
L1: Right mouse click,
R1: Left mouse click,
L2: CTRL+SHIFT+TAB (move to previous tab),
R2: CTRL+TAB (move to next tab),
D-pad Up: scroll up,
D-pad Down: scroll down,
D-pad left: ALT+LEFT (back),
D-pad right: ALT+RIGHT (forward),
Start: HOME (home directory),
PS: WIN+G (Open Chrome),
Triangle: CTRL+W (close tab),
Square: CTRL+= (zoom in),
Cross: CTRL+- (zoom out),
Circle: CTRL+SHIFT+T (restore tab),
Left Analog stick: Slow mouse (15%, for accuracy),
Right Analog stick: Fast Mouse (100% for dropping the cursor in the right general area)
Left stick click: F5 (refresh),
Right stick click: middle mouse click (scroll).
If you are like me, you want to scroll up or down when you press and hold D-pad up, and D-pad down. Just do this:
If you have more specific questions with JoyToKey, don’t hesitate to contact me. :)
Step 3 (optional): Get AutoHotKey
Now if we want to truly make the mapping powerful, we can get AutoHotKey, and assign really complex actions to certain combination of keys. I looked through the manual, and there’s a metric shit-ton of stuff you can do with it.
All I am doing with it is launch google chrome (WIN + G) and open my home directory (HOME), and then I assign these keys to the button, and button on my controller respectively.
When I don’t use the controller after a while, it automatically shuts down. Sometimes pressing the PS button will cause the LED’s to flash a bit and then nothing else happens. I follow this ritual to get my controller voodoo working again:
Do a vibration test in MotionInJoy, if not working, reset the program.
If vibration test passes, click “Enable” in the main MotionInJoy screen.
If the cursor is still not moving, go to JoyToKey->Options, and click “Refresh”
With my current mapping, I have found that I can do almost all of the actions that I usually do with a keyboard and mouse while browsing. I would even argue that I can do them much faster with a controller. The obvious downside to this is when I need to type in a link or a keyword in a search bar. But I minimized that problem by keeping my regular websites in the bookmark bar in Chrome, within my click’s reach.
I hope that more people can see the value of this, since most computer users are so heavily dependent on pointing and clicking their way through the day. This poses obvious ergonomic concerns as wrist and back-pain are so common in office workers. I am planning to improve this whole set-up by writing an application that would effectively bootstrap these applications and combine their functionality for easier configuration.
Go ahead, try it! You’ll feel the difference. Just don’t become this guy:
What I really liked about this tutorial/webcast/interactive podcast, is that it’s a comprehensive learning system that breaks down RoR concepts into small “levels”, and turns the whole experience into a game.
Basically, when I started doing it, I was given a 10 minute instructional video to begin with, and after that, I had to type out the correct code that implements the concepts covered in the video.
Of course, if I am stuck, I can go back to the video and find the answers that I am looking for, and try again until I get the correct solution.
This whole process felt like playing a video game, which reminded me that, although understanding certain programming paradigms can sometimes become an extremely painful process, especially when there is no adequate feedback system or proper documentation, at the end of day, the reason why I learn to code is because its fun.
[UPDATE] Due to popular request, I added Doom’s theme song in for the batch file in my feature branch.
This is basically the tip-of-the-ice-berg “front end” of an automation script that I have written for the QA guys in the office to use.
The automation tool takes the QA analyst to the page they want in the setup wizard, dynamically filling the forms, and choosing radio buttons for them, So that they can continue testing the application.
On start up, the script checks the user’s directory for the dlls that run the test. If the user has not compiled the test solution, the script will automatically do that with MSBuild, then run the wizard.
I used CodedUI for the auto-navigation. I did get to play around with WiPFlash and White before hand, but at the time when I started with CodedUI, White did not work well with our 64-bit machines, and WiPFlash was doing something funky with radio buttons. I have emailed Liz Keogh, the creator of WiPFlash, she agreed that it was a bug, and fixed it, (Sorry Liz, I did not get a chance to try out your newly improved WiPFlash!).
I will probably upload the modified source to my git repo soon.
I was helping someone close to me upload gigabytes worth of data via ftp with FileZilla. At some point, I was getting this error:
“failed to convert command to 8-bit charset”
Turns out some of the file names were encoded with Chinese characters (the names were entirely composed of numbers), and FZ was having trouble reading them.
Of all the solutions I have found on the web, the best one (not surprisingly) was a Chinese blog post addressing this problem on the dot. The author proposed to add GB2312, which is China’s official character set, through the FZ site manager.
Speaking of encoding, I found an interesting, rather passionately written blog post, titled:
Normally when I search for solutions on the web, I would never exclude foreign web spheres as an option. About 90% of the time, I was able to find things on Russian and Chinese sites when I could not find them on English ones.
Luckily for me, my Russian and Mandarin pays off when it comes to searching for computer/programming-related information, especially when those two are the more common first languages of developers world-wide.
My first project at iQmetrix was to work with their bug tracking system, JIRA.
JIRA is a great issue and bug tracking tool from Atlassian. Its simple and elegant UI makes it quite intuitive to use.
Automating certain features would have been nice. So I found myself with a task to take an excel spreadsheet that contained all the field values for a number of issues/bugs (issue ID, summary, description, change log etc.), and automatically import them to JIRA using its SOAP API.
First, I built the parser that would scan the CSV file, and create a new issue object every time it hit an integer for the field value. Since issue ID was the only numeric field value in the file, it was a good separator in general. The rest of the field values were then piped in to their respective strings inside the created issue class.
I found a very helpful piece of C# example code by Tom Wilberding here.
Finally, I had to make sure the same issue does not get duplicated and uploaded twice. If the pending issue’s ID collided with an existing ID, then my code would check which fields were updated and post an automated message as a comment informing of the collision, and show the updated fields, if any.
Having said that, I found that a lot of documentation I was looking at was really not up-to-date. Some methods that I thought would be essential were not there.
I think there is a decline in the effort and interest for the guys at Atlassian to maintain their SOAP API, especially since some of the feature requests made by users primarily in 2005-2008 are still not available.
Regardless of that, I had a lot of fun doing this project, it was a grrreeeat way to dive into C#, and learn the tricks of Visual Studio, and the .NET framework. But it was more about seeing my code actually DO something remotely.
I got to say, it took me a damn long time to just sit down and start writing. Even after I made the decision to start a blog, I tied my hands with all sorts of secondary tasks, such as buying a domain name, finding web hosting, looking for “blog applications” that can run locally without me posting it online. (Jeez, right?)
In the end, the most important thing is content.
I was quite hesitant about buying web hosting, when it is quite obvious that I don’t have any content to begin with. I did know, however, that I wanted my own domain name, so I bought that from namecheap, and all I did was follow tumblr’s very own simple guide to point my domain’s A-record to 220.127.116.11.
I am really digging tumblr’s no BS, quick and easy way to setup a blog and be able to point a custom domain without any hassle or fee.
I think that starting this blog is a good step in the right direction. Indeed, there are millions of other bloggers online hoping to claim their share of the internet-pie, and leave their “legacy” on the web. I know that for myself, writing is the only self-assessing tool I have left, and the only way to momentarily break free from the enormous amount of external-informational stimuli.
I have yet to set a definitive direction where this blog will go, and what exactly I will blog about. My interests sprawl over a wide array of different fields, and I can only assume that my blog will reflect that.