<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>BlockoS</title>
	<atom:link href="http://blog.blockos.org/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://blog.blockos.org</link>
	<description>MooZ devblog</description>
	<lastBuildDate>Sun, 24 Mar 2013 19:22:59 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Roger Quartermain and the lost script of the Heisei era.</title>
		<link>http://blog.blockos.org/?p=811</link>
		<comments>http://blog.blockos.org/?p=811#comments</comments>
		<pubDate>Sun, 24 Mar 2013 16:17:37 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[pc engine]]></category>

		<guid isPermaLink="false">http://blog.blockos.org/?p=811</guid>
		<description><![CDATA[Roger is happy. He bought a cheap PC-Engine CDRom game called &#8220;Nishimura Kyotaro Mystery.: Hokutosei No Onna&#8221;. It seems to be a detective game like J.B. Harold Murder Club, Jake Hunter, Ace Attorney, Le Manoir de Mortevielle or Maupiti Island. &#8230; <a href="http://blog.blockos.org/?p=811">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Roger is happy. He bought a cheap PC-Engine CDRom game called &#8220;Nishimura Kyotaro Mystery.: Hokutosei No Onna&#8221;. It seems to be a detective game like <a href="http://en.wikipedia.org/wiki/J.B._Harold_Murder_Club">J.B. Harold Murder Club</a>, <a hreaf="http://en.wikipedia.org/wiki/Jake_Hunter">Jake Hunter</a>, <a href="http://en.wikipedia.org/wiki/Ace_Attorney">Ace Attorney</a>, <a href="http://en.wikipedia.org/wiki/Mortville_Manor">Le Manoir de Mortevielle</a> or <a href="http://en.wikipedia.org/wiki/Maupiti_Island_%28game%29">Maupiti Island</a>. I was publish by Naxat (now <a href="http://www.kaga-create.co.jp/">Kaga Create</a>) in 1990.<br />
He remembers that some games have a language option. For example, the japanese version of J.B Harold Murder Club <a href="https://iwasateenagepcenginefan.wordpress.com/2011/02/16/so-uh-how-do-i-play-j-b-harold-murder-club-in-english/#comments">can be played in english</a>. Unfortunately such option was nowhere to be found in Hokutosei No Onna&#8230; Nevermind! Roger Quartermain grabs his boots, his hat and jumps into the game dark bowels!<br />
The introduction seems to be about some dude stabbed in his room, 2 girls going to a train station and another guy who is apparently stalking them.<br />
<img src="http://blog.blockos.org/wp-content/uploads/2013/03/Nishimura-0000.png" alt="Nishimura-0000" width="256" height="232" class="alignnone size-full wp-image-821" /><img src="http://blog.blockos.org/wp-content/uploads/2013/03/Nishimura-0013.png" alt="Nishimura-0013" width="256" height="232" class="alignnone size-full wp-image-838" /><br />
<img src="http://blog.blockos.org/wp-content/uploads/2013/03/Nishimura-0004.png" alt="Nishimura-0004" width="256" height="232" class="alignnone size-full wp-image-822" /><img src="http://blog.blockos.org/wp-content/uploads/2013/03/Nishimura-0005.png" alt="Nishimura-0005" width="256" height="232" class="alignnone size-full wp-image-823" /><br />
<img src="http://blog.blockos.org/wp-content/uploads/2013/03/Nishimura-0006.png" alt="Nishimura-0006" width="256" height="232" class="alignnone size-full wp-image-824" /><img src="http://blog.blockos.org/wp-content/uploads/2013/03/Nishimura-0007.png" alt="Nishimura-0007" width="256" height="232" class="alignnone size-full wp-image-825" /></p>
<p>As it&#8217;s a CDRom game, it must use the BIOS function for displaying text. Roger took his <a href="http://debuglife.free.fr/docs/Hu7CD_final.7z">old notes</a> and search for any text related routine. Here it is! <strong>ex_fnt</strong> located at <strong>$e060</strong>. He draw <a href="http://mednafen.sourceforge.net/">his favorite emulator</a> and set a breakpoint to it.<br />
<a href="http://blog.blockos.org/wp-content/uploads/2013/03/debugger00.png"><img src="http://blog.blockos.org/wp-content/uploads/2013/03/debugger00-300x241.png" alt="debugger00" width="300" height="241" class="aligncenter size-medium wp-image-845" /></a>It fires just after the introduction when what seems to be the savegame selection screen appears.<br />
<img src="http://blog.blockos.org/wp-content/uploads/2013/03/Nishimura-00081.png" alt="Nishimura-0008" width="256" height="232" class="alignnone size-full wp-image-850" /><a href="http://blog.blockos.org/wp-content/uploads/2013/03/debugger01.png"><img src="http://blog.blockos.org/wp-content/uploads/2013/03/debugger01-300x241.png" alt="debugger01" width="300" height="241" class="alignnone size-medium wp-image-846" /></a><br />
Roger is not really interested in the <strong>ex_fnt</strong> routine but more in the calling environment. So he sent breakpoints to the potential <strong>rts</strong>. A gentle pression to the <strong>R</strong> key sends him to <strong>$f1e2</strong>. Another push to the <strong>S</strong> key brings him the the caller.<a href="http://blog.blockos.org/wp-content/uploads/2013/03/debugger02.png"><img src="http://blog.blockos.org/wp-content/uploads/2013/03/debugger02-300x241.png" alt="debugger02" width="300" height="241" class="aligncenter size-medium wp-image-858" /></a> Here it is at <strong>$566b</strong>.<br />
<a href="http://blog.blockos.org/wp-content/uploads/2013/03/debugger03.png"><img src="http://blog.blockos.org/wp-content/uploads/2013/03/debugger03-300x241.png" alt="debugger03" width="300" height="241" class="aligncenter size-medium wp-image-859" /></a><br />
According to the notes, the shift-jis is loaded from <strong>$41</strong>, <strong>$42</strong> to <strong>$f8</strong> and <strong>$f9</strong>. The logical next step is to put a write breakpoint to <strong>$41</strong> and <strong>$42</strong>.<br />
<a href="http://blog.blockos.org/wp-content/uploads/2013/03/debugger04.png"><img src="http://blog.blockos.org/wp-content/uploads/2013/03/debugger04-300x241.png" alt="debugger04" width="300" height="241" class="aligncenter size-medium wp-image-869" /></a><br />
The write breakpoint is triggered at <strong>$5b20</strong>. The code is pretty simple.</p>
<pre class="brush: cpp; title: ; notranslate">5b1c: ldy #$00
      lda ($3c), Y
5b20: sta $41
      iny
      lda ($3c), Y
      iny
      sta $42</pre>
<p>The next step is to search where the <strong>$3c</strong> pointer. Once again Roger has to set a new write breakpoint at <strong>$3c</strong> and <strong>$3d</strong>.</p>
<pre class="brush: cpp; title: ; notranslate">5a18: lda #$90
      bra $5a22
      lda #$40
      bra $5a22
      lda #$80
5a22: sta $c0
5a24: sty $3d
      cpy #$00
      beq $5a2f
      stx $3c
      smb5 $c0
      rts</pre>
<p>Unfortunately the caller is not that obvious to discover. But the good news is that the text is not compressed. By keeping track of the values stored at <strong>$41</strong> and <strong>$42</strong>, Roger manages to extract the string
<pre class="brush: plain; title: ; notranslate">40 81 40 81 40 81 C7 82 CC 82 54 8B E4 88 59 8C 96 8E C5 82 6E 8E DF 82 DC 82 B7 82 A9 82 48 81 0D 00 FF 00</pre>
<p> The endiannes must be swapped. He hopefully has some handsome perl script at hand <a href="http://cires.colorado.edu/~braup/software/swap_endian">swap_endian.pl</a>. The last 4 characters looks like some control code. His long time experience enables him to deduce that <strong>00 0D</strong> is some kind of <strong>newline</strong> code and <strong>00 FF</strong> may be for <strong>end of text</strong>. Here&#8217;s the string.<br />
<center><code>　　　どの亀井刑事で始めますか？</code></center><br />
But this doesn&#8217;t tell Roger where the <strong>$3c</strong> pointer is set. Roger knows that on CDRom systems, the data is first transfered to RAM before being executed. This means that the code can be self-modifiable. Unluckily this is the case here. Roger has to set a breakpoint where the jump is done and run it until he finally reaches the pointer initialization code. Time passes and he ends up at <strong>$724d</strong>
<pre class="brush: cpp; title: ; notranslate">724d: ldx #$fc
      ldy #$74
      jmp $5a18</pre>
<p>He restarts the game with only the write breakpoint at <strong>$41</strong> and <strong>$42</strong>. As expected he ends up at the same code as before for the first sentence. The next run lands at a different location <strong>acb4</strong>.
<pre class="brush: cpp; title: ; notranslate">acae: lda $4f
      asl A
      tay
      lda ($50), Y
acb4: sta $41
      iny
      lda ($50), Y
      beq $acd8
      sta $42
      lda $2922
      sta $3f
      lda $2923
      sta $40
      lda #$01
      jsr $5655</pre>
<p> The pointer <strong>$50</strong> is initialized at <strong>ac92</strong>.
<pre class="brush: cpp; title: ; notranslate">ac8a: tay
      lda $312a, Y
      asl
ac8e: tay
ac90: lda ($9f), Y
      sta $50
      iny
      lda ($9f), Y
      sta $51</pre>
<p> So the pointer is set up from a table. He gets the values
<ul>
<li>b1b6</li>
<li>bdb6</li>
<li>cdb6</li>
<li>d9b6</li>
<li>e7b6</li>
</ul>
<p> Hopefully the indices for this pointers are 2,3,4,5,6. Roger searchs in the iso for <strong>b1 b6 bd b6 cb b6 d9 b6 e7 b6</strong>. He ends up at the offset <strong>$11f49</strong>. The place is filled with what looks like pointers. Some bytes after the string he recognises byte swapped shit-jis values. It starts at <strong>$11f53</strong>. So The pointer soup must contain some value equals to <strong>$53Xf</strong>. He scrolls up and finds <strong>$53af</strong> at <strong>$11d45</strong>. Tadam, he has his first table and string bloc. As all the pointers are in increasing order, Roger deduces that the option strings are stored from <strong>$11f53</strong> to <strong>$126f4</strong>. But just after this, he notices some other shift-jis symbols. It goes from <strong>$126f5</strong> to <strong>$132f5</strong>.<br />
Once the options are display, he jumps to another screen where some grumpy old cop is talking to you.<br />
<img src="http://blog.blockos.org/wp-content/uploads/2013/03/Nishimura-0009.png" alt="Nishimura-0009" width="256" height="232" class="aligncenter size-full wp-image-827" /><br />
Once again, he set his breakpoints to <strong>$41</strong> and <strong>$42</strong>. But then he remembers <strong>$5a18</strong>. It starts with
<pre class="brush: cpp; title: ; notranslate">5a18: lda #$90
      bra $5a22
5a1c: lda #$40
      bra $5a22
5a20: lda #$80
5a22: sta $c0</pre>
<p> So he can get here from <strong>$5a18</strong>, <strong>$5a1c</strong> or <strong>$5a20</strong>. This gives him 3 more breakpoints. <strong>$5a20</strong> is the one and as expected it comes from RAM initialized code (<strong>$59ab</strong>). He prepares for a painful ride. And painful it is. Nevertheless, he finds out that that <strong>$5a20</strong> is reached from <strong>$6c5e</strong>.
<pre class="brush: cpp; title: ; notranslate">6c5e: ldy $a5
      lda ($a8), Y
      sta $00
      iny
      lda ($a8), Y
      sta $01
      iny
      sty $a5
      and $00
      cmp #$ff
      beq $6c79
      ldx $00
      ldy $01
      jmp $5a20</pre>
<p> The first sentence of the grumpy cop comes from <strong>$89c9</strong> (iso offset <strong>$1339c9</strong>). This address comes from a table pointed by <strong>$a8</strong>. It&#8217;s setup at <strong>$707e</strong>.
<pre class="brush: cpp; title: ; notranslate">707e: lda #$00
      sta $00
      lda #$80
      sta $01
      lda ($00), Y
      sta $a8
      iny
      lda ($00), Y
      sta $a9
      stz $a5
      stz $a6
      lda #$03
      jmp $619c</pre>
<p> The pointer is store at <strong>$13308c</strong>. Roger is perplex. It&#8217;s not just a simple pointer table. There is some extra data. He needs to figure out how it works but he is tired and there&#8217;s <a href="http://www.rottentomatoes.com/m/night_of_the_creeps/">Night of the Creeps</a> on TV.<br />
He streches, closes the emulator and his laptop and prepares himself for 90 minutes of pure 80&#8242;s badassery.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.blockos.org/?feed=rss2&#038;p=811</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hole in the sky.</title>
		<link>http://blog.blockos.org/?p=455</link>
		<comments>http://blog.blockos.org/?p=455#comments</comments>
		<pubDate>Sat, 16 Jun 2012 20:58:33 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[openGL]]></category>

		<guid isPermaLink="false">http://blog.blockos.org/?p=455</guid>
		<description><![CDATA[I first came across the à trous algorithm when I was looking for a good edge avoiding filter for SSAO. Back then I was trying to code a demo. I had depth of field, some kind of hdr, spherical harmonics &#8230; <a href="http://blog.blockos.org/?p=455">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I first came across the à trous algorithm when I was looking for a good edge avoiding filter for <a href="http://en.wikipedia.org/wiki/Screen_Space_Ambient_Occlusion" target="_blank">SSAO</a>. Back then I was trying to code a demo. I had depth of field, some kind of hdr, spherical harmonics ambient lighting and <a href="http://sirkan.iit.bme.hu/~szirmay/ambientlight_link.htm" target="_blank">screen space ambient transfer</a>. I tried several techniques like the bilateral filter described in this <a href="http://www.ppsloan.org/publications/ProxyPG.pdf" target="_blank">paper</a> (4.2 Bilateral Upsampling). I don&#8217;t remember why but I have issues with this filter so I went on a quest for a better filter. Long story short, thanks to <a href="http://kesen.realtimerendering.com/" target="_blank">Ke-Sen Huang&#8217;s page</a> I read a paper called Edge-Avoiding A-Trous Wavelet Transform for fast Global Illumination Filtering (<a href="http://www.uni-ulm.de/fileadmin/website_uni_ulm/iui.inst.100/institut/Papers/atrousGIfilter.pdf" target="_blank">paper</a>, <a href="http://www.highperformancegraphics.org/previous/www_2010/media/RayTracing_I/HPG2010_RayTracing_I_Dammertz.pdf" target="_blank">slides</a>).<br />
I won&#8217;t make a lecture about wavelet transforms but this is how it roughly works.<br />
We start with the source image <strong>I</strong>. At each iteration <strong>i</strong>we will compute 2 images, \(d_i\) and \(c_i\). The first one will hold the filtered output and the second the details. This can be translated as:</p>
<ul>
<li>\(c_0 = I\)</li>
<li>\(c_{i+1}(p) = \sum_{k \in H} h_i(k) c_i(p+2^ik)\)</li>
<li>\(d_i = c_i &#8211; c_{i+1}\)</li>
</ul>
<p>With \(h_i\) being the filter. And \(H\) the size of our filter. When the desired iteration \(n\) is reached, the set of detail images and the last filtered image form our wavelet transform.</p>
<ul>
<li>\(w(I) = \{d_0, d1, \cdots, d_{n-1}, c_n\}\)</li>
</ul>
<p>As you can see, the space between each sample doubles at each iteration. Hence the name &#8220;à-trous&#8221; (with holes). Moreover the dimensions of the filtered images do not change. As opposed to Haar wavelet transform where \(c_{i+1}\) is half the size of \(c_i\).<br />
The next step is called the synthesis. We simply add the elements of the \(w(I)\) to produce the final image.</p>
<ul>
<li>\(I&#8217; = c_n + \sum_{0 \leq i &lt; n}d_i\)</li>
</ul>
<p>The wavelet filter can be seen as a pyramidal algorithm. The wavelet transform is the &#8220;pull&#8221; phase. And the synthesis the &#8220;push&#8221; phase (see <a href="http://wwwcg.in.tum.de/fileadmin/user_upload/Lehrstuehle/Lehrstuhl_XV/Research/Publications/2009/grapp09.pdf">this paper</a> for an overview of &#8220;push pull&#8221; algorithm). As the scaling function is a \(B_3\) spline, the filter \(h\) is :</p>
<ul>
<li>\(\left(\frac{1}{16},\frac{1}{4},\frac{3}{8},\frac{1}{4},\frac{1}{16}\right)\) in \(\mathbb{R}\)</li>
<li>\(<br />
\begin{pmatrix}<br />
\frac{1}{256} &amp; \frac{1}{64} &amp; \frac{3}{128} &amp; \frac{1}{64} &amp; \frac{1}{256} \\<br />
\frac{1}{64} &amp; \frac{1}{16} &amp; \frac{3}{32} &amp; \frac{1}{16} &amp; \frac{1}{64} \\<br />
\frac{3}{128} &amp; \frac{3}{32} &amp; \frac{9}{64} &amp; \frac{3}{32} &amp; \frac{3}{128} \\<br />
\frac{1}{64} &amp; \frac{1}{16} &amp; \frac{3}{32} &amp; \frac{1}{16} &amp; \frac{1}{64} \\<br />
\frac{1}{256} &amp; \frac{1}{64} &amp; \frac{3}{128} &amp; \frac{1}{64} &amp; \frac{1}{256}<br />
\end{pmatrix}<br />
\) in \(\mathbb{R}^2\)</li>
</ul>
<p>If we apply this to image filtering, we will have:</p>
<ol>
<li>\(c_0 = I\)</li>
<li>\(\forall i \in [0,n[\) and \(\forall p \in [0,S_x] \times [0,S_y[\)
<ul>
<li>\(c_{i+1}(p) = \sum_{0 \leq y &lt; 5} \sum_{0 \leq x &lt; 5} h_i(x,y) c_i\left(p+ 2^i(x,y)\right)\)</li>
<li>\(d_i(p) = c_i &#8211; c_{i+1}(p)\)</li>
</ul>
</li>
<li>\(I&#8217;=c_n + \sum_{0 \leq i &lt; n}d_i\)</li>
</ol>
<p>Edge awareness is acheived by adding a Gaussian distribution based weighing function of the colorimetric difference between the sample and source pixel (just like any standard bilateral filter).</p>
<ul>
<li>\(\omega_{\sigma}(u,v) = e^{\frac{\left\|c_i(u) &#8211; c_i(v)\right\|^2}{\sigma}}\)</li>
</ul>
<p><strong>2</strong>will be:</p>
<ul>
<li>\(c_{i+1}(p) = \frac{1}{W} \sum \sum \omega_{\sigma}\left(c_i(p),c_i\left(p+2^i(x,y)\right)\right)h_i(x,y) c_i(p+2^i(x,y))\)</li>
<li>with \(W = \sum\sum \omega_{\sigma}\left(c_i(p),c_i\left(p+2^i(x,y)\right)\right)h_i(x,y)\)</li>
</ul>
<p>Denoising can be acheived by thresholding the detail images.</p>
<ul>
<li>\(d&#8217;_i = max\left(0, |d_i|-\tau\right) \cdot sign(d_i)\)</li>
</ul>
<p>More details can be found in &#8220;Edge-Optimized À-TrousWavelets for Local Contrast<br />
Enhancement with Robust Denoising&#8221; by Johannes Hanika, Holger Dammertz and Hendrik Lensch (<a href="http://www.darktable.org/wp-content/uploads/2011/11/hdl11_paper.pdf">paper</a>, <a href="http://www.darktable.org/wp-content/uploads/2011/11/hdl11_talk.pdf">slides</a>).<br />
Implementing it in OpenGL/glsl is pretty straightforward. The detail textures will be stored in a texture array. And as we only need the last filtered image for the synthesis, we will ping-pong between 2 textures.<br />
Here is how the texture array is created:</p>
<pre class="brush: cpp; title: ; notranslate">
glBindTexture(GL_TEXTURE_2D_ARRAY, texId);
	glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB32F, imageWidth, imageHeight, LEVEL_MAX, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
	for(i=0; i&lt;LEVEL_MAX; i++)
        {
		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, imageWidth, imageHeight, 1, GL_RGB, GL_UNSIGNED_BYTE, imageData);
	}
	// Set texture wrap and filtering here.
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);</pre>
<p>You attach a layer just like a standard 3D texture.</p>
<pre class="brush: cpp; title: ; notranslate">glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texId, 0, layerIndex);</pre>
<p>You access it in a shader using a <em>sampler2DArray</em>. Here is an example based on the synthesis shader:</p>
<pre class="brush: cpp; title: ; notranslate">#extension GL_EXT_texture_array : enable
uniform sampler2D filtered;
uniform sampler2DArray details;

out vec4 outData;

void main()
{
    int levelMax = int(textureSize(uDetails, 0).z);
    vec4 data = texelFetch(filtered, ivec2(gl_FragCoord.xy), 0);;

    for(int i=0; i&lt;levelMax; i++)
    {
		data += texelFetch(details, ivec3(gl_FragCoord.xy, i), 0);
    }

    outData = data;
}
</pre>
<p>I uploaded the source code of a little demo <a href="http://blockos.org/releases/wavelets/atrous.zip" target="_blank">here</a>. It will filter the infamous mandrill image using a edge preserving à-trous wavelet transform. I intentionally used &#8220;extreme&#8221; parameters to show the effects of the edge avoiding filter. It comes with a Microsoft Visual Studion 2010 project. Note that you will need <a href="http://www.glfw.org/" target="_blank">GLFW</a> and <a href="http://glew.sourceforge.net/" target="_blank">GLEW</a>. You will also have to edit the <strong>ContribDir</strong> item in <strong>platform\windows\wavelet.vcxproj.props</strong>.<br />
On the left you have the original image. And on the right the filtered image with \(\sigma=1.125\) and \(\tau=0.05125\).<br />
<img alt="" src="http://blockos.org/releases/wavelets/mandrill.jpg" title="Original mandrill" class="alignnone" width="250" height="240" /> <img alt="" src="http://blockos.org/releases/wavelets/mandrill_filtered.jpg" title="Filtered mandrill" class="alignnone" width="250" height="240" /></p>
<h2>Stuffs</h2>
<ul>
<li><a href="http://blockos.org/releases/wavelets/atrous.zip" target="_blank">source code</a></li>
</ul>
<h2>References</h2>
<ul>
<li>Gilbert Strang, <a href="http://videolectures.net/mit18085f07_strang_lec27/" target="_blank">Lecture 27: Multiresolution, wavelet transform and scaling function</a></li>
<li>Albert Bijaoui, Jean-Luc Starck, Fionn Murtagh, <a href="http://documents.irevues.inist.fr/handle/2042/1863" target="_blank">Restauration des images multi-échelles par l&#8217;algorithme à trous</a> (french)</li>
<li>Holger Dammertz, Daniel Sewtz, Johannes Hanika, Hendrik P.A. Lensch, <a href="http://www.uni-ulm.de/fileadmin/website_uni_ulm/iui.inst.100/institut/Papers/atrousGIfilter.pdf" target="_blank">Edge-Avoiding À-Trous Wavelet Transform for fast Global<br />
Illumination Filtering</a>, <a href="http://www.highperformancegraphics.org/previous/www_2010/media/RayTracing_I/HPG2010_RayTracing_I_Dammertz.pdf" target="_blank">(slides)</a></li>
<li>Johannes Hanika, Holger Dammertz, Hendrik Lensch, <a href="http://www.darktable.org/wp-content/uploads/2011/11/hdl11_paper.pdf" target="_blank">Edge-Optimized À-Trous Wavelets for Local Contrast Enhancement with Robust Denoising</a>, <a href="http://www.darktable.org/wp-content/uploads/2011/11/hdl11_talk.pdf" target="_blank">(slides)</a>
<li>Peter-Pike Sloan, Naga K. Govindaraju, Derek Nowrouzezahrai, John Snyder,  <a href="http://www.ppsloan.org/publications/ProxyPG.pdf" target="_blank">Image-Based Proxy Accumulation for Real-Time Soft Global Illumination</a></li>
<li>Martin Kraus, <a href="http://wwwcg.in.tum.de/fileadmin/user_upload/Lehrstuehle/Lehrstuhl_XV/Research/Publications/2009/grapp09.pdf" target="_blank">The Pull-Push Algorithm Revisited</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.blockos.org/?feed=rss2&#038;p=455</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>You see this? This&#8230; is my boomstick!</title>
		<link>http://blog.blockos.org/?p=446</link>
		<comments>http://blog.blockos.org/?p=446#comments</comments>
		<pubDate>Fri, 01 Jun 2012 19:51:20 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[pc engine]]></category>

		<guid isPermaLink="false">http://blog.blockos.org/?p=446</guid>
		<description><![CDATA[(10/23/2012) WARNING! As Tomaitheous pointed out, there&#8217;s a problem with this board! Please refer to comments for more informations. Yeah a new post! Some years ago (more like a decade than a year), I bought a Turbo Stick. It&#8217;s the &#8230; <a href="http://blog.blockos.org/?p=446">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><strong>(10/23/2012) WARNING! As Tomaitheous pointed out, there&#8217;s a problem with this board! Please refer to comments for more informations.</strong></p>
<p>Yeah a new post!</p>
<p>Some years ago (more like a decade than a year), I bought a Turbo Stick. It&#8217;s the standard 2 buttons stick for NEC PC Engine console. Unfortunately the stick makes an awfull squealing nose. Forget 1 life run with this plastic beast. After 5 minutes all I wanted to do was to use it as a soccer ball. According to <a title="PC Engine hardware list : Pad/Stick/Mouse" href="http://www6.airnet.ne.jp/wataru/pce/pce_pad.htm" target="_blank">the Wataru&#8217;s PC Engine hardware list</a>, 4 six buttons sticks were released. They are not small and given shipping costs I decided to build one. So I bought a stick and some buttons from <a title="Sparkfun" href="https://www.sparkfun.com/">Sparkfun</a>. Later a friend gave me a <a title="Sanwa" href="http://www.sanwa-d.co.jp/">Sanwa</a> stick and buttons.</p>
<p>There are several places on the internet where to find PC Engine pad schematics. The main source are <a title="Emanuele Bettidi's page" href="http://www.webalice.it/cicciopetito/" target="_blank">Emanuele Bettidi</a>&#8216;s pad schematics, <a title="PCE Wiki" href="http://wiki.pcengine.info/" target="_blank">PCE Wiki</a>, <a title="NFG world" href="http://nfgworld.com/mb/thread/460-PC-Engine-TurboGrafx-16-Pad" target="_blank">NFG PC engine/TG 16 article</a>. I first built a 2 buttons circuit with no auto fire. But there are a few games that requires a 6 buttons stick (Street Fighter 2 for example). The Avnue Pad 6 comes with auto fire and slow mode. The later is a particular ugly hack. The slow mode is acheived by toggling the pause rapidly. It&#8217;s as if you drank too much coffee and go berserk on the RUN button. Here are the <a title="Avenue Pad 6" href="http://wiki.pcengine.info/pmwiki.php?n=Hardware.AvenuePad6" target="_blank">guts shots</a> and <a title="Avenue Pad 6 schematic" href="http://www.webalice.it/cicciopetito/archivio/Avenue_Pad_6_Schematic.png" target="_blank">schematic</a> of an Avenue Pad 6. I spent hours trying to make PCB board in Eagle for the &#8220;complete&#8221; version (with auto fire and slow mode). I didn&#8217;t find a local source for the DTC114Y. A replacement was found on the interweb. It was told that this component can be replaced by a 2N3904 and 2 resistors. This is rather straightforward if you look at the DTC114Y datasheet. Anyway, in the end I didn&#8217;t liked the way the board looked. The most logical step was to remove the rapid fire and slow mode (<a title="Avenue Pad 6 without rapid fire schematic" href="http://img121.imageshack.us/img121/3420/avenuepad6schematicnora.png" target="_blank">schematic</a>). And by the way, I think I&#8217;ll never use slow mode and barely ever used auto-fire.</p>
<p>Here are the current version of the schematic and pcb board:</p>
<ul>
<li><a title="PC Engine 6 buttons arcade stick schematic (eagle file)" href="http://blockos.org/releases/pcengine/hardware/stick6buttons.sch" target="_blank">schematic</a></li>
<li><a title="PC Engine 6 buttons arcade stick board (eagle file)" href="http://blockos.org/releases/pcengine/hardware/stick6buttons.brd" target="_blank">board</a> (<a title="PC Engine 6 buttons arcade stick board (image)" href="http://blockos.org/releases/pcengine/hardware/stick6buttons_board2.png">image</a>)</li>
</ul>
<p style="text-align: center;"><a href="http://blockos.org/releases/pcengine/hardware/stick6buttons.png"><img class="aligncenter" title="PC Engine 6 buttons arcade stick schematic." src="http://blockos.org/releases/pcengine/hardware/stick6buttons.png" alt="" width="410" height="348" /></a></p>
<p>Here&#8217;s a 3d view of the nearly version of the board (made with <a href="http://mayhewlabs.com/webGerber/">WebGerber</a>)</p>
<p style="text-align: center;"><a href="http://blockos.org/releases/pcengine/hardware/top3dview.png"><img class=" aligncenter" title="PC Engine 6 buttons arcade stick pcb top view (3D)" src="http://blockos.org/releases/pcengine/hardware/stick6buttons3dTop.png" alt="" width="275" height="214" /></a><br />
<a href="http://blockos.org/releases/pcengine/hardware/bottom3dview.png"><img class=" aligncenter" title="PC Engine 6 buttons arcade stick pcb bottom view (3D)" src="http://blockos.org/releases/pcengine/hardware/stick6buttons3dBottom.png" alt="" width="275" height="230" /></a></p>
<p style="text-align: left;">I need to add mounting holes in the board. Make some board. And last but not least, build the enclosure!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.blockos.org/?feed=rss2&#038;p=446</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Alice’s bubbles (Part 3)</title>
		<link>http://blog.blockos.org/?p=367</link>
		<comments>http://blog.blockos.org/?p=367#comments</comments>
		<pubDate>Mon, 27 Feb 2012 11:29:56 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[pc engine]]></category>

		<guid isPermaLink="false">http://blog.blockos.org/?p=367</guid>
		<description><![CDATA[Here comes level names. This was the most painful part of the whole translation hacking. First, they are made of sprites. Second, there is a limited number of them. And last but not least, the table that tells which sprites &#8230; <a href="http://blog.blockos.org/?p=367">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Here comes level names. This was the most painful part of the whole translation hacking. First, they are made of sprites. Second, there is a limited number of them. And last but not least, the table that tells which sprites to use for a given level name can&#8217;t be expanded.<br />
The LSB of the pattern indices for the first level are stored at $5196 (file offset) and $519C for the second. After putting a read breakpoint on $*4f96 (remember that there&#8217;s usually a 512 bytes header to PC Engine roms) and $*4f9C, I ended up at $8E3F. A quick look at the code show me there is a address table stored at $8F81 where each address starts 1 byte before the LSB pattern index list. The first byte indicates the number of sprites. Here&#8217;s the complete index list:</p>
<p><code>    8F95 : 05 00 02 04 06 08<br />
    8F9B : 05 0E 02 12 06 08<br />
    8FA1 : 05 18 0A 16 06 08<br />
    8FA7 : 05 14 00 16 06 08<br />
    8FAD : 05 1C 02 20 06 08<br />
    8FB3 : 04 18 1A 06 08<br />
    8FB8 : 04 22 24 06 08<br />
    8FBD : 05 02 10 18 06 08<br />
    8FC3 : 04 26 28 06 08</code></p>
<p>At this point, I managed to avoid using compressed data. Unfortunatelly the whole sprites were compressed. In fact, there are 4 &#8220;decompression&#8221; schemes. The first one is a direct transfer to VRAM using the <em>tia</em> instruction. The second is using a simple <a href="http://en.wikipedia.org/wiki/Run-length_encoding">RLE</a>. The third one and the most tricky mixes <a href="http://en.wikipedia.org/wiki/Run-length_encoding">RLE</a> and some XOR. The last one simply copies the data to VRAM using a handcrafted loop.</p>
<pre class="brush: cpp; title: ; notranslate">f796:   LDA &lt;$7d
        ORA &lt;$7e
        BEQ f7e1
        JSR f888
        CMP #$00
        BNE f7ac
                ; #1 Transfer to VRAM using tia
                TIA $3700, $0002, $0020
                BRA f7d2
f7ac:   CMP #$02
        BNE f7bc
                ; #2 RLE
                JSR f817
                TIA $3700, $0002, $0020
                BRA f7d2
f7bc:   CMP #$03
        BNE f7cf
                ; #3 RLE + XOR
                JSR f817
                JSR f857
                TIA $3700, $0002, $0020
                BRA f7d2
f7cf: ; #4 Loop transfer
        JSR f803

f7d2:   LDA &lt;$7d
        SBC #$01
        STA &lt;$7d
        LDA &lt;$7e
        SBC #$00
        STA &lt;$7e
        BRA f796

f7e1:</pre>
<p>The <a href="http://en.wikipedia.org/wiki/Run-length_encoding">RLE</a> routine:</p>
<pre class="brush: cpp; title: ; notranslate">f817:   LDA [$78]
        STA &lt;$83
        LDY #$04
        LDA #$09
        STA &lt;$81
        STZ &lt;$80
        CLX
        LDA #$20
        STA &lt;$82
       
f828:   DEC &lt;$81
        BNE f83a
        PHY
        LDA #$08
        STA &lt;$81
        INC &lt;$80
        LDY &lt;$80
        LDA [$78], Y
        STA &lt;$83
        PLY

f83a:   ROR &lt;$83 ; the rle counter
        BCS f849
        STZ $3740, X
        INX
        DEC &lt;$82
        BNE f828
        JMP f7f6

f849:   LDA [$78], Y
        STA $3740, X
        INY
        INX
        DEC &lt;$82
        BNE f828
        JMP f7f6</pre>
<p>The &#8220;XOR&#8221; routine:</p>
<pre class="brush: cpp; title: ; notranslate">f857:   PHX
        PHY
        LDY #$07
        CLX
       
f85c:   LDA $3740, X
        EOR $3742, X
        STA $3742, X
        LDA $3741, X
        EOR $3743, X
        STA $3743, X
        LDA $3750, X
        EOR $3752, X
        STA $3752, X
        LDA $3751, X
        EOR $3753, X
        STA $3753, X
       
        INX
        INX
       
        DEY
        BNE f85c
       
        PLY
        PLX
        RTS</pre>
<p>The XOR is used here to maximize the number of repetitions in order to make the <a href="http://en.wikipedia.org/wiki/Run-length_encoding">RLE</a> more efficient. Well, that&#8217;s how I understood it. I didn&#8217;t make any benchmark to verify if it was really the case. The encoder was written pretty quickly. I reworked the font so that it more or less matches the ASCII set. This simplified the script encoder and the display routine.<br />
<img src="http://pcedev.blockos.org/download/file.php?id=34"/></p>
<p>Back to level names! I got help from a bunch of people to translate them. The last character of each level can be translated to <em>country</em>. Unfortunately that was far too big so I switched to <em>&#8220;land&#8221;</em>.</p>
<ul>
<li><img src="http://pcedev.blockos.org/download/file.php?id=24"/> Candy Land</li>
<li><img src="http://pcedev.blockos.org/download/file.php?id=25"/> Toy Land</li>
<li><img src="http://pcedev.blockos.org/download/file.php?id=26"/> Greenery Land</li>
<li><img src="http://pcedev.blockos.org/download/file.php?id=27"/> Ice Land</li>
<li><img src="http://pcedev.blockos.org/download/file.php?id=28"/> Time Land</li>
<li><img src="http://pcedev.blockos.org/download/file.php?id=29"/> Water Land</li>
<li><img src="http://pcedev.blockos.org/download/file.php?id=30"/> Sky Land</li>
<li><img src="http://pcedev.blockos.org/download/file.php?id=31"/> Mirror Land</li>
<li><img src="http://pcedev.blockos.org/download/file.php?id=32"/> Queen Land</li>
</ul>
<p>Here&#8217;s the actual &#8220;font&#8221; made of 16&#215;16 sprites.<br />
The zigzag lines on the last 16&#215;16 sprite are there to make the compressed data fits into 504 bytes. I must also keep an empty sprite for spacing.<br />
<img src="http://pcedev.blockos.org/download/file.php?id=61"/><br />
I had the sprite index list done pretty quickly. But when I started working on the index pointer table, I realized that there were 9 entries. 9? Did I forgot one?<br />
Yes, I forgot one. The water land&#8230; And I didn&#8217;t have enough room to put the missing letters (bloody size limit). </p>
<p>After a cautious review, it was decided to rename <em>&#8220;Greenery land&#8221;</em> into <em>&#8220;Green land&#8221;</em>. As There were already a <em>&#8220;Queen land&#8221;</em>, there&#8217;s now enough room for the missing <em>&#8220;Water&#8221;</em>.<br />
<img src="http://pcedev.blockos.org/download/file.php?id=62"/><br />
The only issue remaining was that the sprite index list is 42 bytes long, and mine was 43. As each level name ends with the same sequence I can use the last index as the beginning of the next one (each sequence starts with the length of the index list). So I swapped the sprite for <em>&#8220;nd&#8221;</em> with the beginning of the one whose index was equal to a sequence length, namely <em>&#8220;To&#8221;</em> which was at index 6. Why 6? First because it&#8217;s the length of the longest index list and also because sprite indexes are always even.</p>
<p>Here&#8217;s the original index list (the fist 2 hexadecimal values are the values of the pointer table):<br />
<code>    8F95 : 05 00 02 04 06 08<br />
    8F9B : 05 0E 02 12 06 08<br />
    8FA1 : 05 18 0A 16 06 08<br />
    8FA7 : 05 14 00 16 06 08<br />
    8FAD : 05 1C 02 20 06 08<br />
    8FB3 : 04 18 1A 06 08<br />
    8FB8 : 04 22 24 06 08<br />
    8FBD : 05 02 10 18 06 08<br />
    8FC3 : 04 26 28 06 08</code></p>
<p>The new one:<br />
<code>    8F95 : 05 00 06 04 24 06<br />
    8F9B : 04 02 04 24 06<br />
    8FA0 : 05 08 0A 0C 24 06<br />
    8FA6 : 04 0E 10 24 06<br />
    8FAB : 05 12 14 28 24 06<br />
    8FB1 : 05 20 22 26 24 06<br />
    8FB7 : 04 16 04 24 06<br />
    8FBB : <u><b>06</b></u> 18 1A 1C 28 24 06<br />
    8FC2 : 05 1E 0A 0C 24 06</code></p>
<p>Shortly after beating the evil level names I received the first version of the translated script. Unfortunately the first tests revealed that the current text layout was unreadeable. There were only 2 or 3 words per line. So I had to crawl brack into the rom and change the text box position and size. I was only some couples of values to change.</p>
<p>So the 24th of July 2011, the english patch was released. Nearly 2 years after I started working on it&#8230; Anyway, some days after the release a couple of angry frenchmen complained that we didn&#8217;t release a french patch. In order to silence those annoying creeters I had to modify the font and the script encoder in order to add accents. That was not a big deal. But I let the french translators handle the level names (with some kind of sadistic grin). After some weeks of hard work, they decided to give up and use the english names. The french translation was released in December 2011.</p>
<ul>
<li>English translation
<ul>
<li><a href="http://www.romhacking.net/translations/1637/">patch</a></li>
<li><a href="http://www.blockos.org/releases/pcengine/translation/Marchen%20Maze%20%5bfinal%5d.zip">source code</a></li>
</ul>
</li>
<li>French translation
<ul>
<li><a href="http://www.romhacking.net/translations/1703/">patch</a></li>
<li><a href="http://www.blockos.org/releases/pcengine/translation/Marchen%20Maze/fr/Marchen%20Maze%20%5bfr%5d%5bfinal%5d.zip">source code</a></li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.blockos.org/?feed=rss2&#038;p=367</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Alice’s bubbles (Part 2)</title>
		<link>http://blog.blockos.org/?p=304</link>
		<comments>http://blog.blockos.org/?p=304#comments</comments>
		<pubDate>Sun, 03 Jul 2011 13:21:48 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[pc engine]]></category>

		<guid isPermaLink="false">http://blog.blockos.org/?p=304</guid>
		<description><![CDATA[Oh hy! I didn&#8217;t notice you were here. Please take a seat. So I were talking about the font. As shown in the following image, the original font already contained uppercase letters. As I wanted to add lowercases and some &#8230; <a href="http://blog.blockos.org/?p=304">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Oh hy! I didn&#8217;t notice you were here. Please take a seat.<br />
So I were talking about the font. As shown in the following image, the original font already contained uppercase letters.<br />
<a href="http://blog.blockos.org/wp-content/uploads/2011/06/MarchenMazeFontOrig.png"><img src="http://blog.blockos.org/wp-content/uploads/2011/06/MarchenMazeFontOrig-300x217.png" alt="Marchen Maze original font" title="MarchenMazeFontOrig" width="300" height="217" class="aligncenter size-medium wp-image-309" /></a><br />
As I wanted to add lowercases and some punctuations, I had to find where and how the font was stored in ROM. The visual editor told me that the font was stored from <strong>$7300</strong> to <strong>$7a10</strong> in VRAM. So under the code debugger I set an aux write breakpoint (ctrl+w) to these addresses. The breakpoint was triggered at <strong>$f7c6</strong> on :
<pre class="brush: cpp; title: ; notranslate">TIA $3740, $0002, $0020</pre>
<p>If you look closely at the following image, you&#8217;ll notice that there are 2 similar preceding occurrences. This is it! You are looking at the piece of code in charge of decompressing the tile data into VRAM. <a href="http://blog.blockos.org/wp-content/uploads/2011/06/MarchenMazeCode0.png"><img src="http://blog.blockos.org/wp-content/uploads/2011/06/MarchenMazeCode0-300x217.png" alt="Mednafen debugger view" title="Marchen Maze debugger " width="300" height="217" class="aligncenter size-medium wp-image-321" /></a><br />
This code supports 4 kind of compression:
<ul>
<li>The tile is filled with 0.</li>
<li>Uncompressed. The data is directly transfered to VRAM.</li>
<li>Simple RLE encoding.</li>
<li>Simple RLE encoding with some kind of postprocessing involving XORing consecutive lines.</li>
</ul>
<p>Laziness told me to avoid writing a little tool to compress the font. So I checked how many uncompresserd char were used and if it was enough to store lowercases. Hopefully there was enough room for all of them. <a href="http://blog.blockos.org/wp-content/uploads/2011/07/MarchenMazeFontMod0.png"><img src="http://blog.blockos.org/wp-content/uploads/2011/07/MarchenMazeFontMod0-300x217.png" alt="Marchen maze brutal lowercases insertion" title="MarchenMazeFontMod0" width="300" height="217" class="aligncenter size-medium wp-image-336" /></a></p>
<p>At this point I had nearly everything I wanted. There were no need to modify the string display routine. Most of the work done would have been done by the script encoder as the lowercases characters where not contigous. It was not a big deal. Nevertheless I wanted to check if there will be enough room for the translated texts and how much characters could be displayed per screen. Basically you had 16 characters per line and 7 or 11 line depending on the screen. This gave me an idea of the maximal script size. Unfortunately it was too big. So I looked for a fast/small/simple text compression/decompression for 6502 based cpu. I had a quick look at the <a href="http://www.romhacking.net">romhacking.net</a> forum. And it seems that one of the most used technique is DTE (Dual Tile Encoding). It&#8217;s a pretty simple approach. A text does not use all the ascii values. Basically you only use upper and lowercases (52 chars), numbers (10) and a dozen punctuation marks. This leaves you with 182 unused values. You can use them to store couples of characters. Bytes with values between 0 and 74 represent a single character and all the others represent a tuple. For example 182 represents &#8216;ab&#8217;, 183 &#8216;en&#8217; and so on. Here is quick example: Let&#8217;s compress the string <strong>&#8220;abcacbabcabcabba&#8221;</strong>. First we extract all the characters couples and count them:
<ul>
<li><strong>ab</strong> : 4</li>
<li><strong>bc</strong> : 3</li>
<li><strong>ca</strong> : 3</li>
<li><strong>ac</strong> : 1</li>
<li><strong>cb</strong> : 1</li>
<li><strong>ba</strong> : 2 </li>
<li><strong>bb</strong> : 1 </li>
</ul>
<p><strong>&#8220;ab&#8221;</strong> is the tuple with the highest occurence. We insert it in the symbol table: <strong>a</strong>,<strong>b</strong>,<strong>c</strong>,<strong>d=&#8217;ab&#8217;</strong>. And let&#8217;s replace it in the original string:<strong>&#8220;dcacbdcdcdba&#8221;</strong>. DTE only works on the original symbols. So in the second  pass we must avoid the newly inserted symbols. The remaining tuples are :
<ul>
<li><strong>ca</strong> : 1</li>
<li><strong>ac</strong> : 1</li>
<li><strong>cb</strong> : 1</li>
<li><strong>ba</strong> : 1 </li>
</ul>
<p> The new symbol table is : <strong>a</strong>,<strong>b</strong>,<strong>c</strong>,<strong>d=&#8217;ab&#8217;</strong>,<strong>e=&#8217;ca&#8217;</strong>,<strong>f=&#8217;cb&#8217;</strong>,<strong>g=&#8217;ba&#8217;</strong>. In the end <strong>&#8220;abcacbabcabcabba&#8221;</strong> becomes <strong>&#8220;defdcdcdg&#8221;</strong>. The tricky part is to choose the right substitution sequence that will lead to the smallest possible string. It&#8217;s a whole new game and you can stick with choosing the tuple with the highest occurence.<br />
Let&#8217;s get back to Alice. I grabbed the infamous <a href="http://www.lipsum.com/">lorem ipsum</a> and made a script out of it. I compressed it with DTE. And I still had a lot of unused values. Remember the second pass of our example when I excluded the newly inserted symbol for the occurence counting. If I included it, DTE would in fact have been what is called BPE (Binary Pair Encoding). Here&#8217;s the mandatory academical reference : <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.46.4046">Byte Pair Encoding: A Text Compression Scheme That Accelerates Pattern Matching (1999)</a>. Using BPE we would have had for <strong>&#8220;dcacbdcdcdba&#8221;</strong>.
<ul>
<li><strong>dc</strong> : 3</li>
<li><strong>ca</strong> : 1</li>
<li><strong>ca</strong> : 1</li>
<li><strong>ac</strong> : 1</li>
<li><strong>cb</strong> : 1</li>
<li><strong>bd</strong> : 1</li>
<li><strong>cd</strong> : 2</li>
<li><strong>db</strong> : 1</li>
<li><strong>ba</strong> : 1</li>
</ul>
<p> Let&#8217;s add <strong>&#8220;dc&#8221;</strong> in the symbol table  <strong>a</strong>,<strong>b</strong>,<strong>c</strong>,<strong>d=&#8217;ab&#8217;</strong>,<strong>e=&#8217;dc&#8217;</strong>. We now have <strong>&#8220;eacbeedba&#8221;</strong>. BPE is basically a recursive algorithm. So when we are decoding a string, we must check if it&#8217;s part of the tuple symbols (let&#8217;s call them &#8220;special&#8221; symbols). If that&#8217;s the case we will have to loop until the decoded symbol does not contain any special symbol. If speed is a concern we may limit the depth of recursion. This means that when we must take the depth of each symbol into consideration. For example imagine we have 2 tuples <strong>&#8220;dc&#8221;</strong> and <strong>&#8220;ca&#8221;</strong>. Both have the same number of occurence in the string. We may choose <strong>&#8220;ca&#8221;</strong> instead of <strong>&#8220;dc&#8221;</strong> because it only contains &#8220;base&#8221; symbols.<br />
Using BPE the &#8220;maximal&#8221; script was small enough to fit. I made a silly test using some part of Hamlet (here&#8217;s the <a href="http://pcedev.blockos.org/download/file.php?id=21">script</a>). You can find the BPE compression/decompression as long as code for generating IPS files in this <a href="http://pcedev.blockos.org/download/file.php?id=22">[archive]</a>.</p>
<p>Next : Levels names. Shitty part : they are sprites. Describe pointer tables and all.<br />
All compressed. So I can&#8217;t avoid it anymore. Describe the compression scheme.<br />
Got help for level name translation. (show the level names and their translation).<br />
As I have a compressor, reworked the font so that it more or less match ascii. Had to spot where the font was rendered to vram. (link to final font). Simplify script encoder and display routine.</p>
<p><strong>Coming next</strong>: Level names. A world of pain and horror!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.blockos.org/?feed=rss2&#038;p=304</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Alice&#8217;s bubbles (Part 1)</title>
		<link>http://blog.blockos.org/?p=164</link>
		<comments>http://blog.blockos.org/?p=164#comments</comments>
		<pubDate>Sun, 17 Apr 2011 17:03:14 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[pc engine]]></category>

		<guid isPermaLink="false">http://blog.blockos.org/?p=164</guid>
		<description><![CDATA[Or more humbly, the awesome Märchen Maze translation postmortem. It&#8217;s more or less a compilation/addendum for this pcedev forum [post]. Märchen Maze is a PCEngine HuCard game released by Namco the 11th of December 1990. It&#8217;s a conversion of the &#8230; <a href="http://blog.blockos.org/?p=164">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><img class="aligncenter" src="http://pcedev.blockos.org/download/file.php?id=5" alt="Marchen Maze title screen" /><br />
Or more humbly, the awesome Märchen Maze translation postmortem. It&#8217;s more or less a compilation/addendum for this pcedev forum <a href="http://pcedev.blockos.org/viewtopic.php?f=5&amp;t=52">[post]</a>.</p>
<p>Märchen Maze is a PCEngine HuCard game released by Namco the 11th of December 1990. It&#8217;s a conversion of the 1988 arcade game. It was also ported to the almighty Sharp X68000. As you may have guessed the X68000 version is a near perfect conversion of the original arcade game. It features some jolly 3D isometric view and colourfull introduction. Well, things are not that fancy on the PCEngine version. The 3D isometric view was changed to a top view (à la Mercs or Commando). And the intro is now in sepia tones. What about the story and gameplay? Check the Video Game Den review <a href="http://www.videogameden.com/hucard.htm?mma">[here]</a>.</p>
<p>Ok! Back to business.<br />
The PCEngine has some neat RPGs. Unfortunately only a few of them were translated into the idiom of the perfidious Albion (English). This was a perfect excuse for trying out that black art called romhacking. <a href="http://www.videogameden.com/cdrom.htm?mom">Monster Maker</a> was my first choice. I must admin that cdrom games are not a really good choice for your first romhacking experience. A HuCard game is far more simpler to hack. So I went for <a href="http://www.videogameden.com/hucard.htm?mok">Momotarō Katsugeki</a>. It&#8217;s a cool platform game with tons of text. Unfortunately the text is displayed top to bottom and from left to right in bubbles. It was clearly out of my league. So I asked some people if they knew some easily translatable games. I can&#8217;t remember who suggested it. But Märchen Maze was designated as it doesn&#8217;t have too much text and no apparent string compression.</p>
<p>The first thing I had to do was to find where the text was stored in the ROM. After hours of pain, <a href="http://pages.interlog.com/~daves/">David Shadoff</a> took pity. And like a mighty wizard, he managed to extract the whole script in no time. So I had the rom location of the strings. All I had to do was to put read breakpoint in <a href="http://mednafen.sourceforge.net">Mednafen</a>. I was able to locate the text output routine (<strong>$87D6</strong>). The string &#8220;parsing&#8221; was spotted from <strong>$89E5</strong> to $<strong>8CD8 </strong>using step-by-step debugging starting from the the output routine. It made me realized that <strong>$5C</strong>,<strong>$5D</strong> held the pointer to the string to be displayed. The parsing routine was called from <strong>$E377</strong> using <strong>jmp ($202C)</strong> instead of <strong>jsr</strong>. The return address was pushed by hand onto the stack. Here&#8217;s an snippet of the parsing routine. <strong>$ff</strong> is a special value. More on this later.</p>
<pre class="brush: cpp; title: ; notranslate">l_89e2: LDY     $271b
        LDA     [$5c], Y
        CMP     #$ff
        BNE     l_89ee</pre>
<p>The most important information was that I now knew the zero page location holding the string pointer. Setting a write breakpoint to <strong>$5C:$5D</strong> led me to <strong>$8C4B</strong>.
<pre class="brush: cpp; title: ; notranslate">        LDA     [$52], Y
        STA     &lt;$5c
        INY     
        LDA     [$52], Y
        STA     &lt;$5d</pre>
<p> I was lucky because what precedes told me where the string table was.
<pre class="brush: cpp; title: ; notranslate">        LDA     #$00
        STA     &lt;$64
        LDA     #$56
        STA     &lt;$65
        LDY     #$0c
        LDA     [$64], Y
        STA     &lt;$52
        INY     
        LDA     [$64], Y
        STA     &lt;$53
        LDA     $2716
        ASL     A
        TAY     
        LDA     [$52], Y
        STA     &lt;$5c
        INY     
        LDA     [$52], Y
        STA     &lt;$5d</pre>
<p> So <strong>$5c:$5d</strong> is set using the data pointed by <strong>$52:$53</strong> indexed by <strong>$2716</strong>. Let&#8217;s put <strong>$2716</strong> aside. This is clearly the string index. So <strong>$52:$53</strong> contains our string pointer. And the preceding lines tells us that the string table address is stored at <strong>$560C</strong>. A quick revealed that the string table was stored from <strong>$5614</strong> to <strong>$5849</strong>. If we translate the address, it&#8217;s at the file offsets <strong>$11814</strong> to <strong>$11A49</strong> (this is with the annoying 512 bytes offset). Now that I had the string pointer table, I could make it point to whenever I want (technically). So the translated texts may not have to fit into the original string locations. I checked that I got it right by swapping the pointer table entries. And as expected the intro started with the second text and so on.<br />
A quick look at the tile vram showed me that the font already contains capital letters. So I decided to manually edit the ROM and managed to get this:<br />
<img src="http://pcedev.blockos.org/download/file.php?id=6" alt="Quick hack" /></p>
<p>The next step was to modify the font in order to have lowercase letters.<br />
To continue&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.blockos.org/?feed=rss2&#038;p=164</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The last man on Earth sat alone in a room&#8230;</title>
		<link>http://blog.blockos.org/?p=171</link>
		<comments>http://blog.blockos.org/?p=171#comments</comments>
		<pubDate>Tue, 30 Nov 2010 16:19:57 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://blog.blockos.org/?p=171</guid>
		<description><![CDATA[This is what is supposed to be the shortest post on this blog. Remember last post where I used __builtin_ctz to compute GCD? Well&#8230; Here&#8217;s a way to compute the log2 of an integer using another gcc builtin. Let me &#8230; <a href="http://blog.blockos.org/?p=171">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>This is what is supposed to be the shortest post on this blog.<br />
Remember last post where I used <strong>__builtin_ctz</strong> to compute GCD? Well&#8230; Here&#8217;s a way to compute the log2 of an integer using another gcc builtin. Let me introduce <strong>__builtin_clz</strong>. <strong>clz</strong> stands for <strong>count leading zeroes</strong>. So this wonderful thing counts 0 bits starting from the most significant bit. Please note that the result is undefined for 0.</p>
<pre class="brush: cpp; title: ; notranslate">inline uint32_t ilog2(uint32_t i)
{
	return (32-__builtin_clz(i));
}
</pre>
<p>Check the section <a href="http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Other-Builtins.html">5.49 of GCC doc</a> for more builtins.</p>
<p>By the way the title of this post comes from a short novel by Fredric Brown called Knock.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.blockos.org/?feed=rss2&#038;p=171</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>GCD and destroy</title>
		<link>http://blog.blockos.org/?p=110</link>
		<comments>http://blog.blockos.org/?p=110#comments</comments>
		<pubDate>Sun, 27 Jun 2010 20:17:48 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://blog.blockos.org/?p=110</guid>
		<description><![CDATA[Some weeks ago I decided to fix once and for all this bloody hdrr. As it requires the framebuffer average log luminance, I decided to compute it be generating a pixel accurate mipmap. So for a 320&#215;240 framebuffer we will &#8230; <a href="http://blog.blockos.org/?p=110">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Some weeks ago I decided to fix once and for all this bloody <a href="http://en.wikipedia.org/wiki/High_dynamic_range_rendering">hdrr</a>. As it requires the framebuffer average log luminance, I decided to compute it be generating a pixel accurate mipmap. So for a 320&#215;240 framebuffer we will have the following downsampling steps : (4,4) (4,4) (5,5) (4,3).<br />
Don&#8217;t ask me why but instead of working on a way to decompose a number, I decided that I needed to find the greatest common divisor of width and height! 10 seconds later thanks to the almighty web search engine I started reading the Wikipedia entry about <a href="http://en.wikipedia.org/wiki/Binary_GCD_algorithm">Binary GCD</a>. And after some interweb jumps I ended on this <a href="http://sputsoft.com/2009/10/computing-the-greatest-common-divisor/">article</a>. The Stein’s algorithm looked cool.<br />
If you look at Sputsoft code, you&#8217;ll realize that the <strong>shift_to_uneven</strong> function removes trailing zeros. This can be optimized using GCC builtins. The builtins we need is <strong>__builtin_ctz</strong> that counts trailing zeros.<br />
We can then replace <strong>shift_to_uneven</strong> by: </p>
<pre class="brush: cpp; title: ; notranslate">u &gt;&gt;= __builtin_ctz(u);</pre>
<p>And the GCD function now looks like this:</p>
<pre class="brush: cpp; title: ; notranslate">
uint32_t gcd( uint32_t c, uint32_t d )
{
	uint32_t u,v,s;
	
	u = __builtin_ctz(c);
	v = __builtin_ctz(d);

	s = (u &lt; v) ? u : v;
    	
	u = c &gt;&gt; u;
	v = d &gt;&gt; v;

	while(u != v)
	{
		if(u &gt; v)
		{
			u -= v;
			u &gt;&gt;= __builtin_ctz(u);
		}
		else
		{
			v -= u;
			v &gt;&gt;= __builtin_ctz(v);
		}
	}
	return u &lt;&lt; s;
}</pre>
<p>Tadam!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.blockos.org/?feed=rss2&#038;p=110</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Malevitch can&#8217;t code!</title>
		<link>http://blog.blockos.org/?p=99</link>
		<comments>http://blog.blockos.org/?p=99#comments</comments>
		<pubDate>Mon, 08 Feb 2010 20:10:02 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.blockos.org/?p=99</guid>
		<description><![CDATA[Some months ago, Iq asked on Pouet bbs if anyone had some tip and tricks on creating a minimal glx framework. Viznut answered that he managed to have open a window and refresh a framebuffer in 300 bytes using kernel &#8230; <a href="http://blog.blockos.org/?p=99">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Some months ago, <a href="http://www.iquilezles.org">Iq</a> asked on <a href="http://pouet.net/topic.php?which=7014">Pouet bbs</a> if anyone had some tip and tricks on creating a minimal glx framework.<br />
<a href="http://www.pelulamu.net/viznut/">Viznut</a> answered that he managed to have open a window and refresh a framebuffer in 300 bytes using kernel syscalls.<br />
So I jumped on the bandwagon and decided to code my own minimal X client using raw X11 protocol.<br />
Here&#8217;s my <a href="http://gist.github.com/252808">miserable attempt</a>. Looking at <a href="http://cgit.freedesktop.org/xcb/">xcb</a> and <a href="http://cgit.freedesktop.org/xorg/lib/libX11/tree/">Xlib</a> code helped a lot. Unfortunately it failed on half of the boxes where it was tested because of authentication.<br />
<a href="http://kernel-error.tuxfamily.org/">Kernel_error</a> tried to add it but he said it&#8217;s a pain in the harp.<br />
Oh by the way, it&#8217;ll crash on x64&#8230; Here&#8217;s <a href="http://nibbles.tuxfamily.org/?p=558">small article in french </a> about the different syscall conventions. And you&#8217;ll surely understand why it&#8217;ll crash <img src='http://blog.blockos.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.blockos.org/?feed=rss2&#038;p=99</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dataflash of the two worlds</title>
		<link>http://blog.blockos.org/?p=88</link>
		<comments>http://blog.blockos.org/?p=88#comments</comments>
		<pubDate>Sat, 09 Jan 2010 21:30:41 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[arduino]]></category>
		<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://blog.blockos.org/?p=88</guid>
		<description><![CDATA[I spent the whole afternoon trying to make the arduino works with 2 dataflash chips. A coupe of really stupid code mistakes and some weird stuffs later, it worked. You can now have 2 instances of ATD45DB161D class. For example &#8230; <a href="http://blog.blockos.org/?p=88">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I spent the whole afternoon trying to make the arduino works with 2 dataflash chips. A coupe of really stupid code mistakes and some weird stuffs later, it worked. You can now have 2 instances of ATD45DB161D class. For example one will use the pins 2, 4 and 5 for SS, RESET and WP and the other one will use pins 10,8 and 7.<br />
I couldn&#8217;t make SS work with an other pin than the pin 10 until I ran across <a href="http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1227719581">forum post</a>. So I have to set both the requested SS pin and pin 10 (hardwired SS pin) high before setting the SPCR register so that the atmega168 becomes master.<br />
So I moved the SPCR initialization to a new method astutely called <em>Enable</em>. And I added its counterpart called <em>Disable</em> which drives the SS pin high.<br />
So before using a given Dataflash chip, you&#8217;ll have to call <em>Enable</em> before using it. And call <em>Disable</em> when you are done with it.</p>
<p><del datetime="2010-01-11T22:12:20+00:00">As I&#8217;m not happy with the current design, I created a new branch for this dev.</del></p>
<p>You can find it <strong><a href="http://github.com/BlockoS/arduino-dataflash/tree/configurable_pins">[here]</a></strong>.<br />
Any ideas/suggestions for a cleaner/safer way to handle multiple SPI device are welcome <img src='http://blog.blockos.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a href="http://blog.blockos.org/wp-content/uploads/2010/01/dataflash2.png"><img src="http://blog.blockos.org/wp-content/uploads/2010/01/dataflash2.png" alt="" title="Arduino Diecimila with 2 atmel Dataflash" width="422" height="270" class="aligncenter size-full wp-image-87" /></a></p>
<p><strong>[edit]</strong>: Arg, I should have checked Atmel site. They have an application note called <a href="http://www.atmel.com/dyn/resources/prod_documents/doc2585.pdf">AVR151: Setup And Use of The SPI</a>.<br />
<strong>[edit]</strong> (it&#8217;s the last one. I swear <img src='http://blog.blockos.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ) I moved the SPI master init into a new function (<em>spi_init</em>). It&#8217;s a little bit cleaner now. But it&#8217;ll stay in a branch until I run more tests and have some feedback.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.blockos.org/?feed=rss2&#038;p=88</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
