Code 'n Stuff2019-01-16T17:36:15-08:00http://www.elliotglaysher.org/Elliot Glaysherglaysher@umich.edurlvm 0.14 released!2014-10-04T00:00:00-07:00http://eglaysher.github.com/2014/10/04/rlvm-14-released<p>rlvm 0.14 adds support for the <a href="http://store.steampowered.com/app/316720/">US edition of planetarian</a> and the Japanese all ages edition of Kud Wafter. It also further attempts to make animations smoother.</p>
<p>I’ve also added a bitcoin donation widget to the rlvm main page. If you’ve found rlvm useful over the last eight years, consider making a donation in Bitcoin to <a href="https://blockchain.info/address/1AXqsVMXgpdjoDZF7995NXbVgGxVUKEDSc">1AXqsVMXgpdjoDZF7995NXbVgGxVUKEDSc</a>.</p>
<p><a href="http://rlvm.net/2014/10/04/rlvm-14-released.html">
Comment</a></p>
<h3>Download</h3>
<p>
<a href="https://github.com/eglaysher/rlvm/releases/download/release-0.14/rlvm_0.14_i386.deb">Ubuntu (Precise) package for x86 machines (version 0.14)</a><br />
<a href="https://github.com/eglaysher/rlvm/releases/download/release-0.14/rlvm_0.14_amd64.deb">Ubuntu (Precise) package for amd64 machines (version 0.14)</a><br />
<a href="https://github.com/eglaysher/rlvm/releases/download/release-0.14/rlvm_0.14.dmg">Mac OSX Application (Intel) (version 0.14)</a><br />
<a href="http://github.com/eglaysher/rlvm/tarball/release-0.14">Source code (0.14)</a>
</p>
rlvm 0.13 released!2013-10-13T00:00:00-07:00http://eglaysher.github.com/2013/10/13/rlvm-13-released<p>rlvm should now do a much better job running Little Busters. It should also detect if the user tried to run a game before installing an English patch and offer to reset save game data.</p>
<p>“lurkmore” has written tonecurve support, so character sprites should be tinted in scenes with different lighting conditions. In addition, there are major changes to the graphics system to allow for sepia effects, colour tinting, and new animation primitives.</p>
<p><a href="http://rlvm.net/2013/10/13/rlvm-13-released.html">
Comment</a></p>
<h3>Download</h3>
<p>
<a href="https://github.com/eglaysher/rlvm/releases/download/release-0.13/rlvm_0.13_i386.deb">Ubuntu (Precise) package for x86 machines (version 0.13)</a><br />
<a href="https://github.com/eglaysher/rlvm/releases/download/release-0.13/rlvm_0.13_amd64.deb">Ubuntu (Precise) package for amd64 machines (version 0.13)</a><br />
<a href="https://github.com/eglaysher/rlvm/releases/download/release-0.13/rlvm_0.13.dmg">Mac OSX Application (Intel) (version 0.13)</a><br />
<a href="http://github.com/eglaysher/rlvm/tarball/release-0.13">Source code (0.13)</a></br />
</p>
Chrome Sync and Android2011-08-27T00:00:00-07:00http://eglaysher.github.com/2011/08/27/chrome-sync-and-android<p>A word of caution; last night I enabled the new “Encrypt all synced data” option in Google Chrome. It is <em>awesome</em> that we now offer this.</p>
<p>The Android browser also talks to the chrome sync servers; their (not Chrome) browser in Honeycomb 3.1 looks like it doesn’t handle encryption yet, and crashes hard when the option is enabled on my G-Slate. Periodically, the com.google.process.gapps process crashes, often while I’m doing something else on my tablet. Looking at the output of <code>adb logcat</code>:</p>
<pre><code>E/AndroidRuntime( 2861): FATAL EXCEPTION: SyncAdapterThread-1
E/AndroidRuntime( 2861): java.lang.NullPointerException
E/AndroidRuntime( 2861): at com.google.android.syncadapters.
bookmarks.BookmarksSyncAdapter.innerPerformSync(
BookmarksSyncAdapter.java:562)
E/AndroidRuntime( 2861): at com.google.android.syncadapters.
bookmarks.BookmarksSyncAdapter.onPerformLoggedSync(
BookmarksSyncAdapter.java:246)
E/AndroidRuntime( 2861): at com.google.android.common.
LoggingThreadedSyncAdapter.onPerformSync(
LoggingThreadedSyncAdapter.java:33)
E/AndroidRuntime( 2861): at android.content.
AbstractThreadedSyncAdapter$SyncThread.run(
AbstractThreadedSyncAdapter.java:202)
</code></pre>
<p>So…don’t turn on encryption on all your browser sync data in Chrome if you have a Honeycomb tablet! Since you can’t disable this once it’s on in Chrome, the workaround is unchecking Accounts & sync > (your Google account) > Sync Browser until their browser supports encrypted datatypes.</p>
<p>(In general, if you’re wondering why something is crashing, you can usually get a good idea by using <code>adb logcat</code> from the Android development SDK or one of the logcat programs on Market.)</p>
Life Counter and Honeycomb2011-07-17T00:00:00-07:00http://eglaysher.github.com/2011/07/17/life-counter-and-honeycomb<p>A little under a month ago, I got a Honeycomb tablet. While trying it out, I noticed that some apps would only display in a small box on the top of the screen. Including <a href="/lifecounter/">Life Counter</a>, my app.</p>
<p>Oops.</p>
<p>I spent most of yesterday evening and today on the update and theoretically, the <a href="https://market.android.com/details?id=org.elliotglaysher.lifecounter">update is live</a>, though I had to clear the My Apps cache on my Honeycomb tablet. (My Gingerbread phone had no problem immediately detecting
the update).</p>
<p>Here is what I think of the process of Honeycombizing an Android app:</p>
<ul>
<li>
<p>When I first started writing Android apps, I was confused about why they emphasized using XML based resources for layout. There had to have been simpler ways to deal with different layouts for orientation. Now that Life Counter supports multiple form factors, I understand and it’s one of the best things about development for Android.</p>
<p>The ability to have an image, and then have another version for larger screens is a really good abstraction. I have four different copies of the 4 player layout depending on orientation and screen size and they’re all treated the same from code. The runtime will determine the best version for the current situation and present that to my app.</p>
</li>
<li>
<p>Integration with the ActionBar is…interesting. In <a href="https://github.com/eglaysher/lifecounter/blob/a04951c36856ab947af82d891df5740f2b642762/src/org/elliotglaysher/lifecounter/LifeCounter.java#L46">the main LifeCounter activity</a>, I use Google’s backwards compatibility library to mark the coin flip menu item so it’ll both activate the display of the action bar and put it in.</p>
<p>Everywhere else, I have Honeycomb specific subclasses. For example, <a href="https://github.com/eglaysher/lifecounter/blob/a04951c36856ab947af82d891df5740f2b642762/src/org/elliotglaysher/lifecounter/coin2d/Coin2DActivityHC.java">Coin2DActivityHC</a> derives from <a href="https://github.com/eglaysher/lifecounter/blob/a04951c36856ab947af82d891df5740f2b642762/src/org/elliotglaysher/lifecounter/coin2d/Coin2DActivity.java">Coin2DActivity</a>, and then <a href="https://github.com/eglaysher/lifecounter/blob/a04951c36856ab947af82d891df5740f2b642762/src/org/elliotglaysher/lifecounter/LifeCounter.java#L133">LifeCounter selects which activity to run</a> at runtime. I almost never do Java; I’m a little shocked that I can compile classes that require certain APIs into “binaries” that are run on systems that don’t provide those APIs. I suppose that makes sense if class loading is lazy and binding doesn’t happen until loading time, though it still was unexpected. (In my defense, I come from a world that still uses <code>dysym()</code>).</p>
</li>
</ul>
rlvm 0.12 released!2011-05-15T00:00:00-07:00http://eglaysher.github.com/2011/05/15/rlvm-12-released<p>rlvm 0.12: The User Interface Release!</p>
<div style="float: right"><img src="/rlvm/images/icon-in-dock.png" /></div>
<p>rlvm is now a desktop application on Linux, meaning it can be started from your Applications menu or dock and will use GTK+ dialogs to select the game! On all platforms, rlvm will now report error messages to the user through native alert dialogs instead of just crashing! You can see rlvm’s new icon to the right.</p>
<div class="downloadinfo">
<h2>Downloads</h2>
<ul>
<li class="ubuntuicon">
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.12_i386.deb" onclick="_gaq.push(['_trackEvent', 'Download', 'rlvm_0.12_i386.deb']);">
Ubuntu (Natty) package for x86 machines (version 0.12)
</a>
</li>
<li class="ubuntuicon">
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.12_amd64.deb" onclick="_gaq.push(['_trackEvent', 'Download', 'rlvm_0.12_amd64.deb']);">
Ubuntu (Natty) package for amd64 machines (version 0.12)
</a>
</li>
<li class="macicon">
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.12.dmg" onclick="_gaq.push(['_trackEvent', 'Download', 'rlvm_0.12.dmg']);">
Mac OSX Application (Intel) (version 0.12)
</a>
</li>
<li class="sourceicon">
<a href="http://github.com/eglaysher/rlvm/tarball/release-0.12" onclick="_gaq.push(['_trackEvent', 'Download', 'source-0.12']);">
Source code (0.12)
</a>
</li>
</ul>
</div>
Lessons on native window/SDL integration.2011-05-05T00:00:00-07:00http://eglaysher.github.com/2011/05/05/lessions-on-native-sdl-integration<p><a href="http://www.libsdl.org">libSDL</a> is great for doing simple, cross-platform game development, though it’s currently showing its age a bit. I recently tried ripping out a set of in game widgets from <a href="http://rlvm.net">rlvm</a> and replaced them with native GTK+ and Cocoa interfaces. I had to backtrack because fullscreen broke HARD, though I’m putting down these notes so the next brave soul to come through knows the ups and downs.</p>
<p>SDL doesn’t make this easy, but you can sort of do this as long as you don’t want to mix SDL content and native widgets in the same window and you don’t have a fullscreen option. Native right-click menus and dialogs are possible. It just takes a bit of work on each platform. This is more a rambling list of things you might want to keep in mind.</p>
<ul>
<li>
<p>The Cocoa port of SDL gives you a real <code>NSWindow</code>; if you’re using the Cocoa SDLMain library you already have a real <code>NSApplication</code> too, which you can customize and add categories to. Interacting with Cocoa elements (<code>NSAlert</code>s, <code>NSMenu</code>s, etc) seems to pause the SDL’s timer. I’m not sure if most actions are spinning up a nested runloop, but the programmer doesn’t need to do anything custom event handling to get NSAlerts and NSMenus running.</p>
</li>
<li>
<p>The X11 port of SDL gives you no such help if you want to integrate with GTK+. Any interaction you want to do needs to be through raw <a href="http://en.wikipedia.org/wiki/Xlib">xlib</a> calls. You’ll need to consider the following:</p>
<p>a. You’ll need to collaborate with GTK’s runloop, which means calling <code>while (gtk_events_pending()) gtk_main_iteration();</code> each iteration through the gameloop to handle events on GTK+ windows.</p>
<p>b. You’ll need to pause your game manually while native dialogs are up. Make sure to offset the number of ticks supplied by <a href="http://sdl.beuc.net/sdl.wiki/SDL_GetTicks"><code>SDL_GetTicks()</code></a> if you use that for animation or other timing.</p>
<p>c. You’ll need to manually do all window management. GTK+ has nice functions for hinting to the OS that one window is a dialog of another window. You will need to do all the emulation of this yourself. You’ll need to handle the position of dialogs manually and you’ll need to emulate dialog modality by bringing the current GTK+ dialog window to the front on mouse and activate events.</p>
<p>d. If you have right click menus that are dismissed on mousedown, the mouseup event might get passed to SDL. Your SDL event handling has to deal with this case.</p>
<p>e. Relatively minor, but <a href="http://sdl.beuc.net/sdl.wiki/SDL_WM_SetIcon"><code>SDL_WM_SetIcon()</code></a> only takes a single SDL_Surface for its icon. Most modern applications have their icons drawn in multiple sizes. rlvm’s 16x16 small application icon is different from its 64x64 and larger icon. If you want to handle this correctly, you’ll need to set this manually in raw xlib.</p>
</li>
<li>
<p>Make sure to call <a href="http://sdl.beuc.net/sdl.wiki/SDL_WM_SetCaption"><code>SDL_WM_SetCaption()</code></a> after calling <a href="http://sdl.beuc.net/sdl.wiki/SDL_Init"><code>SDL_Init()</code></a>, but before calling <a href="http://sdl.beuc.net/sdl.wiki/SDL_SetVideoMode"><code>SDL_SetVideoMode()</code></a> with the correct iconified name of your program. Some newer Linux docks will get confused and won’t attribute your new window to your application if you’ve already opened up a GTK+ window.</p>
</li>
<li>
<p>If you have a fullscreen option, you should either disable it or give up on your native dialog integration project. In both the X11 and Cocoa ports, trying to bring up a dialog while the SDL window is fullscreen doesn’t display the dialog. This made me abandon dialogs during gameplay, but you can still use some of the above to show native dialogs before you bring up your SDL window. ( If you want an example of how something like this is implemented, the platform directories in rlvm (<a href="https://github.com/eglaysher/rlvm/tree/master/src/Platforms/osx">Cocoa</a>, <a href="https://github.com/eglaysher/rlvm/tree/master/src/Platforms/gtk">GTK+</a>) make good reading.)</p>
</li>
</ul>
rlvm 0.11 released!2011-03-06T00:00:00-08:00http://eglaysher.github.com/2011/03/06/rlvm-11-released<p>rlvm 0.11 has bug fixes for everyone! There are graphics glitches fixes and
previously unimplemented graphics commands. There are sound playback and volume
bugfixes. There are text dispay and automode bugfixes.</p>
<p>New features? We have your new features right here: “Return to Previous
Selection” buttons are now enabled and work. Voice clip replay buttons now show
up in the scrollback.</p>
<p>Download now and we’ll throw in performance fixes absolutely free! rlvm will no
longer spend 10% of runtime hopelessly searching your game’s folders for files
that are guarenteed to not exist!</p>
<p><a href="http://www.elliotglaysher.org/rlvm/2011/03/06/rlvm-11-released.html">
Comment</a></p>
<div class="downloadinfo">
<h2>Downloads</h2>
<ul>
<li class="ubuntuicon">
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.11_i386.deb" onclick="_gaq.push(['_trackEvent', 'Download', 'rlvm_0.11_i386.deb']);">
Ubuntu (Maverick) package for x86 machines (version 0.11)
</a>
</li>
<li class="ubuntuicon">
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.11_amd64.deb" onclick="_gaq.push(['_trackEvent', 'Download', 'rlvm_0.11_amd64.deb']);">
Ubuntu (Maverick) package for amd64 machines (version 0.11)
</a>
</li>
<li class="macicon">
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.11.dmg" onclick="_gaq.push(['_trackEvent', 'Download', 'rlvm_0.11.dmg']);">
Mac OSX Application (Intel) (version 0.11)
</a>
</li>
<li class="sourceicon">
<a href="http://github.com/eglaysher/rlvm/tarball/release-0.11" onclick="_gaq.push(['_trackEvent', 'Download', 'source-0.11']);">
Source code (0.11)
</a>
</li>
</ul>
</div>
rlvm 0.10 released!2011-02-02T00:00:00-08:00http://eglaysher.github.com/2011/02/02/rlvm-10-released<p>With rlvm 0.10, Tomoyo After Memorial Edition is now completable. In addition, we now support voices in Planetarian (Tomoyo After and Planetarian shared a common voice archive format, NWK).</p>
<p>Multiple issues regarding glosses in rlBabel have been fixed, along with graphical glitches.</p>
<p><a href="http://rlvm.net/2011/02/02/rlvm-10-released.html">Comment</a></p>
<div class="downloadinfo">
<h2>Downloads</h2>
<ul>
<li class="ubuntuicon">
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.10_i386.deb" onclick="_gaq.push(['_trackEvent', 'Download', 'rlvm_0.10_i386.deb']);">
Ubuntu (Maverick) package for x86 machines (version 0.10)
</a>
</li>
<li class="ubuntuicon">
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.10_amd64.deb" onclick="_gaq.push(['_trackEvent', 'Download', 'rlvm_0.10_amd64.deb']);">
Ubuntu (Maverick) package for amd64 machines (version 0.10)
</a>
</li>
<li class="macicon">
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.10.dmg" onclick="_gaq.push(['_trackEvent', 'Download', 'rlvm_0.10.dmg']);">
Mac OSX Application (Intel) (version 0.10)
</a>
</li>
<li class="sourceicon">
<a href="http://github.com/eglaysher/rlvm/tarball/release-0.10" onclick="_gaq.push(['_trackEvent', 'Download', 'source-0.10']);">
Source code (0.10)
</a>
</li>
</ul>
</div>
rlvm 0.09 released!2010-10-16T00:00:00-07:00http://eglaysher.github.com/2010/10/16/rlvm-09-released<p>As of rlvm 0.9, there is now preliminary Little Busters! support. Currently, only the original version of Little Busters is supported. While the entire game is completable, there are major graphics artifacts and the majority of ending sequences are garbled or just blank.</p>
<p>In addition, new saved games should save the current state of the screen properly. Previous versions of rlvm didn’t know how to save some commonly used graphics effects, leading to a blank background on game load. Hopefully, the new system is future proof to new graphics commands that I’ll implement.</p>
<p>Several other regressions were also fixed.</p>
<p><a href="http://rlvm.net/2010/10/16/rlvm-09-released.html">Comment</a></p>
<h2>Downloads</h2>
<ul>
<li class="ubuntuicon">
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.9_i386.deb" onclick="_gaq.push(['_trackEvent', 'Download', 'rlvm_0.9_i386.deb']);">
Ubuntu (Lucid) package for x86 machines (version 0.09)
</a>
</li>
<li class="ubuntuicon">
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.9_amd64.deb" onclick="_gaq.push(['_trackEvent', 'Download', 'rlvm_0.9_amd64.deb']);">
Ubuntu (Lucid) package for amd64 machines (version 0.09)
</a>
</li>
<li class="macicon">
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.9.dmg" onclick="_gaq.push(['_trackEvent', 'Download', 'rlvm_0.9.dmg']);">
Mac OSX Application (Intel) (version 0.09)
</a>
</li>
<li class="sourceicon">
<a href="http://github.com/eglaysher/rlvm/tarball/release-0.09" onclick="_gaq.push(['_trackEvent', 'Download', 'source-0.9']);">
Source code (0.09)
</a>
</li>
</ul>
rlvm 0.08 released!2010-02-01T00:00:00-08:00http://eglaysher.github.com/2010/02/01/rlvm-08-released<p>rlvm 0.8 is a major update focusing on supporting previously unsupported
features of RealLive. rlvm now can read HIK animation files, such as those used
in the Planetarian opening sequence. rlvm can also now do weather effects:
snow, sakura petals, balls of light, etc. These effects are used in pretty much
every game I can find. rlvm also now does a better job line-breaking Japanese text. There are certain rules about certain characters not being the first character on a line that rlvm previously failed to implement correctly.</p>
<p>This version contains a fairly serious fix where, on certain graphics card
drivers, some (but not all) images would have their blue and red color
components swapped.</p>
<p>Due to a combination of my G4 laptop dying, Apple no longer supporting PPC
chips with the release of Snow Leopard, and difficulties with several libraries
I use on the PPC platform, rlvm 0.8 and future releases will be Intel only on
the Mac.</p>
<p><a href="http://www.elliotglaysher.org/rlvm/2010/02/01/rlvm-08-released.html">
Comment</a></p>
<h3>Download</h3>
<p>
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.8_i386.deb">Ubuntu (Karmic) package for x86 machines (version 0.08)</a><br />
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.8_amd64.deb">Ubuntu (Karmic) package for amd64 machines (version 0.08)</a><br />
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.8.dmg">Mac OSX Application (Intel) (version 0.08)</a><br />
<a href="http://github.com/eglaysher/rlvm/tarball/release-0.08">Source code (0.08)</a>
</p>
rlvm in Debian Unstable2009-12-18T00:00:00-08:00http://eglaysher.github.com/2009/12/18/rlvm-in-debian<p>The <a href="http://bugs.debian.org/535024">ITP bug on packaging rlvm for Debian</a> has been closed. The latest version of rlvm is in <a href="http://packages.debian.org/sid/rlvm">Debian unstable</a>. :)</p>
LifeCounter Open Sourced!2009-12-12T00:00:00-08:00http://eglaysher.github.com/2009/12/12/lifecounter-opensourced<p><a href="/lifecounter/">LifeCounter</a> has been open sourced. The <a href="http://www.github.com/eglaysher/lifecounter">source code</a> is now publicly available on <a href="http://www.github.com/">GitHub</a>.</p>
Google Chrome for Linux Beta2009-12-08T00:00:00-08:00http://eglaysher.github.com/2009/12/08/google-chrome-for-linux-beta<p><img class="alignright" src="/images/2009-12-08-google-chrome-for-linux-beta/lego.jpg" />
It’s been a really long road but it’s finally done. The Linux and Mac betas are out.</p>
<p>I did some work on the Mac port and was included in the <a href="http://www.google.com/chrome/intl/en/huzzah.html">release photograph…as lego</a>. (I’ve separated out “my” lego man to the side for quick identification.) I like mine, but <a href="http://twitter.com/mikepinkerton">Mike Pinkerton</a> has both the best lego man and the best pose.</p>
<p>Even better, in <a href="http://chrome.blogspot.com/2009/12/google-chrome-for-holidays-mac-linux.html">today’s big post on the release</a>, the one screenshot for linux is showing off my GTK theme integration in its final form. I’ve made a lot of progress since I first put up <a href="/2009/07/02/gtk-themes-in-chromium/">my first experiments</a> with the interface. Let’s compare that with what the beta looks like:</p>
<p><img src="/images/2009-12-08-google-chrome-for-linux-beta/albatross.png" alt="Current Google Chrome interface" /></p>
<p><em>Google Chrome for Linux Beta with the Albatross GTK theme</em></p>
rlvm 0.07 released!2009-11-15T00:00:00-08:00http://eglaysher.github.com/2009/11/15/rlvm-07-released<p>rlvm 0.7 is a major update. rlvm now supports AIR, along with several other
non-KEY games (see <a href="http://github.com/eglaysher/rlvm/blob/master/STATUS.TXT">STATUS.TXT</a>). rlvm is now at the point where random older RealLive games <em>may</em> work. It can now read KOE voice archives used by older games, as well as voice patches that are loose <a href="http://en.wikipedia.org/wiki/Vorbis">Ogg Vorbis</a> files (such as the one for KANON). In addition, there’s been a large number of small, minor graphical fixes, including faces in text boxes, text shadow in text boxes, visual appearance of #SELBTNs (such as in Fuuko’s route), and various shading effects.</p>
<p>Because of problems in previous versions of the boost::serialization library,
preferences such as text box color and text speed will not be read with rlvm
0.7. Saved games were not subject to the corruption bugs and should continue to
work.</p>
<p><a href="http://rlvm.net/2009/11/15/rlvm-07-released.html">Comment</a></p>
The Hardest Bug2009-11-07T00:00:00-08:00http://eglaysher.github.com/2009/11/07/hardest-bug<p>This article is long. It covers a bug that took weeks to understand what the problem was and is easily the hardest bug I’ve ever had to track down.</p>
<h2 id="background-the-stage">Background: The stage</h2>
<p><a href="/rlvm/">rlvm</a> is my open source reimplementation of RealLive, a commercial Japanese game engine and scripting system which is used for some fairly niche games. RealLive is a fast Turing-complete bytecode interpreter with a set of standard functions for text, graphics, sound, music and animation. So a programmer would write the game in some unknown scripting language and the game would be compiled into a SEEN.TXT, a binary archive format that contains compiled bytecode.</p>
<p>Because several popular Japanese anime series have been written based off of said games, there’s been interest in the West about playing them. This has lead to a man named named <a href="http://haeleth.net/">Haeleth</a> documenting the inner workings of RealLive and he released an assembler/disassembler for the bytecode format called <a href="http://dev.haeleth.net/rldev.shtml">rldev</a>, which rlvm would have been impossible without. He’s also made a translation tool named rlBabel which I’ll get to in a bit.</p>
<p><a href="http://en.wikipedia.org/wiki/Clannad_(visual_novel)">CLANNAD</a> is one such game. rlvm could play the Japanese version of CLANNAD, but now it was being translated in a wiki. Scripts were disassembled with rldev, which separated the code into a disassembled bytecode file and a string resource file. The string resource files are uploaded to the wiki and translated. The translated string resource files are fed back to rldev to compile a version translated into English.</p>
<p>These games are <em>heavily</em> text based (the genre is called visual novels for a reason) and the bytecode format reflects this. Any quoted freeform text is allowed and is simply printed to screen. There’s an opcode to print out a piece of memory (<code>strout()</code> and <code>intout()</code>) for the uncommon case where a piece of text was built up programmatically in a buffer, but this is rarely used in real games. The bytecode therefore needs to be tokenized into text, commands, debugging symbols, and the raw ASTs which are how math expressions are stored.</p>
<h2 id="the-problem">The problem</h2>
<p>I announced being able to play translated CLANNAD files in version 0.06 of rlvm and everything seemed to work. The translation project then issued a new file with debugging symbols stripped, which shaved several megabytes off the SEEN.TXT file. The problem: It didn’t work in rlvm. The game appeared to work fine as usual, except that it never displayed any text. From the same source code, a SEEN.TXT file compiled with debugging symbols worked, and the stripped SEEN.TXT file didn’t. The game appeared to work, but no text was displayed on screen.</p>
<p><img src="/images/2009-11-07-hardest-bug/broken.jpg" alt="No text in the Text box" title="No text in the box" /></p>
<h2 id="rlbabel-how-these-games-are-translated">rlBabel: How these games are translated</h2>
<p>Haeleth is responsible for pretty much all the tools to translate a game from Japanese into some other language. Japanese text is laid out monospace, contains no spaces between words and, with <a href="http://en.wikipedia.org/wiki/Kinsoku_shori">some exceptions</a>, can be line-broken anywhere, including in the middle of a word. To get around this, Haeleth wrote an additional library: rlBabel, meant to add Western linebreaking rules to a Japanese game engine and added support for rlBabel to his compiler suite.</p>
<p>When you compile a game with rldev and rlBabel turned on, instead of inserting:</p>
<pre><code>"Text to output"
</code></pre>
<p>which goes through the raw, static text interface, it does the equivalent of the following:</p>
<pre><code>strout("") {- Manually call the text system to display a window -}
strcpy(buffer, "Text to output")
Call a DLL with buffer which appends it to an internal buffer
gosub displayText
...
displayText: {- One copy per translation unit -}
loop forever:
retVal = Call a DLL asking about what the bytecode should do.
if retVal is New Line
<cause a new line to be printed>
else if retVal is Print Character
<prints the current character>
<manually moves the text insertion point to where the DLL wants it>
else if retVal is End of String
gosub_return
</code></pre>
<p>So half of rlBabel is some headers that get compiled into your SEEN.TXT, and the other half is a big DLL which does font metrics, text tokenization and feeds the data back to the bytecode side. rlvm has the DLL code compiled into it, slightly modified. A previously translated game can be played start to finish in rlvm.</p>
<p>If you think this is ridiculously over-engineered, attempts to <a href="http://svn.haeleth.net/pub/rldev/lib/textout.kh">do it all in bytecode</a> are worse, not to mention less accurate. Also, it’s almost unusably slow.</p>
<h2 id="debugging-symbols-obscure-the-error">Debugging symbols obscure the error</h2>
<p>After weeks of working on debugging this, with quite a large number of false starts and dead ends, I figured several things out:</p>
<ul>
<li>My in memory representation of the bytecode was equivalent between the two input files, sans line markers, which only exist to say “Line XXX in the source starts here.” Except for line markers, the files were being parsed identically.</li>
<li>My implementation of rlBabel wasn’t to blame. The DLL interface was being called properly, but was mysteriously always passed the empty string as its input buffer. The bytecode would ask the DLL what to do, and my code would sensibly return <code>getcEndOfString</code>.</li>
<li>I then printed out each opcode as it was executed. <code>strcpy()</code> was never being called in the SEEN.TXT file that had debugging symbols stripped.</li>
</ul>
<p>The behaviour in game made sense. A text window would be displayed by the manual printing of an empty string, and nothing else was printed because rlBabel’s input buffer was empty. The rest of the game appeared to work because the only thing broken was something to do with getting data into rlBabel’s input buffer.</p>
<p>In my design, the implementation of each bytecode was responsible for incrementing the instruction pointer. The bug: The instruction pointer was being advanced by the function that caused text to be printed to the screen; it was not incremented after a textout element was finished. This appeared to work because the textout implementation just called that function.</p>
<p>But <code>strout()</code> also called this same low level function. Then <code>strout()</code> incremented the instruction pointer again because it was a function element. The instruction pointer was advanced twice and skipped the call to <code>strcpy()</code>.</p>
<p>Wait, but why did things work with debug symbols? Let’s take a look at the sequence of bytecode elements that one text line and one pause command compile to:</p>
<table>
<tr>
<th>#</th>
<th>Source</th>
<th>With Debug</th>
<th>Without Debug</th>
</tr>
<tr>
<td>1</td>
<td> "Line of Text" </td>
<td> <em>Line marker</em> </td>
<td> </td>
</tr>
<tr>
<td>2</td>
<td> </td>
<td> <em>Kidoku marker</em> </td>
<td> <em>Kidoku marker</em> </td>
</tr>
<tr>
<td>3</td>
<td> </td>
<td> <code>strout</code> </td>
<td> <code>strout</code> </td>
</tr>
<tr>
<td>4</td>
<td> </td>
<td> <em>Line marker</em> </td>
<td> </td>
</tr>
<tr>
<td>3</td>
<td> </td>
<td> <code>strcpy</code> </td>
<td> <code>strcpy</code> </td>
</tr>
<tr>
<td>4</td>
<td> </td>
<td> <em>Line marker</em> </td>
<td> </td>
</tr>
<tr>
<td>5</td>
<td> </td>
<td> <em>Goto</em> </td>
<td> <em>Goto</em> </td>
</tr>
<tr>
<td>6</td>
<td> </td>
<td> <em>Goto</em> </td>
<td> <em>Goto</em> </td>
</tr>
<tr>
<td>7</td>
<td> </td>
<td> <em>Line marker</em> </td>
<td> </td>
</tr>
<tr>
<td>8</td>
<td> </td>
<td> <em>Goto</em> </td>
<td> <em>Goto</em> </td>
</tr>
<tr>
<td>9</td>
<td> </td>
<td> <em>Goto</em> </td>
<td> <em>Goto</em> </td>
</tr>
<tr>
<td>10</td>
<td> <code>pause</code> </td>
<td> <em>Line marker</em> </td>
<td> </td>
</tr>
<tr>
<td>11</td>
<td> </td>
<td> <code>pause</code> </td>
<td> <code>pause</code> </td>
</tr>
</table>
<p>Ignore the gotos; they are an implementation detail of rlBabel. In the debug version, when <code>strout()</code> finishes, the instruction pointer is incremented by two and is placed on <code>strcpy()</code>. The skipped bytecode is a line marker which doesn’t matter. In the version stripped of line markers, when <code>strout()</code> finishes, it jumps over the <code>strcpy()</code> that loads text into rlBabel’s buffer and jumps straight into rlBabel’s implementation.</p>
<p><a href="http://github.com/eglaysher/rlvm/commit/6a116d6b055a8afb9a9bc384a82167440f31a33a">The fix to this was a two line patch</a>.</p>
<p><img src="/images/2009-11-07-hardest-bug/fixed.jpg" alt="Fixed!" title="Text displayed after fix" /></p>
Life Counter and the Android Market2009-08-29T00:00:00-07:00http://eglaysher.github.com/2009/08/29/on-the-android-app-store<p>Back in March, I <a href="/2009/03/15/on-writing-for-android/">tried writing something</a> on the Google Android platform, and released improvements over the next month. <a href="/lifecounter/">LifeCounter</a>, a small app to keep track of the history in a Magic the Gathering game, has now been released for almost six months. As I don’t work on LifeCounter anymore, this is a postmortem.</p>
<h2 id="android-markets-user-comments-are-equivalent-to-those-on-youtube">Android Market’s user comments are equivalent to those on Youtube.</h2>
<p>There was begging for a <a href="http://www.yugiohtheabridgedseries.com/">YuGiOh</a> version. There were two star comments saying that this was great work. There were a lot of comments that were just incoherent. Here are two of my favorite worst comments on the free version of Life Counter:</p>
<blockquote>
<p>This is AWESOME! Too bad none of us will ever get a girlfriend :(
(Five stars)</p>
</blockquote>
<blockquote>
<p>would have been useful 10 years ago(and the phone). No more stealing back
packs for me. (Five stars)</p>
</blockquote>
<p>What!?</p>
<h2 id="people-will-not-pay-for-polish">People will not pay for polish.</h2>
<p>If there’s a free app on the Android Market that does anything remotely similar to what you’re planning to write, I urge you to simply not bother. At the time of initial release, there were two apps that tracked life in Magic. One was simply a background image with large, aliased purple text on it and no obvious way to change the score (you had to tap above and below the number). The other was two numbers (which were different sizes), again with no obvious way to use it (you had to slide up and down on the number).</p>
<p>I arrogantly believed that this would be easy. I just had to build something that was user friendly and then polish it until it shined. Add a log of all changes to the score. Support 2-4 players. Look pretty with different colors, rounded corners, et cetera. I spent significant time on small details and subtle behaviours.</p>
<p>Immediately after I released it as a paid product, I got an email accusing me of swindling people off because it didn’t do anything substantially different. I pointed out all the additional features and UI polish, to no avail. I got a bunch of email in the same vein over LifeCounter’s lifetime.</p>
<p>Over six months, I’ve only sold 104 copies of <a href="/lifecounter/">LifeCounter</a>. It has been a commercial failure. People simply don’t pay for quality, at least in this market.</p>
<h2 id="one-bad-review-can-sink-your-app">One bad review can sink your app.</h2>
<p>Over the lifetime of the paid app, I had 15 five star rating and 1 four star rating. And then I got a 1 star review on August 1st. Here’s what happend to sales:</p>
<p><img src="/images/2009-08-29-on-the-android-app-store/graph.png" alt="Graph of Sales" /></p>
<p>The review retreads the demonstrably false claim that LifeCounter has no features above its free competition. But here’s the thing: It doesn’t matter if it’s false. It’s now the first user comment people see, and it’s obviously affected sales per above. It’s also likely to stay at the top for a long time. Fewer new sales means a smaller pool of people to actually write reviews that would push this lie off the top.</p>
<h2 id="what-should-you-do">What should you do?</h2>
<p>As much as it pains me to say this, as I love the Android platform, I wouldn’t recommend people invest the time to write commercial software for it. I may write more utilities for Android (or port rlvm once the NDK is more complete), but I will probably never do anything expecting to profit from my software on this platform.</p>
rlvm 0.06.32009-08-16T00:00:00-07:00http://eglaysher.github.com/2009/08/16/rlvm-063-released<p>Adds fullscreen support.</p>
<h3>Download</h3>
<p>
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.6.3_i386.deb">Ubuntu (Jaunty) package for x86 machines (version 0.06.3)</a><br />
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.6.3_amd64.deb">Ubuntu (Jaunty) package for amd64 machines (version 0.06.3)</a><br />
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.6.3.dmg">Mac OSX Application (Universal) (version 0.06.3)</a><br />
<a href="http://github.com/eglaysher/rlvm/tarball/release-0.06.3">Source code (0.06.3)</a>
</p>
GTK+ themes in Chromium2009-07-02T00:00:00-07:00http://eglaysher.github.com/2009/07/02/gtk-themes-in-chromium<p><strong><em>Update 01 Dec 2010: People who write GTK+ themes may want to go read the <a href="http://code.google.com/p/chromium/wiki/LinuxGtkThemeIntegration">documentation</a> for telling Google Chrome which colors to use to draw the frame.</em></strong></p>
<p><strong><em>Update 08 Dec 2009: Holy cow this page has a lot of Googlejuice! These screenshots don’t look anything like how the feature turned out. You may want to look at the screenshots in <a href="/2009/12/08/google-chrome-for-linux-beta/">Google Chrome for Linux Beta</a> instead.</em></strong></p>
<p>I don’t usually talk about Chromium, but I have something really cool I want to
share:</p>
<p>Earlier today I committed <a href="http://src.chromium.org/viewvc/chrome?view=rev&revision=19868">the first</a> of several patches to the
Chromium tree that address <a href="http://crbug.com/13967">Bug #13967</a>, “theme base colors should be
picked from system colors.” We’ve gotten a lot of requests to try to visually
match Linux user’s GTK themes. A good option to have, as much as I might like
the default blue theme.</p>
<p>As of <a href="http://src.chromium.org/viewvc/chrome?view=rev&revision=19868">r19868</a>, there is now a “GTK Theme” button on the Personal
Stuff tab of the Option dialog. Clicking it will switch to GTK theme mode,
while “Reset to default theme” will switch you back.</p>
<p>Here’s Chromium running with the “Clearlooks” theme and system title bars and
borders:</p>
<p><img src="/images/2009-07-02-gtk-themes/with_clearlooks.png" alt="Chromium with Clearlooks" /></p>
<p>Here’s Chromium running with the Ubuntu Human theme and using the skyline:</p>
<p><img src="/images/2009-07-02-gtk-themes/with_human.png" alt="Chromium with Human" /></p>
<p>This is obviously not a polished final work. Just from the screenshots above, I
can count four big graphical problems, and Chromium’s interpretation of dark
themes like HighContrastInverse can only be described as unusable. There are
the ongoing problems with 32-bit/64-bit *.so libraries (this time: theme
engines). The fonts are wrong. There’s a lot of work to be done before this is
acceptable for day to day use.</p>
<p>But I’m excited because some progress is being made.</p>
rlvm 0.06.22009-06-21T00:00:00-07:00http://eglaysher.github.com/2009/06/21/rlvm-062-released<p>Bugfix release.</p>
<ul>
<li>Fixes regression where G00 animations weren’t being played (Seen in
Planetarian.)</li>
<li>Fixes regression where Yumemi’s face in the final scene in Planetarian
was being drawn twice because of poor clip rect handling.</li>
<li>Support for English patches compiled with debugging symbols stripped.</li>
<li>Temporarily disables scrollback due to crash that will be invasive to
fix.</li>
</ul>
<h3>Download</h3>
<p>
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.6.2_i386.deb">Ubuntu (Jaunty) package for x86 machines (version 0.06.2)</a><br />
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.6.2_amd64.deb">Ubuntu (Jaunty) package for amd64 machines (version 0.06.2)</a><br />
<a href="http://www.elliotglaysher.org/Releases/rlvm_0.6.2.dmg">Mac OSX Application (Universal) (version 0.06.2)</a><br />
<a href="http://github.com/eglaysher/rlvm/tarball/release-0.06.2">Source code (0.06.2)</a>
</p>
rlvm 0.6.1 released!2009-05-24T00:00:00-07:00http://eglaysher.github.com/2009/05/24/rlvm-061-released<p>Contains initial support for the CLANNAD English patch, available at the
CLANNAD translation wiki’s Assembla page. This is a minor update and only fixes
obvious problems early in the game (i.e. crashing at startup). Despite this
disclaimer, I haven’t gotten a crash with the SEENr28_FV.TXT currently up on
Assembla (though I have only played about half an hour in). Note: The recently
posted SEENr30_FV.TXT doesn’t work; I am not sure why.</p>
<p>In addition, this version fixes reported issues with CLANNAD_FV.</p>
<p>rlvm compiles on Ubuntu Jaunty Jackalope (and most likely any modern Linux
distribution) and Mac OSX 10.5 Leopard / 10.4 Tiger.</p>
<h3><em>Old links removed.</em></h3>
rlvm 0.6 released!2009-04-19T00:00:00-07:00http://eglaysher.github.com/2009/04/19/rlvm-06-released<p>Supports the Full Voice edition of CLANNAD, with several general improvements
to all versions of CLANNAD. Most notably, rlvm 0.6 supports the Ogg Vorbis
voice archives used in CLANNAD Full Voice edition. (Older KOE and NWK archives
are not yet supported).</p>
<p>Currently, English patches to CLANNAD are known to not work. (And I suspect
that they never did.) Specifically, I’ve tested with the SEEN.TXT files on
Assembla and things aren’t working. More investigation is needed. rlvm still
works properly with the NDT Kanon patches.</p>
<p>By popular demand, the OSX application is now a universal binary again. (I am
not sure how many more releases will have universal binaries because my old G4
laptop is dying.)</p>
<p>rlvm compiles on Ubuntu Intrepid Ibex (and most likely any modern Linux
distribution) and Mac OSX 10.5 Leopard / 10.4 Tiger.</p>
<h3><em>Old links removed.</em></h3>
On Writing for Android2009-03-15T00:00:00-07:00http://eglaysher.github.com/2009/03/15/on-writing-for-android<p>Android is Google’s operating system for phones. Now that I’ve released <a href="http://www.elliotglaysher.org/lifecounter">Life
Counter</a> on the Android Marketplace, I’d like to write a bit about
the platform and learning it.</p>
<ul>
<li>
<p>The <a href="http://d.android.com/guide/index.html">documentation</a> isn’t great, which is a shame since most of
the classes are pretty easy to use. The tutorials don’t teach you enough to
bootstrap and the Framework Topics section, while interesting, doesn’t give a
good overview of the system. Framework Topics will also usually cover the way
you do things with imperative statements, instead of the declarative XML,
which is what you should usually use.</p>
<p>The <a href="http://d.android.com/reference/packages.html">javadoc</a> is generally OK, but sometimes it
shines. <a href="http://developer.android.com/reference/android/app/Activity.html">Activity</a>, for example.</p>
<p>I was only really able to “get” the Android API because of a separate book I
bought. <a href="http://www.amazon.com/Hello-Android-Introducing-Development-Platform/dp/1934356174/ref=pd_bbs_sr_1">Hello, Android</a> by Ed Burnette walked through multiple
non-trivial Android programs and showed off various things I wouldn’t have
encountered otherwise. Also, 3rd party tutorials tend to help quite a bit.</p>
</li>
<li>
<p>Android shipped with nowhere near enough widgets in the standard
library. There are a lot more widgets in the <code>com.android.internal.widget</code>
namespace. While you won’t want to use those directly in your project, all
the android code is thankfully released under the <a href="http://www.apache.org/licenses/LICENSE-2.0.html">Apache License, Version
2.0</a>. Check out the code for the <a href="http://android.git.kernel.org/?p=platform/frameworks/base.git">base framework</a> and copy
classes and resources you want into your project’s namespace. For example,
Life Counter’s spin button is copied from
<code>com/android/internal/widget/NumberPicker.java</code>.</p>
</li>
<li>
<p>XML layouts can be confusing, especially figuring out how to properly space
different elements. Like <code>overflow:hidden;</code> solves most problems with IE in
CSS, the magic XML attribute that your layouts are missing is
<code>android:layout_weight="1"</code>. Good luck finding out what that actually means,
since the <a href="http://developer.android.com/reference/android/widget/LinearLayout.LayoutParams.html#attr_android:layout_weight">javadoc for android:layout_weight</a> is empty. The
only place I’ve found a reasonable description of that property is, oddly, in
<a href="http://developer.android.com/guide/tutorials/notepad/notepad-ex2.html">a section of the Notepad tutorial</a>. I learned this
more by trial and error than anything else.</p>
</li>
<li>
<p>Total time to make <a href="http://www.elliotglaysher.org/lifecounter">Life Counter</a>: 2 weekends (with small,
scattered chunks of freetime during the week) from start to finish, including
most of the time spent learning various parts of the android API.</p>
</li>
</ul>
VitaminSEE 0.7.22009-01-24T00:00:00-08:00http://eglaysher.github.com/2009/01/24/vitaminsee-072<p>With version 0.7.2, I’m abandoning VitaminSEE. The code is available on <a href="http://github.com/eglaysher/vitaminsee">github</a> and there’s now a <a href="http://www.elliotglaysher.org/vitaminsee">site for VitaminSEE</a>. I hope that someone forks the code and continues it.</p>
<p>VitaminSEE 0.7.2 is an odd assortment of bug fixes that I’ve accumulated over the years of my own use. The only new user visible feature (that I remember!) is proper unicode sorting on the file list.</p>
<p>
<a href="http://elliotglaysher.org/Releases/VitaminSEE 0.7.2.dmg">VitaminSEE v0.7.2 (Universal Binary)</a><br />
<a href="http://github.com/eglaysher/vitaminsee/tarball/VitaminSEE-0.7.2">VitaminSEE v0.7.2 Source</a><br />
</p>
Importing from SVN2009-01-21T00:00:00-08:00http://eglaysher.github.com/2009/01/21/importing-from-svn<p>Importing a SVN repository into git is a utter pain if you have anything
nonstandard.</p>
<p>A note to everyone out there in the world who came here through google: In
git-svn, there is a function called <code>sub do_git_commit</code>. If you have an svn
branch that isn’t getting merged in correctly, make a local copy of <code>git-svn</code>
and hack that function. There’s a <code>foreach</code> loop where you’re adding ‘-p’
options. Immediately afterwards, hack it to add more parent commits on certain
revisions.</p>
<p>So in my case, <code>r149</code> was supposed to be a merge point. I found the hash of the
commit that should have been one of the parents and wrote:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span></span><span class="k">if</span> <span class="p">(</span><span class="nv">$lr</span> <span class="o">==</span> <span class="mi">148</span><span class="p">)</span> <span class="p">{</span>
<span class="nb">push</span> <span class="nv">@exec</span><span class="p">,</span> <span class="s">'-p'</span><span class="p">,</span> <span class="s">"a8ef9cf2314224558fe205baca770d2a8df556b9"</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>
<p>This worked for me. This probably would have been amazingly harder if I had
more than one of these broken merges since it would probably change a lot of
the commit hashes. YMMV.</p>
rlvm 0.5 released!2009-01-17T00:00:00-08:00http://eglaysher.github.com/2009/01/17/rlvm-05-released<p>The big new feature is rlBabel support! NDT’s Kanon teaser patch is now playable to the end of the translated text. Western text is now word wrapped correctly and translation notes work (though there is a minor bug that they can only be read once). However, italicized text is not supported and italicized words will be displayed with the normal font. The text is also not kerned.</p>
<p>There appears to be some broken unofficial CLANNAD patches floating around. English patches that were <em>not</em> compiled with rlBabel will, obviously, not line break correctly. You can check to see if rlBabel is enabled by hitting [F1] at any time. “rlBabel” should be set to “Enabled” and “Text Encoding” should be set to “Western”. rlvm can not, and will never, support these broken patches.</p>
<p>rlvm now has a <a href="http://rlvm.net">site on github</a> with <a href="http://rlvm.net/screenshots.html">screenshots</a> and <a href="http://rlvm.net/guide_kanon_eng.html">a guide to installing NDT’s English patch</a> under Linux.</p>
<p>rlvm compiles on Ubuntu Intrepid Ibex (and most likely any modern Linux distribution) and Mac OSX 10.5 Leopard.</p>
<h3><em>Old links removed.</em></h3>
Look what I found in the rlBabel code…2008-12-20T00:00:00-08:00http://eglaysher.github.com/2008/12/20/look-what-i-found-in-the-rlbabel-code
<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span></span><span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">T</span><span class="o">></span>
<span class="k">class</span> <span class="nc">test_p</span><span class="o">:</span> <span class="k">public</span> <span class="n">std</span><span class="o">::</span><span class="n">unary_function</span><span class="o"><</span><span class="n">t</span> <span class="p">,</span> <span class="kt">bool</span><span class="o">></span> <span class="p">{</span>
<span class="c1">// Come quick! come quick! thou happy hour</span>
<span class="c1">// When C++ doth closures get,</span>
<span class="c1">// And gain thereby some modern power,</span>
<span class="c1">// And all this clumsiness forget</span>
<span class="c1">// (Though that may take a lifetime yet,</span>
<span class="c1">// Since standards are so hit-and-miss) --</span>
<span class="c1">// Till then, we're stuck with crap like this.</span>
<span class="kt">int</span> <span class="n">x_</span><span class="p">,</span> <span class="n">y_</span><span class="p">;</span>
<span class="k">public</span><span class="o">:</span>
<span class="n">test_p</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span><span class="p">)</span> <span class="o">:</span> <span class="n">x_</span><span class="p">(</span><span class="n">x</span><span class="p">),</span> <span class="n">y_</span><span class="p">(</span><span class="n">y</span><span class="p">)</span> <span class="p">{}</span>
<span class="kt">bool</span> <span class="k">operator</span><span class="p">()(</span><span class="k">const</span> <span class="n">T</span><span class="o">&</span> <span class="n">t</span><span class="p">)</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">t</span><span class="p">.</span><span class="n">test</span><span class="p">(</span><span class="n">x_</span><span class="p">,</span> <span class="n">y_</span><span class="p">);</span> <span class="p">}</span>
<span class="p">};</span></code></pre></figure>
<p>– Haeleth, in <a href="http://svn.haeleth.net/pub/rlBabel/gloss.cpp">rlBabel’s gloss.cpp</a></p>
<p>Writing that class out made Haeleth curse,<br />
So annoyed, he composed a whole verse!<br />
And though Haeleth is vexed,<br />
There’s no joy in Oh X.<br />
The new syntax for lambdas is worse!<br /></p>
rlvm 0.4 released!2008-12-17T00:00:00-08:00http://eglaysher.github.com/2008/12/17/rlvm-04-released<p>CLANNAD is now playable to the True End of the After Story. All routes in Kanon SE are playable, and there’s a minimal default interface for Kanon and other games that don’t provide a custom one.</p>
<p>rlvm still does not handle rlBabel translation patches very well. This is the major planned feature for 0.5, now that there appears to be an incoming Kanon translation patch, along with the ongoing CLANNAD translation work.</p>
<h3><em>Old links removed</em></h3>
<h3>Source Code</h3>
<p>I thought I should also mention that the whole project history, in addition to being hosted locally, is now also <a href="http://github.com/eglaysher/rlvm/tree/master">on github</a>, for those interested in following development or contributing.</p>
rlvm 0.3 released!2008-10-04T00:00:00-07:00http://eglaysher.github.com/2008/10/04/rlvm-03-released<p>Work has been started on getting CLANNAD playable under rlvm. Nagisa’s route is playable to the end, minus the MPEG video. rlvm now remembers the CG viewed. User selections are now usable and don’t lock up the interpreter. Despite all this, CLANNAD support is far from complete. There are still several graphical glitches and unimplemented opcodes.</p>
<p>In addition, there are several stability fixes. The race condition in the BGM system has been fixed. Scrolling through Planetarian’s backlog no longer crashes.</p>
<h3><em>Old links removed</em></h3>
<div id="comments">
<h4 id="comment-header">2 Comments</h4>
<ol class="commentlist">
<li id="comment-17391" class="alt">
<p class="comment-metadata"><strong>Mitchell Ferguson</strong> | 19-Oct-08 at 11:53 pm | <a href="#comment-17391" title="Permalink to this comment" rel="permalink">Permalink</a></p>
<p>Wow, this is looking awesome. I tried it with Clannad and an unoffical english patch, and it’s working mostly as you said it would. It may be a bit early to start making requests, but just some things to note:</p>
<p>Allow use of the “enter” key to advance dialog. Currently, only return works.</p>
<p>When english text is displayed, it is too big for the line height and looks bad, also the letters are too far apart. All together, it’s readable but looks *bad*. It would be awesome if there was some way to switch fonts, next release.</p>
<p>When viewing Clannad backlog, the only way to get back to the present is by clicking. Normally, you can at least use return, if not enter.</p>
<p>All in all, thanks a tonne for your hard work on this!</p>
<p>(Oh yeah, any chance of save compatibility? ^^ I don’t know how far-fetched this is, please ignore my if it’s unreasonable)</p>
</li>
<li id="comment-17596" class="">
<p class="comment-metadata"><strong>glaysher</strong> | 24-Oct-08 at 10:04 pm | <a href="#comment-17596" title="Permalink to this comment" rel="permalink">Permalink</a></p>
<blockquote><p>
When english text is displayed, it is too big for the line height and looks bad, also the letters are too far apart. All together, it’s readable but looks *bad*.
</p></blockquote>
<p>I am not surprised; I’ve hard coded the Japanese text model into rlvm,<br />
much like RealLive does. I don’t have short term plans to support<br />
English/Korean/Chinese fan patches. Obviously, this is one of the big<br />
long term goals on the agenda once unmodified Clannad is rock solid.<br />
The problem is that rldev will generate bytecode that requires<br />
Haeleth’s rlBabel DLL to work correctly. I am not entirely sure what<br />
to do about this and therefore have been putting it off. The easiest<br />
option is to make a compatibility rlbabel-rlvm.kh file and require<br />
everyone who wants to make a patch to compile it in, much as people<br />
use Haeleth’s rlbabel.kh. It’s not a convenient solution, but it may<br />
be the only way. I’ve only done preliminary work on this, though, as I<br />
think there’s still more important work to be done (i.e. stop crashing<br />
on Kotomi’s route).</p>
<blockquote><p>
(Oh yeah, any chance of save compatibility? ^^ I don’t know how far-fetched this is, please ignore my if it’s unreasonable)
</p></blockquote>
<p>This will never happen. The official RealLive.exe appears to simply<br />
dump its in memory structures into a binary file and no one (to my<br />
knowledge) has seriously tried to reverse engineer it. Even if someone<br />
did the prerequisite reverse engineering work, both creating and<br />
maintaining the mapping between RealLive.exe and rlvm’s in memory data<br />
structures would take significant effort for little benefit. I’d<br />
rather spend that time on getting voice files working, reverse<br />
engineering the tonecurve files or HIK animations, et cetera.</p>
</li>
</ol>
</div>
rlvm 0.2 released!2008-07-24T00:00:00-07:00http://eglaysher.github.com/2008/07/24/rlvm-02-released<p>rlvm 0.2 adds music and sound effect support, along with custom mouse cursors included in RealLive games.</p>
<p>While rlvm plays music and sounds, rlvm still does not support voices. nwatowav does not support the voice format used on the Planetarian CD edition. If anyone knows anything about the voice file format used in Planetarian, please contact me at <em>glaysher at umich dot edu</em>.</p>
<p>This version is not backwards compatible with rlvm 0.1’s save files. I’ve added versioning information to the save files so hopefully future versions of rlvm will be compatible with the save game files produced by version 0.2. No user action is required to upgrade; save files are written in a different location and are now compressed with zlib.</p>
<p>rlvm compiles on Ubuntu Hardy Heron (and most likely any modern Linux distribution), Mac OSX 10.4 Tiger, and Mac OSX 10.5 Leopard.</p>
<h3><em>Old links removed</em></h3>
rlvm 0.1 released!2008-04-16T00:00:00-07:00http://eglaysher.github.com/2008/04/16/rlvm-01-released<p>After a year and a half of hard work, I’m pleased to announce the first release of <a href="http://rlvm.net">rlvm</a>. rlvm is a Free Software reimplementation of the VisualArt’s KK’s RealLive interpreter. It is meant to provide Linux and Apple users with a compatible, portable interpreter to play VisualArts games, specifically those released by Key.</p>
<p>As this is the first publicly released version, there are bound to be bugs. The machine is missing major features. (See KNOWN ISSUES in README.TXT.) Right now, only Planetarian is playable through the end.</p>
<p>rlvm compiles on Ubuntu Gutsy Gibbon (and most likely any modern Linux distribution), Mac OSX 10.4 Tiger, and Mac OSX 10.5 Leopard.</p>
<h3><em>Old links removed</em></h3>
VitaminSEE 0.7.1.22006-03-30T00:00:00-08:00http://eglaysher.github.com/2006/03/30/vitaminsee-0712<p>This build fixes a number of memory leaks in VitaminSEE, where memory wasn’t being freed when a window was closed, thus causing VitaminSEE to consume a large amount of memory over a long session.</p>
<p><a href="/Releases/VitaminSEE 0.7.1.2.dmg">VitaminSEE v0.7.1.2 (Universal Binary)</a><br />
<a href="/Releases/VitaminSEE 0.7.1.2-Panther.dmg">VitaminSEE v0.7.1.2 (for 10.3.x)</a><br />
<a href="/Releases/VitaminSEE 0.7.1.2 Source.tar.bz2">VitaminSEE v0.7.1.2 Source</a></p>
<div id="comments">
<h4 id="comment-header">7 Comments</h4>
<ol class="commentlist">
<li id="comment-5" class="alt">
<p class="comment-metadata"><strong>Sergiu Partenie</strong> | 01-Apr-06 at 1:31 am | <a href="#comment-5" title="Permalink to this comment" rel="permalink">Permalink</a></p>
<p>Full screen interface.<br />
Very nice - but a Aperture-type gray pallete for the menus would look much better imho.</p>
<p>And another request - an option that will only display 64×64 thimbnails in the thumbnail pane - the default ones are too big for smaller (800×600) displays</p>
</li>
<li id="comment-6" class="">
<p class="comment-metadata"><strong>Kerry</strong> | 18-Apr-06 at 5:04 am | <a href="#comment-6" title="Permalink to this comment" rel="permalink">Permalink</a></p>
<p>Tried it out. But wish I could have the option of displaying PDFs as thumbnails.</p>
</li>
<li id="comment-20" class="alt">
<p class="comment-metadata"><strong><a href="http://www.debphoto.com" rel="external nofollow">Deb</a></strong> | 01-May-06 at 9:15 am | <a href="#comment-20" title="Permalink to this comment" rel="permalink">Permalink</a></p>
<p>Love your application but how do I view my portrait (vertical) shots? They are rotated in the thumbnail and they are rotated images but VitaminSEE doesn’t recognize or display verticals in the viewer. Is there something I’m missing here? Thank you! Deb</p>
</li>
<li id="comment-21" class="">
<p class="comment-metadata"><strong>glaysher</strong> | 02-May-06 at 4:47 am | <a href="#comment-21" title="Permalink to this comment" rel="permalink">Permalink</a></p>
<p>Deb, this sounds like a bug. Could you please email me (one) of these images, so I can figure out what’s going on for the next version?</p>
</li>
<li id="comment-91" class="alt">
<p class="comment-metadata"><strong>Matt</strong> | 01-Aug-06 at 1:14 am | <a href="#comment-91" title="Permalink to this comment" rel="permalink">Permalink</a></p>
<p>Hi, great software. One observation: there doesn’t seem to be any way to control the default window size: every time I open an image it defaults to a (relatively) small window, and the image shrunk to fit it. Even if I enlarge the window, the next time I launch VitaminSEE it’s small again.</p>
<p>I’d love to see 1) an option to “remember this window size” for future launches, and 2) an option for “view at Actual Size” by default, which is usually what I want (unless the image is larger than my screen).</p>
<p>Thanks!</p>
</li>
<li id="comment-304" class="">
<p class="comment-metadata"><strong><a href="http://buddi.sourceforge.net" rel="external nofollow">Wyatt</a></strong> | 24-Dec-06 at 8:12 pm | <a href="#comment-304" title="Permalink to this comment" rel="permalink">Permalink</a></p>
<p>Excellent program! It looks to be exactly what I was looking for - a graphical interface which allows tagging of images, before I run my archiving scripts on them. A couple of comments:</p>
<p>1) I notice the same problem as Deb: vertical images are not properly rotated. My camera includes the rotation information in the metadata. Most applications recognise this (Finder, Preview, iPhoto, etc) this and flip the photo accordingly, but VitaminSee does not seem to do so.</p>
<p>2) Keyword tagging only seems to work for .jpg; it does not seem to work for .raw (specifically, Olympus RAW: .orf), and .png. I don’t know if this is a limitation with the Exif2 library or the interface. This is not a huge problem, but it would be nice.</p>
<p>3) I can consistently crash the program by doing the following:<br />
a) Open preferences, and edit Keywords<br />
b) Click on a tag (to edit the name)<br />
c) Click on Remove</p>
<p>Regardless, this is a very nice program which does exactly what I need. Thank you very much!</p>
</li>
<li id="comment-555" class="alt">
<p class="comment-metadata"><strong>Kado</strong> | 27-Mar-07 at 6:00 am | <a href="#comment-555" title="Permalink to this comment" rel="permalink">Permalink</a></p>
<p>Great: simple and efficient!</p>
<p>Do you (or someone else) work on VitaminSEE? Please tell me Yes ;-)</p>
</li>
</ol>
</div>
Memory Usage2006-03-30T00:00:00-08:00http://eglaysher.github.com/2006/03/30/memory-usage<p>So, later tonight, I’ll be making a release of VitaminSEE that should fix most of the current memory leaks, so I can go off and make new ones for the next version.</p>
<p>But right now, I want to talk about the conditions under which VitaminSEE consumes ridiculous amounts of memory (which won’t be fixed in this release). You may have noticed that on folders with a large number of image files, VitaminSEE will consume really large amounts of memory.</p>
<p>For example, I have an “Unsorted” folder with 1,666 images in it. VitaminSEE starts from a resting memory position of 8 megabytes. After giving VitaminSEE a few moments to load all the thumbnails, Activity Monitor tells me that VitaminSEE is using 25 megs of real memory. Not optimal, but more then acceptable. After scrolling from the first file in the folder to the last file, VitaminSEE’s memory consumption jumps all the way up to 122 megabytes. Note that it already had the thumbnails in memory before the jump.</p>
<p>From what I can make out from MallocDebug, it appears that the implementation of either <tt>NSBrowser</tt> or <tt>NSMatrix</tt> in Cocoa render their contents into an <tt>NSImage</tt> offscreen, and then copy that cached version onto the screen.</p>
<p>Solving this will require me to do one of the two things:</p>
<ul>
<li>Find a magic way to tell whatever class is at fault to not cache things this way (Quick, unlikely)</li>
<li>Look at other controls and see if I can coerce them to do what I want to do.</li>
<li>Write my own control that doesn't do things this way. (Hard, would take a long time)</li>
</ul>
VitaminSEE 0.7.1.2 Beta2006-03-28T00:00:00-08:00http://eglaysher.github.com/2006/03/28/vitaminsee-0712-beta<p>The entire 0.7 series of VitaminSEE has had a string of severe memory leaks. This build hopes to address most of them. It contains no new features; it is purely a bugfix build.</p>
<p>This is a beta build; the final version will be released in two days if no serious problems are found with it. Please leave a comment if you find a defect (that isn’t present in previous builds). Please do <b>NOT</b> submit this build to the release announcement sites.</p>
<h3><em>Old links removed.</em></h3>
VitaminSEE 0.7.1.12006-03-22T00:00:00-08:00http://eglaysher.github.com/2006/03/22/vitaminsee-0711<p>VitaminSEE 0.7.1.1 is a bugfix release that fixes two issues with VitaminSEE 0.7.1:</p>
<ul>
<li>When I upgraded to IconFamily 0.9.1, I forgot to port my changes that would restore a file’s modification date. Fix this so building a thumbnail of a file does set the modification date.</li>
<li>Back/Forward will now focus on the file/folder you were on previously, instead of always starting at the beginning of the list.</li>
</ul>
<h3><em>Old links removed.</em></h3>
VitaminSEE 0.7.12006-03-21T00:00:00-08:00http://eglaysher.github.com/2006/03/21/vitaminsee-071<p>I have just released VitaminSEE 0.7.1, after three betas and a lot of testing. The <a href="/vitaminsee">product page</a> has been updated. As always, thanks go to B. Star for testing and <a href="http://www.fan.gr.jp/~sakai/">Hiroto Sakai</a> for the updated translation.</p>
<h4>What's new:</h4>
<ul>
<li>Upgrade IconFamily to 0.9.1</li>
<li>Make rename sheet handle extensions like the Save... dialogs do</li>
<li>Add a fullscreen mode</li>
<li>Don't display document types that OSX treats as images, such as postscript
files, and PDFs.</li>
</ul>
<h3><em>Old links removed.</em></h3>
<div id="comments">
<h4 id="comment-header">3 Comments</h4>
<ol class="commentlist">
<li id="comment-2" class="alt">
<p class="comment-metadata"><strong><a href="http://hefixedmymac.com" rel="external nofollow">Paul Russo</a></strong> | 21-Mar-06 at 8:41 pm | <a href="#comment-2" title="Permalink to this comment" rel="permalink">Permalink</a></p>
<p>Hi Elliot,</p>
<p>I’m sorry to give negative feedback about something that you have apparently given so much thought and work to, but here it is.</p>
<p>VitaminSEE 0.7.1 destroys data. </p>
<p>When VitaminSEE automatically creates the thumbnail, it also automatically changes the file modification date. This is a big problem, because the date when I last modified a picture is important data about that picture. </p>
<p>I knew this might happen, so right after I launched VitaminSEE I went straight to the preferences to turn the thumbnailing off. Of course, I was too slow. By then VitaminSEE had already started thumbnailing and changing the modification dates. Luckily I backed up yesterday. Others might not be so lucky.</p>
<p>This is a common problem in early versions of other thumbnailing programs. It’s not just you. </p>
<p>This didn’t have to happen. It is possible for VitaminSEE to change the modification date back to what it was originally after it creates the thumbnail. Resetting the modification date back to what it was originally is standard behavior in thumbnailing programs because of this issue.</p>
<p>Thanks for listening.</p>
<p>Paul</p>
</li>
<li id="comment-3" class="">
<p class="comment-metadata"><strong>glaysher</strong> | 21-Mar-06 at 9:39 pm | <a href="#comment-3" title="Permalink to this comment" rel="permalink">Permalink</a></p>
<p>Actually, this is the second time I’ve fixed this bug. </p>
<p>VitaminSEE uses a third party library called IconFamily to do the thumbnailing. I had to fix it in the previous version IconFamily, and I completely forgot to port my changes up IconFamily 0.9.1 when I updated. I just submitted a patch upstream this time, so hopefully something like this won’t happen a third time.</p>
<p>In any case, could you please try the following build? I believe I’ve fixed the problem:</p>
<p><em>(Beta links removed, since 0.7.1.1 final is out.)</em></p>
<p>As for negative feedback? Don’t worry about it. Unlike quite a bit of criticism I get, yours was at least constructive.</p>
</li>
<li id="comment-4" class="alt">
<p class="comment-metadata"><strong><a href="http://hefixedmymac.com" rel="external nofollow">Paul Russo</a></strong> | 22-Mar-06 at 1:32 am | <a href="#comment-4" title="Permalink to this comment" rel="permalink">Permalink</a></p>
<p>Hi Elliot,</p>
<p>VitaminSEE 0.7.1.1-beta.dmg does the trick. The date/time is now preserved when the thumbnails are added. </p>
<p>Thanks for the quick response :)</p>
<p>Paul</p>
</li>
</ol>
</div>
Duplicate Image Algorithms2006-03-19T00:00:00-08:00http://eglaysher.github.com/2006/03/19/duplicate-image-algorithms<p>GQView was my favorite image viewer on Linux, and a high quality image duplicate finder is the only feature that VitaminSEE lacks that I miss from GQView. I’ve already started thinking beyond 0.7.2 to the big feature of 0.8: Duplicate image search, like in <a href="http://gqview.sourceforge.net/">GQview</a>. I wasn’t sure what the algorithm in gqview was, so I finally stumbled upon <a href="http://www.cit.gu.edu.au/~anthony/info/graphics/image_comparing">this</a> page which outlines a few image comparison implementations.</p>
<p>GQView looks like the simplest algorithm: It subdivides the image into a 32 x 32 grid, and then takes the average pixel color of each block. The difference is simply the sum of the difference between each block in the two images, normalized to a value between 0 and 1. The <a href="http://cvs.sourceforge.net/viewcvs.py/gqview/gqview/src/similar.c?rev=1.1&view=markup">similar.c</a> code in GQView is really that simple. I’m surprised that I got such good results back when I used it. Unless I find something better, I’m guessing that this is going to be the base algorithm, after I figure out how GQView scales with it to deal with hundreds (thousands?) of files.</p>
<p>And after 0.7.2 is released, of course.</p>
Mission Statement2006-03-11T00:00:00-08:00http://eglaysher.github.com/2006/03/11/mission-statement<p>I’ve broken down and started a real website. My previous “website” was a ten minute job that I created as an afterthought to comply with the one rule of the UM Cocoa Codeoff ‘05 that stated that I had to have a website.</p>
<p>This is going to be different. This website is going to be functional, usable, and something I’ll be proud to associate my name with.</p>
<p>This domain will be used for/will contain:</p>
<ul>
<li>Random thoughts on programming</li>
<li>Hosting of the VitaminSEE page, its <a href="http://subversion.tigris.org/">Subversion</a> repository, and the Trac that does wiki and bug management.</li>
<li>Random life things</li>
<li>Everything else I think of</li>
</ul>