<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://mrb0.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://mrb0.com/" rel="alternate" type="text/html" /><updated>2026-04-17T19:09:45-03:00</updated><id>https://mrb0.com/feed.xml</id><title type="html">Mike Burke</title><author><name>Mike Burke</name></author><entry><title type="html">JS Toy: Interactive animated drawing</title><link href="https://mrb0.com/2026/04/17/interactive-circular-drawing/" rel="alternate" type="text/html" title="JS Toy: Interactive animated drawing" /><published>2026-04-17T18:25:52-03:00</published><updated>2026-04-17T18:25:52-03:00</updated><id>https://mrb0.com/2026/04/17/interactive-circular-drawing</id><content type="html" xml:base="https://mrb0.com/2026/04/17/interactive-circular-drawing/"><![CDATA[<p>A few years ago I made an interactive animated JS toy, based on a drawing my friend made.</p>

<style>
  #interactive-drawing-20230526 {
    display: flex;
    align-items: flex-start;
    gap: 1.5rem;
    flex-wrap: wrap;
  }
  #interactive-drawing-20230526 #content {
    flex: 1 1 280px;
  }
  #interactive-drawing-20230526 canvas {
    display: block;
    width: 100%;
    aspect-ratio: 1;
  }
  .drawing-controls {
    flex: 0 0 10rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }
</style>

<div id="interactive-drawing-20230526">

  <div id="content">
    <canvas id="canvas"></canvas>
  </div>

  <div class="drawing-controls">

    <div class="control">
      <label>
        Color amount<br />
        <input type="range" id="range_color_amount" min="0" max="1" step="any" value="0" />
      </label>
    </div>

    <div class="control">
      <label>
        Color target<br />
        <input type="range" id="range_color_target" min="0" max="1" step="any" value="0" />
      </label>
    </div>

    <div class="control">
      <label>
        Horizontal diversity<br />
        <input type="range" id="range_color_horizontal_diversity" min="-1" max="1" step="any" value="0" />
      </label>
    </div>

    <div class="control">
      <label>
        Vertical diversity<br />
        <input type="range" id="range_color_vertical_diversity" min="-1" max="1" step="any" value="0" />
      </label>
    </div>

    <div class="control">
      <label>
        Color dynamism<br />
        <input type="range" id="range_color_dynamism" min="-1" max="1" step="any" value="0" />
      </label>
    </div>

    <div class="control">
      <label>
        Speed<br />
        <input type="range" id="range_speed" min="-1" max="1" step="any" value="0" />
      </label>
    </div>

    <div class="control">
      <button id="reset_btn">Reset</button>
    </div>

  </div>

</div>

<hr />

<p>And here’s the original drawing from my friend:</p>

<div>
  <a href="/a/2023-05-26/drawing.html">
    <picture>
      <source type="image/avif" srcset="/a/2023-05-26/drawing.avif" />
      <source type="image/webp" srcset="/a/2023-05-26/drawing.webp" />
      <img src="/a/2023-05-26/drawing.jpg" alt="Original hand drawing" width="400" height="400" style="max-width: 400px; width: 100%; height: auto;" />
    </picture>
  </a>
</div>

<script src="/a/2023-05-26/main.js"></script>]]></content><author><name>Mike Burke</name></author><summary type="html"><![CDATA[A few years ago I made an interactive animated JS toy, based on a drawing my friend made.]]></summary></entry><entry><title type="html">zsh word splitting behavior with variable and subshell expansion</title><link href="https://mrb0.com/2024/12/23/zsh-word-splitting-with-variable-and-subshell-expansion/" rel="alternate" type="text/html" title="zsh word splitting behavior with variable and subshell expansion" /><published>2024-12-23T15:25:52-04:00</published><updated>2024-12-23T15:25:52-04:00</updated><id>https://mrb0.com/2024/12/23/zsh-word-splitting-with-variable-and-subshell-expansion</id><content type="html" xml:base="https://mrb0.com/2024/12/23/zsh-word-splitting-with-variable-and-subshell-expansion/"><![CDATA[<p><strong>TL;DR:</strong> With zsh’s default settings:</p>

<ul>
  <li><em>Variable expansion</em> <code class="language-plaintext highlighter-rouge">${name}</code>
    <ul>
      <li>NEVER undergoes word
splitting, and even without quoting they’ll be passed with all spaces,
newlines etc. intact.</li>
    </ul>
  </li>
  <li><em>Subshell output</em> <code class="language-plaintext highlighter-rouge">$(cat something)</code>
    <ul>
      <li>DOES undergo word splitting,
unless wrapped in quotes like <code class="language-plaintext highlighter-rouge">"$(cat something)"</code> (except when
assigning the result to a variable).</li>
    </ul>
  </li>
</ul>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/env zsh</span>
<span class="c"># -*- coding: utf-8 -*-</span>

<span class="c"># The only differences I observed in the behavior of variable</span>
<span class="c"># expansion were around how newlines and spaces are treated ("word</span>
<span class="c"># splitting").  When word splitting is performed, newlines are turned</span>
<span class="c"># into spaces, and consecutive spaces are collapsed into a single one.</span>
<span class="c">#</span>
<span class="c"># I never observed any issue with unicode characters, or special</span>
<span class="c"># characters that are significant to the shell in regular syntax -</span>
<span class="c"># these always passed through unmodified and uninterpreted.</span>

<span class="c"># For debugging: Shows commands being invoked, with actual quoted</span>
<span class="c"># arguments.</span>
<span class="nb">set</span> <span class="nt">-x</span>

<span class="c"># Output some test data.</span>
cmd<span class="o">()</span> <span class="o">{</span>
    <span class="nb">cat</span> <span class="o">&lt;&lt;</span><span class="sh">"</span><span class="no">EOF</span><span class="sh">"
OneWord
Two Words
Many     Spaces
  Leading spaces!
An 'apostrophe', "quotes", </span><span class="nv">$ </span><span class="sh">sign, (parens), ? mark, </span><span class="se">\ </span><span class="sh">backslash, </span><span class="se">\</span><span class="sh">
'An '</span><span class="se">\'</span><span class="sh">'apostrophe'</span><span class="se">\'</span><span class="sh">', "quotes", </span><span class="nv">$ </span><span class="sh">sign, (parens), ? mark, </span><span class="se">\ </span><span class="sh">backslash, now escaped for a shell </span><span class="se">\'</span><span class="sh">
c'est français
🤣
</span><span class="no">EOF
</span><span class="o">}</span>


<span class="c"># NO SHELL BEHAVIOR: Store the output as a single scalar string.</span>
<span class="c"># Spaces, newlines, special characters are intact.  Either works.</span>
<span class="nv">content</span><span class="o">=</span><span class="s2">"</span><span class="si">$(</span>cmd<span class="si">)</span><span class="s2">"</span>
<span class="nv">content</span><span class="o">=</span><span class="si">$(</span>cmd<span class="si">)</span>

<span class="c"># NO SHELL BEHAVIOR: Echo the content exactly as it was stored, with</span>
<span class="c"># spaces, newlines, special characters intact. Unlike bash, zsh</span>
<span class="c"># doesn't perform word splitting on expanded variables by default, but</span>
<span class="c"># you can change that with setopt SH_WORD_SPLIT.  Either works.</span>
<span class="nb">echo</span> <span class="s2">"</span><span class="nv">$content</span><span class="s2">"</span>
<span class="nb">echo</span> <span class="nv">$content</span>

<span class="c"># NO SHELL BEHAVIOR: Echo the content exactly, without storing it in</span>
<span class="c"># a variable.</span>
<span class="nb">echo</span> <span class="s2">"</span><span class="si">$(</span>cmd<span class="si">)</span><span class="s2">"</span>

<span class="c"># CAUSES SHELL BEHAVIOR: Perform word splitting: Newlines are treated</span>
<span class="c"># as spaces, consecutive spaces are dropped,</span>
<span class="nb">echo</span> <span class="si">$(</span>cmd<span class="si">)</span>

<span class="c"># CAUSES SHELL BEHAVIOR: ${=name} performs word splitting on $name</span>
<span class="c"># even if it's quoted.</span>
<span class="nb">echo</span> <span class="s2">"</span><span class="k">${</span><span class="p">=content</span><span class="k">}</span><span class="s2">"</span>

<span class="c"># Any text surrounding ${=name} will get "glued" to the first &amp; last</span>
<span class="c"># words in $name after word splitting is performed, even if there are</span>
<span class="c"># spaces in the surrounding text, but otherwise each word in $name</span>
<span class="c"># gets passed as a separate argument.</span>
<span class="c">#</span>
<span class="c"># This split happens even if it looks like we're passing a single</span>
<span class="c"># argument:</span>

<span class="nv">food</span><span class="o">=</span><span class="s1">'barbecue basil spam eggs'</span>
print <span class="nt">-rl</span> <span class="nt">--</span> <span class="s2">"We have </span><span class="k">${</span><span class="p">=food</span><span class="k">}</span><span class="s2"> and nothing else"</span>

<span class="c"># Output:</span>
<span class="c">#     We have barbecue</span>
<span class="c">#     basil</span>
<span class="c">#     spam</span>
<span class="c">#     eggs and nothing else</span>
</code></pre></div></div>

