Clearly A Lack of Focus

So, you want that POD to do something?

November 17th, 2012

You probably saw someone selling an original Photon POD on E-Bay, or you “knew a guy” who let you smuggle one out of a closing Photon, and it’s been sitting in your basement for 20 years. Every once and awhile you see it and connect it to some kind of power supply (hey, you might even have an original diving^Wbattery belt who you were able to get charged.) The bloop-wheep-woop of a freshly plugged in POD is just that bit of nostalgia you needed — but you’ve always wanted more. You want to here the phaser fire. You might even want to hear the sound of a hit (or , as you remember, more often as you remember, a miss or the crushing sound of hitting someone on your own team.) If that’s what you need…

How to Make a Photon Entry Terminal

If you read my last post, “So, you want a modulated IR signal, and you’re too damn cheap to do it right,” you already have part of the answer to that puzzle. However, you’ll need some more bits (or bytes) to successfully fake the functionality of the entry terminal.

What does the POD need to play a game?

The Photon POD gets three pieces of information from the entry terminal:

  • IR Code for this POD
  • RF Slot Number for this POD
  • Game Mode

Sending the IR code AND slot number seem a bit redundant, since one is calculable from the other — but that’s how it was done. If you’ve read the previous articles, you know what these bytes should be. The Game Mode is new, and instructs the POD as to the game type (Public, League, & Free For All) and the number of fields in play (either a single field, or dual field setup)

Wait, what’s a dual-field setup?

Most Photon centers were single-field, but some (such as Chicago Harvey) were lucky enough to have TWO fields. Both of these fields would run games synchronously (starting, and ending at the same time.) To keep things straight, when the dual-field mode is enabled, even-numbered IR codes (and “slots”) ware associated with field 1 (the Alpha field), and odd-numbered IR codes are associated with field 2 (the Omega field.) If you try to shoot someone who’s entered in for the other field, “your phaser won’t work.” (well, it’ll just register a miss.)

Also, on game modes.

Two dimensions of the POD’s behavior are affected by the game mode. One is the length of time a hit registered on this POD will cause the phaser to be deactivated for. You remember from a previous article, the game computer has certain transmit slots to send data to the PODs. When the game computer transmits a POD’s IR code in one of those slots, it’s an indication to the POD that it has been shot, and it will deactivate it’s phaser for some period of time — and give you that nice WHOOP WHOOP sound that you remember fondly. In League and Free For All mode, this duration was a static 5 seconds. In Public mode, a simple handicapping strategy was in effect, and the phaser’s downtime was calculated within a range of 2 to 9 seconds — based on the ratio of hits and “got hits” as tracked by the POD.

The second dimension involves Free For All mode. In Public & League modes, when you were to hit someone on your own team, your POD would transmit the IR code of itself to indicate it had hit it’s own player. The game software would deduct 30 points, and transmit back to the pod it’s own IR code which would cause it’s phaser to be disrupted (this was a great way to test if the POD’s radio was functional, since you quickly got notification of a successful transmission & reception!) In Free For All mode, you could “hit” anyone regardless of team, and it would send the IR code of the player to the game computer. (will cover some interesting shenanigans possible here)

Single Field Dual Field
Public 0xc1 0xE1
League 0xc2 0xE2
Free For All 0xc3 0xE3

JUST SHUT UP ALREADY! I’ve got your damn IR software working, and this POD sitting here all turned on. THE BATTERIES WON’T LAST FOREVER!

Damn ya’ll are impatient. A 6-byte repeating sequence is required to activate a POD:

  • 0x9d (aka BARKER)
  • 0×62 (aka NOTBARKER)
  • Pod’s IR code
  • Pod’s RF Slot #
  • Game Mode
  • Checksum (calculated as BARKER ^ ~BARKER ^ IRCode ^ Slot ^ Mode)

For example, to enter someone in to red slot 5 in a public game on a single field — “red 5 standing by” — you’ll want to send:

