Wednesday, September 3, 2014

LEGO Table

Project LEGO® Table

My son's new LEGO table

First a caveat - I am not a professional woodworker. There is a 100% chance that there are better ways to do about every step of what I did to make this table. Having said that, I think it turned out well.

We've wanted to do something with my son's Legos for quite some time. I saw some ideas on Pinterest based on Ikea tables which inspired me to design and build this one.

Luckily we had run across some LEGO base plates for sale at Target and I cleaned them out of stock (in both locations near us). I also picked up some plastic bins that I thought would work well for the storage underneath.
 
 First I sketched out a design and some measurements. Even though the bins could be pulled out and spare pieces swept into them, I thought the addition of little holes would make a significant psychological interest/incentive to clean up (more fun to drop LEGOs in the holes):

Next I purchased some lumber. I picked up kiln dried 2x6 boards and cut them to 4 foot lengths:

Planed the edges down (actually I used a jig on my table saw):

Glued & clamped them together (this is known as a "glue up" - I alternated the curve of the grain up/down to mitigate warping, but it didn't 100% prevent it):

Dried overnight and planed/sanded smooth:

I marked, drilled, then used my jigsaw to cut the holes. And did a lousy, horrible job of it - the edges were all chewed up and unfixable:

I had decided it would be easier for me to use metal pipe for the base. Since this is an inside piece and my wife wanted it "dark" I went with black iron pipe, which is cheaper than galvanized. Still, black iron pipe and fittings in 1" size is expensive stuff. This was the biggest cost sink of the whole project:

In the picture above, you can see there are some metal pieces next to the holes. I decided that the only way to cover up the ugly sides of those holes was to make some kind of flange or liner. Unfortunately, such a thing in the size I needed (since I'd already cut holes) did not exist. My best option was something called a "Hawse Pipe" which is the fitting in a boat hull that an anchor rope/chain runs through but they didn't make any in the right size. So I thought about buying a welder and making a flange with a lip, however after visiting the local steel/metal yard and getting them to cut me some rect-tube in a size that was close (and modifying the holes slightly), I decided not to put a lip/flange on them. I did have to hit them with the grinder to get all the sharp edges off. All in all, I'm fairly happy with the way they turned out.

We conditioned and stained the top and bottom... and decided that I didn't like the way the stain looked on the top, so I sanded it all off (60, 100, 150, 220 grit) on the top only and started over with a different stain. Then three coats of urethane, sanding in between with 220 or 400 grit paper. Much better:

It took a bit of figuring, but I decided the easiest way for me to make rails for the plastic storage bins was a flat piece of stock and hanger bolts:


Next steps were screwing the base on  gluing the hole-liner metal pieces in:


Then gluing the lego boards on, and putting non-scratch furniture pads on the feet.  The final result is pretty cool looking, in my humble opinion. And my son loves it.




Now, if any of y'all reading this *are* indeed experts and have some tips - I'd love to hear them.

LEGO, the LEGO logo, the Minifigure, DUPLO, LEGENDS OF CHIMA, NINJAGO, MINDSTORMS and MIXELS are trademarks of the LEGO Group.
©2014 The LEGO Group. All rights reserved. Use of this site signifies your agreement to the terms of use.

Friday, June 27, 2014

Sous Vide cooker

Being a self-declared foodie, I decided to build a sous vide (French for under vacuum - water oven/bath cooking... Google it). After quite a bit of research on the interwebs (what else is new?) I decided on a design. Not to get ahead of myself, but it works like a champ and makes some INCREDIBLE food. Cooking large brisket and ribs in the ice chest, and smaller stuff like steaks in a pot on a hotplate. I'm going to try and use it to temper some chocolate for truffles next.

Final product:




Parts were roughly as follows:

I also wanted to be able to cook with some versatility (smaller pots as well as large/bulk items), so I picked up:
Wiring is as follows:
  1. Power goes into switch, 
  2. through fuse, 
  3. out into GFCI, 
  4. a line out of GFCI into PID 
  5. and another set out with positive going into the switched (regular) outlet 
  6. and hot/negative into the switched side of the SSR
  7. Thermo probe connected to PID,
  8. and PID output/trigger for SSR runs into the SSR


Wiring on the fused switch


Top level shot of wiring

Close up of wiring

Power supplied to PID Controller

Wiring of thermo probe and SSR to PID Controller - your probe may be different!

Wiring looking from switch toward GFCI

Another top level shot of wiring, turned around

Fused switch outlet

Final - note this is a later pic with the tubing-sleeved thermo probe

The ice chest and immersion heater. Because I vacuum bag all the food, I'm not worried about BPA leaching.

Saturday, March 9, 2013

Hallowenglish

I have found that of the many obscure and arcane things we find to stress about every day, the steps behind Division, Classification, and Process Analysis shouldn’t be included.  Let me tell a story of how this knowledge was imparted to me…
     The shack was run down, more so than the rest of the shanties leaning to and fro along the boardwalk.  I could hear the rain pittering on the tin roof, made from flattened coffee cans.  The only means to differentiate between the splintered, gaping boards of the flapping door and the adjoining walls was a crooked sign.  I could barely make out what it said.  “Sorceress Extraordinairre,” it announced in faded calligraphic script.
     She must have seen me paused there, hunching over to peer at her plaque, for from inside came a voice straight out of Oz.
     “Well, are you going to stand out there in the rain all day?  Come in, come in…”
     The weather making me no better offer, I hastened through.  It was dim inside and had a musty smell – like one’s attic or basement.  The walls were lined with shelves of bottles, flasks, and jars containing vague floating forms.  Scattered about the floor were several dark, hunched shapes I hoped were furniture.  They made me nervous – even more so when one spoke:
     “Fortune read?” it cackled, shifting to point in my general direction.  “First one’s free, first one’s free!”
     Caught off guard, I stuttered.  “I, uh, I don’t really…” Then something seemed to make up my mind for me.  I heard myself accepting her offer.  “Thank you, I would love it.”  A light flared, and then settled on a candle.  The shape of my hostess turned, shuffling through some curtains I hadn’t previously noticed.  Warily skirting the “furniture,” I followed.
     Inside, there were more candles; their flickering shadows hid more than they revealed.  Even so, I could now perceive my hostess – a wizened little gnome, wisps of white hair poking out from beneath the hood of her robe.  She sat me at a short, round table covered in cloth so faded as to barely make out the design.  In the center, a large crystalline orb sat upon a silver holder designed to look like a toad.
     A face like a cypress pushed toward me, gnarled and ancient – some of the grooves too deep to see bottom.  “What’ll it be?”, she asks.  If I had entertained any questions as to why her furniture didn’t devour her, the wash of fetid breath quickly disposed of them.  “Palm read?  Horoscope? Numerology? Tea leaves?  The I-Ching?”
     Gasping, “Whoa, what is all that?  I thought you would just tell my fortune?”
     “Not one to be impressed by the fancy stuff, eh?” she muttered.  “Fine, fine…,” and leaning over, hawked and spit on the crystal ball.  In almost the same motion, she took a fold of her robe and wiped it off.  It might have been my eyes, but it seemed as if faint shimmers of light followed the motions of her arm.  Mumbling under her breath, she waved long bony hands over the orb.  “I see you very agitated.  Yes, you will be extremely anxious.  There is much work ahead of you if success is to be found, but proper preparation can reduce the burden.  I am to be your guide upon the path of enlightenment.”
     “Isn’t that a bit vague?” I ask.  “That would fit just about anyone I know.”
     Her wavering left eye rolled up to focus briefly on me.  “You want more specific?  How about this: I foresee you completing an assignment for a college class.  Yes, it was foggy but now it’s getting clearer… it’s a paper… on division, classification or process analysis.”
     “Division classification?  Process analysis?  What do they mean? Are those more of your mumbo jumbo mystical phrases?”
     “No, my pet,” she smiled through a nasty, yellow picket fence.  “They are simply ways of organizing information.”
     “Simple?  I don’t even have the faintest clue of where to start!”  Cold skeletal hands gripped my soul.  What fate could be worse than this, I thought, a composition without a clue.
     My concerns must have shown upon my face.  “Fear not,” she cackled, “These aren’t arcane formula, they’re used every day by many ‘normal’ people.
     “To begin with, both categories have several things in common.  Upon beginning your paper, it is important to first choose a subject to analyze.  Will it be spells and potions, or will it be arcane implements?  Maybe you will write about useful local flora.  By picking a topic that you are familiar with, the paper will also be easier to write.
     “Then, you must determine the purpose of your analysis.  Will it be instructive, such as the steps to a love spell, or a treatise on the uses and abuses of poison herbs?  Should it be educational, like a brief synopsis categorizing the ancient orders of druids?  Finding your purpose will also help determine the nature of the paper:  division, classification, process analysis or some combination thereof.
     “In addition to – and often alongside – a purpose, an aspiring scribe should consider their audience.  If your purpose is dividing the faerie into nymph, dryad and the like, you certainly shouldn’t be addressing novices.  It is important to keep in mind who you are writing for.  Boredom or incomprehension could ensue, resulting in needless tragedy for those faerie.”  Here she paused to wheeze for a short moment before continuing.
     “The next thing that needs deciding is one’s tone.  If the scribe isn’t undead, they’ll have an opinion on the topic.  This – and not a third eye – will help set the paper’s point of view.  If you’re angry that newt’s eyes have been left out of potions for hundreds of years, use your anger as a focus.  If it’s light-heartedness you wish to portray in your classification of flying spells, humor is the magic word.”
     “A thesis statement is then developed.  It should clearly and concisely convey all of the above: your topic, point of view, and audience.  It will warn readers of what to expect from the paper.  Ideally, the thesis should be one or two sentences at the beginning of your paper.
     “This is when the three paths split.  The first we follow is that of division.  You should use division when there is a single large idea that must be broken down into smaller pieces to more easily understand.  Take, for instance, the golem.  While some might say, ‘seen one, seen them all,’ you may disagree.  You might wish to help aspiring magi understand the differences between them.  What you would need to do is find where the sharpest differences lay, and that will enable you to categorize them.  With golem, it’s rather easy.  The difference is what they’re made of: Iron, mud, stone, and flesh.”
     With that, she paused to sit back and noisily slurp something from a cup, whose appearance I hadn’t noticed.  In the poor light, the cup resembled a small skull in a way…  She neglected to ask if I wanted any, an oversight I was more than happy to forget.  The sound she made when clearing her throat made me think of the LaBrea tar pits.  I would have checked behind me for saber-toothed creatures if she hadn’t leaned forward, ready to continue.
     “Classification is almost an opposite to division.  When you bring several related items together under a single category, you are classifying.  Bat wings, for instance, may not seem to have much in common with salamander tails or nightshade.  But as we sorceresses know, they all are used in wart hexes, and so may be lumped under one heading.  The same could even be said of magi, sorceresses, wizards and witches – all practitioners of magic!  The key here is finding the similarities between your items.
     “The last style, process analysis, is really a mix of the first two.  It is a technique used to explain the steps required to accomplish something.  All our novices get ‘Build Your Own Broomstick’, a scroll leading them through a sometimes tricky process.  Another example of a process analysis is Hecate’s famous scroll, ‘How I Summoned the BeanSidhe, and Lived to Tell About It,’ a process I’m sure none of us would put to use now – purely informative.  The analysis is usually put forth in a clear, simple, chronological order.  The division and classification help in deciding which large steps you need to break up, and what little steps can be conglomerated.
     “When moving from one division to another within your paper, you may choose to use transition words.  Transitional phrases often contain indicative words such as ‘kinds, parts, categories, abracadabra, first, next’ and so forth.  ‘First the leg of spider, then the wing of bat.’  They help the paper flow, carrying the reader from one idea to the next.
     “At last,” she said, slapping her bony hand on the table for emphasis, “these three styles reunite at the end in what’s called the ‘conclusion’.  In the cauldron of your paper, this would be the time your previous ingredients may bob briefly back to the surface.  Any last minute seasoning, directions for usage, suggestions, or solutions for the audience would be appropriate here, as well.   For example:  after a heart-wrenching essay on the poor non-living conditions today’s vampires suffer, you might reiterate the points made in the thesis, and ask the readers to do their part by leaving their cellar doors or attic windows ajar…”
     As her voice went on, the words got fainter and fainter.  There must have been something wrong with the candles, or it might have been my eyes, for the light seemed to be fading as well.  The last thing I remember was hearing a soft echo,  “Now, novice, you are ready to begin your paper.  Go forth confident in your knowledge.”  Suddenly I felt very sleepy – I just wanted to close my eyes for a bit…
     I awoke in the library, slumped over my notepad amidst half eaten candy-corn.  I shook my head, amused at having fallen asleep while trying to start my paper.  I had been so frustrated with my assignment before, but where once there was emptiness, now there were ideas.  It would be easy to decide on and write about division, classification or process analysis.  I picked up my pencil, turned the page, and stopped – written there in a faint calligraphic script were the words, “The End.”


[I stumbled across one of my old papers/assignments while cleaning out some backups. --Ben]

Ben's Gluten Free Waffles

Ben's GF Waffle Recipe
These are the best waffles I've ever made or had, gluten free or otherwise. Just the right balance of moist, chewy, sweet and nutty.

"Dry ingredients"

  • 1/2 c brown rice flour 
  • 1/4 c coconut flour 
  • 3 Tbs each flaxseed meal, potato starch, powdered milk 
  • 1/4 c Arrowroot flour 
  • 1/2 c Sorghum flour 
  • 2 Tbs brown sugar 
  • 1 tsp baking powder 
  • 1/2 tsp salt 
  • Mix mix mix 
"Moist ingredient"
  • 1 Tbs coconut oil, shortening, or butter** (see notes) 
  • Mix mix mix 
"Wet ingredients"
  • 1 egg 
  • 3/4 c milk 
  • Mix mix mix 
  • 1 Tbs lemon juice 
  • Mix mix 
  • Extra milk if needed. 
**Notes -- I worked the solid coconut oil in like you do with butter/shortening when making pie crust or biscuits, but I probably should have heated it until just liquid and incorporated it at the end.

Saturday, September 1, 2012

Raspberry Pi, MAME, and Ultrastik, pt 1

Among the things I want to do with the Raspberry Pi is to build a miniature arcade thing. I had planned on making one with one of my mini-itx systems, but the Pi just seems so much better. And honestly, it's more stable than any of the mini-itx systems I've used. I had already ordered an Ultimarc Ultrastik 360 and a bunch of arcade buttons. The Ultrastik is awesome, I seriously wouldn't build any type of arcade without using one of these.  One of the things it can do is flash 9x9 control maps so it can be a 4-way, 8-way, 2-way, and more. It also hooks up via usb, supports direct connection of buttons, and the 2.5 firmware can use one of those as a shift (so it basically can support about 16 buttons). Awesome. I got the medium-firm spring and the circular restrictor plate to give it a shorter throw.
I started with the Adafruit Occidentalis build for my RPi, which came with the stuff I needed "out of the box" to get the WiFi dongle working.
Earlier experiments trying to get MAME and a frontend gui working didn't go so well, but I ran across a few posts that helped. I followed Chris's guide and parts of Ben's post to get AdvanceMAME and AdvanceMenu compiled and installed. I'll skip the hassle I had getting all the appropriate files & configurations loaded into the right directories.
Then I snagged Al Crate's configuration utility for linux (link goes to Ultimarc page, code is linked at second line from top). To get that to compile, I needed to grab a few things and compile libhid (because it's not available to RPi via apt-get install yet for some reason). But to get *that* to compile without a warning throwing the whole thing out of the make command, I had to edit the libhid-0.2.16/test/lshid.c
There's a line that says:

len = *((unsigned long*)custom);
Right below it, I threw this:
if(len==0){;}

So that got libhid compiled, and after an ldconfig I got ultrastikcmd to compile. The next set of problems I ran into were:
  • When I ran ultrastikcmd to load a map into the Ultrastik, it dropped off the machine. jstest /dev/input/js0 no longer found it (although an ls /dev/input/ shows a js0 node).
  • When I unplugged and replugged the joystick, the jstest would work again but the input either didn't work at all or was scrambled.  I did a LOT of using my Windows machine to load new maps into joystick.
I ended up fixing the second issue first -- after adding some code to ultrastikcmd.cpp to give it a verbose debugging flag, it appeared that the default map border values (a parameter/setting on the Ultrastik that allows you to tweak the 9x9 grid sizes, I *think* -- but it isn't very well documented yet) were being set by the program but it was passing all 0's to the device. I tweaked that and at least when I unplugged/replugged the device the stick was passing appropriate values to jstest. I'm sending the code to Al so he can get it into the next version, but if you need all the debugging code, etc. let me know.
The section of code I fixed is toward the bottom -- I just commented out the if and closing brace. Since it sets the defaults & overrides them if you load them from a map or command line, it should be ok to write them to the device no matter what. I might not have needed to do this if the Ultrastik configuration maps I used had map values in them.
//if(arguments.border_set){
// Byte[3]-Byte[10] = Map Border Location
memcpy(&data[3],arguments.border,sizeof(arguments.border));
//}

The remaining big issue was the fact that the thing kept falling offline. After hours and hours, and a significant amount of searching, I figured out that when ultrastikcmd takes control of the joystick to flash a map to it, the system unbinds the kernel driver. I tried a couple dozen things to get it rebound programmatically (and learned a lot about devices and usb on linux in the process), but the reattach code isn't in the libusb or other stuff built into the RPi image I was using, and to heck if I'm going to re-compile the whole OS.
I ended up creating a whole lot less elegant solution, but it works.
Here's what we started with. You can see that jstest works - the joystick gives appropriate readings when I move it.
$ jstest /dev/input/js0
Driver version is 2.1.0.
Joystick (Ultimarc Ultra-Stik Ultimarc Ultra-Stik Player 1) has 2 axes (X, Y)
and 16 buttons (Trigger, ThumbBtn, ThumbBtn2, TopBtn, TopBtn2, PinkieBtn, BaseBtn, BaseBtn2, BaseBtn3, BaseBtn4, BaseBtn5, BaseBtn6, BtnDead, BtnA, BtnB, BtnC).
Testing ... (interrupt to exit)
Axes: 0: 0 1: 0 Buttons: 0:off 1:off 2:off 3:off 4:off 5:off 6:off 7:off 8:off 9:off 10:off 11:off 12:off 13:off 14:off 15:off
Now switching to 4-way map
$ ultrastikcmd -vfou ~/ustik_maps/4-way.um
And trying jstest again -- no love
$ jstest /dev/input/js0 jstest: No such device

One of the things I learned about along the way is sysfs. That and a bit of poking around yielded something interesting. This presumes you have usbip installed, and gives you a list of usb devices by USB BUS ID. d209:0501 is the Ultrastik.
$ sudo usbip list -l
- busid 1-1.3.3 (d209:0501)
        1-1.3.3:1.0 -> unknown
        1-1.3.3:1.1 -> usbhid
See that little "unknown" there? That's the not-bound kernel driver. Here are the input devices -- notice there aren't any js0 entries, but there is for event1 (1-1.3.3:1.1), which comes from the Ultrastik. Note: for this and other directory listings, I'm going to edit them down to save space & improve readability.
$ ls -la /sys/class/input/
event1 -> ../../devices/platform/bcm2708_usb/usb1/1-1/1-1.3/1-1.3.3/1-1.3.3:1.1/input/input10/event1
mice -> ../../devices/virtual/input/mice
mouse0 -> ../../devices/platform/bcm2708_usb/usb1/1-1/1-1.3/1-1.3.3/1-1.3.3:1.1/input/input10/mouse0
It doesn't show above as bound to the driver, but we can double check. No driver listed!
$ ls -la /sys/bus/usb/devices/1-1.3.3:1.0/
bAlternateSetting
bInterfaceClass
bInterfaceNumber
bInterfaceProtocol
bInterfaceSubClass
bNumEndpoints
ep_82
modalias
power
subsystem -> ../../../../../../../../bus/usb
supports_autosuspend
uevent

This one is (the one for event1, which is the other BUS ID listed by the usbid command).
$ ls -la /sys/bus/usb/devices/1-1.3.3:1.1/
0003:D209:0501.000B
bAlternateSetting
bInterfaceClass
bInterfaceNumber
bInterfaceProtocol
bInterfaceSubClass
bNumEndpoints
driver -> ../../../../../../../../bus/usb/drivers/usbhid
ep_81
input
modalias
power
subsystem -> ../../../../../../../../bus/usb
supports_autosuspend
uevent
Yup, a driver!

Now for the fun part. Evidently, if you write the appropriate usb bus ID to the kernel driver bind file, it rebinds. Hmmm...
echo -n "1-1.3.3:1.0" | sudo tee -a /sys/bus/usb/drivers/usbhid/bind
You need to put the sudo in the right spot and use tee because the user doesn't have write permissions to bind. I'll fix that later.

Now lets check to see if it appears rebound:
$ sudo usbip list -l
- busid 1-1.3.3 (d209:0501)
        1-1.3.3:1.0 -> usbhid
        1-1.3.3:1.1 -> usbhid

Yes! And importantly, jstest worked again!

Now how do I keep from having to manually do this every time I load a map into the Ultrastik.  Enter udev (and two more links) and some shell scripting.
First step, since I want to try and programmatically be able to rebind in user (vs. root) space, I'm changing permissions/group for the usbhid kernel bind. I'm sure someone will point out all kinds of evil wrong things this will do, but this isn't a server/production machine... it's an arcade joystick.
$ sudo chmod g+w /sys/bus/usb/drivers/usbhid/bind
$ sudo chown root:pi /sys/bus/usb/drivers/usbhid/bind
$ ls -la /sys/bus/usb/drivers/usbhid/
--w--w----  1 root pi   4096 Aug 31 23:45 bind

To make things easy, I also want to create a symlink to the bind in a convenient location.
$ ln -s /sys/bus/usb/drivers/usbhid/bind ~/ultrastik/usbhid_bind

Now I need a udev rule. I've added a rule to write the kernel to a file under the home folder, for ease of access in my shell script.
$ cat /etc/udev/rules.d/81-ultrastik.rules
SUBSYSTEM=="usb", ATTRS{idVendor}=="d209", ATTRS{idProduct}=="0501", GROUP="input", RUN+="/home/pi/receive_udev.sh '%s{manufacturer}' '%k'"


That matches the Ultimarc Ultrastik, ensures when it's added that a group the user is in can get to it, and then runs a custom shell script passing in a couple variables. I'm not using the first one (manufacturer), it was just for testing. Here's the script that receives that rule and writes the usb bus id out. I'm hard-coding the ":1.0" part in hopes that doesn't screw it up later.
$ cat receive_udev.sh
#!/bin/bash
echo "$2:1.0" > /home/pi/ultrastik/ultrastik_sysfs_id

So now all I need to do to fix/rebind the joystick is:
$ cat ~/ultrastik/ultrastik_sysfs_id > ~/ultrastik/usbhid_bind

I've tweaked the AdvanceMenu configuration (~/.advance/advmenu.rc) emulator line to call a generic emulator (my script):
emulator "AdvanceMAMECustom" generic "/home/pi/ultrastik/advshim.sh" "%s"

That script is as follows -- where you see rom1|rom2, etc. you would replace those with the names of the roms that need a specific Ultrastik map.
#!/bin/bash
# if no command line arg given
# set ROM to Unknown
if [ -z $1 ]
then
  ROM="*** Unknown ROM ***"
elif [ -n $1 ]
then
# otherwise make first arg as a ROM
  ROM="$1"
fi
case $ROM in
        # 8-way
        rom1|rom2|rom3)
          ultrastikcmd -ou ~/ultrastik/ustik_maps/8-way.um
          cat ~/ultrastik/ultrastik_sysfs_id > ~/ultrastik/usbhid_bind
          ;;
        # 4-way
         rom4|rom5)
          ultrastikcmd -ou ~/ultrastik/ustik_maps/4-way.um
          cat ~/ultrastik/ultrastik_sysfs_id > ~/ultrastik/usbhid_bind
          ;;
        *)
          echo "Sorry, no ROM defined!"
          ;;
esac
/usr/local/bin/advmame $ROM

So...

  1. On boot or Ultrastik insert, udev catches it and writes something like 1-1.3.3:1.0 to  ~/ultrastik/ultrastik_sysfs_id
  2. When you launch a game from advmenu, it calls the  advshim.sh script, passing in the rom name.
  3. The script checks the rom name to find the appropriate ultrastik configuration map, 
  4. ...runs the ultrastikcmd configurator (losing the joystick in the process), 
  5. ...writes the contents of the previously-written usb bus ID to the bind to pick back up the joystick,
  6. ...then launches advmame with the rom.
Easy, right?  I really did want to do something elegant in the ultrastikcmd program itself, like issue a USBDEVFS_CONNECT command via ioctl. But that didn't work (kept giving me a device busy error). If someone out there has suggestions on how I can better accomplish this, I'm all ears.
Now all I need to do is wire up the buttons, get them all configured properly, and build a case for the whole assembly.
And PS -- don't load a strict 2-way only map... you can't navigate advancemame without up & down. I'll make a map that had most of the 9x9 grid filled with left and right, and only a narrow up/down portion for anything that might require only left and right normally.