<p><a href="https://gist.github.com/mRB0/7ed3b977d7da1a65e4e6cfc5a7e512f4">Also available as a gist.</a></p>]]></content><author><name>Mike Burke</name></author><summary type="html"><![CDATA[zsh's variable expansion (`${name}`) never undergoes word splitting, but subshell output (`$(cmd)`) does unless quoted.]]></summary></entry><entry><title type="html">More thoughts on foreign function interfaces</title><link href="https://mrb0.com/2024/08/23/more-thoughts-on-foreign-function-interfaces/" rel="alternate" type="text/html" title="More thoughts on foreign function interfaces" /><published>2024-08-23T16:04:09-03:00</published><updated>2024-08-23T16:04:09-03:00</updated><id>https://mrb0.com/2024/08/23/more-thoughts-on-foreign-function-interfaces</id><content type="html" xml:base="https://mrb0.com/2024/08/23/more-thoughts-on-foreign-function-interfaces/"><![CDATA[<p>I have been thinking some more about <a href="/2024/05/28/c-libraries-in-java/">Using a C library from Java</a>, especially the <em>Translate to JVM</em> approach.</p>

<p>When I tried this, I mostly got caught up in compiling the target library to MIPS in the first place. I tried building a GCC cross compiler for MIPS, but ran into some build errors and kinda gave up.</p>

<p>Since then, I’ve looked at using clang to target a MIPS binary, and this looks feasible, but I haven’t tried it. There’s also an option to build to LLVM IR and interpret that. This seems like a good idea, but I’ve heard, via other projects that work off LLVM IR, that it’s something of a moving target; also, it seems like a more complex process than it would be to integrate a MIPS core.</p>

<p>I’ll need to compile a C library with enough functionality to support the target library, and the library has C++ components so I’ll need to deal with that too. At least the library exposes a C interface so I don’t need to build C++ FFI glue.</p>

<p>I identified all of these problems earlier on, but despite all this I wasn’t quite sure how I would actually call the target library’s functions from outside the MIPS core. I knew I could use interrupts to switch out of the MIPS context, like syscalls do to switch from user to kernel context, but I didn’t quite know where to fit that machinery in.</p>

<p>So I came up with some options:</p>

<ol>
  <li>I could write some glue, in C, that I package with the library, to provide a syscall-like interface between the MIPS guest and the host (Java) code. The Java code acts as a supervisor and has access to the MIPS core’s registers, memory (&amp; stack), etc., so would be able to use that for passing arguments &amp; context around. But if possible, I’d like to do it without writing C glue code.</li>
  <li>
    <p>I can have some host (Java) code that set up the stack &amp; environment etc. required to call a function, and then start executing at the right location. It’ll have to capture the return somehow, which I can either intercept with something akin to a debugger breakpoint, or place some code in memory to invoke an interrupt (as in option 1).</p>

    <p>It occurred to me while I was considering this option, that even though I’m running the code in a virtual host environment that’s local to my own program, it’s still C code and I still have to think about all the usual FFI stuff: Type signatures, struct packing, memory management etc. That means that even if I run the library in an emulated core, I’ll still end up building an interface similar to <a href="https://github.com/java-native-access/jna">Java Native Access</a> or the newer <a href="https://openjdk.org/jeps/454">Java Foreign Function and Memory (FFM) API</a>. I guess I kind of hoped that part of the process would be simpler.</p>
  </li>
</ol>

<p>I still think it’s a viable solution with real benefits, especially if I need to target multiple platforms. I also wonder if it might be feasible to compile or transpile the C library directly to Java, whether to source code or bytecode. That sounds far more difficult to me because it depends on compiler internals, but maybe building a new backend onto an existing compiler could be practical?</p>]]></content><author><name>Mike Burke</name></author><summary type="html"><![CDATA[I have been thinking more about using a C library from Java, by using a MIPS binary and virtual machine. It still requires significant effort to manage data and calls between the MIPS guest code and the Java host.]]></summary></entry><entry><title type="html">On generating structured data from templates</title><link href="https://mrb0.com/2024/06/17/on-code-generation-from-templates/" rel="alternate" type="text/html" title="On generating structured data from templates" /><published>2024-06-17T22:08:32-03:00</published><updated>2024-06-17T22:08:32-03:00</updated><id>https://mrb0.com/2024/06/17/on-code-generation-from-templates</id><content type="html" xml:base="https://mrb0.com/2024/06/17/on-code-generation-from-templates/"><![CDATA[<p>Recently I chatted with <a href="https://anderegg.ca/">a friend</a> about generating structured data from templates. Specifically, he observed that Jekyll’s atom feed is generated from an XML template. <a href="https://anderegg.ca/2024/05/24/on-templatebased-feed-generation">He posted about his experience</a>.</p>

<p>I’ve long felt that it’s extremely challenging to correctly use templates to generate structured data, meaning files like source code - HTML/XML/C/etc. I don’t particularly like templating, but I acknowledge its value, especially in HTML templating where you’re mostly writing static markup to represent the page layout. In fact, template-engine substitutions in HTML templates are only a small part of most HTML template files.</p>

<p>The problem I have is that the template engine doesn’t actually know the context for how it’s making substitutions. No HTML template engine parses the HTML and decides what escaping rules are appropriate for each piece of data being placed into the generated output.</p>

<p>This post is kinda rambly, but I have some lightly-organized thoughts about templating that I wanted to put into words.</p>

<h2 id="a-typical-problem">A typical problem</h2>

<p>Let me give an example:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"name"</span><span class="nt">&gt;</span>Hello, {{ email }}!<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;script&gt;</span>
    <span class="nx">database</span><span class="p">.</span><span class="nf">saveEmail</span><span class="p">(</span><span class="dl">'</span><span class="s1">{{ email }}</span><span class="dl">'</span><span class="p">);</span>
<span class="nt">&lt;/script&gt;</span>
</code></pre></div></div>

<p>If <code class="language-plaintext highlighter-rouge">email</code> is <code class="language-plaintext highlighter-rouge">'Baz' &lt;foo.bar@example.com&gt;</code>, what happens?</p>

<p>I see two typical options, both of which result in the wrong result:</p>

<ul>
  <li>
    <p>The value of <code class="language-plaintext highlighter-rouge">email</code> is substituted directly into the template with no modification. The resulting output is incorrect:</p>

    <div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="c">&lt;!-- WRONG! &lt;foo...&gt; is not a valid HTML tag! --&gt;</span>
  <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"name"</span><span class="nt">&gt;</span>Hello, 'Baz' <span class="nt">&lt;foo.bar</span><span class="err">@</span><span class="na">example.com</span><span class="nt">&gt;</span>!<span class="nt">&lt;/div&gt;</span>
  <span class="nt">&lt;script&gt;</span>
      <span class="c1">// WRONG! Incorrectly quoted; leads to syntax error!</span>
      <span class="nx">database</span><span class="p">.</span><span class="nx">saveEmail</span><span class="p">(</span><span class="dl">''</span><span class="nx">Baz</span><span class="dl">'</span><span class="s1"> &lt;foo.bar@example.com&gt;</span><span class="dl">'</span><span class="p">);</span>
  <span class="nt">&lt;/script&gt;</span>
</code></pre></div>    </div>
  </li>
  <li>
    <p>The value of <code class="language-plaintext highlighter-rouge">email</code> is escaped for HTML. Django and many other template engines will do this for regular strings.</p>

    <div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="c">&lt;!-- Correct: The string is escaped for inclusion as plain text in HTML. --&gt;</span>
  <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"name"</span><span class="nt">&gt;</span>Hello, 'Baz' <span class="ni">&amp;lt;</span>foo.bar@example.com<span class="ni">&amp;gt;</span>!<span class="nt">&lt;/div&gt;</span>
  <span class="nt">&lt;script&gt;</span>
      <span class="c1">// WRONG! Still incorrectly quoted, and now we're incorrectly</span>
      <span class="c1">// storing HTML entities in the database instead of the</span>
      <span class="c1">// original string!</span>
      <span class="nx">database</span><span class="p">.</span><span class="nf">saveEmail</span><span class="p">(</span><span class="dl">''</span><span class="nx">Baz</span><span class="dl">'</span><span class="s1"> &amp;lt;foo.bar@example.com&amp;gt;</span><span class="dl">'</span><span class="p">);</span>
  <span class="nt">&lt;/script&gt;</span>
</code></pre></div>    </div>
  </li>
</ul>

<h2 id="comparison-to-sql">Comparison to SQL</h2>

<p>The problem is similar to SQL injection, although the stakes are usually a lot lower. The typical solution for avoiding SQL injection bugs when writing SQL is by using SQL-aware interpolation functions provided by our SQL libraries:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">db</span><span class="p">.</span><span class="nf">execute</span><span class="p">(</span><span class="sh">'</span><span class="s">SELECT * FROM foo WHERE email = ?</span><span class="sh">'</span><span class="p">,</span> <span class="n">email</span><span class="p">)</span>
</code></pre></div></div>

<p>In SQL, this works because SQL allows <strong>every</strong> value in a query to be represented as a string literal with consistent quoting &amp; escaping rules, regardless of the data type of the value being represented:</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">select</span> <span class="s1">'3'</span><span class="p">::</span><span class="nb">integer</span> <span class="o">+</span> <span class="s1">'4'</span><span class="p">::</span><span class="nb">integer</span><span class="p">;</span>
<span class="c1">-- Result: 7</span>
</code></pre></div></div>

<p>But SQL-aware interpolation <strong>only</strong> works for data. Other SQL syntax and identifiers cannot be represented as string data, so this code:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># This won't work!
</span><span class="n">table_name</span> <span class="o">=</span> <span class="sh">"</span><span class="s">user_table</span><span class="sh">"</span>
<span class="n">db</span><span class="p">.</span><span class="nf">execute</span><span class="p">(</span><span class="sh">"</span><span class="s">SELECT COUNT(*) FROM ?</span><span class="sh">"</span><span class="p">,</span> <span class="n">user_table</span><span class="p">)</span>
</code></pre></div></div>

<p>results in an invalid query:</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="k">COUNT</span><span class="p">(</span><span class="o">*</span><span class="p">)</span> <span class="k">FROM</span> <span class="s1">'user_table'</span><span class="p">;</span>
<span class="c1">-- ERROR:  syntax error at or near "'user_table'"</span>
</code></pre></div></div>

<p>In SQL, you often avoid this by marking the interpolated string as “safe”, which indicates that you’ve already verified that it won’t lead to problems if it’s substituted raw:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">table_name</span> <span class="o">=</span> <span class="sh">"</span><span class="s">user_table</span><span class="sh">"</span>
<span class="n">db</span><span class="p">.</span><span class="nf">execute</span><span class="p">(</span><span class="sh">"</span><span class="s">SELECT COUNT(*) FROM ?</span><span class="sh">"</span><span class="p">,</span> <span class="nc">AsIs</span><span class="p">(</span><span class="n">user_table</span><span class="p">))</span>
</code></pre></div></div>

<p>You do have to be really careful that <code class="language-plaintext highlighter-rouge">table_name</code> doesn’t include anything malicious, since its contents will be interpreted as valid SQL syntax. I might even suggest that we should be able to tag it as a different kind of identifier, like <code class="language-plaintext highlighter-rouge">TableName(table_name)</code>, so the interpolating code can validate/quote/escape it for use ONLY as a table name.</p>

<h2 id="usage-contexts">Usage contexts</h2>

