A Brief List of Ways to Make Xinerama and Games Get Along

As none of you certainly know, my system has a very odd video setup:

  • Because I hate bad window management misplacing things when the resolution changes, I’ve used xorg.conf to lock my desktop at 2560×1024
  • Because I’m using nVidia TwinView, XRandR tells applications that the entire desktop is one monitor but the window manager still gets the Xinerama hints it needs to interpret fullscreen and maximize as only half of that.
  • Games generally assume that you’ll want to play them fullscreen… sometimes not even offering an obvious way to enable windowed mode.
  • Since I got my new video card with HDMI for the second monitor, my right monitor is the first one, not my left one.

I think you can see where this might cause a problem. Games tend to exhibit one of the following behaviours:

  • Fullscreen across both displays, centered on the big physical gap between screens. (Not since my new video card)
  • Fullscreen on the right-hand monitor, center as if fullscreening across both displays. (Since my new video card)
  • Fullscreen on one monitor, letterbox to the aspect ratio of the desktop as a whole (YouTube and Cortex Command, I’m looking at you)
  • Windowed mode, but only offer 2560×1024 as a resolution unless you edit the config file manually because they naïvely use SDL’s list of fullscreen resolutions for windowed mode too.

This wouldn’t be a huge deal, since I tend to prefer windowed-mode play anyway, except that sometimes, the mouse is mapped wrong too, so you can see the “Options” button but can’t click it.

So far, here are the workarounds I’ve found successful:

  1. Just let the stupid things muck with your resolution settings (I’d rather not game instead, but you may feel differently)
  2. Manually edit the config file to set windowed mode and a sane resolution. (Most commonly successful option for open-source games. Look for ~/.gamename, ~/.config/gamename, or possibly ~/.local/share/gamename)
  3. Check -h, -help, --help, -?, and any README files for an option to start windowed. Try -w, -windowed, and --windowed just in case. (eg. Braid)
  4. Try pressing Alt+Enter at the main menu screen (eg. World of Goo)
  5. Run it inside Xephyr (Currently only supports software rendering, but there’s a fork I haven’t tried yet which passes OpenGL through to the host for hardware rendering.)
  6. Run the Windows version inside Wine with a virtual desktop. (eg. Psychonauts, Space Rangers 2. Doesn’t work with all games because, for reasons I can’t fathom, some games do double-buffering normally (which Wine supports) and triple- or quadruple-buffering (which Wine doesn’t yet support) when you try to run them in a virtual desktop)
  7. If it’s something where having a bar down the center of the monitor is a small price to pay for seeing more  (like a strategy game), use export SDL_VIDEO_FULLSCREEN_HEAD=2 to put it on your top-left monitor so it’ll try to span all of them without realizing it. (eg. Revenge of the Titans. Thanks to MakeTechEasier.com for this.)

Once you’ve got that, you may want to simulate fullscreen on a single monitor. The simplest way to do that is to set the window to the same resolution as your monitor, use “Always on Top” to make it cover your panels (taskbar, etc.), and then hide the window border to make it fit the screen. There are two ways to do that:

  1. Right-click your window titlebar while the window’s loading, set Always on Top, and then either do it again to hide the window decoration or, if that’s no an option, bind something like WinKey+T to toggle WinDeco and press it. (Tested working in KDE and LXDE/OpenBox)
  2. If your window manager allows you to set per-application rules (again, tested working with KDE and LXDE/OpenBox), you can automate this. See your window manager’s documentation for details. (I also use this to make Minecraft start maximized)

One more tip: With games like Trine and Aquaria which capture the mouse, you can toggle the grab with Ctrl+G… useful in Trine for switching back and forth between the game and a walkthrough to get those last few experience vials that you literally can’t find without being told about them.

Update: One or both of these may also help with some games. (Thanks to the Torchlight README.linux for clueing me in)

export SDL_VIDEO_X11_XINERAMA=0
export SDL_VIDEO_X11_XRANDR=0
Posted in Geek Stuff | 1 Comment

Git Tricks for Clean Histories

As much as I love the concept of cheap branching and revision control, I’m a bit of a “code first, ask questions later” kind of guy. Most of my best ideas only come to me once I’m elbow-deep in code and they tend to arrive in bits small enough to make planning my branching and committing impossible.

For this reason, I get a lot of use out of git commands which help me to code first and then sort it out later. Here are my favorites:

IMPORTANT: None of these should be used on commits which have already been shared. Clean up your repository, then “git push”. Eagerness to push is one bad habit you’ll just have to break the hard way.

