<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title></title>
    <link href="https://dwarfdreams.com/atom.xml" rel="self" type="application/atom+xml"/>
    <link href="https://dwarfdreams.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2023-10-09T00:00:00+00:00</updated>
    <id>https://dwarfdreams.com/atom.xml</id>
    <entry xml:lang="en">
        <title>Attempting to crack NIST curve seeds</title>
        <published>2023-10-09T00:00:00+00:00</published>
        <updated>2023-10-09T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="https://dwarfdreams.com/nist/" type="text/html"/>
        <id>https://dwarfdreams.com/nist/</id>
        
        <content type="html">&lt;p&gt;Nothing game related this time, just a little distraction.&lt;&#x2F;p&gt;
&lt;p&gt;A few days ago I came across the page &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;words.filippo.io&#x2F;dispatches&#x2F;seeds-bounty&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The challenge is to figure out the phrase that Jerry Solinas used to help derive some NIST curve seeds.
I put together a quick little attempt in Rust.  I didn&#x27;t find shit, but the code is &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;0xDEADFED5&#x2F;curve_cracker&quot;&gt;here&lt;&#x2F;a&gt; if anyone wants to try their luck.&lt;&#x2F;p&gt;
&lt;p&gt;Tt&#x27;s not the fastest thing in the world (55 million&#x2F;sec vs hashcat&#x27;s 150 million&#x2F;sec on my machine), but it calculates the hashes a lot faster than I can come up with sane guesses, so there&#x27;s that.&lt;&#x2F;p&gt;
&lt;p&gt;code:&lt;&#x2F;p&gt;
&lt;p&gt;change MAX_THREADS to match your hardware.
change MUT_LEN if you modify number of string mutations.
change STRING_VARIATIONS when you change the string templates (that&#x27;s the whole point, right?)&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;use std::{fs::{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;}, io::{BufReader, BufRead}, sync::atomic::{AtomicBool, Ordering, AtomicU64}, time, env};
&lt;&#x2F;span&gt;&lt;span&gt;use std::io::prelude::*;
&lt;&#x2F;span&gt;&lt;span&gt;use std::fs::OpenOptions;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;macro_use&lt;&#x2F;span&gt;&lt;span&gt;(concat_string)]
&lt;&#x2F;span&gt;&lt;span&gt;extern crate concat_string;
&lt;&#x2F;span&gt;&lt;span&gt;use sha1::{Sha1, Digest, digest::{generic_array::GenericArray, typenum::&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;U20&lt;&#x2F;span&gt;&lt;span&gt;}};
&lt;&#x2F;span&gt;&lt;span&gt;use arrayvec::ArrayString;
&lt;&#x2F;span&gt;&lt;span&gt;use std::thread;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; max string length, adjust as needed
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LEN&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; largest number to append to strings
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX_COUNT&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;i16 &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;3333&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; adjust as needed, 3 minimum because i&amp;#39;m lazy
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX_THREADS&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;ABOOL&lt;&#x2F;span&gt;&lt;span&gt;: AtomicBool = AtomicBool::new(false);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;AZERO&lt;&#x2F;span&gt;&lt;span&gt;: AtomicU64 = AtomicU64::new(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;static mut &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;FINISHED&lt;&#x2F;span&gt;&lt;span&gt;: [AtomicBool; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX_THREADS &lt;&#x2F;span&gt;&lt;span&gt;- &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;] = [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;ABOOL&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX_THREADS &lt;&#x2F;span&gt;&lt;span&gt;- &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;static mut &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;TOTAL&lt;&#x2F;span&gt;&lt;span&gt;: [AtomicU64; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX_THREADS &lt;&#x2F;span&gt;&lt;span&gt;- &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;] = [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;AZERO&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX_THREADS &lt;&#x2F;span&gt;&lt;span&gt;- &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;check_result&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;GenericArray&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;,U20&amp;gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;nist&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;[[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;;20];NIST_LEN]) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; found = false;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; h in nist {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;20 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; h[x] == input[x]
&lt;&#x2F;span&gt;&lt;span&gt;            {
&lt;&#x2F;span&gt;&lt;span&gt;                found = true;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                found = false;
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; found {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    found
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; this has to match max number of strings generated in mutate_string() below
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;mutate_string&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;counter&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;i16&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;output&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; [ArrayString&amp;lt;LEN&amp;gt;;MUT_LEN * STRING_VARIATIONS], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;index&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; example: Jerry and Satan deserve a raise666.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; counter != -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; ascii numbers
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; count = counter.to_string();
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; tmp = concat_string!(input, count);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_lowercase();
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_uppercase();
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; i don&amp;#39;t like this one
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; tmp = concat_string!(input, count, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_lowercase();
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_uppercase();
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; tmp = concat_string!(input, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, count);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_lowercase();
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_uppercase();
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; tmp = concat_string!(input, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, count);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_lowercase();
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_uppercase();
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; binary numbers
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; bin = counter.to_le_bytes();
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; sbin = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{ core::str::from_utf8_unchecked(&amp;amp;bin) };
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; tmp = concat_string!(input, sbin);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_lowercase();
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_uppercase();
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; still don&amp;#39;t like this one
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; tmp = concat_string!(input, sbin, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_lowercase();
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_uppercase();
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; tmp = concat_string!(input, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, sbin);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_lowercase();
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_uppercase();
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; tmp = concat_string!(input, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, sbin);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_lowercase();
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_uppercase();
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; -1 means don&amp;#39;t append a counter
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; example: Jerry and Satan deserve a raise.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;input);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;input);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_lowercase();
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;input);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_uppercase();
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; tmp = concat_string!(input, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_lowercase();
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_uppercase();
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; tmp = concat_string!(input, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_lowercase();
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;].push_str(&amp;amp;tmp);
&lt;&#x2F;span&gt;&lt;span&gt;        output[index * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;].make_ascii_uppercase();
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; has to match the number of string variations in get_strings() below
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;STRING_VARIATIONS&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;get_strings&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;counter&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;i16&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;output&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; [ArrayString&amp;lt;LEN&amp;gt;;MUT_LEN * STRING_VARIATIONS]) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; index = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = concat_string!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Jerry and &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, name, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; deserve a raise&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;); &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; 1
&lt;&#x2F;span&gt;&lt;span&gt;    mutate_string(&amp;amp;s, counter, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; output, index);
&lt;&#x2F;span&gt;&lt;span&gt;    index += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = concat_string!(name, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; and Jerry deserve a raise&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;); &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; 2
&lt;&#x2F;span&gt;&lt;span&gt;    mutate_string(&amp;amp;s, counter, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; output, index);
&lt;&#x2F;span&gt;&lt;span&gt;    index += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Jerry deserves a raise&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; 3
&lt;&#x2F;span&gt;&lt;span&gt;    mutate_string(&amp;amp;s, counter, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; output, index);
&lt;&#x2F;span&gt;&lt;span&gt;    index += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Jerry deserves a break&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; 4
&lt;&#x2F;span&gt;&lt;span&gt;    mutate_string(&amp;amp;s, counter, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; output, index);
&lt;&#x2F;span&gt;&lt;span&gt;    index += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Jerry needs a coffee&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; 5
&lt;&#x2F;span&gt;&lt;span&gt;    mutate_string(&amp;amp;s, counter, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; output, index);
&lt;&#x2F;span&gt;&lt;span&gt;    index += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = concat_string!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Jerry and &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, name, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; deserve raises&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;); &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; 6
&lt;&#x2F;span&gt;&lt;span&gt;    mutate_string(&amp;amp;s, counter, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; output, index);
&lt;&#x2F;span&gt;&lt;span&gt;    index += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = concat_string!(name, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; and Jerry deserve raises&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;); &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; 7
&lt;&#x2F;span&gt;&lt;span&gt;    mutate_string(&amp;amp;s, counter, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; output, index);
&lt;&#x2F;span&gt;&lt;span&gt;    index += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = concat_string!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Jerry and &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, name, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; deserve promotions&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;); &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; 8
&lt;&#x2F;span&gt;&lt;span&gt;    mutate_string(&amp;amp;s, counter, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; output, index);
&lt;&#x2F;span&gt;&lt;span&gt;    index += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = concat_string!(name, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; and Jerry deserve promotions&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;); &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; 9
&lt;&#x2F;span&gt;&lt;span&gt;    mutate_string(&amp;amp;s, counter, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; output, index);
&lt;&#x2F;span&gt;&lt;span&gt;    index += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = concat_string!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Jerry and &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, name, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; deserve a promotion&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;); &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; 10
&lt;&#x2F;span&gt;&lt;span&gt;    mutate_string(&amp;amp;s, counter, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; output, index);
&lt;&#x2F;span&gt;&lt;span&gt;    index += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = concat_string!(name, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; and Jerry deserve a promotion&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;); &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; 11
&lt;&#x2F;span&gt;&lt;span&gt;    mutate_string(&amp;amp;s, counter, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; output, index);
&lt;&#x2F;span&gt;&lt;span&gt;    index += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = concat_string!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Give Jerry and &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, name, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; a raise&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;); &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; 12
&lt;&#x2F;span&gt;&lt;span&gt;    mutate_string(&amp;amp;s, counter, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; output, index);
&lt;&#x2F;span&gt;&lt;span&gt;    index += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = concat_string!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Give &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, name, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; and Jerry a raise&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;); &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; 13
&lt;&#x2F;span&gt;&lt;span&gt;    mutate_string(&amp;amp;s, counter, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; output, index);
&lt;&#x2F;span&gt;&lt;span&gt;    index += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = concat_string!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Give &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, name, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; and Jerry raises&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;); &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; 14
&lt;&#x2F;span&gt;&lt;span&gt;    mutate_string(&amp;amp;s, counter, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; output, index);
&lt;&#x2F;span&gt;&lt;span&gt;    index += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = concat_string!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Give Jerry and &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, name, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; raises&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;); &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; 15
&lt;&#x2F;span&gt;&lt;span&gt;    mutate_string(&amp;amp;s, counter, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; output, index);
&lt;&#x2F;span&gt;&lt;span&gt;    index += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Give Jerry a raise&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; 16
&lt;&#x2F;span&gt;&lt;span&gt;    mutate_string(&amp;amp;s, counter, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; output, index);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;log_found&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;path&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; f = OpenOptions::new()
&lt;&#x2F;span&gt;&lt;span&gt;        .write(true)
&lt;&#x2F;span&gt;&lt;span&gt;        .append(true)
&lt;&#x2F;span&gt;&lt;span&gt;        .create(true)
&lt;&#x2F;span&gt;&lt;span&gt;        .open(path)
&lt;&#x2F;span&gt;&lt;span&gt;        .unwrap();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; prints fucked up UTF-8 to console, saves actual bytes to log
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; might have to view log file with a hex editor
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;FOUND: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, String::from_utf8_lossy(msg));
&lt;&#x2F;span&gt;&lt;span&gt;    f.write(msg).expect(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;error writing file...&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    f.write(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;.as_bytes()).expect(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;error writing file...&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; update this if length of nist array below is modified
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;NIST_LEN&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;worker&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;id&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;names&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;[String], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;start&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;i16&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;end&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;i16&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; nist: [[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;NIST_LEN&lt;&#x2F;span&gt;&lt;span&gt;] = [
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;[1,125,225,238,87,121,14,202,36,38,70,93,194,152,145,244,32,50,251,70], &#x2F;&#x2F; Jerry and Satan deserve a raise&amp;#39;0x05&amp;#39;&amp;#39;0x0D&amp;#39;.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;[38,232,14,202,25,250,218,187,145,59,48,16,185,82,241,75,189,87,53,117], &#x2F;&#x2F; Jerry and Satan deserve a raise.3333
&lt;&#x2F;span&gt;&lt;span&gt;    [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;48&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;69&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;174&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;111&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;200&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;66&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;47&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;100&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;237&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;87&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;149&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;40&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;211&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;129&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;234&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;225&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;33&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;150&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;213&lt;&#x2F;span&gt;&lt;span&gt;], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; # NIST P-192, ANSI prime192v1
&lt;&#x2F;span&gt;&lt;span&gt;    [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;189&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;113&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;52&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;71&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;153&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;213&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;199&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;252&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;220&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;69&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;181&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;159&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;163&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;185&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;171&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;143&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;106&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;148&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;139&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;197&lt;&#x2F;span&gt;&lt;span&gt;], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; # NIST P-224
&lt;&#x2F;span&gt;&lt;span&gt;    [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;196&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;157&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;54&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;134&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;231&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;147&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;106&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;102&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;120&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;225&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;157&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;38&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;183&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;129&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;159&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;126&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;144&lt;&#x2F;span&gt;&lt;span&gt;], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; # NIST P-256, ANSI prime256v1
&lt;&#x2F;span&gt;&lt;span&gt;    [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;163&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;53&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;146&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;106&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;163&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;162&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;122&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;137&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;106&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;103&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;115&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;164&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;130&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;122&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;205&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;172&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;115&lt;&#x2F;span&gt;&lt;span&gt;], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; # NIST P-384
&lt;&#x2F;span&gt;&lt;span&gt;    [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;208&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;158&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;136&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;41&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;184&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;83&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;150&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;204&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;103&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;57&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;132&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;170&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;160&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;218&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;100&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;186&lt;&#x2F;span&gt;&lt;span&gt;], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; # NIST P-521
&lt;&#x2F;span&gt;&lt;span&gt;    ];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; output: [ArrayString&amp;lt;LEN&amp;gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;STRING_VARIATIONS&lt;&#x2F;span&gt;&lt;span&gt;] = [ArrayString::&amp;lt;LEN&amp;gt;::new();&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;STRING_VARIATIONS&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; digest;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; total = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; update_counter = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; n in names {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x in start..=end {
&lt;&#x2F;span&gt;&lt;span&gt;            get_strings(x, n, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; output);
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; y in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..output.len() {
&lt;&#x2F;span&gt;&lt;span&gt;                digest = Sha1::digest(output[y].as_bytes());
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;check_result(&amp;amp;digest, &amp;amp;nist) {
&lt;&#x2F;span&gt;&lt;span&gt;                   log_found(output[y].as_bytes(), log);
&lt;&#x2F;span&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;span&gt;                output[y].clear();
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; update infos every 100,000
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; update_counter &amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;100_000 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;TOTAL&lt;&#x2F;span&gt;&lt;span&gt;[id].store(total, Ordering::Relaxed) };
&lt;&#x2F;span&gt;&lt;span&gt;                update_counter = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            total += (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;STRING_VARIATIONS&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u64&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            update_counter += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;STRING_VARIATIONS&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        } 
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;TOTAL&lt;&#x2F;span&gt;&lt;span&gt;[id].store(total, Ordering::Release) };
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;FINISHED&lt;&#x2F;span&gt;&lt;span&gt;[id].store(true, Ordering::Release) };
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;get_total&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u64 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; result = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX_THREADS &lt;&#x2F;span&gt;&lt;span&gt;- &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{ result += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;TOTAL&lt;&#x2F;span&gt;&lt;span&gt;[x].load(Ordering::Relaxed); }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    result
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;threads_done&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; result = false;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX_THREADS &lt;&#x2F;span&gt;&lt;span&gt;- &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{ result = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;FINISHED&lt;&#x2F;span&gt;&lt;span&gt;[x].load(Ordering::Acquire); }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;!result {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    result
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;watcher&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;total_hashes&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u64&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; total;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; last_total: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u64 &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;loop &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        thread::sleep(time::Duration::from_secs(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;threads_done() {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        total = get_total();
&lt;&#x2F;span&gt;&lt;span&gt;        println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; hashes per second, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{:.0}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;% done&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, total - last_total, (total as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32 &lt;&#x2F;span&gt;&lt;span&gt;&#x2F; total_hashes as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;) * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;100.0&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;        last_total = total;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    total = get_total();
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Finished.\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; total hashes checked.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, total);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; args: Vec&amp;lt;_&amp;gt; = env::args().collect();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; args.len() != &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;&amp;amp;&amp;amp; args.len() != &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;3 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Usage: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; wordlist logfile(optional)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, args[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]);
&lt;&#x2F;span&gt;&lt;span&gt;        println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Matches are printed to console and saved to output.log by default&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;        println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Example: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; names.txt&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, args[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]);
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; log = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;output.log&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; args.len() == &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;3 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        log = &amp;amp;args[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; file = fs::File::open(&amp;amp;args[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]).unwrap();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; reader = BufReader::new(file);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; names: Vec&amp;lt;String&amp;gt; = vec![];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; line in reader.lines() {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if let &lt;&#x2F;span&gt;&lt;span&gt;Ok(l) = line {
&lt;&#x2F;span&gt;&lt;span&gt;            names.push(l);
&lt;&#x2F;span&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else if let &lt;&#x2F;span&gt;&lt;span&gt;Err(e) = line {
&lt;&#x2F;span&gt;&lt;span&gt;            println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;error reading wordlist: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, e.to_string());
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; names loaded from wordlist&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, names.len());
&lt;&#x2F;span&gt;&lt;span&gt;    println!{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;{} threads to be spun up...&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX_THREADS&lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; start: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;i16 &lt;&#x2F;span&gt;&lt;span&gt;= -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; assign each thread a number range
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; (thread id, start number, end number)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; thread_info: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;i16&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;i16&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; = vec![];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX_THREADS &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; c = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX_COUNT &lt;&#x2F;span&gt;&lt;span&gt;&#x2F; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX_THREADS &lt;&#x2F;span&gt;&lt;span&gt;- &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;i16&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; x == &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX_THREADS &lt;&#x2F;span&gt;&lt;span&gt;- &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            c = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX_COUNT &lt;&#x2F;span&gt;&lt;span&gt;- start;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        thread_info.push((x, start, start + c));
&lt;&#x2F;span&gt;&lt;span&gt;        start += c + &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; total_hashes = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MUT_LEN &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u64 &lt;&#x2F;span&gt;&lt;span&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;STRING_VARIATIONS &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u64 &lt;&#x2F;span&gt;&lt;span&gt;* (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX_COUNT &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u64 &lt;&#x2F;span&gt;&lt;span&gt;* names.len() as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u64&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    thread::scope(|&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;s&lt;&#x2F;span&gt;&lt;span&gt;| {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x in thread_info.iter() {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; x.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX_THREADS &lt;&#x2F;span&gt;&lt;span&gt;- &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; builder = thread::Builder::new();
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; res = builder.spawn_scoped(s, || watcher(total_hashes) );
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; res.is_err() {
&lt;&#x2F;span&gt;&lt;span&gt;                    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;error spinning up watcher: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, res.err().unwrap());
&lt;&#x2F;span&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; builder = thread::Builder::new();
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; res = builder.spawn_scoped(s, || worker(x.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &amp;amp;names, x.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, x.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, log) );
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; res.is_err() {
&lt;&#x2F;span&gt;&lt;span&gt;                    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;error spinning up worker: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, res.err().unwrap());
&lt;&#x2F;span&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    });
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rust crate for setting struct fields by string</title>
        <published>2023-09-09T00:00:00+00:00</published>
        <updated>2023-09-09T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="https://dwarfdreams.com/macro2/" type="text/html"/>
        <id>https://dwarfdreams.com/macro2/</id>
        
        <content type="html">&lt;p&gt;I just published a tiny little Rust crate.  It&#x27;s the third iteration of my macro for setting struct fields.&lt;&#x2F;p&gt;
&lt;p&gt;The crate is called &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;set_field&quot;&gt;set_field&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Example usage:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;use set_field::SetField;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;derive&lt;&#x2F;span&gt;&lt;span&gt;(SetField)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;struct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;Foo &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;: Option&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;c&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; t = Foo { a: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;777&lt;&#x2F;span&gt;&lt;span&gt;, b: None, c: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; return true on success:
&lt;&#x2F;span&gt;&lt;span&gt;	assert_eq!(t.set_field(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;888&lt;&#x2F;span&gt;&lt;span&gt;), true);
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; return true on success:
&lt;&#x2F;span&gt;&lt;span&gt;	assert_eq!(t.set_field(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, Some(true)), true);
&lt;&#x2F;span&gt;&lt;span&gt;	assert_eq!(t.a, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;888&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;	assert_eq!(t.b, Some(true));
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; return false on nonexistent field:
&lt;&#x2F;span&gt;&lt;span&gt;	assert_eq!(t.set_field(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;), false);
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; return false on wrong type:
&lt;&#x2F;span&gt;&lt;span&gt;	assert_eq!(t.set_field(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;), false);
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; won&amp;#39;t compile:
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; assert_eq!(t.set_field(&amp;quot;a&amp;quot;, 0.0), false);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;set_field returns true on success&lt;&#x2F;li&gt;
&lt;li&gt;set_field returns false if field doesn&#x27;t exist&lt;&#x2F;li&gt;
&lt;li&gt;set_field returns false if you attempt to set a field to the wrong type&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The SetField macro expands Foo into this: &lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;struct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;Foo &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;: Option&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;c&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;impl &lt;&#x2F;span&gt;&lt;span&gt;SetField&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;Foo &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;set_field&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;field&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; field {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;=&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.a = value;
&lt;&#x2F;span&gt;&lt;span&gt;                true
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;c&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;=&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.c = value;
&lt;&#x2F;span&gt;&lt;span&gt;                true
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            _ =&amp;gt; false,
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;impl &lt;&#x2F;span&gt;&lt;span&gt;SetField&amp;lt;Option&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt; for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;Foo &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;set_field&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;field&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span&gt;: Option&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; field {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;=&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.b = value;
&lt;&#x2F;span&gt;&lt;span&gt;                true
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            _ =&amp;gt; false,
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;dependencies:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;set_field_macro&quot;&gt;set_field_macro&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;syn&quot;&gt;syn&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;quote&quot;&gt;quote&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rust macro for matching on struct fields</title>
        <published>2023-08-20T00:00:00+00:00</published>
        <updated>2023-08-20T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="https://dwarfdreams.com/macros/" type="text/html"/>
        <id>https://dwarfdreams.com/macros/</id>
        
        <content type="html">&lt;p&gt;&lt;u&gt;&lt;strong&gt;updated: 2023-08-29&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;This was just a Rust macro_rules! macro example before.&lt;&#x2F;strong&gt;
&lt;strong&gt;I&#x27;ve since appended a proc_macro_derive example.&lt;&#x2F;strong&gt;&lt;&#x2F;u&gt;&lt;&#x2F;p&gt;
&lt;p&gt;OpenGL code has been mostly done, but I moved on to something else for now: Dwarf Fortress &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;dwarffortresswiki.org&#x2F;index.php&#x2F;Raw_file&quot;&gt;RAWs&lt;&#x2F;a&gt;.
There are around 220 text files for configuring Dwarf Fortress.  There&#x27;s a lot there, it&#x27;s the soul of DF, and it&#x27;s in the public domain. Fuck yah!&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been working on a parser for the raw files, and it finally forced me to learn Rust &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;book&#x2F;ch19-06-macros.html&quot;&gt;macros&lt;&#x2F;a&gt;.
Here&#x27;s a quick post where I&#x27;m going to step thru a macro I just made line by line, because the internet needs more Rust macro examples.  Even if it doesn&#x27;t, too late.&lt;&#x2F;p&gt;
&lt;p&gt;First, the problem I wanted to solve.  I have a giant struct that looks like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;set_token! {
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;cfg_attr&lt;&#x2F;span&gt;&lt;span&gt;(feature = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;serde&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;derive&lt;&#x2F;span&gt;&lt;span&gt;(Serialize, Deserialize))]
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;derive&lt;&#x2F;span&gt;&lt;span&gt;(Default, PartialEq)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub struct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;material_tokens &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;IMPLIES_ANIMAL_KILL&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ALCOHOL_PLANT&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ALCOHOL_CREATURE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;CHEESE_PLANT&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;CHEESE_CREATURE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;POWDER_MISC_PLANT&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;POWDER_MISC_CREATURE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;STOCKPILE_GLOB&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;STOCKPILE_GLOB_PASTE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;STOCKPILE_GLOB_PRESSED&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;STOCKPILE_PLANT_GROWTH&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;LIQUID_MISC_PLANT&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;LIQUID_MISC_CREATURE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;LIQUID_MISC_OTHER&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;STRUCTURAL_PLANT_MAT&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;SEED_MAT&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;BONE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;WOOD&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;THREAD_PLANT&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;TOOTH&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;HORN&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;HAIR&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;PEARL&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;SHELL&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;LEATHER&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;SILK&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;SOAP&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;GENERATES_MIASMA&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;MEAT&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ROTS&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;BLOOD_MAP_DESCRIPTOR&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ICHOR_MAP_DESCRIPTOR&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;GOO_MAP_DESCRIPTOR&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;SLIME_MAP_DESCRIPTOR&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;PUS_MAP_DESCRIPTOR&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;SWEAT_MAP_DESCRIPTOR&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;TEARS_MAP_DESCRIPTOR&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;SPIT_MAP_DESCRIPTOR&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;EVAPORATES&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ENTERS_BLOOD&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;EDIBLE_VERMIN&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;EDIBLE_RAW&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;EDIBLE_COOKED&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;DO_NOT_CLEAN_GLOB&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;NO_STONE_STOCKPILE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ITEMS_METAL&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ITEMS_BARRED&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ITEMS_SCALED&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ITEMS_LEATHER&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ITEMS_SOFT&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ITEMS_HARD&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;IS_STONE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;UNDIGGABLE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;DISPLAY_UNGLAZED&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;YARN&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;STOCKPILE_THREAD_METAL&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;IS_METAL&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;IS_GLASS&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;CRYSTAL_GLASSABLE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ITEMS_WEAPON&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ITEMS_WEAPON_RANGED&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ITEMS_ANVIL&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ITEMS_AMMO&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ITEMS_DIGGER&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ITEMS_ARMOR&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ITEMS_DELICATE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ITEMS_SIEGE_ENGINE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ITEMS_QUERN&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I&#x27;m going to have other big ass structs, too.  I want to add a function to that struct and others that will let me easily set any of those flags.
It&#x27;ll save me from writing many lines of code.&lt;&#x2F;p&gt;
&lt;p&gt;Instead of doing something like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; obj = material_template::default();
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; key {
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;IMPLIES_ANIMAL_KILL&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;=&amp;gt; { 
&lt;&#x2F;span&gt;&lt;span&gt;		obj.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MATERIAL_TOKENS&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;IMPLIES_ANIMAL_KILL &lt;&#x2F;span&gt;&lt;span&gt;= true; 
&lt;&#x2F;span&gt;&lt;span&gt;	}
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;ALCOHOL_PLANT&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;=&amp;gt; { 
&lt;&#x2F;span&gt;&lt;span&gt;		obj.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MATERIAL_TOKENS&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;ALCOHOL_PLANT &lt;&#x2F;span&gt;&lt;span&gt;= true; 
&lt;&#x2F;span&gt;&lt;span&gt;	}
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; etc.
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I would much rather do something like the following, and handle all those cases with a single call:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; obj = material_template::default();
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; success = obj.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MATERIAL_TOKENS&lt;&#x2F;span&gt;&lt;span&gt;.set_token(key);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Before I go through the macro I&#x27;d like to give credit for some of the inspiration to the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;bitflags&quot;&gt;bitflags&lt;&#x2F;a&gt; crate.  It would&#x27;ve taken me longer without using that code as an example.  I also used &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;veykril.github.io&#x2F;tlborm&#x2F;decl-macros&#x2F;macros-methodical.html&quot;&gt;The Little Book of Rust Macros&lt;&#x2F;a&gt;.
As you can see from the struct code above, the macro wraps around the entire struct.  That&#x27;s because I need access to each field and also need to know where the struct ends (so I can put the &lt;code&gt;impl&lt;&#x2F;code&gt; there).&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s my macro:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; modify struct to add set_token() for easily setting tokens&#x2F;errors
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;macro_export&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;macro_rules! &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;set_token &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    ($(#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;$outer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;meta&lt;&#x2F;span&gt;&lt;span&gt;])*
&lt;&#x2F;span&gt;&lt;span&gt;    $sv:vis struct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;$name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;ident&lt;&#x2F;span&gt;&lt;span&gt; {
&lt;&#x2F;span&gt;&lt;span&gt;        $($fv:vis &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;$field_name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;ident&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;$field_type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;ty&lt;&#x2F;span&gt;&lt;span&gt;,)*
&lt;&#x2F;span&gt;&lt;span&gt;    }) =&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;        $(#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;$outer&lt;&#x2F;span&gt;&lt;span&gt;])*
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;$sv &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;struct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;$name&lt;&#x2F;span&gt;&lt;span&gt; {
&lt;&#x2F;span&gt;&lt;span&gt;            $(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;$fv $field_name&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;$field_type&lt;&#x2F;span&gt;&lt;span&gt;,)*
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;impl $name &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span&gt; fn set_token(&amp;amp;mut self, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;token&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; {
&lt;&#x2F;span&gt;&lt;span&gt;                match token {
&lt;&#x2F;span&gt;&lt;span&gt;                    $(stringify!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;$field_name&lt;&#x2F;span&gt;&lt;span&gt;) =&amp;gt; { self.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;$field_name&lt;&#x2F;span&gt;&lt;span&gt; = true; true })*
&lt;&#x2F;span&gt;&lt;span&gt;                    _ =&amp;gt; { false }
&lt;&#x2F;span&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A macro is split into two parts: &lt;code&gt;($matcher) =&amp;gt; {$expansion}&lt;&#x2F;code&gt;.  There are 5 lines above with the &lt;code&gt;$(...)*&lt;&#x2F;code&gt; pattern: 2 in the matcher and 3 in the expansion section.  They will each match or expand 0 or more times.
The &lt;u&gt;only&lt;&#x2F;u&gt; lines which can repeat in the expansion above are the ones that follow that pattern.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;First line of matcher: &lt;code&gt;($(#[$outer:meta])*&lt;&#x2F;code&gt; matches any attributes.
&lt;code&gt;$outer&lt;&#x2F;code&gt; matches &lt;code&gt;cfg_attr(feature = &amp;quot;serde&amp;quot;, derive(Serialize, Deserialize))&lt;&#x2F;code&gt; and &lt;code&gt;derive(Default)&lt;&#x2F;code&gt; from the struct above.&lt;&#x2F;li&gt;
&lt;li&gt;On the next line &lt;code&gt;$sv:vis struct $name:ident {&lt;&#x2F;code&gt;,
&lt;code&gt;$sv&lt;&#x2F;code&gt; matches &lt;code&gt;pub&lt;&#x2F;code&gt; and &lt;code&gt;$name&lt;&#x2F;code&gt; matches &lt;code&gt;material_tokens&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Last line of matcher: &lt;code&gt;$($fv:vis $field_name:ident: $field_type:ty,)*&lt;&#x2F;code&gt; matches each field.
&lt;code&gt;$fv&lt;&#x2F;code&gt; for first match is &lt;code&gt;pub&lt;&#x2F;code&gt;, &lt;code&gt;$field_name&lt;&#x2F;code&gt; is &lt;code&gt;IMPLIES_ANIMAL_KILL&lt;&#x2F;code&gt;, and &lt;code&gt;$field_type&lt;&#x2F;code&gt; is &lt;code&gt;bool&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;First line of expansion: &lt;code&gt;$(#[$outer])*&lt;&#x2F;code&gt; expands back to the attributes from above, unchanged.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;$sv struct $name {&lt;&#x2F;code&gt; expands to &lt;code&gt;pub struct material_tokens {&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;$($fv $field_name: $field_type,)*&lt;&#x2F;code&gt; duplicates each field.
First iteration expands to &lt;code&gt;pub IMPLIES_ANIMAL_KILL: bool,&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;impl $name {&lt;&#x2F;code&gt; expands to &lt;code&gt;impl material_tokens {&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;$(stringify!($field_name) =&amp;gt; { self.$field_name = true; true })*&lt;&#x2F;code&gt; expands to the fields matched above.
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;macro.stringify.html&quot;&gt;stringify!&lt;&#x2F;a&gt; macro creates a &lt;code&gt;&amp;amp;str&lt;&#x2F;code&gt;.
First iteration expands to &lt;code&gt;&amp;quot;IMPLIES_ANIMAL_KILL&amp;quot; =&amp;gt; { self.IMPLIES_ANIMAL_KILL = true; true }&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Here&#x27;s what a snippet of the expanded struct looks like:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;&#x2F; Recursive expansion of set_token! macro
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; ========================================
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;cfg_attr&lt;&#x2F;span&gt;&lt;span&gt;(feature = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;serde&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;derive&lt;&#x2F;span&gt;&lt;span&gt;(Serialize, Deserialize))]
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;derive&lt;&#x2F;span&gt;&lt;span&gt;(Default, PartialEq)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub struct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;material_tokens &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;IMPLIES_ANIMAL_KILL&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ALCOHOL_PLANT&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; snip
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ITEMS_QUERN&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;impl &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;material_tokens &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;set_token&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;token&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; token {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;IMPLIES_ANIMAL_KILL&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;=&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;IMPLIES_ANIMAL_KILL &lt;&#x2F;span&gt;&lt;span&gt;= true;
&lt;&#x2F;span&gt;&lt;span&gt;                true
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;ALCOHOL_PLANT&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;=&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;ALCOHOL_PLANT &lt;&#x2F;span&gt;&lt;span&gt;= true;
&lt;&#x2F;span&gt;&lt;span&gt;                true
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; snip
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;ITEMS_QUERN&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;=&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;ITEMS_QUERN &lt;&#x2F;span&gt;&lt;span&gt;= true;
&lt;&#x2F;span&gt;&lt;span&gt;                true
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            _ =&amp;gt; false,
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I use Visual Studio Code for development, and the rust-analyzer plugin has a pretty decent macro expander.  It produced the output above. To use it right-click in the IDE and select &lt;code&gt;Command Palette...&lt;&#x2F;code&gt; or press &lt;code&gt;Ctrl+Shift+P&lt;&#x2F;code&gt;, start typing in &lt;code&gt;macro&lt;&#x2F;code&gt; and you should see a match for &lt;code&gt;rust-analyzer: Expand macro recursively&lt;&#x2F;code&gt;.
You can set a hotkey for it right there, too.&lt;&#x2F;p&gt;
&lt;p&gt;After my first test here&#x27;s the relevant output from my parser:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#151515;color:#e8e8d3;&quot;&gt;&lt;code&gt;&lt;span&gt;INFO  [dfraw_parse] material_template_ = ..&#x2F;vanilla\material_template_default.txt
&lt;&#x2F;span&gt;&lt;span&gt;INFO  [dfraw_parse::material_template] parsing started after line: 3
&lt;&#x2F;span&gt;&lt;span&gt;ERROR [example] errors found: 14
&lt;&#x2F;span&gt;&lt;span&gt;00001 line number: 448, unknown MATERIAL_TOKEN: &amp;#39;CARTILAGE&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;00002 line number: 539, unknown MATERIAL_TOKEN: &amp;#39;FEATHER&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;00003 line number: 584, unknown MATERIAL_TOKEN: &amp;#39;SCALE&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;00004 line number: 772, unknown MATERIAL_TOKEN: &amp;#39;NERVOUS_TISSUE&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;00005 line number: 1475, unknown MATERIAL_TOKEN: &amp;#39;HOOF&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;00006 line number: 1983, unknown MATERIAL_TOKEN: &amp;#39;CHITIN&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;00007 line number: 2484, unknown MATERIAL_TOKEN: &amp;#39;SYNDROME&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;00008 line number: 2488, unknown MATERIAL_TOKEN: &amp;#39;SYN_INGESTED&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;00009 line number: 2489, unknown MATERIAL_TOKEN: &amp;#39;SYN_INJECTED&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;00010 line number: 2490, unknown MATERIAL_TOKEN: &amp;#39;SYN_NO_HOSPITAL&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;00011 line number: 3014, unknown MATERIAL_TOKEN: &amp;#39;SYNDROME&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;00012 line number: 3018, unknown MATERIAL_TOKEN: &amp;#39;SYN_INGESTED&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;00013 line number: 3019, unknown MATERIAL_TOKEN: &amp;#39;SYN_INJECTED&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;00014 line number: 3020, unknown MATERIAL_TOKEN: &amp;#39;SYN_NO_HOSPITAL&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Looks like I missed a few materials, and now I need to parse syndromes.  I finally feel like I&#x27;m writing nearly proper Rust.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;added: 2023-08-29&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;same-macro-as-above-but-proc-macro-derive-type-instead&quot;&gt;Same macro as above, but proc_macro_derive type instead&lt;&#x2F;h1&gt;
&lt;p&gt;I used a macro_rules! above because it was the first macro type I learned.
However, I recently needed to make a custom derive macro, so I converted this macro at the same time.&lt;&#x2F;p&gt;
&lt;p&gt;I followed the guide &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;book&#x2F;ch19-06-macros.html#how-to-write-a-custom-derive-macro&quot;&gt;here&lt;&#x2F;a&gt; for the initial setup.
It involves creating a separate crate and using dependencies like the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;syn&quot;&gt;syn&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;quote&quot;&gt;quote&lt;&#x2F;a&gt; crates to help.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m not going to repeat a lot of stuff here, here&#x27;s the macro above as a proc_macro_derive:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;use proc_macro::TokenStream;
&lt;&#x2F;span&gt;&lt;span&gt;use quote::quote;
&lt;&#x2F;span&gt;&lt;span&gt;use syn::{Data, DeriveInput, Fields, Type};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; set bool fields on struct by string, return true on success
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;proc_macro_derive&lt;&#x2F;span&gt;&lt;span&gt;(SetToken)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;set_token_derive&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;: TokenStream) -&amp;gt; TokenStream {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; ast = syn::parse(input).unwrap();
&lt;&#x2F;span&gt;&lt;span&gt;    impl_set_token(&amp;amp;ast)
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;impl_set_token&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ast&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;DeriveInput) -&amp;gt; TokenStream {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; name = &amp;amp;ast.ident;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; matches = quote!();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match &lt;&#x2F;span&gt;&lt;span&gt;&amp;amp;ast.data {
&lt;&#x2F;span&gt;&lt;span&gt;        Data::Struct(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; data) =&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match &lt;&#x2F;span&gt;&lt;span&gt;&amp;amp;data.fields {
&lt;&#x2F;span&gt;&lt;span&gt;                Fields::Named(fields) =&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;                    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; f in &amp;amp;fields.named {
&lt;&#x2F;span&gt;&lt;span&gt;                        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match &lt;&#x2F;span&gt;&lt;span&gt;&amp;amp;f.ty {
&lt;&#x2F;span&gt;&lt;span&gt;                            Type::Path(p) =&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;                                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; p.path.segments.first() {
&lt;&#x2F;span&gt;&lt;span&gt;                                    Some(s) =&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;                                        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; s.ident.to_string().as_str() {
&lt;&#x2F;span&gt;&lt;span&gt;                                            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;=&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;                                                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match &lt;&#x2F;span&gt;&lt;span&gt;&amp;amp;f.ident {
&lt;&#x2F;span&gt;&lt;span&gt;                                                    Some(i) =&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;                                                        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = i.to_string();
&lt;&#x2F;span&gt;&lt;span&gt;                                                        matches.extend(quote!{
&lt;&#x2F;span&gt;&lt;span&gt;                                                                #s =&amp;gt; { 
&lt;&#x2F;span&gt;&lt;span&gt;                                                                    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.#i = true; 
&lt;&#x2F;span&gt;&lt;span&gt;                                                                    true
&lt;&#x2F;span&gt;&lt;span&gt;                                                                }
&lt;&#x2F;span&gt;&lt;span&gt;                                                        });
&lt;&#x2F;span&gt;&lt;span&gt;                                                    }
&lt;&#x2F;span&gt;&lt;span&gt;                                                    _ =&amp;gt; {}
&lt;&#x2F;span&gt;&lt;span&gt;                                                }
&lt;&#x2F;span&gt;&lt;span&gt;                                            }
&lt;&#x2F;span&gt;&lt;span&gt;                                            _ =&amp;gt; {}
&lt;&#x2F;span&gt;&lt;span&gt;                                        }
&lt;&#x2F;span&gt;&lt;span&gt;                                    }
&lt;&#x2F;span&gt;&lt;span&gt;                                    _=&amp;gt; {}
&lt;&#x2F;span&gt;&lt;span&gt;                                }
&lt;&#x2F;span&gt;&lt;span&gt;                            }
&lt;&#x2F;span&gt;&lt;span&gt;                            _ =&amp;gt; {}
&lt;&#x2F;span&gt;&lt;span&gt;                        }
&lt;&#x2F;span&gt;&lt;span&gt;                    }
&lt;&#x2F;span&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;span&gt;                _ =&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        _ =&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;            panic!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;struct only!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    };
&lt;&#x2F;span&gt;&lt;span&gt;    quote! {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;impl &lt;&#x2F;span&gt;&lt;span&gt;SetToken for #&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;name &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;set_token&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;token&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; token {
&lt;&#x2F;span&gt;&lt;span&gt;                    #matches
&lt;&#x2F;span&gt;&lt;span&gt;                    _ =&amp;gt; {  
&lt;&#x2F;span&gt;&lt;span&gt;                        false
&lt;&#x2F;span&gt;&lt;span&gt;                    }
&lt;&#x2F;span&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }.into()
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;SetToken trait:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub trait &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;SetToken &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;set_token&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;token&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Holy shit, I thought the first macro was painful to read.&lt;&#x2F;p&gt;
&lt;p&gt;The differences between this macro and the previous one:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;This macro only generates matches for &lt;code&gt;bool&lt;&#x2F;code&gt; struct fields.&lt;&#x2F;li&gt;
&lt;li&gt;Used with &lt;code&gt;#[derive(SetToken)]&lt;&#x2F;code&gt; attribute instead of using &lt;code&gt;!set_token&lt;&#x2F;code&gt; macro&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rendering Sprite Sheets in Rust</title>
        <published>2023-07-19T00:00:00+00:00</published>
        <updated>2023-07-19T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="https://dwarfdreams.com/spritesheets/" type="text/html"/>
        <id>https://dwarfdreams.com/spritesheets/</id>
        
        <content type="html">&lt;p&gt;I&#x27;ve made some progress learning OpenGL.  For tile locations on screen, I calculate all the vertex positions per tile (2 triangles per tile, 6 vertices per triangle = 12 vertices) and store them in a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Vertex_buffer_object&quot;&gt;vertex buffer object&lt;&#x2F;a&gt;.  I add the 0.0 Z coordinate in the shader, so that doesn&#x27;t need to be stored, at least.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s what the geometry looks like for a 1920x1200 display configured for 32x32 pixel tiles:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;spritesheets&#x2F;tile_geometry.avif&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;spritesheets&#x2F;tile_geometry.avif&quot; alt=&quot;tile_geometry&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Screenshot is from &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developer.nvidia.com&#x2F;nsight-graphics&quot;&gt;NVIDIA Nsight Graphics&lt;&#x2F;a&gt;, a pretty awesome tool for a beginner like me.  &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;renderdoc.org&#x2F;&quot;&gt;RenderDoc&lt;&#x2F;a&gt; is great, too, but Nsight Graphics was able to immediately tell me what was wrong with my render pipeline.  (Remember to bind the vertex array every draw call)&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s the code for calculating the tile vertices:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; tile = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;loop &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; verts = get_tex_vertices(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;512.0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;512.0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;32.0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;32.0&lt;&#x2F;span&gt;&lt;span&gt;, tile);        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;upper right        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices.push(xf + &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;32.0&lt;&#x2F;span&gt;&lt;span&gt;);        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices.push(yf + &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;32.0&lt;&#x2F;span&gt;&lt;span&gt;);        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;upper left        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices.push(xf);        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices.push(yf + &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;32.0&lt;&#x2F;span&gt;&lt;span&gt;);        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;lower left        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices.push(xf);        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices.push(yf);        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;upper right        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices.push(xf + &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;32.0&lt;&#x2F;span&gt;&lt;span&gt;);        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices.push(yf + &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;32.0&lt;&#x2F;span&gt;&lt;span&gt;);        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;lower left        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices.push(xf);        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices.push(yf);        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;lower right        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices.push(xf + &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;32.0&lt;&#x2F;span&gt;&lt;span&gt;);        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices.push(yf);        
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    uvs.extend_from_slice(&amp;amp;verts);        
&lt;&#x2F;span&gt;&lt;span&gt;    tile += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span&gt;;        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; tile &amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;255.0 &lt;&#x2F;span&gt;&lt;span&gt;{        
&lt;&#x2F;span&gt;&lt;span&gt;        tile = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;;        
&lt;&#x2F;span&gt;&lt;span&gt;    }        
&lt;&#x2F;span&gt;&lt;span&gt;    xf += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;32.0&lt;&#x2F;span&gt;&lt;span&gt;;        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; xf &amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1920.0 &lt;&#x2F;span&gt;&lt;span&gt;{        
&lt;&#x2F;span&gt;&lt;span&gt;        xf = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;;        
&lt;&#x2F;span&gt;&lt;span&gt;        yf += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;32.0&lt;&#x2F;span&gt;&lt;span&gt;;        
&lt;&#x2F;span&gt;&lt;span&gt;    }        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; yf &amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1200.0 &lt;&#x2F;span&gt;&lt;span&gt;{        
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;        
&lt;&#x2F;span&gt;&lt;span&gt;    }        
&lt;&#x2F;span&gt;&lt;span&gt;}                
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Screen resolution is temporarily hard coded so that I could check the geometry without running fullscreen.  Generally, the vertex shader wants vertices in &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;learnopengl.com&#x2F;Getting-started&#x2F;Coordinate-Systems&quot;&gt;normalized device coordinates&lt;&#x2F;a&gt; which range from -1.0,-1.0 to 1.0,1.0.  Right now I&#x27;m normalizing the coordinates in the shader like so:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;#version &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;330
&lt;&#x2F;span&gt;&lt;span&gt;layout (location = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;) in vec2 vert;
&lt;&#x2F;span&gt;&lt;span&gt;layout (location = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) in vec2 _uv;
&lt;&#x2F;span&gt;&lt;span&gt;out vec2 uv;
&lt;&#x2F;span&gt;&lt;span&gt;void main()
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    uv = _uv;
&lt;&#x2F;span&gt;&lt;span&gt;    gl_Position = vec4((vert.x &#x2F; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1920.0 &lt;&#x2F;span&gt;&lt;span&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2.0&lt;&#x2F;span&gt;&lt;span&gt;) - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span&gt;, (vert.y &#x2F; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1200.0 &lt;&#x2F;span&gt;&lt;span&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2.0&lt;&#x2F;span&gt;&lt;span&gt;) - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But when I rewrite my shaders in a moment I&#x27;ll just handle it on the CPU since I only need to calculate those vertices once.&lt;&#x2F;p&gt;
&lt;p&gt;Next I had to figure out how to access individual sprites in a sprite sheet (also called a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Texture_atlas&quot;&gt;texture atlas&lt;&#x2F;a&gt;).  I&#x27;m targeting 32x32 tile size, so I looked for an example to do testing with.  I found a cool tileset for Dwarf Fortress by &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;dffd.bay12games.com&#x2F;file.php?id=14072&quot;&gt;Vettlingr&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s the tileset:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;spritesheets&#x2F;vettlingr_32x32.png&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;spritesheets&#x2F;vettlingr_32x32.png&quot; alt=&quot;vettlingr_32x32&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note: I&#x27;m not planning on using these graphics officially, it&#x27;s just for demonstration purposes.&lt;&#x2F;p&gt;
&lt;p&gt;The image is 512x512 pixels.  Each tile is 32x32 pixels, which means there are 16x16 (or 256) tiles total. In the code above I call get_tex_vertices() to generate the texture coordinates for each tile.  Textures use &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;learnopengl.com&#x2F;Getting-started&#x2F;Textures&quot;&gt;yet another coordinate system&lt;&#x2F;a&gt; that ranges from 0.0,0.0 to 1.0,1.0.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s the code for calculating texture coordinates based on texture size, sprite size, and sprite index:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; tile index = 0 from left to right, top to bottom.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;get_tex_vertices&lt;&#x2F;span&gt;&lt;span&gt;(        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;sheet_w&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;,        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;sheet_h&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;,        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;tile_w&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;,        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;tile_h&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;,        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;tile_index&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;,        
&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;] {        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; vertices: [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;] = [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;];        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; cols = sheet_w &#x2F; tile_w;        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; x = tile_index % cols;        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; y = (tile_index &#x2F; cols).floor();        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;invert y by default        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;lower right        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w + tile_w) &#x2F; sheet_w;        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h) &#x2F; sheet_h;        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;lower left        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w) &#x2F; sheet_w;        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h) &#x2F; sheet_h;        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;upper left        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w) &#x2F; sheet_w;        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h + tile_h) &#x2F; sheet_h;        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;lower right        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w + tile_w) &#x2F; sheet_w;        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h) &#x2F; sheet_h;        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;upper left        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w) &#x2F; sheet_w;        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h + tile_h) &#x2F; sheet_h;        
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;upper right        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w + tile_w) &#x2F; sheet_w;        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h + tile_h) &#x2F; sheet_h;        
&lt;&#x2F;span&gt;&lt;span&gt;    vertices        
&lt;&#x2F;span&gt;&lt;span&gt;}        
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This code automatically inverts the y coordinates.  That&#x27;s because there are more coordinate systems fighting each other here.  Unless configured differently, drawing in OpenGL at the origin (0,0) usually means the &lt;em&gt;lower&lt;&#x2F;em&gt; left corner of the screen.  Many image formats have their 0,0 at the &lt;em&gt;upper&lt;&#x2F;em&gt; left of the screen.  Instead of rotating lots of image data around in memory, I&#x27;ll rotate the texture coordinates instead.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s the vertex geometry of the sprite sheet visualized:
&lt;a href=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;spritesheets&#x2F;sprite_geometry.avif&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;spritesheets&#x2F;sprite_geometry.avif&quot; alt=&quot;sprite_geometry&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I put together a few transforms for texture coordinates.  This lets me pre-calculate flipped, rotated, mirrored, etc. texture coordinates for animation later on.&lt;&#x2F;p&gt;
&lt;p&gt;Here are a few examples:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;transform_uvs&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;uvs&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;; 12],
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;sheet_w&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;sheet_h&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;tile_w&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;tile_h&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;tile_index&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;transform&lt;&#x2F;span&gt;&lt;span&gt;: Transforms,
&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; cols = sheet_w &#x2F; tile_w;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; transform == Transforms::FlipVertical {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; y = (tile_index &#x2F; cols).floor();
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; y_low = (y * tile_h) &#x2F; sheet_h;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; y_high = (y * tile_h + tile_h) &#x2F; sheet_h;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;flip &lt;&#x2F;span&gt;&lt;span&gt;= |&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;index&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;| {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; uvs[index] == y_low {
&lt;&#x2F;span&gt;&lt;span&gt;                uvs[index] = y_high;
&lt;&#x2F;span&gt;&lt;span&gt;            } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                uvs[index] = y_low;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;        };
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; odd vertices = y coordinates
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; i in (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;..=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;).step_by(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;            flip(i);
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; transform == Transforms::FlipHorizontal {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; x = tile_index % cols;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; x_low = (x * tile_w) &#x2F; sheet_w;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; x_high = (x * tile_w + tile_w) &#x2F; sheet_w;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;flip &lt;&#x2F;span&gt;&lt;span&gt;= |&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;index&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;| {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; uvs[index] == x_low {
&lt;&#x2F;span&gt;&lt;span&gt;                uvs[index] = x_high;
&lt;&#x2F;span&gt;&lt;span&gt;            } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                uvs[index] = x_low;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;        };
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;even vertices = x coordinates
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; i in (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;).step_by(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;            flip(i);
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; transform == Transforms::Rotate90Left {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; x = tile_index % cols;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; y = (tile_index &#x2F; cols).floor();
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w + tile_w) &#x2F; sheet_w;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h + tile_h) &#x2F; sheet_h;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w + tile_w) &#x2F; sheet_w;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h) &#x2F; sheet_h;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w) &#x2F; sheet_w;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h) &#x2F; sheet_h;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w + tile_w) &#x2F; sheet_w;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h + tile_h) &#x2F; sheet_h;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w) &#x2F; sheet_w;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h) &#x2F; sheet_h;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w) &#x2F; sheet_w;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h + tile_h) &#x2F; sheet_h;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; transform == Transforms::Rotate90LeftHMirror {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; x = tile_index % cols;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; y = (tile_index &#x2F; cols).floor();
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w + tile_w) &#x2F; sheet_w;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h) &#x2F; sheet_h;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w + tile_w) &#x2F; sheet_w;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h + tile_h) &#x2F; sheet_h;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w) &#x2F; sheet_w;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h + tile_h) &#x2F; sheet_h;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w + tile_w) &#x2F; sheet_w;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h) &#x2F; sheet_h;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w) &#x2F; sheet_w;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h + tile_h) &#x2F; sheet_h;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;] = (x * tile_w) &#x2F; sheet_w;
&lt;&#x2F;span&gt;&lt;span&gt;        uvs[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;] = (y * tile_h) &#x2F; sheet_h;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;} 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This math is specific to the coordinates I generated before.  It&#x27;s also specific for my vertex buffer layout.  It&#x27;s just there to give an idea on how to approach the problem for other people trying to learn how to 2d graphics in 2023 =)&lt;&#x2F;p&gt;
&lt;p&gt;Next post I&#x27;m going to finish the shaders, allowing me to update tile indexes on demand and render many layers.  I&#x27;m also going to add in palette support.  My near term goal is to import the Dwarf Fortress raws and basically duplicate the rendering system.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s one last picture showing my title screen with the Vettlingr tiles in the background:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;spritesheets&#x2F;title_screen.avif&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;spritesheets&#x2F;title_screen.avif&quot; alt=&quot;title_screen&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cross-platform GUI demo</title>
        <published>2023-07-08T00:00:00+00:00</published>
        <updated>2023-07-08T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="https://dwarfdreams.com/gui-demo/" type="text/html"/>
        <id>https://dwarfdreams.com/gui-demo/</id>
        
        <content type="html">&lt;p&gt;Lately I&#x27;ve been building my 2D tile rendering engine.  The current plan is for square tiles and each tile can be composed of 8 or more layers.  Also, I&#x27;ll do something similar to how the current Dwarf Fortress does it:  I&#x27;ll render a few Z levels below with increasing opacity.  I&#x27;ll add animation too, but overall it&#x27;s going to be as simple and straightforward as possible so that I can jump into the actual game logic ASAP.&lt;&#x2F;p&gt;
&lt;p&gt;My plan &lt;em&gt;was&lt;&#x2F;em&gt; to use &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.khronos.org&#x2F;opengl&#x2F;wiki&#x2F;Array_Texture&quot;&gt;array textures&lt;&#x2F;a&gt;, but since I&#x27;m targeting OpenGL 3.3, I&#x27;m only guaranteed GL_MAX_ARRAY_TEXTURE_LAYERS of 256 or more, so I guess I&#x27;ll stick to using a good old &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Texture_atlas&quot;&gt;texture atlas&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This is the first time I&#x27;ve done any graphics programming, so it&#x27;s a bit of a learning curve for me.  In the meantime I&#x27;ve made a little recording of my title screen mock-up.&lt;&#x2F;p&gt;
&lt;p&gt;YouTube video is located &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;Lchk3ICaSes?vq=hd1080&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s just a simple little proof of concept that uses &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;emilk&#x2F;egui&quot;&gt;egui&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;grovesNL&#x2F;glow&quot;&gt;glow&lt;&#x2F;a&gt;, and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-windowing&#x2F;winit&quot;&gt;winit&lt;&#x2F;a&gt; for cross-platform compatibility.&lt;&#x2F;p&gt;
&lt;p&gt;The background fragment shader is ported from &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.shadertoy.com&#x2F;view&#x2F;Xt2SRG&quot;&gt;this ShaderToy submission&lt;&#x2F;a&gt; to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;OpenGL_Shading_Language&quot;&gt;GLSL&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Background vertex shader:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;VERTEX_SHADER_SOURCE&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;str &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;#&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;#version 130
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;const vec2 coords[] = vec2[3] (
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;    vec2(-1., -1.),
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;    vec2(3., -1.),
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;    vec2(-1., 3.)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;void main()
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;{
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;    gl_Position = vec4(coords[gl_VertexID], 0., 1.);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;}
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;#&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The vertex shader source code is from &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;30fps.net&#x2F;pages&#x2F;twotris&#x2F;&quot;&gt;this page&lt;&#x2F;a&gt; about full screen triangle optimization, ported to GLSL.  &lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Terrain erosion part III</title>
        <published>2023-06-22T00:00:00+00:00</published>
        <updated>2023-06-22T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="https://dwarfdreams.com/terrain3/" type="text/html"/>
        <id>https://dwarfdreams.com/terrain3/</id>
        
        <content type="html">&lt;p&gt;Last part of my terrain erosion series.  Here are some example images showing a couple before and afters of my hydraulic erosion simulation.
Tested on a 8192x8192 game map, one pixel represents one tile.  These images show a small fraction of the smallest possible game map.&lt;&#x2F;p&gt;
&lt;p&gt;Before:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain3&#x2F;orig_terrain.avif&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain3&#x2F;orig_terrain.avif&quot; alt=&quot;orig_terrain&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;After:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain3&#x2F;eroded_terrain.avif&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain3&#x2F;eroded_terrain.avif&quot; alt=&quot;eroded_terrain&quot; &#x2F;&gt;&lt;&#x2F;a&gt;
(light blue to black colors represent water, grey to white represent mountains and snow)&lt;&#x2F;p&gt;
&lt;p&gt;Here are some more, but zoomed in further:&lt;&#x2F;p&gt;
&lt;p&gt;Before:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain3&#x2F;orig_terrain_zoom.avif&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain3&#x2F;orig_terrain_zoom.avif&quot; alt=&quot;orig_terrain_zoom&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;After:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain3&#x2F;eroded_terrain_zoom.avif&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain3&#x2F;eroded_terrain_zoom.avif&quot; alt=&quot;eroded_terrain_zoom&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;On my 8-core dev machine the erosion sim carved over 16,000 separate paths through the terrain in about 30 seconds.  There are already quite a few variables in place to allow tuning the process.  The image above roughly equates to medium density, medium intensity, and with maximum coverage (no map sections left out).  I can currently limit areas based on average elevation, and further along my worldgen process I&#x27;ll take into account precipitation levels for particular biomes.&lt;&#x2F;p&gt;
&lt;p&gt;Next up I&#x27;m going to start on OpenGL graphics and UI code so that I can plug in the beginnings of my worldgen code.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>I&#x27;m officially a citizen of The Republic of Slowjamastan!</title>
        <published>2023-06-20T00:00:00+00:00</published>
        <updated>2023-06-20T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="https://dwarfdreams.com/slowjamastan/" type="text/html"/>
        <id>https://dwarfdreams.com/slowjamastan/</id>
        
        <content type="html">&lt;p&gt;Today I am proud to announce that I am officially a citizen of the totally real nation of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.slowjamastan.org&#x2F;&quot;&gt;Slowjamastan&lt;&#x2F;a&gt;.
My Slowjamastani name is Urist McMiner.  Though my native country of Happyhardcoristan has traditionally had fraught relations with Slowjamastan, in the interests of peace, love, unity, and respect I dutifully submitted my application for citizenship.&lt;&#x2F;p&gt;
&lt;p&gt;Proof of my citizenship is recorded on the republic&#x27;s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.slowjamastan.org&#x2F;citizens-laws-misc&#x2F;&quot;&gt;website&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;slowjamastan&#x2F;proooooof.avif&quot; alt=&quot;proooooof&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;=)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Simple Coordinate Subdivision in Rust</title>
        <published>2023-06-20T00:00:00+00:00</published>
        <updated>2023-06-20T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="https://dwarfdreams.com/subdivision/" type="text/html"/>
        <id>https://dwarfdreams.com/subdivision/</id>
        
        <content type="html">&lt;p&gt;Just a quick little post about a simple topic.  I want to subdivide my square game map into X by X squares for various reasons...some current reasons, and some future reasons.&lt;&#x2F;p&gt;
&lt;p&gt;I want to more efficiently narrow down parts of the map to change for my erosion simulation.  It&#x27;s also something close to what I&#x27;ll need in the future because I plan on eventually dealing with my map in 256x256 tile chunks.  That&#x27;s a topic for the future though.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s the quick and dirty code:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub struct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;Section &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt;: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;impl &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;Section &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;with_width&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;width&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;Self &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;Self &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            from: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            to: (width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;subdivide&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;divisor&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; Vec&amp;lt;Section&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; retval: Vec&amp;lt;Section&amp;gt; = vec![];
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; width = (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.to.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;- &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.from.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;) + &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; divisor &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;|| width &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; retval;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; step = width &#x2F; divisor;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; x1 = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; y1 = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; x2 = step - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; y2 = step - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;while&lt;&#x2F;span&gt;&lt;span&gt; y2 &amp;lt; width {
&lt;&#x2F;span&gt;&lt;span&gt;            retval.push(Section {
&lt;&#x2F;span&gt;&lt;span&gt;                from: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.from.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;+ x1, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.from.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;+ y1),
&lt;&#x2F;span&gt;&lt;span&gt;                to: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.from.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;+ x2, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.from.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;+ y2),
&lt;&#x2F;span&gt;&lt;span&gt;            });
&lt;&#x2F;span&gt;&lt;span&gt;            x1 += step;
&lt;&#x2F;span&gt;&lt;span&gt;            x2 = x1 + step - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; x1 &amp;gt; width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                x1 = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;                x2 = step - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;                y1 += step;
&lt;&#x2F;span&gt;&lt;span&gt;                y2 = y1 + step - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        retval
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;One caveat: it&#x27;s only perfect if width modulo divisor == 0.  This is all I need though, so it&#x27;s all I wrote.  However, even if you use it on a width that doesn&#x27;t evenly divide, all the coordinates will still be valid, but a bit of the area will be left out. (at least (width % divisor) * width?)&lt;&#x2F;p&gt;
&lt;p&gt;With the following test code:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s = Section::with_width(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;99&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s2 = s.subdivide(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s3 = s2[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;].subdivide(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When I render each square in s2 with alternating colors it looks like this (11x11 squares, 9x9 pixels each):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;subdivision&#x2F;subdivided1.avif&quot; alt=&quot;subdivided1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When I render s3 it looks like this (the first of the previous squares further subdivided into 3x3 squares, 3x3 pixels each):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;subdivision&#x2F;subdivided2.avif&quot; alt=&quot;subdivided2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;(the grey on grey grid background is just my standard background for my test images, and these images are scaled up 4x)&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s pretty much it.  For the Section struct, from = the upper left corner of the square, to = the lower right corner of the square.  There&#x27;s no concept of pixels, tiles, etc. in this code...it&#x27;s just coordinates I can make squares with.&lt;&#x2F;p&gt;
&lt;p&gt;Cheers!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Tale of Two Bresenhams</title>
        <published>2023-06-16T00:00:00+00:00</published>
        <updated>2023-06-16T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="https://dwarfdreams.com/bresenham/" type="text/html"/>
        <id>https://dwarfdreams.com/bresenham/</id>
        
        <content type="html">&lt;h3 id=&quot;or-how-to-draw-thick-bresenham-lines-in-rust&quot;&gt;...or How To Draw Thick Bresenham Lines in Rust&lt;&#x2F;h3&gt;
&lt;p&gt;I decided last post to construct rivers basically using a bunch of circles.  One reason for that is because it would make it easy to have the middle of my rivers be deeper than the edges.  Another reason is because properly drawing thick lines has been frustrating me a bit lately and I was eager to just move on.  They were both pretty bad reasons.   Bad because the zillion circle idea turned out to be really slow (partly because I kept a ring buffer of previous tiles so I could avoid where my circles overlapped), and also bad because where&#x27;s the fun in being lazy and not figuring something out?&lt;&#x2F;p&gt;
&lt;p&gt;I tried lots of algorithms for thick lines.  Lots.  Some of them just didn&#x27;t work, possibly my fault.  Some of them were just plain wrong and the line ends weren&#x27;t perpendicular.  I suck at math, so it took me a bit to wrap my head around the problem.  At first, I&#x27;m thinking to myself:  A thick line is just a rectangle...all I need are a couple perpendicular lines to set the corners to, and fill in all the pixels one line at a time.  How hard can it be?&lt;&#x2F;p&gt;
&lt;p&gt;Every friggin&#x27; site on the internet says that to draw a perpendicular line, just invert the slope.  Problem solved!  (I mean, except for zero and infinity, but that&#x27;s easy because at that point we&#x27;re dealing with vertical or horizontal lines, and even &lt;em&gt;I&lt;&#x2F;em&gt; can add to X or add to Y to get a perpendicular point).  But alas, the internet lies.  Just blindly inverting a slope will give you a perpendicular slope only &lt;em&gt;some&lt;&#x2F;em&gt; of the time.&lt;&#x2F;p&gt;
&lt;p&gt;I finally found a promising link here: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ArminJo&#x2F;Arduino-BlueDisplay&#x2F;blob&#x2F;master&#x2F;src&#x2F;LocalGUI&#x2F;ThickLine.hpp&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;ArminJo&#x2F;Arduino-BlueDisplay&#x2F;blob&#x2F;master&#x2F;src&#x2F;LocalGUI&#x2F;ThickLine.hpp&lt;&#x2F;a&gt;.
At first I recoiled in horror at the camelCase variable names, the &lt;em&gt;same exact&lt;&#x2F;em&gt; way I hated Rust&#x27;s snake_case names at first.  Rust got this one right though.  I ended up making 3 different versions, all tailored for my specific use, which is why I&#x27;m not making (or contributing to) a crate.&lt;&#x2F;p&gt;
&lt;p&gt;get_thick_line_unchecked() will make a proper fat line, even if it overlaps canvas boundaries (which are still only square). I call it unchecked because if any parts of the line go out of bounds, there will be duplicate points.  get_thick_line() will also make a proper fat line, account for out of bounds, but also remove duplicates.  Option #3 is the scary one, and I&#x27;ll write about it in a bit.  Both of the unchecked versions will produce perfect lines with &lt;em&gt;zero&lt;&#x2F;em&gt; duplicates if no parts of the &lt;del&gt;line&lt;&#x2F;del&gt; rectangle go out of bounds.  Here&#x27;s the code for the first version:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; ported from https:&#x2F;&#x2F;github.com&#x2F;ArminJo&#x2F;Arduino-BlueDisplay&#x2F;blob&#x2F;master&#x2F;src&#x2F;LocalGUI&#x2F;ThickLine.hpp
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;get_thick_line_unchecked&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt;: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;line_width&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;thick_mode&lt;&#x2F;span&gt;&lt;span&gt;: ThicknessMode,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;map_width&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; line: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; = vec![];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; x1 = from.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; x2 = to.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; y1 = from.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; y2 = to.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; dx: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; dy: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; dx2: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; dy2: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; err: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; step_x: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; step_y: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; max_width = (map_width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; x1 &amp;gt; max_width {
&lt;&#x2F;span&gt;&lt;span&gt;        x1 = max_width;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; x2 &amp;gt; max_width {
&lt;&#x2F;span&gt;&lt;span&gt;        x2 = max_width;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; y1 &amp;gt; max_width {
&lt;&#x2F;span&gt;&lt;span&gt;        y1 = max_width;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; y2 &amp;gt; max_width {
&lt;&#x2F;span&gt;&lt;span&gt;        y2 = max_width;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; line_width &amp;lt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;get_line_overlap((x1, y1), (x2, y2), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_NONE&lt;&#x2F;span&gt;&lt;span&gt;, map_width);
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    dy = x2 - x1;
&lt;&#x2F;span&gt;&lt;span&gt;    dx = y2 - y1;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; swap = true;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; dx &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        dx = -dx;
&lt;&#x2F;span&gt;&lt;span&gt;        step_x = -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        swap = !swap;
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        step_x = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; dy &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        dy = -dy;
&lt;&#x2F;span&gt;&lt;span&gt;        step_y = -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        swap = !swap;
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        step_y = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    dx2 = dx &amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    dy2 = dy &amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; overlap: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; draw_start_adjust_count = line_width &#x2F; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; thick_mode == ThicknessMode::LineThicknessDrawCounterclockwise {
&lt;&#x2F;span&gt;&lt;span&gt;        draw_start_adjust_count = line_width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else if&lt;&#x2F;span&gt;&lt;span&gt; thick_mode == ThicknessMode::LineThicknessDrawClockwise {
&lt;&#x2F;span&gt;&lt;span&gt;        draw_start_adjust_count = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; dx &amp;gt;= dy {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; swap {
&lt;&#x2F;span&gt;&lt;span&gt;            draw_start_adjust_count = (line_width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) - draw_start_adjust_count;
&lt;&#x2F;span&gt;&lt;span&gt;            step_y = -step_y;
&lt;&#x2F;span&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            step_x = -step_x;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        err = dy2 - dx;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;_ in (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..draw_start_adjust_count).rev() {
&lt;&#x2F;span&gt;&lt;span&gt;            x1 -= step_x;
&lt;&#x2F;span&gt;&lt;span&gt;            x2 -= step_x;
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; err &amp;gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                y1 -= step_y;
&lt;&#x2F;span&gt;&lt;span&gt;                y2 -= step_y;
&lt;&#x2F;span&gt;&lt;span&gt;                err -= dx2;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            err += dy2;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        line.append(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span&gt;get_line_overlap(
&lt;&#x2F;span&gt;&lt;span&gt;            (x1, y1),
&lt;&#x2F;span&gt;&lt;span&gt;            (x2, y2),
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_NONE&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;            map_width,
&lt;&#x2F;span&gt;&lt;span&gt;        ));
&lt;&#x2F;span&gt;&lt;span&gt;        err = dy2 - dx;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;_ in (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;..line_width).rev() {
&lt;&#x2F;span&gt;&lt;span&gt;            x1 += step_x;
&lt;&#x2F;span&gt;&lt;span&gt;            x2 += step_x;
&lt;&#x2F;span&gt;&lt;span&gt;            overlap = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_NONE&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; err &amp;gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                y1 += step_y;
&lt;&#x2F;span&gt;&lt;span&gt;                y2 += step_y;
&lt;&#x2F;span&gt;&lt;span&gt;                err -= dx2;
&lt;&#x2F;span&gt;&lt;span&gt;                overlap = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_MAJOR&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            err += dy2;
&lt;&#x2F;span&gt;&lt;span&gt;            line.append(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span&gt;get_line_overlap(
&lt;&#x2F;span&gt;&lt;span&gt;                (x1, y1),
&lt;&#x2F;span&gt;&lt;span&gt;                (x2, y2),
&lt;&#x2F;span&gt;&lt;span&gt;                overlap,
&lt;&#x2F;span&gt;&lt;span&gt;                map_width,
&lt;&#x2F;span&gt;&lt;span&gt;            ))
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; swap {
&lt;&#x2F;span&gt;&lt;span&gt;            step_x = -step_x;
&lt;&#x2F;span&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            draw_start_adjust_count = (line_width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) - draw_start_adjust_count;
&lt;&#x2F;span&gt;&lt;span&gt;            step_y = -step_y;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        err = dx2 - dy;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;_ in (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..draw_start_adjust_count).rev() {
&lt;&#x2F;span&gt;&lt;span&gt;            y1 -= step_y;
&lt;&#x2F;span&gt;&lt;span&gt;            y2 -= step_y;
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; err &amp;gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                x1 -= step_x;
&lt;&#x2F;span&gt;&lt;span&gt;                x2 -= step_x;
&lt;&#x2F;span&gt;&lt;span&gt;                err -= dy2;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            err += dx2;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        line.append(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span&gt;get_line_overlap(
&lt;&#x2F;span&gt;&lt;span&gt;            (x1, y1),
&lt;&#x2F;span&gt;&lt;span&gt;            (x2, y2),
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_NONE&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;            map_width,
&lt;&#x2F;span&gt;&lt;span&gt;        ));
&lt;&#x2F;span&gt;&lt;span&gt;        err = dx2 - dy;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;_ in (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;..line_width).rev() {
&lt;&#x2F;span&gt;&lt;span&gt;            y1 += step_y;
&lt;&#x2F;span&gt;&lt;span&gt;            y2 += step_y;
&lt;&#x2F;span&gt;&lt;span&gt;            overlap = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_NONE&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; err &amp;gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                x1 += step_x;
&lt;&#x2F;span&gt;&lt;span&gt;                x2 += step_x;
&lt;&#x2F;span&gt;&lt;span&gt;                err -= dy2;
&lt;&#x2F;span&gt;&lt;span&gt;                overlap = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_MAJOR&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            err += dx2;
&lt;&#x2F;span&gt;&lt;span&gt;            line.append(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span&gt;get_line_overlap(
&lt;&#x2F;span&gt;&lt;span&gt;                (x1, y1),
&lt;&#x2F;span&gt;&lt;span&gt;                (x2, y2),
&lt;&#x2F;span&gt;&lt;span&gt;                overlap,
&lt;&#x2F;span&gt;&lt;span&gt;                map_width,
&lt;&#x2F;span&gt;&lt;span&gt;            ));
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; these are 2.5x slower than using get_thick_line() to remove dupes:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;line.sort();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;line.dedup();
&lt;&#x2F;span&gt;&lt;span&gt;    line
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and....&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_NONE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; No line overlap, like in standard Bresenham
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_MAJOR&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; Overlap - first go major then minor direction. Pixel is drawn as extension after actual line
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_MINOR&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0x02&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; Overlap - first go minor then major direction. Pixel is drawn as extension before next line
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_BOTH&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0x03&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; Overlap - both
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;derive&lt;&#x2F;span&gt;&lt;span&gt;(PartialEq)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub enum &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ThicknessMode &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    LineThicknessMiddle = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    LineThicknessDrawClockwise = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    LineThicknessDrawCounterclockwise = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; ported from https:&#x2F;&#x2F;github.com&#x2F;ArminJo&#x2F;Arduino-BlueDisplay&#x2F;blob&#x2F;master&#x2F;src&#x2F;LocalGUI&#x2F;ThickLine.hpp
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;get_line_overlap&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt;: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;overlap&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;map_width&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; x1 = from.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; x2 = to.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; y1 = from.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; y2 = to.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; line: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; = vec![];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; dx: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; dy: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; dx2: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; dy2: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; err: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; step_x: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; step_y: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; max_width = (map_width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    dx = x2 - x1;
&lt;&#x2F;span&gt;&lt;span&gt;    dy = y2 - y1;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; dx &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        dx = -dx;
&lt;&#x2F;span&gt;&lt;span&gt;        step_x = -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        step_x = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; dy &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        dy = -dy;
&lt;&#x2F;span&gt;&lt;span&gt;        step_y = -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        step_y = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    dx2 = dx &amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    dy2 = dy &amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    line.push((
&lt;&#x2F;span&gt;&lt;span&gt;        x1.clamp(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, max_width) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        y1.clamp(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, max_width) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    ));
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; dx &amp;gt; dy {
&lt;&#x2F;span&gt;&lt;span&gt;        err = dy2 - dx;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;while&lt;&#x2F;span&gt;&lt;span&gt; x1 != x2 {
&lt;&#x2F;span&gt;&lt;span&gt;            x1 += step_x;
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; err &amp;gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; overlap &amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_MAJOR &lt;&#x2F;span&gt;&lt;span&gt;!= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                    line.push((
&lt;&#x2F;span&gt;&lt;span&gt;                        x1.clamp(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, max_width) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;                        y1.clamp(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, max_width) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;                    ));
&lt;&#x2F;span&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;span&gt;                y1 += step_y;
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; overlap &amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_MINOR &lt;&#x2F;span&gt;&lt;span&gt;!= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                    line.push((
&lt;&#x2F;span&gt;&lt;span&gt;                        (x1 - step_x).clamp(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, max_width) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;                        y1.clamp(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, max_width) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;                    ));
&lt;&#x2F;span&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;span&gt;                err -= dx2;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            err += dy2;
&lt;&#x2F;span&gt;&lt;span&gt;            line.push((
&lt;&#x2F;span&gt;&lt;span&gt;                x1.clamp(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, max_width) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;                y1.clamp(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, max_width) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;            ));
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        err = dx2 - dy;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;while&lt;&#x2F;span&gt;&lt;span&gt; y1 != y2 {
&lt;&#x2F;span&gt;&lt;span&gt;            y1 += step_y;
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; err &amp;gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; overlap &amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_MAJOR &lt;&#x2F;span&gt;&lt;span&gt;!= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                    line.push((
&lt;&#x2F;span&gt;&lt;span&gt;                        x1.clamp(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, max_width) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;                        y1.clamp(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, max_width) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;                    ));
&lt;&#x2F;span&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;span&gt;                x1 += step_x;
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; overlap &amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_MINOR &lt;&#x2F;span&gt;&lt;span&gt;!= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                    line.push((
&lt;&#x2F;span&gt;&lt;span&gt;                        x1.clamp(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, max_width) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;                        (y1 - step_y).clamp(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, max_width) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;                    ));
&lt;&#x2F;span&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;span&gt;                err -= dy2;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            err += dx2;
&lt;&#x2F;span&gt;&lt;span&gt;            line.push((
&lt;&#x2F;span&gt;&lt;span&gt;                x1.clamp(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, max_width) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;                y1.clamp(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, max_width) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;            ));
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    line
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Okay, that&#x27;s the first version.  It works, but possibly includes duplicate points.  If you&#x27;re actually trying to rasterize a rectangle pixel by pixel in 2023, then dupes might not matter.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s the guaranteed dupe free version, with an option for an unsafe unchecked version:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; ported from https:&#x2F;&#x2F;github.com&#x2F;ArminJo&#x2F;Arduino-BlueDisplay&#x2F;blob&#x2F;master&#x2F;src&#x2F;LocalGUI&#x2F;ThickLine.hpp
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; i strongly discourage use of the unsafe_unchecked version unless you&amp;#39;re 100% sure of what you&amp;#39;re doing
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;get_thick_line&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt;: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;line_width&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;thick_mode&lt;&#x2F;span&gt;&lt;span&gt;: ThicknessMode,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;map_width&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;unsafe_unchecked&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; line: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; = vec![];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; x1 = from.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; x2 = to.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; y1 = from.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; y2 = to.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; dx: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; dy: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; dx2: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; dy2: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; err: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; step_x: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; step_y: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; max_width = (map_width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; x1 &amp;gt; max_width {
&lt;&#x2F;span&gt;&lt;span&gt;        x1 = max_width;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; x2 &amp;gt; max_width {
&lt;&#x2F;span&gt;&lt;span&gt;        x2 = max_width;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; y1 &amp;gt; max_width {
&lt;&#x2F;span&gt;&lt;span&gt;        y1 = max_width;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; y2 &amp;gt; max_width {
&lt;&#x2F;span&gt;&lt;span&gt;        y2 = max_width;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;convert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;max_width&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; retval: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; = Vec::with_capacity(input.len());
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..input.len() {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; input[x].&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;amp;&amp;amp; input[x].&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;= max_width
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;amp;&amp;amp; input[x].&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;amp;&amp;amp; input[x].&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;= max_width
&lt;&#x2F;span&gt;&lt;span&gt;            {
&lt;&#x2F;span&gt;&lt;span&gt;                retval.push((input[x].&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, input[x].&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        retval
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;unsafe fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;fast_convert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt;) -&amp;gt; Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; v = std::mem::ManuallyDrop::new(input);
&lt;&#x2F;span&gt;&lt;span&gt;        Vec::from_raw_parts(v.as_mut_ptr() as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;*mut &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;), v.len(), v.capacity())
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; line_width &amp;lt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        line = get_line_overlap2((x1, y1), (x2, y2), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_NONE&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;convert(&amp;amp;line, max_width);
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    dy = x2 - x1;
&lt;&#x2F;span&gt;&lt;span&gt;    dx = y2 - y1;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; swap = true;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; dx &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        dx = -dx;
&lt;&#x2F;span&gt;&lt;span&gt;        step_x = -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        swap = !swap;
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        step_x = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; dy &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        dy = -dy;
&lt;&#x2F;span&gt;&lt;span&gt;        step_y = -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        swap = !swap;
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        step_y = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    dx2 = dx &amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    dy2 = dy &amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; overlap: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; draw_start_adjust_count = line_width &#x2F; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; thick_mode == ThicknessMode::LineThicknessDrawCounterclockwise {
&lt;&#x2F;span&gt;&lt;span&gt;        draw_start_adjust_count = line_width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else if&lt;&#x2F;span&gt;&lt;span&gt; thick_mode == ThicknessMode::LineThicknessDrawClockwise {
&lt;&#x2F;span&gt;&lt;span&gt;        draw_start_adjust_count = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; dx &amp;gt;= dy {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; swap {
&lt;&#x2F;span&gt;&lt;span&gt;            draw_start_adjust_count = (line_width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) - draw_start_adjust_count;
&lt;&#x2F;span&gt;&lt;span&gt;            step_y = -step_y;
&lt;&#x2F;span&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            step_x = -step_x;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        err = dy2 - dx;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;_ in (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..draw_start_adjust_count).rev() {
&lt;&#x2F;span&gt;&lt;span&gt;            x1 -= step_x;
&lt;&#x2F;span&gt;&lt;span&gt;            x2 -= step_x;
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; err &amp;gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                y1 -= step_y;
&lt;&#x2F;span&gt;&lt;span&gt;                y2 -= step_y;
&lt;&#x2F;span&gt;&lt;span&gt;                err -= dx2;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            err += dy2;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        line.append(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span&gt;get_line_overlap2(
&lt;&#x2F;span&gt;&lt;span&gt;            (x1, y1),
&lt;&#x2F;span&gt;&lt;span&gt;            (x2, y2),
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_NONE&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        ));
&lt;&#x2F;span&gt;&lt;span&gt;        err = dy2 - dx;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;_ in (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;..line_width).rev() {
&lt;&#x2F;span&gt;&lt;span&gt;            x1 += step_x;
&lt;&#x2F;span&gt;&lt;span&gt;            x2 += step_x;
&lt;&#x2F;span&gt;&lt;span&gt;            overlap = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_NONE&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; err &amp;gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                y1 += step_y;
&lt;&#x2F;span&gt;&lt;span&gt;                y2 += step_y;
&lt;&#x2F;span&gt;&lt;span&gt;                err -= dx2;
&lt;&#x2F;span&gt;&lt;span&gt;                overlap = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_MAJOR&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            err += dy2;
&lt;&#x2F;span&gt;&lt;span&gt;            line.append(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span&gt;get_line_overlap2((x1, y1), (x2, y2), overlap));
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; swap {
&lt;&#x2F;span&gt;&lt;span&gt;            step_x = -step_x;
&lt;&#x2F;span&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            draw_start_adjust_count = (line_width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) - draw_start_adjust_count;
&lt;&#x2F;span&gt;&lt;span&gt;            step_y = -step_y;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        err = dx2 - dy;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;_ in (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..draw_start_adjust_count).rev() {
&lt;&#x2F;span&gt;&lt;span&gt;            y1 -= step_y;
&lt;&#x2F;span&gt;&lt;span&gt;            y2 -= step_y;
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; err &amp;gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                x1 -= step_x;
&lt;&#x2F;span&gt;&lt;span&gt;                x2 -= step_x;
&lt;&#x2F;span&gt;&lt;span&gt;                err -= dy2;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            err += dx2;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        line.append(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span&gt;get_line_overlap2(
&lt;&#x2F;span&gt;&lt;span&gt;            (x1, y1),
&lt;&#x2F;span&gt;&lt;span&gt;            (x2, y2),
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_NONE&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        ));
&lt;&#x2F;span&gt;&lt;span&gt;        err = dx2 - dy;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;_ in (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;..line_width).rev() {
&lt;&#x2F;span&gt;&lt;span&gt;            y1 += step_y;
&lt;&#x2F;span&gt;&lt;span&gt;            y2 += step_y;
&lt;&#x2F;span&gt;&lt;span&gt;            overlap = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_NONE&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; err &amp;gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                x1 += step_x;
&lt;&#x2F;span&gt;&lt;span&gt;                x2 += step_x;
&lt;&#x2F;span&gt;&lt;span&gt;                err -= dy2;
&lt;&#x2F;span&gt;&lt;span&gt;                overlap = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_MAJOR&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            err += dx2;
&lt;&#x2F;span&gt;&lt;span&gt;            line.append(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span&gt;get_line_overlap2((x1, y1), (x2, y2), overlap));
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; unsafe_unchecked {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{ fast_convert(line) }
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        convert(&amp;amp;line, max_width)
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and...&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; ported from https:&#x2F;&#x2F;github.com&#x2F;ArminJo&#x2F;Arduino-BlueDisplay&#x2F;blob&#x2F;master&#x2F;src&#x2F;LocalGUI&#x2F;ThickLine.hpp
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;get_line_overlap2&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt;: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;overlap&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; x1 = from.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; x2 = to.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; y1 = from.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; y2 = to.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; line: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; = vec![];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; dx: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; dy: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; dx2: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; dy2: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; err: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; step_x: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; step_y: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    dx = x2 - x1;
&lt;&#x2F;span&gt;&lt;span&gt;    dy = y2 - y1;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; dx &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        dx = -dx;
&lt;&#x2F;span&gt;&lt;span&gt;        step_x = -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        step_x = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; dy &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        dy = -dy;
&lt;&#x2F;span&gt;&lt;span&gt;        step_y = -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        step_y = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    dx2 = dx &amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    dy2 = dy &amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    line.push((x1, y1));
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; dx &amp;gt; dy {
&lt;&#x2F;span&gt;&lt;span&gt;        err = dy2 - dx;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;while&lt;&#x2F;span&gt;&lt;span&gt; x1 != x2 {
&lt;&#x2F;span&gt;&lt;span&gt;            x1 += step_x;
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; err &amp;gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; overlap &amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_MAJOR &lt;&#x2F;span&gt;&lt;span&gt;!= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                    line.push((x1, y1));
&lt;&#x2F;span&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;span&gt;                y1 += step_y;
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; overlap &amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_MINOR &lt;&#x2F;span&gt;&lt;span&gt;!= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                    line.push((x1 - step_x, y1));
&lt;&#x2F;span&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;span&gt;                err -= dx2;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            err += dy2;
&lt;&#x2F;span&gt;&lt;span&gt;            line.push((x1, y1));
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        err = dx2 - dy;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;while&lt;&#x2F;span&gt;&lt;span&gt; y1 != y2 {
&lt;&#x2F;span&gt;&lt;span&gt;            y1 += step_y;
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; err &amp;gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; overlap &amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_MAJOR &lt;&#x2F;span&gt;&lt;span&gt;!= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                    line.push((x1, y1));
&lt;&#x2F;span&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;span&gt;                x1 += step_x;
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; overlap &amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;LINE_OVERLAP_MINOR &lt;&#x2F;span&gt;&lt;span&gt;!= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                    line.push((x1, y1 - step_y));
&lt;&#x2F;span&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;span&gt;                err -= dy2;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            err += dx2;
&lt;&#x2F;span&gt;&lt;span&gt;            line.push((x1, y1));
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    line
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Above I talked about scary Option #3.  That&#x27;s calling get_thick_line() with unsafe_unchecked = true.  The unsafe version just directly casts an (isize, isize) vec into a (usize, usize) vec.  If you are 100% damn sure that the entirety of your thick line lies within the canvas boundaries, you&#x27;ll get a thick line with no duplicates and no crashing.&lt;&#x2F;p&gt;
&lt;p&gt;If, however, you cast negative signed coordinates into unsigned ones, and actually attempt to use them without checking them...Bad Things Will Happen™ (and if you have overflow checks enabled, the app will crash before you can even attempt to crash the app in a different way)&lt;&#x2F;p&gt;
&lt;p&gt;Here are some example images produced using the code, showing proper handling of out of bounds coordinates:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;bresenham&#x2F;fat_line_0.avif&quot; alt=&quot;fat_line_0&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;bresenham&#x2F;fat_line_1.avif&quot; alt=&quot;fat_line_1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;bresenham&#x2F;fat_line_2.avif&quot; alt=&quot;fat_line_2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;bresenham&#x2F;fat_line_3.avif&quot; alt=&quot;fat_line_3&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;bresenham&#x2F;fat_line_4.avif&quot; alt=&quot;fat_line_4&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;bresenham&#x2F;fat_line_5.avif&quot; alt=&quot;fat_line_5&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll have a crude little benchmark further below.  First though, a little tidbit about a problem I had testing the code originally.  Thick lines in the middle of the canvas were like the ones above, perfectly fine.  But as parts of the line got further out of bounds, the line would take on a trapezoid shape, or sometimes sort of &amp;quot;bounce&amp;quot; off the boundary of the canvas.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s an example of the trapezoid anomaly (notice the starting points in yellow are off-center as well):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;bresenham&#x2F;fat_line_weird.avif&quot; alt=&quot;fat_line_weird&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I eventually tracked it down to the beginning of the drawLineOverlap function &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ArminJo&#x2F;Arduino-BlueDisplay&#x2F;blob&#x2F;master&#x2F;src&#x2F;LocalGUI&#x2F;ThickLine.hpp#L75&quot;&gt;here&lt;&#x2F;a&gt;.
So I snipped out my version of this code:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;c&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(aXStart &amp;gt;= LOCAL_DISPLAY_WIDTH) {
&lt;&#x2F;span&gt;&lt;span&gt;        aXStart = LOCAL_DISPLAY_WIDTH - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(aXEnd &amp;gt;= LOCAL_DISPLAY_WIDTH) {
&lt;&#x2F;span&gt;&lt;span&gt;        aXEnd = LOCAL_DISPLAY_WIDTH - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(aYStart &amp;gt;= LOCAL_DISPLAY_HEIGHT) {
&lt;&#x2F;span&gt;&lt;span&gt;        aYStart = LOCAL_DISPLAY_HEIGHT - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(aYEnd &amp;gt;= LOCAL_DISPLAY_HEIGHT) {
&lt;&#x2F;span&gt;&lt;span&gt;        aYEnd = LOCAL_DISPLAY_HEIGHT - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;...and the issue disappeared.  I&#x27;m not sure if it&#x27;s actually a bug in the implementation I copied, or if it was my fault in how I ported the code.  All I know is that it&#x27;s fixed now in my code =)&lt;&#x2F;p&gt;
&lt;p&gt;Crude benchmark code:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;test_fat_lines&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;tests&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;map_width&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;line_width&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;----------------------- [ test begin ] -----------------------&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; rng = nanorand::tls_rng();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; points1: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; = vec![];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; points2: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; = vec![];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; line: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; len: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;_ in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..tests {
&lt;&#x2F;span&gt;&lt;span&gt;        points1.push((rng.generate_range(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..map_width), rng.generate_range(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..map_width)));
&lt;&#x2F;span&gt;&lt;span&gt;        points2.push((rng.generate_range(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..map_width), rng.generate_range(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..map_width)));
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; start = Instant::now();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..tests {
&lt;&#x2F;span&gt;&lt;span&gt;        line = utils::get_thick_line_unchecked(
&lt;&#x2F;span&gt;&lt;span&gt;            points1[x],
&lt;&#x2F;span&gt;&lt;span&gt;            points2[x],
&lt;&#x2F;span&gt;&lt;span&gt;            line_width,
&lt;&#x2F;span&gt;&lt;span&gt;            utils::ThicknessMode::LineThicknessMiddle,
&lt;&#x2F;span&gt;&lt;span&gt;            map_width,
&lt;&#x2F;span&gt;&lt;span&gt;        );
&lt;&#x2F;span&gt;&lt;span&gt;        len += line.len();
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; duration = start.elapsed();
&lt;&#x2F;span&gt;&lt;span&gt;    println!(
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; iterations for get_thick_line_unchecked() took: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{:?}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        tests, duration
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;span&gt;    println!(
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;total pixels = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;, line width = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;, canvas size = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        len, line_width, map_width, map_width
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    len = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; start = Instant::now();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..tests {
&lt;&#x2F;span&gt;&lt;span&gt;        line = utils::get_thick_line(
&lt;&#x2F;span&gt;&lt;span&gt;            points1[x],
&lt;&#x2F;span&gt;&lt;span&gt;            points2[x],
&lt;&#x2F;span&gt;&lt;span&gt;            line_width,
&lt;&#x2F;span&gt;&lt;span&gt;            utils::ThicknessMode::LineThicknessMiddle,
&lt;&#x2F;span&gt;&lt;span&gt;            map_width,
&lt;&#x2F;span&gt;&lt;span&gt;            false,
&lt;&#x2F;span&gt;&lt;span&gt;        );
&lt;&#x2F;span&gt;&lt;span&gt;        len += line.len();
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; duration = start.elapsed();
&lt;&#x2F;span&gt;&lt;span&gt;    println!(
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; iterations for get_thick_line() took: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{:?}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        tests, duration
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;span&gt;    println!(
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;total pixels = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;, line width = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;, canvas size = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        len, line_width, map_width, map_width
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    len = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; start = Instant::now();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..tests {
&lt;&#x2F;span&gt;&lt;span&gt;        line = utils::get_thick_line(
&lt;&#x2F;span&gt;&lt;span&gt;            points1[x],
&lt;&#x2F;span&gt;&lt;span&gt;            points2[x],
&lt;&#x2F;span&gt;&lt;span&gt;            line_width,
&lt;&#x2F;span&gt;&lt;span&gt;            utils::ThicknessMode::LineThicknessMiddle,
&lt;&#x2F;span&gt;&lt;span&gt;            map_width,
&lt;&#x2F;span&gt;&lt;span&gt;            true,
&lt;&#x2F;span&gt;&lt;span&gt;        );
&lt;&#x2F;span&gt;&lt;span&gt;        len += line.len();
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; duration = start.elapsed();
&lt;&#x2F;span&gt;&lt;span&gt;    println!(
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; iterations for get_thick_line(unsafe unchecked) took: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{:?}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        tests, duration
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;span&gt;    println!(
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;total pixels = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;, line width = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;, canvas size = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        len, line_width, map_width, map_width
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the results of a few tests with different parameters:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#151515;color:#e8e8d3;&quot;&gt;&lt;code&gt;&lt;span&gt;----------------------- [ test begin ] -----------------------
&lt;&#x2F;span&gt;&lt;span&gt;5000 iterations for get_thick_line_unchecked() took: 16.8303775s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 1470765496, line width = 500, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;5000 iterations for get_thick_line() took: 22.3055861s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 1348434370, line width = 500, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;5000 iterations for get_thick_line(unsafe unchecked) took: 16.1727516s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 1470765496, line width = 500, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;----------------------- [ test begin ] -----------------------
&lt;&#x2F;span&gt;&lt;span&gt;5000 iterations for get_thick_line_unchecked() took: 5.7484512s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 589019150, line width = 200, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;5000 iterations for get_thick_line() took: 7.6234731s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 578641650, line width = 200, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;5000 iterations for get_thick_line(unsafe unchecked) took: 5.1384081s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 589019150, line width = 200, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;----------------------- [ test begin ] -----------------------
&lt;&#x2F;span&gt;&lt;span&gt;10000 iterations for get_thick_line_unchecked() took: 1.8566417s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 294929612, line width = 50, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;10000 iterations for get_thick_line() took: 2.2578805s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 294517820, line width = 50, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;10000 iterations for get_thick_line(unsafe unchecked) took: 1.6420243s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 294929612, line width = 50, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;----------------------- [ test begin ] -----------------------
&lt;&#x2F;span&gt;&lt;span&gt;50000 iterations for get_thick_line_unchecked() took: 1.5864814s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 288522185, line width = 10, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;50000 iterations for get_thick_line() took: 1.854512s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 288501000, line width = 10, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;50000 iterations for get_thick_line(unsafe unchecked) took: 1.4808243s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 288522185, line width = 10, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The unsafe code is always fastest of course, but it&#x27;s not that far behind the version with potential duplicates.  In the pixel counts you can see how many pixels were removed by the version of the function which removes dupes. get_thick_line(unsafe unchecked) will &lt;em&gt;ONLY&lt;&#x2F;em&gt; have duplicates if it has been abused (like in my above tests).&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s all for today, code for this post and the previous one can be found here: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;0xDEADFED5&#x2F;dwarf_dreams&#x2F;tree&#x2F;main&#x2F;thick_bresenham&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;0xDEADFED5&#x2F;dwarf_dreams&#x2F;tree&#x2F;main&#x2F;thick_bresenham&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Kudos and respect to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ArminJo&quot;&gt;ArminJo&lt;&#x2F;a&gt;, without their code I&#x27;d probably still be scratching my head.&lt;&#x2F;p&gt;
&lt;p&gt;quick edit:&lt;&#x2F;p&gt;
&lt;p&gt;I ran the tests again, this time with coordinates firmly within the canvas, but with the same parameters as the previous tests.  As expected, each function call returned the same number of pixels, but with differing performance.  Here are the results:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#151515;color:#e8e8d3;&quot;&gt;&lt;code&gt;&lt;span&gt;----------------------- [ test begin ] -----------------------
&lt;&#x2F;span&gt;&lt;span&gt;5000 iterations for get_thick_line_unchecked() took: 22.2698107s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 2500000000, line width = 500, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;5000 iterations for get_thick_line() took: 30.3468048s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 2500000000, line width = 500, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;5000 iterations for get_thick_line(unsafe unchecked) took: 19.8017243s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 2500000000, line width = 500, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;----------------------- [ test begin ] -----------------------
&lt;&#x2F;span&gt;&lt;span&gt;5000 iterations for get_thick_line_unchecked() took: 8.2815981s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 1000000000, line width = 200, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;5000 iterations for get_thick_line() took: 11.9877238s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 1000000000, line width = 200, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;5000 iterations for get_thick_line(unsafe unchecked) took: 7.7751189s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 1000000000, line width = 200, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;----------------------- [ test begin ] -----------------------
&lt;&#x2F;span&gt;&lt;span&gt;10000 iterations for get_thick_line_unchecked() took: 3.6693278s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 500000000, line width = 50, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;10000 iterations for get_thick_line() took: 6.2115697s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 500000000, line width = 50, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;10000 iterations for get_thick_line(unsafe unchecked) took: 3.3808899s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 500000000, line width = 50, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;----------------------- [ test begin ] -----------------------
&lt;&#x2F;span&gt;&lt;span&gt;50000 iterations for get_thick_line_unchecked() took: 1.749504s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 500000000, line width = 10, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;50000 iterations for get_thick_line() took: 2.2008861s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 500000000, line width = 10, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;50000 iterations for get_thick_line(unsafe unchecked) took: 1.4769065s
&lt;&#x2F;span&gt;&lt;span&gt;total pixels = 500000000, line width = 10, canvas size = 1000x1000
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Bresenham, splines, and nipples, oh my!</title>
        <published>2023-06-11T00:00:00+00:00</published>
        <updated>2023-06-11T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="https://dwarfdreams.com/terrain2/" type="text/html"/>
        <id>https://dwarfdreams.com/terrain2/</id>
        
        <content type="html">&lt;p&gt;Site update: added Yandex and Twitter login support to the comment system.&lt;&#x2F;p&gt;
&lt;p&gt;Well, I&#x27;ve been testing lots of different hydraulic erosion simulation code on my noise based terrain.  I started off with a pretty complex sim I put together that modeled water sources, water quantity, water velocity, amount of sediment carried in the water, soil deposition rates, etc.  I tested this on 8000x8000 maps of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;primitive.f32.html&quot;&gt;f32&lt;&#x2F;a&gt; data.&lt;&#x2F;p&gt;
&lt;p&gt;Even though my code is fully threaded (current machine: 8 core&#x2F;16 thread), my simulations were slow.  Incredibly slow.  Like possibly approaching the heat death of the universe for my simulation to end slow.  After several iterations of simplifying the simulation I had a realization.  I don&#x27;t need some crazy full map erosion process that takes forever.  I mostly want mountains that don&#x27;t suck and realistic looking rivers.  After I get that nailed I can get to work implementing terrain for specific biomes.&lt;&#x2F;p&gt;
&lt;p&gt;My new simplified river plan is this, for each river:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Starting point is a mountain peak which receives precipitation&lt;&#x2F;li&gt;
&lt;li&gt;Chart a path downhill&lt;&#x2F;li&gt;
&lt;li&gt;Widen river as conditions are met&lt;&#x2F;li&gt;
&lt;li&gt;End the river at an existing body of water, a depression to form a lake, or the edge of map&lt;&#x2F;li&gt;
&lt;li&gt;Also, erosion only at this time&lt;&#x2F;li&gt;
&lt;li&gt;When water physics is added in I&#x27;ll add evaporation and take another look at sediment deposits&lt;&#x2F;li&gt;
&lt;li&gt;A modest speed increase: I was sharing one map between 16 threads and using reader&#x2F;writer locking semantics.  I didn&#x27;t measure contention, but I suspected a fair amount.  So now I create 16 copies of the map, give each thread their own version to work on, and merge the maps back together at the end.  I got around a 10% performance boost.  RAM is meant to be used right? ....right?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I&#x27;m not going to traverse every single tile&#x2F;pixel downhill.  First off, it&#x27;s friggin&#x27; slow.  Secondly, it produces some weird shaped rivers.  That can be fixed by running a gazillion iterations, but that&#x27;s one of the things I&#x27;m trying to avoid.  So instead I&#x27;m going to search for the lowest point in a set radius, draw a line to it, and keep doing that until I have a river of attached line segments.&lt;&#x2F;p&gt;
&lt;p&gt;First I need to be able to draw a line from x1, y1 to x2, y2, preferably as quickly as possible.  Luckily for me, some guy named &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Jack_Elton_Bresenham&quot;&gt;Jack Elton Bresenham&lt;&#x2F;a&gt; came up with a fast algorithm called &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bresenham%27s_line_algorithm&quot;&gt;Bresenham&#x27;s line algorithm&lt;&#x2F;a&gt; back in 1962.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;members.chello.at&#x2F;%7Eeasyfilter&#x2F;bresenham.html&quot;&gt;This&lt;&#x2F;a&gt; page has some cool examples of Bresenham&#x27;s algorithm in C. (for some reason uBlock hates this page now, but as of this blog post date that page is safe and ad-free)&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s my Rust implementation based on the code from that page:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; adapted from http:&#x2F;&#x2F;members.chello.at&#x2F;%7Eeasyfilter&#x2F;bresenham.html
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;get_line_unchecked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt;: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)) -&amp;gt; Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; line: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; = vec![];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; ix0 = from.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; iy0 = from.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; ix1 = to.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; iy1 = to.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; dx: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize &lt;&#x2F;span&gt;&lt;span&gt;= ix1.abs_diff(ix0) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; sx: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; ix0 &amp;gt; ix1 {
&lt;&#x2F;span&gt;&lt;span&gt;        sx = -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; dy: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize &lt;&#x2F;span&gt;&lt;span&gt;= -(iy1.abs_diff(iy0) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; sy: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; iy0 &amp;gt; iy1 {
&lt;&#x2F;span&gt;&lt;span&gt;        sy = -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; err = dx + dy;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; e2: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;loop &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        line.push((ix0 as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, iy0 as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; ix0 == ix1 &amp;amp;&amp;amp; iy0 == iy1 {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        e2 = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;* err;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; e2 &amp;gt;= dy {
&lt;&#x2F;span&gt;&lt;span&gt;            err += dy;
&lt;&#x2F;span&gt;&lt;span&gt;            ix0 += sx;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; e2 &amp;lt;= dx {
&lt;&#x2F;span&gt;&lt;span&gt;            err += dx;
&lt;&#x2F;span&gt;&lt;span&gt;            iy0 += sy;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    line
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I called it get_line_unchecked because it&#x27;s naive.  I intend to draw lines on a specific canvas&#x2F;map size within only the positive coordinate plane.  This function doesn&#x27;t know that.  It just gives me a vector of points from one point to the other.  Since I intend to use each of these points as a direct memory index into my map I want to make sure I return valid points.  If a line extends off my map and I try to use that as a map index I&#x27;m going to experience 1 of 2 possible errors:  Best case scenario, I index the wrong location on the map and modify something where I didn&#x27;t intend to.  Worst case scenario is I attempt to index beyond my maximum map size, which results in an array out of bounds error, or memory access exception, or whatever happens in Rust...and then the application crashes.  Also, this function uses signed integers (to support the entire coordinate plane), so if I get a negative coordinate and cast it to an unsigned integer for my map index one of those 2 possible errors I just wrote about is going to happen.  It&#x27;s definitely more likely to be the crashy kind of error though.&lt;&#x2F;p&gt;
&lt;p&gt;So I updated the code a bit.  I still use that previous code when I know it&#x27;s safe and I want extra speed.  Otherwise I use this one:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; adapted from http:&#x2F;&#x2F;members.chello.at&#x2F;%7Eeasyfilter&#x2F;bresenham.html
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;&#x2F; if remove_out_of_bounds = false, points outside of map will be placed on edge of map
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;&#x2F; if remove_out_of_bounds = true, points outside of map will be ignored
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;get_line&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt;: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;map_width&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;remove_out_of_bounds&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; line: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; = vec![];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; ix0 = from.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; iy0 = from.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; ix1 = to.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; iy1 = to.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; dx: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize &lt;&#x2F;span&gt;&lt;span&gt;= ix1.abs_diff(ix0) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; sx: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; imap_width = map_width as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; clamped: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool &lt;&#x2F;span&gt;&lt;span&gt;= false;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;try_clamp &lt;&#x2F;span&gt;&lt;span&gt;= |&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;coord&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;| -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; coord &amp;gt; imap_width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            clamped = true;
&lt;&#x2F;span&gt;&lt;span&gt;            map_width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else if&lt;&#x2F;span&gt;&lt;span&gt; coord &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            clamped = true;
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            coord as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    };
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; ix0 &amp;gt; ix1 {
&lt;&#x2F;span&gt;&lt;span&gt;        sx = -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; dy: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize &lt;&#x2F;span&gt;&lt;span&gt;= -(iy1.abs_diff(iy0) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; sy: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; iy0 &amp;gt; iy1 {
&lt;&#x2F;span&gt;&lt;span&gt;        sy = -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; err = dx + dy;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; e2: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; skip_point: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;loop &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        skip_point = false;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; remove_out_of_bounds
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;amp;&amp;amp; (ix0 &amp;gt; imap_width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;|| ix0 &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;|| iy0 &amp;gt; imap_width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;|| iy0 &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        {
&lt;&#x2F;span&gt;&lt;span&gt;            skip_point = true;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;!skip_point {
&lt;&#x2F;span&gt;&lt;span&gt;            line.push((try_clamp(ix0), try_clamp(iy0)))
&lt;&#x2F;span&gt;&lt;span&gt;        };
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; ix0 == ix1 &amp;amp;&amp;amp; iy0 == iy1 {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        e2 = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;* err;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; e2 &amp;gt;= dy {
&lt;&#x2F;span&gt;&lt;span&gt;            err += dy;
&lt;&#x2F;span&gt;&lt;span&gt;            ix0 += sx;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; e2 &amp;lt;= dx {
&lt;&#x2F;span&gt;&lt;span&gt;            err += dx;
&lt;&#x2F;span&gt;&lt;span&gt;            iy0 += sy;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;!remove_out_of_bounds &amp;amp;&amp;amp; clamped {
&lt;&#x2F;span&gt;&lt;span&gt;        line.sort();
&lt;&#x2F;span&gt;&lt;span&gt;        line.dedup();
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    line
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;My points are usize tuples because for better or worse, Rust forces slice indexes to be usize... and I use my points as indexes.  I only have a width parameter because my game maps are square.  I use the try_clamp closure so that I can keep track if any points have extended beyond the map.  I keep track because if I&#x27;m not removing out of bounds map points and placing them on the map edge I could end up with duplicate points.  The whole reason I want these points is so I can manipulate those parts of the map.  I don&#x27;t want to perform those manipulations multiple times at the same location on accident.  Therefore, if any point locations have been clamped, I know that I need to sort my vector and remove possible duplicates.&lt;&#x2F;p&gt;
&lt;p&gt;Here are some totally random lines representing a sort of rudimentary river:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain2&#x2F;line_grid_scaled.avif&quot; alt=&quot;line_grid_scaled&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Okay, next thing I need to do is figure out how to select a circle of pixels&#x2F;tiles.  For every point along my &amp;quot;river&amp;quot;, depending on how wide the river is, I want to select a circle of tiles, and erode earth from that circle, eroding less earth the further out from the center of the circle that I go.  I sort of picture it like dragging an ice cream cone shape along the path of the river, carving out the earth using that shape.&lt;&#x2F;p&gt;
&lt;p&gt;On that page I shared &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;members.chello.at&#x2F;%7Eeasyfilter&#x2F;bresenham.html&quot;&gt;earlier&lt;&#x2F;a&gt; there&#x27;s a version of Bresenham&#x27;s algorithm for &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Midpoint_circle_algorithm&quot;&gt;circles&lt;&#x2F;a&gt;.  Here&#x27;s my Rust version for a filled circle:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;adapted from http:&#x2F;&#x2F;members.chello.at&#x2F;%7Eeasyfilter&#x2F;bresenham.html
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;get_full_circle&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;xm&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ym&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;r&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;width&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; xm = xm as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; ym = ym as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;let mut r = r as isize;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; width2 = width as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; x = -r;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; y = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; err: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;- &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;* r;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; empty_circle: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; = vec![];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; full_circle: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; = vec![];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; clamped: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool &lt;&#x2F;span&gt;&lt;span&gt;= false;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; need to know if clamp has ocurred, as this can create duplicate coordinates
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;try_clamp &lt;&#x2F;span&gt;&lt;span&gt;= |&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;coord&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;| -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; coord &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            clamped = true;
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else if&lt;&#x2F;span&gt;&lt;span&gt; coord &amp;gt;= width2 {
&lt;&#x2F;span&gt;&lt;span&gt;            clamped = true;
&lt;&#x2F;span&gt;&lt;span&gt;            width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            coord as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    };
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;while&lt;&#x2F;span&gt;&lt;span&gt; x &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        empty_circle.push((try_clamp(xm - x), try_clamp(ym + y)));
&lt;&#x2F;span&gt;&lt;span&gt;        empty_circle.push((try_clamp(xm - y), try_clamp(ym - x)));
&lt;&#x2F;span&gt;&lt;span&gt;        empty_circle.push((try_clamp(xm + x), try_clamp(ym - y)));
&lt;&#x2F;span&gt;&lt;span&gt;        empty_circle.push((try_clamp(xm + y), try_clamp(ym + x)));
&lt;&#x2F;span&gt;&lt;span&gt;        r = err;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; r &amp;lt;= y {
&lt;&#x2F;span&gt;&lt;span&gt;            y += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            err += y * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; r &amp;gt; x || err &amp;gt; y {
&lt;&#x2F;span&gt;&lt;span&gt;            x += &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            err += x * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; empty_circle.len() == &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; empty_circle;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F; sort by X axis. this allows easy dupe removal and quickly getting coords inside the circle
&lt;&#x2F;span&gt;&lt;span&gt;    empty_circle.sort();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; clamped {
&lt;&#x2F;span&gt;&lt;span&gt;        empty_circle.dedup();
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; lowest = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; highest = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; current = empty_circle.first().unwrap().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;&#x2F;&#x2F;find lowest Y and highest Y for each X coordinate, and grab all the coords between (inclusive)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; p in empty_circle {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; p.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;!= current {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; y in lowest..=highest {
&lt;&#x2F;span&gt;&lt;span&gt;                full_circle.push((current, y));
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            lowest = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;MAX&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            highest = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            current = p.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; p.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;&amp;lt; lowest {
&lt;&#x2F;span&gt;&lt;span&gt;            lowest = p.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; p.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; highest {
&lt;&#x2F;span&gt;&lt;span&gt;            highest = p.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; y in lowest..=highest {
&lt;&#x2F;span&gt;&lt;span&gt;        full_circle.push((current, y));
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    full_circle
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This code looks quite a bit different because I want a filled circle, not just a circle outline.  Basically for each horizontal (X) step across the circle diameter I make, I fill in the whole range of vertical (Y) pixels. You could do it the other way around too, of course.  I think it could be optimized a bit, but it works.  Oh yeah, and like before I&#x27;ve got my clamping code in there in case I try to get a filled circle too close to the map edge.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s an example:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain2&#x2F;bresenham_filled_circle.avif&quot; alt=&quot;bresenham_filled_circle&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m going to be drawing lots of circles though, and I wasn&#x27;t sure if that was the fastest way to get a filled circle.  So I wrote a more naive version.  Basically, if I want a filled circle of radius R, first get the tiles&#x2F;pixels in a square 2R X 2R centered where I want the circle.  Then calculate the distance of each pixel from the center.  If it&#x27;s less than or equal to the circle radius I want, then it&#x27;s inside the circle.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s my code for that version:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;get_full_circle_naive&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;xm&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ym&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;r&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;width&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;with_nipples&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;ignore_center&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; full_circle: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; = vec![];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; nipples: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; = vec![];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; startx: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; starty: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; endx: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; endy: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; r2 = r as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; xm &amp;gt;= r2 {
&lt;&#x2F;span&gt;&lt;span&gt;        startx = xm - r2;
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        startx = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; ym &amp;gt;= r2 {
&lt;&#x2F;span&gt;&lt;span&gt;        starty = ym - r2;
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        starty = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; width &amp;gt; xm + r2 {
&lt;&#x2F;span&gt;&lt;span&gt;        endx = xm + r2
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        endx = width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; width &amp;gt; ym + r2 {
&lt;&#x2F;span&gt;&lt;span&gt;        endy = ym + r2;
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        endy = width - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; dist: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x in startx..=endx {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; y in starty..=endy {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; ignore_center &amp;amp;&amp;amp; x == xm &amp;amp;&amp;amp; y == ym {
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;continue&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            dist = distance((x, y), (xm, ym));
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; dist &amp;lt; r {
&lt;&#x2F;span&gt;&lt;span&gt;                full_circle.push((x, y));
&lt;&#x2F;span&gt;&lt;span&gt;            } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else if&lt;&#x2F;span&gt;&lt;span&gt; with_nipples &amp;amp;&amp;amp; dist == r {
&lt;&#x2F;span&gt;&lt;span&gt;                nipples.push((x, y));
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; with_nipples {
&lt;&#x2F;span&gt;&lt;span&gt;        full_circle.append(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; nipples);
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    full_circle
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Oh right, and my terribly complex distance function:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;(always)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;distance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;pos1&lt;&#x2F;span&gt;&lt;span&gt;: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;pos2&lt;&#x2F;span&gt;&lt;span&gt;: (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; x1 = pos1.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; x2 = pos2.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; y1 = pos1.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; y2 = pos2.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    ((x1 - x2).powi(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) + (y1 - y2).powi(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)).sqrt()
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here&#x27;s what it looks like rendered:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain2&#x2F;naive_filled_circle_with_nipples.avif&quot; alt=&quot;naive_filled_circle_with_nipples&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Well, that&#x27;s what it looked like with the first version I made.  I call it the nipple version because well...I mean look at it.  I usually like nipples, but not those ones.  So I modified the code a bit, version 2 is what you see above.  And here&#x27;s an example of calling the function + with_nipples = false:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain2&#x2F;naive_filled_circle.avif&quot; alt=&quot;naive_filled_circle&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Much better.  The Bresenham one still looks the best IMO though.  What about performance?&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s my janky test code (using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;nanorand&quot;&gt;nanorand&lt;&#x2F;a&gt; crate).  I didn&#x27;t look at the assembly code that was emitted, but I tried to stop the compiler from cheating:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;test_circles&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;test_num&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;r&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;isize&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    debug_assert!(r &amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; rf = r as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; points: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; = vec![];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; rng = nanorand::tls_rng();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;_ in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..test_num {
&lt;&#x2F;span&gt;&lt;span&gt;        points.push((rng.generate_range(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;10_000&lt;&#x2F;span&gt;&lt;span&gt;), rng.generate_range(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;10_000&lt;&#x2F;span&gt;&lt;span&gt;)));
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; circle: Vec&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; len: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; start = Instant::now();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..test_num {
&lt;&#x2F;span&gt;&lt;span&gt;        circle = utils::get_full_circle(points[x].&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, points[x].&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, r, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;11000&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;        len += circle.len();
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; duration = start.elapsed();
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;len = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, len);
&lt;&#x2F;span&gt;&lt;span&gt;    println!(
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; iterations for utils::get_full_circle() took: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{:?}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        test_num, duration
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    len = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; start = Instant::now();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..test_num {
&lt;&#x2F;span&gt;&lt;span&gt;        circle = utils::get_full_circle_naive(points[x].&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, points[x].&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, rf, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;11000&lt;&#x2F;span&gt;&lt;span&gt;, true, false);
&lt;&#x2F;span&gt;&lt;span&gt;        len += circle.len();
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; duration = start.elapsed();
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;len = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, len);
&lt;&#x2F;span&gt;&lt;span&gt;    println!(
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt; iterations for utils::get_full_circle_naive() took: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#7697d6;&quot;&gt;{:?}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        test_num, duration
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I tested with a large number of smallish circles, and a smaller number of larger circles, results were not terribly different.
In debug mode with opt-level = 0, the naive filled circle code is just over 4x slower!  Ouch.  I tried integer math that I ported from C for sqrt and distance calculations, and it was freakishly slower yet.
In release mode with opt-level = 3, the bresenham filled circle code is 28% faster with MSVC toolchain, and it&#x27;s about 10% faster with GNU toolchain.  Interestingly, the integer code is slower with GNU, and the floating point code is faster with GNU, explaining the narrowed performance difference.&lt;&#x2F;p&gt;
&lt;p&gt;This brings me back to the first picture I posted above.  My sharp angled, not very river-like line.
This thing:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain2&#x2F;line_grid_scaled.avif&quot; alt=&quot;line_grid_scaled&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m no riverologist, but I don&#x27;t think rivers usually have those sharp angles.  So now I need to smooth em out.  I did a bit of searching and it looks like I want some &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cubic_Hermite_spline&quot;&gt;cubic splines&lt;&#x2F;a&gt;.  I used the first crate I found, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;cubic_spline&quot;&gt;cubic_spline&lt;&#x2F;a&gt; and after running those same points through it, here&#x27;s my result:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain2&#x2F;spline_grid_scaled.avif&quot; alt=&quot;spline_grid_scaled&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Much better.  Of course, after I finished up that rendering code, I found another crate called &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;splines&quot;&gt;splines&lt;&#x2F;a&gt;.  I haven&#x27;t tested it yet, but I will, because I&#x27;m curious about any differences.  Next post I&#x27;ll hopefully have some mountainy mountains and rivery rivers to show off.&lt;&#x2F;p&gt;
&lt;p&gt;In other news, rust-analyzer started doing this thing where it would reindex &lt;em&gt;everything&lt;&#x2F;em&gt; every new line of code I typed. Sucked a lot.  I trashed everything Rust related on the machine and started out clean, now my coding sanity is restored.  Well, as much as it could be anyhow.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Terrain generation</title>
        <published>2023-03-28T00:00:00+00:00</published>
        <updated>2023-03-28T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="https://dwarfdreams.com/terrain/" type="text/html"/>
        <id>https://dwarfdreams.com/terrain/</id>
        
        <content type="html">&lt;p&gt;I&#x27;ve started work on generating terrain.  I&#x27;ve settled on world sizes of 64,000x64,000, 48,000x48,000, and 32,000x32,000 tiles.  For speed and memory efficiency I&#x27;m going to generate terrain data at 1&#x2F;4 that detail and then scale it up.  That means I&#x27;ll be generating between 8,000^2 and 16,000^2 terrain data points.&lt;&#x2F;p&gt;
&lt;p&gt;My plan is to generate some nice looking noise, and use that as a height map...pretty standard for game design.  I&#x27;ve tested out a number of algorithms:  Different flavors of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Perlin_noise&quot;&gt;Perlin&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Simplex_noise&quot;&gt;Simplex&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;OpenSimplex_noise&quot;&gt;OpenSimplex&lt;&#x2F;a&gt;, and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fractional_Brownian_motion&quot;&gt;fractional Brownian motion&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Regarding libraries, at first I did a lot of experimentation with &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Razaekel&#x2F;noise-rs&quot;&gt;noise-rs&lt;&#x2F;a&gt;.  It&#x27;s really nice and quite flexible.  When I wanted to scale up the size of the noise maps produced it got quite slow, however.  So I transitioned to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;verpeteren&#x2F;rust-simd-noise&quot;&gt;simdnoise&lt;&#x2F;a&gt;.  Noise-rs has a really useful utility for rendering noise maps &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Razaekel&#x2F;noise-rs&#x2F;blob&#x2F;develop&#x2F;src&#x2F;utils&#x2F;color_gradient.rs&quot;&gt;here&lt;&#x2F;a&gt;, so I refactored it to work with bytes instead of floating points, which works better for my current workflow.  Any color renders below were produced using a customized version of color_gradient.rs from noise-rs.&lt;&#x2F;p&gt;
&lt;p&gt;I settled on fractional Brownian motion(fBm) because I like how it looks and how flexible it is.  Here&#x27;s a scaled down version of 8,000^2 fBm rendered in greyscale:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain&#x2F;fbm.avif&quot; alt=&quot;fBm&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Just looks like a cloud, right?  Well, if we imagine that black is the lowest elevation, white is the highest elevation, and render the varying &amp;quot;heights&amp;quot; of each pixel according to a handful of colors to represent water, land, grass, mountains, snow, etc. (10 base colors + blending)...we get a result like this:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain&#x2F;fbm_terrain88.avif&quot; alt=&quot;fbm_terrain88&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s with water level set at 88 Z levels out of 256.  It&#x27;s kinda cool.  Sort of get a shape of the continent with bodies of water.  The mountains kinda suck though.  They&#x27;re just clouds pasted on top of the land.&lt;&#x2F;p&gt;
&lt;p&gt;Various noise functions can be tweaked to produce ridge patterns.  For instance here&#x27;s one that I scaled down from 8,000^2, rendered in greyscale:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain&#x2F;ridge.avif&quot; alt=&quot;ridge&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s what it looks like if it&#x27;s rendered in color as before, with water level at 88:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain&#x2F;ridge_terrain88.avif&quot; alt=&quot;ridge_terrain88&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Yikes.  It&#x27;s pretty ugly, but the mountain ranges are more realistic with ridges that look decent.  What if I blended the two noise maps together, and then rendered the result? Simdnoise returns a &lt;code&gt;Vec&amp;lt;f32&amp;gt;&lt;&#x2F;code&gt; for generated noise maps.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s my code for blending two maps (dest is one of the noise maps being blended, it will be overwritten):&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;blend&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;dest&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span&gt;Vec&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;other&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;Vec&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;amount&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;f32&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..dest.len() {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; other[x] &amp;gt; dest[x] {
&lt;&#x2F;span&gt;&lt;span&gt;            dest[x] = (other[x]-dest[x]).mul_add(amount, dest[x]);
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            dest[x] = (dest[x]-other[x]).mul_add(amount, other[x]);
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Pretty basic, but here&#x27;s the results for 0.5 blend from 48 water level to 128 water level in 20 Z level increments:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain&#x2F;blended_terrain48.avif&quot; alt=&quot;blended_terrain48&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain&#x2F;blended_terrain68.avif&quot; alt=&quot;blended_terrain68&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain&#x2F;blended_terrain88.avif&quot; alt=&quot;blended_terrain88&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain&#x2F;blended_terrain108.avif&quot; alt=&quot;blended_terrain108&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;terrain&#x2F;blended_terrain128.avif&quot; alt=&quot;blended_terrain128&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m pretty happy with the shape of the worlds I&#x27;m generating now.  But the mountains still need a little love, and I have to figure out where to place rivers.  So next post I&#x27;ll be playing around with simulating hydraulic erosion.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fun With Data Structures</title>
        <published>2023-03-22T00:00:00+00:00</published>
        <updated>2023-03-22T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="https://dwarfdreams.com/data-structures/" type="text/html"/>
        <id>https://dwarfdreams.com/data-structures/</id>
        
        <content type="html">&lt;p&gt;Okay, time for my first post.  This is my first project in Rust.  I&#x27;m an amateur coder, so don&#x27;t expect anything too mind-blowing here.&lt;&#x2F;p&gt;
&lt;p&gt;I played around with terrain generation a bit, but I got ahead of myself.  Before I can start to really plan out the scope of this thing I need to see what my limits are regarding RAM and disk space usage.  Dwarf Fortress&#x27; largest worlds are I believe somewhere around 196608x196608x256? tiles.  That&#x27;s an impressive number.  If I were to store just a single byte for each of those tiles it would add up to over 9.2 TiB of data.&lt;&#x2F;p&gt;
&lt;p&gt;So obviously some kind of sparse data structure is going to be helpful here. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;B-tree&quot;&gt;B-trees&lt;&#x2F;a&gt; seem like a good fit, and the Rust stdlib has something called &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;std&#x2F;collections&#x2F;struct.BTreeMap.html&quot;&gt;BTreeMap&lt;&#x2F;a&gt;.  With a B-tree I can have a huge blank canvas, but only save the x,y,z coordinates of discovered or modified tiles.&lt;&#x2F;p&gt;
&lt;p&gt;After thinking a bit, I decided to limit map size to 65536x65536x256 tiles. It&#x27;s plenty huge to get started with, and my coordinates of (u16,u16,u8) will take up less memory.&lt;&#x2F;p&gt;
&lt;p&gt;I put together a little test.  I wanted to test how fast I could insert 2,000,000 triplets of (u16,u16,u8) into a B-tree, write it to disk, read it back from disk, and compare each value to make sure that I serialized and deserialized all the data correctly.  For serialization I&#x27;ll be using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;bincode&quot;&gt;bincode&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#151515;color:#e8e8d3;&quot;&gt;&lt;code&gt;&lt;span&gt;Results for flat b-tree as XYZ: # of tests: 5, iterations = 2000000, width = 64000, serialize=true
&lt;&#x2F;span&gt;&lt;span&gt;minimum time = 598.6441ms, maximum time = 659.3505ms, mean time = 616.20734ms, file size = 11.44 MiB
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Well that doesn&#x27;t seem terrible. 2 million inserts, serialize&#x2F;deserialize, and 2 million compares on a B-tree in 663ms...and bincode even worked some magic to make the file nice and compact.  I wonder though, would reordering the coordinates to z,x,y speed it up since I only have 256 Z levels, but 64,000 width&#x2F;height?&lt;&#x2F;p&gt;
&lt;p&gt;I think I&#x27;ll extend this test in the most ugly way possible and find out.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#151515;color:#e8e8d3;&quot;&gt;&lt;code&gt;&lt;span&gt;Results for flat b-tree as XYZ: # of tests: 5, iterations = 2000000, width = 64000, serialize=true
&lt;&#x2F;span&gt;&lt;span&gt;minimum time = 607.8915ms, maximum time = 656.4575ms, mean time = 619.5944ms, file size = 11.44 MiB
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Results for flat b-tree as ZXY: # of tests: 5, iterations = 2000000, width = 64000, serialize=true
&lt;&#x2F;span&gt;&lt;span&gt;minimum time = 867.2752ms, maximum time = 900.4827ms, mean time = 881.3094ms, file size = 11.44 MiB
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Well that&#x27;s no good, it&#x27;s slower.  I can&#x27;t help but think there must be a more efficient way to store these coordinates.  If I nest the B-trees I can index individual B-trees with just u8.&lt;&#x2F;p&gt;
&lt;p&gt;My first attempt looks like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub struct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;DeeplyNestedBTree&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;T&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;buf&lt;&#x2F;span&gt;&lt;span&gt;: BTreeMap&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, Branch4&amp;lt;T&amp;gt;&amp;gt;,
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;struct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;Branch&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;T&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;buf&lt;&#x2F;span&gt;&lt;span&gt;: BTreeMap&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, T&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;struct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;Branch2&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;T&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;buf&lt;&#x2F;span&gt;&lt;span&gt;: BTreeMap&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, Branch&amp;lt;T&amp;gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;struct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;Branch3&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;T&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;buf&lt;&#x2F;span&gt;&lt;span&gt;: BTreeMap&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, Branch2&amp;lt;T&amp;gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;struct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;Branch4&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;T&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;buf&lt;&#x2F;span&gt;&lt;span&gt;: BTreeMap&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, Branch3&amp;lt;T&amp;gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It didn&#x27;t go well.  For every get and insert it has to traverse &lt;em&gt;all&lt;&#x2F;em&gt; the B-trees.  Here are the test results:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#151515;color:#e8e8d3;&quot;&gt;&lt;code&gt;&lt;span&gt;Results for flat b-tree as XYZ: # of tests: 5, iterations = 2000000, width = 64000, serialize=true
&lt;&#x2F;span&gt;&lt;span&gt;minimum time = 586.4466ms, maximum time = 639.7647ms, mean time = 602.92022ms, file size = 11.44 MiB
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Results for flat b-tree as ZXY: # of tests: 5, iterations = 2000000, width = 64000, serialize=true
&lt;&#x2F;span&gt;&lt;span&gt;minimum time = 850.5513ms, maximum time = 863.2367ms, mean time = 858.85032ms, file size = 11.44 MiB
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Results for deeply nested btree: # of tests: 5, iterations = 2000000, width = 64000, serialize=true
&lt;&#x2F;span&gt;&lt;span&gt;minimum time = 1.5296632s, maximum time = 1.5497243s, mean time = 1.5375108s, file size = 22.08 MiB
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It&#x27;s not only slower, but takes up a lot more memory. I had another idea.  I could transform (u16,u16,u8) coordinates into a group of shallower nested B-trees.  Here&#x27;s what I came up with:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub struct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;NestedBTree&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;T&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;x65535y65535&lt;&#x2F;span&gt;&lt;span&gt;: BTreeMap&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;), BTreeMap&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;), T&amp;gt;&amp;gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;x65535y255&lt;&#x2F;span&gt;&lt;span&gt;: BTreeMap&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;), BTreeMap&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;), T&amp;gt;&amp;gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;x255y65535&lt;&#x2F;span&gt;&lt;span&gt;: BTreeMap&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;), BTreeMap&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;), T&amp;gt;&amp;gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;x255y255&lt;&#x2F;span&gt;&lt;span&gt;: BTreeMap&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;), BTreeMap&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;), T&amp;gt;&amp;gt;,
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;T&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;NestedBTree&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;T&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; NestedBTree&amp;lt;T&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;Self &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            x255y255: BTreeMap::new(),
&lt;&#x2F;span&gt;&lt;span&gt;            x255y65535: BTreeMap::new(),
&lt;&#x2F;span&gt;&lt;span&gt;            x65535y255: BTreeMap::new(),
&lt;&#x2F;span&gt;&lt;span&gt;            x65535y65535: BTreeMap::new(),
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    #[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;(always)]
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;get &lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u16&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;y&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u16&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;z&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; Result&amp;lt;&amp;amp;T, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;&amp;#39;static str&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; x &amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;255 &lt;&#x2F;span&gt;&lt;span&gt;&amp;amp;&amp;amp; y &amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;255 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; child = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.x65535y65535.get(&amp;amp;((x&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, (y&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;)) {
&lt;&#x2F;span&gt;&lt;span&gt;                None =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;Err(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Not found&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;                Some(s) =&amp;gt; s,
&lt;&#x2F;span&gt;&lt;span&gt;            };
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; child = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; child.get(&amp;amp;((x%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, (y%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, z)) {
&lt;&#x2F;span&gt;&lt;span&gt;                None =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;Err(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Not found&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;                Some(s) =&amp;gt; s,
&lt;&#x2F;span&gt;&lt;span&gt;            };
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;Ok(&amp;amp;child);
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else if&lt;&#x2F;span&gt;&lt;span&gt; x &amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;255 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; child = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.x65535y255.get(&amp;amp;((x&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, y as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;)) {
&lt;&#x2F;span&gt;&lt;span&gt;                None =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;Err(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Not found&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;                Some(s) =&amp;gt; s,
&lt;&#x2F;span&gt;&lt;span&gt;            };
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; child = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; child.get(&amp;amp;((x%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, y as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, z)) {
&lt;&#x2F;span&gt;&lt;span&gt;                None =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;Err(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Not found&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;                Some(s) =&amp;gt; s,
&lt;&#x2F;span&gt;&lt;span&gt;            };
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;Ok(&amp;amp;child);
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else if&lt;&#x2F;span&gt;&lt;span&gt; y &amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;255 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; child = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.x255y65535.get(&amp;amp;(x as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, (y&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;)) {
&lt;&#x2F;span&gt;&lt;span&gt;                None =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;Err(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Not found&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;                Some(s) =&amp;gt; s,
&lt;&#x2F;span&gt;&lt;span&gt;            };
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; child = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; child.get(&amp;amp;(x as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, (y%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, z)) {
&lt;&#x2F;span&gt;&lt;span&gt;                None =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;Err(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Not found&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;                Some(s) =&amp;gt; s,
&lt;&#x2F;span&gt;&lt;span&gt;            };
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;Ok(&amp;amp;child);
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; child = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.x255y255.get(&amp;amp;(x as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, y as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;)) {
&lt;&#x2F;span&gt;&lt;span&gt;                None =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;Err(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Not found&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;                Some(s) =&amp;gt; s,
&lt;&#x2F;span&gt;&lt;span&gt;            };
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; child = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; child.get(&amp;amp;(x as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, y as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, z)) {
&lt;&#x2F;span&gt;&lt;span&gt;                None =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;Err(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;Not found&lt;&#x2F;span&gt;&lt;span style=&quot;color:#556633;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;                Some(s) =&amp;gt; s,
&lt;&#x2F;span&gt;&lt;span&gt;            };
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;Ok(&amp;amp;child);
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    #[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span&gt;(always)]
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fad07a;&quot;&gt;insert&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u16&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;y&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u16&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;z&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span&gt;: T) {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; x &amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;255 &lt;&#x2F;span&gt;&lt;span&gt;&amp;amp;&amp;amp; y &amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;255 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.x65535y65535.contains_key(&amp;amp;((x&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, (y&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;)){
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.x65535y65535.insert(((x&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, (y&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;), BTreeMap::new());
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; child = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.x65535y65535.get_mut(&amp;amp;((x&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, (y&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;)).unwrap();
&lt;&#x2F;span&gt;&lt;span&gt;            child.insert(((x%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, (y%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, z), value);
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else if&lt;&#x2F;span&gt;&lt;span&gt; x &amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;255 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.x65535y255.contains_key(&amp;amp;((x&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, y as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;)){
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.x65535y255.insert(((x&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, y as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;), BTreeMap::new());
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; child = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.x65535y255.get_mut(&amp;amp;((x&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, y as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;)).unwrap();
&lt;&#x2F;span&gt;&lt;span&gt;            child.insert(((x%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, y as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, z), value);
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else if&lt;&#x2F;span&gt;&lt;span&gt; y &amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;255 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.x255y65535.contains_key(&amp;amp;(x as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, (y&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;)){
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.x255y65535.insert((x as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, (y&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;), BTreeMap::new());
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; child = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.x255y65535.get_mut(&amp;amp;(x as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, (y&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;)).unwrap();
&lt;&#x2F;span&gt;&lt;span&gt;            child.insert((x as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, (y%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, z), value);
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.x255y255.contains_key(&amp;amp;(x as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, y as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;)){
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.x255y255.insert((x as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, y as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;), BTreeMap::new());
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; child = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.x255y255.get_mut(&amp;amp;(x as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, y as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;)).unwrap();
&lt;&#x2F;span&gt;&lt;span&gt;            child.insert((x as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, y as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbfdc;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, z), value);
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the results are much better (it&#x27;s the last test).  Around 25% faster and a good bit smaller memory footprint too:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#151515;color:#e8e8d3;&quot;&gt;&lt;code&gt;&lt;span&gt;Results for flat b-tree as XYZ: # of tests: 5, iterations = 2000000, width = 64000, serialize=true
&lt;&#x2F;span&gt;&lt;span&gt;minimum time = 590.74ms, maximum time = 673.3517ms, mean time = 615.34436ms, file size = 11.44 MiB
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Results for flat b-tree as ZXY: # of tests: 5, iterations = 2000000, width = 64000, serialize=true
&lt;&#x2F;span&gt;&lt;span&gt;minimum time = 857.0916ms, maximum time = 877.4087ms, mean time = 865.27806ms, file size = 11.44 MiB
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Results for deeply nested btree: # of tests: 5, iterations = 2000000, width = 64000, serialize=true
&lt;&#x2F;span&gt;&lt;span&gt;minimum time = 1.5320715s, maximum time = 1.5865624s, mean time = 1.54960012s, file size = 22.08 MiB
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Results for nested btree: # of tests: 5, iterations = 2000000, width = 64000, serialize=true
&lt;&#x2F;span&gt;&lt;span&gt;minimum time = 432.0617ms, maximum time = 450.3567ms, mean time = 440.51756ms, file size = 7.78 MiB
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I want to do one more test.  I want to see what 100,000,000 bytes inserted into the different B-trees looks like:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#151515;color:#e8e8d3;&quot;&gt;&lt;code&gt;&lt;span&gt;x,y,z insert finished...23.9162098s elapsed
&lt;&#x2F;span&gt;&lt;span&gt;x,y,z write finished...2.5539319s elapsed
&lt;&#x2F;span&gt;&lt;span&gt;x,y,z read finished...9.7052168s elapsed
&lt;&#x2F;span&gt;&lt;span&gt;x,y,z compare finished...33.5086576s elapsed
&lt;&#x2F;span&gt;&lt;span&gt;Data is the same = true
&lt;&#x2F;span&gt;&lt;span&gt;total elapsed = 71.030024s, iterations = 100000000, dimenions = 64000 X 64000 X 256, serialize&#x2F;deserialize = true
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;z,x,y insert finished...30.5735892s elapsed
&lt;&#x2F;span&gt;&lt;span&gt;z,x,y write finished...3.8273196s elapsed
&lt;&#x2F;span&gt;&lt;span&gt;z,x,y read finished...11.3962669s elapsed
&lt;&#x2F;span&gt;&lt;span&gt;z,x,y compare finished...46.5156209s elapsed
&lt;&#x2F;span&gt;&lt;span&gt;Data is the same = true
&lt;&#x2F;span&gt;&lt;span&gt;total elapsed = 94.0144163s, iterations = 100000000, dimenions = 256 X 64000 X 64000, serialize&#x2F;deserialize = true
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;deeply nested insert finished...40.1103969s elapsed
&lt;&#x2F;span&gt;&lt;span&gt;deeply nested write finished...10.5372181s elapsed
&lt;&#x2F;span&gt;&lt;span&gt;deeply nested read finished...14.5991097s elapsed
&lt;&#x2F;span&gt;&lt;span&gt;deeply nested compare finished...48.1683471s elapsed
&lt;&#x2F;span&gt;&lt;span&gt;Data is the same = true
&lt;&#x2F;span&gt;&lt;span&gt;total elapsed = 127.0032545s, iterations = 100000000, dimenions = 64000 X 64000 X 256, serialize&#x2F;deserialize = true
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;nested insert finished...16.0633079s elapsed
&lt;&#x2F;span&gt;&lt;span&gt;nested write finished...1.4942538s elapsed
&lt;&#x2F;span&gt;&lt;span&gt;nested read finished...10.3389582s elapsed
&lt;&#x2F;span&gt;&lt;span&gt;nested compare finished...17.84099s elapsed
&lt;&#x2F;span&gt;&lt;span&gt;Data is the same = true
&lt;&#x2F;span&gt;&lt;span&gt;total elapsed = 48.4802249s, iterations = 100000000, dimenions = 64000 X 64000 X 256, serialize&#x2F;deserialize = true
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Results for flat b-tree as XYZ: # of tests: 1, iterations = 100000000, width = 64000, serialize=true
&lt;&#x2F;span&gt;&lt;span&gt;minimum time = 71.030024s, maximum time = 71.030024s, mean time = 71.030024s, file size = 572.20 MiB
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Results for flat b-tree as ZXY: # of tests: 1, iterations = 100000000, width = 64000, serialize=true
&lt;&#x2F;span&gt;&lt;span&gt;minimum time = 94.0144163s, maximum time = 94.0144163s, mean time = 94.0144163s, file size = 572.20 MiB
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Results for deeply nested btree: # of tests: 1, iterations = 100000000, width = 64000, serialize=true
&lt;&#x2F;span&gt;&lt;span&gt;minimum time = 127.0032545s, maximum time = 127.0032545s, mean time = 127.0032545s, file size = 1053.44 MiB
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Results for nested btree: # of tests: 1, iterations = 100000000, width = 64000, serialize=true
&lt;&#x2F;span&gt;&lt;span&gt;minimum time = 48.4802249s, maximum time = 48.4802249s, mean time = 48.4802249s, file size = 382.73 MiB
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Not bad.  It&#x27;s a good bit faster on all metrics, except for deserializing, which was just a tad slower than the flat B-tree.  Memory footprint is also much improved.  Now I can move on to terrain generation.&lt;&#x2F;p&gt;
&lt;p&gt;Source code from this post is available at &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;0xDEADFED5&#x2F;dwarf_dreams&#x2F;tree&#x2F;main&#x2F;btree_test&#x2F;src&quot;&gt;btree_test&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>[ insert title here ]</title>
        <published>2023-03-21T00:00:00+00:00</published>
        <updated>2023-03-21T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="https://dwarfdreams.com/about/" type="text/html"/>
        <id>https://dwarfdreams.com/about/</id>
        
        <content type="html">&lt;p&gt;This blog is a record of my attempt at making a Dwarf Fortress clone in Rust, as the very first thing I&#x27;ve ever coded in &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Rust_(programming_language)&quot;&gt;Rust&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m creating my clone because I want it to be faster (on modern hardware) and have different bugs.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Contact me at admin@dwarfdreams.com&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Welcome</title>
        <published>2023-03-21T00:00:00+00:00</published>
        <updated>2023-03-21T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="https://dwarfdreams.com/welcome/" type="text/html"/>
        <id>https://dwarfdreams.com/welcome/</id>
        
        <content type="html">&lt;h3 id=&quot;welcome-to-dwarfdreams-com&quot;&gt;Welcome to DwarfDreams.com!&lt;&#x2F;h3&gt;
&lt;p&gt;This site will chronicle my work on a game I&#x27;m making: a clone of a game called Dwarf Fortress by &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.bay12games.com&#x2F;dwarves&#x2F;&quot;&gt;Bay 12 Games&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Here are my plans in no particular order:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Coded in Rust&lt;&#x2F;li&gt;
&lt;li&gt;Fully threaded, will use all available CPU cores&lt;&#x2F;li&gt;
&lt;li&gt;Custom OpenGL 3.3 tilemap engine&lt;&#x2F;li&gt;
&lt;li&gt;Windows&#x2F;Mac&#x2F;Linux compatibility (hence the OpenGL)&lt;&#x2F;li&gt;
&lt;li&gt;Animated characters (gratefully accepting art submissions!)&lt;&#x2F;li&gt;
&lt;li&gt;No concept of &#x27;embark area&#x27;, world can be freely explored&lt;&#x2F;li&gt;
&lt;li&gt;Implement all systems of Dwarf Fortress&lt;&#x2F;li&gt;
&lt;li&gt;Support importation of DF raws&lt;&#x2F;li&gt;
&lt;li&gt;Fix bugs&#x2F;annoyances in DF that I personally want to fix&lt;&#x2F;li&gt;
&lt;li&gt;Add some DFHack features like blueprints&lt;&#x2F;li&gt;
&lt;li&gt;Simplify language system to facilitate future translations&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Longer term goals:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Adventure mode&lt;&#x2F;li&gt;
&lt;li&gt;Lua scripting for mods&lt;&#x2F;li&gt;
&lt;li&gt;My own added features&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;dwarfdreams.com&#x2F;welcome&#x2F;dwarf.jpg&quot; alt=&quot;&quot; &#x2F;&gt;
Do six-fingered dwarves dream of electric ale?&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