<p>The main problem I see with HTML and other languages is that there are way more different kinds of contexts that variables get substituted into.</p>

<p>Above, I showed that one escaping rule isn’t sufficient when a variable gets substituted into both HTML and JavaScript.</p>

<p>A common solution here is to indicate the context to your template engine - perhaps using a filter:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"name"</span><span class="nt">&gt;</span>Hello, {{ email | html }}!<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;script&gt;</span>
    <span class="nx">database</span><span class="p">.</span><span class="nf">saveEmail</span><span class="p">(</span><span class="dl">'</span><span class="s1">{{ email | javascript_string }}</span><span class="dl">'</span><span class="p">);</span>
<span class="nt">&lt;/script&gt;</span>
</code></pre></div></div>

<p>This works OK when the number of different usage contexts is small, like in this example, but I don’t like that you have to remember to use the right filter every time you code in a substitution. If the default behavior is to escape for HTML, you’ll start omitting the <code class="language-plaintext highlighter-rouge">| html</code> part, and then it’s easy to accidentally miss the <code class="language-plaintext highlighter-rouge">| javascript_string</code> filter because it’s used so much less-frequently.</p>

<p>And if you do miss it, will you even notice? You’ll only see problems with strings that contain syntax that that’s meaningful to JavaScript. So it becomes a bug that happens infrequently, which makes it harder to find later on. This is actually also a problem that SQL interpolation would suffer from:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Don't do this! It's SO UNSAFE!
# But it results in working code, and doesn't even break for most typical
# inputs, and that's almost worse!
</span>
<span class="n">email</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">GET</span><span class="p">[</span><span class="sh">'</span><span class="s">email</span><span class="sh">'</span><span class="p">]</span>     <span class="c1"># eg. foo@example.com
</span><span class="n">db</span><span class="p">.</span><span class="nf">execute</span><span class="p">(</span><span class="sa">f</span><span class="sh">"</span><span class="s">SELECT * FROM foo WHERE email = </span><span class="sh">'</span><span class="si">{</span><span class="n">email</span><span class="si">}</span><span class="sh">'"</span><span class="p">)</span>
</code></pre></div></div>

<h3 id="too-many-contexts">Too many contexts</h3>

<p>If you have a lot of different contexts that substitutions need to be placed into, it can be arduous to make sure they’re all correct:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># NOTE: Function {{ fn_name | for_comment }} is generated from a template.
</span><span class="k">def</span> <span class="err">{{ </span><span class="nf">fn_name</span> <span class="o">|</span> <span class="n">for_identifier</span> <span class="p">}}():</span>
    <span class="n">num1</span> <span class="o">=</span> <span class="p">{{</span> <span class="n">num1</span> <span class="o">|</span> <span class="n">for_number</span> <span class="p">}}</span>
    <span class="n">num_squared</span> <span class="o">=</span> <span class="n">num1</span> <span class="o">*</span> <span class="n">num1</span>

    <span class="n">logging</span><span class="p">.</span><span class="nf">debug</span><span class="p">(</span><span class="sa">r</span><span class="sh">'</span><span class="s">{{ name | for_raw_string }}</span><span class="sh">'</span><span class="p">)</span>

    <span class="nf">print</span><span class="p">(</span><span class="sa">f</span><span class="sh">'</span><span class="s">Hey {{ name | for_string }}, your squared number {{ num1 | for_string }} is </span><span class="si">{</span><span class="n">num1</span><span class="si">}</span><span class="s">!</span><span class="sh">'</span><span class="p">)</span>
</code></pre></div></div>

<p>The idea here is that you need to escape/quote/etc. values depending on how they’re being used. Like, in a string, <code class="language-plaintext highlighter-rouge">\</code> should be escaped to <code class="language-plaintext highlighter-rouge">\\</code>, but that would be inappropriate in a raw string. Numbers shouldn’t have spaces or anything in them.</p>

<h2 id="not-using-templates">Not using templates</h2>

<p>There are libraries that allow you to generate HTML by writing code in your host language. This is comparable to generating JSON using a JSON library, or XML using an XML library, and it can also be a pain:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">doc</span> <span class="o">=</span> <span class="nf">htmltag</span><span class="p">(</span><span class="sh">'</span><span class="s">html</span><span class="sh">'</span><span class="p">)</span>
<span class="n">body</span> <span class="o">=</span> <span class="nf">htmltag</span><span class="p">(</span><span class="sh">'</span><span class="s">body</span><span class="sh">'</span><span class="p">).</span><span class="nf">add_to</span><span class="p">(</span><span class="n">doc</span><span class="p">)</span>

<span class="c1"># Static elements are too much work to create.
</span><span class="n">div</span> <span class="o">=</span> <span class="nf">htmltag</span><span class="p">(</span><span class="sh">'</span><span class="s">div</span><span class="sh">'</span><span class="p">,</span> <span class="p">{</span>
    <span class="sh">'</span><span class="s">id</span><span class="sh">'</span><span class="p">:</span> <span class="sh">'</span><span class="s">outermost</span><span class="sh">'</span>
<span class="p">}).</span><span class="nf">add_to</span><span class="p">(</span><span class="n">body</span><span class="p">)</span>

<span class="c1"># Attribute values are too much work, but they'll be properly escaped on output.
</span><span class="n">textinput</span> <span class="o">=</span> <span class="nf">htmltag</span><span class="p">(</span><span class="sh">'</span><span class="s">input</span><span class="sh">'</span><span class="p">,</span> <span class="p">{</span>
    <span class="sh">'</span><span class="s">type</span><span class="sh">'</span><span class="p">:</span> <span class="sh">'</span><span class="s">text</span><span class="sh">'</span><span class="p">,</span>
    <span class="sh">'</span><span class="s">name</span><span class="sh">'</span><span class="p">:</span> <span class="sh">'</span><span class="s">user_email</span><span class="sh">'</span><span class="p">,</span>
    <span class="sh">'</span><span class="s">value</span><span class="sh">'</span><span class="p">:</span> <span class="n">email_address</span>
<span class="p">}.</span><span class="nf">add_to</span><span class="p">(</span><span class="n">div</span><span class="p">)</span>

<span class="c1"># When htmltext is rendered to HTML, its contents are escaped.
</span><span class="nf">htmltext</span><span class="p">(</span><span class="sa">f</span><span class="sh">'</span><span class="s">Hello, </span><span class="si">{</span><span class="n">email</span><span class="si">}</span><span class="s">!</span><span class="sh">'</span><span class="p">).</span><span class="nf">add_to</span><span class="p">(</span><span class="n">div</span><span class="p">)</span>

<span class="n">response</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="n">doc</span><span class="p">.</span><span class="nf">render_to_html</span><span class="p">())</span>
</code></pre></div></div>

<p>In my experience, nobody wants to write HTML in anything other than an HTML file. Totally understandable - editors have good syntax highlighting, feedback, etc. for HTML, and you’re mostly writing static HTML anyway with only a few substitutions here and there.</p>

<h2 id="what-do-i-want-anyway">What do I want anyway</h2>

<p>I don’t really know. I think templating has substantial problems.</p>

<p>I feel like the fact that frameworks usually have default settings that “just work” for most cases, so it’s easy to get complacent in less-common situations. Or, people fail to gain an understanding how templating works, and the gotchas when they need to substitute different contexts, like JavaScript code.</p>

<p>Even if you’re well-aware of the limitations and gotchas, it’s also easy to make a mistake and not notice until some unusual text shows up and breaks your output.</p>

<hr />

<p>By the way:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;script&gt;</span>
    <span class="nx">database</span><span class="p">.</span><span class="nf">saveEmail</span><span class="p">(</span><span class="dl">'</span><span class="s1">{{ email | javascript_string }}</span><span class="dl">'</span><span class="p">);</span>
<span class="nt">&lt;/script&gt;</span>
</code></pre></div></div>

<p>It’s inappropriate to replace <code class="language-plaintext highlighter-rouge">&lt;</code> and <code class="language-plaintext highlighter-rouge">&gt;</code> with HTML entities in JavaScript strings, so they’ll get substituted verbatim in the string. What happens if <code class="language-plaintext highlighter-rouge">email</code> contains the text <code class="language-plaintext highlighter-rouge">&lt;/script&gt;</code>?</p>]]></content><author><name>Mike Burke</name></author><summary type="html"><![CDATA[I find templates to be a poor fit for generating structured data, like HTML. It's hard to get escaping right; you have to be keenly aware of the context where you're substituting a value, so you can apply the proper escaping rules (or stack of escaping rules).]]></summary></entry><entry><title type="html">Using a C library from Java</title><link href="https://mrb0.com/2024/05/28/c-libraries-in-java/" rel="alternate" type="text/html" title="Using a C library from Java" /><published>2024-05-28T23:51:02-03:00</published><updated>2024-05-28T23:51:02-03:00</updated><id>https://mrb0.com/2024/05/28/c-libraries-in-java</id><content type="html" xml:base="https://mrb0.com/2024/05/28/c-libraries-in-java/"><![CDATA[<p>Recently I’ve been considering making Java bindings to an open-source C library.</p>

<p>It’s such a pain though.</p>

<p><strong>Update:</strong> On 2024-08-23, I wrote <a href="https://mrb0.com/2024/08/23/more-thoughts-on-foreign-function-interfaces/">another post about this topic</a>.</p>

<h1 id="native-binding-to-c-library">Native binding to C library</h1>

<p>Traditionally you’d do this with JNI:</p>

<ol>
  <li>Compile the C library,</li>
  <li>Write some JNI glue in C and Java,</li>
  <li>Package it all up into a JAR</li>
</ol>

<p>Writing JNI isn’t trivial. I experimented with it and there are a lot of gotchas around memory management and string handling. I’m confident I could manage it but it’s a lot of work even to just move a UTF-8 string from C into Java without leaking memory or mis-handling exceptions.</p>

<p><a href="https://openjdk.org/projects/jdk/22/">Java 22</a> reached General Availability recently (March 2024) and it includes the first non-preview release of the <a href="https://docs.oracle.com/en/java/javase/22/core/foreign-function-and-memory-api.html">Java Foreign Function and Memory (FFM) API</a>, which is like a libffi or Python ctypes mechanism for Java - which <a href="https://github.com/java-native-access/jna">Java Native Access (JNA)</a> also already provided.</p>