0x9d, 0×62, 0×46 (0×42 + 4), 0×08 (0×04 + 4), 0xC1, 0x0D (that checksum thing)

Send that via IR to the pod a few times repeated, and, your pod might* work.

* Your POD will need a GR16 or greater version of the ROM. Otherwise, try the “dual field” game mode!

So, you want a modulated IR signal…and you’re too damn cheap to do it right.

November 7th, 2012

So, a long LONG time ago I was sitting at home hacking on the Photon gear, and wanted to implement a solution for the Entry Terminal, but was too lazy to build a hardware solution to take a 1200-baud serial signal and do the correct 38khz modulation on the signal to communicate with the Photon POD. (btw, 38.4khz IR modulation is the common modulation for most IR remote controls — so have fun)

I did some thinking — your typical PC serial port can comfortably output 115kbps. This means you have control of the “on and off” of your serial port’s transmit line is 3x the required resolution to correctly modulate a 38.4khz signal (115200 / 38.4 == 3, woohoo). There’s one problem — you don’t have full control over that TX line. Setting your serial port at 115200,8,n,1 (8 bits, no parity, one stop bit), you have control over 8 of the 10 bits sent (for reference). But! This infrared communications stuff must be tolerant to some amount of noise — so I took a leap of faith… Maybe the “noise” will be acceptable, and this will actually work. So, I grabbed a serial cable, shoved an IR LED onto the Tx and GND lines, and started hacking. Here’s what I came up with, and, believe it or not it bloody worked. Enjoy.

(remember, I wrote this code back in 1995. Don’t let it reflect on me professionally now. But I’ve added some comments to help decipher it)

// OMG this is not thread safe.
static int state = 0;
static int state2 = 0;
static unsigned char irbuf[255][100]; /* lookup table */

static int fd;

// Modulate's a single bit value (i == 1, or 0) at 38khz on to str beginning at
// ptr (a bit position within str)
static int modulate (int i, int ptr, unsigned char *str) {
  int which;
  int bob;
  int add;
  int f;
  static int takenext = 0;
  static int skipnext = 0; // if 1, we're at a bit we have no control over.
  static int state = 0; // state is tracking the modulation.

  // 115200 baud / 1200 baud == 96
  for (f = 0; f < 96; ++f) {
    // 115200 / 38400 == 3.
    if (state == 2)
      state = 0;
    else
      ++state;

    // this is a bit we have no control over, can't do anything.
    if (skipnext) {
      skipnext = 0;
      continue;
    }

    // and, we're actually at the start bit, get ready to work again.
    if ((ptr % 8 == 0) && (takenext != 1)) {
      takenext = 1;
      continue;
    }

    takenext = 0;

    // if state is 1 or 2, set the bit. Otherwise, don't.
    // Other than the stop * start bit, this is one element of "noise" -- our square wave
    // modulation was 2 steps on, one step off. Turned out not to be a problem,
    // probably because of the inherent on-off ramp times.
    if ((i == 1) && (state) ) {
      which = ptr / 8;
      bob = ptr % 8;
      add = 1 << bob;
      str[which] += add;
    }

    // at a stop bit
    if ((ptr % 8) == 7) {
      skipnext = 1;
    }

    ++ptr;
  }
  return ptr;
}

// For the value of a byte, modulate the "bits" to str.
int mod_byte(unsigned char outbyte, unsigned char *str) {
  int i;
  int ptr = 0;
  state = 0;
  state2 = 0;

  // start bit is high.
  ptr = modulate(1, ptr, str);

  // 8 data bits
  for (i = 0; i < 8; ++i ) {
    if (( outbyte >> i ) & 1 )
      ptr = modulate(0, ptr, str);
    else
      ptr = modulate(1, ptr, str);
  }

  // stop bit is 0.
  ptr = modulate(0, ptr, str);

  /* length (in bytes, not bits) of our modulated bitstream... */

  return((ptr + 7) / 8);
}

