Emacs

A recent project revived my interest in Emacs. I used it daily back then when I was in college and was pretty fluent in using it as editor for my C codes. Back then.

Now after years of not using it, my Emacs knowledge has become rusty. Looked up the web for tutorial and found a good one:

So basically I can also compile C codes from within Emacs. I can access shell from within Emacs. I just have to create a file called .emacs in my home directory as per the instruction in the above web page and fill it with following configurations:


(global-font-lock-mode t)
(global-set-key "\C-xs" 'save-buffer)
(global-set-key "\C-xv" 'quoted-insert)
(global-set-key "\C-xg" 'goto-line)
(global-set-key "\C-xf" 'search-forward)
(global-set-key "\C-xc" 'compile)
(global-set-key "\C-xt" 'text-mode);
(global-set-key "\C-xr" 'replace-string);
(global-set-key "\C-xa" 'repeat-complex-command);
(global-set-key "\C-xm" 'manual-entry);
(global-set-key "\C-xw" 'what-line);
(global-set-key "\C-x\C-u" 'shell);
(global-set-key "\C-x0" 'overwrite-mode);
(global-set-key "\C-x\C-r" 'toggle-read-only);
(global-set-key "\C-t" 'kill-word);
(global-set-key "\C-p" 'previous-line);
(global-set-key "\C-u" 'backward-word);
(global-set-key "\C-o" 'forward-word);
(global-set-key "\C-h" 'backward-delete-char-untabify);
(global-set-key "\C-x\C-m" 'not-modified);
(setq make-backup-files 'nil);
(setq default-major-mode 'text-mode)
(setq text-mode-hook 'turn-on-auto-fill)
(set-default-font "-misc-fixed-medium-r-normal--15-140-*-*-c-*-*-1")
(setq auto-mode-alist (cons '("\\.cxx$" . c++-mode) auto-mode-alist))
(setq auto-mode-alist (cons '("\\.hpp$" . c++-mode) auto-mode-alist))
(setq auto-mode-alist (cons '("\\.tex$" . latex-mode) auto-mode-alist))

;(require 'font-lock)
;(add-hook 'c-mode-hook 'turn-on-font-lock)
;(add-hook 'c++-mode-hook 'turn-on-font-lock)


The following is custom command to compile, run, and access terminal from within Emacs when the above config has been done:


Step Four - Compile the program and prepare the executable

  • Now, to compile your program just type make at the UNIX prompt.Alternatively (and this is recommended) if you have installed the appropriate .emacs file you can continue to do everything from inside emacs:
  • Use Ctrl-x b to switch back to hello_world.cpp.
  • Now press Ctrl-x c and hit enter to begin the compilation.
  • The screen will split into two windows (press Ctrl-x o to switch between them and Ctrl-x 1 to return to single window mode).
  • If there are any errors they should be listed in the compilation window. To correct them use Ctrl-x g to go to a particular line (alternatively advanced users might like to edit their .emacs file and map the emacs command next-error onto a key of their choice).

Step Five - run the executable program

  • To execute your program just type ./hello_world at the UNIX prompt.Alternatively, you can continue to work from inside emacs (with the recommended .emacs files):
  • If you are not in two window mode, press Ctrl-x 2.
  • If you are not in the lower of the two windows, press Ctrl-x o until you are.
  • Press Ctrl-x Ctrl-u to bring up a UNIX prompt inside the current emacs window.
  • Now type ./hello_world at the UNIX prompt. All the output from the program will be displayed in the emacs window.

Installing Linphone for Ubuntu

As is always the case with Linphone, there are many steps not written in the README that one needs do.

First get linphone:

git clone git://git.linphone.org/linphone.git --recursive


And then, do the following (I'm on Ubuntu. If your on other distros the lib name might be different!)


sudo apt-get install libgtk2.0-dev
sudo apt-get install intltool
sudo apt-get install libosip2-dev
sudo apt-get install libexosip2-dev
sudo apt-get install libspeex-dev
sudo apt-get install libspeexdsp-dev
sudo apt-get install ffmpeg
sudo apt-get install libavcodec-dev
sudo apt-get install libswscale-dev
sudo apt-get install libxv-dev
sudo apt-get install libv4l-dev

Lib name is case sensitive and differ from platform to platform. To know the exact lib name, you can go to http://pkgs.org/search and enter the common lib name (as is mentioned in the README) in the search field in the top right corner. The site will then list the exact library name for your distro and how to install it. Very convenient!

After all the above directories are installed, enter the directory where you git pulled linphone and do:

./autogen.sh
./configure
make
sudo make install

Last step, you need to have the shared dynamic library generated during linphone compilation into your path. I added the following line to my ~/.profile

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

And then I restarted my machine to make the changes in profile takes permanent effect.

Now linphone is installed in /usr/local/bin and just type:

linphone

from terminal to execute it.

PVR Texture Format, Texture Cache

I have been looking around for tools to make my sprite sheet smaller. People say that PVR textures are the way to go.

So the graphics processor on iPhone is a design licensed from Power VR  (http://en.wikipedia.org/wiki/PowerVR). PVR textures are in such a format that Power VR graphics chips can easily digest, resulting in much faster processing. And smaller file size.

Sometime ago I bought Vladu Bogdan's SpriteHelper and LevelHelper toolsuite. In SpriteHelper, there is an option to save the resulting sprite sheet into a PVR format. But the quality is so low (it's lossily compressed). I'm looking for a tool that enables me to reduce the size and memory footprint of my sprite sheets without the quality degradation (lossless compression or uncompressed).

I used Level Helper in just one project that needed it. It's ok. I use Sprite Helper quite a lot but recently with the introduction of the Gatekeeper for Mac, it has become increasingly a pain to use. Really. It just frustrates me how Sprite Helper gets stuck at the beach ball of death phase when starting up. How it fails to save the plist, how it won't add  multiple images at once, etc. I have just grown sick of it now.

Anyway, back to PVR.

XCode comes with a tool to convert sprite sheet into PVR texture, but just as SpriteHelper, it uses lossy compression. The tool can be found in dir: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/texturetool

It's called texturetool.

Another tool: TexturePacker. I read people praising it, but it's paid app. Haven't tried.

Then there is this tool from Power VR themselves: PVRTexTool. It comes with both GU and CL interfaces. But I have not managed to get it working. I mean, I can't get it to convert my PNG files (generated by Sprite Helper) into pvr format.

So I fall back to texturetool. I created a small bash script to convert all PNG files in a directory into PVR format. Here it is:


#!/bin/bash

for file in `find ./ -name "*png"`
do
texturetool  -e PVRTC --bits-per-pixel-4 -f PVR -m  -o $file.pvr $file
done


The image quality is lower than the original PNG and in some cases the difference stands out. But I have not got much of a choice right now. Will tinker with PVRTexTool later when I got time.

I also learn about how sprite frame cache and texture cache work in Cocos2D. So basically texture cache is a dictionary with keys being the file/texture names and values the textures. One texture can (and should) contain a whole slew of images. Not just one. And you access each image by sprite frame cache.

So for instance you have image1.png, image2.png.... image50.png. You pack them into one big image using Sprite Helper or other tools. And then you have another file describing the position/coordinate of each image. This file is called the plist file. It's a dictionary with key being the individual image name (image1, etc) and value the coordinate of it in the big, packed image.

You create sprite frame cache from the plist (i.e you pass the plist name as the argument into sprite frame cache static methods). Then sprite frame cache will try to load the image with the same name as the plist into the texture cache. Sprite frame cache will expect the image to end with the png extension. If you have different image extension, such as pvr, you need to load the image manually into the texture  cache. Code snippet:


    CCSpriteFrameCache *frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
    NSString *spriteFrameName = @"myplistfile.plist";
    NSString *textureName = @"myspritesheet.pvr";
    CCTexture2D *texture = [[CCTextureCache sharedTextureCache] textureForKey:textureName];
    [frameCache addSpriteFramesWithFile:spriteFrameName texture:texture];




Ubuntu failed to connect to LAN

Someone screwed up with my computer LAN cabling at office, and now my Ubuntu could not connect to internet. It turned out to be such a headache to fix.
It was a headache. But should it happen again, it won't be, since now I know how to fix it.

Click on the internet connection icon on top right corner of the desktop. Edit a connection and choose to set it up manually. Fill in the IP, subnet mask and gateway.

And another important bit, set up the DNS. You can't set it up via that GUI interface in the preceding paragraph. Edit the file /etc/resolv.conf instead. On my Ubuntu 12, this file is a symlink to the /run/resolvconf/resolv.conf. The latter file is automatically generated by the resolvconf tool. So to manually edit DNS, you must first delete the symlink /etc/resolv.conf. And then, create a regular file at the same location, and enter in your DNS settings, such as below:

nameserver 192.168.0.11
nameserver 8.8.8.8

Restart the machine and you should be connected now.

Compile linphone for iPhone

My environment is Mac OS X Lion, newest macports (version 2.1.2). I followed the README down to each letter but errors were returned. The tools in the newest version of Macports have different requirements than the older ones used to write the README.

I then submitted a question to the linphone mailing list and got an answer. As follow:

Arek,

I've been struggling with this for days. It's mystifying to me that it was so hard to get working. I'm using Mountain Lion, Xcode 4.5, and iOS 6. I wonder if perhaps MacPorts is now installing newer versions of the tools required by the install guide.

At any rate, I just got Linphone fully built earlier today. To fix your 'install-sh' problem, you just need to create an empty file that is required by newer versions of autoconf:
> 'touch submodules/linphone/install-sh

At this point, I was stumped for a very long time by another error: 
> ./configure: line 4543: syntax error near unexpected token `HAVE_MD5SUM,test'
> ./configure: line 4543: `AM_CONDITIONAL(HAVE_MD5SUM,test -n $MD5SUM)'
As it turned out, the problem was again triggered by a line in configure.ac:
> configure.ac:42: error: 'AM_PROG_CC_STDC': this macro is obsolete.

The solution was to edit submodules/linphone/configure.ac and delete the line that says:
AM_PROG_CC_STDC
You will need to 'make veryclean' or run 'cd build/linphone; ./autogen.sh'

Incidentally, while working through this I also figured out the necessary steps to replace MacPorts with brew which has the advantage of being more self-contained and easily reversible than MacPorts.
1) Install brew: (instructions at http://mxcl.github.com/homebrew/)
2) Install dependencies:
brew install coreutils automake autoconf libtool intltool 
brew install wget pkgconfig cmake gmake yasm doxygen ImageMagick optipng
brew tap homebrew/dupes
brew install xz homebrew/dupes/grep

Linphone is hardcoded to look for a lot of tools in MacPorts-specific locations, (e.g. /opt/local/bin) so I also had to create a link from there to brew's standard install location: 'ln -s /usr/local /opt/local'

Good luck!
Eli

On Jan 15, 2013, at 12:00 PM, linphone-developers-request@nongnu.org wrote:

> Message: 1
> Date: Tue, 15 Jan 2013 16:08:36 +0800 (SGT)
> From: Firman 
> To: linphone-developers@nongnu.org
> Subject: [Linphone-developers] liblinphone SDK build failed.
> Message-ID:
>     <1358237316.44153.YahooMailClassic@web193306.mail.sg3.yahoo.com>
> Content-Type: text/plain; charset="iso-8859-1"

> Hi everybody,
> I have sifted through the mailing list archives but have not found anyone posting the same build failure problem as mine.

> So I cloned the git repo for iPhone
> git clone 
> git://git.linphone.org/linphone-iphone.git?--recursive

> and then followed everything that the README file says about how to build the liblinphone SDK down to each letter. And then I do

> sudo make all.

> It failed first with the following error:

> Generating configuration files for Speex, please wait....
> ? aclocal 
> configure.ac:5: error: 'AM_CONFIG_HEADER': this macro is obsolete.
> ??? You should use the 'AC_CONFIG_HEADERS' macro instead.
> /opt/local/share/aclocal-1.13/obsolete-err.m4:12: AM_CONFIG_HEADER is expanded from...
> configure.ac:5: the top level
> autom4te: /opt/local/bin/gm4 failed with exit status: 1
> aclocal: error: echo failed with exit status: 1
> make[1]: *** [/Users/barablu/Documents/workspace/liniphone/linphone-iphone/submodules/build/..//externals/speex/configure] Error 1
> make: *** [build] Error 2

> I then changed line 5 of configure.ac in speex directory from 
> AM_CONFIG_HEADER to AC_CONFIG_HEADERS. That error went away but now I get the following error that I have no clue how to solve. Can anybody please help me? I'm using XCode 4.5, iOS SDK 6, Mac OS X Lion. Thank you.

> Best regards,
> Arek Malang

> configure: loading site script /Users/barablu/Documents/workspace/liniphone/linphone-iphone/submodules/build/..//build/iphone-config.site
> Loading config.site for iPhone platform=Simulator version=4.0
> /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk
> /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.2.sdk
> /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.0.sdk
> /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.1.sdk
> /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.2.sdk
> /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk
> Selecting SDK path = /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk
> configure: error: cannot find install-sh, install.sh, or shtool in "/Users/barablu/Documents/workspace/liniphone/linphone-iphone/submodules/build/..//linphone" "/Users/barablu/Documents/workspace/liniphone/linphone-iphone/submodules/build/..//linphone/.." "/Users/barablu/Documents/workspace/liniphone/linphone-iphone/submodules/build/..//linphone/../.."
> make[1]: *** [/Users/barablu/Documents/workspace/liniphone/linphone-iphone/submodules/build/../build-i386-apple-darwin/linphone/Makefile] Error 1
> make: *** [build] Error 2

Compile linphone for Android

Compiling linphone has always been a challenge for me. Even after following the README down to each letter, I always get errors. Compiling linphone for Android is no difference.

So I followed the README, got everything installed, and did make.

And I ended up with numerous such errors:

Fatal error: invalid -march= option: `armv5te'

After a while, I figured out that it was caused by failure in cross compilation. So linphone uses a lot of libraries written for intel (desktop) processors. Those libraries need to be cross compiled for ARM. I failed at this stage.

So to summarize, the following are the steps needed to compile linphone for Android. These steps are taken from the README, with my comments inside the parentheses.
(My OS is Ubuntu 12).

0) download the Android sdk with platform-tools and tools updated to latest revision (at least API 16 is needed), then add both 'tools' and 'platform-tools' folders in your path.
1) download the Android ndk (>=r8b) from google and add it to your path.
2) install the autotools: autoconf, automake, aclocal, libtoolize pkgconfig (On my Ubuntu, aclocal is part of automake. pkgconfig is in a package called pkg-config and already installed. libtoolize is in a package called libtool. So actually I had to: sudo apt-get install automake autoconf libtool)
3) install the code sourcery toolchain. This step is crucial as the toolchain is needed for succesful cross compilation. This step is not mentioned in the README!!!!

So to install the sourcery toolchain, do these steps:
1. Get the binary from sourcery.mentor.com. Get the binary for Linux, not the source, to save you from compilation headache. The filename is: arm-2008q3-72-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2. You have to register, agree to some formalities, and then download it.
2. Unzip it. Preferable to a subdir inside the /opt dir to make it look pro.
3. Add path to the bin directory inside the unzipped directory to your path.

And then, done. Follow the readme to make and make install and you'll compile with success.

Installing Java on Ubuntu

I still remember how *gruesome* it was to install or update Java on Ubuntu. I wrote it somewhere in earlier post. Fortunately now with Ubuntu 12.10, an easier method (a ready to execute script) is available:

First you need to remove openjdk for this run the following command from your terminal
sudo apt-get purge openjdk*
If you installed java 7 from any other PPA and you are having problem with java then you have to do following steps before installing the PPA menctioned here
sudo rm /var/lib/dpkg/info/oracle-java7-installer*
sudo apt-get purge oracle-java7-installer*
sudo rm /etc/apt/sources.list.d/*java*
sudo apt-get update
Install oracle java 7 in ubuntu 12.04
Open the terminal and run the following commands
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java7-installer

http://www.ubuntugeek.com/how-to-install-oracle-java-7-in-ubuntu-12-04.html

ADB not recognized on newly installed Ubuntu 12.10

I just installed latest Ubuntu (12.10) on my office computer running Win 7. Problems soon appear.

The first is that from time to time the desktop became totally unresponsive. Paralyzed. I had to wait for a few minutes until my mouse clicks did anything at all.
After looking at top, I found out that the process mount.ntfs occupied 100% of CPU. So I got windows partition mounted and Ubuntu was doing something to it that hogged the resources. I don't know how to solve this... I installed this Ubuntu from Windows initially.

And then I needed to put Eclipse to the Unity launcher. Unity launcher is a vertical container of icons on the left side of the desktop, as in following picture:

How: 
1. Create a file with .desktop extension, containing info like this:

[Desktop Entry]
Version=
Name=Eclipse
Comment=
Exec=/home/switchlab/Documents/bin/eclipse/eclipse
Icon=/home/switchlab/Documents/bin/eclipse/icon.xpm
Terminal=false
Type=Application
Categories=Application;

2. Put it in /usr/share/applications
3. In Dash Home, search for Eclipse and then drag and drop it to launcher.

I installed Android SDK, but then I failed to run adb eventhough I got it on my PATH. The error message said: No such file or directory. This is very weird. I checked that the adb did exist in platform-tools. So why this message? 

It turned out that this is caused by a glitch on my Ubuntu 64 bit installation. I had to do:
sudo dpkg --add-architecture i386 && sudo apt-get update && sudo apt-get install ia32-libs

and everything worked fine again. I still haven't got a clue what that command does. Anyway, thanks goes to Scotty Delicious who wrote it here: http://askubuntu.com/questions/219465/cannot-install-ia32-lib-package

Objective C memory management

After a while finally (I think) I grasp how this memory management thing works in Objective C.

First about assign and retain.

When you declare properties using (retain) then the retain count will be incremented by one when you assign value to it.

@interface LayerA : CCLayer{

   CCSprite *sprite;
}

@property (retain) CCSprite *sprite;
@end

Now if in other classes you call:

LayerA.sprite = [CCSprite node];

The retain count of sprite in LayerA will be incremented by one and as such, it won't be released until you call:

LayerA.sprite = nil;

which will decrease the retain count by one. So everytime you assign a value to a retain property, you must have a matching nil assignment to it.

This can complicate manual memory management and I usually prefer to have assign instead of property.


@interface LayerA : CCLayer{

   CCSprite *sprite;
}

@property (assign) CCSprite *sprite;
@end

Now when you assign a value to the sprite property, the retain count will not be incremented.

Another case about memory management that I learnt the hard way was when passing argument to the class constructor.

When class A calls the constructor of class B and passes parameters, the parameters will be released when class A is released. So if class B caches those parameters, it is good only as long as class A lives. The constructor in class B needs to make deep copy of the parameter if class B wants to use the parameters in methods other than constructor.

Box2D weld joint

So one might think this is the simplest joint, but it turns out there are so much subtlety into it. After a gruesome few days of trying to figure out what went wrong with my weld joint, finally I (think I) get a good grasp of it.

Let's start with the basic:

There are 3 major components with joints.
1. The reference body. This is the body that goes first in the b2JointDef.Initialize method. The reference is the body to which the joint is attached.
2. The target body. This is the body that goes second in the b2JointDef.Initialize method. The target body is the attached body. So the movement of the target body follows that of the reference body.
3. Anchor. Where to attach the target body to the reference body. This is a b2Vec2 coordinate relative to the reference body.

i.e:

b2WeldJointDef.Initialize(refBody, targetBody, b2Vec2(-5, 10));

The target body will be glued to the reference body at -5, 10 from the ref body position.

As for the weld joint, one must define the following for it to work:


    bodyDef.fixedRotation = FALSE;
    fixDef.density = 2.0f;


Basically one must define the density and set fixedRotation to false. Otherwise, the weld joint will fall off. The bodies glued together using weld joint must also be large enough. There will be an area check somewhere inside the Box2D engine to make sure that areas joined exceed a certain delta value!

Apple Code Signing

I was just released from being mired in litany of predicaments due to code signing procedures and here's my story...

So I work on a new macbook, someone else's, and i fail to code sign my app before deploying it to my device.

After two days I finally figured it out. (or better put: people sharing their knowledge on internet got it figured out).

Basically, code signing process is following:

You need to have the following in your computer when code sign:
- public and private key pair.
- certificate issued by you (if you are administrator of your Apple developer program)
- Apple intermediate certificate.

You got to have public and private key for code signing. This pair is created on your computer when you created certificates and provisioning profile FOR THE FIRST TIME. If you move development to other machine, you will have to do something to move this pair to the new machine.... The easiest way would be to re-create everything from scratch: delete your certificate in developer.apple.com and recreate it by submitting new certificate request from keychain.

If you develop on a new machine, the private key is usually missing. You can tell by going to the keychain. Your certificate should have a little triangle next to it, that you can click and it will show you the public and private key pair. If you don't have that triangle, you have the certificate but not the key pair and your code signing won't work.

The intermediate certificate can be downloaded from the the usual place in developer site without having to submit certificate request first. If you don't install this, you'll get this error from XCode: /usr/bin/codesign fail or something similar.

Code signing is one part. Then there's this thing called provisioning profile which basically says which certificate to sign which app and which app can be deployed on which device...

Er... I'm unsure. But that's my impression of two days fixing code signing error.

One more thing, I deleted all passwords in keychain because I used my own apple credential in XCode automatic refresh and now I wanted to use someone else's. I couldn't find the right password for XCode in keychain so I deleted them all. .-))
It worked. I was asked to enter new credential when I clicked refresh in XCode organizer. But another problem arose: When I created certificate request it gave me errors like incorrect passphrase or something. I could not create certificate request because I deleted all of my passwords! Solution is simple: restart the computer!