<p>With that approach, you don’t write any glue code in C: Instead, you describe the C library’s exports in Java and use FFM/JNA to access them.</p>

<p>So then, your process looks like:</p>

<ol>
  <li>Compile the C library,</li>
  <li>Write FFM/JNA glue in Java,</li>
  <li>Package it all up into a JAR</li>
</ol>

<p>It’s still not perfect, though. In C, you can have platform- and implementation-dependent definitions of primitive types, standard library types and typedefs, etc. In C, these are resolved at compile time, so JNI gives you the opportunity to adapt to the platform’s specifications in a general way.</p>

<p>I wrote about this problem before: <a href="/2023/08/13/setjmp-longjmp-and-fflush-in-java-jna/">Using setjmp/longjmp from Java</a>.</p>

<p><code class="language-plaintext highlighter-rouge">setjmp</code> is a pretty obscure example, though. Here’s an easier example: <code class="language-plaintext highlighter-rouge">long int</code> is 64 bits on Linux x86_64, but 32 bits on Windows x86_64, and also on both Linux &amp; Windows x86_32. So if you want to call <code class="language-plaintext highlighter-rouge">unsigned long strtoul(...)</code>, you need to know how big <code class="language-plaintext highlighter-rouge">unsigned long</code> is at runtime when you’re describing <code class="language-plaintext highlighter-rouge">strtoul</code> to FFM/JNA.</p>

<p>In theory, types and sizes will vary depending on:</p>

<ul>
  <li>Operating system (Linux, Windows, macOS, …)</li>
  <li>C library (glibc, musl, MSVC, …)</li>
  <li>Compiler (gcc, clang, Visual C++, …)</li>
</ul>

<p>The above typically choose different behaviour depending on CPU architecture (x86_32, x86_64, 64-bit ARM, …)</p>

<h2 id="compile-the-c-library">Compile the C library</h2>

<p>The C library you’re wrapping also needs to be compiled to match all of the above too.</p>

<p>Most Linux distributions standardize on glibc, but musl is also common (like on Alpine Linux, which is extremely common in Docker images).</p>

<p>Practically speaking, you’ll need to link dynamically against the same C library that’s being used on the system. If you bring another C library in (like through static linking, or including it as a pre-packaged dynamic library), you’re likely to encounter conflicts with the system-installed library.</p>

<p>You can avoid that problem with statically-linked executables, but libraries are not executables, so they have less control over their immediate execution environment. That is, they need to stay compatible with other libraries that are also linked into the same project, which are certainly using the system C library.</p>

<p>More precisely, you need to link against a version of the C library that is ABI-compatible with the one that’s present at runtime: If I compile my library against glibc 2.13 x86_64 Linux, I can be pretty confident it’ll run on glibc 2.15 x86_64 Linux, because glibc is backward-compatible. However, glibc is not forward-compatible, so it won’t run on glibc 2.10 x86_64 Linux. And of course, it won’t work on x86_32, musl, etc.</p>

<p>This doesn’t apply to JUST the C library, but any dependency you need to link against. That could include a C++ standard library or other more exotic dependencies, depending on the library you’re trying to wrap.</p>

<p>And since Java is used on so many different platforms…</p>

<p>… you end up having to compile your library for every possible combination you’re willing to support.</p>

<p>Look at the matrix of <a href="https://github.com/xerial/sqlite-jdbc?tab=readme-ov-file#supported-operating-systems">SQLite-JDBC supported operating systems</a>:</p>

<p><img style="height: auto;" src="/a/2024-05-28/2024-05-28-sqlite@1x.png" srcset="/a/2024-05-28/2024-05-28-sqlite@2x.png 2x" width="749" height="384" /></p>

<p>They compile the SQLite C library separately for each of those targets! You can peek at <a href="https://github.com/xerial/sqlite-jdbc/blob/master/Makefile#L134-L214">the platform targets in the Makefile</a> for a hint on how they’re cross-compiling. I find their approach very impressive, but it sure seems like a lot of work to maintain!</p>

<h1 id="translate-to-jvm">Translate to JVM</h1>

<p><a href="https://emscripten.org/">Emscripten</a> compiles C code and libraries to Javascript. At a very high level, it does this by providing C standard library functionality (primarily, the functionality provided by the OS kernel), and using JS/WASM as the compilation target.</p>

<p>In JS, you basically have no choice: You can’t run native code in the Javascript sandbox, so you have to provide everything as JS code.</p>

<p>You’d expect a performance hit for this, but that’s OK for a lot of libraries. This is true for me, too: The library I want to provide in Java provides unique functionality, and doesn’t necessarily need to run fast.</p>

<p>So I’d like to use a similar approach in Java:</p>

<ol>
  <li>Compile a C library to JVM bytecode (or even plain Java code),</li>
  <li>Write glue to provide a better Java-style interface,</li>
  <li>Package it all up as a JAR</li>
</ol>

<p>This is totally feasible. I’ve found two projects that use translation to achieve this:</p>

<ul>
  <li><a href="https://github.com/davidar/lljvm">LLJVM</a> translates LLVM IR (bitcode) to Java bytecode and provides C library via newlib &amp; custom Java. Inactive since ~2010.</li>
  <li><a href="http://nestedvm.ibex.org/">NestedVM</a> translates MIPS binaries to Java bytecode. GCC can create MIPS binaries. Inactive since ~2009 with some more recent updates available on a <a href="https://github.com/bgould/nestedvm">fork</a>.</li>
</ul>

<p>A lot of the discourse I’ve read focuses on how people want to call native C libraries from Java because the native code is expected to perform better, so this kind of “translation” approach typically gets dismissed: Why write your high-performance code in C in the first place if you’re going to run it in the JVM?</p>

<p>The library I want to wrap:</p>

<ol>
  <li>Doesn’t require high performance</li>
  <li>Wasn’t written by me, so I didn’t have the choice to write it in Java vs. C</li>
  <li>Has unique and specialized functionality that’s hard to replicate</li>
  <li>Already works in Emscripten</li>
</ol>

<p>So I’d love to try a translation approach and see how it works. It has some pretty significant advantages over using a native library:</p>

<ol>
  <li>No difficulty compiling for all platform, OS, CPU architecture, compiler, and standard library configurations</li>
  <li>No difficulty porting, running, and testing on obscure platforms/configurations</li>
  <li>Low maintenance: Java code, even compiled, typically ages well and works unmodified for years/decades</li>
</ol>

<p>It sounds absolutely delightful!</p>]]></content><author><name>Mike Burke</name></author><summary type="html"><![CDATA[Recently I've been considering making Java bindings to an open-source C library. It's such a pain though.]]></summary></entry><entry><title type="html">Uncommon zsh shell techniques, part 1</title><link href="https://mrb0.com/2024/04/08/zsh-shell-techniques/" rel="alternate" type="text/html" title="Uncommon zsh shell techniques, part 1" /><published>2024-04-08T11:47:02-03:00</published><updated>2024-04-08T11:47:02-03:00</updated><id>https://mrb0.com/2024/04/08/zsh-shell-techniques</id><content type="html" xml:base="https://mrb0.com/2024/04/08/zsh-shell-techniques/"><![CDATA[<p>I’ve been gradually writing more and more zsh-specific shell scripts. Zsh has some techniques that don’t get a lot of attention because they’re not available in bash, which most people are targeting for their scripts… but I have found many of these handy to know, particularly at the command line.</p>

<p>Some of these work in other shells too, but I only use zsh these days.</p>

<h1 id="anonymous-functions">Anonymous functions</h1>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">()</span> <span class="o">{</span> <span class="nb">cp</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> /tmp/ <span class="o">}</span> filename
</code></pre></div></div>

<p>This works the same as <code class="language-plaintext highlighter-rouge">cp filename /tmp/</code>, but it’s more convenient in some cases:</p>

<ul>
  <li>When you’re running the same command on many filenames, and want to use command history (up + enter) to modify the filename. You don’t have to position the cursor onto the filename mid-command - it’s just at the end.</li>
  <li>When you use the argument multiple times, or need to use <a href="https://zsh.sourceforge.io/Doc/Release/Expansion.html#Modifiers">variable modifiers</a> on the input:
    <div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Print the directory containing the passed file</span>
<span class="o">()</span> <span class="o">{</span> <span class="nb">echo</span> <span class="s2">"</span><span class="k">${</span><span class="nv">1</span>:A:h<span class="k">}</span><span class="s2">"</span> <span class="o">}</span> file.csv

