tag:blogger.com,1999:blog-53092955765327105192024-03-04T22:59:48.011-08:00The Robot Can TalkBut, it chooses to type instead...Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.comBlogger42125tag:blogger.com,1999:blog-5309295576532710519.post-4073234176190545762016-07-01T07:02:00.003-07:002016-07-01T13:55:59.566-07:00A Much Better xterm<div dir="ltr" style="text-align: left;" trbidi="on"><h1 id="a-much-better-xterm">A Much Better xterm</h1><br />
<p>A while back, I posted about improving my default xterm from drab nothingness to … something better. Here - <a href="http://robotcantalk.blogspot.com/2016/05/a-better-xterm.html">A Better xterm</a>. </p><br />
<p>Though, it was an improvement over the depressing white/black, its charm wore out pretty quickly. The colors were just too dull. And the script just wasn’t generic/flexible enough for my taste. That’s why I wrote another script(s), and this time, I certainly did get aesthetically pleasing <em>random</em> soft pastel colors - just as I wanted in the first place. </p><br />
<p>To start with, you’ll need to have my <code>.Xresources</code>, and merge it in your environment using <code>xrdb -merge .Xresources</code>.</p><br />
<p><i class="icon-code"> <a href="https://github.com/SonalPinto/LinuxScripts/blob/master/.Xresources">My .Xresources</a></i></p><br />
<a name='more'></a><br />
<br />
<p>With the config in the <code>.Xresources</code> you’d already have a decent looking xterm (a massive improvement over the default). The next step is to enable random <em>aesthetically</em> pleasing colors to set as the foreground/background, each time we call it. I wrote a perl script that generates the fg/bg arguments.</p><br />
<p><i class="icon-code"> <a href="https://github.com/SonalPinto/LinuxScripts/blob/master/bin/xtermc.pl">xtermc.pl : random fg/bg argument generator</a></i></p><br />
<pre class="prettyprint"><code class="language-[perl] hljs perl"><span class="hljs-comment">#!/usr/bin/perl </span>
<span class="hljs-keyword">use</span> strict;
<span class="hljs-keyword">use</span> warnings;
<span class="hljs-comment"># parse mixing brightness or default it to 256</span>
<span class="hljs-comment"># 256 - nice pastel colors</span>
<span class="hljs-comment"># 128 = dark pastel</span>
<span class="hljs-keyword">my</span> <span class="hljs-variable">$mix</span> = <span class="hljs-keyword">shift</span> || <span class="hljs-number">256</span>;
<span class="hljs-comment"># generate random BG</span>
<span class="hljs-keyword">my</span> <span class="hljs-variable">$r</span> = <span class="hljs-keyword">int</span>(<span class="hljs-keyword">rand</span>(<span class="hljs-number">256</span>));
<span class="hljs-keyword">my</span> <span class="hljs-variable">$g</span> = <span class="hljs-keyword">int</span>(<span class="hljs-keyword">rand</span>(<span class="hljs-number">256</span>));
<span class="hljs-keyword">my</span> <span class="hljs-variable">$b</span> = <span class="hljs-keyword">int</span>(<span class="hljs-keyword">rand</span>(<span class="hljs-number">256</span>));
<span class="hljs-comment"># mix in the offset</span>
<span class="hljs-variable">$r</span> = (<span class="hljs-variable">$r</span>+<span class="hljs-variable">$mix</span>) / <span class="hljs-number">2</span>;
<span class="hljs-variable">$g</span> = (<span class="hljs-variable">$g</span>+<span class="hljs-variable">$mix</span>) / <span class="hljs-number">2</span>;
<span class="hljs-variable">$b</span> = (<span class="hljs-variable">$b</span>+<span class="hljs-variable">$mix</span>) / <span class="hljs-number">2</span>;
<span class="hljs-comment"># format the bg color string</span>
<span class="hljs-keyword">my</span> <span class="hljs-variable">$bg</span> = <span class="hljs-keyword">sprintf</span>(<span class="hljs-string">"#<span class="hljs-variable">%x</span><span class="hljs-variable">%x</span><span class="hljs-variable">%x</span>"</span>, <span class="hljs-variable">$r</span>, <span class="hljs-variable">$g</span>, <span class="hljs-variable">$b</span>);
<span class="hljs-comment"># generate FG color based on luminosity of the BG</span>
<span class="hljs-comment"># V = 0.2126 R + 0.7152 G + 0.0722 B</span>
<span class="hljs-keyword">my</span> <span class="hljs-variable">$lumin</span> = (<span class="hljs-number">0</span>.<span class="hljs-number">2126</span><span class="hljs-variable">*$</span>r + <span class="hljs-number">0</span>.<span class="hljs-number">7152</span><span class="hljs-variable">*$</span>g + <span class="hljs-number">0</span>.<span class="hljs-number">0722</span><span class="hljs-variable">*$</span>b)/<span class="hljs-number">256</span>;
<span class="hljs-keyword">my</span> <span class="hljs-variable">$fg</span> = (<span class="hljs-variable">$lumin</span><<span class="hljs-number">0</span>.<span class="hljs-number">5</span>) ? <span class="hljs-string">'#f2f3f4'</span> : <span class="hljs-string">'#131516'</span>;
<span class="hljs-comment"># print "\n|$bg|$fg|\n";</span>
<span class="hljs-comment">#generate text string for xterm commands</span>
<span class="hljs-keyword">print</span> <span class="hljs-string">"-fg <span class="hljs-variable">$fg</span> -bg <span class="hljs-variable">$bg</span>"</span>;</code></pre><br />
<p>It generates a random color and then blends it with an offset color, to make the BG. In this script the blending color is defaulted to white, but can take any gray color (R=G=B). Surely, this could be modified to afford any kind of blends (reds, violets, etc), but I have left it simple. The FG is decided based on the luminosity (brightness) of the BG, and takes a natural light/dark color. The brightness of an RGB color is obtained according to the HSV color notation (<code>V = 0.2126 R + 0.7152 G + 0.0722 B</code>) (credit: <a href="http://stackoverflow.com/questions/43044/algorithm-to-randomly-generate-an-aesthetically-pleasing-color-palette">source1</a>, <a href="http://stackoverflow.com/questions/6763032/how-to-pick-a-background-color-depending-on-font-color-to-have-proper-contrast">source2</a>).</p><br />
<p>Here’s a jsfiddle that I forked that demonstrates the above concept: <a href="http://jsfiddle.net/sonalpinto/gp94byL6/">JS Color Palette Gen</a> - You can play around with the blend colors and see what palette it generates.</p><br />
<iframe width="100%" height="500" src="//jsfiddle.net/sonalpinto/gp94byL6/embedded/" allowfullscreen="allowfullscreen"></iframe><br />
<br />
<hr><br />
<p>Finally, alias that script in your <code>.baschrc</code> or <code>.cshrc</code> to some command you can call easily, say <em>term</em>, just like in <a href="http://robotcantalk.blogspot.com/2016/05/a-better-xterm.html">part-1</a>.</p><br />
<br />
<br />
<pre class="prettyprint"><code class="language-[bash] hljs ruby"><span class="hljs-keyword">alias</span> term <span class="hljs-string">'xterm `/home/a0226966/bin/xtermc.pl` &'</span></code></pre><br />
<br />
<hr><br />
<p><code>Blend = White(#ffffff)</code>: <br />
<br />
<img src="https://i.imgur.com/vDUDKI2.png" alt="Blend = White(#ffffff)" title=""></p><br />
<p><code>Blend = Gray(#7f7f7f)</code>: <br />
<br />
<img src="https://i.imgur.com/3RXcj8m.png" alt="Blend = Gray(#7f7f7f)" title=""></p></div>Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-34050820087312817272016-05-27T07:23:00.003-07:002016-07-01T07:05:36.264-07:00A Better xterm<div dir="ltr" style="text-align: left;" trbidi="on"><h1 id="a-better-xterm">A Better xterm</h1><br />
<p>Well, if you are like me, and use xterms to get things done, and have them spread around your display - <em>maybe</em>, you have gotten tired of looking at these drab default xterms?</p><br />
<p><img src="https://imgur.com/VeE0UTP.png" alt="Blank Xterm" title=""></p><br />
<a name='more'></a><br />
<br />
<p>xterms are lightweight and often the only thing works without latency-frustration when working over VNCs (located on another continent…). Consider using FluxBox as your window manager, if you find yourself in such a situation (it has a neat feature to clip and tab all the windows you have open - including your xterms).</p><br />
<p>Over, the year, like many others, I have ended up gathering some settings to determine how my xterm looks. Here’s my <code>.Xresources</code> (make one in your home dir <code>~/</code>, if you don’t already have one).</p><br />
<pre class="prettyprint"><code class="language-[bash] hljs perl">!right hand side scrollbar...
xterm<span class="hljs-variable">*rightScrollBar</span>: true
xterm<span class="hljs-variable">*ScrollBar</span>: true
! stop output to terminal from jumping down to bottom of scroll again
! xterm<span class="hljs-variable">*scrollTtyOutput</span>: false
XTerm<span class="hljs-variable">*faceName</span>: Bitstream Vera Serif Mono
xterm<span class="hljs-variable">*faceSize</span>: <span class="hljs-number">11</span>
! xterm<span class="hljs-variable">*vt100</span><span class="hljs-variable">*geometry</span>: <span class="hljs-number">80</span>x6<span class="hljs-number">0</span>
xterm<span class="hljs-variable">*saveLines</span>: <span class="hljs-number">16384</span>
xterm<span class="hljs-variable">*loginShell</span>: true
xterm<span class="hljs-variable">*charClass</span>: <span class="hljs-number">33</span>:<span class="hljs-number">48</span>,<span class="hljs-number">35</span>:<span class="hljs-number">48</span>,<span class="hljs-number">37</span>:<span class="hljs-number">48</span>,<span class="hljs-number">43</span>:<span class="hljs-number">48</span>,<span class="hljs-number">45</span>-<span class="hljs-number">47</span>:<span class="hljs-number">48</span>,<span class="hljs-number">64</span>:<span class="hljs-number">48</span>,<span class="hljs-number">95</span>:<span class="hljs-number">48</span>,<span class="hljs-number">126</span>:<span class="hljs-number">48</span>
xterm<span class="hljs-variable">*termName</span>: xterm-color
xterm<span class="hljs-variable">*eightBitInput</span>: false
!BLK Cursor
<span class="hljs-comment">#define _color0 #000d18</span>
<span class="hljs-comment">#define _color8 #000d18</span>
!RED Tag
<span class="hljs-comment">#define _color1 #e89393</span>
<span class="hljs-comment">#define _color9 #e89393</span>
!GRN SpecialKey
<span class="hljs-comment">#define _color2 #9ece9e</span>
<span class="hljs-comment">#define _color10 #9ece9e</span>
!YEL Keyword
<span class="hljs-comment">#define _color3 #f0dfaf</span>
<span class="hljs-comment">#define _color11 #f0dfaf</span>
!BLU Number
<span class="hljs-comment">#define _color4 #8cd0d3</span>
<span class="hljs-comment">#define _color12 #8cd0d3</span>
!MAG Precondit
<span class="hljs-comment">#define _color5 #c0bed1</span>
<span class="hljs-comment">#define _color13 #c0bed1</span>
!CYN Float
<span class="hljs-comment">#define _color6 #dfaf8f</span>
<span class="hljs-comment">#define _color14 #dfaf8f</span>
!WHT Search
<span class="hljs-comment">#define _color7 #efefef</span>
<span class="hljs-comment">#define _color15 #efefef</span>
!FMT Include, StatusLine, ErrorMsg
<span class="hljs-comment">#define _colorBD #ffcfaf</span>
<span class="hljs-comment">#define _colorUL #ccdc90</span>
<span class="hljs-comment">#define _colorIT #80d4aa</span>
!TXT Normal, Normal, Cursor
<span class="hljs-comment">#define _foreground #dcdccc</span>
<span class="hljs-comment">#define _background #1f1f1f</span>
<span class="hljs-comment">#define _cursorColor #8faf9f</span>
URxvt<span class="hljs-variable">*color0</span> : _color<span class="hljs-number">0</span>
URxvt<span class="hljs-variable">*color1</span> : _color1
URxvt<span class="hljs-variable">*color2</span> : _color2
URxvt<span class="hljs-variable">*color3</span> : _color3
URxvt<span class="hljs-variable">*color4</span> : _color4
URxvt<span class="hljs-variable">*color5</span> : _color5
URxvt<span class="hljs-variable">*color6</span> : _color6
URxvt<span class="hljs-variable">*color7</span> : _color7
URxvt<span class="hljs-variable">*color8</span> : _color8
URxvt<span class="hljs-variable">*color9</span> : _color9
URxvt<span class="hljs-variable">*color10</span> : _color1<span class="hljs-number">0</span>
URxvt<span class="hljs-variable">*color11</span> : _color11
URxvt<span class="hljs-variable">*color12</span> : _color12
URxvt<span class="hljs-variable">*color13</span> : _color13
URxvt<span class="hljs-variable">*color14</span> : _color14
URxvt<span class="hljs-variable">*color15</span> : _color15
URxvt<span class="hljs-variable">*colorBD</span> : _colorBD
URxvt<span class="hljs-variable">*colorIT</span> : _colorIT
URxvt<span class="hljs-variable">*colorUL</span> : _colorUL
URxvt<span class="hljs-variable">*foreground</span> : _foreground
URxvt<span class="hljs-variable">*background</span> : _background
URxvt<span class="hljs-variable">*cursorColor</span> : _cursorColor
XTerm<span class="hljs-variable">*color0</span> : _color<span class="hljs-number">0</span>
XTerm<span class="hljs-variable">*color1</span> : _color1
XTerm<span class="hljs-variable">*color2</span> : _color2
XTerm<span class="hljs-variable">*color3</span> : _color3
XTerm<span class="hljs-variable">*color4</span> : _color4
XTerm<span class="hljs-variable">*color5</span> : _color5
XTerm<span class="hljs-variable">*color6</span> : _color6
XTerm<span class="hljs-variable">*color7</span> : _color7
XTerm<span class="hljs-variable">*color8</span> : _color8
XTerm<span class="hljs-variable">*color9</span> : _color9
XTerm<span class="hljs-variable">*color10</span> : _color1<span class="hljs-number">0</span>
XTerm<span class="hljs-variable">*color11</span> : _color11
XTerm<span class="hljs-variable">*color12</span> : _color12
XTerm<span class="hljs-variable">*color13</span> : _color13
XTerm<span class="hljs-variable">*color14</span> : _color14
XTerm<span class="hljs-variable">*color15</span> : _color15
XTerm<span class="hljs-variable">*colorBD</span> : _colorBD
XTerm<span class="hljs-variable">*colorIT</span> : _colorIT
XTerm<span class="hljs-variable">*colorUL</span> : _colorUL
XTerm<span class="hljs-variable">*foreground</span> : _foreground
XTerm<span class="hljs-variable">*background</span> : _background
XTerm<span class="hljs-variable">*cursorColor</span> : _cursorColor</code></pre><br />
<p>And then source that one-time with <code>xrdb -merge .Xresources</code>. Open up a new xterm, and it should look like this:</p><br />
<p><img src="https://imgur.com/M6PltG8.png" alt="better xterm" title=""></p><br />
<p>This a good default xterm to have with a dark background and light foreground with a better reading font. This is usually good enough. But having a lot of these around, can get confusing at times. So, I decided to colorize them! Random dark BG with a light FG (or other way around if that’s your thing). First, write this script down somewhere (say, <code>~/bin/xtermc.sh</code>):</p><br />
<pre class="prettyprint"><code class="language-[bash] hljs bash"><span class="hljs-shebang">#!/bin/bash
</span>
<span class="hljs-comment"># Foreground </span>
<span class="hljs-comment"># Higher value = lighter color</span>
n=<span class="hljs-number">160</span>
n1=$(( <span class="hljs-number">256</span> - <span class="hljs-variable">$n</span> ))
fg=$( <span class="hljs-built_in">printf</span> <span class="hljs-string">"#%x%x%x\n"</span> $(( <span class="hljs-variable">$RANDOM</span> % <span class="hljs-variable">$n1</span> + <span class="hljs-variable">$n</span> )) \
$(( <span class="hljs-variable">$RANDOM</span> % <span class="hljs-variable">$n1</span> + <span class="hljs-variable">$n</span> )) \
$(( <span class="hljs-variable">$RANDOM</span> % <span class="hljs-variable">$n1</span> + <span class="hljs-variable">$n</span> )) )
<span class="hljs-comment"># Background </span>
<span class="hljs-comment"># Low value = darker color</span>
m=<span class="hljs-number">32</span>
bg=$( <span class="hljs-built_in">printf</span> <span class="hljs-string">"#%x%x%x\n"</span> $(( <span class="hljs-variable">$RANDOM</span> % <span class="hljs-variable">$m</span> + <span class="hljs-number">16</span> )) \
$(( <span class="hljs-variable">$RANDOM</span> % <span class="hljs-variable">$m</span> + <span class="hljs-number">16</span> )) \
$(( <span class="hljs-variable">$RANDOM</span> % <span class="hljs-variable">$m</span> + <span class="hljs-number">16</span> )) )
<span class="hljs-comment"># summon xterm</span>
<span class="hljs-comment"># xterm -fn fixed -fg "$fg" -bg Gray12 &</span>
xterm -fn fixed -fg <span class="hljs-string">"<span class="hljs-variable">$fg</span>"</span> -bg <span class="hljs-string">"<span class="hljs-variable">$bg</span>"</span> &
</code></pre><br />
<p>If you call this, you get nice and pretty terminals. Alias that script in your <code>.baschrc</code> or <code>.cshrc</code> to some command you can call easily, say <em>term</em></p><br />
<pre class="prettyprint"><code class="language-[bash] hljs ruby"><span class="hljs-keyword">alias</span> term <span class="hljs-string">"~/bin/xtermc.sh"</span></code></pre><br />
<p><img src="https://imgur.com/mPlkGKk.png" alt="enter image description here" title=""></p><br />
<p>Edit: <a href="http://robotcantalk.blogspot.com/2016/07/a-much-better-xterm.html"> Part-II: A Much Better xterm</a><br />
</p></div>Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-81197681099950400292015-03-09T23:52:00.000-07:002015-03-09T23:52:57.193-07:00Interfacing the Arduino with an SSD1306 driven OLED Display - part 2<div dir="ltr" style="text-align: left;" trbidi="on"><h1 id="interfacing-the-arduino-with-an-ssd1306-driven-oled-display-part-2">Interfacing the Arduino with an SSD1306 driven OLED Display - part 2</h1><br />
<p><i class="icon-play"><a href="http://robotcantalk.blogspot.in/2015/03/interfacing-arduino-with-ssd1306-driven.html">PART 1</a></i></p><br />
<p>This time around we are going to cover how to use the SSD1306 OLED as a buffered display. The OLED has a resolution of 128x64. If we take a bit to store the state of each pixel (1=bright, 0=dark), we’d end up having to stash 8192 bits in the atmega328’s SRAM. A whopping 1KB of ram used up to buffer the display!</p><br />
<p><i class="icon-code"><a href="https://github.com/SonalPinto/Arduino_SSD1306_OLED/tree/master/oled_test2">SOURCECODE - Arduino Sketch</a></i></p><br />
<p><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjS_QoVavr6FEzbSjWbnMqe3IpT772or8-YD_cqBHkWAaPVOVamuM0ZX1gRFOcKvAPM5kLjflyHgC7Dd8SRZhhOT8ahPnh1PlNlIk9a4mNfO0W0lo89ElMybRAnHbJ3GeTZxsed_ax4r7A/s512/" alt="enter image description here" title="oled_1.jpg"></p><br />
<a name='more'></a><br />
<br />
<h3 id="128x64-display-buffer">128x64 Display Buffer</h3><br />
<p>Define a array to hold the buffer info!</p><br />
<pre class="prettyprint"><code class=" hljs objectivec"><span class="hljs-keyword">static</span> <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">char</span> buffer [<span class="hljs-number">1024</span>] = {
<span class="hljs-comment">// 1024 bytes!, stacked in rows of 16</span>
};</code></pre><br />
<p>First I drew a 128x64 pixel-art to be my splash screen on boot. </p><br />
<p><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitdHHzRvP3stURS9f34pTeboipXVbagf6vkdecJARxVWHOPrKGG1kipVMwO5tYuyFLaxcxgKSVLtS7DoMZTYY0P2ByFnNTRxOjoPRAS89tCGXNW6MYkD5atEhON9Z89zArJZIYcrN6ubc/s300/" alt="enter image description here" title="buffer.bmp"></p><br />
<p>I used this nifty <a href="http://en.radzio.dxp.pl/bitmap_converter/">LCD Converter</a> to convert my bitmap image to byte description that I could copy <em>as-is</em> into my source code.</p><br />
<p><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPAu9qIVdFt7ump4BXa2Ks8yRiS-fUUU1OuxOrbCM7T2anQvfmnarWbdfO7JJ9TAQzYzBmBQn3dy9-ajBiOU65BisnQIeHjaGSU-n2aLuP9HjkoS5mM90K5cYmXmbgT4FdjHGfojswLu8/s600/lcd_assistant.PNG" alt="enter image description here" title="lcd_assistant.PNG"></p><br />
<p>Which will give you something like this: <i class="icon-doc"><a href="https://github.com/SonalPinto/Arduino_SSD1306_OLED/blob/master/oled_test2/buffer.txt">buffer.txt</a></i></p><br />
<p>To actually have it render, we’d need to traverse through the whole buffer array as we transmit them in 16-byte burst transfers. This is small modification of the arduino <code>loop()</code> over what we had in <a href="http://robotcantalk.blogspot.in/2015/03/interfacing-arduino-with-ssd1306-driven.html#loop">Part-1</a> of this tutorial.</p><br />
<pre class="prettyprint"><code class="language-cpp hljs "> <span class="hljs-keyword">for</span>(uint16_t i=<span class="hljs-number">0</span>;i<<span class="hljs-number">1024</span>;i++){
Wire.beginTransmission(OLED_I2C_ADDRESS);
Wire.write(OLED_CONTROL_BYTE_DATA_STREAM);
<span class="hljs-keyword">for</span> (uint8_t x=<span class="hljs-number">0</span>; x<<span class="hljs-number">16</span>; x++) {
Wire.write(buffer[i]);
i++;
}
i--;
Wire.endTransmission();
}</code></pre><br />
<h3 id="fps-frames-per-second">FPS: Frames Per Second</h3><br />
<p>To maintain an FPS, we’d only want the screen to be refreshed ever so often, which gives us room to do other things (like figure out all the fun stuff that needs to go on the display). 40ms or 25FPS is a pretty good target for an Arduino Uno to drive. All you’d have to do is control when to initiate the whole display buffer transfer.</p><br />
<pre class="prettyprint"><code class="language-cpp hljs "><span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> frame;
<span class="hljs-keyword">void</span> loop() {
<span class="hljs-comment">// Collect the current time. </span>
<span class="hljs-comment">// This is to ensure maximum frame time will be 40ms</span>
frame=millis();
<span class="hljs-comment">// TRANSFER THE DISPLAY</span>
<span class="hljs-comment">// Frame Guard. Ensure that the frame lasted at least 40ms</span>
<span class="hljs-keyword">while</span>((millis()-frame)<<span class="hljs-number">40</span>){};
}</code></pre><br />
<p>But, to even achieve that framerate, you’d need to boost the I2C clock to run at Fast-Mode (400KHz). This is done by setting the <code>TWBR</code> (Two-Wire Bit Rate) register to “12”. Note that by default, the Arduino I2C clock runs at 100KHz (~100kbps). Transferring 8192 bits at normal rate would only give you 9FPS (I checked) . Hence, I modded the <code>OLED_init()</code> function to rev the I2C clock into Fast-Mode (which will give you ~26FPS).</p><br />
<p><i class="icon-doc">Read more on the <a href="http://playground.arduino.cc/Main/WireLibraryDetailedReference">Wire Library</a> and Two Wire Interface registers</i></p><br />
<pre class="prettyprint"><code class="language-cpp hljs "><span class="hljs-keyword">void</span> OLED_init() {
<span class="hljs-comment">// Init the I2C interface (pins A4 and A5 on the Arduino Uno board) in Master Mode.</span>
Wire.begin();
<span class="hljs-comment">// Set the I2C to FM mode - 400KHz!</span>
<span class="hljs-comment">// TWBR = (CPU_CLK / I2C_CLK) -16 /2</span>
<span class="hljs-comment">// TWBR = ((16,000,000 / 400,000) - 16) / 2 = 12</span>
TWBR=<span class="hljs-number">12</span>;
<span class="hljs-comment">// oled initialization...</span>
<span class="hljs-comment">// End the I2C comm with the SSD1306</span>
Wire.endTransmission();
}
</code></pre><br />
<p><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAcdia3xahUChZobUye0LGTSORShG0XWftXcBZNzYchIR7bFrHMfhRRruJOqKADdyvtpy8X3SrhqpQ2OmU3sKDKASTdLat-bcEBkO5HqGJxmyiJQar1KSEi9lf8TKUezaE7kNPQud1wTQ/s512/" alt="enter image description here" title="oled_2.jpg"></p><br />
<p><i class="icon-play"><a href="http://robotcantalk.blogspot.in/2015/03/interfacing-arduino-with-ssd1306-driven.html">PART 1</a></i></p></div>Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com1tag:blogger.com,1999:blog-5309295576532710519.post-67088935586325182372015-03-04T10:12:00.000-08:002015-03-09T23:54:41.376-07:00Interfacing the Arduino with an SSD1306 driven OLED Display - part 1<div dir="ltr" style="text-align: left;" trbidi="on"><h1 id="interfacing-the-arduino-with-an-ssd1306-driven-oled-display-part-1">Interfacing the Arduino with an SSD1306 driven OLED Display - part 1</h1><br />
<p>Who doesn’t want a spiffy display for their Arduino!? An tiny OLED screen will let you do just that. I decided to get myself a display module for a intriguing project that I have in mind - emulating the <a href="http://en.wikipedia.org/wiki/CHIP-8">CHIP-8</a> system on an Arduino Uno (atmega328). I decided to start by building the display interface.</p><br />
<p><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm-VCxIiiPvuaQLK5ye6MsgUlCiP5F5vuOF49S5MrhKoQKwcKAN6W3klfNqJsPKAuGrQ9WL8CqTmzLWzU6huqpJ25bL4w-1IuMYMsYkOOLfJhjcHLfDOxEir1zbZixvT99pvj6Yi1kocQ/s500/" alt="enter image description here" title="oled_module.jpeg"></p><br />
<a name='more'></a><br />
<br />
<p>Browsing around the web, I figured that this - <a href="http://www.adafruit.com/product/326">Adafruit Monochrome 0.96” 128x64 OLED graphic display</a> - fits the bill just right, aesthetically and technologically. The CHIP-8 has a resolution of 64x32, while it’s successor, the SCHIP-8 (Super Chip-8) has a resolution of 128x64.</p><br />
<p><div class="toc"><ul><li><a href="#interfacing-the-arduino-with-an-ssd1306-driven-oled-display-part-1">Interfacing the Arduino with an SSD1306 driven OLED Display - part 1</a><ul><li><ul><li><a href="#purchasing-the-part">Purchasing the part</a></li>
<li><a href="#first-impressions">First Impressions</a></li>
<li><a href="#shortcut">Shortcut</a></li>
<li><a href="#parsing-the-dreadful-datasheet">Parsing the dreadful datasheet</a><ul><li><a href="#i2c-communication">I2C Communication</a></li>
<li><a href="#gddram-graphic-display-data-ram">GDDRAM - Graphic Display Data RAM</a></li>
<li><a href="#minimal-command-reference">Minimal Command Reference</a></li>
</ul></li>
<li><a href="#arduino-sketch">Arduino Sketch</a><ul><li><a href="#setup">setup</a></li>
<li><a href="#loop">loop</a></li>
</ul></li>
</ul></li>
</ul></li>
</ul></div></p><br />
<br />
<br />
<h3 id="purchasing-the-part">Purchasing the part</h3><br />
<p>As usual, I couldn’t find the original product among my trusted distributors in India (sigh…), at least without shoveling out tons of money for import costs - which defeats the point of an Arduino project. But! I did find a neat alternative at <a href="http://www.simplelabs.co.in/">simplelabs.com</a> (same place where I got my <a href="http://www.simplelabs.co.in/content/induino-r3-low-cost-arduino-r3-usb-clone-board">Induino</a>, a perfect low cost and feature rich Arduino Uno Rev3 Clone).</p><br />
<p><i class="icon-basket"><a href="http://www.simplelabs.co.in/content/96-blue-i2c-oled-module">simplelabs 0.96” Blue I2C OLED Display Module</a> </i></p><br />
<p><i class="icon-pin">Bonus part -</i> <a href="http://www.simplelabs.co.in/content/prototyping-shield-for-arduino-with-mini-breadboard">simplelabs Arduino Protyping Shield</a> - not really required, but kinda helps keep things neat.</p><br />
<br />
<br />
<h3 id="first-impressions">First Impressions</h3><br />
<p><code>OLED vs penny</code> <br><br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW-QQlLGfJRAMDhsKpQislOw7RwYHsqZtHBiuqaxemN-Rol321QTYAlKrYreVBBeWPWa0GsrlZ6avHAQ1CwLQw7fDBer8TENXArTMTKtIIPmiT8NwrgTw_qDXznECB1WSQxAIw5CV93M8/s300/" alt="enter image description here" title="oled_size.jpg"></p><br />
<p><code>OLED front</code> <br><br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijwVro59wFhrulTapXKcWkjti9Ltfhwrkx01uMRC7-mKoGleC_Xkb9QDxWChmUrLTXpP3f3KjK1pyO7KS7Xwe-QGrm-ZgCYf-aJcnnRpaVtv2YC0QMo6o2JchkHaYrJmj08ITOdybSDOo/s400/" alt="OLED front" title="front"></p><br />
<p><code>OLED Back</code> <br><br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-CQY12DLMonRlZkoXHNp69amhjwFf537wgckiSy65zn47zkMzoE-nYhpzUBeSwt9e6yB-5AWum0hwkpnv5XZyBx4q9VuKz_zPM8JnDUEqtipYv_2ukzBTDA7Du6_pQqO0MI4tl7Hssyo/s400/" alt="OLED back" title="back"></p><br />
<p>Looking at the backside of the PCB it seems that this part is the same as this - <a href="http://heltec.diytrade.com/sdp/2044581/4/pd-6785993/11659284-0/0_96_inch_blue_OLED_display_module_supply_arduino.html">heltec 0.96 inch blue OLED</a>. Another glaring fact is that this heltec OLED, though sporting the same controller, the <code>SSD1306</code>, only allows you to only interface with it via the I2C (TWI - Two Wire Inteface). That would be the SDA and SCL - which would take only 2 pins from the Arduino (A4 and A5).</p><br />
<p>Secondly, there’s no pin header for the Reset pin. The original Adafruit part has 8 pins with support for both 3-wire and 4-wire SPI along with I2C - and - a reset pin. Oh well… that’s that.</p><br />
<br />
<br />
<h3 id="shortcut">Shortcut</h3><br />
<p>The heltec OLED module (henceforth, simply called, the OLED <i class="icon-smile"></i>) will work right off the bat with these libraries - <a href="https://github.com/adafruit/Adafruit_SSD1306">Adafruit_SSD1306</a> and <a href="https://github.com/adafruit/Adafruit-GFX-Library">Adafruit-GFX</a>. Install them both (ie: unzip them and place them in your user libraries folder) and run the example sketch - <code>ssd1306_128x64_i2c.ino</code>. You’ll need to modify this line (line#61):</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs sql">display.<span class="hljs-operator"><span class="hljs-keyword">begin</span>(SSD1306_SWITCHCAPVCC, <span class="hljs-number">0x3D</span>);</span></code></pre><br />
<p>to </p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs sql">display.<span class="hljs-operator"><span class="hljs-keyword">begin</span>(SSD1306_SWITCHCAPVCC, <span class="hljs-number">0x3C</span>);</span></code></pre><br />
<p>The I2C slave address is 0x3C, as the OLED address select jumpers have been soldered to 0x78 (I’ll explain this part later).</p><br />
<p>The library is neat. But, I am masochistic when it comes to microcontrollers and I want to have optimal control and fully understand what I am doing. Plus, this project (the CHIP-8) will require a tight leash on execution speed and code length. Hence, I had no choice but to take the hard road…</p><br />
<br />
<br />
<h3 id="parsing-the-dreadful-datasheet">Parsing the dreadful datasheet</h3><br />
<p><i class="icon-doc">Datasheet - <a href="http://www.adafruit.com/datasheets/SSD1306.pdf">SSD1306 OLED Controller</a></i></p><br />
<p>The datasheet says the the RES should be a 3us low pulse (pg.49). I wonder if there’s an auto-reset circuit - for this case, RESET low (IC is reset with a low pulse) - it should be a capacitor to GND and a pullup resistor to VDD. It’s probably there (looking at the components) - but, I can’t really tell - as the heltec website doesn’t provide any info.</p><br />
<p>Okay… okay… let’s take it from the top. </p><br />
<br />
<br />
<h4 id="i2c-communication">I2C Communication</h4><br />
<p>The SSD1306 is a 128x64 Dot Matrix Driver/Controller manufactured by Solomon Systech (based in HK). The sheet says that the VDD for the IC is supposed to be 3.3V max - but the OLED module will work with a 5V as well because there seems to be a levelshifter (<a href="http://www.aliexpress.com/store/product/10pcs-XC6206P332MR-662K-3-3V-0-5A-Positive-Fixed-LDO-Voltage-Regulator-SOT-23/708669_610198839.html">3-pin LDO with 662K</a> inscribed) on board. Since, the OLED only has an I2C interface, I shall focus on those specs, which begin on pg.19.</p><br />
<p><code>I2C Bus Data Format</code> <br><br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQoH_hUTmkm6Tp1TM3R9x79-Q_nCcetReJOExjlEXP_wHvQ76QGII_BYhu2O1u86JhF1T1I_4Rza57gOfOVBoeRr6xNvAKBrKGZ5Ad0pR5jyzgfotp0ZjQ-KZxrOkE74aI83DQc_orI78/s700/i2c_bus_data_format.PNG" alt="i2c_bus" title="i2c_bus_data_format.PNG"></p><br />
<p>Write Mode - is the only mode I care about. So, the Arduino is going to be the I2C master and the OLED, the I2C slave. As per the protocol, after the start condition, the Slave Address (SLA) needs to be sent.</p><br />
<dl><dt>SSD1306 Slave Adress (SLA) is 0x3C</dt>
<dd>The back of the PCB shows that the 0x78 jumper has been soldered. The sheet says that the slave adress is a 7-bit code that can be either 0x3C (011-1100) or 0x3D (011-11001), based on the SAO bit (LSB of the adress). The SAO bit can be controlled by the D/C# pin of the SSD1306 (not to be confused with the D/C# bit of the control byte in the above image!). I guess, heltec must have soldered the pin to GND. Moreover, since, the OLED will always be interfaced in WRITE mode, the <code>I2C First Byte</code> will be the 7-bit SLA and the WRITE mode bit (0) - which becomes the byte, 0x78. Ha!</dd>
</dl><br />
<p>After sending the SLA+Mode byte, in order to do anything with the OLED, a <code>Control Byte</code> needs to be sent. The Control Byte determines whether the upcoming bytes would be treated as Data (which is written directly to the GDDRAM) or as Commands (to the internal MCU). Also controls the length of the upcoming bytes - single or stream (multiple bytes to received by the SSD1306 until I2C Stop condition).</p><br />
<dl><dt>Control Byte</dt>
<dd>Deciphering this took some trial and error and real sloooooow reading of section 8.1.5.2 (Writing mode for I2C) point 5. The Control Byte has these <br>
<code>Co</code> : bit 8 : Continuation Bit <br>
* <strong>1</strong> = no-continuation (only one byte to follow) <br>
* <strong>0</strong> = the controller should expect a stream of bytes. <br>
<code>D/C#</code> : bit 7 : Data/Command Select bit <br>
* <strong>1</strong> = the next byte or byte stream will be Data. <br>
* <strong>0</strong> = a Command byte or byte stream will be coming up next. <br>
Bits 6-0 will be all zeros. <br>
<strong>Usage:</strong> <br>
<code>0x80</code> : Single Command byte <br>
<code>0x00</code> : Command Stream <br>
<code>0xC0</code> : Single Data byte <br>
<code>0x40</code> : Data Stream</dd>
</dl><br />
<br />
<br />
<h4 id="gddram-graphic-display-data-ram">GDDRAM - Graphic Display Data RAM</h4><br />
<p>OLED has an 128x64 SRAM driven display with 64 rows divided as 8 Pages and 128 Columns.</p><br />
<p><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglwTGRvlNNOZvpPR-9cfpczEBguAxtMSiiTTm8FM3OiH5d8j2Gc2KbcGrXmGt9ATnG81Ie2Xs9QkVifIvoV-4jNxmetGcz2gINS0vWpeSWbTVZfxqX7ZF6sdANP81rY_vxqLnVBh5M-Pg/s600/gddram_page_map.PNG" alt="gddram" title="gddram_page_map.PNG"></p><br />
<p>Each <code>PAGE</code> will have 8 rows (COM pins) and 128 byte-sized column fractions called <code>SEGMENT</code>. The whole mapping is fully customizable, ie: You can rearrange the COM/COL assignment to have the xy(0,0) at any corner. The GDDRAM is divided into Pages to allow easy writing of character sized sprites. That means you can also use this OLED as a 8-line character display by default.</p><br />
<p><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiu-ksQbzbHoiEEAv492pUUM-ZZhsaJhLlLQTYSEPIRXkN1n2fe12E5cUaIHNhZGydniu6uMR-_Izqpd8vTmhseXb7QPUD3Ams1vSPOG5-Xd8kPBw4psANKE9hkZfL_DRj9g48c9v-kQqA/s600/gddram_single_page.PNG" alt="page" title="gddram_single_page.PNG"></p><br />
<p>But, I wanna use this as a generic buffered dispaly. Hence, among the three memory addressing modes (pg.34-35), Horizonal seemed to be perfect for me. Starting from (PAGE0,COL0), the address line will auto-shift to the next segment after each data byte write, and will shift to the next page when all 128 segments of a page are written onto. Kinda exactly like the KS108 based graphic LCD, without the need to select the segment driver.</p><br />
<p><code>Horizontal Addressing Mode</code> <br><br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-PgzMohD8_NWeMTHmoiU6bcMw5DI82EV3L7861X1EqOQU4huy55imUvsZo9s6imnoBB-hI2MuZNtMlFh7Um76vkJUlaGpTD-zONaGYWSJgLWAQhEYZBwNLSuy0Ig7doK3EXyy_vC36qM/s600/horz_adressing_mode.PNG" alt="horz_addr_mode" title="horz_adressing_mode.PNG"></p><br />
<br />
<br />
<h4 id="minimal-command-reference">Minimal Command Reference</h4><br />
<p>I parsed section 9 (pg28-32 and pg62) of the sheet to collect these commands that would be most pertinent to interface with the OLED as a generic buffered display.</p><br />
<br />
<br />
<pre class="prettyprint"><code class="language-cpp hljs "><span class="hljs-comment">// SLA (0x3C) + WRITE_MODE (0x00) = 0x78 (0b01111000)</span>
<span class="hljs-preprocessor">#define OLED_I2C_ADDRESS 0x3C</span>
<span class="hljs-comment">// Control byte</span>
<span class="hljs-preprocessor">#define OLED_CONTROL_BYTE_CMD_SINGLE 0x80</span>
<span class="hljs-preprocessor">#define OLED_CONTROL_BYTE_CMD_STREAM 0x00</span>
<span class="hljs-preprocessor">#define OLED_CONTROL_BYTE_DATA_STREAM 0x40</span>
<span class="hljs-comment">// Fundamental commands (pg.28)</span>
<span class="hljs-preprocessor">#define OLED_CMD_SET_CONTRAST 0x81 <span class="hljs-comment">// follow with 0x7F</span></span>
<span class="hljs-preprocessor">#define OLED_CMD_DISPLAY_RAM 0xA4</span>
<span class="hljs-preprocessor">#define OLED_CMD_DISPLAY_ALLON 0xA5</span>
<span class="hljs-preprocessor">#define OLED_CMD_DISPLAY_NORMAL 0xA6</span>
<span class="hljs-preprocessor">#define OLED_CMD_DISPLAY_INVERTED 0xA7</span>
<span class="hljs-preprocessor">#define OLED_CMD_DISPLAY_OFF 0xAE</span>
<span class="hljs-preprocessor">#define OLED_CMD_DISPLAY_ON 0xAF</span>
<span class="hljs-comment">// Addressing Command Table (pg.30)</span>
<span class="hljs-preprocessor">#define OLED_CMD_SET_MEMORY_ADDR_MODE 0x20 <span class="hljs-comment">// follow with 0x00 = HORZ mode = Behave like a KS108 graphic LCD</span></span>
<span class="hljs-preprocessor">#define OLED_CMD_SET_COLUMN_RANGE 0x21 <span class="hljs-comment">// can be used only in HORZ/VERT mode - follow with 0x00 and 0x7F = COL127</span></span>
<span class="hljs-preprocessor">#define OLED_CMD_SET_PAGE_RANGE 0x22 <span class="hljs-comment">// can be used only in HORZ/VERT mode - follow with 0x00 and 0x07 = PAGE7</span></span>
<span class="hljs-comment">// Hardware Config (pg.31)</span>
<span class="hljs-preprocessor">#define OLED_CMD_SET_DISPLAY_START_LINE 0x40</span>
<span class="hljs-preprocessor">#define OLED_CMD_SET_SEGMENT_REMAP 0xA1 </span>
<span class="hljs-preprocessor">#define OLED_CMD_SET_MUX_RATIO 0xA8 <span class="hljs-comment">// follow with 0x3F = 64 MUX</span></span>
<span class="hljs-preprocessor">#define OLED_CMD_SET_COM_SCAN_MODE 0xC8 </span>
<span class="hljs-preprocessor">#define OLED_CMD_SET_DISPLAY_OFFSET 0xD3 <span class="hljs-comment">// follow with 0x00</span></span>
<span class="hljs-preprocessor">#define OLED_CMD_SET_COM_PIN_MAP 0xDA <span class="hljs-comment">// follow with 0x12</span></span>
<span class="hljs-preprocessor">#define OLED_CMD_NOP 0xE3 <span class="hljs-comment">// NOP</span></span>
<span class="hljs-comment">// Timing and Driving Scheme (pg.32)</span>
<span class="hljs-preprocessor">#define OLED_CMD_SET_DISPLAY_CLK_DIV 0xD5 <span class="hljs-comment">// follow with 0x80</span></span>
<span class="hljs-preprocessor">#define OLED_CMD_SET_PRECHARGE 0xD9 <span class="hljs-comment">// follow with 0xF1</span></span>
<span class="hljs-preprocessor">#define OLED_CMD_SET_VCOMH_DESELCT 0xDB <span class="hljs-comment">// follow with 0x30</span></span>
<span class="hljs-comment">// Charge Pump (pg.62)</span>
<span class="hljs-preprocessor">#define OLED_CMD_SET_CHARGE_PUMP 0x8D <span class="hljs-comment">// follow with 0x14</span></span>
</code></pre><br />
<br />
<br />
<h3 id="arduino-sketch">Arduino Sketch</h3><br />
<p><i class="icon-code">SOURCE: </i> <a href="https://github.com/SonalPinto/Arduino_SSD1306_OLED">oled_test</a></p><br />
<p>The <a href="https://github.com/SonalPinto/Arduino_SSD1306_OLED/tree/master/oled_test">oled_test</a> sketch is flash-ready for the Arduino plugged to a SSD1306 OLED over I2C - and - it’s well commented <i class="icon-smile"></i>.</p><br />
<dl><dt>Connections</dt>
<dd>Arduino <code>A4</code> to OLED <code>SDA</code></dd>
<dd>Arduino <code>A5</code> to OLED <code>SCL</code></dd>
</dl><br />
<p>The I2C control of the OLED is pretty simple. To send a command to the OLED, you’d need to transmit a Command Control Byte first, and similarly to write to the GDDRAM, you’d need to transmit a Data Control Byte.</p><br />
<br />
<br />
<div class="flow-chart"><svg height="961.359375" version="1.1" width="580.26171875" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="overflow: hidden; position: relative; top: -0.5625px;"><desc style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Created with Raphaël 2.1.2</desc><defs style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><marker id="raphael-marker-endblock33-obj28" markerHeight="3" markerWidth="3" orient="auto" refX="1.5" refY="1.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 1.5 1.5) scale(0.6,0.6)" stroke-width="1.6667" fill="black" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock33-obj29" markerHeight="3" markerWidth="3" orient="auto" refX="1.5" refY="1.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 1.5 1.5) scale(0.6,0.6)" stroke-width="1.6667" fill="black" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock33-obj31" markerHeight="3" markerWidth="3" orient="auto" refX="1.5" refY="1.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 1.5 1.5) scale(0.6,0.6)" stroke-width="1.6667" fill="black" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock33-obj33" markerHeight="3" markerWidth="3" orient="auto" refX="1.5" refY="1.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 1.5 1.5) scale(0.6,0.6)" stroke-width="1.6667" fill="black" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock33-obj34" markerHeight="3" markerWidth="3" orient="auto" refX="1.5" refY="1.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 1.5 1.5) scale(0.6,0.6)" stroke-width="1.6667" fill="black" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock33-obj35" markerHeight="3" markerWidth="3" orient="auto" refX="1.5" refY="1.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 1.5 1.5) scale(0.6,0.6)" stroke-width="1.6667" fill="black" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock33-obj36" markerHeight="3" markerWidth="3" orient="auto" refX="1.5" refY="1.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 1.5 1.5) scale(0.6,0.6)" stroke-width="1.6667" fill="black" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock33-obj37" markerHeight="3" markerWidth="3" orient="auto" refX="1.5" refY="1.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 1.5 1.5) scale(0.6,0.6)" stroke-width="1.6667" fill="black" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock33-obj38" markerHeight="3" markerWidth="3" orient="auto" refX="1.5" refY="1.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 1.5 1.5) scale(0.6,0.6)" stroke-width="1.6667" fill="black" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock33-obj39" markerHeight="3" markerWidth="3" orient="auto" refX="1.5" refY="1.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 1.5 1.5) scale(0.6,0.6)" stroke-width="1.6667" fill="black" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock33-obj40" markerHeight="3" markerWidth="3" orient="auto" refX="1.5" refY="1.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 1.5 1.5) scale(0.6,0.6)" stroke-width="1.6667" fill="black" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker></defs><rect x="0" y="0" width="277.046875" height="39" rx="20" ry="20" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" stroke-width="2" class="flowchart" id="st" transform="matrix(1,0,0,1,4,33.4844)"></rect><text x="10" y="19.5" text-anchor="start" font-family="sans-serif" font-size="14px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-family: sans-serif; font-size: 14px; font-weight: normal;" id="stt" class="flowchartt" font-weight="normal" transform="matrix(1,0,0,1,4,33.4844)"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">beginTransmission(OLED_I2C_ADDRESS)</tspan></text><path fill="#ffffff" stroke="#000000" d="M48.984375,24.4921875L0,48.984375L97.96875,97.96875L195.9375,48.984375L97.96875,0L0,48.984375" stroke-width="2" font-family="sans-serif" font-weight="normal" id="cond" class="flowchart" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;" transform="matrix(1,0,0,1,44.5547,126.4844)"></path><text x="53.984375" y="48.984375" text-anchor="start" font-family="sans-serif" font-size="14px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-family: sans-serif; font-size: 14px; font-weight: normal;" id="condt" class="flowchartt" font-weight="normal" transform="matrix(1,0,0,1,44.5547,126.4844)"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">DATA(1)/CMD(0)</tspan></text><rect x="0" y="0" width="221.96875" height="39" rx="0" ry="0" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" stroke-width="2" class="flowchart" id="ctrl_data" transform="matrix(1,0,0,1,31.5391,307.9375)"></rect><text x="10" y="19.5" text-anchor="start" font-family="sans-serif" font-size="14px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-family: sans-serif; font-size: 14px; font-weight: normal;" id="ctrl_datat" class="flowchartt" font-weight="normal" transform="matrix(1,0,0,1,31.5391,307.9375)"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">CONTROL_BYTE_DATA_STREAM</tspan></text><rect x="0" y="0" width="119.0625" height="39" rx="0" ry="0" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" stroke-width="2" class="flowchart" id="cd_s1" transform="matrix(1,0,0,1,82.9922,430.4219)"></rect><rect x="10" y="0" width="99.0625" height="39" rx="0" ry="0" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;" stroke-width="2" id="cd_s1i" font-family="sans-serif" font-weight="normal" transform="matrix(1,0,0,1,82.9922,430.4219)"></rect><text x="20" y="19.5" text-anchor="start" font-family="sans-serif" font-size="14px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-family: sans-serif; font-size: 14px; font-weight: normal;" id="cd_s1t" class="flowchartt" font-weight="normal" transform="matrix(1,0,0,1,82.9922,430.4219)"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">data_byte_1</tspan></text><rect x="0" y="0" width="119.0625" height="39" rx="0" ry="0" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" stroke-width="2" class="flowchart" id="cd_s2" transform="matrix(1,0,0,1,82.9922,552.9063)"></rect><rect x="10" y="0" width="99.0625" height="39" rx="0" ry="0" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;" stroke-width="2" id="cd_s2i" font-family="sans-serif" font-weight="normal" transform="matrix(1,0,0,1,82.9922,552.9063)"></rect><text x="20" y="19.5" text-anchor="start" font-family="sans-serif" font-size="14px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-family: sans-serif; font-size: 14px; font-weight: normal;" id="cd_s2t" class="flowchartt" font-weight="normal" transform="matrix(1,0,0,1,82.9922,552.9063)"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">data_byte_2</tspan></text><rect x="0" y="0" width="119.0625" height="39" rx="0" ry="0" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" stroke-width="2" class="flowchart" id="cd_s3" transform="matrix(1,0,0,1,82.9922,675.3906)"></rect><rect x="10" y="0" width="99.0625" height="39" rx="0" ry="0" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;" stroke-width="2" id="cd_s3i" font-family="sans-serif" font-weight="normal" transform="matrix(1,0,0,1,82.9922,675.3906)"></rect><text x="20" y="19.5" text-anchor="start" font-family="sans-serif" font-size="14px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-family: sans-serif; font-size: 14px; font-weight: normal;" id="cd_s3t" class="flowchartt" font-weight="normal" transform="matrix(1,0,0,1,82.9922,675.3906)"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">data_byte_3</tspan></text><rect x="0" y="0" width="119.0625" height="39" rx="0" ry="0" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" stroke-width="2" class="flowchart" id="cd_s4" transform="matrix(1,0,0,1,82.9922,797.875)"></rect><rect x="10" y="0" width="99.0625" height="39" rx="0" ry="0" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;" stroke-width="2" id="cd_s4i" font-family="sans-serif" font-weight="normal" transform="matrix(1,0,0,1,82.9922,797.875)"></rect><text x="20" y="19.5" text-anchor="start" font-family="sans-serif" font-size="14px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-family: sans-serif; font-size: 14px; font-weight: normal;" id="cd_s4t" class="flowchartt" font-weight="normal" transform="matrix(1,0,0,1,82.9922,797.875)"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">data_byte_4</tspan></text><rect x="0" y="0" width="128.109375" height="39" rx="20" ry="20" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" stroke-width="2" class="flowchart" id="e" transform="matrix(1,0,0,1,78.4688,920.3594)"></rect><text x="10" y="19.5" text-anchor="start" font-family="sans-serif" font-size="14px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-family: sans-serif; font-size: 14px; font-weight: normal;" id="et" class="flowchartt" font-weight="normal" transform="matrix(1,0,0,1,78.4688,920.3594)"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">endTransmission</tspan><tspan dy="18" x="10" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></tspan></text><rect x="0" y="0" width="217.078125" height="39" rx="0" ry="0" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" stroke-width="2" class="flowchart" id="ctrl_cmd" transform="matrix(1,0,0,1,324.4766,155.9688)"></rect><text x="10" y="19.5" text-anchor="start" font-family="sans-serif" font-size="14px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-family: sans-serif; font-size: 14px; font-weight: normal;" id="ctrl_cmdt" class="flowchartt" font-weight="normal" transform="matrix(1,0,0,1,324.4766,155.9688)"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">CONTROL_BYTE_CMD_STREAM</tspan></text><rect x="0" y="0" width="117.90625" height="39" rx="0" ry="0" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" stroke-width="2" class="flowchart" id="cc_s1" transform="matrix(1,0,0,1,374.0625,278.4531)"></rect><rect x="10" y="0" width="97.90625" height="39" rx="0" ry="0" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;" stroke-width="2" id="cc_s1i" font-family="sans-serif" font-weight="normal" transform="matrix(1,0,0,1,374.0625,278.4531)"></rect><text x="20" y="19.5" text-anchor="start" font-family="sans-serif" font-size="14px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-family: sans-serif; font-size: 14px; font-weight: normal;" id="cc_s1t" class="flowchartt" font-weight="normal" transform="matrix(1,0,0,1,374.0625,278.4531)"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">cmd_byte_1</tspan></text><rect x="0" y="0" width="117.90625" height="39" rx="0" ry="0" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" stroke-width="2" class="flowchart" id="cc_s2" transform="matrix(1,0,0,1,374.0625,400.9375)"></rect><rect x="10" y="0" width="97.90625" height="39" rx="0" ry="0" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;" stroke-width="2" id="cc_s2i" font-family="sans-serif" font-weight="normal" transform="matrix(1,0,0,1,374.0625,400.9375)"></rect><text x="20" y="19.5" text-anchor="start" font-family="sans-serif" font-size="14px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-family: sans-serif; font-size: 14px; font-weight: normal;" id="cc_s2t" class="flowchartt" font-weight="normal" transform="matrix(1,0,0,1,374.0625,400.9375)"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">cmd_byte_2</tspan></text><path fill="none" stroke="#000000" d="M142.5234375,72.484375C142.5234375,72.484375,142.5234375,112.13847494125366,142.5234375,123.48481408460066" stroke-width="2" marker-end="url(#raphael-marker-endblock33-obj28)" font-family="sans-serif" font-weight="normal" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path fill="none" stroke="#000000" d="M142.5234375,224.453125C142.5234375,224.453125,142.5234375,290.0221241079271,142.5234375,304.94163269400815" stroke-width="2" marker-end="url(#raphael-marker-endblock33-obj29)" font-family="sans-serif" font-weight="normal" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><text x="147.5234375" y="234.453125" text-anchor="start" font-family="sans-serif" font-size="14px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-family: sans-serif; font-size: 14px; font-weight: normal;" font-weight="normal"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">yes</tspan></text><path fill="none" stroke="#000000" d="M240.4921875,175.46875C240.4921875,175.46875,306.4902363708243,175.46875,321.4751449279206,175.46875" stroke-width="2" marker-end="url(#raphael-marker-endblock33-obj31)" font-family="sans-serif" font-weight="normal" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><text x="245.4921875" y="165.46875" text-anchor="start" font-family="sans-serif" font-size="14px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-family: sans-serif; font-size: 14px; font-weight: normal;" font-weight="normal"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">no</tspan></text><path fill="none" stroke="#000000" d="M142.5234375,346.9375C142.5234375,346.9375,142.5234375,412.5064991079271,142.5234375,427.42600769400815" stroke-width="2" marker-end="url(#raphael-marker-endblock33-obj33)" font-family="sans-serif" font-weight="normal" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path fill="none" stroke="#000000" d="M142.5234375,469.421875C142.5234375,469.421875,142.5234375,534.9908741079271,142.5234375,549.9103826940081" stroke-width="2" marker-end="url(#raphael-marker-endblock33-obj34)" font-family="sans-serif" font-weight="normal" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path fill="none" stroke="#000000" d="M142.5234375,591.90625C142.5234375,591.90625,142.5234375,657.4752491079271,142.5234375,672.3947576940081" stroke-width="2" marker-end="url(#raphael-marker-endblock33-obj35)" font-family="sans-serif" font-weight="normal" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path fill="none" stroke="#000000" d="M142.5234375,714.390625C142.5234375,714.390625,142.5234375,779.9596241079271,142.5234375,794.8791326940081" stroke-width="2" marker-end="url(#raphael-marker-endblock33-obj36)" font-family="sans-serif" font-weight="normal" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path fill="none" stroke="#000000" d="M142.5234375,836.875C142.5234375,836.875,142.5234375,902.4439991079271,142.5234375,917.3635076940081" stroke-width="2" marker-end="url(#raphael-marker-endblock33-obj37)" font-family="sans-serif" font-weight="normal" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path fill="none" stroke="#000000" d="M433.015625,194.96875C433.015625,194.96875,433.015625,260.5377491079271,433.015625,275.45725769400815" stroke-width="2" marker-end="url(#raphael-marker-endblock33-obj38)" font-family="sans-serif" font-weight="normal" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path fill="none" stroke="#000000" d="M433.015625,317.453125C433.015625,317.453125,433.015625,383.0221241079271,433.015625,397.94163269400815" stroke-width="2" marker-end="url(#raphael-marker-endblock33-obj39)" font-family="sans-serif" font-weight="normal" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path fill="none" stroke="#000000" d="M433.015625,439.9375C433.015625,439.9375,433.015625,895.359375,433.015625,895.359375C433.015625,895.359375,142.5234375,895.359375,142.5234375,895.359375C142.5234375,895.359375,142.5234375,910.7328195571899,142.5234375,917.3686227742583" stroke-width="2" marker-end="url(#raphael-marker-endblock33-obj40)" font-family="sans-serif" font-weight="normal" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path></svg></div><br />
<br />
<br />
<h4 id="setup">setup</h4><br />
<p>The entire I2C comm is handled by the <a href="http://playground.arduino.cc/Main/WireLibraryDetailedReference">Arduino Wire library</a> and is easy is setup. The <code>OLED_init()</code> function follows the software config instructions detailed on pg.64 of the datasheet. The various command bytes are sent over as a stream. Most of the values are set as the default <code>RESET</code> state values as described in the Command Table (Section 9 in the sheet). The addressing mode is set to <code>Horizontal</code>.</p><br />
<p><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1CerIjR6VGL5HYus3DwyFuLMEs68PLmT4kyYWyXVTQxdBRDuVKhwx6mHckFTXs0Nb7zg3VjYOoLmZCFJOedQ0xtUBHMDi91O4h5jMEDvUAp06Z3tLAiw9GIyaroy-VPsNms0fGZrd7RM/s600/oled_setup.PNG" alt="enter image description here" title="oled_setup.PNG"></p><br />
<p>As I had said before, the ROW and COL mapping is completely customizable to any corner. This is described in the Hardware Config table on pg.31 (<code>Set-Segment-Remap</code> and <code>Set-COM-Output-Scan-direction</code>). For example, if the board pins are north, then by setting those two to <code>0xA1</code> and <code>0xC8</code>, you’d have the xy(0,0) at top-right. Whereas, if you place the board such that the pins are south, you’d need to transmit <code>0xA0</code> and <code>0xC0</code> - which is the default setting after a <em>reset</em>.</p><br />
<p><code>board placed with pins facing north</code> <br><br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEmiVnLiy57ln7vNf7GPqVQVHi8tCynExYTmf34xQADxd8981i6Of0voVG5eIEoOjX_Br3Ahqtx2gfozN70yfm9_m3IcyI7Wu-gmj9hx2d_j4OOWXeFL2Ex1dnotAWjI7b8cPTfMzcgio/s300/" alt="enter image description here" title="oled_display_northPin.jpg"></p><br />
<p><code>board placed with pins facing south</code> <br><br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKEc7rhNcFtXeZbbhQxZcUuOOnSAgZYRAOYEE-giyvM85A7M5-6VOjLzolR1Rl31rvnxPoAgySDGtjPi8FFKzqHM3R8yqARtj0oWtbrBc_0wsTWF3r1LoAYQJEghdg_s6m6LXc75CZQ_c/s300/" alt="enter image description here" title="oled_display_southPin.jpg"></p><br />
<br />
<br />
<h4 id="loop">loop</h4><br />
<p>At every <code>frame</code>, I reset the column and page address to the full range, ie: <code>COLUMN</code> from 0 to 127 (0x7F) and <code>PAGE</code> from 0 to 7. This sets the address line at (seg0,page0) - the top-right.</p><br />
<br />
<br />
<pre class="prettyprint"><code class="language-cpp hljs "> Wire.beginTransmission(OLED_I2C_ADDRESS);
Wire.write(OLED_CONTROL_BYTE_CMD_STREAM);
Wire.write(OLED_CMD_SET_COLUMN_RANGE);
Wire.write(<span class="hljs-number">0x00</span>);
Wire.write(<span class="hljs-number">0x7F</span>);
Wire.write(OLED_CMD_SET_PAGE_RANGE);
Wire.write(<span class="hljs-number">0</span>);
Wire.write(<span class="hljs-number">0x07</span>);
Wire.endTransmission();
<span class="hljs-keyword">for</span>(uint16_t i=<span class="hljs-number">0</span>;i<<span class="hljs-number">1024</span>;i++){
Wire.beginTransmission(OLED_I2C_ADDRESS);
Wire.write(OLED_CONTROL_BYTE_DATA_STREAM);
<span class="hljs-keyword">for</span> (uint8_t x=<span class="hljs-number">0</span>; x<<span class="hljs-number">16</span>; x++) {
Wire.write(<span class="hljs-number">0x81</span>);
i++;
}
i--;
Wire.endTransmission();
}</code></pre><br />
<p>128x64 is 8192 bits. If I am to transfer them in terms of bytes, then I would need to send 1024 bytes. In the above loop, this is done in 16 byte burst transfers. In the inner loop, you can set what type of byte you’d want to send over. I have detailed two patterns as well - <code>pattern1</code> and <code>pattern2</code>. Ensure that there’s only one <code>write</code> command in the inner loop.</p><br />
<p><code>Wire.write(0x81)</code> <br><br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJdAw3polnqXFuiiR9fURLoY8V4Is9yXxl3sB95A1pgs5Sn5vL7xkXvafMKlRF1OEFDK27FE3oH0xEyQXKd97bGorokGS5jsdkgvpz0FbTtWfhm-_IZn9K9TS1nL01aNXl6sfl0Udx6gM/s300/oled_pattern_1.jpg" alt="enter image description here" title="oled_pattern_1.jpg"></p><br />
<p><code>Wire.write(pattern1[x])</code> <br><br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoozRISJ6PSape8aTJZxULB6uKuDJ1yliR49ANGBZ0zjcz53gXji9DAOqyPvJvWaaEpYhCVg4LNaL1GHw0A5DGYNaUflWCN9rG5Ds-c3oOria9JVTH1Bknp1f8v16SQuFp05BBa5JjEb0/s300/oled_pattern_2.jpg" alt="enter image description here" title="oled_pattern_2.jpg"></p><br />
<p><code>Wire.write(pattern2[x])</code> <br><br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjL51zTClDcQn25ZeBD9Wnzat3P_Cd5MQNuyCwjHvb058t-_UfyIS-BD6PhwQsnADZnpCU9wJlCNFbQfMPJLQ2qx19xvk5id0AAE6qb3JmBM5DVTfYV4HiZmdUt9wHQdPQ18Nhyphenhyphen9acPhUI/s300/oled_pattern_3.jpg" alt="enter image description here" title="oled_pattern_3.jpg"></p><br />
<p>Cool, huh? But, this simply shows how to interface the SSD1306 OLED to an Arduino. </p><br />
<p>Next up, true implementation of a buffered display on the SSD1306 OLED with higher FPS.</p><br />
<p><i class="icon-play"><a href="http://robotcantalk.blogspot.in/2015/03/interfacing-arduino-with-ssd1306-driven_9.html">PART II - Arduino and SSD1306</a></i></p></div>Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com4tag:blogger.com,1999:blog-5309295576532710519.post-2357013288609548132015-02-21T08:45:00.001-08:002015-03-03T20:20:55.199-08:00DFT on an Arduino - Part 2<div dir="ltr" style="text-align: left;" trbidi="on">
It’s been a year! A year since I was supposed to document my code. Please, hold the applause while I accept the award for <code>Laziest SlacKing</code> for 2014. Sigh … alright, let’s get on with this. I hope I can understand what I had written…<br />
<br />
<a href="http://robotcantalk.blogspot.in/2014/01/dft-on-arduino.html">DFT on an Arduino - Part 1</a><br />
<br />
I am going to continue <strong><em>exactly</em></strong> where I left off.<br />
<br />
<i class="icon-code"> <a href="https://github.com/SonalPinto/arduino_DFT">SOURCE CODE</a></i><br />
<br />
<a name='more'></a><br />
<br />
The <a href="https://github.com/SonalPinto/arduino_DFT/blob/master/dft_C.ino"><code>dft_C.ino</code></a> is the main arduino sketch.<br />
<br />
<br />
<div class="toc">
<ul>
<li><ul>
<li><ul>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#lcd-setup">LCD Setup</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#mic-setup">Mic Setup</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#the-loop">The Loop</a><ul>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#sampling">Sampling</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#dft">DFT</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#render">Render</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<br />
<br />
<br />
<br />
<h3 id="lcd-setup">
LCD Setup</h3>
<br />
The primary display is a <a href="http://www.simplelabs.co.in/content/16x2-character-lcd-black-green-5v">16x2 generic LCD panel</a>. Here’s the Arduino <a href="http://arduino.cc/en/Reference/LiquidCrystal"><code>LiquidCrystal</code></a> library that I’d use to manipulate it. Since, I would require <em>bands</em> to show the strength of the spectrum, I created some custom characters for the LCD controller using <a href="http://arduino.cc/en/Reference/LiquidCrystalCreateChar">createChar</a>. Here are some neat LCD chara creators - <a href="http://mikeyancey.com/hamcalc/lcd_characters.php">link</a>, <a href="http://omerk.github.io/lcdchargen/">link2</a>.<br />
<br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs markdown"><span class="hljs-header">#include <LiquidCrystal.h></span>
// LCD object - and pins it hogs
LiquidCrystal lcd(8,9,10,11,12,13);
// LCD Levels - store in the progmem
prog<span class="hljs-emphasis">_uint8_</span>t lcd_char[<span class="hljs-link_label">8</span>][<span class="hljs-link_reference">8</span>] PROGMEM = {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F},
{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F},
{0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x1F},
{0x00,0x00,0x00,0x00,0x1F,0x1F,0x1F,0x1F},
{0x00,0x00,0x00,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x00,0x00,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x00,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F}
};
// temp var
uint8<span class="hljs-emphasis">_t tlcd_</span>char[8];
void setup() {
<span class="hljs-code"> for(i=0;i<8;i++){</span>
<span class="hljs-code"> for(j=0;j<8;j++){</span>
<span class="hljs-code"> // Extract the chara info from the progmem</span>
<span class="hljs-code"> tlcd_char[j]=pgm_read_byte(&lcd_char[i][j]);</span>
<span class="hljs-code"> }</span>
<span class="hljs-code"> // Shove each custom chara to the LCD controller</span>
<span class="hljs-code"> lcd.createChar(i, tlcd_char);</span>
<span class="hljs-code"> }</span>
}</code></pre>
<br />
<br />
<br />
<h3 id="mic-setup">
Mic Setup</h3>
<br />
I got myself a simple <a href="https://www.mgsuperlabs.co.in/estore/SparkFun-Electret-Microphone-Breakout?search=electret">electret mic</a>. and strapped it to the integrated 10-bit ADC on the atmega328. Since, the inbuilt <a href="http://arduino.cc/en/Reference/analogRead"><code>analogRead</code></a> takes a while, I decided to take direct control of the ADC. Here, <a href="http://garretlab.web.fc2.com/en/arduino/inside/arduino/wiring_analog.c/analogRead.html">read this</a> to know how to do this on your own.<br />
<br />
There are some fancy mic options nowadays : <a href="http://www.simplelabs.co.in/content/arduino-microphone-sound-detection-sensor">link1</a>, <a href="https://www.mgsuperlabs.co.in/estore/Electret-Microphone-Amplifier-MAX9814-with-Auto-Gain-Control?search=electret">link2</a><br />
<br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs cs"><span class="hljs-comment">// On the Induino, I used the A2</span>
<span class="hljs-keyword">byte</span> micPort = <span class="hljs-number">0x02</span>;
<span class="hljs-keyword">void</span> setup() {
<span class="hljs-comment">// Set up ADC</span>
<span class="hljs-comment">// Vref = 5V (REFS1:REFS0 = bit8:7 = 01)</span>
<span class="hljs-comment">// Left Adjust read (ADLAR = bit6 = 1)</span>
<span class="hljs-comment">// Select analog channel (MUX3:0 = bit3:0)</span>
ADMUX = <span class="hljs-number">0</span>b01100000;
ADMUX |= micPort;
ADCSRB = <span class="hljs-number">0</span>;
ADCSRA = <span class="hljs-number">0</span>;
ADCSRA |= <span class="hljs-number">1</span><<ADEN; <span class="hljs-comment">// Enable ADC</span>
ADCSRA |= <span class="hljs-number">1</span><<ADSC; <span class="hljs-comment">// Start ADC</span>
ADCSRA |= <span class="hljs-number">1</span><<ADPS2; <span class="hljs-comment">// ADPS2:0 = 3bit prescaler set to 64</span>
ADCSRA |= <span class="hljs-number">1</span><<ADPS1;
}</code></pre>
<br />
The ADC is set to 5V and LAR (Left Adjust Read) - ie: the higher bits are stored in the ADCH and the remaining lower bits are in the ADCL. Since, I need only 8 bits, hence I am going to grab the ADCH and move on.<br />
<br />
<br />
<br />
<h3 id="the-loop">
The Loop</h3>
<br />
Ah, finally, the main course…<br />
<br />
<br />
<br />
<h4 id="sampling">
Sampling</h4>
<br />
Sample in the higher 8 bits (the ADCH) to collect 64 values. This part takes the most amount of time.<br />
<br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs mel"><span class="hljs-comment">// Select Analog Channel </span>
ADMUX |= micPort;
<span class="hljs-keyword">for</span>(i = <span class="hljs-number">0</span>;i<DFT_N;i++){
<span class="hljs-comment">// Start conversion</span>
ADCSRA |= <span class="hljs-number">1</span><<ADSC;
<span class="hljs-comment">// Wait till conversion is done</span>
<span class="hljs-keyword">while</span>(ADCSRA & <span class="hljs-number">1</span><<ADSC){};
<span class="hljs-comment">// Read ADCH. </span>
x[i] = (ADCH);
}
<span class="hljs-comment">// Scale from 0-255 to -128 to +127</span>
<span class="hljs-comment">// Apply window to reduce spectral leakage</span>
<span class="hljs-keyword">for</span>(i = <span class="hljs-number">0</span>;i<DFT_N;i++){
x[i]-=<span class="hljs-number">128</span>;
x[i]=(x[i]<span class="hljs-variable">*(</span>int8_t)pgm_read_byte(&<span class="hljs-keyword">window</span>[i]))>><span class="hljs-number">7</span>;
}</code></pre>
<br />
<br />
<br />
<h4 id="dft">
DFT</h4>
<br />
Convolute the samples with the DFT constants and accumulate the raw spectral results. You need to keep shifting it because there really isn’t much space in 16bits. At the end, get the magnitude as that’s what you’d finally display as bands.<br />
<br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs glsl"> <span class="hljs-keyword">for</span>(k=<span class="hljs-number">1</span>;k<DFT_Nb2;k++) {
dft_ReX[k]=<span class="hljs-number">0</span>;
dft_ImX[k]=<span class="hljs-number">0</span>;
<span class="hljs-keyword">for</span>(i =<span class="hljs-number">0</span>;i<DFT_N;i++) {
dft_ReX[k] += ((int8_t)pgm_read_byte(&REx_cons[k][i]) * x[i])>><span class="hljs-number">2</span>;
<span class="hljs-keyword">if</span>(k<DFT_Nb2-<span class="hljs-number">1</span>){
dft_ImX[k] += -<span class="hljs-number">1</span> * ((int8_t)pgm_read_byte(&IMx_cons[k][i]) * x[i])>><span class="hljs-number">2</span>;
}
}
dft_ReX[k] = dft_ReX[k] >> (<span class="hljs-number">5</span>+LOG2_Nb2);
dft_ImX[k] = dft_ImX[k] >> (<span class="hljs-number">5</span>+LOG2_Nb2);
}
<span class="hljs-comment">//dft_ReX[0] = dft_ReX[0] >> 1;</span>
dft_ReX[DFT_Nb2-<span class="hljs-number">1</span>] = dft_ReX[DFT_Nb2-<span class="hljs-number">1</span>] >> <span class="hljs-number">1</span>;
<span class="hljs-comment">//Magnitude Calculation</span>
<span class="hljs-keyword">for</span>(k =<span class="hljs-number">1</span>;k<DFT_Nb2;k++) {
dftX[k] = <span class="hljs-built_in">sqrt</span>(dft_ReX[k]*dft_ReX[k] + dft_ImX[k]*dft_ImX[k]);
}</code></pre>
<br />
<br />
<br />
<h4 id="render">
Render</h4>
<br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs mel"> lcd.<span class="hljs-keyword">clear</span>();
lcd.setCursor(<span class="hljs-number">0</span>,<span class="hljs-number">1</span>);
<span class="hljs-keyword">for</span>(k =<span class="hljs-number">0</span>;k<<span class="hljs-number">16</span>;k++) {
<span class="hljs-comment">//LINEAR </span>
<span class="hljs-keyword">mag</span>=dftX[Bands[k]];
<span class="hljs-comment">// LOG: 18*log2</span>
<span class="hljs-keyword">mag</span> = pgm_read_byte(&logMag[<span class="hljs-keyword">mag</span>]);
<span class="hljs-comment">// Noise adjust</span>
<span class="hljs-keyword">if</span>(k==<span class="hljs-number">0</span> && <span class="hljs-keyword">mag</span><<span class="hljs-number">80</span>){<span class="hljs-keyword">mag</span>=<span class="hljs-number">0</span>;}
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (k==<span class="hljs-number">1</span> && <span class="hljs-keyword">mag</span><<span class="hljs-number">42</span>){<span class="hljs-keyword">mag</span>=<span class="hljs-number">0</span>;}
<span class="hljs-keyword">mag</span> = <span class="hljs-keyword">mag</span>>><span class="hljs-number">3</span>;
<span class="hljs-comment">// chaser - slowly falling bands (instead of flickering silliness)</span>
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">mag</span><lcd_lvl[k]){lcd_lvl[k]--;}
<span class="hljs-keyword">else</span> {lcd_lvl[k] = <span class="hljs-keyword">mag</span>;}
<span class="hljs-comment">// Print the bands!</span>
<span class="hljs-keyword">if</span>(lcd_lvl[k]><span class="hljs-number">7</span>){
lcd.setCursor(k,<span class="hljs-number">0</span>);
lcd.write(lcd_lvl[k]-<span class="hljs-number">8</span>);
lcd.setCursor(k,<span class="hljs-number">1</span>);
lcd.write(<span class="hljs-number">7</span>);
} <span class="hljs-keyword">else</span> {
lcd.write(lcd_lvl[k]);
}
}</code></pre>
</div>
Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-71903894138189130582014-10-03T07:07:00.003-07:002014-10-03T07:20:29.282-07:00Tower of Fun - Part 2<div dir="ltr" style="text-align: left;" trbidi="on"><h1 id="pixel-art-makes-all-the-difference">Pixel art makes all the difference</h1><br />
<p>Expanding on the <a href="http://robotcantalk.blogspot.in/2014/10/tower-of-fun-part-1.html">previous</a>, I decided to improve the art in the game. </p><br />
<p><i class="icon-code"> <a href="https://github.com/SonalPinto/TowerOfFun/tree/master/games/ToF_v2">SOURCE</a> </i> <br />
<br />
<i class="icon-gamepad"> <a href="http://toweroffun.bitballoon.com/games/tof_v2">PLAY</a></i></p><br />
<a name='more'></a><br />
<p><div class="toc"><ul><li><a href="#pixel-art-makes-all-the-difference">Pixel art makes all the difference</a><ul><li><ul><li><a href="#eye-of-the-beholder">Eye of the beholder</a></li>
<li><a href="#player-is-move">Player is Move</a></li>
</ul></li>
</ul></li>
</ul></div></p><br />
<p>One step at a time, ya? So far, the game looks like this:</p><br />
<p><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHp6m6olo5OlXJbVsC2LisCpAuKFBmSWZN-P4BjA-vwF2M8iK6PKpY0K1btFr4KSeDhkqgLjnbQO033vx7o2zWeai896zR6TXGC9P-Om5P5WTvq0tN19MGvYa3uNF4M9HazuhWGHYjZ2w/s0/" alt="enter image description here" title="tofv1.PNG"></p><br />
<p>The above used these simple tiles: <br />
<br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFxH1g7WAp70uJMYfu5IIk9Qo6BUmxShyphenhyphenfLNSExtEsL-E2wNDDXoIK4rtvb2N4aVPdKu02oDvokm0dBCZUAf6S5O_963VqikkB5DhzGv4ZR8CBOUwKeP8I2t0g-xsPiOrse7J-BYLRe8w/s256/" alt="enter image description here" title="tiles1.png"></p><br />
<p>And, then I had them replaced with these: <br />
<br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQUYsHE_QvKIaxpv8QIMbRa4UScJDjmSxni6gBQzmRpfAbdg1z6SxtjoeUaZuCIPvHcN_s7sGSbudAkmiak7KL9s7va-jxkhLT9Vbvv1xxeUea73wmNCjQoWKsDcmTyAQbqxOIUJI3iss/s256/tiles_2tone.png" alt="enter image description here" title="tiles_2tone.png"></p><br />
<p>If you look closer, each of the tile sprites have only 2 colors in them. They took less than 30 mins to draft and when I loaded up the game with these tiles I was surprised. I realized how simple art alone could add huge value to the game. See for yourself,</p><br />
<p><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjY6sttT0Y8nCjvV9Qzui8rv5lIra_IcDY1eHGHAcAXNQyzL9vPxGoVWOkXqgBn-IpkJV4PZaG7zAuUuK_iYmSpuSF0Hjmjn2zzQcH-po-5QIxD_pVsqeHd1cr90DOo7Nh10Uj2ahC7Few/s0/" alt="enter image description here" title="screen_flatTiles.png"></p><br />
<hr><br />
<br />
<br />
<h3 id="eye-of-the-beholder">Eye of the beholder</h3><br />
<p>To add more depth, I drew the walls, actually be walls, rather than look like flat sprites on the ground, like the above.</p><br />
<p><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2BbBIlwCYYLWQVRudUM0yE0K7UYmuC6H0A4lj3d5qrVVk2R8_BGifyLo8GyBlFtLHnv0RScWCS81dy28Oh6X4ENtYTpzYDT5HWeGqCTDLax_XegVsP3WZ_z1-bha_uIeej-TgVcf2_aQ/" alt="enter image description here" title="tiles.png"></p><br />
<p>Wrote a simple <a href="https://github.com/SonalPinto/TowerOfFun/blob/master/games/ToF_v2/js/tiler.js"><code>tiler.js</code></a> which took the default Dungeon <code>map</code> array which had only values for 0, 1 and 2 (wall, room and corridor - ie, wall, grass and ground) - and returned an array with indices to one of the sprties in the upgraded tileSheet.</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs cs"><span class="hljs-comment">// Tile Library</span>
<span class="hljs-comment">// This stores the tile indices for the sprite sheet</span>
<span class="hljs-comment">// Allows independance from sprite sheet ordering, as we now only have to edit the library</span>
<span class="hljs-comment">// instead of the tileMapTranslate function</span>
<span class="hljs-keyword">var</span> tileLibrary = {
wall: {
front: <span class="hljs-number">0</span>,
flat: <span class="hljs-number">1</span>,
},
room: <span class="hljs-number">2</span>,
corridor: <span class="hljs-number">3</span>,
blank: <span class="hljs-number">4</span>
};</code></pre><br />
<p>Right after the dungeon is created, we call upon <a href="https://github.com/SonalPinto/TowerOfFun/blob/master/games/ToF_v2/js/tiler.js"><code>tiler.js</code></a> primary function, <code>tileMapTranslate()</code> to do our bidding, our <code>Game.Play,create()</code> in <a href="https://github.com/SonalPinto/TowerOfFun/blob/master/games/ToF_v2/js/main.js"><code>main.js</code></a>. <code>tileMapTranslate()</code> goes through every tile in the map and assigns the correct tile index to it based on it’s neighbors. For example, every 1 and 2 would become a grass and ground tile respectively. It gets slightly complex for walls, for we need to ensure that top and bottom walls are face-walls, while the left, right and filler walls are flat-top walls.</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs cs"><span class="hljs-comment">// Create new Dungeon and generate it</span>
<span class="hljs-keyword">this</span>.dungeon = <span class="hljs-keyword">new</span> Dungeon();
<span class="hljs-keyword">this</span>.dungeon.generate(<span class="hljs-keyword">this</span>.MAP_SIZE);
<span class="hljs-keyword">this</span>.map = <span class="hljs-keyword">this</span>.dungeon.getMap();
<span class="hljs-comment">// Translate the map into a spriteMap (check tiler.js)</span>
<span class="hljs-keyword">this</span>.tileSpriteMap = tileMapTranslate(<span class="hljs-keyword">this</span>.map);
<span class="hljs-comment">// Assign the tileSprite indices to the actual tileMap object</span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i<<span class="hljs-keyword">this</span>.MAP_SIZE; i++) {
<span class="hljs-keyword">for</span>(<span class="hljs-keyword">var</span> j=<span class="hljs-number">0</span>; j<<span class="hljs-keyword">this</span>.MAP_SIZE; j++) {
<span class="hljs-keyword">this</span>.tileMap.putTile(<span class="hljs-keyword">this</span>.tileSpriteMap[i][j], i, j, <span class="hljs-keyword">this</span>.layer0);
}
}</code></pre><br />
<p>Now, isn’t this pretty? <em>Such GFX!</em></p><br />
<p><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqeBX9PCzvuWneXdVbde7xp7zRb8CKdLHoVVmxZNJnbAloyJsCkKK9U3VFv8nQswvahjzdUfPYv24gX6A2tJkO48dw6fRI19LeLTGAEYsiLU55ObHJkvYL69ITS4z9fZvnONrLQbd-RYA/s0/tofv2.PNG" alt="enter image description here" title="tofv2.PNG"></p><br />
<hr><br />
<br />
<br />
<h3 id="player-is-move">Player is Move</h3><br />
<p>Having a static player sprite gets old real quick. Hence animation!</p><br />
<p><img src="https://lh3.googleusercontent.com/-yAIR63cWrqk/VC6n8lXyvaI/AAAAAAAACMw/z8U_0EvWD7A/s0/player-down.gif" alt="enter image description here" title="player-down.gif"><img src="https://lh6.googleusercontent.com/-0bBDdidRN7A/VC6oFuUdJuI/AAAAAAAACM8/1FjaeCwIfKM/s0/player-up.gif" alt="enter image description here" title="player-up.gif"><img src="https://lh3.googleusercontent.com/-Nvf_H8fuuD0/VC6oKqJ6RCI/AAAAAAAACNI/B5u_AcFxGSo/s0/player-left.gif" alt="enter image description here" title="player-left.gif"><img src="https://lh3.googleusercontent.com/-D-cD5FTwtL0/VC6oOsSGITI/AAAAAAAACNU/OcHVSjAnqiM/s0/player-right.gif" alt="enter image description here" title="player-right.gif"></p><br />
<p>The player sprite asset is no longer a single sprite, but is a spritesheet, with each frame building up the animation:</p><br />
<p><img src="https://lh5.googleusercontent.com/-sFdf8w2gBks/VC6olDVSatI/AAAAAAAACNg/2CgjGwox_9k/s0/player.png" alt="enter image description here" title="player.png"></p><br />
<p>We add these animations to the Player in the <code>create()</code> function, after the Player sprite object has been created. In this case, each animation has 4 frames, and they are indexed from left to right and top to bottom in the spritesheet.</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs cs"><span class="hljs-comment">// Assign Player Animations</span>
<span class="hljs-keyword">this</span>.player.animations.add(<span class="hljs-string">'left'</span>, [<span class="hljs-number">8</span>, <span class="hljs-number">9</span>, <span class="hljs-number">10</span>, <span class="hljs-number">11</span>], <span class="hljs-keyword">this</span>.PLAYERFRAME_SPEED, <span class="hljs-keyword">true</span>);
<span class="hljs-keyword">this</span>.player.animations.add(<span class="hljs-string">'right'</span>, [<span class="hljs-number">12</span>, <span class="hljs-number">13</span>, <span class="hljs-number">14</span>, <span class="hljs-number">15</span>], <span class="hljs-keyword">this</span>.PLAYERFRAME_SPEED, <span class="hljs-keyword">true</span>);
<span class="hljs-keyword">this</span>.player.animations.add(<span class="hljs-string">'up'</span>, [<span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>], <span class="hljs-keyword">this</span>.PLAYERFRAME_SPEED, <span class="hljs-keyword">true</span>);
<span class="hljs-keyword">this</span>.player.animations.add(<span class="hljs-string">'down'</span>, [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>], <span class="hljs-keyword">this</span>.PLAYERFRAME_SPEED, <span class="hljs-keyword">true</span>);</code></pre><br />
<p>To control the animation on the Player object, i just kick it off when the user inputs a direction to move in. This code would go in the <code>update()</code> part.</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs cs"> <span class="hljs-comment">// Move Up/Down</span>
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.cursors.up.isDown) {
<span class="hljs-keyword">this</span>.player.body.velocity.y = -<span class="hljs-keyword">this</span>.PLAYER_SPEED;
<span class="hljs-keyword">this</span>.player.animations.play(<span class="hljs-string">'up'</span>);
moving++;
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.cursors.down.isDown) {
<span class="hljs-keyword">this</span>.player.body.velocity.y = <span class="hljs-keyword">this</span>.PLAYER_SPEED;
<span class="hljs-keyword">this</span>.player.animations.play(<span class="hljs-string">'down'</span>);
moving++;
}</code></pre><br />
<p>Since, <a href="http://docs.phaser.io/Phaser.AnimationManager.html">Phaser’s AnimationManager</a> plays the animation on loop by default (though, AnimationManager can take more instructions on how to deal with animations), the animations on the Player have to stop when the Player isn’t moving.</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs cs"> <span class="hljs-comment">// Standing still</span>
<span class="hljs-keyword">if</span>(!moving){
<span class="hljs-keyword">this</span>.player.animations.stop(<span class="hljs-keyword">null</span>,<span class="hljs-keyword">true</span>);
<span class="hljs-comment">// this.player.frame = 0;</span>
}</code></pre><br />
<p><i class="icon-code"> <a href="https://github.com/SonalPinto/TowerOfFun/tree/master/games/ToF_v2">SOURCE</a> </i> <br />
<br />
<i class="icon-gamepad"> <a href="http://toweroffun.bitballoon.com/games/tof_v2">PLAY</a></i></p><br />
<hr><br />
<p>I have been using <a href="http://www.aseprite.org/">Aseprite</a> to draw all my pixel art. It’s a great tool and free if you compile it yourself, else it’s also available for 10$. That’s cheaper than a medium size pizza. It comes with a stunning feature set where you get to animate in layers, tiled the sprites, support for spritesheets, etc. Head on over and check it out: <br />
<br />
<a href="http://www.aseprite.org/"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlLTV2eemfMeKIDnsFOSzdNW6MBgyEp-gl-cJ-VRz2lj0kJvef6drxRVax6QiTE1T9b08PffYN98O3DhbTeuJ3KGT-PhwAK4S2Plz6r7oG4AAd7oVz-nvk33PKUgsRFqXH2Yx2MR3Tx5o/s200/aseprite.png" alt="AespriteLogo" title="aseprite.png"></a></p><br />
<p><i class="icon-right"> <a href="http://robotcantalk.blogspot.in/p/blog-page.html">Back to Tower of Fun</a> </i></p></div>Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-21141155179477512102014-10-02T22:22:00.000-07:002014-10-02T22:45:01.184-07:00Tower of Fun - Part 1<div dir="ltr" style="text-align: left;" trbidi="on"><h1 id="tilemap-and-player">TileMap and Player</h1><br />
<p>This is where it really begun. Tower of Fun. Last time, I made myself a <a href="http://robotcantalk.blogspot.in/2014/09/dungeon-generator.html">dungeon generation</a> algorithm based on BSP trees and got it up and running on <a href="http://robotcantalk.blogspot.in/2014/10/dungeon-drawing-in-phaser-using-tilemap.html">Phaser using tilemaps</a>. Now, it’s time to really set the stage. Tower of Fun will build upon our simple dungeon generator and head to version 1, ending up something like this: <br><br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHp6m6olo5OlXJbVsC2LisCpAuKFBmSWZN-P4BjA-vwF2M8iK6PKpY0K1btFr4KSeDhkqgLjnbQO033vx7o2zWeai896zR6TXGC9P-Om5P5WTvq0tN19MGvYa3uNF4M9HazuhWGHYjZ2w/" alt="tofv1" title="tofv1.PNG"></p><br />
<p><i class="icon-code"> <a href="https://github.com/SonalPinto/TowerOfFun/tree/master/games/ToF_v1">SOURCE</a></i> <br><br />
<i class="icon-gamepad"> <a href="http://toweroffun.bitballoon.com/games/tof_v1">Play</a></i></p><br />
<a name='more'></a><br />
<p><div class="toc"><div class="toc"><ul><li><a href="#tilemap-and-player">TileMap and Player</a><ul><li><ul><li><a href="#game-states-using-phaser">Game States using Phaser</a></li>
<li><a href="#being-classy">Being classy</a></li>
<li><a href="#a-load-in-time-saves-nine">A Load in time saves nine</a></li>
<li><a href="#whats-special-on-todays-main-menu">What’s special on today’s Main Menu</a></li>
<li><a href="#ready-player-one">Ready Player One</a></li>
<li><a href="#start-your-engines">Start your engines</a></li>
</ul></li>
</ul></li>
</ul></div></div></p><br />
<hr><br />
<br />
<br />
<h3 id="game-states-using-phaser">Game States using Phaser</h3><br />
<p>If you have played games, then you would ahve noticed, that a games usually begins fancy initial credits and logos flashing, then some mysterious “<em>Loading…</em>” and then the main menu. You get to actually play the game where the real gameplay exists via the main menu, probably by clicking on something. Each of these phases, <code>initial credits</code>, <code>Loading...</code>, <code>Main menu</code> and the <code>actual game</code> are States of the Game. A <code>game state</code> describes the current phase of the game and, the game moves from one state to another when certain conditions are met. For example, the “Loading…” screen leads to the Main menu when all assets are done loading. </p><br />
<p>Phaser has a nifty way to handle game states. Here, <a href="https://github.com/photonstorm/phaser/wiki/Phaser-General-Documentation-:-States">Phaser docs on states</a> tell you all about it. A state in phaser, on its own represents nothing. But, it’s a bundle of important Phaser core functions like <code>preload()</code>, <code>create()</code>, <code>update()</code> and <code>render()</code>. At each state, Phaser will execute those functions as it <a href="http://robotcantalk.blogspot.in/2014/10/dungeon-drawing-in-phaser-using-tilemap.html#set-phaser-on-stun">normally would</a>. Moreover Phaser auto-destroys any content that we created during the state, so that we don’t have to do it. Hence, we can kinda look at it like a game within a game, and when certain inputs (like clicking Play) or conditions (assets are loaded) are met, the mini-game will move onto the next mini-game. <em>Gameception</em>!</p><br />
<p>Using Phaser states and enlisting them is as easy as it gets. As mentioned before, the State is nothing but an simple object with core functions that Phaser would call. You can enlist a state using the <code>state.add(key, GameSateObject)</code> and call the state using the <code>state.start(key)</code>. </p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs javascript"><span class="hljs-keyword">var</span> Game = {};
Game.Preloader = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span>{</span>};
Game.Preloader.prototype = {
preload: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
}
};
Game.MainMenu = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span>{</span>};
Game.MainMenu.prototype = {
create: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
}
};
Game.Play = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span>{</span>};
Game.Play.prototype = {
create: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
},
update: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
},
render: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
},
};
<span class="hljs-keyword">var</span> game = <span class="hljs-keyword">new</span> Phaser.Game(<span class="hljs-number">800</span>, <span class="hljs-number">480</span>, Phaser.AUTO, <span class="hljs-string">'phaserCanvas'</span>);
game.state.add(<span class="hljs-string">'Preloader'</span> , Game.Preloader);
game.state.add(<span class="hljs-string">'MainMenu'</span> , Game.MainMenu);
game.state.add(<span class="hljs-string">'Play'</span> , Game.Play);
game.state.start(<span class="hljs-string">'Preloader'</span>);</code></pre><br />
<p>Tower of Fun will currently have 3 states:</p><br />
<dl><dt>Preloader</dt>
<dd>All Game assets such as sprites and tilesheets will be loaded here, and the game will move onto the next state when they are done loading. It will have minimal graphic content.</dd>
<dt>Main Menu</dt>
<dd>The main menu of the game, where the Player can start the game or check some options, maybe…</dd>
<dt>Play</dt>
<dd>The actual gameplay section. The Dungeon will be rendered using assets that were loaded during the <code>Preloader</code> state and the Player will be able to experience GOTY level gameplay.</dd>
</dl><br />
<hr><br />
<br />
<br />
<h3 id="being-classy">Being classy</h3><br />
<p>Most of the changes happen to <a href="https://github.com/SonalPinto/TowerOfFun/blob/master/games/ToF_v1/js/main.js"><code>main.js</code></a> but a minor change was made to <a href="https://github.com/SonalPinto/TowerOfFun/blob/master/games/ToF_v1/js/dungeon.js"><code>dungeon.js</code></a>. The Dungeon object has now been made in to a class, so that it could be instantiated in the Game.</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs javascript"><span class="hljs-comment">// Main Dungeon object</span>
<span class="hljs-keyword">var</span> Dungeon = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>};
Dungeon.prototype= {</code></pre><br />
<hr><br />
<br />
<br />
<h3 id="a-load-in-time-saves-nine">A Load in time saves nine</h3><br />
<p>We create an empty object called <code>Game</code>, which will house all our <code>game states</code>. Same with <code>Preloader</code>. It starts off being empty and is then filled with regular Phaser core game loop functions.</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs javascript"><span class="hljs-comment">// The main Game Object</span>
<span class="hljs-comment">// The Game!</span>
<span class="hljs-comment">// It shall hold all the Phaser game states</span>
<span class="hljs-keyword">var</span> Game = {};
<span class="hljs-comment">// Preloader state. This where the loading screen and stuff would go... if I had one.</span>
<span class="hljs-comment">// Load all the assets into the cache, and onLoadComplete, run this.loadComplete</span>
<span class="hljs-comment">// and head to the next state.</span>
Game.Preloader = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span>{</span>};
Game.Preloader.prototype = {
preload: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
<span class="hljs-keyword">this</span>.game.stage.backgroundColor = <span class="hljs-string">'#000000'</span>;
<span class="hljs-keyword">var</span> style = { font: <span class="hljs-string">"24px Arial"</span>, fill: <span class="hljs-string">"white"</span>, align: <span class="hljs-string">"center"</span> };
<span class="hljs-keyword">this</span>.add.text(game.world.centerX, game.world.centerY, <span class="hljs-string">"Preloading..."</span>, style);
<span class="hljs-keyword">this</span>.load.spritesheet(<span class="hljs-string">'tileSheet'</span>, <span class="hljs-string">'../../assets/tiles1.png'</span>,<span class="hljs-number">32</span>,<span class="hljs-number">32</span>);
<span class="hljs-keyword">this</span>.load.image(<span class="hljs-string">'player'</span>,<span class="hljs-string">'../../assets/player_solo.png'</span>,<span class="hljs-number">32</span>,<span class="hljs-number">32</span>);
<span class="hljs-keyword">this</span>.load.onLoadComplete.add(<span class="hljs-keyword">this</span>.loadComplete, <span class="hljs-keyword">this</span>)
},
loadComplete: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
<span class="hljs-keyword">this</span>.game.state.start(<span class="hljs-string">'MainMenu'</span>);
}
};</code></pre><br />
<p>You can see that the assets, <code>tiles1.png</code> and <code>player_solo.png</code> would be added to the cache. A Phaser event called <code>onLoadComplete</code> which is a part of the <a href="http://docs.phaser.io/Phaser.Loader.html">Phaser.Loader</a> class can be used to track when the assets have been loaded. Here, I picked it from this <a href="http://examples.phaser.io/_site/view_full.html?d=loader&f=load+events.js&t=load%20events">Phaser example</a>. It will call <code>Game.Preloader.loadComplete()</code> when the event is fired, which will lead to the <code>MainMenu</code></p><br />
<hr><br />
<br />
<br />
<h3 id="whats-special-on-todays-main-menu">What’s special on today’s Main Menu</h3><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs javascript"><span class="hljs-comment">// The state that states itself after the Preloader. The formidable MainMenu.</span>
<span class="hljs-comment">// There is nothing here now. Just click to Play, rendered via text</span>
Game.MainMenu = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span>{</span>};
Game.MainMenu.prototype = {
preload: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
},
create: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
<span class="hljs-keyword">var</span> style = { font: <span class="hljs-string">"24px Arial"</span>, fill: <span class="hljs-string">"white"</span>, align: <span class="hljs-string">"center"</span> };
<span class="hljs-keyword">this</span>.add.text(game.world.centerX, game.world.centerY, <span class="hljs-string">"MainMenu\nPlay"</span>, style);
<span class="hljs-comment">// Click to go to the next state (Play)</span>
<span class="hljs-keyword">this</span>.game.input.onDown.add(<span class="hljs-keyword">this</span>.startGame, <span class="hljs-keyword">this</span>);
},
update: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
},
startGame: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
<span class="hljs-keyword">this</span>.game.state.start(<span class="hljs-string">'Play'</span>);
}
};</code></pre><br />
<p>The <code>MainMenu</code> state loads no asset and simply has a text indicator that says:</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs mathematica">MainMenu
<span class="hljs-keyword">Play</span></code></pre><br />
<p>You go the next, and finally interesting state when you click (anywhere in the game canvas).</p><br />
<hr><br />
<br />
<br />
<h3 id="ready-player-one">Ready Player One</h3><br />
<p>Finally the interesting game state. Well, the others where kinda placeholders. Phaser is capable if really cool features such as preloader bars, which I haven’t used yet (or rather didn’t know about when I wrote version 1 or 2 for that matter<i class="icon-smile"></i>). The <code>Game.Play</code> object will have it’s own default vars and functions, like any other state. We shall use a tilesheet or 32x32 tiles instead of individual sprites, albeit still flat colored.</p><br />
<p><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhx_iYtRMb98ryrhJnKQrn-Ic-Lsjfq2aIw5byoYDO3cLSPxSAY3Vny0jAp21gHrp1zABKKysqUiACBVPuzu3k3Npa3VHxPtZ4ZvS6k1qV00k7vwIKr3igpBuxyFyb0J8TFiGDORTj-_Q8/s256/tiles1.png" alt="enter image description here" title="tiles1.png"></p><br />
<p>Most of rest of the code in <code>Game.Play</code> exactly the same as <a href="http://robotcantalk.blogspot.in/2014/10/dungeon-drawing-in-phaser-using-tilemap.html"><code>Dungeon Generator</code></a>, except that part where the <code>Dungeon</code> class is instantiated as a local object <code>Game.Play.dungeon</code>. This time on, when we create the <code>layer</code> for the <code>tilemap</code>, we set the collision for any tile block with the index 0, ie: walls. That assigns these wall as impassable tiles.</p><br />
<pre class="prettyprint"><code class=" hljs coffeescript"> <span class="hljs-regexp">//</span> Creates a <span class="hljs-keyword">new</span> blank layer <span class="hljs-keyword">and</span> sets the map dimensions.
<span class="hljs-keyword">this</span>.layer0 = <span class="hljs-keyword">this</span>.tileMap.create(<span class="hljs-string">'layer0'</span>,<span class="hljs-keyword">this</span>.MAP_SIZE,<span class="hljs-keyword">this</span>.MAP_SIZE,<span class="hljs-number">32</span>,<span class="hljs-number">32</span>);
<span class="hljs-keyword">this</span>.layer0.resizeWorld();
<span class="hljs-regexp">//</span> Set collision <span class="hljs-literal">on</span> walls
<span class="hljs-keyword">this</span>.tileMap.setCollision(<span class="hljs-number">0</span>);</code></pre><br />
<p>The new part is where we add the Player in the <code>create()</code> function. <br><br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpJaWREeLD-L76qJkKSODC3DY7My_fAYvup_KvVt9ovYUYZ-qrpniIv9Lo3vASQgoFYKKCLLYgHx12jioCHkBT4xJj2UTC_pk58c3FPhu-YGd3KAHV18SNfcmiLaCaHBtIglory6M6_5Y/s256/player_soloBig.png" alt="Player 1" title="player_soloBig.png"></p><br />
<pre class="prettyprint"><code class=" hljs cs"><span class="hljs-comment">// Add the Player sprite at the center of the first room in the room list (it could be anywhere)</span>
<span class="hljs-keyword">this</span>.player = <span class="hljs-keyword">this</span>.add.sprite(<span class="hljs-keyword">this</span>.rooms[<span class="hljs-number">0</span>].center.x*<span class="hljs-number">32</span>, <span class="hljs-keyword">this</span>.rooms[<span class="hljs-number">0</span>].center.y*<span class="hljs-number">32</span>, <span class="hljs-string">'player'</span>);
<span class="hljs-keyword">this</span>.physics.arcade.enable(<span class="hljs-keyword">this</span>.player);
<span class="hljs-comment">// Have the Viewport follow the Player. See how easy this is?</span>
<span class="hljs-keyword">this</span>.camera.follow(<span class="hljs-keyword">this</span>.player);
<span class="hljs-comment">// Graphics object. Maybe I'll need it if I want to draw things. Dunno.</span>
<span class="hljs-keyword">this</span>.marker = <span class="hljs-keyword">this</span>.add.graphics();
<span class="hljs-comment">// Have an object to track keyboard cursor input</span>
<span class="hljs-keyword">this</span>.cursors = <span class="hljs-keyword">this</span>.input.keyboard.createCursorKeys();</code></pre><br />
<p>Here, we create a player sprite, starting in the center of some room and enable Phaser’s <code>ARCADE</code> physics on it. We also have the camere (viewport) follow the player as he moves around the world, with a single command. Lastly, to record input (arrow key presses on the keyboard) we use Phaser’s insta cursor object creation function. All of this, picked from <a href="http://www.photonstorm.com/phaser/tutorial-making-your-first-phaser-game">Photon Storm’s tutorial on Phaser</a>.</p><br />
<p>To actually do something about those <code>cursors</code> we need to update the <code>update()</code> function to poll for inputs. When a particular key press is detected, the Player’s velocity will be altered accordingly.</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs avrasm"><span class="hljs-label">update:</span> function() {
this<span class="hljs-preprocessor">.physics</span><span class="hljs-preprocessor">.arcade</span><span class="hljs-preprocessor">.collide</span>(this<span class="hljs-preprocessor">.player</span>, this<span class="hljs-preprocessor">.layer</span>0)<span class="hljs-comment">;</span>
// INPUT HANDLING
// Reset the players velocity (movement)
this<span class="hljs-preprocessor">.player</span><span class="hljs-preprocessor">.body</span><span class="hljs-preprocessor">.velocity</span><span class="hljs-preprocessor">.x</span> = <span class="hljs-number">0</span><span class="hljs-comment">;</span>
this<span class="hljs-preprocessor">.player</span><span class="hljs-preprocessor">.body</span><span class="hljs-preprocessor">.velocity</span><span class="hljs-preprocessor">.y</span> = <span class="hljs-number">0</span><span class="hljs-comment">;</span>
if (this<span class="hljs-preprocessor">.cursors</span><span class="hljs-preprocessor">.left</span><span class="hljs-preprocessor">.isDown</span>) {
// Move to the left
this<span class="hljs-preprocessor">.player</span><span class="hljs-preprocessor">.body</span><span class="hljs-preprocessor">.velocity</span><span class="hljs-preprocessor">.x</span> = -this<span class="hljs-preprocessor">.PLAYER</span>_SPEED<span class="hljs-comment">;</span>
} else if (this<span class="hljs-preprocessor">.cursors</span><span class="hljs-preprocessor">.right</span><span class="hljs-preprocessor">.isDown</span>) {
// Move to the right
this<span class="hljs-preprocessor">.player</span><span class="hljs-preprocessor">.body</span><span class="hljs-preprocessor">.velocity</span><span class="hljs-preprocessor">.x</span> = this<span class="hljs-preprocessor">.PLAYER</span>_SPEED<span class="hljs-comment">;</span>
}
if (this<span class="hljs-preprocessor">.cursors</span><span class="hljs-preprocessor">.up</span><span class="hljs-preprocessor">.isDown</span>) {
// Move up
this<span class="hljs-preprocessor">.player</span><span class="hljs-preprocessor">.body</span><span class="hljs-preprocessor">.velocity</span><span class="hljs-preprocessor">.y</span> = -this<span class="hljs-preprocessor">.PLAYER</span>_SPEED<span class="hljs-comment">;</span>
} else if (this<span class="hljs-preprocessor">.cursors</span><span class="hljs-preprocessor">.down</span><span class="hljs-preprocessor">.isDown</span>) {
// Move down
this<span class="hljs-preprocessor">.player</span><span class="hljs-preprocessor">.body</span><span class="hljs-preprocessor">.velocity</span><span class="hljs-preprocessor">.y</span> = this<span class="hljs-preprocessor">.PLAYER</span>_SPEED<span class="hljs-comment">;</span>
}
}</code></pre><br />
<br />
<br />
<h3 id="start-your-engines">Start your engines</h3><br />
<p>At last, put all the states together and fire up Phaser. The game will start on the <code>Preloader</code> and move onto the MainMenu when all assets are loaded. At this point the game looks like the Player is flying around above a sea of green, blue and gray sheets.</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs oxygene"><span class="hljs-comment">// Finally, instantiate Phaser with canvas dimensions of 800x480</span>
<span class="hljs-comment">// Assing the states to Phaser and start on the Preloader</span>
<span class="hljs-keyword">var</span> game = <span class="hljs-keyword">new</span> Phaser.Game(<span class="hljs-number">800</span>, <span class="hljs-number">480</span>, Phaser.AUTO, <span class="hljs-string">'phaserCanvas'</span>);
game.state.<span class="hljs-keyword">add</span>(<span class="hljs-string">'Preloader'</span> , Game.Preloader);
game.state.<span class="hljs-keyword">add</span>(<span class="hljs-string">'MainMenu'</span> , Game.MainMenu);
game.state.<span class="hljs-keyword">add</span>(<span class="hljs-string">'Play'</span> , Game.Play);
game.state.start(<span class="hljs-string">'Preloader'</span>);</code></pre><br />
<p><i class="icon-code"> <a href="https://github.com/SonalPinto/TowerOfFun/tree/master/games/ToF_v1">SOURCE</a></i> <br><br />
<i class="icon-gamepad"> <a href="http://toweroffun.bitballoon.com/games/tof_v1">Play</a></i></p><br />
<p><i class="icon-right"> <a href="http://robotcantalk.blogspot.in/p/blog-page.html">Back to Tower of Fun</a></i></p></div>Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-57278018444576029472014-10-02T06:25:00.000-07:002014-10-02T08:02:15.112-07:00Using Markdown via StackEdit on Blogger<div dir="ltr" style="text-align: left;" trbidi="on"><h1 id="stackedit-for-blogger">StackEdit for Blogger</h1><br />
I had posted the default Hello page from <a href="https://stackedit.io/">StackEdit</a> to demo how amazing StackEdit can be. StackEdit is a <a href="http://en.wikipedia.org/wiki/Markdown">markdown</a> editor, with integrated featured from <a href="http://fortawesome.github.io/Font-Awesome/">font-awesome</a>, <a href="https://highlightjs.org/">highlight.js</a>, <a href="http://www.mathjax.org/">MathJax</a>, <a href="http://adrai.github.io/flowchart.js/">flowchart.js</a> and so much more that I have yet to discover. I went ahead wrote some more pages for my Tower of Fun project.<br />
<br />
<ul><li><a href="http://robotcantalk.blogspot.in/p/blog-page.html">Tower of Fun</a></li>
<li><a href="http://robotcantalk.blogspot.in/2014/10/dungeon-drawing-in-phaser-using-tilemap.html">Intro to Phaser</a></li>
<li><a href="http://robotcantalk.blogspot.in/2014/09/dungeon-generator.html">Dungeon Generator</a></li>
</ul><br />
<a name='more'></a><br />
<br />
<h3 id="live-preview">Live Preview</h3><br />
You get see what you type as you type! What more can you ask for? <br />
<br />
<img alt="enter image description here" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkHUM1Xr2B_Znpt297FmbRp4NkDMYXcDL_qKDZuRlje3habG8w-RWzPWIJ97Dk9JCMGN9HNZvy9jjjrYwCFKko9yoSCRwDbnKbRSiHIXqIk4eSAm2Dhk6UPQBn77w-pTYu5M9rpqxqDOI/s0/stackeditGood.PNG" title="stackeditGood.PNG" /><br />
<br />
<br />
<br />
<h3 id="fenced-code">Fenced Code</h3><br />
It is super frustrating to use Blogger’s editor to display any form of source code. With html5 markdown this simply become way too easy. Look at this neatly formatted code.<br />
<br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">genMap</span><span class="hljs-params">()</span> {</span>
console.clear();
Dungeon.generate(MAP_SIZE);
<span class="hljs-comment">// Dungeon.print();</span>
map = Dungeon.getMap();
stats = Dungeon.getStats();
rooms = Dungeon.getRooms();
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i<MAP_SIZE; i++) {
<span class="hljs-keyword">for</span>(<span class="hljs-keyword">var</span> j=<span class="hljs-number">0</span>; j<MAP_SIZE; j++) {
gmap.putTile(map[i][j],i,j,layer0);
}
}
drawBox();
}</code></pre><br />
<br />
<br />
<h3 id="inline-icons">Inline Icons</h3><br />
:Used font-awesome to add a zing to the regular links and titles. <a href="https://stackedit.io/res/libs/fontello/demo.html">Here’s the full list</a>. Examples: <br />
<br />
<i class="icon-code"> source code <br />
<br />
<i class="icon-gamepad"> Play!</i></i><br />
<br />
<br />
<br />
<h3 id="uml-diagrams-in-a-snap">UML Diagrams in a snap</h3><br />
StackEdit comes with <a href="http://adrai.github.io/flowchart.js/"><code>flowchart.js</code></a>. Here, look:<br />
<br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs php">st=>start: Phaser
pr=>operation: Preload
cr=>operation: Create
rndr=>operation: Render
e=>end: Update
st->pr->cr->e
e->rndr->e</code></pre><br />
it converts <i class="icon-up">this simple set of instructions into <i class="icon-down"> this:</i></i><br />
<br />
<br />
<br />
<div class="flow-chart"><svg height="397" style="overflow: hidden; position: relative; top: -0.78125px;" version="1.1" width="99.453125" xmlns="http://www.w3.org/2000/svg"><desc style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Created with Raphaël 2.1.0</desc><defs style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><path d="M5,0 0,2.5 5,5z" id="raphael-marker-block" stroke-linecap="round" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><marker id="raphael-marker-endblock33" markerheight="3" markerwidth="3" orient="auto" refx="1.5" refy="1.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use fill="black" stroke-width="1.6667" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" transform="rotate(180 1.5 1.5) scale(0.6,0.6)" xlink:href="#raphael-marker-block"></use></marker></defs><rect fill="#ffffff" height="37" r="20" rx="20" ry="20" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" transform="matrix(1,0,0,1,4.0859,2)" width="67.53125" x="0" y="0"></rect><text fill="#000000" font-family="sans-serif" font-size="14px" font-weight="normal" font="10px "Arial"" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: start;" text-anchor="start" transform="matrix(1,0,0,1,4.0859,2)" x="10" y="18.5"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Phaser</tspan></text><rect fill="#ffffff" height="37" r="0" rx="0" ry="0" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" transform="matrix(1,0,0,1,2,91)" width="71.703125" x="0" y="0"></rect><text fill="#000000" font-family="sans-serif" font-size="14px" font-weight="normal" font="10px "Arial"" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: start;" text-anchor="start" transform="matrix(1,0,0,1,2,91)" x="10" y="18.5"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Preload</tspan></text><rect fill="#ffffff" height="37" r="0" rx="0" ry="0" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" transform="matrix(1,0,0,1,5.3359,180)" width="65.03125" x="0" y="0"></rect><text fill="#000000" font-family="sans-serif" font-size="14px" font-weight="normal" font="10px "Arial"" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: start;" text-anchor="start" transform="matrix(1,0,0,1,5.3359,180)" x="10" y="18.5"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Create</tspan></text><rect fill="#ffffff" height="37" r="20" rx="20" ry="20" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" transform="matrix(1,0,0,1,3.6641,269)" width="68.375" x="0" y="0"></rect><text fill="#000000" font-family="sans-serif" font-size="14px" font-weight="normal" font="10px "Arial"" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: start;" text-anchor="start" transform="matrix(1,0,0,1,3.6641,269)" x="10" y="18.5"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Update</tspan></text><rect fill="#ffffff" height="37" r="0" rx="0" ry="0" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" transform="matrix(1,0,0,1,3.25,358)" width="69.203125" x="0" y="0"></rect><text fill="#000000" font-family="sans-serif" font-size="14px" font-weight="normal" font="10px "Arial"" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: start;" text-anchor="start" transform="matrix(1,0,0,1,3.25,358)" x="10" y="18.5"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Render</tspan></text><path d="M37.8515625,39C37.8515625,39,37.8515625,76.92477893829346,37.8515625,87.99851810093969" fill="none" font-family="sans-serif" font-weight="normal" marker-end="url(#raphael-marker-endblock33)" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path d="M37.8515625,128C37.8515625,128,37.8515625,165.92477893829346,37.8515625,176.9985181009397" fill="none" font-family="sans-serif" font-weight="normal" marker-end="url(#raphael-marker-endblock33)" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path d="M37.8515625,217C37.8515625,217,37.8515625,254.92477893829346,37.8515625,265.9985181009397" fill="none" font-family="sans-serif" font-weight="normal" marker-end="url(#raphael-marker-endblock33)" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path d="M37.8515625,306C37.8515625,306,37.8515625,343.92477893829346,37.8515625,354.9985181009397" fill="none" font-family="sans-serif" font-weight="normal" marker-end="url(#raphael-marker-endblock33)" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path d="M72.453125,376.5C72.453125,376.5,97.453125,376.5,97.453125,376.5C97.453125,376.5,97.453125,244,97.453125,244C97.453125,244,37.8515625,244,37.8515625,244C37.8515625,244,37.8515625,259.37344455718994,37.8515625,266.00924777425826" fill="none" font-family="sans-serif" font-weight="normal" marker-end="url(#raphael-marker-endblock33)" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path></svg></div><br />
<br />
<br />
<h3 id="instant-table-of-contents">Instant Table of Contents</h3><br />
You want a Table of Contents? Not even a challenge…<br />
<br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs json">[TOC]</code></pre><br />
becomes this:<br />
<br />
<br />
<div class="toc"><div class="toc"><ul><li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#stackedit-for-blogger">StackEdit for Blogger</a><ul><li><ul><li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#live-preview">Live Preview</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#fenced-code">Fenced Code</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#inline-icons">Inline Icons</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#uml-diagrams-in-a-snap">UML Diagrams in a snap</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#instant-table-of-contents">Instant Table of Contents</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#making-it-work-with-blogger">Making it work with Blogger</a></li>
</ul></li>
</ul></li>
</ul></div></div><br />
<br />
And it auto tracks as you build your content.<br />
<br />
<br />
<br />
<h3 id="making-it-work-with-blogger">Making it work with Blogger</h3><br />
This whole this was written in StackEdit. I don’t think that needs to be said anymore. I doubt I will ever go back to Blogger’s default editor, except to paste StackEdit’s html code directly there.<br />
<br />
By default, StackEdit won’t look right. You’d need to add this to your Blogger template. Go to <code>Template->Edit HTML</code><br />
<br />
<img alt="enter image description here" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdtanBCIp_Q41ow_b9IhzhdyiugJYuUIFcMVlHc1-B8AbVOxuqfGkFfFlZuipB9_9hZh576YaxyDYDYwmEn_P_WKdlX_rrF_n6pzxHi5DJU33wA59axWTKlzLTumhEbjU5XdL6yFDDtIc/s0/stackeditGood1.PNG" title="stackeditGood1.PNG" /><br />
<br />
and then add these lines in the head of your template.<br />
<br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs xml"> <span class="hljs-tag"><<span class="hljs-title">link</span> <span class="hljs-attribute">href</span>=<span class="hljs-value">'https://stackedit.io/res-min/themes/base.css'</span> <span class="hljs-attribute">rel</span>=<span class="hljs-value">'stylesheet'</span>/></span>
<span class="hljs-tag"><<span class="hljs-title">link</span> <span class="hljs-attribute">href</span>=<span class="hljs-value">'//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css'</span> <span class="hljs-attribute">rel</span>=<span class="hljs-value">'stylesheet'</span>/></span>
<span class="hljs-tag"><<span class="hljs-title">link</span> <span class="hljs-attribute">href</span>=<span class="hljs-value">'http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.2/styles/default.min.css'</span> <span class="hljs-attribute">rel</span>=<span class="hljs-value">'stylesheet'</span>/></span>
<span class="hljs-tag"><<span class="hljs-title">script</span> <span class="hljs-attribute">src</span>=<span class="hljs-value">'http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.2/highlight.min.js'</span>/></span><span class="javascript"></span></code></pre><br />
Like this: <br />
<br />
<img alt="enter image description here" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiINBnKzKUCwbA5AaDOrgTob4yR_S3XyARsModfW5MbbAtE3bNV8O9seEXsj4VI2JEUy_2xK_ynOTxoeUd_k79qsGsUC_WITmNgXne_-qxV20hht_Vw8fYzraKLEE15iqR6xOh2xWJvtQ4/s0/stackeditGood2.PNG" title="stackeditGood2.PNG" /><br />
<br />
And, <i class="icon-ok-circled">DONE</i><br />
<br />
</div>Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-32952730202278972012014-10-02T00:57:00.000-07:002014-10-02T08:02:28.858-07:00Dungeon Drawing in Phaser using Tilemap<div dir="ltr" style="text-align: left;" trbidi="on"><h1 id="introduction-to-phaser">Introduction to Phaser</h1><br />
<p>The <code>Dungeon Generator</code> creates perfecrtly logical maps. You could witness the perfection in the console by using <code>Dungeon.print()</code>. But, really… we can’t have a game on the console right?</p><br />
<p>That’s where <a href="http://phaser.io/">Phaser</a> comes in. Phaser is an HTML5 game enigine that’s based on webGL, with a neat fallback to HTML5 Canavs. It is super lightweight and mobile platform oriented. The best part? The massive store of <a href="http://docs.phaser.io/">documentation</a> and <a href="http://examples.phaser.io/">examples</a>. And, there a whole load of tutorials out there that would help a noob like me figure out how things are done. This was the first <a href="http://www.photonstorm.com/phaser/tutorial-making-your-first-phaser-game">Phaser tutorial</a> I took. You should really check out the examples to see what Phaser is capable of.</p><br />
<a name='more'></a><br />
<p>Source for this part is the same as <a href="http://robotcantalk.blogspot.in/2014/09/dungeon-generator.html">last time</a>. <br />
<br />
<i class="icon-code"> <a href="https://github.com/SonalPinto/TowerOfFun/tree/master/games/dungeon">SOURCE</a></i></p><br />
<p><i class="icon-gamepad"> <a href="http://toweroffun.bitballoon.com/games/dungeon">Play</a></i></p><br />
<p><div class="toc"><div class="toc"><ul><li><a href="#introduction-to-phaser">Introduction to Phaser</a><ul><li><ul><li><a href="#dungeon-time">Dungeon Time</a></li>
<li><a href="#set-phaser-on-stun">Set Phaser on Stun</a></li>
<li><a href="#load-before-firing">Load before firing</a></li>
<li><a href="#let-there-be-tiles">Let there be Tiles</a></li>
<li><a href="#drawing-words">Drawing Words</a></li>
</ul></li>
</ul></li>
</ul></div></div></p><br />
<br />
<br />
<h3 id="dungeon-time">Dungeon Time</h3><br />
<p>The map would have 32x32 tiles and hence, <code>MAP_SIZE</code> has been set to 32. We call our fancy <code>Dungeon</code> object that we had made <a href="http://robotcantalk.blogspot.in/2014/09/dungeon-generator.html">last time</a>. It prints the dungeon array onto the console.</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs go"><span class="hljs-keyword">var</span> MAP_SIZE =<span class="hljs-number"> 32</span>;
Dungeon.generate(MAP_SIZE);
Dungeon.<span class="hljs-built_in">print</span>();
<span class="hljs-keyword">var</span> <span class="hljs-keyword">map</span> = Dungeon.getMap();
<span class="hljs-keyword">var</span> rooms = Dungeon.getRooms();
<span class="hljs-keyword">var</span> tree = Dungeon.getTree();</code></pre><br />
<br />
<br />
<h3 id="set-phaser-on-stun">Set Phaser on Stun</h3><br />
<p>The <a href="https://github.com/SonalPinto/TowerOfFun/blob/master/games/dungeon/index.html"><code>index.html</code></a> sets the playing field for Phaser.</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs applescript"><<span class="hljs-keyword">div</span> style=<span class="hljs-string">"margin-left:64px;"</span> <span class="hljs-property">id</span>=<span class="hljs-string">"phaserCanvas"</span>></<span class="hljs-keyword">div</span>></code></pre><br />
<p>We kickstart Phaser in the <a href="https://github.com/SonalPinto/TowerOfFun/blob/master/games/dungeon/js/main.js"><code>main.js</code></a>. </p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs javascript"><span class="hljs-keyword">var</span> game = <span class="hljs-keyword">new</span> Phaser.Game(<span class="hljs-number">640</span>, <span class="hljs-number">384</span>, Phaser.AUTO, <span class="hljs-string">'phaserCanvas'</span>, {
preload: preload,
create: create,
update: update,
render: render
});
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">preload</span><span class="hljs-params">()</span> {</span>
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">create</span><span class="hljs-params">()</span> {</span>
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">update</span><span class="hljs-params">()</span> {</span>
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">render</span><span class="hljs-params">()</span> {</span>
}</code></pre><br />
<p>This will set the Phaser canvas to 640x384 pixels and renders it on the div <code>phaserCanvas</code>. These functions - <code>preload()</code>, <code>create()</code>, <code>update()</code> and <code>render()</code> form Game Loop. You <strong><em>preload</em></strong> the assets such as images and music, you then <strong><em>create</em></strong> all game objects such as the background, player and enemies. At every iteration of the Game Loop, you <strong><em>update</em></strong> the game objects, say, player movement or enemy logic. Finally you <strong><em>render</em></strong> the extra game objects onto the canvas, after Phaser is done drawing everything. Like this.</p><br />
<div class="flow-chart"><svg height="407" version="1.1" width="96.296875" xmlns="http://www.w3.org/2000/svg" style="overflow: hidden; position: relative; top: -0.28125px;"><desc style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Created with Raphaël 2.1.0</desc><defs style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><marker id="raphael-marker-endblock33" markerHeight="3" markerWidth="3" orient="auto" refX="1.5" refY="1.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xlink:href="#raphael-marker-block" transform="rotate(180 1.5 1.5) scale(0.6,0.6)" stroke-width="1.6667" fill="black" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker></defs><rect x="0" y="0" width="63.421875" height="39" r="20" rx="20" ry="20" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" stroke-width="2" transform="matrix(1,0,0,1,4.9141,2)"></rect><text x="10" y="19.5" text-anchor="start" font="10px "Arial"" stroke="#000000" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-family: sans-serif;" font-size="14px" font-family="sans-serif" font-weight="normal" transform="matrix(1,0,0,1,4.9141,2)"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Phaser</tspan></text><rect x="0" y="0" width="69.25" height="39" r="0" rx="0" ry="0" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" stroke-width="2" transform="matrix(1,0,0,1,2,93)"></rect><text x="10" y="19.5" text-anchor="start" font="10px "Arial"" stroke="#000000" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-family: sans-serif;" font-size="14px" font-family="sans-serif" font-weight="normal" transform="matrix(1,0,0,1,2,93)"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Preload</tspan></text><rect x="0" y="0" width="61.40625" height="39" r="0" rx="0" ry="0" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" stroke-width="2" transform="matrix(1,0,0,1,5.9219,184)"></rect><text x="10" y="19.5" text-anchor="start" font="10px "Arial"" stroke="#000000" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-family: sans-serif;" font-size="14px" font-family="sans-serif" font-weight="normal" transform="matrix(1,0,0,1,5.9219,184)"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Create</tspan></text><rect x="0" y="0" width="66.515625" height="39" r="20" rx="20" ry="20" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" stroke-width="2" transform="matrix(1,0,0,1,3.3672,275)"></rect><text x="10" y="19.5" text-anchor="start" font="10px "Arial"" stroke="#000000" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-family: sans-serif;" font-size="14px" font-family="sans-serif" font-weight="normal" transform="matrix(1,0,0,1,3.3672,275)"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Update</tspan></text><rect x="0" y="0" width="65.34375" height="39" r="0" rx="0" ry="0" fill="#ffffff" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" stroke-width="2" transform="matrix(1,0,0,1,3.9531,366)"></rect><text x="10" y="19.5" text-anchor="start" font="10px "Arial"" stroke="#000000" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: start; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-family: sans-serif;" font-size="14px" font-family="sans-serif" font-weight="normal" transform="matrix(1,0,0,1,3.9531,366)"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Render</tspan></text><path fill="none" stroke="#000000" d="M36.625,41C36.625,41,36.625,78.92477893829346,36.625,89.99851810093969" stroke-width="2" marker-end="url(#raphael-marker-endblock33)" font-family="sans-serif" font-weight="normal" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path fill="none" stroke="#000000" d="M36.625,132C36.625,132,36.625,169.92477893829346,36.625,180.9985181009397" stroke-width="2" marker-end="url(#raphael-marker-endblock33)" font-family="sans-serif" font-weight="normal" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path fill="none" stroke="#000000" d="M36.625,223C36.625,223,36.625,260.92477893829346,36.625,271.9985181009397" stroke-width="2" marker-end="url(#raphael-marker-endblock33)" font-family="sans-serif" font-weight="normal" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path fill="none" stroke="#000000" d="M36.625,314C36.625,314,36.625,351.92477893829346,36.625,362.9985181009397" stroke-width="2" marker-end="url(#raphael-marker-endblock33)" font-family="sans-serif" font-weight="normal" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path fill="none" stroke="#000000" d="M69.296875,385.5C69.296875,385.5,94.296875,385.5,94.296875,385.5C94.296875,385.5,94.296875,250,94.296875,250C94.296875,250,36.625,250,36.625,250C36.625,250,36.625,265.37344455718994,36.625,272.00924777425826" stroke-width="2" marker-end="url(#raphael-marker-endblock33)" font-family="sans-serif" font-weight="normal" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path></svg></div><br />
<p>An awesome feature about Phaser is that it completely handles the rendering part. The game objects such as player sprite or background tiles are rendered on each iteration in the order in which they were created. Hence, the <code>render()</code> function serves to augment the canvas with objects that we hadn’t already created during the <code>create()</code> call. Neat, huh?</p><br />
<hr><br />
<h3 id="load-before-firing">Load before firing</h3><br />
<p>We fill up the <code>preload()</code> with relevant <a href="https://github.com/SonalPinto/TowerOfFun/tree/master/assets">assets</a> that we’d want to load. </p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs sql">function preload() {
game.<span class="hljs-operator"><span class="hljs-keyword">load</span>.image(<span class="hljs-string">'wall'</span>, <span class="hljs-string">'../../assets/wall.png'</span>);</span>
game.<span class="hljs-operator"><span class="hljs-keyword">load</span>.image(<span class="hljs-string">'floor'</span>, <span class="hljs-string">'../../assets/floor.png'</span>);</span>
game.<span class="hljs-operator"><span class="hljs-keyword">load</span>.image(<span class="hljs-string">'corridor'</span>, <span class="hljs-string">'../../assets/corridor.png'</span>);</span>
game.<span class="hljs-operator"><span class="hljs-keyword">load</span>.spritesheet(<span class="hljs-string">'button'</span>, <span class="hljs-string">'../../assets/flixel-button.png'</span>, <span class="hljs-number">80</span>, <span class="hljs-number">20</span>);</span>
}</code></pre><br />
<p>The <a href="http://docs.phaser.io/Phaser.Loader.html"><code>Phaser.Loader</code></a> class functions are used to add the assets to the cache. The wall, floor and corridor tiles are simply flat colored 12x12 pixel sprites. I stole the flixel-button sprite from the Phaser examples.</p><br />
<hr><br />
<br />
<br />
<h3 id="let-there-be-tiles">Let there be Tiles</h3><br />
<p><code>create()</code> is where all the magic happens. Game objects are brought to life and given starting properties. </p><br />
<p>To draw our dungeon, I have used a <a href="http://docs.phaser.io/Phaser.Tilemap.html"><code>Phaser.tilemap</code></a> object. This comes with a lot of cool functions that I would otherwise have to write myself, if I had simply used regular Sprite objects. </p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs cs"> <span class="hljs-comment">// Creates a blank tilemap</span>
gmap = game.add.tilemap();
<span class="hljs-comment">// Add a Tileset image to the map</span>
gmap.addTilesetImage(<span class="hljs-string">'wall'</span>,<span class="hljs-string">'wall'</span>,<span class="hljs-number">12</span>,<span class="hljs-number">12</span>,<span class="hljs-keyword">null</span>,<span class="hljs-keyword">null</span>,<span class="hljs-number">0</span>);
gmap.addTilesetImage(<span class="hljs-string">'floor'</span>,<span class="hljs-string">'floor'</span>,<span class="hljs-number">12</span>,<span class="hljs-number">12</span>,<span class="hljs-keyword">null</span>,<span class="hljs-keyword">null</span>,<span class="hljs-number">1</span>);
gmap.addTilesetImage(<span class="hljs-string">'corridor'</span>,<span class="hljs-string">'corridor'</span>,<span class="hljs-number">12</span>,<span class="hljs-number">12</span>,<span class="hljs-keyword">null</span>,<span class="hljs-keyword">null</span>,<span class="hljs-number">2</span>);</code></pre><br />
<p>Once <code>gmap</code> is created we assign the assets that we had preloaded to it. Look at <a href="http://docs.phaser.io/Phaser.Tilemap.html#addTilesetImage">Phaser.Tilemap.addTilesetImage</a>:</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs erlang"><span class="hljs-function"><span class="hljs-title">addTilesetImage</span><span class="hljs-params">(tileset, key, tile<span class="hljs-variable">Width</span>, tile<span class="hljs-variable">Height</span>, tile<span class="hljs-variable">Margin</span>, tile<span class="hljs-variable">Spacing</span>, gid)</span></span></code></pre><br />
<p>Since I am using individual tile sprites, rather than a sprite sheet, I need to manually assign the <code>gid</code>. Else, the <code>gid</code> gets reset and reconfigured each time. Using 0, 1 and 2 for wall, grass and corridor works default with out <code>Dungeon.map</code>.</p><br />
<p>The tilemap object, <code>gmap</code> is a logic object. We still need a <a href="http://docs.phaser.io/Phaser.TilemapLayer.html"><code>Phaser.TilemapLayer</code></a> which would be the graphic representation of the tilemap. A tilemap can have multiple layers, and we can assign unique tiles to any layer. In our case, we just need one.</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs coffeescript"> <span class="hljs-regexp">//</span> Creates a <span class="hljs-keyword">new</span> blank layer <span class="hljs-keyword">and</span> sets the map dimensions.
layer0 = gmap.create(<span class="hljs-string">'layer0'</span>,MAP_SIZE,MAP_SIZE,<span class="hljs-number">12</span>,<span class="hljs-number">12</span>);
layer0.resizeWorld();
stats = Dungeon.getStats();
<span class="hljs-keyword">for</span> (<span class="hljs-reserved">var</span> i=<span class="hljs-number">0</span>; i<MAP_SIZE; i++) {
<span class="hljs-keyword">for</span>(<span class="hljs-reserved">var</span> j=<span class="hljs-number">0</span>; j<MAP_SIZE; j++) {
gmap.putTile(map[i][j],i,j,layer0);
}
}</code></pre><br />
<p>And now, the fun part. We finally assign our <code>map</code> to the tilemap on the appropriate layer. Here’s what <a href="http://docs.phaser.io/Phaser.Tilemap.html#putTile"><code>Phaser.putTile</code></a> takes:</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs erlang"><span class="hljs-function"><span class="hljs-title">putTile</span><span class="hljs-params">(tile, x, y, layer)</span></span></code></pre><br />
<p>Where, the first argument is the tile key that we had assigned during the <code>addTilesetImage</code> calls. Since, the <code>map</code> holds values 0,1 or 2, it fits along with keys that we had assigned. The <code>x,y</code> indicates the tile position in tile units (not pixels). The last argument adds our tile to our only layer.</p><br />
<p>I kinda just picked up the code by going over this <a href="http://examples.phaser.io/_site/view_full.html?d=tilemaps&f=blank+tilemap.js&t=blank%20tilemap">Blank Tilemap example</a> and the <a href="http://docs.phaser.io/Phaser.Tilemap.html">tilemap docs</a>, and a bit of trial and error.</p><br />
<p>The last part is creating the buttons that would re-generate the map and toggle displaying the Boxes. Once, again <a href="http://examples.phaser.io/_site/view_full.html?d=buttons&f=action+on+click.js&t=action%20on%20click">Phaser’s Button Example</a> gave me all that I needed. We also need a handle to the graphics object to draw the Boxes. Here’s the <a href="http://examples.phaser.io/_site/view_full.html?d=display&f=graphics.js&t=graphics">Phaser Display Graphics example</a>. The buttons, when clicked on will call <code>genMap()</code> and <code>toggleBox()</code></p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs oxygene"> game.<span class="hljs-keyword">add</span>.button( <span class="hljs-number">400</span>, <span class="hljs-number">256</span>, <span class="hljs-string">'button'</span>, genMap,this, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>);
game.<span class="hljs-keyword">add</span>.button( <span class="hljs-number">400</span>, <span class="hljs-number">300</span>, <span class="hljs-string">'button'</span>, toggleBox,this, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>);
marker = game.<span class="hljs-keyword">add</span>.graphics();</code></pre><br />
<p>If you run the game even with empty update() and render() functions, you’d see this: <br />
<br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQvCdTfdSJJahWHxDgzH_aXVhVDqvjTrI1P1Tb2TDh5b-nHTIFO3-Z46XRjkPBvfKBrnazaXadQUQTZWne8zk-9QzDcN-7EgeHomX-qPFbgKGibKG34o3o6Con7cRvKTPNVWRTb2GVJS0/s0/dungeonPhaser1.PNG" alt="enter image description here" title="dungeonPhaser1.PNG"></p><br />
<p>That’s just how awesome and simple Phaser is. All you had to do was load a few assets and assign them to game objects, and lo, Phaser handles the rest.</p><br />
<hr><br />
<h3 id="drawing-words">Drawing Words</h3><br />
<p>Honestly at this point, just with the <code>preload()</code> and <code>create()</code> functions, we are all set. The map would render onto the screen using the tile sprites we assigned. But, if I wanted to re-generate the map I would have no choice but to reload the page. That’s why we had added those buttons.</p><br />
<p><code>genMap()</code> repopulates the <code>map</code> array with a newly generated dungeon and reassigns the tiles on tilemap object. <code>toggleBox()</code> toggles a logic variable that records whether the Boxes need to be drawn or not and calls <code>drawBox()</code>. The tree object has the information for the boxes, yes? So, we <code>drawRect</code> with those dimensions using the Phaser graphics object, <code>marker</code>.</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">genMap</span><span class="hljs-params">()</span> {</span>
console.clear();
Dungeon.generate(MAP_SIZE);
<span class="hljs-comment">// Dungeon.print();</span>
map = Dungeon.getMap();
stats = Dungeon.getStats();
rooms = Dungeon.getRooms();
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i<MAP_SIZE; i++) {
<span class="hljs-keyword">for</span>(<span class="hljs-keyword">var</span> j=<span class="hljs-number">0</span>; j<MAP_SIZE; j++) {
gmap.putTile(map[i][j],i,j,layer0);
}
}
drawBox();
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">toggleBox</span><span class="hljs-params">()</span> {</span>
state_toggleBox = state_toggleBox? <span class="hljs-number">0</span>: <span class="hljs-number">1</span> ;
drawBox();
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">drawBox</span><span class="hljs-params">()</span> {</span>
<span class="hljs-keyword">if</span>(state_toggleBox){
marker.clear();
marker.lineStyle(<span class="hljs-number">4</span>, <span class="hljs-number">0x000000</span>, <span class="hljs-number">1</span>);
tree = Dungeon.getTree();
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> node <span class="hljs-keyword">in</span> tree) {
<span class="hljs-keyword">var</span> t = tree[node];
marker.drawRect(t.x*<span class="hljs-number">12</span>, t.y*<span class="hljs-number">12</span>, t.w*<span class="hljs-number">12</span>, t.h*<span class="hljs-number">12</span>);
}
} <span class="hljs-keyword">else</span> {
marker.clear();
}
}</code></pre><br />
<p><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNqHJg0jUqGkisfk0MbHqJlb_dTl3lJSYWd-Pf4u2sECgtw3Vbe5HAlHNKqkVAVQLDfAjTq674sG61hseo1KNCFDRM-_GjjS47ihnx7l8PSGKkMchQoPx8KGV0nDKqRdGB0zj34mLD8YA/s0/dungeonPhaser2.PNG" alt="enter image description here" title="dungeonPhaser2.PNG"></p><br />
<p>As a last feature, I wanted to display the sizes of each room at the center of the room. Used <a href="http://docs.phaser.io/Phaser.Utils.Debug.html#text">Phaser.debug.text</a>. All of these instructions would go into the <code>render()</code> command. The stats would be drawn in the corner and button text would be drawn over the buttons.</p><br />
<br />
<br />
<pre class="prettyprint"><code class=" hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">render</span><span class="hljs-params">()</span> {</span>
game.debug.text(<span class="hljs-string">"gen"</span>, <span class="hljs-number">400</span>+<span class="hljs-number">16</span>, <span class="hljs-number">256</span>+<span class="hljs-number">12</span>,<span class="hljs-string">'#F00'</span>);
game.debug.text(<span class="hljs-string">"box: "</span>+state_toggleBox, <span class="hljs-number">400</span>+<span class="hljs-number">5</span>, <span class="hljs-number">300</span>+<span class="hljs-number">14</span>, <span class="hljs-string">'#000'</span>);
<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>;
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> key <span class="hljs-keyword">in</span> stats) {
game.debug.text(key+<span class="hljs-string">": "</span>+stats[key], <span class="hljs-number">400</span>, <span class="hljs-number">48</span>+(i*<span class="hljs-number">16</span>));
i++;
}
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i<rooms.length; i++) {
<span class="hljs-keyword">var</span> r = rooms[i];
game.debug.text(r.w+<span class="hljs-string">"x"</span>+r.h, r.center.x*<span class="hljs-number">12</span>, r.center.y*<span class="hljs-number">12</span>);
}
}</code></pre><br />
<p>Adding simple text gave more depth to the whole thing. We are now Done! <br />
<br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK9SktrA9XuVMIneLVnoJlRrrFqDmGovvaVKDWWymAJm8V4kS-QbzgDESBuJ19FScvazDm1KLgkbYiP7WHeqY-f-RFO_MVQzL7WVfKst08A8iwi_Zosv3XMlZU1-zoyXzLuRqBJlDIZ5g/s0/dungeonPhaser3.PNG" alt="enter image description here" title="dungeonPhaser3.PNG"></p><br />
<p><i class="icon-gamepad"> <a href="toweroffun.bitballoon.com/games/dungeon">Play it</a></i></p><br />
<p><i class="icon-right"><a href="http://robotcantalk.blogspot.in/p/blog-page.html">Back to Tower of Fun Project</a></i></p></div>Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-16365621215638295492014-09-30T23:48:00.001-07:002014-10-02T01:32:20.266-07:00Hello StackEdit!<div dir="ltr" style="text-align: left;" trbidi="on">
<h1 id="welcome-to-stackedit">
Welcome to StackEdit!</h1>
The whole of this is what StackEdit can do. I am sabsolutely stunned. I don’t think I will ever go back to the vanilla Blogger Editor.<br />
<br />
I mean, look at the stuff I have already published using StackEdit:<br />
<a href="http://robotcantalk.blogspot.in/p/blog-page.html">http://robotcantalk.blogspot.in/p/blog-page.html</a><br />
<a href="http://robotcantalk.blogspot.in/2014/10/dungeon-drawing-in-phaser-using-tilemap.html">http://robotcantalk.blogspot.in/2014/10/dungeon-drawing-in-phaser-using-tilemap.html</a><br />
<a href="http://robotcantalk.blogspot.in/2014/09/dungeon-generator.html">http://robotcantalk.blogspot.in/2014/09/dungeon-generator.html</a><br />
<br />
<br />
Hey! I’m your first Markdown document in <strong>StackEdit</strong><a class="footnote" href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#fn:stackedit" id="fnref:stackedit" title="See footnote">1</a>. Don’t delete me, I’m very helpful! I can be recovered anyway in the <strong>Utils</strong> tab of the <i class="icon-cog"></i> <strong>Settings</strong> dialog.<br />
<br />
<br />
<a name='more'></a><br />
<br />
<h3 id="documents">
Documents</h3>
StackEdit stores your documents in your browser, which means all your documents are automatically saved locally and are accessible <strong>offline!</strong><br />
<blockquote>
<strong>Note:</strong><br />
<ul>
<li>StackEdit is accessible offline after the application has been loaded for the first time.</li>
<li>Your local documents are not shared between different browsers or computers.</li>
<li>Clearing your browser’s data may <strong>delete all your local documents!</strong> Make sure your documents are synchronized with <strong>Google Drive</strong> or <strong>Dropbox</strong> (check out the <a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#synchronization"><i class="icon-refresh"></i> Synchronization</a> section).</li>
</ul>
</blockquote>
<h4 id="create-a-document">
<i class="icon-file"></i> Create a document</h4>
The document panel is accessible using the <i class="icon-folder-open"></i> button in the navigation bar. You can create a new document by clicking <i class="icon-file"></i> <strong>New document</strong> in the document panel.<br />
<h4 id="switch-to-another-document">
<i class="icon-folder-open"></i> Switch to another document</h4>
All your local documents are listed in the document panel. You can switch from one to another by clicking a document in the list or you can toggle documents using <kbd>Ctrl+[</kbd> and <kbd>Ctrl+]</kbd>.<br />
<h4 id="rename-a-document">
<i class="icon-pencil"></i> Rename a document</h4>
You can rename the current document by clicking the document title in the navigation bar.<br />
<h4 id="delete-a-document">
<i class="icon-trash"></i> Delete a document</h4>
You can delete the current document by clicking <i class="icon-trash"></i> <strong>Delete document</strong> in the document panel.<br />
<h4 id="export-a-document">
<i class="icon-hdd"></i> Export a document</h4>
You can save the current document to a file by clicking <i class="icon-hdd"></i> <strong>Export to disk</strong> from the <i class="icon-provider-stackedit"></i> menu panel.<br />
<blockquote>
<strong>Tip:</strong> Check out the <a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#publish-a-document"><i class="icon-upload"></i> Publish a document</a> section for a description of the different output formats.</blockquote>
<hr />
<h3 id="synchronization">
Synchronization</h3>
StackEdit can be combined with <i class="icon-provider-gdrive"></i> <strong>Google Drive</strong> and <i class="icon-provider-dropbox"></i> <strong>Dropbox</strong> to have your documents saved in the <em>Cloud</em>. The synchronization mechanism takes care of uploading your modifications or downloading the latest version of your documents.<br />
<blockquote>
<strong>Note:</strong><br />
<ul>
<li>Full access to <strong>Google Drive</strong> or <strong>Dropbox</strong> is required to be able to import any document in StackEdit. Permission restrictions can be configured in the settings.</li>
<li>Imported documents are downloaded in your browser and are not transmitted to a server.</li>
<li>If you experience problems saving your documents on Google Drive, check and optionally disable browser extensions, such as Disconnect.</li>
</ul>
</blockquote>
<h4 id="open-a-document">
<i class="icon-refresh"></i> Open a document</h4>
You can open a document from <i class="icon-provider-gdrive"></i> <strong>Google Drive</strong> or the <i class="icon-provider-dropbox"></i> <strong>Dropbox</strong> by opening the <i class="icon-refresh"></i> <strong>Synchronize</strong> sub-menu and by clicking <strong>Open from…</strong>. Once opened, any modification in your document will be automatically synchronized with the file in your <strong>Google Drive</strong> / <strong>Dropbox</strong> account.<br />
<h4 id="save-a-document">
<i class="icon-refresh"></i> Save a document</h4>
You can save any document by opening the <i class="icon-refresh"></i> <strong>Synchronize</strong> sub-menu and by clicking <strong>Save on…</strong>. Even if your document is already synchronized with <strong>Google Drive</strong> or <strong>Dropbox</strong>, you can export it to a another location. StackEdit can synchronize one document with multiple locations and accounts.<br />
<h4 id="synchronize-a-document">
<i class="icon-refresh"></i> Synchronize a document</h4>
Once your document is linked to a <i class="icon-provider-gdrive"></i> <strong>Google Drive</strong> or a <i class="icon-provider-dropbox"></i> <strong>Dropbox</strong> file, StackEdit will periodically (every 3 minutes) synchronize it by downloading/uploading any modification. A merge will be performed if necessary and conflicts will be detected.<br />
If you just have modified your document and you want to force the synchronization, click the <i class="icon-refresh"></i> button in the navigation bar.<br />
<blockquote>
<strong>Note:</strong> The <i class="icon-refresh"></i> button is disabled when you have no document to synchronize.</blockquote>
<h4 id="manage-document-synchronization">
<i class="icon-refresh"></i> Manage document synchronization</h4>
Since one document can be synchronized with multiple locations, you can list and manage synchronized locations by clicking <i class="icon-refresh"></i> <strong>Manage synchronization</strong> in the <i class="icon-refresh"></i> <strong>Synchronize</strong> sub-menu. This will let you remove synchronization locations that are associated to your document.<br />
<blockquote>
<strong>Note:</strong> If you delete the file from <strong>Google Drive</strong> or from <strong>Dropbox</strong>, the document will no longer be synchronized with that location.</blockquote>
<hr />
<h3 id="publication">
Publication</h3>
Once you are happy with your document, you can publish it on different websites directly from StackEdit. As for now, StackEdit can publish on <strong>Blogger</strong>, <strong>Dropbox</strong>, <strong>Gist</strong>, <strong>GitHub</strong>, <strong>Google Drive</strong>, <strong>Tumblr</strong>, <strong>WordPress</strong> and on any SSH server.<br />
<h4 id="publish-a-document">
<i class="icon-upload"></i> Publish a document</h4>
You can publish your document by opening the <i class="icon-upload"></i> <strong>Publish</strong> sub-menu and by choosing a website. In the dialog box, you can choose the publication format:<br />
<ul>
<li>Markdown, to publish the Markdown text on a website that can interpret it (<strong>GitHub</strong> for instance),</li>
<li>HTML, to publish the document converted into HTML (on a blog for example),</li>
<li>Template, to have a full control of the output.</li>
</ul>
<blockquote>
<strong>Note:</strong> The default template is a simple webpage wrapping your document in HTML format. You can customize it in the <strong>Advanced</strong> tab of the <i class="icon-cog"></i> <strong>Settings</strong> dialog.</blockquote>
<h4 id="update-a-publication">
<i class="icon-upload"></i> Update a publication</h4>
After publishing, StackEdit will keep your document linked to that publication which makes it easy for you to update it. Once you have modified your document and you want to update your publication, click on the <i class="icon-upload"></i> button in the navigation bar.<br />
<blockquote>
<strong>Note:</strong> The <i class="icon-upload"></i> button is disabled when your document has not been published yet.</blockquote>
<h4 id="manage-document-publication">
<i class="icon-upload"></i> Manage document publication</h4>
Since one document can be published on multiple locations, you can list and manage publish locations by clicking <i class="icon-upload"></i> <strong>Manage publication</strong> in the <i class="icon-provider-stackedit"></i> menu panel. This will let you remove publication locations that are associated to your document.<br />
<blockquote>
<strong>Note:</strong> If the file has been removed from the website or the blog, the document will no longer be published on that location.</blockquote>
<hr />
<h3 id="markdown-extra">
Markdown Extra</h3>
StackEdit supports <strong>Markdown Extra</strong>, which extends <strong>Markdown</strong> syntax with some nice features.<br />
<blockquote>
<strong>Tip:</strong> You can disable any <strong>Markdown Extra</strong> feature in the <strong>Extensions</strong> tab of the <i class="icon-cog"></i> <strong>Settings</strong> dialog.<br />
<strong>Note:</strong> You can find more information about <strong>Markdown</strong> syntax <a href="http://daringfireball.net/projects/markdown/syntax" title="Markdown">here</a> and <strong>Markdown Extra</strong> extension <a href="https://github.com/jmcmanus/pagedown-extra" title="Pagedown Extra">here</a>.</blockquote>
<h3 id="tables">
Tables</h3>
<strong>Markdown Extra</strong> has a special syntax for tables:<br />
<table><thead>
<tr> <th>Item</th> <th>Value</th> </tr>
</thead> <tbody>
<tr> <td>Computer</td> <td>$1600</td> </tr>
<tr> <td>Phone</td> <td>$12</td> </tr>
<tr> <td>Pipe</td> <td>$1</td> </tr>
</tbody></table>
You can specify column alignment with one or two colons:<br />
<table><thead>
<tr> <th align="left">Item</th> <th align="right">Value</th> <th align="center">Qty</th> </tr>
</thead> <tbody>
<tr> <td align="left">Computer</td> <td align="right">$1600</td> <td align="center">5</td> </tr>
<tr> <td align="left">Phone</td> <td align="right">$12</td> <td align="center">12</td> </tr>
<tr> <td align="left">Pipe</td> <td align="right">$1</td> <td align="center">234</td> </tr>
</tbody></table>
<h3 id="definition-lists">
Definition Lists</h3>
<strong>Markdown Extra</strong> has a special syntax for definition lists too:<br />
<dl>
<dt>Term 1</dt>
<dt>Term 2</dt>
<dd>Definition A</dd> <dd>Definition B</dd>
<dt>Term 3</dt>
<dd>Definition C</dd> <dd>Definition D
<br />
<blockquote>
part of definition D</blockquote>
</dd> </dl>
<h3 id="fenced-code-blocks">
Fenced code blocks</h3>
GitHub’s fenced code blocks are also supported with <strong>Highlight.js</strong> syntax highlighting:<br />
<pre class="prettyprint"><code class=" hljs cs"><span class="hljs-comment">// Foo</span>
<span class="hljs-keyword">var</span> bar = <span class="hljs-number">0</span>;</code></pre>
<blockquote>
<strong>Tip:</strong> To use <strong>Prettify</strong> instead of <strong>Highlight.js</strong>, just configure the <strong>Markdown Extra</strong> extension in the <i class="icon-cog"></i> <strong>Settings</strong> dialog.<br />
<strong>Note:</strong> You can find more information:<br />
<ul>
<li>about <strong>Prettify</strong> syntax highlighting <a href="https://code.google.com/p/google-code-prettify/">here</a>,</li>
<li>about <strong>Highlight.js</strong> syntax highlighting <a href="http://highlightjs.org/">here</a>.</li>
</ul>
</blockquote>
<h3 id="footnotes">
Footnotes</h3>
You can create footnotes like this<a class="footnote" href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#fn:footnote" id="fnref:footnote" title="See footnote">2</a>.<br />
<h3 id="smartypants">
SmartyPants</h3>
SmartyPants converts ASCII punctuation characters into “smart” typographic punctuation HTML entities. For example:<br />
<table><thead>
<tr> <th></th> <th>ASCII</th> <th>HTML</th> </tr>
</thead> <tbody>
<tr> <td>Single backticks</td> <td><code>'Isn't this fun?'</code></td> <td>‘Isn’t this fun?’</td> </tr>
<tr> <td>Quotes</td> <td><code>"Isn't this fun?"</code></td> <td>“Isn’t this fun?”</td> </tr>
<tr> <td>Dashes</td> <td><code>-- is en-dash, --- is em-dash</code></td> <td>– is en-dash, — is em-dash</td> </tr>
</tbody></table>
<h3 id="table-of-contents">
Table of contents</h3>
You can insert a table of contents using the marker <code>[TOC]</code>:<br />
<br />
<div class="toc">
<div class="toc">
<ul>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#welcome-to-stackedit">Welcome to StackEdit!</a><ul>
<li><ul>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#documents">Documents</a><ul>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#create-a-document"> Create a document</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#switch-to-another-document"> Switch to another document</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#rename-a-document"> Rename a document</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#delete-a-document"> Delete a document</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#export-a-document"> Export a document</a></li>
</ul>
</li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#synchronization">Synchronization</a><ul>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#open-a-document"> Open a document</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#save-a-document"> Save a document</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#synchronize-a-document"> Synchronize a document</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#manage-document-synchronization"> Manage document synchronization</a></li>
</ul>
</li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#publication">Publication</a><ul>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#publish-a-document"> Publish a document</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#update-a-publication"> Update a publication</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#manage-document-publication"> Manage document publication</a></li>
</ul>
</li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#markdown-extra">Markdown Extra</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#tables">Tables</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#definition-lists">Definition Lists</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#fenced-code-blocks">Fenced code blocks</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#footnotes">Footnotes</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#smartypants">SmartyPants</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#table-of-contents">Table of contents</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#uml-diagrams">UML diagrams</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#support-stackedit">Support StackEdit</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
<br />
<h3 id="uml-diagrams">
UML diagrams</h3>
You can also render sequence diagrams like this:<br />
<div class="sequence-diagram">
<svg height="255" style="left: -0.5px; overflow: hidden; position: relative; top: -0.828125px;" version="1.1" width="393.125" xmlns="http://www.w3.org/2000/svg"><desc style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Created with Raphaël 2.1.0</desc><defs style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><path d="M5,0 0,2.5 5,5z" id="raphael-marker-block" stroke-linecap="round" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><marker id="raphael-marker-endblock55" markerheight="5" markerwidth="5" orient="auto" refx="2.5" refy="2.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use fill="#000" stroke-width="1.0000" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" transform="rotate(180 2.5 2.5) scale(1,1)" xlink:href="#raphael-marker-block"></use></marker></defs><rect fill="none" height="37" r="0" rx="0" ry="0" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" width="52.53125" x="10" y="20"></rect><rect fill="#ffffff" height="17" r="0" rx="0" ry="0" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" width="32.53125" x="20" y="30"></rect><text fill="#000000" font-family="Andale Mono, monospace" font-size="16px" font="10px "Arial"" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: 'Andale Mono', monospace; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: middle;" text-anchor="middle" x="36.265625" y="38.5"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Alice</tspan></text><rect fill="none" height="37" r="0" rx="0" ry="0" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" width="52.53125" x="10" y="198"></rect><rect fill="#ffffff" height="17" r="0" rx="0" ry="0" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" width="32.53125" x="20" y="208"></rect><text fill="#000000" font-family="Andale Mono, monospace" font-size="16px" font="10px "Arial"" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: 'Andale Mono', monospace; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: middle;" text-anchor="middle" x="36.265625" y="216.5"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Alice</tspan></text><path d="M36.265625,57L36.265625,198" fill="none" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect fill="none" height="37" r="0" rx="0" ry="0" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" width="46.71875" x="196.34375" y="20"></rect><rect fill="#ffffff" height="17" r="0" rx="0" ry="0" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" width="26.71875" x="206.34375" y="30"></rect><text fill="#000000" font-family="Andale Mono, monospace" font-size="16px" font="10px "Arial"" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: 'Andale Mono', monospace; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: middle;" text-anchor="middle" x="219.703125" y="38.5"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Bob</tspan></text><rect fill="none" height="37" r="0" rx="0" ry="0" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" width="46.71875" x="196.34375" y="198"></rect><rect fill="#ffffff" height="17" r="0" rx="0" ry="0" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" width="26.71875" x="206.34375" y="208"></rect><text fill="#000000" font-family="Andale Mono, monospace" font-size="16px" font="10px "Arial"" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: 'Andale Mono', monospace; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: middle;" text-anchor="middle" x="219.703125" y="216.5"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Bob</tspan></text><path d="M219.703125,57L219.703125,198" fill="none" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect fill="#ffffff" height="17" r="0" rx="0" ry="0" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" width="163.4375" x="46.265625" y="73.5"></rect><text fill="#000000" font-family="Andale Mono, monospace" font-size="16px" font="10px "Arial"" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: 'Andale Mono', monospace; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: middle;" text-anchor="middle" x="127.984375" y="82"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Hello Bob, how are you?</tspan></text><path d="M36.265625,94C36.265625,94,185.30177110433578,94,214.7014796131989,94" fill="none" marker-end="url(#raphael-marker-endblock55)" stroke-dasharray="0" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect fill="none" height="27" r="0" rx="0" ry="0" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" width="80.0625" x="239.703125" y="114"></rect><rect fill="#ffffff" height="17" r="0" rx="0" ry="0" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" width="70.0625" x="244.703125" y="119"></rect><text fill="#000000" font-family="Andale Mono, monospace" font-size="16px" font="10px "Arial"" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: 'Andale Mono', monospace; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: middle;" text-anchor="middle" x="279.734375" y="127.5"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Bob thinks</tspan></text><rect fill="#ffffff" height="17" r="0" rx="0" ry="0" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" width="119.25" x="68.359375" y="157.5"></rect><text fill="#000000" font-family="Andale Mono, monospace" font-size="16px" font="10px "Arial"" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: 'Andale Mono', monospace; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: middle;" text-anchor="middle" x="127.984375" y="166"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">I am good thanks!</tspan></text><path d="M219.703125,178C219.703125,178,70.66697889566422,178,41.2672703868011,178" fill="none" marker-end="url(#raphael-marker-endblock55)" stroke-dasharray="6,2" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path></svg></div>
And flow charts like this:<br />
<div class="flow-chart">
<svg height="349.78515625" style="overflow: hidden; position: relative; top: -0.421875px;" version="1.1" width="186.5703125" xmlns="http://www.w3.org/2000/svg"><desc style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Created with Raphaël 2.1.0</desc><defs style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><marker id="raphael-marker-endblock33" markerheight="3" markerwidth="3" orient="auto" refx="1.5" refy="1.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use fill="black" stroke-width="1.6667" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" transform="rotate(180 1.5 1.5) scale(0.6,0.6)" xlink:href="#raphael-marker-block"></use></marker></defs><rect fill="#ffffff" height="37" r="20" rx="20" ry="20" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" transform="matrix(1,0,0,1,54.9414,2)" width="51.6875" x="0" y="0"></rect><text fill="#000000" font-family="sans-serif" font-size="14px" font-weight="normal" font="10px "Arial"" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: start;" text-anchor="start" transform="matrix(1,0,0,1,54.9414,2)" x="10" y="18.5"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Start</tspan></text><rect fill="#ffffff" height="37" r="0" rx="0" ry="0" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" transform="matrix(1,0,0,1,25.7617,91)" width="110.046875" x="0" y="0"></rect><text fill="#000000" font-family="sans-serif" font-size="14px" font-weight="normal" font="10px "Arial"" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: start;" text-anchor="start" transform="matrix(1,0,0,1,25.7617,91)" x="10" y="18.5"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">My Operation</tspan></text><path d="M39.392578125,19.6962890625L0,39.392578125L78.78515625,78.78515625L157.5703125,39.392578125L78.78515625,0L0,39.392578125" fill="#ffffff" font-family="sans-serif" font-weight="normal" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;" transform="matrix(1,0,0,1,2,180)"></path><text fill="#000000" font-family="sans-serif" font-size="14px" font-weight="normal" font="10px "Arial"" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: start;" text-anchor="start" transform="matrix(1,0,0,1,2,180)" x="44.392578125" y="39.392578125"><tspan dy="5.494140625" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Yes or No?</tspan><tspan dy="18" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" x="44.392578125"></tspan></text><rect fill="#ffffff" height="37" r="20" rx="20" ry="20" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" transform="matrix(1,0,0,1,57.4336,310.7852)" width="46.703125" x="0" y="0"></rect><text fill="#000000" font-family="sans-serif" font-size="14px" font-weight="normal" font="10px "Arial"" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: start;" text-anchor="start" transform="matrix(1,0,0,1,57.4336,310.7852)" x="10" y="18.5"><tspan dy="5.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">End</tspan></text><path d="M80.78515625,39C80.78515625,39,80.78515625,76.92477893829346,80.78515625,87.99851810093969" fill="none" font-family="sans-serif" font-weight="normal" marker-end="url(#raphael-marker-endblock33)" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path d="M80.78515625,128C80.78515625,128,80.78515625,165.92477893829346,80.78515625,176.9985181009397" fill="none" font-family="sans-serif" font-weight="normal" marker-end="url(#raphael-marker-endblock33)" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><path d="M80.78515625,258.78515625C80.78515625,258.78515625,80.78515625,296.70993518829346,80.78515625,307.7836743509397" fill="none" font-family="sans-serif" font-weight="normal" marker-end="url(#raphael-marker-endblock33)" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><text fill="#000000" font-family="sans-serif" font-size="14px" font-weight="normal" font="10px "Arial"" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: start;" text-anchor="start" x="85.78515625" y="268.78515625"><tspan dy="5.49609375" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">yes</tspan></text><path d="M159.5703125,219.392578125C159.5703125,219.392578125,184.5703125,219.392578125,184.5703125,219.392578125C184.5703125,219.392578125,184.5703125,66,184.5703125,66C184.5703125,66,80.78515625,66,80.78515625,66C80.78515625,66,80.78515625,81.37344455718994,80.78515625,88.00924777425826" fill="none" font-family="sans-serif" font-weight="normal" marker-end="url(#raphael-marker-endblock33)" stroke-width="2" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-weight: normal;"></path><text fill="#000000" font-family="sans-serif" font-size="14px" font-weight="normal" font="10px "Arial"" stroke="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-anchor: start;" text-anchor="start" x="164.5703125" y="209.392578125"><tspan dy="5.494140625" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">no</tspan></text></svg></div>
<blockquote>
<strong>Note:</strong> You can find more information:<br />
<ul>
<li>about <strong>Sequence diagrams</strong> syntax <a href="http://bramp.github.io/js-sequence-diagrams/">here</a>,</li>
<li>about <strong>Flow charts</strong> syntax <a href="http://adrai.github.io/flowchart.js/">here</a>.</li>
</ul>
</blockquote>
<h3 id="support-stackedit">
Support StackEdit</h3>
<a href="https://monetizejs.com/authorize?client_id=ESTHdCYOi18iLhhO&summary=true"><img alt="" src="https://cdn.monetizejs.com/resources/button-32.png" title="" /></a><br />
<div class="footnotes">
<hr />
<ol>
<li id="fn:stackedit"><a href="https://stackedit.io/">StackEdit</a> is a full-featured, open-source Markdown editor based on PageDown, the Markdown library used by Stack Overflow and the other Stack Exchange sites. <a class="reversefootnote" href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#fnref:stackedit" title="Return to article">↩</a></li>
<li id="fn:footnote">Here is the <em>text</em> of the <strong>footnote</strong>. <a class="reversefootnote" href="https://www.blogger.com/blogger.g?blogID=5309295576532710519#fnref:footnote" title="Return to article">↩</a></li>
</ol>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-70486778720928727252014-09-30T04:25:00.000-07:002014-10-02T01:10:34.192-07:00Project: Tower of Fun<div dir="ltr" style="text-align: left;" trbidi="on"><div><div>I am not really sure how I ended up here, but I like it and I think I shall continue while the interest lasts. It's been a month or two since I began <a href="http://robotcantalk.blogspot.in/2014/08/dabbling-with-web.html" target="_blank">dabbling with the web</a>, and one fine day, last week I had decided to implement a dungeon generator. There's a fancy word for this -"Procedural Content Generation" - <a href="http://pcg.wikidot.com/" target="_blank">wiki</a>, I think. The end game I have in my mind is probably some sort of minimalist roguelike built on html5 and Javascript.</div></div><div><br />
<a name='more'></a><br />
</div><div>I decided to pick <a href="http://phaser.io/" target="_blank">Phaser</a> as the game engine, primarily because it's ridiculously easy to use. Phaser has simple ways to deal with complex tasks such as collision and physics and, handles these in the background while you work on the real game logic. Not to forget the abundance of documentation and a helpful online community. I tried getting my hands dirty with <a href="http://craftyjs.com/" target="_blank">craftyJS</a>, and I really - <i>REALLY </i>liked the <a href="http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/" target="_blank">Entity-Component System</a> (ECS) it implemented. But, it just didn't offer the breadth of functionality or documentation or ease that Phaser did. I might move to <a href="http://www.html5quintus.com/" target="_blank">Quintus </a>(which also implements an ECS) if it becomes mature enough. I like ECS. It just clicks with me.</div><div><br />
</div><div><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihNcwzVc-xqN2jrEEJ94XNd7_2dEFo1FOqsf68aO4vQh1ljAia5aRHbeHhPGJzpOu5FiBtkqx2d8ezNe3L2sWB0EKONpktu1ldLHITWPfl-jUvzrW4XEPo9PVhyphenhyphenND2rRWHtiQ5PbKGL6k/s1600/header.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihNcwzVc-xqN2jrEEJ94XNd7_2dEFo1FOqsf68aO4vQh1ljAia5aRHbeHhPGJzpOu5FiBtkqx2d8ezNe3L2sWB0EKONpktu1ldLHITWPfl-jUvzrW4XEPo9PVhyphenhyphenND2rRWHtiQ5PbKGL6k/s1600/header.jpg" height="224" width="320" /></a></div><div><br />
<div><br />
</div><div>Here's the <a href="http://robotcantalk.blogspot.in/2014/09/dungeon-generator.html" target="_blank">Dungeon Generator</a> I had made last week. Uses a simple Binary Space Partitioning technique to carve out rooms and corridors. Portray's Phaser's amazing tilemap and tilemaplayer class in action.</div></div><div><br />
</div><div>Soon after that, I had gone through a few more tutorials on Phaser and kinda built an idea of how a game in Phaser is structured. The states and various function calls finally made sense to me. I have to admit, vacillating between having to choose craftyJS, Quintus and Phaser has given me quit a nightmare and a helped build my perspective on engines in general. I spend days googling strings like "<i>Phaser vs</i>" or "<i>Quintus vs Phaser</i>" or "<i>craftyJS dungeon</i>". I guess this would be a phase ever gameDevNoob would go through if they were just figuring out the awesomeness of html5 game engines and had to pick one (out of many amazing ones).</div><div><br />
</div><h3 style="text-align: left;">Phaser</h3><div>Link : <a href="http://phaser.io/">http://phaser.io/</a> - <a href="http://www.lessmilk.com/phaser-tutorial/" target="_blank">Phaser Tutorial Repository</a> & <a href="http://examples.phaser.io/" target="_blank">Phaser Examples</a></div><div><br />
</div><div>A whole bunch of other Phaser related links:</div><div><br />
</div><div><a href="http://www.photonstorm.com/phaser/tutorial-making-your-first-phaser-game">http://www.photonstorm.com/phaser/tutorial-making-your-first-phaser-game</a></div><div><a href="http://gamedevelopment.tutsplus.com/articles/how-to-learn-the-phaser-html5-game-engine--gamedev-13643">http://gamedevelopment.tutsplus.com/articles/how-to-learn-the-phaser-html5-game-engine--gamedev-13643</a></div><div><a href="http://www.lessmilk.com/games/11/">http://www.lessmilk.com/games/11/</a></div><div><a href="http://svejkgames.com/blog/post/phaser-framework-tutorial/">http://svejkgames.com/blog/post/phaser-framework-tutorial/</a></div><div><a href="http://toastedware.com/?p=258">http://toastedware.com/?p=258</a></div><div><a href="http://www.gamedevacademy.org/category/tutorials/">http://www.gamedevacademy.org/category/tutorials/</a></div><div><a href="http://blog.lessmilk.com/make-html5-games-with-phaser-1/">http://blog.lessmilk.com/make-html5-games-with-phaser-1/</a></div><div><a href="http://www.codevinsky.com/phaser-2-0-tutorial-flappy-bird-part-1/">http://www.codevinsky.com/phaser-2-0-tutorial-flappy-bird-part-1/</a></div><div><a href="http://www.html5gamedevs.com/topic/7992-the-wizard-turn-based-dungeon-puzzler-release-july-23rd-phaser/">http://www.html5gamedevs.com/topic/7992-the-wizard-turn-based-dungeon-puzzler-release-july-23rd-phaser/</a></div><div><a href="http://www.sitepoint.com/javascript-game-programming-using-phaser/">http://www.sitepoint.com/javascript-game-programming-using-phaser/</a></div><div><a href="http://jsfiddle.net/dirkk0/4C8kk/">http://jsfiddle.net/dirkk0/4C8kk/</a></div><div><a href="http://gamedevelopment.tutsplus.com/tutorials/getting-started-with-phaser-building-monster-wants-candy--cms-21723">http://gamedevelopment.tutsplus.com/tutorials/getting-started-with-phaser-building-monster-wants-candy--cms-21723</a></div><div><a href="http://gamedolph.in/tutorials/state-management-tiny-tutorial/">http://gamedolph.in/tutorials/state-management-tiny-tutorial/</a></div><div><a href="http://gamedolph.in/tutorials/setting-up-a-phaser-project/">http://gamedolph.in/tutorials/setting-up-a-phaser-project/</a></div><div><a href="https://github.com/photonstorm/phaser/wiki/Phaser-General-Documentation-:-States">https://github.com/photonstorm/phaser/wiki/Phaser-General-Documentation-:-States</a></div><div><a href="https://github.com/EnclaveGames/Cyber-Orb/tree/gh-pages/src">https://github.com/EnclaveGames/Cyber-Orb/tree/gh-pages/src</a></div><div><a href="http://stackoverflow.com/questions/22069816/wait-for-click-before-starting-the-game-in-phaser">http://stackoverflow.com/questions/22069816/wait-for-click-before-starting-the-game-in-phaser</a></div><div><br />
</div><div><br />
</div><h3 style="text-align: left;">html5 game engines</h3><div><a href="http://html5gameengine.com/">http://html5gameengine.com/</a> : Shows a popularity index</div><div><a href="http://www.jsbreakouts.org/" target="_blank">Breakout Project</a> : Implementation of the classic Breakouts on various game engines to help you pick one.</div><div><a href="http://buildnewgames.com/game-engine-comparison/">http://buildnewgames.com/game-engine-comparison/</a></div><div><br />
</div><div><br />
</div><h3 style="text-align: left;">Articles on ECS</h3><div><a href="http://gameprogrammingpatterns.com/component.html">http://gameprogrammingpatterns.com/component.html</a></div><div><a href="http://www.reddit.com/r/gamedev/comments/1f83c5/3_articles_about_component_entity_systems/">http://www.reddit.com/r/gamedev/comments/1f83c5/3_articles_about_component_entity_systems/</a></div><div><a href="http://www.tomseysdavies.com/2011/01/15/game-architecture/">http://www.tomseysdavies.com/2011/01/15/game-architecture/</a></div><div><br />
</div><h3 style="text-align: left;">CraftyJS</h3><div><a href="http://craftyjs.com/">http://craftyjs.com/</a></div><div><a href="http://cykod.github.io/Presentations/HTML5/Crafty/">http://cykod.github.io/Presentations/HTML5/Crafty/</a></div><div><a href="http://buildnewgames.com/introduction-to-crafty/">http://buildnewgames.com/introduction-to-crafty/</a></div><div><a href="http://www.xlr8.at/rpg/">http://www.xlr8.at/rpg/</a></div><div><a href="http://dailyjs.com/2011/02/11/crafty/">http://dailyjs.com/2011/02/11/crafty/</a></div><div><a href="https://developer.tizen.org/documentation/articles/game-development-craftyjs-library-introduction">https://developer.tizen.org/documentation/articles/game-development-craftyjs-library-introduction</a></div><div><br />
</div><div><br />
</div><h3 style="text-align: left;">Quintus</h3><div><a href="http://www.html5quintus.com/">http://www.html5quintus.com/</a></div><div><a href="http://html5gametutorial.com/">http://html5gametutorial.com/</a></div><div><a href="http://www.remcodraijer.nl/quintus/tutorial.html">http://www.remcodraijer.nl/quintus/tutorial.html</a></div><div><a href="http://html5gametutorial.com/tutorial/game1-tower-man/">http://html5gametutorial.com/tutorial/game1-tower-man/</a></div><div><br />
</div><h3 style="text-align: left;">Back on Track</h3><div>Picking up game dev as hobby again brings back memories. Especially trying it out on a new platform on an all new engine. The last time I had tried something like this, was back in school. I had used C++ on the <a href="http://hge.relishgames.com/" target="_blank">HGE engine</a> to build a pretty ok tank<i> Shoot'em Up</i> (shump). I don't even want to talk about my experiences with Allegro.</div><div><br />
</div><div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/s4cRETqOeLg?feature=player_embedded' frameborder='0'></iframe></div><div></div><div>I got myself an account on <a href="https://www.bitballoon.com/" target="_blank">BitBalloon</a> and hosted my <i>Work-In-Progress</i>.</div><div></div><div>Tower of Fun is going to be a infinite procedurally generated top-down shump roguelike with probably some unique features that I have in mind. Too many keywords... ya, I am aware. </div><div></div><div>Tower of Fun : <a href="http://toweroffun.bitballoon.com/">http://toweroffun.bitballoon.com/</a></div><div></div><div>Once I figure out how to use bitbucket or Git in general (read: noob) I shall write up on ToFv1 and ToFv2. Well, for now, you can see how it's going in the above link. </div><div></div><div>I draw my own sprites. :) edit: Ha! Girlfriend taught me how to use github. Source code's here - <a href="https://github.com/SonalPinto/TowerOfFun" target="_blank">TowerOfFun</a> </div>
<i class="icon-right"><a href="http://robotcantalk.blogspot.in/p/blog-page.html">Back to TowerOfFun Project</a></i></div>Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com1tag:blogger.com,1999:blog-5309295576532710519.post-23282437646174680302014-09-26T21:08:00.000-07:002014-10-02T00:59:40.104-07:00Dungeon Generator<div dir="ltr" style="text-align: left;" trbidi="on"><br />
<div style="text-align: left;">Look! A Dungeon Generator. Once you have played enough dungeon crawlers, you just <b><i>have </i></b>to build your own dungeon crawler (#<i>amiright</i>?!). Since, my current fascination is web development (read: <a href="http://robotcantalk.blogspot.in/2014/08/dabbling-with-web.html" target="_blank">Dabbling</a>, look at that neat calculator), I figured I might as well make a web game. Playing <a href="http://www.orangepixel.net/heroesofloot/" target="_blank">Heroes of Loot</a> might have had something to do with this.</div><div style="text-align: left;"><br />
</div><div style="text-align: left;">A procedural generated fast-paced infinite dungeon crawler is what I have in mind. Hence, first off, I need a neat Dungeon Generating algorithm. You know... those rooms and corridors. </div><div style="text-align: left;"><br />
<a name='more'></a><br />
</div><div style="text-align: left;">I looked at a few algorithm, and finally settles with the <a href="http://en.wikipedia.org/wiki/Binary_space_partitioning" target="_blank">BSP</a> (Binary Space Partitioning) Trees method. Here, have a look at the <a href="http://doryen.eptalys.net/articles/bsp-dungeon-generation/" target="_blank">algorithm</a>. The link explains the overall idea pretty well, aye? I implemented it in Javascript.</div><iframe allowfullscreen="allowfullscreen" frameborder="0" height="450" src="http://jsfiddle.net/sonalpinto/76u0pte1/6/embedded/result,js,html/" width="100%"></iframe> <br />
<div style="text-align: left;"><br />
Edit: Hosted on <a href="http://toweroffun.bitballoon.com/">http://toweroffun.bitballoon.com/</a> (Didn't add a preloader, because I didn't know how to use states when I made this).<br />
Also look at this - <a href="http://robotcantalk.blogspot.in/p/blog-page.html" target="_blank">Tower of Fun</a> - My new hobby project!<br />
<br />
</div><h3 style="text-align: left;">Getting right to it</h3><div>Source: <a href="https://github.com/SonalPinto/TowerOfFun/tree/master/games/dungeon" target="_blank">Github : TowerOfFun/games/dungeon</a></div><div><br />
</div><div>Docs:</div><div><br />
</div><div>Write a default <a href="https://github.com/SonalPinto/TowerOfFun/blob/master/games/dungeon/index.html" target="_blank">index.html </a>and place a div for the Phaser Engine to start in. <a href="https://github.com/SonalPinto/TowerOfFun/blob/master/games/dungeon/js/dungeon.js" target="_blank"> dungeon.js</a> hosts the Dungeon object that actually houses the dungeon generation algorithm. <a href="https://github.com/SonalPinto/TowerOfFun/blob/master/games/dungeon/js/main.js">main.js</a> houses the Phaser engine code.<br />
<br />
It would be wise through go through some Phaser documentation that I linked on this <a href="http://robotcantalk.blogspot.in/2014/09/project-tower-of-fun.html">Tower of Fun </a>post before delving into main.js.<br />
<br />
</div>Before we head further, I really hope you have read this - <a href="http://doryen.eptalys.net/articles/bsp-dungeon-generation/">Dungeon Generation using BSP</a><br />
OK! <a href="https://github.com/SonalPinto/TowerOfFun/blob/master/games/dungeon/js/dungeon.js"><code>dungeon.js</code></a> defines <code>Dungeon</code>, the object that does all the fancy procedural generation. If you looked at the source, it has these.<br />
<dl><dt><i class="icon-plus-squared">map</i></dt>
<dd>A 2D array that stores the integer indices for tile types. Here we have 3 types of tiles. Logically, we’d only need 2 types of tiles - walkable and non-walkable. But, I just wanted to extend it to this: * 0 - non-walkable tiles (grey in the jsFiddle above) * 1 - walkable room tile (green) * 2 - walkable corridor tile (blue)</dd>
<dt><i class="icon-plus-squared">map_size</i></dt>
<dd>The size of the tile grid, say 32x32</dd>
<dt><i class="icon-plus-squared">rooms</i></dt>
<dd>A list that stores the rooms that we would generate</dd>
<dt><i class="icon-plus-squared">stats</i></dt>
<dd>An object to store results, like number of rooms and some config parameters that you’ll see below.</dd>
<dt><i class="icon-plus-squared">tree</i></dt>
<dd>To BSP the grid, we need to store the “sub-Boxes” in a tree. That’s what this is for.</dd>
<dt><i class="icon-plus-squared">stack</i></dt>
<dd>Each time we create child nodes on the tree, ie: new sub-Boxes in a big Box, we push information about that pair onto the stack. Later on, once all rooms are built, and it’s time to place the corridors, we pop each pair of this stack and “join” the rooms</dd>
<dt><i class="icon-plus-squared">gid</i></dt>
<dd>Updates each time a new tree node is created. I wanted each node to have a unique ID, and the tree traversal is recursive, hence, keeping a global ID tracker was useful.</dd>
<dt><i class="icon-plus-squared">minRoomSize</i></dt>
<dd>Minimum Room Size. What did you think <code>min</code> stood for?</dd>
<dt><i class="icon-plus-squared">minSizeFactor</i></dt>
<dd>Alright, this one isn’t intuitive as the last one. This states the minimum ratio in which a box can be split into 2 smaller boxes. This ensures not having really small boxes or really big boxes.</dd> </dl><hr />The main function in the <code>Dungeon</code> object is <code>Dungeon.generate()</code>. It starts of by clearing all variables and the setting the <code>map</code> array to default values (all to 0 - walls). Next, a root node is create in the tree. The root node will be the biggest “Box”. The root Box is kept slightly smaller than the map as we would want the map to be fully enclosed, ie: no walkable tile touches the edge of the map.<br />
<pre class="prettyprint"><code class=" hljs cs"> <span class="hljs-keyword">var</span> X=<span class="hljs-number">1</span>;
<span class="hljs-keyword">var</span> Y=<span class="hljs-number">1</span>;
<span class="hljs-keyword">var</span> W=<span class="hljs-keyword">this</span>.map_size-<span class="hljs-number">2</span>;
<span class="hljs-keyword">var</span> H=<span class="hljs-keyword">this</span>.map_size-<span class="hljs-number">2</span>;
<span class="hljs-comment">// Root Node</span>
<span class="hljs-keyword">var</span> rootBox={};
rootBox.x = X;
rootBox.y = Y;
rootBox.w = W;
rootBox.h = H;
<span class="hljs-keyword">this</span>.tree[<span class="hljs-keyword">this</span>.gid]=rootBox;
<span class="hljs-keyword">this</span>.gid++;
<span class="hljs-comment">// Build Tree</span>
<span class="hljs-keyword">this</span>.buildTree(<span class="hljs-number">1</span>);</code></pre>The root Box gets added to <code>Dungeon.tree</code> and the <code>Dungeon.gid</code> is incremented. <code>Dungeon.buildTree()</code> is called. This is going to recursively try to split the root Box into smaller boxes, until it hits the limit <code>minRoomSize</code>, ie: child boxes would not be able to house a room of <code>minRoomSize</code>.<br />
Look at the <code>Dungeon.buildTree()</code> method:<br />
<pre class="prettyprint"><code class=" hljs coffeescript"> <span class="hljs-regexp">//</span> Select a split - Horizontal((<span class="hljs-number">0</span>) <span class="hljs-keyword">or</span> Vertical(<span class="hljs-number">1</span>)
<span class="hljs-regexp">//</span> This allows you to have a valid splitType oppurtunity
<span class="hljs-reserved">var</span> splitType=<span class="hljs-number">1</span>;
<span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.minSizeFactor*W < <span class="hljs-keyword">this</span>.minRoomSize){
<span class="hljs-regexp">//</span> <span class="hljs-literal">no</span> space <span class="hljs-keyword">for</span> splitting vertically, <span class="hljs-keyword">try</span> Horizontal
splitType = <span class="hljs-number">0</span>;
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.minSizeFactor*H < <span class="hljs-keyword">this</span>.minRoomSize){
<span class="hljs-regexp">//</span> <span class="hljs-literal">no</span> space <span class="hljs-keyword">for</span> splitting vertically, <span class="hljs-keyword">try</span> Vertical
splitType = <span class="hljs-number">1</span>;
} <span class="hljs-keyword">else</span> {
<span class="hljs-regexp">//</span> random - Both H <span class="hljs-keyword">and</span> V are valid splits
<span class="hljs-keyword">if</span>(Math.random()><span class="hljs-number">0.5</span>){splitType=<span class="hljs-number">0</span>;}
}</code></pre>When splitting a parent Box, we have a choice to split vertically or horizontally. Once that choice is made, two child Boxes will be created. For a vertical split,<br />
<pre class="prettyprint"><code class=" hljs avrasm"> roomSize = this<span class="hljs-preprocessor">.minSizeFactor</span>*W<span class="hljs-comment">;</span>
if(roomSize >= this<span class="hljs-preprocessor">.minRoomSize</span>){
var w1 = randPlus(roomSize, (W-roomSize))<span class="hljs-comment">;</span>
var w2 = W - w1<span class="hljs-comment">;</span>
var box1={}<span class="hljs-comment">;</span>
box1<span class="hljs-preprocessor">.x</span> = <span class="hljs-built_in">X</span><span class="hljs-comment">;</span>
box1<span class="hljs-preprocessor">.y</span> = <span class="hljs-built_in">Y</span><span class="hljs-comment">;</span>
box1<span class="hljs-preprocessor">.w</span> = w1<span class="hljs-comment">;</span>
box1<span class="hljs-preprocessor">.h</span> = H<span class="hljs-comment">;</span>
box1<span class="hljs-preprocessor">.alignment</span> = <span class="hljs-string">'V'</span><span class="hljs-comment">;</span>
var box2={}<span class="hljs-comment">;</span>
box2<span class="hljs-preprocessor">.x</span> = <span class="hljs-built_in">X</span>+w1<span class="hljs-comment">;</span>
box2<span class="hljs-preprocessor">.y</span> = <span class="hljs-built_in">Y</span><span class="hljs-comment">;</span>
box2<span class="hljs-preprocessor">.w</span> = w2<span class="hljs-comment">;</span>
box2<span class="hljs-preprocessor">.h</span> = H<span class="hljs-comment">;</span>
box2<span class="hljs-preprocessor">.alignment</span> = <span class="hljs-string">'V'</span><span class="hljs-comment">;</span>
ok++<span class="hljs-comment">;</span>
}</code></pre>Similarly, child boxes would be created if the split was horizontal. Finally, if a split was truly done, then the child nodes will be added to the tree under the parent node that they were split from.<br />
<pre class="prettyprint"><code class=" hljs avrasm"> this<span class="hljs-preprocessor">.tree</span>[this<span class="hljs-preprocessor">.gid</span>]=box1<span class="hljs-comment">;</span>
this<span class="hljs-preprocessor">.tree</span>[root]<span class="hljs-preprocessor">.L</span> = this<span class="hljs-preprocessor">.gid</span><span class="hljs-comment">;</span>
this<span class="hljs-preprocessor">.gid</span>++<span class="hljs-comment">;</span>
this<span class="hljs-preprocessor">.tree</span>[this<span class="hljs-preprocessor">.gid</span>]=box2<span class="hljs-comment">;</span>
this<span class="hljs-preprocessor">.tree</span>[root]<span class="hljs-preprocessor">.R</span> = this<span class="hljs-preprocessor">.gid</span><span class="hljs-comment">;</span>
this<span class="hljs-preprocessor">.gid</span>++<span class="hljs-comment">;</span>
this<span class="hljs-preprocessor">.stack</span><span class="hljs-preprocessor">.push</span>([this<span class="hljs-preprocessor">.tree</span>[root]<span class="hljs-preprocessor">.L</span>,this<span class="hljs-preprocessor">.tree</span>[root]<span class="hljs-preprocessor">.R</span>])<span class="hljs-comment">;</span>
this<span class="hljs-preprocessor">.buildTree</span>(this<span class="hljs-preprocessor">.tree</span>[root]<span class="hljs-preprocessor">.L</span>)<span class="hljs-comment">;</span>
this<span class="hljs-preprocessor">.buildTree</span>(this<span class="hljs-preprocessor">.tree</span>[root]<span class="hljs-preprocessor">.R</span>)</code></pre>You can see that the <code>Dungeon.gid</code> will be unique for every box. The pair of ids will be pushed onto the <code>Dungeon.stack</code> for later use. Now, that we have child boxes, they grow up to be parents and we call <code>Dungeon.buildTree</code> on them too.<br />
When all boxes are discovered and a full <code>Dungeon.tree</code> is ready, we carve out rooms in the leaf nodes in that tree. A leaf node is easily identified by the lack of child nodes. Room objects are created with position and dimension properties. The ID of the Box is copied over to the room. Once all the rooms are conceived, the <code>Dungeon.map</code> is updated, ie: the indices on the map that overlap the rooms are flipped to 1 (walkable).<br />
<pre class="prettyprint"><code class=" hljs avrasm"> // Next, build rooms <span class="hljs-keyword">in</span> the leaf nodes of the tree
for (var nodeID <span class="hljs-keyword">in</span> this<span class="hljs-preprocessor">.tree</span>){
var node = this<span class="hljs-preprocessor">.tree</span>[nodeID]<span class="hljs-comment">;</span>
if(node<span class="hljs-preprocessor">.hasOwnProperty</span>(<span class="hljs-string">"L"</span>)){continue<span class="hljs-comment">;}</span>
var room = {}<span class="hljs-comment">;</span>
room<span class="hljs-preprocessor">.w</span> = randPlus(this<span class="hljs-preprocessor">.minRoomSize</span>, node<span class="hljs-preprocessor">.w</span>)<span class="hljs-comment">;</span>
room<span class="hljs-preprocessor">.h</span> = randPlus(this<span class="hljs-preprocessor">.minRoomSize</span>, node<span class="hljs-preprocessor">.h</span>)<span class="hljs-comment">;</span>
room<span class="hljs-preprocessor">.x</span> = node<span class="hljs-preprocessor">.x</span> + Math<span class="hljs-preprocessor">.floor</span>((node<span class="hljs-preprocessor">.w</span>-room<span class="hljs-preprocessor">.w</span>)/<span class="hljs-number">2</span>)<span class="hljs-comment">;</span>
room<span class="hljs-preprocessor">.y</span> = node<span class="hljs-preprocessor">.y</span> + Math<span class="hljs-preprocessor">.floor</span>((node<span class="hljs-preprocessor">.h</span>-room<span class="hljs-preprocessor">.h</span>)/<span class="hljs-number">2</span>)<span class="hljs-comment">;</span>
room<span class="hljs-preprocessor">.center</span>={}<span class="hljs-comment">;</span>
room<span class="hljs-preprocessor">.center</span><span class="hljs-preprocessor">.x</span> = Math<span class="hljs-preprocessor">.floor</span>(room<span class="hljs-preprocessor">.x</span> + room<span class="hljs-preprocessor">.w</span>/<span class="hljs-number">2</span>)<span class="hljs-comment">;</span>
room<span class="hljs-preprocessor">.center</span><span class="hljs-preprocessor">.y</span> = Math<span class="hljs-preprocessor">.floor</span>(room<span class="hljs-preprocessor">.y</span> + room<span class="hljs-preprocessor">.h</span>/<span class="hljs-number">2</span>)<span class="hljs-comment">;</span>
room<span class="hljs-preprocessor">.id</span>=nodeID<span class="hljs-comment">;</span>
this<span class="hljs-preprocessor">.rooms</span><span class="hljs-preprocessor">.push</span>(room)<span class="hljs-comment">;</span>
this<span class="hljs-preprocessor">.tree</span>[nodeID]<span class="hljs-preprocessor">.hasRoom</span> = nodeID<span class="hljs-comment">;</span>
}
// Assign the rooms to the Map
for (var i=<span class="hljs-number">0</span><span class="hljs-comment">; i<this.rooms.length; i++) {</span>
var r = this<span class="hljs-preprocessor">.rooms</span>[i]<span class="hljs-comment">;</span>
console<span class="hljs-preprocessor">.log</span>(<span class="hljs-string">"Room: "</span>,[r<span class="hljs-preprocessor">.x</span>,r<span class="hljs-preprocessor">.y</span>,r<span class="hljs-preprocessor">.w</span>,r<span class="hljs-preprocessor">.h</span>])<span class="hljs-comment">;</span>
for (var <span class="hljs-built_in">x</span> = r<span class="hljs-preprocessor">.x</span><span class="hljs-comment">; x<(r.x + r.w) ; x++) {</span>
for (var <span class="hljs-built_in">y</span> = r<span class="hljs-preprocessor">.y</span><span class="hljs-comment">; y<(r.y + r.h); y++) {</span>
this<span class="hljs-preprocessor">.map</span>[<span class="hljs-built_in">x</span>][<span class="hljs-built_in">y</span>] = <span class="hljs-number">1</span><span class="hljs-comment">;</span>
}
}
}
// Build Corridors
this<span class="hljs-preprocessor">.joinRooms</span>()<span class="hljs-comment">;</span></code></pre>Cool, huh? We are almost done. At this point we have rooms across the map, that aren’t connected to each other. This was precisely what the object was all along - to generate a bunch of disconnected rooms or varying sizes. Next up is the easy part - joining them.<br />
Since, we already have a <code>Dungeon.stack</code> that had stored id pairs in the order of creation, we simply have to pop one pair at a time and “join” them. That’s where the <code>Dungeon.joinRooms</code> function comes in. Here, we pick a random thickness for the corridor and connect the two Boxes via a simple rectangle. Dimensions for horizontal or vertical corridors are calculated and they are placed connecting the two centers of the Boxes. Only the <em>tiles</em> on <code>Dungeon.map</code> with 0 are flipped to 2.<br />
And, done. <code>Dungeon.buildTree</code> finally sets the results in <code>Dungeon.stats</code>. The map array is retrieved via the function <code>Dungeon.getMap()</code>.<br />
<hr />In <a href="https://github.com/SonalPinto/TowerOfFun/blob/master/games/dungeon/js/main.js"><code>main.js</code></a>, the <code>Dungeon</code> object is used.<br />
<pre class="prettyprint"><code class=" hljs go"><span class="hljs-keyword">var</span> MAP_SIZE =<span class="hljs-number"> 32</span>;
Dungeon.generate(MAP_SIZE);
Dungeon.<span class="hljs-built_in">print</span>();
<span class="hljs-keyword">var</span> <span class="hljs-keyword">map</span> = Dungeon.getMap();
<span class="hljs-keyword">var</span> rooms = Dungeon.getRooms();
<span class="hljs-keyword">var</span> tree = Dungeon.getTree();
<span class="hljs-keyword">var</span> stats = DUngeon.getStats();</code></pre><code>Dungeon.print</code> simply prints the 2D map array onto the console. To actually see the map drawn on the screen as a tileMap, you’d have to use the awesome power of html5 or CSS3. There are many ways to get this done, say, drawing directly on the html5 canvas or manipulating the DOM. I <a href="http://robotcantalk.blogspot.in/2014/09/project-tower-of-fun.html]">decided to pick Phaser</a> as the engine for this project.<br />
I am not going to talk about Phaser here. That’s for the next part. I try to keep the game logic completely independent of the Game Engine, because this would allow code portability, I guess. <em>Modularizashun</em> !! It just feels right to do it this way.<br />
<i class="icon-left"><a href="http://robotcantalk.blogspot.in/2014/10/dungeon-drawing-in-phaser-using-tilemap.html">Onwards to the Next Part: Dungeon Drawing in Phaser using Tilemap</a> <br />
<i class="icon-right"><a href="http://robotcantalk.blogspot.in/p/blog-page.html">Back to TowerOfFun Project</a></i></i><br />
<hr />Oh! And the whole of above was written in <a href="https://stackedit.io/">StackEdit</a>. It’s clearly way too awesome. StackEdit is an html5 markdown editor that has integrated markdown extra and a freaking Live Preview. All I do is write the whole thing down in StackEdit and then simply copy over the html to the Blogger editor. Here - <a href="http://robotcantalk.blogspot.in/2014/09/hello.html">Hello StackEdit!</a> - you can see what it is capable of.</div>Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-34859080884643640692014-08-15T22:52:00.000-07:002014-09-30T04:25:30.305-07:00Dabbling with the Web<div dir="ltr" style="text-align: left;" trbidi="on">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<style type="text/css">
.sandbox {
margin-top: 20px;
margin-left: auto;
margin-right:auto;
display: none;
overflow: hidden;
box-shadow: 5px 5px 10px #666666;
-webkit-user-select: none;
user-select: none;
}
#openCalc {
color: #e0f2f1;
background: #00bfa5;
text-align: center;
vertical-align: middle;
font-size: 1.2em;
box-shadow: 1px 2px 8px #666666;
border: none;
width: 150px;
line-height: 2em;
cursor: pointer;
margin-right: auto;
margin-left: auto;
-webkit-user-select: none;
user-select: none;
}
.calc_sandbox {
height : 380px;
width : 240px;
padding : none;
color : #fafafa;
background : #9e9e9e;
font-weight : 300;
}
#calc_menu {
position: relative;
width: 240px;
height: 20px;
background: #424242;
}
#calc_menu #calc_quit {
width: 60px;
height: 20px;
background: #616161;
color: #9e9e9e;
text-align: center;
float:right;
cursor: pointer;
}
#calc_lcd {
position: relative;
width: 240px;
height: 120px;
box-shadow: 0px 0px 10px #666666 inset;
}
#calc_output {
font-size: 2em;
position: absolute;
right: 10px;
bottom: 10px;
}
#calc_mem {
font-size: 1.5em;
position: absolute;
right: 10px;
top: 10px;
}
#calc_leftpanel {
float:left;
width:180px;
overflow:hidden;
}
#calc_rightpanel {
float:left;
width:60px;
overflow:hidden;
}
.calc_number {
float: left;
background: #424242;
width: 60px;
height: 60px;
text-align: center;
vertical-align: middle;
line-height: 60px;
cursor: pointer;
}
#calc_leftpanel .calc_operator {
float: left;
background: #424242;
width: 60px;
height: 60px;
text-align: center;
vertical-align: middle;
line-height: 60px;
cursor: pointer;
}
#calc_rightpanel .calc_operator {
float: left;
background: #616161;
width: 60px;
height: 48px;
text-align: center;
vertical-align: middle;
line-height: 48px;
cursor: pointer;
}
</style>
<script type="text/javascript">
$(document).ready(function(){
$('#openCalc').click(function(){
initCalc($('.sandbox'))
});
});
var output;
var input;
var mem;
var op;
var state;
var lcd_length=10;
// init the calc sandbox
var initCalc = function($canvas) {
var dynamic_HTML;
$canvas.empty().addClass('calc_sandbox').fadeIn('slow');
dynamic_HTML = '<div id="calc_menu"><div id="calc_quit">✖</div></div> \
<div id="calc_lcd">\
<div id="calc_mem"></div> \
<div id="calc_output">0</div> \
</div> \
<div id="calc_leftpanel">\
<div class="calc_number">7</div> \
<div class="calc_number">8</div> \
<div class="calc_number">9</div> \
<div class="calc_number">4</div> \
<div class="calc_number">5</div> \
<div class="calc_number">6</div> \
<div class="calc_number">1</div> \
<div class="calc_number">2</div> \
<div class="calc_number">3</div> \
<div class="calc_number">.</div> \
<div class="calc_number">0</div> \
<div class="calc_operator">=</div>\
</div>\
<div id="calc_rightpanel"">\
<div class="calc_operator">DEL</div>\
<div class="calc_operator">+</div>\
<div class="calc_operator">-</div>\
<div class="calc_operator">/</div>\
<div class="calc_operator">*</div>\
</div>';
$canvas.append(dynamic_HTML);
$('#calc_quit').click(function(){calc_quit($canvas)});
calc_render(0);
state = 'general_input';
output=0;
input=0;
mem='';
// input event handler
// State machine
$('.calc_number,.calc_operator').click(function(){
var n = $(this).text();
calc_fsm(n);
})
$('.calc_number,.calc_operator').click(function() {
$(this).animate(
{'color':'#259b24','font-size':'1.2em'},120
).delay(100).animate(
{'color':'#fafafa','font-size':'1.0em'},120
);
});
}
// destroyer
var calc_quit = function ($canvas) {
state = 'general_input';
output=0;
input=0;
mem='';
$canvas.fadeOut('slow', function(){
$canvas.empty().removeClass('calc_sandbox');
});
}
// Evaulate the stream
var calc_eval = function(a,b,operation){
switch(operation){
case '+': a+=b;break;
case '-': a-=b;break;
case '*': a*=b;break;
case '/': a/=b;break;
}
if(a.toString().match(/\./)){
return a.toFixed(2);
} else {
return a;
}
}
// lcd render
var calc_render = function(mode) {
if(mode==0){
$('#calc_output').html(output);
$('#calc_mem').html(mem);
} else if(mode==1){
$('#calc_output').html(input);
} else {
$('#calc_output').html('ERROR');
}
}
// Finite State Machine for the Calc
var calc_fsm = function(n) {
if(n == 'DEL'){
state = 'general_input';
output=0;
input=0;
mem='';
calc_render(0);
} else {
switch(state){
case 'general_input':
if(n.match(/[0-9]/)){
if(input.toString().length <= lcd_length){
input = input*10 + parseInt(n);
calc_render(1);
} else {
calc_render(2);
state='error';
}
} else if(n.match(/[\+\-\*\/]/)){
output=input;
mem = input+' '+n;
op=n;
input=0;
calc_render(0);
state='eval';
} else if(n=='='){
output=input;
mem = input;
calc_render(0);
input=0;
}
break;
case 'eval':
if(n.match(/[0-9]/)){
if(input.toString().length <= lcd_length){
input = input*10 + parseInt(n);
calc_render(1);
} else {
calc_render(2);
state='error';
}
} else if(n.match(/[\+\-\*\/]/)) {
output = calc_eval(output,input,op);
if(output.toString().length > lcd_length){
calc_render(2);
state='error';
} else {
mem = output+' '+n;
op=n;
input=0;
calc_render(0);
}
} else if(n=='='){
output=calc_eval(output,input,op);
if(output.toString().length > lcd_length){
calc_render(2);
state='error';
} else {
mem = '';
input=output;
calc_render(0);
input=0;
state='general_input';
}
}
break;
};
}
// console.log(state+":"+input+":"+output);
}
</script>
<br />
<div dir="ltr" style="text-align: left;" trbidi="on">
My work usually involves a lot of experimentation. Well, aside from the thinking part, the part that takes the longest is comprehending the results. The sooner I understand the outcome, the sooner I can apply and augment the experiment. That's where <a href="http://en.wikipedia.org/wiki/Data_visualization" target="_blank">Data Visualization</a> comes in. Truth be told, I got tired of reading and parsing log files, each with four million plus lines of text. Perl helped a lot in the early days. I used Perl to parse these colossal logs and create simple static web reports. The keyword here being static. Being static, I used to render the web reports and store them. Or if I wanted to compare some trials, create a new report for that too. Manual work.<br />
<div>
<br /></div>
<div>
I believe there was a greater scope for improvement here. Though that did help improve experimentation rate by 10x - being no small number by itself. Having an interface to deal with a huge database of raw data - would be ideal. That's where Dynamic Web comes in to picture. That meant I had to learn html, css, javascript, jQuery or whatever these web Devs use these days. Head on over to <a href="http://www.codecademy.com/" target="_blank">CodeAcademy </a>and arm yourselves.</div>
<div>
<br /></div>
<div>
In order to test myself, I made a calculator. Styling inspired by <a href="http://www.google.com/design/spec/material-design/introduction.html">Google's Material Design</a>.
<br />
<br />
<b>edit</b>: I got myself a bitballoon account and hosted my dabbling - <a href="http://sonallearsntoweb.bitballoon.com/">http://sonallearsntoweb.bitballoon.com/</a>
</div>
<div>
<br>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXG7O1GzrJlY6l7hj6EMSyQameSJ26c_SxfvHa4wjA1rnRdTO3MyouHAuHen7SwBpy7k74ViWAVMl-POnmWSzRC4JeJQCGUgsWxkWABg3h7NyXnj5PevCWUQ2R1te-kcViFxv2WbQfYSY/s1600/materialdesign-principles-layersquares_large_mdpi.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXG7O1GzrJlY6l7hj6EMSyQameSJ26c_SxfvHa4wjA1rnRdTO3MyouHAuHen7SwBpy7k74ViWAVMl-POnmWSzRC4JeJQCGUgsWxkWABg3h7NyXnj5PevCWUQ2R1te-kcViFxv2WbQfYSY/s1600/materialdesign-principles-layersquares_large_mdpi.png" height="200" width="200" /></a></div>
<br /></div>
</div>
<div id="openCalc">PLAY</div>
<div class="sandbox"></div>
</div>Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-90280954660370140252014-08-15T22:18:00.001-07:002014-08-15T22:18:52.945-07:00Dilapidated<div dir="ltr" style="text-align: left;" trbidi="on">
This Blog is Absolutely Dilapidated.<br />
<br />
<div class="vk_ans" style="background-color: white; color: #222222; font-family: arial, sans-serif; font-size: xx-large !important; font-weight: lighter !important; margin-bottom: 0px;">
<span data-dobid="hdw">di·lap·i·dat·ed</span></div>
<div style="background-color: white; color: #222222; font-family: arial, sans-serif; font-size: small;">
<div class="lr_dct_ent_ph" style="font-size: large;">
<span class="lr_dct_ph">diˈlapiˌdātid/</span></div>
<div>
<div class="lr_dct_sf_h" style="padding-top: 10px;">
<i>adjective</i></div>
<div class="xpdxpnd vk_gy" data-mh="-1" style="-webkit-transition: max-height 0.3s; color: rgb(135, 135, 135) !important; max-height: 0px; overflow: hidden; transition: max-height 0.3s;">
<b></b></div>
<ol class="lr_dct_sf_sens" style="border: 0px; margin: 0px; padding: 0px 0px 0px 20px;">
<li style="border: 0px; line-height: 1.2; list-style: none; margin: 0px; padding: 0px;"><div class="lr_dct_sf_sen vk_txt" style="font-weight: lighter !important; padding-top: 10px;">
<div style="margin-left: 20px;">
<div style="margin-left: -20px;">
<div data-dobid="dfn" style="display: inline;">
(of a building or object) in a state of disrepair or ruin as a result of age or neglect.</div>
<div>
<table class="vk_tbl vk_gy" style="border-collapse: collapse; color: rgb(135, 135, 135) !important;"><tbody>
<tr><td class="lr_dct_nyms_ttl" style="font-style: italic; padding: 0px 3px 0px 0px; vertical-align: top; white-space: nowrap;">synonyms:</td><td style="padding: 0px;">run-down, <a href="https://www.google.com/search?newwindow=1&sa=X&biw=1600&bih=775&q=define+tumbledown&ei=HenuU4OpB4e7oQThwICQAQ&ved=0CB4Q_SowAA" style="color: #660099; cursor: pointer; text-decoration: none;">tumbledown</a>, <a href="https://www.google.com/search?newwindow=1&sa=X&biw=1600&bih=775&q=define+ramshackle&ei=HenuU4OpB4e7oQThwICQAQ&ved=0CB8Q_SowAA" style="color: #660099; cursor: pointer; text-decoration: none;">ramshackle</a>, <a href="https://www.google.com/search?newwindow=1&sa=X&biw=1600&bih=775&q=define+broken-down&ei=HenuU4OpB4e7oQThwICQAQ&ved=0CCAQ_SowAA" style="color: #660099; cursor: pointer; text-decoration: none;">broken-down</a>, in disrepair, <a href="https://www.google.com/search?newwindow=1&sa=X&biw=1600&bih=775&q=define+shabby&ei=HenuU4OpB4e7oQThwICQAQ&ved=0CCEQ_SowAA" style="color: #660099; cursor: pointer; text-decoration: none;">shabby</a>,<a href="https://www.google.com/search?newwindow=1&sa=X&biw=1600&bih=775&q=define+battered&ei=HenuU4OpB4e7oQThwICQAQ&ved=0CCIQ_SowAA" style="color: #660099; cursor: pointer; text-decoration: none;">battered</a>, <a href="https://www.google.com/search?newwindow=1&sa=X&biw=1600&bih=775&q=define+beat-up&ei=HenuU4OpB4e7oQThwICQAQ&ved=0CCMQ_SowAA" style="color: #660099; cursor: pointer; text-decoration: none;">beat-up</a>, <a href="https://www.google.com/search?newwindow=1&sa=X&biw=1600&bih=775&q=define+rickety&ei=HenuU4OpB4e7oQThwICQAQ&ved=0CCQQ_SowAA" style="color: #660099; cursor: pointer; text-decoration: none;">rickety</a>, <a href="https://www.google.com/search?newwindow=1&sa=X&biw=1600&bih=775&q=define+shaky&ei=HenuU4OpB4e7oQThwICQAQ&ved=0CCUQ_SowAA" style="color: #660099; cursor: pointer; text-decoration: none;">shaky</a>, <a href="https://www.google.com/search?newwindow=1&sa=X&biw=1600&bih=775&q=define+unsound&ei=HenuU4OpB4e7oQThwICQAQ&ved=0CCYQ_SowAA" style="color: #660099; cursor: pointer; text-decoration: none;">unsound</a>, crumbling, in ruins, ruined,decayed, decaying, <a href="https://www.google.com/search?newwindow=1&sa=X&biw=1600&bih=775&q=define+decrepit&ei=HenuU4OpB4e7oQThwICQAQ&ved=0CCcQ_SowAA" style="color: #660099; cursor: pointer; text-decoration: none;">decrepit</a>; <span data-log-string="synonyms-more-click" jsaction="dob.m"><span class="lr_dct_more_btn" style="color: #1122cc; cursor: pointer; padding-left: 4px;">More</span><div style="display: inline;">
<div style="display: inline;">
<div class="lr_dct_more_txt xpdxpnd xpdnoxpnd" data-mh="-1" style="-webkit-transition: max-height 0.3s; max-height: 0px; overflow: hidden; transition: max-height 0.3s;">
<a href="https://www.google.com/search?newwindow=1&sa=X&biw=1600&bih=775&q=define+neglected&ei=HenuU4OpB4e7oQThwICQAQ&ved=0CCkQ_SowAA" style="color: #660099; cursor: pointer; text-decoration: none;"></a><a href="https://www.google.com/search?newwindow=1&sa=X&biw=1600&bih=775&q=define+untended&ei=HenuU4OpB4e7oQThwICQAQ&ved=0CCoQ_SowAA" style="color: #660099; cursor: pointer; text-decoration: none;"></a></div>
<div class="lr_dct_more_blk xpdxpnd xpdnoxpnd vk_gy" data-mh="-1" style="-webkit-transition: max-height 0.3s; max-height: 0px; overflow: hidden; transition: max-height 0.3s;">
</div>
</div>
</div>
</span></td></tr>
</tbody></table>
</div>
</div>
</div>
</div>
</li>
</ol>
</div>
</div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-83112581533158993822014-04-21T22:18:00.003-07:002015-03-03T20:54:48.666-08:00Shut Up and Take My Money - MicroView<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: left;">
<span style="font-size: x-large;">MicroView on </span><a href="https://www.kickstarter.com/projects/1516846343/microview-chip-sized-arduino-with-built-in-oled-di" target="_blank"><span style="font-size: x-large;">Kickstarter</span></a></div>
<div style="text-align: left;">
<a href="https://www.kickstarter.com/projects/1516846343/microview-chip-sized-arduino-with-built-in-oled-di" target="_blank"><span style="font-size: x-large;"><br /></span></a><span style="font-size: large;">Their <a href="http://microview.io/" target="_blank">Website</a></span></div>
<div>
<div style="text-align: left;">
<br /></div>
<blockquote class="tr_bq">
<b><span style="background-color: white; border: 0px; color: #666666; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 15px; line-height: 22.66666603088379px; margin: 0px; padding: 0px; vertical-align: baseline;">The MicroView is the first chip-sized Arduino compatible that lets you see what your Arduino is thinking using a built-in OLED display.</span></b></blockquote>
It's the cutest Arduino I have ever seen.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/UcylgeO37E4?feature=player_embedded' frameborder='0'></iframe></div>
<br />
Look at it. LOOK!<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://cdn.shopify.com/s/files/1/0331/5361/files/73174d137b1f8b99b082ee13c04f574f_large.png?212" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://cdn.shopify.com/s/files/1/0331/5361/files/73174d137b1f8b99b082ee13c04f574f_large.png?212" height="257" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
More!<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://cdn.shopify.com/s/files/1/0331/5361/files/d5d34f67cb573d6914c9f727ad561e71_large.gif?230" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://cdn.shopify.com/s/files/1/0331/5361/files/d5d34f67cb573d6914c9f727ad561e71_large.gif?230" height="256" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://cdn.shopify.com/s/files/1/0331/5361/files/91e37c9fdaecfffa3d74ba5eba0d9d9e_large.gif?230" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://cdn.shopify.com/s/files/1/0331/5361/files/91e37c9fdaecfffa3d74ba5eba0d9d9e_large.gif?230" height="257" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
OMG Wow! It's so CUTE!<br />
<br />
<div style="text-align: left;">
This is definite Shut up and Take My Money artifice. </div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://mashalot.com/wp-content/uploads/2013/06/shut-up-and-take-my-money.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://mashalot.com/wp-content/uploads/2013/06/shut-up-and-take-my-money.jpg" height="199" width="320" /></a></div>
<br />
<br /></div>
</div>
Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-49835776792004595232014-01-15T03:17:00.000-08:002015-03-03T20:22:58.547-08:00DFT on an Arduino<div dir="ltr" style="text-align: left;" trbidi="on">
You read that right. DFT, not FFT. Discrete Fourier Transform, DFT.<br />
<br />
Why would I do such a thing you ask? Why not just simply use the <i>faster </i>and <i>simpler </i>FFT (Fast Fourier Transform)? It even has Fast as part of its name!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/99-lr7KrZRU?feature=player_embedded' frameborder='0'></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<a href="http://www.freerangefactory.org/site/uploads/Main/dsp_guide_cover.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://www.freerangefactory.org/site/uploads/Main/dsp_guide_cover.png" height="320" width="222" /></a><br />
<br />
Well, I was still on chapter 11 of this amazing book<b><i> T</i></b><i><b>he Scientist and Engineer's Guide to Digital Signal Processing</b></i> by, Steven W. Smith as this experiment. FFT was the next chapter. There's an on-line abridged version too: <a href="http://www.dspguide.com/">http://www.dspguide.com/</a><br />
<br />
Why? Letsee... About a month back (2013Dec), Ashok asked me on facebook whether I knew anything about embedded systems and microelectronics. I replied that I did, but I had never actually used one. I told him that there some cool stuff around - Arduino and such, that make prototyping super easy. I then remembered an old memory. I always wanted to learn DSP properly and new exactly what I wanted to do with that knowledge. Back in college I had absolutely wasted away my DSP course by slacking off. Regretful :(
<br />
<br />
<a name='more'></a><br />
<br />
Some time in my junior year at college, I went overboard on a project where I was to simply make something around a 555 timer chip... and made this:
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/Kqj-ap1lbWI?feature=player_embedded' frameborder='0'></iframe></div>
<br />
That was just a lot of opamps and LEDs. Kinda simple really. Bandpass filters being mutiplexed one LED column at a time, by a 555 timer chip. See, I used a 555 chip there. The very next semester I had DSP. I knew I had to digitize the Audio Visualizer. I just had to. But, as I was slacking off, I couldn't really get what Proakis and Oppenheim (The two college recommended books) had to offer. Three years down the road, NOW, I looked around for a DSP book that I could actually learn (not study) from. That books is the one from Steve Smith. Amazing book, really. Has a brilliant and very understandable intro to DSP. Think of it like a Dummies Guide to DSP. Another good book would be DSP book by Richard Lyon. It's far more in-depth.
But, I wanted something that would get me started as fast as possible. Smith does just that.<br />
<a href="http://www.simplelabs.co.in/78-large_leometr/induinox-arduino-learners-kit.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="http://www.simplelabs.co.in/78-large_leometr/induinox-arduino-learners-kit.jpg" /></a><br />
<br />
Alright! Getting right to it. I wanted to make the Audio Visualizer using DSP on a cheap microcontroller setup. Arduino fit the bill just right. Looking around, I found that Simple Labs had a pretty awesome Arduino clone, the Induino. So, I went ahead and got myself the <a href="http://www.simplelabs.co.in/content/induinox-arduino-learners-kit" target="_blank">Induino Learner's kit</a>. It came with an 16x2 character LCD which was <i>perfect </i>for the Audio Visualizer I had in mind. I am not going to explain DSP or DFT here. It would be grossly redundant. Read the book. Nothing I have come across could explain it better.
Also, this ain't a Arduino tutorial. You kinda need to know that stuff before jumping to something funny like DFT. If you have an Induino, this is a good place to learn - <a href="http://www.induino.com/2013/07/list-of-contents.html" target="_blank">Induino Tutorial</a><br />
<br />
Prerequisite knowledge:
<br />
<ul style="text-align: left;">
<li>Control over character LCD. <a href="http://arduino.cc/en/Tutorial/LiquidCrystal" target="_blank">link</a></li>
<li>Control over ADC - not just the Arduino analogRead(), but the actual Atmega328 ADC. <a href="http://garretlab.web.fc2.com/en/arduino/inside/arduino/wiring_analog.c/analogRead.html" target="_blank">link</a></li>
<li>Knowledge of how to store and read content from the flash memory. <a href="http://arduino.cc/en/Reference/PROGMEM" target="_blank">link</a></li>
</ul>
<br />
Before sketching on the Arduino, it's always best to check your algorithm. So, I used Octave for that. I really hope you know what Octave is. Ever used Matlab? Ya? Well, <a href="https://www.gnu.org/software/octave/%E2%80%8E" target="_blank">Octave</a> is just that - but free! Gnu licensed, open source. This - <a href="http://en.wikipedia.org/wiki/Window_function">http://en.wikipedia.org/wiki/Window_function</a> - is very good place to understand various windowing functions. Without windows we end up with very annoying spectral leakage. <i>Spectral Leakage</i>, such a cool word... sounds very haunted.
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgESQQUKhIzGAzCBIQl9aYkYkTMmyx-FbEWwLPWv09vPHPpsZ7BAj-hqNPBl8CKHqNYN3yfvcmgAfK-nbFeoZOcwwj2t4-Ui9CAir6yEJetCASsJfTqRzY9yLH3bDU7iTONpBOO9hxDCPY/s1600/dft_64_hamming.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgESQQUKhIzGAzCBIQl9aYkYkTMmyx-FbEWwLPWv09vPHPpsZ7BAj-hqNPBl8CKHqNYN3yfvcmgAfK-nbFeoZOcwwj2t4-Ui9CAir6yEJetCASsJfTqRzY9yLH3bDU7iTONpBOO9hxDCPY/s400/dft_64_hamming.png" height="197" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">64pt DFT with Hamming Window</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_nv4Azt6CsjCsiPTpCgOdEICzgp4v-uIEw7wOEZOWU6mBJFqy4vP0u-TjQ8SZJT6RhUWe1-s80WQBMSwF4hVR31c-Y2Gpc3wRgWV5pD-9dY3wS4_RfOtalY_xiloK1dD6zhN62YwFiZI/s1600/dft_64_nowindow.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_nv4Azt6CsjCsiPTpCgOdEICzgp4v-uIEw7wOEZOWU6mBJFqy4vP0u-TjQ8SZJT6RhUWe1-s80WQBMSwF4hVR31c-Y2Gpc3wRgWV5pD-9dY3wS4_RfOtalY_xiloK1dD6zhN62YwFiZI/s400/dft_64_nowindow.png" height="197" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">64pt DFT with Rectangular Window, ie: No window. Look at that awful Spectral Leakage.</td></tr>
</tbody></table>
<div style="text-align: center;">
<span id="goog_1797918500"></span><span id="goog_1797918501"></span> All Source Code : <a href="https://github.com/SonalPinto/arduino_DFT">on Github</a><br />
<br /></div>
Now, lets get to the main course. The Arduino Sketch.
Looking at the Octave code, it's kinda obvious that one cannot generate those coefficients on the arduino during run time. Hence, we ought to store those coefficients in a neat LUT (Look-up Table) - nothing fancy, just some arrays stored in a header file. Get those LUTs from Octave by saving those matrices. So, this is how I am going to do this, here. Below is the whole code. You can just copy it and flash it right away, after setting up the right ports in the code. Explanation follows that, though the comments are kinda self-explanatory.<br />
<br />
Remember that the Atmega328 used in the Arduino is build on the Harvard architecture. The space for instruction and dara is separate. With 2KB ram, its impossible to store huge arrays of coefficients in the small sram, hence you'd need to store it in the code space, which is huge - 32KB. The<span style="color: red;"> <b style="background-color: white;"><a href="https://github.com/SonalPinto/arduino_DFT/blob/master/dftcons.h">dftcons.h</a></b></span> contains LUTs for:
<br />
<ul style="text-align: left;">
<li>Cosine coefficients - REx_cons[DFT_Nb2][DFT_N] - 8bit signed</li>
<li>Sine coefficients - IMx_cons[DFT_Nb2][DFT_N] - 8bit signed</li>
<li>Hamming window - window[DFT_N] - 8bit signed</li>
<li>Log Power level - logMag[128] - 18*log2(x) - 8bit unsigned</li>
<li>Bands[16] - Selects which band goes to which column of the 16x2 LCD - 8bit unsigned </li>
</ul>
<div>
DFT_N is the number of sample points on which DFT is preformed. It is the specification of the DFT, and in this case, 64. It pretty much decides everything - memory size, operation performance, spectral resolution, etc. Read the book.
<br />
<br /></div>
<div>
</div>
<div>
DFT_Nb2 is exactly what you think it is - N/2+1, ie 33 in this case.</div>
<div>
If you have read the book, you'll know that the Frequency spectrum is redundant over the centre (-pi/2 to pi/2). It's basically mirrored. To check this out, in the Octave code, do a DFT over all 64 points. Hence, you only need just half the spectrum. This goes hand in hand with the concept of Nyquist Theorem where you maximum knowledge of the input signal you can have is half the sampling rate, ie: N/2+1<br />
<br /></div>
<div>
The 0th band is the Zero frequency power - DC signal, hence you always need the +1. Yes.
</div>
<div>
</div>
<div>
LOG2_Nb2 is the log2(64/2) = 5. This is important during Magnitude correction... rather, calling it Normalization would be more accurate.
<br />
<br /></div>
<div>
</div>
The <a href="https://github.com/SonalPinto/arduino_DFT/blob/master/dft_C.ino">dft_C.ino</a> is the arduino sketch. <br />
<br />
<a href="http://robotcantalk.blogspot.in/2015/02/dft-on-arduino-part-2.html">PART 2</a></div>
Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-15072758526731392602013-10-10T22:17:00.000-07:002014-01-15T00:49:58.194-08:00Genetic Algorithms, Bacon and an Irish Car bomb<div dir="ltr" style="text-align: left;" trbidi="on">
Where do I begin?... I have always had this problem where I cannot figure out how to start a narrative. What makes the story and what parts to leave out? Should I tell you of my adventures at the US Consulate or should I tell you of the time when I was almost robbed in Santa Clara? *shrugs*... I'll just pen whatever comes to mind.<br />
<br />
<a name='more'></a><br />
<br />
Lets just begin with this - One fine day, a rainy one at that, I sat sipping my daily espresso, half heartedly crawling through my daily feeds on a monitor that I could never seem to set the right brightness on. It would either be too bright or too dim. sigh...<br />
<a href="http://runezone.com/imagehost/images/5146/bored-face.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="150" src="http://runezone.com/imagehost/images/5146/bored-face.jpg" width="200" /></a>Outlook pops out a notification for a new mail. It read that for some reason, some of the fancy tech that I had worked on caught the attention of the Nvidia nTECH committee and they had decided to call me over to Santa Clara to speak about it. Yes, it was an application of Genetic algorithms to solve a obviously non-deterministic ASIC design problem.<br />
<br />
Woohoo?... ('-_-) speaking in front of many people... yay... so exciting (-_-')... I just love speaking to a crowd... yay.... sigh<br />
<br />
<br />
<span style="color: #38761d;">// OK This is post in now literraly 6 months overdue, and I no longer remember what I was going to type.<br />// This is what my quick notes from 6 months ago looked like</span><br />
<br />
<i>The Nvidia nTECH - what is</i><br />
<i><br /></i>
<i>firts thing first get VISA - talk about visa process - how short interview was - 2 guys infrnt - stduent visa rehected</i><br />
<i><br /></i>
<i>next ticketing - insta - Emriates flight - Hyatt House booking... Hmmm - k</i><br />
<i><br /></i>
<i>Super awesome evening anston. </i><br />
<i><br /></i>
<i>fligtj! lost kindle - heart brokern :( so sad couldne t sleeh :( got it back on way back dubai.</i><br />
<br />
<br />
Anyhoo... here's some pics:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfMXwShQg-bQyaIWF3Bnp6ib_wYp0aS8rBb1Xlft38ETHP7F7JCIPJIfCfuluB4AkncG34mBvQnvnASVHchrMtzDUsIvacb4bpUy1Ko5ZDl9k8FuqGTnI2UexY7rHnQKAStZqKhHj03Tk/s1600/IMG_20130916_145734.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfMXwShQg-bQyaIWF3Bnp6ib_wYp0aS8rBb1Xlft38ETHP7F7JCIPJIfCfuluB4AkncG34mBvQnvnASVHchrMtzDUsIvacb4bpUy1Ko5ZDl9k8FuqGTnI2UexY7rHnQKAStZqKhHj03Tk/s320/IMG_20130916_145734.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Sonal lands at SFO airport</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk8ZQGSEp0biSwIIf13FpyraTyLJHtCYmj-UJwj-BqcVJEmFcqfPhWrOA1V1f2dw7yp728z5gUFMHAWAfBG2eP0-Q2aOoXX3_fzJCMrh-axparZ8u0NFIkKoFooOmIvXhw__BS6ouxwZ4/s1600/IMG_20130916_145752.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk8ZQGSEp0biSwIIf13FpyraTyLJHtCYmj-UJwj-BqcVJEmFcqfPhWrOA1V1f2dw7yp728z5gUFMHAWAfBG2eP0-Q2aOoXX3_fzJCMrh-axparZ8u0NFIkKoFooOmIvXhw__BS6ouxwZ4/s320/IMG_20130916_145752.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Sonal takes SuperShuttle - $38</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH8LLflIKptb18tGLhjmrYOUQYhQU7nh03rJN-_3b4He8BVpYhIrks7j3gvpSv6UpAqZpJNihdNRoi2VzVgl5g94AS9eh_YKgKK47IAkRza530wU_lupYpeSd5REoGOyO9-OlFxSBrBhI/s1600/IMG_20130916_170629.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH8LLflIKptb18tGLhjmrYOUQYhQU7nh03rJN-_3b4He8BVpYhIrks7j3gvpSv6UpAqZpJNihdNRoi2VzVgl5g94AS9eh_YKgKK47IAkRza530wU_lupYpeSd5REoGOyO9-OlFxSBrBhI/s320/IMG_20130916_170629.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Sonal walks down the corridor to his room at The Hyatt House</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiw6m_X4IwWRiqM3zKp1oxxf_bplLTv1Xc6NLOQFF6aUN7Ns0ZkdjMgBVDL5MgrvM3WsORoI4bAK240QiAlAGBotmvKQbWmRmktJD6PVFodQl42EoUQBcpISS0kR6y09DC6_dX0DoEonIU/s1600/IMG_20130916_170758.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiw6m_X4IwWRiqM3zKp1oxxf_bplLTv1Xc6NLOQFF6aUN7Ns0ZkdjMgBVDL5MgrvM3WsORoI4bAK240QiAlAGBotmvKQbWmRmktJD6PVFodQl42EoUQBcpISS0kR6y09DC6_dX0DoEonIU/s320/IMG_20130916_170758.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Sonal was like "Wow"... $700 for three days - and I am not paying - wow</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2XkLUM93_0I8FvlRkWfnfEnrPSvDmAGWW6oMD4OHV6apVK2_v2gMTWydUePl1AacfMGBugag4c4keIe501cev5eIGQxbOkWcnBy9vV_zWVbaMR4AeFoae_blUN1HBMdotcjonGFijCts/s1600/IMG_20130916_170811.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2XkLUM93_0I8FvlRkWfnfEnrPSvDmAGWW6oMD4OHV6apVK2_v2gMTWydUePl1AacfMGBugag4c4keIe501cev5eIGQxbOkWcnBy9vV_zWVbaMR4AeFoae_blUN1HBMdotcjonGFijCts/s320/IMG_20130916_170811.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Yup. As comfy as it looks</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKQjoVUwD0laJTswwPtefHFTp7FbjLi649CtB-s6-gJ4ldOMBUzNmfP5Lhn0LpdsKWG89TPEhsTcNbqCPI3CFMReNwZRYkzC1OCDwTnHhKLyLeo5KqBUILKtZcYE6YuHk3q9qNI8Pq9sE/s1600/IMG_20130916_170821.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKQjoVUwD0laJTswwPtefHFTp7FbjLi649CtB-s6-gJ4ldOMBUzNmfP5Lhn0LpdsKWG89TPEhsTcNbqCPI3CFMReNwZRYkzC1OCDwTnHhKLyLeo5KqBUILKtZcYE6YuHk3q9qNI8Pq9sE/s320/IMG_20130916_170821.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Even comes with a full kitchen. Dayum.</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW7xMso2V1diFSsRp-UAiZS8Gzwu7Oqnf-SFXmGF5rJ-pq-Yp4WbCZAyrsiUZOer0pVdfvJNRbeirtxPHjDEIPD-5GGVaBlGAmffU9veJiEZUq_XF-dayPpg8uJUGsj5S2nzkKU1GBnOY/s1600/IMG_20130916_181909.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW7xMso2V1diFSsRp-UAiZS8Gzwu7Oqnf-SFXmGF5rJ-pq-Yp4WbCZAyrsiUZOer0pVdfvJNRbeirtxPHjDEIPD-5GGVaBlGAmffU9veJiEZUq_XF-dayPpg8uJUGsj5S2nzkKU1GBnOY/s320/IMG_20130916_181909.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Outside the window</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQWCKHVQnmvEU6PhqW4Bk592r7jIxxR8rf_mIbANftU3uw2OD-x_wuPNl1GXtZbducRN_B67vG-j74SeOoZtq9AunbJEHYlVKxVbUK7Qgms-Yrcm_ZNLbsrGLjGng9eIDeD7iiwPRY6do/s1600/IMG_20130917_061724.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQWCKHVQnmvEU6PhqW4Bk592r7jIxxR8rf_mIbANftU3uw2OD-x_wuPNl1GXtZbducRN_B67vG-j74SeOoZtq9AunbJEHYlVKxVbUK7Qgms-Yrcm_ZNLbsrGLjGng9eIDeD7iiwPRY6do/s320/IMG_20130917_061724.jpg" width="240" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Spider!</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgC-NIUIKWgrQEDyNvy13bTyLEMMvdUc6SrlblTDGD_0L8MaGT4MoyHpL7xxaQVo5S0eoYXlluXtfmV-2TC-99lVGoIgGxZYksvGK2nYw5TfuRRkWj3sp8BVACzo6yIJnbf4mUoV9oB-A8/s1600/IMG_20130917_075555.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgC-NIUIKWgrQEDyNvy13bTyLEMMvdUc6SrlblTDGD_0L8MaGT4MoyHpL7xxaQVo5S0eoYXlluXtfmV-2TC-99lVGoIgGxZYksvGK2nYw5TfuRRkWj3sp8BVACzo6yIJnbf4mUoV9oB-A8/s320/IMG_20130917_075555.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">My daily ride to the office. Freaking truck limo thing with super air-conditioning</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuhGKldsn9ZZx_o10RF5Aosb9oWbwG8u0TcxyYmfCzbqxjIVJCkF7xqt5Bd8QXSAxWRbhJ3XKdIulML145LhWjvwGoJrnmJSimdHLpd37pkWI2EHTlZMDTZVGUengs7cLq1AAJZcBkatI/s1600/IMG_20130917_085234.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuhGKldsn9ZZx_o10RF5Aosb9oWbwG8u0TcxyYmfCzbqxjIVJCkF7xqt5Bd8QXSAxWRbhJ3XKdIulML145LhWjvwGoJrnmJSimdHLpd37pkWI2EHTlZMDTZVGUengs7cLq1AAJZcBkatI/s320/IMG_20130917_085234.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">nTech morning... Sept17, I think</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqlrzquGRZW1s7SXJ1lfGi6z9RqOHnKarlAo424TqdNQqPJdvbNmQVdWbaUBQUZx0KmI-1F3QGqo8jfFn0aesGA3YXGaDSok737LlD4zufyZVmH-qp0cFZv9Nn7dJIeV0fuZ2Oc2Dq6Uk/s1600/IMG_20130917_171824.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqlrzquGRZW1s7SXJ1lfGi6z9RqOHnKarlAo424TqdNQqPJdvbNmQVdWbaUBQUZx0KmI-1F3QGqo8jfFn0aesGA3YXGaDSok737LlD4zufyZVmH-qp0cFZv9Nn7dJIeV0fuZ2Oc2Dq6Uk/s320/IMG_20130917_171824.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Teslas parked outside the conference room</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjk8KgfDi4258i8gAPovEO52VCAgP3vX9j1LgQe7Kt5omdSKgApOhZEuaDY1QmrcBjYt6M-a91h2Dc4w-h8zDCEl2T5e7AqFRFeXpN2FshCBcFv8wEoozTiKHNqb9J9guJRWAH8szUUNs4/s1600/IMG_20130917_171835.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjk8KgfDi4258i8gAPovEO52VCAgP3vX9j1LgQe7Kt5omdSKgApOhZEuaDY1QmrcBjYt6M-a91h2Dc4w-h8zDCEl2T5e7AqFRFeXpN2FshCBcFv8wEoozTiKHNqb9J9guJRWAH8szUUNs4/s320/IMG_20130917_171835.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Tesla S!</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-QDb74nb39JE_oQtd1s7z1lyitxpwiJ5X4mymmfPSQZH0JhWz_6KD44n6wH9FFrTDAjosT56sNg93215ZpHh5ToBEoA3BktpJWlRM3DoHN2FDKm101LkDJwZ25eNkk_Be4-AqqQuc5H0/s1600/IMG_20130917_171849.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-QDb74nb39JE_oQtd1s7z1lyitxpwiJ5X4mymmfPSQZH0JhWz_6KD44n6wH9FFrTDAjosT56sNg93215ZpHh5ToBEoA3BktpJWlRM3DoHN2FDKm101LkDJwZ25eNkk_Be4-AqqQuc5H0/s320/IMG_20130917_171849.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">ooooh shiny!</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEccmsSSB1GdLRWrK989oqB-cQ5ViKU7wCZNP4DEkvVT4IMLgYLezA9ekhyvZkcEftSSnThHvpX52KRu-yN8lTJ6rCfI8HY-tQZg8b507uEcN0pi6kIle4Rx38g0aeUQDS-6_RdYAaQxc/s1600/IMG_20130917_175802.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEccmsSSB1GdLRWrK989oqB-cQ5ViKU7wCZNP4DEkvVT4IMLgYLezA9ekhyvZkcEftSSnThHvpX52KRu-yN8lTJ6rCfI8HY-tQZg8b507uEcN0pi6kIle4Rx38g0aeUQDS-6_RdYAaQxc/s320/IMG_20130917_175802.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Fireside chat between Nvidia Co-Founder and Nvidia Chief Scientist</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiq5IQgvNge42Qu-Uc2x2Wkhbl2LfTUBE5oze6VjvLc70GSMxpKsaWgMED8TU8LOOw-Hx-vXUvrlA-s5bHdDgSgaBbVNxdr9iQdn3sedBotfwCCEjjEXdIUCQwJErgmDPkJGGBYeqcAXWk/s1600/IMG_20130917_181818.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiq5IQgvNge42Qu-Uc2x2Wkhbl2LfTUBE5oze6VjvLc70GSMxpKsaWgMED8TU8LOOw-Hx-vXUvrlA-s5bHdDgSgaBbVNxdr9iQdn3sedBotfwCCEjjEXdIUCQwJErgmDPkJGGBYeqcAXWk/s320/IMG_20130917_181818.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Elon Musk and Jensen Huang</td></tr>
</tbody></table>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5tP6jpGeNPAWw8qQk8LKXngWd8hRS7pXSVpDCCgkjmdvSasK24XX2jWwAO6DJwu5LxeEq5Lj3x2JcmdqzlZMpIaYURJRajhwC-svzVXSFyAqX_gYlC562IlzeoDs_Zsa-r6Xr4wcZhxA/s1600/IMG_20130917_181831.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5tP6jpGeNPAWw8qQk8LKXngWd8hRS7pXSVpDCCgkjmdvSasK24XX2jWwAO6DJwu5LxeEq5Lj3x2JcmdqzlZMpIaYURJRajhwC-svzVXSFyAqX_gYlC562IlzeoDs_Zsa-r6Xr4wcZhxA/s320/IMG_20130917_181831.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_dndg2YdJ5HgvIslEbcpLatxpxcFg3ILzG6eSuAgIGnQvdXXaHeJRF8Lg9_J_1KXtx4a0XlvNGpja4m0FPCX1xOPuXjZGe5QyC_17J8j4tRNS6OlgfgsxLlkiU0SWyToqdiw0gGHhxE0/s1600/IMG_20130917_181841.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_dndg2YdJ5HgvIslEbcpLatxpxcFg3ILzG6eSuAgIGnQvdXXaHeJRF8Lg9_J_1KXtx4a0XlvNGpja4m0FPCX1xOPuXjZGe5QyC_17J8j4tRNS6OlgfgsxLlkiU0SWyToqdiw0gGHhxE0/s320/IMG_20130917_181841.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeIBtoSB2OVukQ4wtOoCAqCF3J_-X9GsqDfkVP0ZFXeWKepmdILrOnJMS29J6eQyKFPljZN4-E7Fah8sW_tH14SJ2QlASa-jRbMJyHlwr8PXauZdoL-xa_B2Vv7cHTPmkvjvFMK8nko2o/s1600/IMG_20130917_182933.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeIBtoSB2OVukQ4wtOoCAqCF3J_-X9GsqDfkVP0ZFXeWKepmdILrOnJMS29J6eQyKFPljZN4-E7Fah8sW_tH14SJ2QlASa-jRbMJyHlwr8PXauZdoL-xa_B2Vv7cHTPmkvjvFMK8nko2o/s320/IMG_20130917_182933.jpg" width="320" /></a></div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbSLJQsrXdE2Ro9RptmOE00m6OTSECAARJfE-VYxSY5Ee5p3q5DXz0esEoa4RVqavG9bf4KeUMSiTNd-EFrGXf_Ff9boEzKmwsobWJdVy_WScW6pqZIn5OUhuFVOF1AW1_p1ubXA9fpVU/s1600/IMG_20130918_065624.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbSLJQsrXdE2Ro9RptmOE00m6OTSECAARJfE-VYxSY5Ee5p3q5DXz0esEoa4RVqavG9bf4KeUMSiTNd-EFrGXf_Ff9boEzKmwsobWJdVy_WScW6pqZIn5OUhuFVOF1AW1_p1ubXA9fpVU/s320/IMG_20130918_065624.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Road?</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvomoWPbEbUHdnQT-2mG6Bebt0riRHrCEJJlCcra7pICp2L8mea6ClVQfis7ISsTUAoYeiE1yh3Ae4d5WMLaRAhQH7aFhqykRGVDm7gilHVPdYZjhgaq13ezxqE1h_vKHCayq4VHC0jGA/s1600/IMG_20130918_070034.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvomoWPbEbUHdnQT-2mG6Bebt0riRHrCEJJlCcra7pICp2L8mea6ClVQfis7ISsTUAoYeiE1yh3Ae4d5WMLaRAhQH7aFhqykRGVDm7gilHVPdYZjhgaq13ezxqE1h_vKHCayq4VHC0jGA/s320/IMG_20130918_070034.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">BACON</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAkPtSc-WkPFjD4a5JpM0nDrbMy5j84M8vGlwhJIafKlFGCWjEpg65mZ74uBuiOX0VNxVXh7ZH1DGT6MqM-HS4FLH9m0mdUw_hu06FFD7_oP1Otr71tXwpYFJt_xmV71p-mUO6Kut61XU/s1600/IMG_20130918_070151.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAkPtSc-WkPFjD4a5JpM0nDrbMy5j84M8vGlwhJIafKlFGCWjEpg65mZ74uBuiOX0VNxVXh7ZH1DGT6MqM-HS4FLH9m0mdUw_hu06FFD7_oP1Otr71tXwpYFJt_xmV71p-mUO6Kut61XU/s320/IMG_20130918_070151.jpg" width="240" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">BACON</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwEKzm6Nfwld3FvwjKPlYmuVZth0GDEbsey22Y-0R2M978Tu-DwE3bkrodZIa6VggveH18ujj32Fyde00L-rM2vanMwSsm6uAss7BFNtu-wCZxCFKDJjZhgOircAqCPQKSg7dsLrBdRu8/s1600/IMG_20130918_070437.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwEKzm6Nfwld3FvwjKPlYmuVZth0GDEbsey22Y-0R2M978Tu-DwE3bkrodZIa6VggveH18ujj32Fyde00L-rM2vanMwSsm6uAss7BFNtu-wCZxCFKDJjZhgOircAqCPQKSg7dsLrBdRu8/s320/IMG_20130918_070437.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Free breakfast every morning at The Hyatt House</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZzzLDaT8ZIjrUrqZnjRPZsGcdhOLwRPKzuZH0_31mlNOwdog5R4O6F4GFWU7i83YBkp0BNWBIsswF_SUCJ6nL-eKAwlNIgFBhppdfhcjKshe6-Dx_AOk22ApSWepSWYBBydLhCiHtK8M/s1600/IMG_20130918_082730.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZzzLDaT8ZIjrUrqZnjRPZsGcdhOLwRPKzuZH0_31mlNOwdog5R4O6F4GFWU7i83YBkp0BNWBIsswF_SUCJ6nL-eKAwlNIgFBhppdfhcjKshe6-Dx_AOk22ApSWepSWYBBydLhCiHtK8M/s320/IMG_20130918_082730.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Coffee at the conference</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSJEKqV8kP5-5bI6luKA4A3zhK2rtx-F5rdSpecx76tRwP4wf3GTnGfxr4mh33Yu5No2qXI1a0ASL-_LIKV2W7I1FmCOQYqxQrhoUtn239pjDKAPkD1UxQpdimihmkdbV-Tfu-ve6inhw/s1600/IMG_20130919_000836.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSJEKqV8kP5-5bI6luKA4A3zhK2rtx-F5rdSpecx76tRwP4wf3GTnGfxr4mh33Yu5No2qXI1a0ASL-_LIKV2W7I1FmCOQYqxQrhoUtn239pjDKAPkD1UxQpdimihmkdbV-Tfu-ve6inhw/s320/IMG_20130919_000836.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Irish Pub with Anston - He's paying the bill... hehehe</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiqRKPXH4M4yQgngyuDdntIYf_ncn6_7cztnLp1G1k6hmlvlRvKq6P5Ipp1aFVB_e53w1MGCUIxCElZbPHfkPa3l8Hr6kHGpqsth2a-QEK-n8cwKttbzsTg2sqCowhXSqFEvy39o_ivuY/s1600/IMG_20130919_071441.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiqRKPXH4M4yQgngyuDdntIYf_ncn6_7cztnLp1G1k6hmlvlRvKq6P5Ipp1aFVB_e53w1MGCUIxCElZbPHfkPa3l8Hr6kHGpqsth2a-QEK-n8cwKttbzsTg2sqCowhXSqFEvy39o_ivuY/s320/IMG_20130919_071441.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">BREAKFAST!</td></tr>
</tbody></table>
<br />
Well, that's that.<br />
<div>
Things that were awesome:</div>
<div>
<ol style="text-align: left;">
<li>nTech</li>
<li>Anston</li>
<li>Bacon</li>
</ol>
Things I figured out:<br />
<br />
<ol style="text-align: left;">
<li>People drink way too much coke and pepsi, ie Soda.</li>
<li>Weather is awesome. I wanna live there!</li>
<li>People don't honk at the signals.</li>
<li>They have unicycles.</li>
</ol>
<br />
<br />
<br /></div>
</div>
Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-19158216159845183882013-07-03T21:58:00.001-07:002014-09-30T04:43:22.936-07:00Adventure at the RTA<div dir="ltr" style="text-align: left;" trbidi="on">
Sometime during the month of May'13, I had moved to a new apartment in Whitefields, Hyderabad. It was a way too spacious 4BHK along with other homely cynics like myself. I had always wanted to get myself a ride, for it seemed inefficient to spend on those accursed autos. Moreover with my own ride, I would no longer have to restrict myself to the office cab timings. I could enjoy the luxury of work for extended hours... workaholic, much?<br />
<br />
There are two parts to this story. One about my adventure to obtain the fabled Learner's License, and another quest to own a scooter.<br />
<br />
<br />
<a name='more'></a><br />
Getting yourself ANY government document in India isn't that easy, especially when you are a nomad. Well, except for the Income Tax department, which, has a world class super easy system to ensure highest "performance". You can get your PAN card within the week and even file your IT returns online on a server that is never down. <i><b>*clap*</b></i><br />
But the RTA (Road Transport Authority) departments do not really want to engage themselves with the evil of "making life easier for the civilian". It's probably peer pressure. When a they see a fellow RTA colleague ruining a civilian's day, they believe that they too must take up the fad, else be mocked at the lunch table. How cute.<br />
<br />
Anyway, for some reason the Andhra Pradesh RTA had gone online with their license slots bookings. Must have been the drunken act of an RTA employee in a fit of altruism. He/She deserves a cake with strawberries., unless he/she has diabetes, of course. I hope they do.<br />
<br />
<div style="text-align: right;">
<b><a href="http://www.aptransport.org/html/online_services.htm">http://www.aptransport.org/html/online_services.htm</a></b></div>
<br />
Well, that made booking a slot for my Learner's pretty easy (costs about 60Rs), though I kinda had to google to figure out what my "<i>Mandal</i>" was, and I am still unsure if I put the right one up. Doesn't matter, got my slot anyway. Next up was a sub quest to gather all required papers to be dutiful presented to the troll officer a the designated RTA.<br />
<br />
Finally, the day had come. I double checked my inventory. I pretty much had all the quest items... except for a legitimate address proof. Apparently the Rent agreement (attested by a Public notary) isn't enough proof. This was my mistake. I was unable to gauge the level of my opponent, the Troll Officer at the RTA. He firmly shooed me away, pointing at a pretty ancient piece of manuscript stuck with tape right next to his tiny window. This described a list of what could have been considered as a proof of address. None of which could be legally obtained by a person not living in his own house - a tenant. I believe this might be a conspiracy to ensure that people without their own houses have a hard time... or, maybe the folks at the RTA are just good people and are subtly encouraging you to get your own house.<br />
<br />
But there was one list item that seemed "doable" - A bank statement or a copy of the Passbook of a Bank showing your address" - a ray of hope, indeed.<br />
<br />
Cutting the long story, short. While I was a student at NIT, Warangal, I had to set up a mandatory account at the State Bank of Hyderabad, attached to the Institute. So, I got that account swiftly transferred to the nearest SBH (which was actually pretty near...). Got my address updated. By the way, they too wanted a proof of address, but unlike the RTA folks, they were satisfied with a simply HR letter from Nvidia stating the same. Obtained a new passbook and a scroll of Bank Statement, this time, mentioning my address. Phew!...<br />
<br />
Booked another slot. Another try at this quest. The Troll was pretty annoyed that I had all my papers in order. This time around, I had emerged victorious with a duly attested Learner's License in hand. The test itself was a meagre - Answer 20 multiple choice questions in 10 minutes. Piece of cake...<br />
<br />
<div style="text-align: right;">
<i>Here's a mock test, if you ain't confident enough. Honestly, the test was just common sense.</i></div>
<div style="text-align: right;">
<a href="http://llrmocktest-aptd.cgg.gov.in/Home.aspx">ht<b>tp://llrmocktest-aptd.cgg.gov.in/Home.aspx</b></a></div>
<br />
<br />
Now, it was time to get myself a scooter. My evil steed... My 110cc Red Dullahan. This quest was far easier than I had thought. Went up to the nearest Honda Showroom, asked them what scooter was available. They eagerly presented a Red Dio, ready to sell off. Activas and Aviators had a waiting period of 45+ days... and I didn't want to wait. Bought myself that Dio...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglSid2jJzVyVth77x5mECwmagh960DI7Syl_TUultruDSLdoDC7cldivyZ14PP3YDAjNuDypzHm4sonnLP6Wusyeir-U7jWTawVMdZg48xe-8eT4aGbeiuJqN93jqynh2MlGYPAbvaUn0/s1600/IMG_20130606_094910.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglSid2jJzVyVth77x5mECwmagh960DI7Syl_TUultruDSLdoDC7cldivyZ14PP3YDAjNuDypzHm4sonnLP6Wusyeir-U7jWTawVMdZg48xe-8eT4aGbeiuJqN93jqynh2MlGYPAbvaUn0/s320/IMG_20130606_094910.jpg" height="320" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip0CytvJZvh-d_ImgFHO6w9Hr1IeH-DUDtiAPePmPHP4VOD9D_biLlLyJtdJI1i51EkoovYykESrxINohQO6EhO0t3Kn8tHdKhbUwktscoWISssvNs_9P9eZXhjqoNu5-DeiZklcylVeQ/s1600/IMG_20130605_101238.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip0CytvJZvh-d_ImgFHO6w9Hr1IeH-DUDtiAPePmPHP4VOD9D_biLlLyJtdJI1i51EkoovYykESrxINohQO6EhO0t3Kn8tHdKhbUwktscoWISssvNs_9P9eZXhjqoNu5-DeiZklcylVeQ/s320/IMG_20130605_101238.jpg" height="320" width="320" /></a></div>
<br />
<br />
Considering that the Showroom wanted the customers to have a smooth purchasing experience with them... they had their hands inside the RTA's pants. Got my registration done in a jiffy. All I had to do was present myself at the RTA and sign. The agent that was assigned to me handled all of the nasty paperwork...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-CI2zKRnOcm8/UdUAeJHeckI/AAAAAAAABcQ/0TfYj8drg9Y/s1600/IMG_20130625_090913.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-CI2zKRnOcm8/UdUAeJHeckI/AAAAAAAABcQ/0TfYj8drg9Y/s320/IMG_20130625_090913.jpg" height="320" width="320" /></a></div>
<br />
<br />
This is an important lesson. The Indian System is pretty much corrupt. But... It also promotes employment. It has created a whole layer of middle men (agents) in between the Gov't and the Civilian. Fascinating, yet absolutely redundant and wasteful. </div>
Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-91224192805681265462013-06-10T22:19:00.002-07:002013-06-10T22:20:53.468-07:00A Small Dinner for One, Please<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white; color: #404040;"><span style="font-family: inherit; line-height: 18px;">Been cooking these days. Dinner only. For breakfast, the most important meal of the day, I have a disciplinary small serving of bran cereal with milk every morning (With militarist discipline, yes). Lunch, I grab a <i>roti </i>(Indian flat bread) or two with a small cup of <i>dal </i>(lentil soup)... sometimes with a dash of a random Indian side dish (I call this indulging, and I ashamed of it). </span></span><br />
<span style="background-color: white; color: #404040;"><span style="font-family: inherit; line-height: 18px;"><br /></span></span>
<span style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif;"><span style="font-size: x-small;"><span style="line-height: 18px;"><br /></span></span></span>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://www.kelloggs.ca/content/dam/common/products/AllBranFlakescereal_19.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="http://www.kelloggs.ca/content/dam/common/products/AllBranFlakescereal_19.jpg" width="207" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">the Breakfast</td></tr>
</tbody></table>
<span style="color: #404040; font-family: Roboto, arial, sans-serif; font-size: x-small;"><span style="line-height: 18px;"></span></span><br />
<a name='more'></a><span style="color: #404040; font-family: Roboto, arial, sans-serif; font-size: x-small;"><br /></span>
<div style="text-align: left;">
<span style="font-family: inherit;"><span style="line-height: 18px;">Now, Dinner is a whole different game. This meal, I do make myself, like a robot who can fend for himself. I love green peas. I add green peas to most my my culinary misadventures. Here's some filler text, describing how awesome green peas are! :</span></span></div>
<span style="background-color: white; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 18px;"><br /></span>
<i><span style="font-family: inherit;"><span style="background-color: white; line-height: 18px;">Whole peas need to be soaked in cold water for at least eight hours before cooking, while split peas do not need this extra preparation. To prepare peas, place the legumes in a saucepan using three cups of fresh water for each cup of peas. Bring to a boil and then reduce to a simmer and cover. Whole peas generally take about an hour to become tender while split peas only take about 30 minutes. Foam may form during the first 15 minutes of cooking, which can simply be skimmed off. </span><span style="background-color: white; color: blue; line-height: 18px;"><a href="http://www.whfoods.com/genpage.php?tname=foodspice&dbid=56" target="_blank">LINK</a></span></span></i><br />
<br />
I usually, just boil some mixed frozen veg (contains carrots, beans, cauliflower and obviously, green peas) in a small tsp of olive oil (Xtra virgin, duh!) and some random seasoning (salt, pepper, mystery Indian spice mix). Drain and served with dressings that I find in the local super market.<br />
<br />
Sometimes, if I'm too lazy, or far too guilty of my indulgence during lunch, I go for a quick recipe - A small bowl of shredded toast and a diced tomato, drenched in yogurt, with a dash of pickle for taste (Usually garlic or prawn - I <3 Goan Prawn Pickle! - Goa, A state in India). Yup, quite humble.<br />
<br />
I poached chicken too... though I need to work on this. I scramble eggs as well, when I feel peckish.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1sPI257aHpxB94fkC6KMMOhOsH_pf6mNxNCQJjwDQ9kxh6BByckIPx2mzwrMzDKdvTQEUOcLtDDyE_JE_2qcul3Tiu1tjKKJjE0-5DHbNXrckQW5oVcsX6D6CPQVu5YWsB7rZY0LYxpg/s1600/IMG_20130602_181538.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1sPI257aHpxB94fkC6KMMOhOsH_pf6mNxNCQJjwDQ9kxh6BByckIPx2mzwrMzDKdvTQEUOcLtDDyE_JE_2qcul3Tiu1tjKKJjE0-5DHbNXrckQW5oVcsX6D6CPQVu5YWsB7rZY0LYxpg/s320/IMG_20130602_181538.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Scrambled Eggs with assorted veggies</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-imr9RflIJXw/Ua4W3ddTQBI/AAAAAAAABUc/6zjowHhHFyo/s1600/IMG_20130524_210409.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="http://4.bp.blogspot.com/-imr9RflIJXw/Ua4W3ddTQBI/AAAAAAAABUc/6zjowHhHFyo/s320/IMG_20130524_210409.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Tomatoes, Peas, beans and Yogurt!</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-tjszZj_E8O0/Ua4W5kuh9yI/AAAAAAAABUs/oaww_-QoDfE/s1600/IMG_20130523_194254.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="http://4.bp.blogspot.com/-tjszZj_E8O0/Ua4W5kuh9yI/AAAAAAAABUs/oaww_-QoDfE/s320/IMG_20130523_194254.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Beans Galore - French Salad Dressing</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9LXi9GUiEgll78YMJ957dUmi_-JymD1YJWGI91Xq6ahr39qbL1RWwRuszWGsc0ngDKNYiT-t32r1Ec1r4n5u6CDwWCcN6SveSE6ABlptsC84FuTLuRzGFffJDEOzlO-pvawf-t8Ppd3o/s1600/IMG_20130610_174050.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9LXi9GUiEgll78YMJ957dUmi_-JymD1YJWGI91Xq6ahr39qbL1RWwRuszWGsc0ngDKNYiT-t32r1Ec1r4n5u6CDwWCcN6SveSE6ABlptsC84FuTLuRzGFffJDEOzlO-pvawf-t8Ppd3o/s320/IMG_20130610_174050.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Poached Chicken with boiled mushrooms and Spinach</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-p8Lql6AMJDs/Ua4WyijVuCI/AAAAAAAABUE/1WWcjmCbN9Y/s1600/IMG_20130604_192542.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="http://2.bp.blogspot.com/-p8Lql6AMJDs/Ua4WyijVuCI/AAAAAAAABUE/1WWcjmCbN9Y/s320/IMG_20130604_192542.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Cabbage Mush - Yes, I am calling it that. Hmph!</td></tr>
</tbody></table>
<br /></div>
Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-14121787832479908062013-05-29T21:50:00.002-07:002013-05-29T21:52:39.347-07:00Tame your Samsung Galaxy SIII<div dir="ltr" style="text-align: left;" trbidi="on">
As you might know (or not) that I had previously, rooted my S3 as soon as I had gotten it. For a very good reason too. The stock apps (samsung push, etc) were really bad on my battery. So, I had to root and clear out those stock apps via Titanium Backup.<br />
<br />
<div style="text-align: right;">
<i>read: <a href="http://robotcantalk.blogspot.in/2013/03/root-your-galaxy-siii.html">http://robotcantalk.blogspot.in/2013/03/root-your-galaxy-siii.html</a></i></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-KUEmqKwhF8A/UZ7r9bCezsI/AAAAAAAABRs/lMehHHkzPgk/s1600/Screenshot_2013-05-24-09-51-58.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="http://2.bp.blogspot.com/-KUEmqKwhF8A/UZ7r9bCezsI/AAAAAAAABRs/lMehHHkzPgk/s640/Screenshot_2013-05-24-09-51-58.png" width="360" /></a></div>
<br />
<a name='more'></a><br />
<br />
Now, months had passed, and I had gotten quite bored with Touchwiz. Not to mention, I really missed JB 4.2.2 which I had on my HTC DesireS (rooted+Andromadus ROM - CM 10.1 based). So, I flashed a CM 10.1(CyanogenMod) rom onto my S3. It's <i>waaaaaay </i>smoother now.<br />
<br />
First, I upgraded my recovery (TWRP) to the latest version - <a href="http://www.teamw.in/project/twrp2">http://www.teamw.in/project/twrp2</a> . You gotta do this via Odin (check my Root the S3 post on how to do this).<br />
Second, scout for roms on <a href="http://forum.xda-developers.com/forumdisplay.php?f=1563" target="_blank"><b><i><span style="color: blue;">xda</span></i></b></a>. The good folks on xda, have many a thread indexing all of them. Check them out and pick any that meets your fancy.<br />
<br />
Get the rom and the appropriate Google apps (each version of Android comes with a different set of gapps - Don't mess this up). Follow the instructions on the thread and you are done. The dance usually goes like this:<br />
<br />
<ul style="text-align: left;">
<li>Download ROM and Gapps onto sdcard</li>
<li>Boot into rcovery.</li>
<li>Factory reset.</li>
<li>Wipe cache + Dalvik.</li>
<li>Flash ROM.</li>
<li>Flash Gapps.</li>
<li>Reboot.</li>
</ul>
So... I flashed <b><i><a href="http://forum.xda-developers.com/showthread.php?t=2264782" target="_blank"><span style="color: blue;">LiquidSmooth</span> </a>2.5</i></b> (CM 10.1 based). Did I mention how <i>smoooooth </i>things are? :)With CM10.1 you get profiles and quickTiles and the whole Dark Android theme.<br />
<br />
While you are at it, you should look into this app - <a href="https://play.google.com/store/apps/details?id=com.dianxinos.dxbs.paid&hl=en" target="_blank"><span style="color: blue;"><b><i>Battery Saver Du</i></b></span></a>. The best and most legit battery saver app I have ever seen. It's worth the few pennies you throw at it. With regular use (Always ON wifi/data/gps), I easily scrape 40hrs of battery life. To truly benefit from this app, you'd better have root though.<br />
<br /></div>
Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-64592598164478491502013-05-07T02:32:00.001-07:002013-05-07T02:37:30.691-07:00Lets Move<div dir="ltr" style="text-align: left;" trbidi="on">
Damn... it's been ages since I even looked at this blog. It's become my ignored bastard child. I just don't feel motivated to drive the original goal any more - to rant about pretty much everything. Being doing that a lot of facebook, lately. Maybe I should just port some of those threads here, verbatim. Hmmmm... I'll think about it.<br />
<br />
I even stopped OfficeMan for Odin's sake! :(<br />
<br />
Anyway! I have switched cubicles at work. Had to move all my stuff too. Re-stick all the posters and paraphernalia I am also switching flats during the weekends. Moving to an awesome 4bhk in Whitefields, Hyderabad. Yay...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-nyxrz2aEFdg/UYjIaVU2MQI/AAAAAAAABFM/Nhfj_ZIov5w/s1600/20130507_121033.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://1.bp.blogspot.com/-nyxrz2aEFdg/UYjIaVU2MQI/AAAAAAAABFM/Nhfj_ZIov5w/s320/20130507_121033.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-Hx4MoRqrxY4/UYjIdUZPwAI/AAAAAAAABF0/I8XwILTrEXY/s1600/20130507_121009.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://1.bp.blogspot.com/-Hx4MoRqrxY4/UYjIdUZPwAI/AAAAAAAABF0/I8XwILTrEXY/s320/20130507_121009.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAlL5IEV9HsoEX-wI-eEMwbJ7b9uMwS-1-PD00UtSEKHuvA_qhu1lejwCUhfVCQ7JMUOLqy1N5y5unmcepBnZ6lQGF5m1OYhDP5vlV9JQM56JNOuOR6-kxQ4PqenyY_Z7UHkbkW1yhwBo/s1600/20130507_120946.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAlL5IEV9HsoEX-wI-eEMwbJ7b9uMwS-1-PD00UtSEKHuvA_qhu1lejwCUhfVCQ7JMUOLqy1N5y5unmcepBnZ6lQGF5m1OYhDP5vlV9JQM56JNOuOR6-kxQ4PqenyY_Z7UHkbkW1yhwBo/s320/20130507_120946.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br /></div>
Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-84725104909476171262013-03-28T23:47:00.000-07:002013-03-28T23:47:25.649-07:00Root your Galaxy SIII<div dir="ltr" style="text-align: left;" trbidi="on">
Why would I root a brand new Samsung Galaxy S3, within three days of purchase, you ask? Well, in all honesty, sammy apps were killing the battery - Samsung Push, after I jumped to Jellybean 4.1.2 stock. It was unrelentingly annoying. So, I had no choice but to root it and get rid of bloatware. Guess what... It took five minutes to do so.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-GthI_yXxkw4/UUuve4-HNGI/AAAAAAAAA9M/yhykZy7-d_k/s1600/2013+-+1" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="http://3.bp.blogspot.com/-GthI_yXxkw4/UUuve4-HNGI/AAAAAAAAA9M/yhykZy7-d_k/s400/2013+-+1" width="225" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">After Root + bloatware removal</td></tr>
</tbody></table>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-iNgzMrnGeJk/UUuve21HykI/AAAAAAAAA9U/wgJI6OBjsH4/s1600/2013+-+2" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://2.bp.blogspot.com/-iNgzMrnGeJk/UUuve21HykI/AAAAAAAAA9U/wgJI6OBjsH4/s400/2013+-+2" width="225" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<a name='more'></a><br />
<h3 style="text-align: left;">
How to Root</h3>
Get Samsung S3 drivers - first -<a href="http://www.teamandroid.com/download-android-usb-drivers/" target="_blank"> http://www.teamandroid.com/download-android-usb-drivers/ </a><br />
<br />
Basically, I used the ChainFire Root + Odin method. Kinda way too easy.<br />
Get these:<br />
<br />
<ul style="text-align: left;">
<li>ChainFire tarball - <a href="http://download.chainfire.eu/232/CF-Root/CF-Auto-Root/CF-Auto-Root-m3-m3zh-gti9305.zip" target="_blank">LINK</a></li>
<li>Odin v1.85 - <a href="http://www.mediafire.com/download.php?hbc7pyftyyu75fr" target="_blank">LINK</a></li>
</ul>
<div>
Boot to Odin mode - Shutdown, then press - Volume Down + Power + Home button together... You'll get a warning screen. Go along with it. Connect the phone to the computer via USB, now.</div>
<div>
<br /></div>
<div>
Run Odin in admin mode. If your phone had it's drivers installed properly, then you should see a COM port listing in Odin. Select the chainfire tarball in the PDA tab. Make sure Autoreboot is NOT checked.</div>
<div>
<br /></div>
<div>
Click on Start. It takes seconds... and whence Odin reports success (everything is green)... <I know most of you are going to cringe at this next part, but...> ... remove the battery and put it back again - ie: Hard reboot.<br /><br />Boot up phone... and you have a rooted S3. Simple wasn't it? Told, ya. It takes less than 5 minutes.</div>
<div>
<br /></div>
<h3 style="text-align: left;">
Post Rooting</h3>
<div>
Install Titanium backup and uninstall bloatware - especially Samsung Push.</div>
<div>
<br /></div>
<div>
I wasn't a fan of ClockworkMod recovery (default installed with ChainFire). So I got rid of that (via titanium backup) and replaced it with TWRP (install via Odin).</div>
<div>
<br /></div>
<div>
Also there's another tool call PalaTool which helps remove bloatware and gives you the option of installing stock android apps - AOSP calender, clock, keyboard, etc.</div>
<div>
<br /></div>
<div>
Fun! Never had such good battery life, and I am still using stock.</div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
</div>
Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-33950378025412221482013-03-05T04:00:00.002-08:002013-03-07T21:16:24.550-08:00I DesireS Jellybean<div dir="ltr" style="text-align: left;" trbidi="on">
I have always been afraid of tampering with my <span style="background-color: cyan;"><b>HTC Desire S</b></span>. Not in the fear of voiding warranty, rather following the logic of <i>"Why fix something when it's not broken"</i>. It's nearly two years old now and I have been in the mood of getting a new phone since MWC'13. With Samsung Galaxy S4 and HTC ONE looming around the corner, causing the prices of galaxy S3 and oneX to plummet, now was the perfect time to truly enjoy android. I must warn you though... trying to "<i>have fun</i>" with an HTC phone is one pain in the circuit. Obviously, I am not commanding you to do anything... it is you, who must decide to pursue this lolgag or not and risk bricking your device.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6gNLKVcrCn_yxXu6VSwEwmkBW3_dy6s0UoBwW8V1hUKrZcYSK6eDWG7j8Xc2k1ejvmA_8kFOma71O4edZnkxTK00PKX8N9OSB69XNfbqPGYu-2ds-wN32POYH9mGrcf_vJBbSaen2-08/s1600/2013-03-04" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6gNLKVcrCn_yxXu6VSwEwmkBW3_dy6s0UoBwW8V1hUKrZcYSK6eDWG7j8Xc2k1ejvmA_8kFOma71O4edZnkxTK00PKX8N9OSB69XNfbqPGYu-2ds-wN32POYH9mGrcf_vJBbSaen2-08/s320/2013-03-04" width="192" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">JB-4.2.2 on Desire S. Woohoo!</td></tr>
</tbody></table>
<br />
<br />
<a name='more'></a><br /><br />
<h2 style="text-align: left;">
Objective</h2>
Install Android JellyBean 4.2.2 on a stock HTC Desire S with HTC Gingerbread 2.3.5<br />
<br />
<h2 style="text-align: left;">
How-To</h2>
<div>
Well... the general OEM android phone would have it's bootloader locked, ie: No root access for you. Need to get rid of that first, and voila we are done. NOT! Desire S being an HTC phone, you'd also have to deal with the S-OFF/ON situation. HTC phones are default S-ON, blocking access to NAND. That makes this game a whole lot messy/fun.</div>
<div>
<br /></div>
<div>
Rooting is truly simple. But getting going S-ON to S-OFF is not. For S-OFF you'd need to replace your bootloader with ENG HBOOT (from Revolutionary), and that only works when your stock hboot is 0.98.x., which is not the case in most Desire S with GB-2.3.5. So, logically, you'd have to downgrade your hboot from whatever version you have (I had v2.x.x) to v0.98.x and then S-OFF. To downgrade your device, you'd need to install an older RUU (ROM Update Utility - Stock android from OEM) from HTC which would be region specific. What if you don't find an older RUU for your region (like in my case)!? You'd need a GoldCard which allows you to install any RUU regardless of region checks. So, now you install an older RUU to get an older hboot - v0.98.x. Revolutionary's S-OFF tool can now work with this. With this, you now have an S-OFF'd device. Flash a recovery again. Root your phone via recovery. And we are done. You can now flash any rom you want via the recovery you installed. I warned ya that it was going to be a pain.</div>
<div>
<ol style="text-align: left;">
<li>Unlock device via HTCDev.</li>
<li>Make a GoldCard.</li>
<li>Flash a recovery #1.</li>
<li>Flash Root #1.</li>
<li>Change device version to an older one than the old RUU that you are going to install to downgrade your hboot to 0.98.x. Via misc_version.</li>
<li>Lock device via fastboot.</li>
<li>Install RUU</li>
<li>Run Revolurionary's S-OFF tool.</li>
<li>Flash a recovery #2.</li>
<li>Done.</li>
<li>Install Custom Rom for lulz.</li>
</ol>
<div>
<br /></div>
<h3 style="text-align: left;">
0. Prerequisites</h3>
<div>
You'll need a few things in the right place.</div>
<h4 style="text-align: left;">
DesireS/Android drivers</h4>
<div>
Download HTC Sync, install it. Plug in device and let it install the drivers. Now, uninstll HTC Sync - we only needed that trash of an application for it's bundeled drivers.</div>
<h4 style="text-align: left;">
DesireS All-in-One Toolkit v2.0</h4>
<div>
<a href="http://forum.xda-developers.com/showthread.php?t=2088385" target="_blank">Link</a></div>
<div>
The biggest and baddest gun in the arsenal. Has a lot of utils and comes with <b><i>adb </i></b>and <i style="font-weight: bold;">fastboot </i>(which you'll use quite often). This is what you'll use to root it the first time (Unlock via HTCDev). Also you'll use it quite often to boot into bootloader/recovery, in case you are too lazy to type out shell commands. Instead of having to download the whole SDK or android utils, just get this and familiarize yourself with the interface (kinda way too simple really).</div>
<h4 style="text-align: left;">
GoldCard Utils</h4>
<div>
You'll need a spare microSD (small one is fine, I used a 1GB) to act as your GoldCard for your device. A GoldCard is basically a little code in the code section of your microSD header. Helps bypass RUU region checks. Also in case you brick your phone, you can use this to install a fresh RUU.</div>
<div>
Dowload <a href="https://sites.google.com/site/roothtchero/goldcard-2" target="_blank">GoldCard Tool</a>.</div>
<h4 style="text-align: left;">
Root App - su</h4>
<div>
Inorder to gain root, you'll need to flash a root app through recovery.</div>
<div>
Dowload and keep <a href="http://download.chainfire.eu/315/SuperSU/UPDATE-SuperSU-v1.25.zip" target="_blank">SuperSU</a>.</div>
<h4 style="text-align: left;">
Recovery</h4>
<div>
Every rooted android phone has a recovery flashed on it. This is what you'll use to install roms, install zips, clear cache/data, even backup. Very important and very useful. I picked <a href="http://www.4ext.net/ddl/saga/recovery.zip" target="_blank">4ext </a>(<a href="http://forum.xda-developers.com/showthread.php?t=1377745" target="_blank">xda-forum</a>)for this. You may also pick amongst <a href="http://www.clockworkmod.com/rommanager" target="_blank">CWM </a>and <a href="http://teamw.in/project/twrp2" target="_blank">TWRP</a>. Get the <b><i>recovery.img</i></b> and keep it somewhere for any of them. You'll use fastboot to flash the recovery image.</div>
<h4 style="text-align: left;">
misc_version</h4>
<div>
This helps mask the device version to a very old one, so that you may install the old RUU on it. </div>
<div>
<a href="http://forum.xda-developers.com/showthread.php?t=1318919" target="_blank">xdaForumLink</a> - <a href="http://forum.xda-developers.com/attachment.php?attachmentid=762966&d=1319707863" target="_blank">downloadZip</a></div>
<h4 style="text-align: left;">
The RUU</h4>
<div>
Any old HTC Desire S RUU will do as we have a GoldCard. I picked - RUU_Saga_HTC_Europe_1.28.401.1</div>
<div>
<a href="http://www.androidfiles.org/ruu/?dir=Saga" target="_blank">Directory1 </a>- <a href="http://www.tsar3000.com/Joomla/index.php?option=com_content&view=article&id=492:htc-desire-s-s510e-saga-stock-roms&catid=65:htc-downloads&Itemid=107" target="_blank">Directory2</a></div>
<div>
My DesireS has a region code of HTC__J15, which is the GCC region. I couldn't find any old RUU for my region.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Try to keep all of the above in the same place. I kept all the software/img/zip/ruu in the DesireS All-in-One's resource directory - where adb and fastboot reside.</div>
<div>
<br /></div>
<div>
Ensure that USB Debugging is enabled and that the phone is indeed connected to the PC. Quite often that's the solution to many problems you might face.</div>
<div>
<br /></div>
<div>
Check with adb shell (comes with the All-in-One Tkit) command:</div>
<div>
<br /></div>
<div style="text-align: left;">
<span style="font-family: Courier New, Courier, monospace;">> adb devices</span></div>
<div>
<br /></div>
<h3 style="text-align: left;">
1. Unlock Device via HTCDev</h3>
</div>
<div>
Use the DesireS All-in-One toolkit and get this done. Make sure USB debugging is enabled on the device. It's the steps in the top-left pane, titled, "To Root the Phone, Follow in Order". Once all the five steps are done. Boot in bootlader and verify - *UNLOCKED* </div>
<div>
<br /></div>
<h3 style="text-align: left;">
2. Make a GoldCard</h3>
<div>
<ol style="text-align: left;">
<li>Take your microSD and format in the phone.</li>
<li>Connect to PC as disk Drive.</li>
<li>Place the SuperUser app zip in it (Will be used later).</li>
<li>Follow <a href="https://sites.google.com/site/roothtchero/goldcard-2" target="_blank">Instructions</a>.</li>
</ol>
<div>
Now that you have a GoldCard, you are <i>almost </i>ready for an RUU installation.</div>
</div>
<div>
<br /></div>
<h3 style="text-align: left;">
3. Flash a Recovery #1</h3>
<div>
Use All-in-One Tkit to boot into bootloader. Then use fastboot via cmd prompt. The below commands consider that you have recovery.img and fastboot in the same directory.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">fastboot flash recovery recovery.img</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">fastboot reboot-bootloader</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<h3 style="text-align: left;">
4. Flash Root #1</h3>
<div>
Now that you have installed a recovery and are in the bootloader. Get into the recovery. </div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://forum.xda-developers.com/attachment.php?attachmentid=807847&stc=1&d=1323221036" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://forum.xda-developers.com/attachment.php?attachmentid=807847&stc=1&d=1323221036" width="192" /></a><a href="http://forum.xda-developers.com/attachment.php?attachmentid=807845&stc=1&d=1323221036" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://forum.xda-developers.com/attachment.php?attachmentid=807845&stc=1&d=1323221036" width="192" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Install the SuperUser zip. There should be an option somewhere in your recovery tool to install from zip (in 4ext, this is inside "<i>install from SDCard</i>" menu).</div>
<div>
After installation, reboot the phone normally in the recovery itself ("<i>reboot now</i>").</div>
<div>
<br /></div>
<div>
Go to the SuperSU app, and set the "user permissions/handling of new requests" from <i>prompt </i>to <i>grant</i>. This is very important for the next step.</div>
<div>
<br /></div>
<h3 style="text-align: left;">
5. misc_version</h3>
<div>
Ensure USB debugging is on while the phone is connect as "<i>Charge Only</i>". In the command prompt shell, </div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">> adb push misc_version /data/local/tmp</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">> adb shell chmod 777 /data/local/tmp/misc_version</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">> adb shell</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">$ su</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"># cd /data/local/tmp</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"># ./misc_version -s 1.27.405.6</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"># exit</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">> adb reboot-bootloader</span></div>
</div>
<div>
<br /></div>
<div>
<span style="font-family: inherit;">Note that, ">" is cmdPrompt, '$' is adbShell and '#' is su granted adb shell. It has to be a '#' else you have not been given root access permission and you must redo the previous step (Step 4).</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">The misc_version argument (</span><span style="font-family: 'Courier New', Courier, monospace;">1.27.405.6</span><span style="font-family: inherit;">) has to be very accurate, else the next step won't work.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<h3 style="text-align: left;">
<span style="font-family: inherit;">6. Relock Device</span></h3>
<div>
<span style="font-family: Courier New, Courier, monospace;">fastboot oem lock</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">You'll see an error in the cmdPrompt. Ignore it.</span></div>
<div>
<span style="font-family: inherit;">The device should restart itself. If not already at bootloader, restart into bootloader. You'll see a *RE-LOCKED*</span></div>
<div>
<span style="font-family: inherit;">So far so good. Reboot the phone normally.</span></div>
<div>
<br /></div>
<h3 style="text-align: left;">
7. Install RUU</h3>
<div>
Ensure USB Debugging. Run the RUU.exe</div>
<div>
Sit back and relax. If you have done everything to the word so far, then you shouldn't be seeing any problem. The RUU will detect your phone's version as 1.27.405.6 and "upgarde" accordingly.</div>
<div>
<br /></div>
<div>
When done. Restart into bootloader and observer the hboot version. Should be some 0.98.x.x.</div>
<div>
<br /></div>
<h3 style="text-align: left;">
8. Revolutionary's S-OFF</h3>
<div>
<a href="http://revolutionary.io/">http://revolutionary.io/</a></div>
<div>
<ol style="text-align: left;">
<li>Get the zip - revolutionary-<i>version</i>.zip</li>
<li>Run revolutionary.exe, get beta key.</li>
<li>Fill in your info in the form on the site and get the serial key.</li>
<li>Enter the serial key in to the tool.</li>
<li>Time for another coffee...</li>
</ol>
<div>
This will temproot your phone via zergRush and S-OFF it. You'll see some message about life and lemons. That's when you it's going smooth.</div>
</div>
<div>
<br /></div>
<h3 style="text-align: left;">
9. Flash a Recovery #2 - Same as Step 3</h3>
<h3 style="text-align: left;">
10. Done</h3>
<div>
You have now successfully rooted your HTC Desire S. Woohoo!</div>
<div>
<br /></div>
<h3 style="text-align: left;">
11. Installing JB</h3>
<div>
I picked<i> Flinny <a href="http://andromadus.flinny.org/" target="_blank">Andromadus </a>CM_10.1 build 16</i> for this. It comes with Jellybean 4.2.2. Get the rom zip and the google apps (gapps zip). Place the same in the root of your SDCard.</div>
<div>
<br /></div>
<div>
Boot into recovery (You should know how to do this by now)</div>
<div>
<br /></div>
<div>
Check md5 and then install the rom followed by the apps. If you have some backup.zip (from nandroid or Titanium backup), now is a good time to install that too.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3fyODvpvy4JNemX2o7tpBHUQ_9nSl-YxEp7giFjhnDaUsRJL-8Yxfxqpt1B50aKpGgYL7ab0RG17FnTmWd_oBSAP9J1MR2_jUdfsU_MFVS3_ao8wY46oKnrYEBBYdwy06T-9j0f3bp5gb/s1600/Screenshot_2013-03-05-17-29-12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3fyODvpvy4JNemX2o7tpBHUQ_9nSl-YxEp7giFjhnDaUsRJL-8Yxfxqpt1B50aKpGgYL7ab0RG17FnTmWd_oBSAP9J1MR2_jUdfsU_MFVS3_ao8wY46oKnrYEBBYdwy06T-9j0f3bp5gb/s400/Screenshot_2013-03-05-17-29-12.png" width="240" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
</div>
Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-12269018041566596802013-02-13T00:51:00.000-08:002013-02-13T00:51:20.538-08:00OfficeMan #28<div dir="ltr" style="text-align: left;" trbidi="on">
Parrot Blade Tonfa?... I need a sanity check or a some fresh creativity.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqmA1PFUT9IRGR_efs7S87XzFA54aauyfVKDbtsHcFvD7uGeDes5uiq6Wa4Sca7Vuf_gma8SuavvIqN26Q0koFWaMx6tc_-A5gn26JHbjnpBf4tfZjEdeGt7ROHICLtQl0YMk4aNhn86c/s1600/IMAG0425.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqmA1PFUT9IRGR_efs7S87XzFA54aauyfVKDbtsHcFvD7uGeDes5uiq6Wa4Sca7Vuf_gma8SuavvIqN26Q0koFWaMx6tc_-A5gn26JHbjnpBf4tfZjEdeGt7ROHICLtQl0YMk4aNhn86c/s320/IMAG0425.jpg" width="320" /></a></div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0tag:blogger.com,1999:blog-5309295576532710519.post-11059619024812471682013-02-07T03:16:00.002-08:002013-02-07T03:16:40.137-08:00Philately ... LOL!<div dir="ltr" style="text-align: left;" trbidi="on">
So... I used to collect stamps as a kid [-_-] . Thee's a good variety. I found my stamp book when I went back home for a vacation.<br />
here,<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-l6rmMtBd-iI/UNsfsR5-W5I/AAAAAAAAAu8/myZE8Vd15DY/s1600/IMAG0329.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="http://4.bp.blogspot.com/-l6rmMtBd-iI/UNsfsR5-W5I/AAAAAAAAAu8/myZE8Vd15DY/s320/IMAG0329.jpg" width="320" /></a></div>
<br />
<a name='more'></a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMQ9oG1wrLx6dhC9y03IMp8VILt4aXamC1xE90uISIXLHEG517is4ddMqoqt3ZysxLLgOVBsgvFQ92bf9KO5kuwEp4r0Z3sH9A_UPy8JRkV6qmL3xPsXBL2r4WV2Plpe-G80CbmXftVY8/s1600/IMAG0330.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMQ9oG1wrLx6dhC9y03IMp8VILt4aXamC1xE90uISIXLHEG517is4ddMqoqt3ZysxLLgOVBsgvFQ92bf9KO5kuwEp4r0Z3sH9A_UPy8JRkV6qmL3xPsXBL2r4WV2Plpe-G80CbmXftVY8/s320/IMAG0330.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-ZVxDxK9vuZY/UNsfrbmYeOI/AAAAAAAAAu0/OOrnIeh5pRQ/s1600/IMAG0331.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="http://3.bp.blogspot.com/-ZVxDxK9vuZY/UNsfrbmYeOI/AAAAAAAAAu0/OOrnIeh5pRQ/s320/IMAG0331.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-LrOHw7uqK1E/UNsfxHN01II/AAAAAAAAAvM/BQqyOTG1oBg/s1600/IMAG0332.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="http://3.bp.blogspot.com/-LrOHw7uqK1E/UNsfxHN01II/AAAAAAAAAvM/BQqyOTG1oBg/s320/IMAG0332.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLKEw6FdUvIV0xflIQv3WZJVTZT-fTcUqQATx1qRfn9NMcIbizcPSZX9ZRcf2G2tPChLRmrQTMdaqJpsoQItTTue6iMeKzkHeriWsF4iwPYUB1vb6T3L0vE2NpOC2Cluywg91VGR_fnew/s1600/IMAG0333.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLKEw6FdUvIV0xflIQv3WZJVTZT-fTcUqQATx1qRfn9NMcIbizcPSZX9ZRcf2G2tPChLRmrQTMdaqJpsoQItTTue6iMeKzkHeriWsF4iwPYUB1vb6T3L0vE2NpOC2Cluywg91VGR_fnew/s320/IMAG0333.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-2Bz993Ohteo/UNsfz74luyI/AAAAAAAAAvY/6Snn_fEu0mA/s1600/IMAG0334.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="http://2.bp.blogspot.com/-2Bz993Ohteo/UNsfz74luyI/AAAAAAAAAvY/6Snn_fEu0mA/s320/IMAG0334.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimWwp2-SZfso_iv1sjf91cFv-VSJMatiEz47N6xnjEHRPyU-rnJnuW5RsXQH5Ipwo0HC22SWTvuzhTOMIy-nkmHRfSh5Ci3g7F-f9oTZI1gUAV3xKfIO-xQufKikzz_IRmW3o5KfC9hUw/s1600/IMAG0335.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimWwp2-SZfso_iv1sjf91cFv-VSJMatiEz47N6xnjEHRPyU-rnJnuW5RsXQH5Ipwo0HC22SWTvuzhTOMIy-nkmHRfSh5Ci3g7F-f9oTZI1gUAV3xKfIO-xQufKikzz_IRmW3o5KfC9hUw/s320/IMAG0335.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgphYBO5kJdYKoFN0xIGRESTOvrBjZAyBcbot9f_AdVJZvPZyotnwEDCKWvztCjvosLr7I3u9GmKVHL-oCLbh3-yQAVBqyJ24M5mmXsJmT8p0h6rlK7mYuF6Wr-G2G7CHit3akX9e3fDKQ/s1600/IMAG0336.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgphYBO5kJdYKoFN0xIGRESTOvrBjZAyBcbot9f_AdVJZvPZyotnwEDCKWvztCjvosLr7I3u9GmKVHL-oCLbh3-yQAVBqyJ24M5mmXsJmT8p0h6rlK7mYuF6Wr-G2G7CHit3akX9e3fDKQ/s320/IMAG0336.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1gTWDsi_Hq3SCeIEDr3v9Mu5AdATclRxHcaI8JqWm7tL-9aLs4IVZhRjO3teJHDQjRdHeE7Ff7HzIOrueq0_ukq9MPfPQRQErBRdA37JJ01PjeMznr5Y5zxFXQm6FL7JwLy-BriJgQfg/s1600/IMAG0337.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1gTWDsi_Hq3SCeIEDr3v9Mu5AdATclRxHcaI8JqWm7tL-9aLs4IVZhRjO3teJHDQjRdHeE7Ff7HzIOrueq0_ukq9MPfPQRQErBRdA37JJ01PjeMznr5Y5zxFXQm6FL7JwLy-BriJgQfg/s320/IMAG0337.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-WF9slEGUfmU/UNsf9RIH5bI/AAAAAAAAAv8/0mOBs3n6m5w/s1600/IMAG0338.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="http://2.bp.blogspot.com/-WF9slEGUfmU/UNsf9RIH5bI/AAAAAAAAAv8/0mOBs3n6m5w/s320/IMAG0338.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-_81rSmAIOHg/UNsf-cZiSzI/AAAAAAAAAwA/j_G6-oUlxu4/s1600/IMAG0339.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="http://2.bp.blogspot.com/-_81rSmAIOHg/UNsf-cZiSzI/AAAAAAAAAwA/j_G6-oUlxu4/s320/IMAG0339.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-OJlxVM8Q02c/UNsgCqxU8SI/AAAAAAAAAwQ/cpFYecu9jGM/s1600/IMAG0341.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="http://3.bp.blogspot.com/-OJlxVM8Q02c/UNsgCqxU8SI/AAAAAAAAAwQ/cpFYecu9jGM/s320/IMAG0341.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-F4e2anRQEIw/UNsgEs7s1MI/AAAAAAAAAwY/0Je5kCLa7y4/s1600/IMAG0342.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="http://1.bp.blogspot.com/-F4e2anRQEIw/UNsgEs7s1MI/AAAAAAAAAwY/0Je5kCLa7y4/s320/IMAG0342.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCFbUMmmgxK76YyAguJ3pUbOn7tj0469l90JW6t5O8E0JOmxREQcmP1k_a79n4w5lsqcl98KPtonooyBRHXRcyiAHuWgmHmY7x4BzNofyLwe4f8mHsX36SMNcFgvXW0v4rf5d4FLFER3s/s1600/IMAG0343.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCFbUMmmgxK76YyAguJ3pUbOn7tj0469l90JW6t5O8E0JOmxREQcmP1k_a79n4w5lsqcl98KPtonooyBRHXRcyiAHuWgmHmY7x4BzNofyLwe4f8mHsX36SMNcFgvXW0v4rf5d4FLFER3s/s320/IMAG0343.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-mP2_5dG4ZEU/UNsgIkpsV4I/AAAAAAAAAwo/nVLHMcgj6Fo/s1600/IMAG0344.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="http://1.bp.blogspot.com/-mP2_5dG4ZEU/UNsgIkpsV4I/AAAAAAAAAwo/nVLHMcgj6Fo/s320/IMAG0344.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw6RqWOQs1d8vywuB-gW9BtlZGRNESA7hmmPgkta4EevQXHtCLoXcMAH-HfG_3e3S6RbWRit43GY3rrXuQZKWRbeufgFGdvu9zIblIyPKT18Om2YpYZnDGX6ScndIB9D8hxe3ZDYPu9ps/s1600/IMAG0345.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw6RqWOQs1d8vywuB-gW9BtlZGRNESA7hmmPgkta4EevQXHtCLoXcMAH-HfG_3e3S6RbWRit43GY3rrXuQZKWRbeufgFGdvu9zIblIyPKT18Om2YpYZnDGX6ScndIB9D8hxe3ZDYPu9ps/s320/IMAG0345.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgC7OwZNsIEdLcaNVM8p3XEz4Nlvj0OFEnoToZSqP0haX8fjv78uabmZJMaK_p-YMBGhClJ10pVACy60cauaN-cXfn0SN_MqIW9_hRR9OcSeakL1N2kLOqN9Tf2uN13bEZhv3loM7hs8wI/s1600/IMAG0346.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgC7OwZNsIEdLcaNVM8p3XEz4Nlvj0OFEnoToZSqP0haX8fjv78uabmZJMaK_p-YMBGhClJ10pVACy60cauaN-cXfn0SN_MqIW9_hRR9OcSeakL1N2kLOqN9Tf2uN13bEZhv3loM7hs8wI/s320/IMAG0346.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-QBoez3Sc1CU/UNsgN0peaPI/AAAAAAAAAw8/cZYRQa1U2E0/s1600/IMAG0347.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="http://1.bp.blogspot.com/-QBoez3Sc1CU/UNsgN0peaPI/AAAAAAAAAw8/cZYRQa1U2E0/s320/IMAG0347.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQGZfH6NUtmrpyP-xOUuHoPwyCts1Sizk45yH1waI1qAOkb8UEIiQubvtWuCJDy6PaA6lyf0SherSfN8mheNDpRfF74FPQ6p0mj44A8el1cVPqRZhD3R1qRc3jV-Y3nlMKq_Ar5n4-Wco/s1600/IMAG0350.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQGZfH6NUtmrpyP-xOUuHoPwyCts1Sizk45yH1waI1qAOkb8UEIiQubvtWuCJDy6PaA6lyf0SherSfN8mheNDpRfF74FPQ6p0mj44A8el1cVPqRZhD3R1qRc3jV-Y3nlMKq_Ar5n4-Wco/s320/IMAG0350.jpg" width="320" /></a></div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/05434679103598742337noreply@blogger.com0