ssize_t outir(unsigned char outbyte) {
  static int i;
  static unsigned char buf[128];
  ssize_t j;
  j = write(fd, irbuf[outbyte], 96);
  usleep(50);
  return j;
}

void ir_setup(char *file) {
  struct termios t;
  unsigned char i;
  fd = open (file, O_WRONLY);
  ioctl(fd, TIOCGETA, &t);
  cfsetspeed( &t, B115200);
  ioctl(fd, TIOCSETA, &t);
  printf("modulating");
  for (i=0; i != 0xff; ++i ) {
    if ((i % 8) == 0) {
      printf("."); fflush(stdout);
    }
    mod_byte(i, irbuf[i]);
  }
  printf("done.\n");
}

Offsite Backups.

October 26th, 2012

I’ve recently decided to find a different solution for my offsite backups. For years, I’ve had a server in a co-lo facility — but I’ve realized that I don’t really need it much except for offsite backups. Factoring in the monthly costs to the colo facility, plus the time I should be spending maintaining the server to current patch levels, options such as Amazon S3 and Google Drive look rather competitive. However, there’s the question of what sort of software to use… Some basic requirements:

  • Compatible with FreeBSD.
  • Encryption.
  • Reasonably efficient incremental backup functionality.

Googling around, there’s s3rsync which has been around for quite awhile. There’s also a package that I remember from my past, Amanda – we used to use this at UMBC — and it seems to have some support now for S3 storage! However, I remember Amanda being reasonably complicated to deal with. Plus, it doesn’t seem to have support for Google Drive yet.

However, the other day I ran across Duplicity, which seems to be all that and a bag of kittens. Has backends for your popular cloud storage providers, encrypts your data via GnuPG.

Speaking of Google Drive — it’s not that I’m shilling for my employer — unlike Amazon we don’t seem to charge for upload/download bandwidth — and it’s price competitive — and I already pay for Google Apps for Business. So I think I’ll give that a try.

Any other ideas?

How Photon Works: Editorial Intermission

October 24th, 2012

Bryan Manternach made a comment and mentioned that Photon had an almost cinematic quality — so taking a bit of an editorial break to address that, and give my self a chance to think about what to cover next. Will it be the rather hacktastic but genius design of the CD remote control interface? The Entry Terminal’s pod entry protocol?

Disneyworld