<span class="c"># Transcode to mp3, unless the source is already mp3</span>
<span class="o">()</span> <span class="o">{</span> <span class="nv">newfn</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">1</span>:r<span class="k">}</span><span class="s2">.mp3"</span><span class="p">;</span> <span class="k">if</span> <span class="o">[[</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">!=</span> <span class="s2">"</span><span class="nv">$newfn</span><span class="s2">"</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then </span><span class="nb">echo</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2"> -&gt; </span><span class="nv">$newfn</span><span class="s2">"</span><span class="p">;</span> ffmpeg <span class="nt">-i</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$newfn</span><span class="s2">"</span><span class="p">;</span> <span class="k">fi</span> <span class="o">}</span> foo.flac
</code></pre></div>    </div>
  </li>
</ul>

<p>It’s also safe to use with spaces &amp; other sensitive characters.</p>

<h1 id="-c-with-variables">-c with variables</h1>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># List all files without extensions</span>
find <span class="nb">.</span> <span class="nt">-type</span> f <span class="nt">-exec</span> zsh <span class="nt">-c</span> <span class="s1">'printf "%s\n" "${1:r}"'</span> <span class="nb">.</span> <span class="s1">'{}'</span> <span class="s1">';'</span>
</code></pre></div></div>

<p>It’s tempting and common to place <code class="language-plaintext highlighter-rouge">{}</code> directly into the argument passed to <code class="language-plaintext highlighter-rouge">zsh -c</code>, like this:</p>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># DON'T DO THIS!</span>
find <span class="nb">.</span> <span class="nt">-type</span> f <span class="nt">-exec</span> zsh <span class="nt">-c</span> <span class="s1">'printf "%s\n" "{}"'</span> <span class="s1">';'</span>
</code></pre></div></div>

<p>This will cause problems for filenames that contain special characters like <code class="language-plaintext highlighter-rouge">"</code>, because <code class="language-plaintext highlighter-rouge">find</code> (and many other programs) won’t escape them. How could it? It doesn’t know what escaping strategy to use, because it depends on the command you’re invoking. For example, we’re using zsh here, but if you were writing inline Python code you’d need to escape the string following Python rules instead of zsh.</p>

<p>By passing the argument to <code class="language-plaintext highlighter-rouge">zsh -c</code> instead, you can use <code class="language-plaintext highlighter-rouge">$1</code> in zsh as a variable with all the safety that comes along with that. You also get to use variable modifiers like <code class="language-plaintext highlighter-rouge">:r</code>.</p>

<p>Note also:</p>

<ul>
  <li>I passed <code class="language-plaintext highlighter-rouge">.</code> to act as the <code class="language-plaintext highlighter-rouge">$0</code> argument to the command-line script. I’m not using the value of it in the script, but I need to pass it so that the filename is passed as <code class="language-plaintext highlighter-rouge">$1</code>.</li>
  <li>I used <code class="language-plaintext highlighter-rouge">printf</code> instead of <code class="language-plaintext highlighter-rouge">echo</code> because <code class="language-plaintext highlighter-rouge">echo</code> will try to handle filenames like <code class="language-plaintext highlighter-rouge">-n</code> as an argument.</li>
</ul>

<h1 id="globbing-flags-and-qualifiers">Globbing flags and qualifiers</h1>

<p>I find the <a href="https://zsh.sourceforge.io/Doc/Release/Expansion.html#Filename-Generation">zsh documentation on filename generation</a> pretty hard to read, but here are some examples I use that might help:</p>

<h2 id="globbing-flags">Globbing flags</h2>

<p><a href="https://zsh.sourceforge.io/Doc/Release/Expansion.html#Globbing-Flags">Globbing flags</a> appear right before the part of the glob you want to apply them on. I usually apply them to the whole pattern so I put them right at the start.</p>

<p>These require <a href="https://zsh.sourceforge.io/Doc/Release/Options.html#Expansion-and-Globbing"><code class="language-plaintext highlighter-rouge">extended_glob</code> (see docs)</a> to be set.</p>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Match all .jpg files, matched case-insensitively (so it also includes</span>
<span class="c"># *.JPG, *.Jpg, etc.), like the option nocaseglob.</span>
setopt extended_glob
<span class="nb">echo</span> <span class="o">(</span><span class="c">#i)*.jpg</span>
</code></pre></div></div>

<h2 id="glob-qualifiers">Glob qualifiers</h2>

<p><a href="https://zsh.sourceforge.io/Doc/Release/Expansion.html#Glob-Qualifiers">Glob qualifiers</a> are suffixes that modify how the glob works.</p>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># List all jpg and gif files. No matches = no arguments.</span>
<span class="nb">echo</span> <span class="k">*</span>.jpg<span class="o">(</span>N<span class="o">)</span> <span class="k">*</span>.gif<span class="o">(</span>N<span class="o">)</span>
</code></pre></div></div>

<p>Adding <code class="language-plaintext highlighter-rouge">(N)</code> to a glob string makes it expand to no arguments if there are no matches (same as the <code class="language-plaintext highlighter-rouge">null_glob</code> option). Without this, you’ll typically either pass the raw argument <code class="language-plaintext highlighter-rouge">*.jpg(N)</code> if there are no matches, or zsh won’t run the command and will raise an error instead.</p>

<p>The exact default behaviour depends on the setting of options <code class="language-plaintext highlighter-rouge">null_glob</code>, <code class="language-plaintext highlighter-rouge">nomatch</code>, and <code class="language-plaintext highlighter-rouge">null_glob</code>.</p>

<h2 id="together">Together</h2>

<p>You can use them together:</p>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Match GIF, JPG, JPEG, HEIF, and AVIF extensions</span>
<span class="c"># with case-insensitive matching,</span>
<span class="c"># and run with no arguments if no files match.</span>
setopt extended_glob
<span class="nb">echo</span> <span class="s2">"Image files:"</span> <span class="o">(</span><span class="c">#i)*.(gif|jpe#g|heif|avif|png)(N)</span>
</code></pre></div></div>]]></content><author><name>Mike Burke</name></author><summary type="html"><![CDATA[I’ve been gradually writing more and more zsh-specific shell scripts. Zsh has some techniques that don’t get a lot of attention because they’re not available in bash, which most people are targeting for their scripts… but I have found many of these handy to know, particularly at the command line.]]></summary></entry><entry><title type="html">Bluetooth codec scripts for pulseaudio</title><link href="https://mrb0.com/2024/03/21/bluetooth-pulseaudio-scripts/" rel="alternate" type="text/html" title="Bluetooth codec scripts for pulseaudio" /><published>2024-03-21T19:58:19-03:00</published><updated>2024-03-21T19:58:19-03:00</updated><id>https://mrb0.com/2024/03/21/bluetooth-pulseaudio-scripts</id><content type="html" xml:base="https://mrb0.com/2024/03/21/bluetooth-pulseaudio-scripts/"><![CDATA[<p>I made <a href="https://github.com/mRB0/pulseaudio-bluetooth-codecs">some scripts</a> to help me see what codecs are supported by my Bluetooth audio devices, and select the one I want.</p>

<p>My devices were coming up with the sbc codec which is the most basic codec, but they support higher-bitrate codecs. Selection is a little clumsy on my headless, ssh-access-only Linux box that I’m playing audio from.</p>

<p>My devices support for example:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sbc: SBC
sbc_xq_453: SBC XQ 453kbps
sbc_xq_512: SBC XQ 512kbps
sbc_xq_552: SBC XQ 552kbps
</code></pre></div></div>

<p>I’m surprised my devices only support sbc codecs and not aac/mp3/whatever else. Actually, I don’t know what’s even typical! Do other operating systems use other codecs? I don’t know! Maybe I’ll try to find out what codecs these devices use on macOS or Windows someday.</p>

<p>It’s also possible I’m not seeing other options here because pulseaudio only supports sbc for Bluetooth. I have read that pipewire has better Bluetooth codec support, but I’m not currently willing to swap a working audio setup (pulseaudio) for one that might need tweaking (pipewire).</p>

<p><a href="https://github.com/mRB0/pulseaudio-bluetooth-codecs">The scripts are available on GitHub.</a></p>

<p><strong>Current mood:</strong> 😀 accomplished<br />
<strong>Current music:</strong> Big Wreck - Hey Mama</p>]]></content><author><name>Mike Burke</name></author><summary type="html"><![CDATA[I made some scripts to help me see what codecs are supported by my Bluetooth audio devices, and select the one I want.]]></summary></entry><entry><title type="html">My first 4K monitor, on Windows</title><link href="https://mrb0.com/2024/03/07/new-4k-monitor-on-windows/" rel="alternate" type="text/html" title="My first 4K monitor, on Windows" /><published>2024-03-07T15:58:19-04:00</published><updated>2024-03-07T15:58:19-04:00</updated><id>https://mrb0.com/2024/03/07/new-4k-monitor-on-windows</id><content type="html" xml:base="https://mrb0.com/2024/03/07/new-4k-monitor-on-windows/"><![CDATA[<p>I just got a pair of 4K monitors - one for a Mac Mini, and one for Windows.</p>

<p>The Mac is hooked up over HDMI and I use it purely for desktop applications. It works fine.</p>

<p>But on Windows, I’ve encountered a surprising number of issues.</p>

<h2 id="problem-1-no-display-during-boot">Problem 1: No display during boot</h2>

<p>I connected the monitor using DisplayPort because it seemed most appropriate to my video card, a GeForce GTX 960. It has 3 DisplayPort ports, and only one HDMI port; and I didn’t know if the HDMI port supported 4K at 60 Hz (it does), but I knew the DisplayPort ports would do it.</p>

<p>I swapped the monitor while the computer was on, and everything was fine… but when I rebooted, I had no display.</p>

<p><strong>FIX:</strong> It wasn’t super easy to find information about this but eventually I found a post that pointed me towards an <a href="https://www.nvidia.com/en-us/drivers/nv-uefi-update-x64/">NVIDIA firmware update tool for DisplayPort 1.3 and 1.4 displays</a> that fixes the issue:</p>

<blockquote>
  <p>Without the update, systems that are connected to a DisplayPort 1.3 / 1.4 monitor could experience blank screens on boot until the OS loads, or could experience a hang on boot.</p>
</blockquote>

<h2 id="problem-2-euro-truck-simulator-2-stuck-minimized">Problem 2: Euro Truck Simulator 2 stuck minimized</h2>

<p><strong>UPDATE:</strong> Fixed: My Epson scanner software includes a tray icon. If I kill the process, this problem goes away. I guess it’s stealing focus when the resolution &amp; scale change? Even though it isn’t actually showing a window? 🙄</p>

<p>My video card can’t handle 4K resolutions at a reasonable framerate, so I’m running games at 1080p. Also, I often stream games to my living room TV using Steam, and it’s a 1080p TV so it fits better.</p>

<p>When I launch Euro Truck Simulator 2, it immediately minimizes into the background, and any attempt to restore it brings it up for a brief moment but then it goes minimized again.</p>

<p>It doesn’t happen if one of the following is true:</p>

<ul>
  <li>ETS2 is run at the desktop resolution—but at 4K it takes a severe framerate hit… or</li>
  <li>Windows display scale is set to 100%—but at 27” 4K, 150% is far more usable. This is the workaround I’m using but I wish I didn’t have to!</li>
</ul>

<p>I don’t know if this is an ETS2 problem specifically, or a Windows problem. I assume other games will be affected too, but I’ve only tried Cities: Skylines and it has no such issue. ETS2 actually changes the desktop resolution for fullscreen, while Cities: Skylines uses a borderless mode that leaves the desktop resolution unchanged; this might explain the difference.</p>

<h2 id="problem-3-1080p-not-pixel-perfect">Problem 3: 1080p not pixel perfect</h2>

<p>A 4K monitor can theoretically upscale 1080p using pixel doubling, where each 1080p pixel is displayed with four 4k pixels (doubled in both X and Y axes). I want this because it looks clear and perfect, as though I’m using a 1080p monitor…</p>

<p>… but my particular monitor (LG 27UL550-W) doesn’t do this - it performs smoothing/interpolation of some sort on the upscale, and as a result it looks blurry.</p>

<p>I feel that my GPU drivers should be able to render at 1080p but output at 4K, but if it can I haven’t found out how.</p>

<p><strong>UPDATE:</strong> <a href="https://www.nvidia.com/content/Control-Panel-Help/vLatest/en-us/mergedProjects/nvdsp/CS_Display_Scaling.htm">Integer scaling is available in the NVIDIA control panel for Turing-architecture GPUs</a> (GeForce 16xx, GeForce 20xx and up). I have a 960 so outta luck!!</p>

<h2 id="problem-4-displayport-disconnects-when-monitor-off">Problem 4: DisplayPort disconnects when monitor off</h2>

<p>When I turn off the monitor, the computer sees that as a disconnected display. This is a well-known hotplug detection feature.</p>

<p>This isn’t really a problem when I’m sitting in front of it, but I like to stream games from the computer to my living room TV.</p>

<p>When I do that, I want to turn off the locally-attached display. If I do, then games basically don’t work - they see no display connected and aren’t able to select a display resolution because there’s no display to switch on. So streaming just doesn’t work at all.</p>

<p>Even if I’m not streaming, I prefer to have direct control over the power of my display, instead of having to use the display sleep timer to shut it off.</p>

<p><strong>WORKAROUND:</strong> Use HDMI, but long-term I’m probably just gonna have to live with this problem because I understand some features require DisplayPort, like FreeSync. Some monitors have an option to turn off while appearing connected to the computer, but mine doesn’t!</p>

<h2 id="other-thoughts">Other thoughts</h2>

<p>These are all small-ish problems. Some of them have workarounds or whatever, but like, they’re all surprising issues that I feel shouldn’t happen at all. And I’ve only had the monitor for one day!</p>

<h2 id="hardware">Hardware</h2>

<ul>
  <li>MSI NVIDIA GeForce GTX 960</li>
  <li>MSI Z270-A Pro motherboard</li>
  <li>Windows 10 up-to-date</li>
  <li>NVIDIA drivers up-to-date</li>
</ul>

<p>My old monitor is a 2560x1440 panel connected over dual-link DVI. It exhibited none of the above problems, but I used it at 100% scale, at native resolution, and without DisplayPort.</p>]]></content><author><name>Mike Burke</name></author><summary type="html"><![CDATA[I just got a pair of 4K monitors - one for a Mac Mini, and one for Windows. The Mac is hooked up over HDMI and I use it purely for desktop applications. It works fine. But on Windows, I've encountered a surprising number of issues.]]></summary></entry><entry><title type="html">Un-mangling some mangled unicode</title><link href="https://mrb0.com/2023/08/27/unmangling-unicode/" rel="alternate" type="text/html" title="Un-mangling some mangled unicode" /><published>2023-08-27T13:56:26-03:00</published><updated>2023-08-27T13:56:26-03:00</updated><id>https://mrb0.com/2023/08/27/unmangling-unicode</id><content type="html" xml:base="https://mrb0.com/2023/08/27/unmangling-unicode/"><![CDATA[<p>Recently I got some data from an external source that I’m to review and correct prior to use. One of the things I’ve been addressing is weird Unicode encoding stuff.</p>

<p>For example:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="sa">b</span><span class="sh">'</span><span class="s">O</span><span class="se">\xc3\x82\xc2\x80\xc2\x99</span><span class="s">SAMPLA</span><span class="sh">'</span>
</code></pre></div></div>

<p>Clearly this is supposed to have an apostrophe <code class="language-plaintext highlighter-rouge">’</code>, but how on earth did it get turned into <code class="language-plaintext highlighter-rouge">\xc3\x82\xc2\x80\xc2\x99</code>?</p>

<p>After poking at it with different coding systems for a while, I finally figured it out:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Mangle input
</span><span class="p">(</span><span class="sh">'</span><span class="s">’</span><span class="sh">'</span>
    <span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="sh">'</span><span class="s">utf-8</span><span class="sh">'</span><span class="p">)</span>    <span class="c1"># b'\xe2\x80\x99'
</span>    <span class="p">.</span><span class="nf">decode</span><span class="p">(</span><span class="sh">'</span><span class="s">latin-1</span><span class="sh">'</span><span class="p">)</span>  <span class="c1"># 'â\x80\x99'
</span>    <span class="p">.</span><span class="nf">upper</span><span class="p">()</span>            <span class="c1"># 'Â\x80\x99'
</span>    <span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="sh">'</span><span class="s">utf-8</span><span class="sh">'</span><span class="p">)</span>    <span class="c1"># b'\xc3\x82\xc2\x80\xc2\x99'
</span><span class="p">)</span>
</code></pre></div></div>