Temporarily get rid of uncommitted changes
git stash
[do your thing]
git stash pop
The manpage gives some examples for where this can be helpful. The most obvious is “boss interrupts you demanding a bugfix immediately”.
Use a GUI to stage and commit only certain lines
git gui

I use this to untangle unrelated changes into clean commits after the fact. The “git citool” alias makes it automatically close when you commit.

Add the staged changes to the last commit you made instead of a new one
git commit --amend

…or just use “git gui”.

Merge “oops” commits within the last 12 into what they should have been part of
git rebase -i HEAD~12

…and then move each “oops” commit below its parent and change “pick” to “fixup”.

Interactive rebase is a very powerful function which can also be used to apply arbitrary changes to any commit you haven’t yet shared. For details, check out the “reword”, “edit”, and “exec” commands in the instructions it displays.

Note: Rebase can sometimes get confused, but if you ever find yourself confused by its requests for clarification and just want to change your mind, simply use git rebase --abort

Move the last 8 commits to a new branch
git branch my_new_branch
git reset HEAD~8
git checkout my_new_branch

Use this when you you find yourself thinking “Dammit! This should be a feature branch.” It works by telling git to create a new branch with its HEAD here and then to move the current branch’s HEAD 8 commits into the past.

Move the last 8 commits to an existing branch
git stash
git checkout -b tmp
git rebase --onto right_branch HEAD~8
git checkout right_branch
git merge tmp
git branch -d tmp
git checkout wrong_branch
git reset --hard HEAD~8
git checkout right_branch
git stash pop

This complex string of commands is for when you make some commits, then realize you’re on the wrong branch. I wish I could offer something simpler, but moving a string of commits to a branch that could’ve diverged quite far is a complex task.

Basically, you stash away your uncommitted changes, use a temporary branch to rebase and merge the changes into the new branch, and then remove them from the old branch, and apply the uncommitted changes to the new branch.

Undo a merge and rebase instead after accidentally running “git pull” instead of “git fetch”
This is useful when you want to keep a nice, linear development history, you’ve developed something, you try to push it, it fails, and you respond with git pull rather than git fetch. (I tend to forget to pull before developing when switching machines)
The trick is to use git’s reflog feature (git’s Undo history). If your branch is named mybranch and the remote is origin/mybranchand `git pull` is the last thing that made changes, you can undo it like this:

git stash
git reset --merge mybranch@{1}
git rebase origin/mybranch
git stash pop

(You can omit the git stash lines if you don’t have any uncommitted changes)

This feature isn’t limited to undoing merges either. Use this command to see what else you can feed to git reset:

git reflog show
And so on…
Got a type of “oops” I missed? Tell me so I can update this post.

UPDATE: Justin Hileman has an excellent flowchart which you’ll probably also want to check out.

Posted in Geek Stuff | Leave a comment

Status Update

For the last while, I haven’t really posted anything on this blog. While I’d like to blame it on coursework or other projects, the truth is that there are many reasons.

Aside from “coursework and other projects”, I’ve also been preparing to switch this blog from WordPress to Jekyll to make it more compact, easier to theme, and more secure. (After all, it’s pretty hard to perform a worthwhile exploit on a site that’s nothing but static HTML and a some JS includes for Disqus, FriendFeed, and AddToAny… especially given some of the security policy extensions on the horizon for HTML)

However, being the perfectionist that I am, I tend to get stuck on sub-problems that, while I can reorder them, must all be done before I can make the switch. (Things like making absolutely certain that no links will break)

To make things simpler, I’ve been working from a known-good export of the blog’s contents and not updating the blog. (Though, as anyone who follows my Identi.ca/Twitter review/rating posts will know, I have continued to work away at the same activities as always)

Given that my switch to Jekyll wasn’t completed before my Christmas vacation, I may reconsider that decision. I have built up quite a backlog of topics to blog on and it’d probably be better for everyone if I just cleared that out and let the switch to Jekyll happen whenever I finally get everything right.

I do still have projects and coursework to do, so I won’t begin posting again right away, and knowing my history with time management, I can’t make any promises, but I’ll try.

Posted in Geek Stuff, Otaku Stuff, Site Updates | 2 Comments

A Quick And Dirty m0n0wall “Get WAN IP” API

Until recently, I’d been using WhatIsMyIP.com’s API to fill in the external IP field in my Conky readout, but a few days ago, they started a very silly thing where, for whatever reason, clients have to follow a 301 redirect to the URL they just asked for in order to get the IP. I decided that was excuse enough to write a more direct solution.