Early Photon centers truly tried to build an experience around the game. For 1985/1986, they spared no expense. The first time I played (it was a the Ocean City, MD site — store #028), I was completely disoriented. I had no choice to follow the instructions that boomed over the sound system – commence strategic maneuvers – trying to make my way around a confusing maze. The lights on the field were constantly changing, and the expertly crafted soundtrack served to continuously raise the tension – intruder alert, intruder alert. I think that first game felt like it lasted hours, which I later would learn was only 6 minutes! The Ocean City Photon offered a “play all day” special — my brother and I spent our entire week’s vacation there. I’d say it was raining and we couldn’t go to the beach, but I honestly don’t remember going outside other than to grab a slice of pizza from the boardwalk.

Anyone who remembers me from the Baltimore Photon remembers that I was rather overly obsessed with the field’s lighting & sound experience. I’d spend hours refreshing gels, re-aiming lights and adjusting the lighting program so the shadows in the engine room where just right. Jeff Krepner and I fine tuning the crossover and equalization of the sound system so the bass rumbles during the beginning of Track 1 & 3 really “shook your balls”, but didn’t shake the BINGO scoreboard* off the wall of the neighboring “BINGO PLAZA BINGO”. It was also very important that the appropriate stereo separation be observable from key listening points while enjoying King Diamond’s “The Eye” at 2am.

* They did at one point accuse the bass coming off of our field of doing this. I’ll take them at their word.

Costco.

And this is why I don’t play any of the current laser-tag games. Every one I’ve been to — even the one I have some responsibility for (XP Lasersport in Laurel) — has the mystery and embrace of a Costco. I get my fix now daydreaming on the 101 while listening to Track 3. Remembering that first game in Ocean City. Joining the Junior League at Photon Baltimore (store #010) after coming back from vacation. Getting that Alpha pin. Getting a chance to spend time with  great folks like Skip Haughay and Lou Alevato — and everyone else of course, but Skip & Lou need to be remembered.

 

How Photon Works Part 2: Mexican Radio

October 23rd, 2012

I feel a hot wind on my shoulder
And the touch of a world that is older

When thinking of the day, I often associate memories of Photon with music that I listened to at the time, the smell of mildew-y carpet, the collection of rug-burns on my elbows and knees from said carpet and the healthy smell of freshly Lysol’d helmets. It’s also hard to forget that the day was a much simpler time. Best of luck to you when you connect an o-scope up to your 5ghz wifis and end up with any clue as to WTF is going on there.

I turn the switch and check the number
I leave it on when in bed I slumber

Photon used a very simple TDM (that’s Time Division Multiplexing) scheme for communication between the player units (pods) and the game computer. TDM means that you have a time to talk, and a time to listen. Photon divided up their cycles into 66 slots, as as follows:

Slot(s) Transmitter What
1 Game Computer Sync Byte
2 thru 4 Processing Time
5 thru 24 Pods Red Pods 1-20
25 thru 29 Game Computer Data for Pods
31 thru 50 Pods Green Pods 1-20
51 thru 55 Game Computer Data for Pods
56 thru 66 Processing Time

The table above may be the only information here that could be considered important for improving your game. I assume the processing time slots were set aside because the game computer was pretty damn slow — this was 1985 shit.

I hear the rhythms of the music
I buy the product and never use it

The sync byte was really the rhythm of the system. It advertised the state of the game, and could be:

  • 0xC5 - PSYNC – The Pre-Game sync signal
  • 0xCA - GSYNC - Game Sync
  • 0xEE - ESYNC - End of Game Sync

When a pod was “entered in” at the Entry Terminal (later post), it would be in a dormant state until it received three consecutive PSYNC signals; the lights on the helmet would begin blinking, signaling the player was ready to participate in the Ultimate Game on Planet Earth. When the game would start, the game computer would switch to transmitting GSYNC, which would trigger the POD to both begin transmitting data in its assigned timeslot in addition to listening for transmissions from the game computer in it’s assigned slots. Upon reception of three consecutive ESYNC signals, the POD would leave the game mode, and reset to it’s un-entered state.

It’s important to note that the PODs were programmed only to go through these state changes after repeated receptions of a specific sync byte — the RF communications were rather error prone.

I hear the talking of the DJ
Can’t understand just what does he say?

If you paid attention to the previous article, you might already know some of the story.

A POD has three (and then some other) transmission states:

  • Nothin’s goin’ on – Transmit my POD ID byte.
  • OMG I SHOT SOMEONE OMG OMG OMG - IR code of the lucky boy (see previous article)
  • OMG OMG I SHOT BASE THREE TIMES - IR code of the base you’ve shot three times. (OMGOMG, I can’t stop telling you!)
  • SMISS (0xBO) – Swore I expected a sync signal, but I missed it.
  • PRCVD (oxB5) - Hey, I’m receiving a PSYNC signal, but I’m supposed to be in a GSYNC state. WTF dude?
  • ERCVD (0xBA) - I’ve received the ESYNC signal. I see our time together is at an end.
  • EALARM (0xBB) - (meaning of this value has been paged out of my brain.)
  • HIT ACKNOWLEDGEMENT (0xA0 – 0xAF) - I acknowledge that I’ve received a hit signal (n – 0xA0 times)
The POD ID byte is a unique value burned into the EPROM of each POD; this unique identifier is used in conjunction with the RF data received to generate a performance profile of each unit. When a player successfully hit base three times in a row, the POD would switch from transmitting it’s ID to transmitting the code for the base for the rest of the game. In the instance where a player would hit someone on their own team, the POD would transmit the code for itself.
The stuff you really care about are the first three. The rest of the POD trasmission codes are only useful for diagnostics.
I’m on a mexican radio. I’m on a Mexican – whoah – radio
When the Game Computer received an indication that a POD had been hit, or that someone had hit their own player, the GC would send that PODs IR code in one of its designated transmit slots. Upon reception, the POD plays the most memorable “WHOOP” sound, and remember, “take cover, or they’ll keep zapping you.”
Remember, PODs did not communicate between each other — it was the Game Computer’s job to bridge the gap. The transmit frequencies used by the pods and the GC were slightly different.
I dial it in and tune the station
They talk about the U.S. inflation
I understand just a little
No comprende, it’s a riddle
The game computer and the PODs transmitted at slightly different frequencies — each were around 49Mhz, which if you recall was a typical frequency for a household wireless phone at the time. Before you start thinking about it, that’s ~6 meter wavelength. While providing for an efficient central antenna for this wavelength wasn’t a problem — even a 1/4 wavelength antenna for the PODs would have required at least 5ft.
I wish I was in Tijuana
Eating barbequed iguana
I’d take requests on the telephone
I’m on a wavelength far from home
The data transmission itself were FM-modulated 1200-baud bytes. The TDM slices were based on timing that was calculated by the oscillator on the POD’s logic board. Due to software limitations at the time — the Photon game software was written in compiled BASIC — the designers implemented the Game Computer’s side of the RF communication channel with a stripped-down version of the POD hardware on an ISA card. This was connected to the Central Radio via a basic serial interface — the central radio itself being a slightly modified version of the POD’s radio board (with the transmit & receive frequency crystals swapped, of course!) Those familiar with the gear would recognize this as the “Slave Board.”
I feel a hot wind on my shoulder
I dial it in from south of the border
I hear the talking of the DJ
Can’t understand just what does he say?
When writing replacement Photon software — both back in 1991 and later in 1999 on FreeBSD, dealing with the TDM timing was the trickiest bit. In 1991, I was writing the software in DOS — and since it was not a real operating system, it was a free-for-all as to what you could do. My approach was to find a custom divisor for the PC’s timer interrupt that would provide me with an interrupt to match the expected timing of the POD itself. The first rough guess was by the magic of math, and then it was later refined through experimentation. (as mentioned above, the POD would make it obvious if it didn’t receive a SYNC signal when it expected one.)
Radio radio… Radio radio… Radio radio…
I’m on a mexican radio. I’m on a Mexican, whoa-Oh, radio
I’m on a mexican radio. I’m on a Mexican, whoa-Oh, radio
So how might knowing this improve my chances of winning at Photon, you’re asking?
Well, for example, being entered into a later slot of the game on the ET would mean that if you shot someone very close to the time you were slotted to transmit, they’d be “down” with less of a delay.
Radio radio… What does he say ?
In the previous article, I mentioned some secret about the haunting of “green slot one”. Why it’s not 0×80 anymore? 0×80 is 1000000 in binary. That’s one “bit” of noise, that could be easily interpreted by the radio receiver and a UART as “you’ve just lost 10 points, and your phaser won’t work.” It’s really unfortunate that the communications protocol used by Photon didn’t include provisions for modern concepts such as error checking — but you have to give it to them that they realized from experience that some bytes were less fortunate than others.

 

How does (did) Photon work? Part 1, The Gun Does Not Shoot

October 22nd, 2012

Welcome to part 1 of an part series on how Photon, the Ultimate Game on Planet Earth worked. We’re talking about the game that you payed to play in an arena, not the hokey take-home thing.

The Gun Does Not Shoot

Photon operated on a reverse ir system. Meaning the suits or other targets emitted an infra-red signal that the phaser received. The infrared signal consisted of a single repeating byte, at 1200-baud*, 8 bits, no parity bit, 1 stop bit — modulated at 38khz. There are 20 possible “slots” on the red and green sides. Players on the red side emitted bytes 0×42 through 0×55. Players on the green side emitted 0×94 and 0×81 through 0×93. Early versions of the software used 0×80 as the code for the first green slot, however, this was found to put this player at an unfair disadvantage that will be discussed in a later article. Some systems ran in a “two field” configuration, where one field used the odd slots, and the other field used the even slots . A “hit” is scored by pulling the trigger on the phaser, and receiving three successive identical codes.

As you may remember, there were targets other than players on the field that had the following codes:

  • Red Base – 0×35
  • Red Base 2 – 0×36
  • Green Base – 0x2b
  • Green Base 2 – 0x2d
  • Red Tower – 0×32
  • Green Tower – 0×24
  • Target – 0×38

The ones we probably remember are the red base and the green base. I used to know what the “tower” and “target” were supposed to do, but the demand-paged memory system used in my brain has demanded that information be paged out.

There were also two major versions of the phasers in use. The first people commonly referred to as the “600 baud” phaser — the phaser itself wasn’t 600 baud — but this board was powered by 12 volts and used a handful of discrete components to demodulate the signal. As the quality of the capacitors and resistors varied, it typically had to be “tuned” via a variable resistor to optimally demodulate. The “1200 baud” or “autotuning” phaser-board used an integrated IR demodulator made by Sharp. It’s only downfall was being very sensitive to RF interference, and if it’s RF shield wasn’t fully attached would pick up interpret the electrical interference generated by the pulsating IR emitters of the suit it was attached to.

Apparently a dozen or so IR emitters draws a lot of power and makes a lot of noise — and while the phaser was “firing”, the IR emitters of the suit were shut down. Before you think that this is some magic way you could stop people from shooting you — remember, you could only fire once every (approx) 1.1 seconds — and those infrared emitters were only disabled for the time it takes to receive 3 bytes. Napkin math makes that out to be .024 seconds of freedom — if you were able to use this to your advantage, your timing was much better than mine.

So, now that you know you’ve shot someone — how do they find out they’re down? That’s the radio part — you’ll have to wait until the next episode.

Back in the day I had worked all of this out with the help of a o-scope, a PC, a couple fried UARTs, some alligator clips, and a lot of patience.

* The original Photon hardware used a 600-baud encoding.

Test post

October 15th, 2012

Like or make a comment to see if this works.

A New Hope

October 15th, 2012

A lot of stuff is going on.

There’s a baby.

There’s all of this house renovation stuff going on.

All is interesting.

I’ve decided to reset my “internet presence”, and wipe the old www.nofocus.org. I expect some bits will return after awhile, such as my mixes, Photon archives, and photo gallery. In time, of course.

I feel vindicated.

October 15th, 2012

It seems I wasn’t imagining things when I reported that Aruba Instant wasn’t handling IPv6 router/neighbor solicitations and advertisements correctly:

http://community.arubanetworks.com/t5/Aruba-Instant/Aruba-Instant-amp-IPv6/td-p/36091

I will say that, other than this little bug which I’ve been able to deal with by running older firmware — my three Aruba IAP-105s were a great acquisition  Certainly not cheap, but they provide a quality wireless experience in a house where the architecture & materials choices are a handicap. Quite stylish too — they don’t look too shabby flush-mounted to the ceiling.

The home network currently consists of a NetGear GS724TP switch, which provides Power-Over-Ethernet and VLAN support. Routing is provide by a FreeBSD 9 server — fuzzy.nofocus.org (connected via a Gig-E trunk) — the Arubas provide two SSIDs — a private wireless ironically named FreePublicWifi, and a guest wireless SSID (CostlyPublicWifi) which is bandwidth limited via FreeBSD’s ipfw. The Comcast Business Internet link is trunked into the FreeBSD machine via a separate VLAN.

fuzzy has a rather substantial ZFS pool for data backup and media serving, consisting of 4x 2TB and 4x 3TB drives (in mirrored pairs, of course) connected via an LSI Logic SAS controller.