<p>I’ve never seen mangled Unicode get passed through <code class="language-plaintext highlighter-rouge">.upper()</code> before. I wasn’t around to see this data get created in the first place, but my guess is something like this happened:</p>

<ol>
  <li>Software A accepted the input <code class="language-plaintext highlighter-rouge">O’SAMPLA</code></li>
  <li>Software A exported the data using UTF-8 encoding</li>
  <li>Software B imported the data but incorrectly interpreted it using Latin-1 encoding</li>
  <li>Software B uppercased the data (typical for this software)</li>
  <li>Software B exported the data using UTF-8 encoding</li>
</ol>

<p>Here’s the reverse, to restore the original data:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Fix mangled input
</span><span class="p">(</span><span class="sa">b</span><span class="sh">'</span><span class="s">O</span><span class="se">\xc3\x82\xc2\x80\xc2\x99</span><span class="s">SAMPLA</span><span class="sh">'</span>
    <span class="p">.</span><span class="nf">decode</span><span class="p">(</span><span class="sh">'</span><span class="s">utf-8</span><span class="sh">'</span><span class="p">)</span>    <span class="c1"># 'OÂ\x80\x99SAMPLA'
</span>    <span class="p">.</span><span class="nf">lower</span><span class="p">()</span>            <span class="c1"># 'oâ\x80\x99sampla'
</span>    <span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="sh">'</span><span class="s">latin-1</span><span class="sh">'</span><span class="p">)</span>  <span class="c1"># b'o\xe2\x80\x99sampla'
</span>    <span class="p">.</span><span class="nf">decode</span><span class="p">(</span><span class="sh">'</span><span class="s">utf-8</span><span class="sh">'</span><span class="p">)</span>    <span class="c1"># 'o’sampla'
</span>    <span class="p">.</span><span class="nf">upper</span><span class="p">()</span>            <span class="c1"># 'O’SAMPLA'
</span><span class="p">)</span>
</code></pre></div></div>

<p>This works for this particular input because <code class="language-plaintext highlighter-rouge">Â</code> needs to become <code class="language-plaintext highlighter-rouge">â</code> before the latin-1/utf-8 interpretation steps, but I don’t consider it appropriate to assume this will work for all inputs. Some inputs may not have been affected at all by <code class="language-plaintext highlighter-rouge">upper()</code>, and it would be incorrect to apply <code class="language-plaintext highlighter-rouge">lower()</code> to them.</p>

<p>Unfortunately I can’t predict with total confidence whether applying <code class="language-plaintext highlighter-rouge">lower()</code> is appropriate for each input, so this data is gonna require manual review.</p>]]></content><author><name>Mike Burke</name></author><summary type="html"><![CDATA[Recently I got some data from an external source that I’m to review and correct prior to use. One of the things I’ve been addressing is weird Unicode encoding stuff.]]></summary></entry><entry><title type="html">Hurdles to making a multitasking environment on the NES</title><link href="https://mrb0.com/2023/08/23/hurdles-to-multitasking-on-the-nes/" rel="alternate" type="text/html" title="Hurdles to making a multitasking environment on the NES" /><published>2023-08-23T18:35:32-03:00</published><updated>2023-08-23T18:35:32-03:00</updated><id>https://mrb0.com/2023/08/23/hurdles-to-multitasking-on-the-nes</id><content type="html" xml:base="https://mrb0.com/2023/08/23/hurdles-to-multitasking-on-the-nes/"><![CDATA[<p>I’ve been thinking about what would be required to make a multitasking environment/platform on the NES.</p>

<p>Requirements:</p>

<ul>
  <li>Can load applications on-demand as independent processes</li>
  <li>Can launch multiple instances of each application</li>
  <li>Uses cooperative multitasking</li>
</ul>

<p>Realistically you’ll want the cartridge to have some RAM and allow bank switching for both RAM and ROM in order to increase the memory &amp; storage available to programs.</p>

<ul>
  <li>The 6502 has a single stack that’s fixed to live from $100 to $1ff. This is mapped to console RAM and can’t be bank-switched. Each process wants its own stack, so they’ll either have to share this very limited space, or you’ll have to swap the contents of the stack when switching tasks.
    <ul>
      <li>Compared to x86, where you can update SS to any segment &amp; SP to any location within the segment.</li>
    </ul>
  </li>
  <li>Similarly, process memory stored in system RAM will need to be swapped out on task switch. Memory located above $4020 could be bank-switched instead.</li>
  <li>Accessing data in different banks is desirable so we can jump to code in a currently-unloaded bank, or simply access data from one.
    <ul>
      <li>We can add code to perform this work and store it in a fixed bank that’s always available, and make the compiler use that instead of a plain JSR.</li>
      <li>Pointers will need to include bank information as well.</li>
      <li>Compared to x86, where you can jump to a different segment directly without losing access to the caller’s segment.</li>
    </ul>
  </li>
  <li>Graphics/PPU state also needs to be associated with each process.
    <ul>
      <li>It’s probably easiest to give the active process the full screen, instead of allowing background processes to share the display (eg. overlapping/tiled windows). The CHR ROM (or other video data) for a background application probably needs to get swapped out for the active process so it won’t be available to show properly, and there are challenges around sharing the current palette.
        <ul>
          <li>It might be possible to switch banks/contexts between scanlines, which could require windows to be screen-width but let them successfully stack vertically.</li>
        </ul>
      </li>
      <li>A system menu UI could be handled using code &amp; data in reserved always-available banks, like the code we use to handle moves and jumps across banks.</li>
    </ul>
  </li>