Since, recently, I’d learned that it’s possible to muck about in m0n0wall without pulling the CF card (despite the lack of proper SSH), I decided to take m0n0wall’s interfaces readout page, strip out everything that wasn’t necessary to get the WAN IPv4 address, and add an explode() call to separate the IP from the hostmask.

If you want it for your own m0n0wall box, here are the instructions:

  1. Grab api_wan_ipaddr4.php from my GitHub Gist.
  2. Go to exec.php on your m0n0wall box (http://192.168.1.1/exec.php with the default DHCP configuration)
  3. (optional) Type “status_interfaces.php” into the download box and use a tool like diff to verify that I haven’t added anything nefarious.
  4. Use the exec.php upload interface to upload api_wan_ipaddr4.php.
  5. Run these commands using the exec field:
    mv /tmp/api_wan_ipaddr4.php /usr/local/www
    chmod 755 api_wan_ipaddr4.php
  6. Load it in your browser (http://192.168.1.1/api_wan_ipaddr4.php with defaults) to confirm that it’s working.
  7. Use wget/curl/etc. with HTTP authentication to retrieve your external IP whenever you want. I use this command for my conky:

    curl -s --insecure --anyauth --netrc https://192.168.0.1/api_wan_ipaddr4.php

Posted in Geek Stuff | 5 Comments

My Unofficial “How to Extend distutils” FAQ

Whenever I have to set up a Python project, I’m always amazed at how little documentation there is on extending distutils to add new commands or otherwise deal with un-anticipated (and apparently, some anticipated) circumstances. In the absence of an easily found HOWTO or guide, I’ve had to go source-diving… and when I do that, it’s only good manners that I share what I found.

The following questions are things I found myself frequently wondering, but feel free to ask me other questions. I’ll add answers for the “likely to be frequent” ones as time permits.

How do I create a new command for distutils?
As I find myself often forgetting this, I’ve posted a template with explanatory comments as a GitHub Gist.
How do I add my custom command to multiple projects without including it and setting cmdclass in each one?
As far as I know, using only distutils, you can’t. However, setuptools provides a mechanism.
How do I make a custom command fail gracefully if non-optional dependencies aren’t present?
  • For dependencies internal to Python (modules, specific module versions, etc.), you can define your command inside a try/except or if block. my template includes an example.
  • For external commands, I recommend defining your command inside an if block and using a which function to test for them. (Using an external “which” command is ugly and fragile)
How do I access the attributes I passed to setup() from my custom command?
This was a surprisingly involved thing to figure out. setup() passes its arguments to an instance of distutils.dist.Distribution which then parcels them out to various places. 

The simple explanation is that, if it’s set in setup() and setup.py doesn’t complain about it being unrecognized, your command can access it as an attribute of either self.distribution or self.distribution.metadata. (With the possible exception of it being a command-specific option. I forget how those work)

However, the metadata also offers a comprehensive collection of getter methods which return strings like “UNKNOWN” in place of None, so you’ll probably want to ask PyDoc for details:

pydoc distutils.dist.DistributionMetadata

A practical example of the most common use I’ve had for this is retrieving the list of packages to be installed via self.distribution.packages so a tool like Epydoc or Pylint can be run on them.

What’s the recommended way to output messages?
I’m not sure, but from distutils import log seems to be what’s used internally.
Is there a clean, sane way to bundle resources (eg. custom toolbar icons) with my project
Not really. [1] [2] [3] The approaches linked aren’t pretty, but they’re all I’ve been able to find.
Where do I find new commands?
Given that Python has PyPI, you’d think there would at least be a repository of commands for setuptools. However, aside from the commands that come bundled with their associated programs (nosetests, flakes, build_sphinx, etc.), I haven’t found anything. The wiki mentioned in the next question has a very sparse cookbook though.
There’s really no community documentation for this stuff?
There is, but it only covers some of the questions listed here. One of these days when I’m not feeling so unmotivated, I’ll merge this FAQ into theirs. 

Until then, these sites may help to cover some of the deficiencies:

Isn’t anybody working to fix this mess?
Yes, but it’s not going to happen overnight.
Posted in Geek Stuff | Leave a comment

Game Reviews: Aquaria

Rating: 4.5/5

A few months back, I was informed of an offering known as the Humble Indie Bundle. Seeing it as an opportunity to finally pick up a copy of World of Goo, I bought in. However, my brother quickly insisted that I try another one of the games in the bundle…

Aquaria is an aquatic platformer. More specifically, an aquatic platformer with gorgeous art, beautiful music, and a focus on semi-linear exploration. If Braid is one possible expression of “Super Mario Bros.‘s almost nonexistant story done right” (A review for another day), then Aquaria is an expression of “Super Metroid done right”.

Everything about the game seems carefully crafted to emphasize the atmosphere around you and it makes exploration a treat, there’s a wide variety of enemies, and the “forms” system throws back to the various weapons Samus had to use… though with less focus on different attacks and more on different skills to pass region barriers.

However, it is still firmly a platformer, so while the story gets a fair bit more work than Super Metroid, there are some rough edges which clearly show that storytelling was not the creators’ specialty and that, while a significant improvement on Super Metroid, improvements still could be made.

The combat mechanic does sometimes take precedence in situations where it’s detrimental to the atmosphere (for example, the boss battles where, without fail, you have to defeat enraged or corrupted gods, receiving boons from them in moments of lucidity before they finally die) and the descent into the abyss near the end of the game does make the game less engaging… something a corresponding increase in story-focus could have mitigated.

However, given how rare Metroid-style exploration platformers are and how much I enjoyed exploring the world, I’m willing to forgive that somewhat. It would definitely have been nicer, though, if they’d provided more “ancient turtle” warp points. (The three largest regions in the game still only get one apiece and one surprise region of respectable size gets none at all, while the surface waters get two) More frequent save points would also have probably been a good idea, given that not everybody is as flexible with their schedule as I am.

A more significant problem, story wise, was the feeling that, toward the end, the story was at once both rushed and sparse. Structuring the game more like an essay, with most of the abyss-crawling in the middle and the triumphant revelation of the coral reefs of the surface (or some “beyond” area) would have helped significantly, as would more voice-acted “vision” sequences. As is, it feels as if it’s building toward something as you head for the surface waters… and then the plunge into the abyss quickly ends the story with loose plot threads being tied up before they could fully be developed.

The fact that, apparently, some recipes in the cooking system are alternate paths to dishes and can only be found by experimentation further develops this impression as players tend to measure their progress by the proportion of discoverable items they’ve found compared to the total number. Speaking of the cooking system…

I did find the cooking mechanic enjoyable, primarily because it let me handle my health and powerup management in my own distinctive fashions (and because I used to play games like Harvest Moon), but I felt that, to use a programming term, the set of recipes was oriented too much toward depth rather than breadth. Too many ingredients useful in only one recipe, too many recipes that require multiple steps, and too much dependence on a small set of core ingredients that aren’t proportionally available unless you grind sources of them. Nonetheless, it was fun.

Finally, the collectable trophies seemed too “collectable for the sake of having them”, given how thoroughly hidden some of them were. (In some cases, you have to either know where they are already, or be just plain insane to find them) Of all the trophies I collected, the one I still like most is the ever-respawning pot of fish meat. (one of those few over-utilized base ingredients I talked about)

Overall, it gives the impression that the designers had plenty of skill and envisioned something that they, at the time, didn’t realize would be twice as long as they had the budget for. Nonetheless, I’d give it a solid 4.5 out of 5 and encourage anyone who enjoyed the old 2D Metroid games (or enjoys 2D platformers and 3D Metroid).

P.S. If you really want to feel the atmosphere to its fullest, let a friend or family member wait through the intro that plays the first time you start the game so you don’t see it, then click on the crystal in the menu screen to view it (for the first time) after completing Mithalas Cathedral. That way, you won’t have any potentially inaccurate preconceptions to color Naija’s initial realization that she knows nothing of her origins.

Update: If you get the chance, listen to the special OST-only track “Fear the Dark” before and after you play Aquaria. It’s a beautiful piece (preview) and it does a beautifully clever job of hiding its relation to Aquaria so that you only “get” it once you’ve beaten the game. (Thanks to their clever use of pronouns and implicit subjects, it just sounds like very beautiful, if ordinary, love song unless you know who is being talked about)

Posted in Geek Stuff, Otaku Stuff | Leave a comment

Many Tanks Site Updates

Just a quick status update.

I’ve done some significant re-theming on http://www.ficfan.org/ and fixed a bug that was causing many of the quotes to not show their additional metadata.

While doing so, I noticed that, because of how wp-lifestream caches paths (though I can see no benefit to it), the switchover to the new fileserver caused it to get in a fight with PHP’s safe_mode. (Why doesn’t anybody tell me these things?) That is now fixed.

Finally, now that I’m on vacation, I had time to dig into wp-lifestream and add a workaround for the double-encoded YouTube links. YouTube faves in my lifestream now actually work.

Enjoy.

Posted in Geek Stuff, Site Updates | Leave a comment