</ul>]]></content><author><name>Mike Burke</name></author><summary type="html"><![CDATA[I’ve been thinking about what would be required to make a multitasking environment/platform on the NES.]]></summary></entry><entry><title type="html">Using setjmp/longjmp from JNA</title><link href="https://mrb0.com/2023/08/13/setjmp-longjmp-and-fflush-in-java-jna/" rel="alternate" type="text/html" title="Using setjmp/longjmp from JNA" /><published>2023-08-13T20:00:00-03:00</published><updated>2023-08-13T20:00:00-03:00</updated><id>https://mrb0.com/2023/08/13/setjmp-longjmp-and-fflush-in-java-jna</id><content type="html" xml:base="https://mrb0.com/2023/08/13/setjmp-longjmp-and-fflush-in-java-jna/"><![CDATA[<p>TLDR: I didn’t think it would work, and it didn’t.</p>

<p>Today I had a goal to call an established C library from Java, but it uses <code class="language-plaintext highlighter-rouge">setjmp</code> and <code class="language-plaintext highlighter-rouge">longjmp</code> for error reporting.</p>

<p>I had been hoping/planning to use <a href="https://github.com/java-native-access/jna">Java Native Access</a> to interact with the libraries. This is just a simple hobby project, so I want to keep it as simple as I realistically can. That means I don’t want to add a C build step to my project at all, not to mention having the build target multiple OS platforms and CPU architectures.</p>

<p>But I didn’t really expect <code class="language-plaintext highlighter-rouge">setjmp</code> and <code class="language-plaintext highlighter-rouge">longjmp</code> to work in Java. I have no idea what the JVM does with the execution environment and I expected <code class="language-plaintext highlighter-rouge">longjmp</code> would interfere with it in a way that would very probably corrupt the JVM’s state.</p>

<p>I tried it anyway. It didn’t work. The program crashed with SIGABRT after <code class="language-plaintext highlighter-rouge">longjmp</code> (running on Linux).</p>

<hr />

<p>I encountered some things I found a little more interesting than just “it doesn’t work”, though:</p>

<h2 id="jmp_bufs-size-isnt-predictable">jmp_buf’s size isn’t predictable</h2>

<p><code class="language-plaintext highlighter-rouge">setjmp</code> requires that you allocate a <code class="language-plaintext highlighter-rouge">jmp_buf</code> to store the environment in.</p>

<p><code class="language-plaintext highlighter-rouge">jmp_buf</code> is defined in the system <code class="language-plaintext highlighter-rouge">setjmp.h</code>. On my 64-bit Linux system, <code class="language-plaintext highlighter-rouge">sizeof(jmp_buf) == 200</code>, and it’s defined as a 1-element array containing a struct, so it can be allocated easily then passed by reference.</p>

<p>I dug into <code class="language-plaintext highlighter-rouge">setjmp.h</code> first to understand it more, and realized the size of <code class="language-plaintext highlighter-rouge">jmp_buf</code> isn’t really predictable:</p>

<ol>
  <li>It varies by architecture even with the same C library, and</li>
  <li>It’s not specified by the standard that it even has to be a struct or anything. It could just be a handle or whatever.</li>
</ol>

<h2 id="setjmp-could-be-a-macro">setjmp could be a macro</h2>

<p>The standard doesn’t specify whether <code class="language-plaintext highlighter-rouge">setjmp</code> is a function or macro. JNA can only call functions, since macros are inlined by the compiler at build time.</p>

<p>(I didn’t check how it’s implemented in other C libraries, like MSVCRT on Windows or libSystem on macOS.)</p>

<hr />

<p>Not exactly related, but I also happened to call <code class="language-plaintext highlighter-rouge">fflush(stdout)</code> from Java. It turns out that <code class="language-plaintext highlighter-rouge">stdout</code> is actually specified in C89/C99 to be a macro. In glibc, it’s also exported as <code class="language-plaintext highlighter-rouge">extern FILE *stdout</code> so I was able to use that, but then my code would not conform to standard.</p>

<hr />

<p>I guess I’m gonna have to write a C adapter library that’s more Java-friendly.</p>]]></content><author><name>Mike Burke</name></author><summary type="html"><![CDATA[TLDR: I didn’t think it would work, and it didn’t.]]></summary></entry><entry><title type="html">ChatGPT does canvas</title><link href="https://mrb0.com/2023/07/30/chatgpt-does-canvas/" rel="alternate" type="text/html" title="ChatGPT does canvas" /><published>2023-07-30T17:06:00-03:00</published><updated>2023-07-30T17:06:00-03:00</updated><id>https://mrb0.com/2023/07/30/chatgpt-does-canvas</id><content type="html" xml:base="https://mrb0.com/2023/07/30/chatgpt-does-canvas/"><![CDATA[<p>I asked ChatGPT to draw a bunch of things using a Javascript canvas. I created a <a href="/chatgpt-canvas/">gallery of the results</a>.</p>

<a href="/chatgpt-canvas/"><img
  width="650"
  height="371"
  src="/a/2023-07-30/2023-07-30-chatgpt-canvas-open-gallery-1x.png"
  srcset="/a/2023-07-30/2023-07-30-chatgpt-canvas-open-gallery-1x.png 1x,
          /a/2023-07-30/2023-07-30-chatgpt-canvas-open-gallery-2x.png 2x"
  alt="Link to ChatGPT canvas gallery"
></a>]]></content><author><name>Mike Burke</name></author><summary type="html"><![CDATA[I asked ChatGPT to draw a bunch of things using a Javascript canvas. I created a gallery of the results.]]></summary></entry><entry><title type="html">Jet Grind Radio Dreamcast VMU animation</title><link href="https://mrb0.com/2020/02/12/jet-set-or-grind-radio-vmu-animation/" rel="alternate" type="text/html" title="Jet Grind Radio Dreamcast VMU animation" /><published>2020-02-12T16:29:00-04:00</published><updated>2020-02-12T16:29:00-04:00</updated><id>https://mrb0.com/2020/02/12/jet-set-or-grind-radio-vmu-animation</id><content type="html" xml:base="https://mrb0.com/2020/02/12/jet-set-or-grind-radio-vmu-animation/"><![CDATA[<canvas id="canvas" width="300" height="400"></canvas>

<script src="/a/2020-02-12/jsr-vmu.js"></script>]]></content><author><name>Mike Burke</name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Smooth scrolling inside caves on Dragon Warrior for the NES</title><link href="https://mrb0.com/2020/01/30/smooth-scrolling-inside-caves-on-dragon-warrior/" rel="alternate" type="text/html" title="Smooth scrolling inside caves on Dragon Warrior for the NES" /><published>2020-01-30T13:01:00-04:00</published><updated>2020-01-30T13:01:00-04:00</updated><id>https://mrb0.com/2020/01/30/smooth-scrolling-inside-caves-on-dragon-warrior</id><content type="html" xml:base="https://mrb0.com/2020/01/30/smooth-scrolling-inside-caves-on-dragon-warrior/"><![CDATA[<p>Lately I’ve been wondering if it’s possible to achieve smooth scrolling in Dragon Warrior on the NES.</p>

<p>This post describes the problem and a possible solution. I haven’t tried this solution, but based on my understanding of the NES’s PPU (picture processing unit), I think it could work. At least, maybe it’ll inspire someone to try it or to propose different techniques.</p>

<h1 id="background">Background</h1>

<p>In Dragon Warrior, scrolling is smooth in totally-exposed areas, which means all areas outside of caves. On the NES, this is achieved by using a method typical of the NES: by updating the <a href="http://wiki.nesdev.com/w/index.php/PPU_scrolling">PPU’s scroll registers</a> and updating the tiles just outside the visible screen area while scrolling. I’m not going to explain PPU mirroring and scrolling; there are explanations of the topic like <a href="https://www.youtube.com/watch?v=wfrNnwJrujw">Retro Game Mechanics Explained’s great video on the topic</a>.</p>

<p>Dragon Warrior uses <a href="https://wiki.nesdev.com/w/index.php/Mirroring">vertical mirroring</a>, which means that the video memory can support two whole screens wide and tiles can be updated off-screen while moving horizontally; but the tiles being updated on the top and bottom of the screen are visible during a vertical scroll. This is hidden by most TVs (and emulators!) because it’s outside the physically visible screen area, due to <a href="https://en.wikipedia.org/wiki/Overscan">overscan</a>.</p>

<video autoplay="" loop="" muted="" playsinline="">
    <source src="/a/2020-01-30/vertical-scrolling-artifacts.webm" type="video/webm" />
    <source src="/a/2020-01-30/vertical-scrolling-artifacts.mp4" type="video/mp4" />
    <img src="/a/2020-01-30/vertical-scrolling-artifacts.gif" alt="Clip of tiles updating on the top and bottom of the screen." />
</video>

<p>In caves, Dragon Warrior doesn’t scroll smoothly at all. This is caused by two conflicting factors:</p>

<ul>
  <li>To hide the tiles being updated as they change or become visible/invisible, they need to be on the screen edges.</li>
  <li>In caves, you can only see the area immediately surrounding you, which varies from a 1x1-tile area (no lighting) to a 7x7-tile area (RADIANT spell). This doesn’t reach the edges of the screen.</li>
</ul>

<p>As a result, stepping by one “Dragon Warrior” tile in a cave only has two frames of animation: One stepping halfway (one 8x8 character) and then one to step the next half.</p>

<video autoplay="" loop="" muted="" playsinline="">
    <source src="/a/2020-01-30/cave-movement-with-radiant.webm" type="video/webm" />
    <source src="/a/2020-01-30/cave-movement-with-radiant.mp4" type="video/mp4" />
    <img src="/a/2020-01-30/cave-movement-with-radiant.gif" alt="Clip of cave movement." />
</video>

<p>Aside: While viewing the name table in <a href="http://www.fceux.com/web/home.html">FCEUX</a> I observed that the X scroll position alternates between 32 ⯈ 0 ⯈ 32 during a cave step:</p>

<ol>
  <li>X scroll = 32 (at idle)</li>
  <li>Update all the tiles for the half-step in the off-screen nametable at X = 0</li>
  <li>Set X scroll to 0</li>
  <li>Update all the tiles for the full step in the off-screen nametable at X = 32</li>
  <li>Set X scroll to 32</li>
</ol>

<video autoplay="" loop="" muted="" playsinline="">
    <source src="/a/2020-01-30/nametable.webm" type="video/webm" />
    <source src="/a/2020-01-30/nametable.mp4" type="video/mp4" />
    <img src="/a/2020-01-30/nametable.gif" alt="Clip of name table viewer showing half and full steps in a cave." />
</video>

<h1 id="the-problem">The problem</h1>

<p>This feels sluggish and disorienting, especially when you’re only using a torch or have no light at all. In fact, the brick floor is only an 8x8 repeating pattern, and since a half-tile step moves by 8 pixels at a time, you can’t tell if you’re moving at all. Pressing in a direction isn’t a reliable way to move because move inputs only seem to register on certain frames, so depending on when you press a direction and for how long, you might turn &amp; move, or just turn.</p>

<p><img src="/a/2020-01-30/cave-movement-no-light.gif" alt="Clip of cave movement with no light." /></p>

<p>Most players would be using a torch or the RADIANT spell, so they can orient themselves using the walls visible around them. But speedrunners, especially those playing <a href="https://github.com/mcgrew/dwrandomizer">Dragon Warrior randomizer</a>, are more likely to lack or avoid using torches or RADIANT, and they’re familiar enough with the cave layouts that they don’t need to see where they are in them. However, they still need to know whether or not their inputs registered as movements.</p>

<p>In a situation like this, players typically bonk against walls to orient themselves, which plays a sound effect. But sometimes you need to make a turn before reaching a wall, so the problem isn’t solved for all cases.</p>

<h1 id="proposed-solution">Proposed solution</h1>

<p>I think it’s possible to use the NES’s smooth scrolling in caves, while still keeping a limited visible area.</p>

<p>The process is essentially the same as full-screen smooth scrolling, but instead of updating characters that are just off the edges of the screen, we’ll update them right outside of the player’s lit area, and try to hide them so that the result looks clean.</p>

<p>This is a little different for horizontal and vertical scrolling because of the PPU’s limitations.</p>

<h2 id="horizontal-scrolling">Horizontal scrolling</h2>

<p>This process uses black sprites on the left and right of the lit area to cover our tiles while they’re updated. This is a pretty common technique for full-screen horizontal scrolling, where the left edge of the screen is masked using a PPU feature that does precisely that; and the right edge is covered by sprites.</p>

<p>When the player moves left or right:</p>

<ol>
  <li>Place a column of black sprites just outside the left and right of the lit area. These will cover the characters as they’re being updated.</li>
  <li>Place the new set of characters on the side that’s coming into view – eg. on the right when the player moves right. They’ll be obscured by the column of black sprites on that side.</li>
  <li>Update the X scroll as usual during a horizontal scroll. The outgoing side will also be covered by a column of black sprites that we added in step 1.</li>
  <li>Remove the characters and the sprites.</li>
</ol>

<p>Since the hero is typically the only sprite visible while in caves, sprite limitations are unlikely to be a problem. The only other example I can think of is that the princess is probably also a sprite in the swamp cave. The Dragonlord at the bottom of Charlock is also a sprite, but that area isn’t dark; it’s a full-screen fully-visible area.</p>

<h2 id="vertical-scrolling">Vertical scrolling</h2>

<p>This is the same process as horizontal scrolling, but we can’t use sprites to obscure the characters being updated, because there’s a limit of 8 sprites per scanline. However, it’s possible to <a href="http://wiki.nesdev.com/w/index.php/PPU_scrolling#Split_X_scroll">update the X scroll position between scanlines</a>, which games often use to achieve a status bar that stays in position instead of scrolling with the rest of the screen. We’re going to use that to display an empty part of the nametable for the areas where we’re updating the characters during a scroll.</p>

<p>First, we need to ensure that the nametable is empty (all black characters) at Xscroll + 32, so that when we swap over to it, we won’t show anything. This only needs to be done when entering the cave, because we will never have any reason to draw anything in that space while doing other cave stuff.</p>

<p>Then, during a vertical move, we need to do this on every frame:</p>

<ol>
  <li>Increment X scroll by 32 so that we’re showing the empty area.</li>
  <li>Update the Y scroll to keep a smooth scroll.</li>
  <li>After drawing the last empty scanline, increment X scroll by 32 again so it wraps around and starts showing our tiles.</li>
  <li>Allow it to draw the entire lit area.</li>
  <li>After the last lit scanline is drawn, increment X scroll by 32 again so that we show the empty area again.</li>
  <li>At the end of the frame, increment X scroll by 32 again to return it back to the visible area. This is where we want to stay while idle, and during a movement we can repeat this process. As an optimization, we can skip this step and step 1 if the next frame is a continuation of the vertical scroll, because they cancel each other out.</li>
</ol>

<p>As with horizontal scrolling, we’ll need to update the incoming and outgoing tiles during the scroll, but this is also as usual during a vertical scroll; we’re just doing it near the lit area rather than at the screen edges.</p>

<p>Split scrolling can cause some artifacting/jitter as the scroll position might not get updated before the next scanline starts to be drawn, but since we have just empty black space at the start of each scanline, I don’t think the artifacting will even be visible.</p>

<h1 id="possible-issues-and-limitations">Possible issues and limitations</h1>

<h2 id="visible-updates-during-scroll">Visible updates during scroll</h2>

<p>Although I think this process will work, I haven’t actually tested it. My primary concern is that we don’t have enough time to update the incoming characters before we need to show them. I think it would be unacceptable to delay a tile movement to update those characters before the animation, because this would make continuous movement (eg. holding right for 2+ tile movements) jittery as it would need to pause on each tile.</p>

<p>I’m also not sure if we would leak palette changes into the lit area during scroll.</p>

<h2 id="ui-interference">UI interference</h2>

<p>It’s possible that this solution would interfere with the UI and battle view, but I don’t think it will because none of those can happen during a scroll, and when the hero’s position is aligned with the tile we don’t need to do any work to scroll at all.</p>

<h2 id="mitigating-these-issues">Mitigating these issues</h2>

<p>In existing full-screen scroll implementations, games ensure that the characters immediately off-screen are ready for the next scroll. If we did that, we’d need to maintain the X scroll split and the “hiding” sprites at all times. I think this would solve the problem with having enough time to update characters before the scroll, because we can update them during the scroll instead – just like games already do for full-screen scrolling.</p>

<p>This would definitely cause interference with the UI. To mitigate that, it might be acceptable to clear all of our scroll machinery (our hiding sprites and pre-drawn characters) when we need to show UI, and restore it when the UI disappears. This would probably add some delay to UI appearance and removal, but I think that would be acceptable as the UI isn’t particularly quick to begin with.</p>

<h1 id="terms-used-in-this-post">Terms used in this post</h1>

<ul>
  <li><a href="http://wiki.nesdev.com/w/index.php/PPU">PPU</a>: The NES’s picture processing unit that manages video memory, the nametable, scrolling, and everything else connected to the display.</li>
  <li>Player: The player of the game.</li>
  <li>Hero: The hero sprite that the player controls.</li>
  <li>Character: A PPU character, which is a single 8x8-pixel entry in the <a href="http://wiki.nesdev.com/w/index.php/PPU_nametables">PPU’s nametable</a>.</li>
  <li>Tile: A “Dragon Warrior” tile, a 16x16-pixel background tile composed of four 8x8-pixel nametable characters arranged in a 2x2 fashion. This is a common arrangement on the NES because even though characters are 8x8, color palettes apply only to a 16x16-pixel space.</li>
  <li>Lit area: The visible tiles in the cave. The area varies from 1x1 to 7x7 depending on whether the player is using the RADIANT spell (which gradually decays from 7x7 to 1x1), a torch (3x3 decaying to 1x1), or neither (1x1).</li>
</ul>]]></content><author><name>Mike Burke</name></author><summary type="html"><![CDATA[Lately I’ve been wondering if it’s possible to achieve smooth scrolling in Dragon Warrior on the NES.]]></summary></entry><entry><title type="html">Updated Jekyll</title><link href="https://mrb0.com/2020/01/22/updated-jekyll/" rel="alternate" type="text/html" title="Updated Jekyll" /><published>2020-01-22T14:46:00-04:00</published><updated>2020-01-22T14:46:00-04:00</updated><id>https://mrb0.com/2020/01/22/updated-jekyll</id><content type="html" xml:base="https://mrb0.com/2020/01/22/updated-jekyll/"><![CDATA[<p>Today I updated <a href="https://jekyllrb.com/">Jekyll</a>, which I use for this site, and fixed some problems with URLs that had affected this site ever since I created it at the start of 2016.</p>

<p>I switched from the <a href="http://jekyllthemes.org/themes/blackdoc/">BlackDoc</a> theme to <a href="https://github.com/pages-themes/midnight">Midnight</a> with some customizations (mostly, simplified). I’m not especially experienced with HTML or CSS/SCSS so I limited myself to simple changes only.</p>

<p>I think the URL problems were caused by some bad assumptions in some layout files; possibly assumptions I had made, I’m not sure. The result was that the RSS and Atom feeds had URLs with too many slashes, such as <code class="language-plaintext highlighter-rouge">https://mrb0.com///</code>. This was caused by two things in my <code class="language-plaintext highlighter-rouge">_config.yml</code>:</p>

<ol>
  <li><code class="language-plaintext highlighter-rouge">url</code> was <code class="language-plaintext highlighter-rouge">https://mrb0.com/</code> with a trailing slash that I’ve removed.</li>
  <li><code class="language-plaintext highlighter-rouge">baseurl</code> was <code class="language-plaintext highlighter-rouge">/</code>, but should be <code class="language-plaintext highlighter-rouge">""</code>.</li>
</ol>

<p>However, when I fixed both of those things, only pages in the root of the URL were properly-styled, because the layout files used <code class="language-plaintext highlighter-rouge">baseurl</code> to reference the CSS resources (and probably others); eg. <code class="language-plaintext highlighter-rouge">&lt;link href="style.css"&gt;</code>, which now resolves to <code class="language-plaintext highlighter-rouge">style.css</code> instead of <code class="language-plaintext highlighter-rouge">/style.css</code>.</p>

<p>Ultimately, I decided to switch to the Midnight theme after seeing <a href="https://speveril.github.io/">Shamus Peveril</a> use it on his new site.</p>

<p>There are still a few style tweaks I’d like to make, but I’m happy with the site so far. Syntax highlighting works in code blocks; I’m not sure it did before. I’m not sure I ever tested it!</p>]]></content><author><name>Mike Burke</name></author><summary type="html"><![CDATA[Today I updated Jekyll, which I use for this site, and fixed some problems with URLs that had affected this site ever since I created it at the start of 2016.]]></summary></entry></feed>