skip navigation

The ATARI XG-1 Light Gun

Description

In this episode we learn about the history, mechanics, functionally and how to program the Atari XG-1 Light Gun to make our own shooting game

Released:
January 10, 2025

Original Link:
https://youtube.com/watch/2Uy3hhwdqqs

Transcription

Your support is greatly appreciated! https://www.patreon.com/8blit

Welcome to 8-Blit, a channel covering all the tips, tricks, and everything in between to program your own games for the Atari 2600 from 1977. In this episode we explore the Atari XG-1 Light Gun. What it is. Why it exists… and how we can use it in our own games for the Atari 2600. This was a difficult video to make due to the lack of available information, so stick with me here because we’re about to do something no one has apparently done… for good reason. That’s all coming up on this episode of 8Blit.

This channel is supported by viewers like you. A huge thanks to all our patrons that help keep the intrepid spirit of 8-bit game programming alive by donating a few dollars each month. You can help me produce more episodes like this one, where we dive deep into the inner workings of the ATARI 2600 hardware, the 6502 processor, and assembly language programming. Our patrons are also featured in the credits of each video. To become a patron, check out the link in this episode’s description. Thank-you all for your continued support, your contribution is greatly appreciated.

Light guns have been a part of gaming history for decades. First introduced in 1936 with the mechanical duck hunting game, Ray-O-Light, by Seeburg, a Manufacturer of automated machines such as vending equipment, jukeboxes, and coin-operated phonographs. The game featured a model duck that moved across a pond scene depicted within a cutout of a wooden box, and had a light-sensing vacuum tube within the duck’s body. Pulling the trigger on the game’s built-in rifle would engage a light inside the barrel which the duck’s sensor would detect should… the marksman’s aim not run foul. In what may seem like a massive leap in technology for the time, the early 1950’s brought us the invention of what we later referred to as a Light Pen, which was a light sensing wand that worked in conjunction with a CRT screen. The Light Pen would find wide use within early computing, especially in aerospace and military applications. However, probably due to the enormous cost, complexity, and size of the machines, the technology would not become synonymous with games until a couple decades later.In the mid-sixties, Namco, Sega, Midway, and Williams all made electro-mechanical games such as 1965’s Periscope, Captain Kid Rifle in ‘66, and Arctic Gun in ‘67. In 1968, Sega brought out Duck Hunt which used rear image projection with animated moving targets that disappeared when they were shot. This closely resembled an electronic game, but was still electro-mechanical with the image projection and animation done in the manner of a zoetrope. A device that produces the illusion of motion by spinning a drum with images inside, and viewed through slits, making the images appear to move due to the persistence of vision. The 1970s brought us true electronic arcade games, starting with Pong in 1972, but In the home we had the Magnavox Odyssey, with its own light gun accessory called the ‘Electronic Rifle’, and the game ‘Shooting Gallery’. The light guns of this era flipped how they operated due to the use of bright video screens. Now, the light sensor was moved from the target, and placed in the barrel of the gun. The on-screen targets would light up, which the gun would detect. Exactly, how the Light Pen operated a couple decades earlier. In 1985, the Nintendo Entertainment System was released in North America, which introduced the light gun to a large home audience, along with the games Duck Hunt, and Hogan’s Alley, followed by the Sega Master System in 1986, with the Light Phaser, and Safari Hunt… and in 1987, The Atari XG-1 light gun was released, considered by many to be… lacking.

To recount a tale of Atari is to navigate a labyrinth of bold, yet often questionable decisions. This is certainly… one such tale. After the Atari Video Computer System (VCS) debuted in 1977, it took approximately five years for its successor, the Atari 5200, to be released in 1982. You can easily identify the 5200 as the successor since 5200 is precisely double 2600, a nod to the original VCS part number. In order to clearly communicate this fact, the VSC was rebranded as the 2600. The 5200 internals were basically an Atari 400 8-bit computer without the bits that make it a computer. Due to it being a little late to market, and lack of any backwards compatibility with the hundreds of games available for the 2600, the 5200 achieved a lack-luster reception and was pulled from the shelves after only a couple of years. In 1986, Atari released the 7800 console. Three times that of the 2600… in keeping with the now established naming convention… and it was good. I mean, it had hand cramping controllers, but they were accurate, and it was backwards compatible with the majority of 2600 games. Just not the 5200 games. At the time of release, it was competing directly against the Nintendo Entertainment System which had already established an 80% market share. Even though the 7800 was technically impressive at the time, it couldn’t compete against Nintendo’s dominance, but did manage to sell over 1 million units until its discontinuation in 1992. Not content with having 1 mildly successful game console on the market, the Atari XE Game System was released in 1987, one year after the 7800 was released. It was basically an Atari XE 8-bit computer that could operate without a keyboard. Essentially, an upgraded 5200, but weirdly totally incompatible with it. The XE Games system could be purchased either with an included joystick, or as a deluxe set with a joystick, keyboard, and yes, finally… the XG-1 light gun. The XG-1 light gun functions similarly to a light pen, but with a grip and a lens to better focus light from the CRT screen. It connects to the console using the DE-9 port, just like other controllers. It’s generally regarded as inaccurate, with many users pointing out issues with horizontal tracking. The model bundled with the XE and sold separately is a very pale gray, while a reddish-orange variation was planned for the 2600 and 7800, but ultimately canceled. The XE Games system saw a total of 7 games utilizing the gun, while the 7800 had 5, and the 2600 had Sentinel. Released in 1990, it was the Atari 2600’s only originally released light gun game. To the best of my knowledge, we have discovered the unreleased game Shooting Gallery, a test rom, and a single homebrew game called Bobby is Hungry. Let’s add to that. While I have a couple games in the works, this episode example code includes the basics of another game I’m working on titled ‘Summer Sausages No Sunday Sales’. You play a farmer trying to protect his family and animals against an invasion of dastardly space robots. Use your gun and blast those tin cans back to where they came from! The core component of a light gun is a photodiode or a photosensor in the barrel that can detect changes in light intensity. Generally, when the trigger is pulled the screen is first blanked. As the CRT screen refreshes again, the photodiode detects the bright spots created by the scanning electron beam. When the beam is in a position in such a way that the lens inside the barrel of the gun can focus light on the sensor, then a hit is registered and the gun sends a signal to the console. It’s important to remember that the sensor will only register the beam when the gun is pointed at the spot where the beam is currently pointed. Our brains are slow and we’re tricked into seeing solid images on a CRT screen. This is called persistence of vision. In reality, the screen is flickering incredibly fast and the phosphor coating the inside of the screen is only glowing brightly briefly while the beam hits it, and then starts to decay. By the time the next scanline is drawn, the previous scanline has dimmed enough that the light sensor won’t detect it. In order to obtain an X/Y screen coordinate, the time interval between the screen refreshing and the hit being detected is used to calculate the coordinates. You then use these coordinates to calculate if they intersect your target on the screen. Some games use hit boxes instead of X/Y screen coordinates. Famously, Duck Hunt on the Nintendo Entertainment System would blank the screen and only draw white squares where the ducks were. If the gun registers a hit then the game knows the duck was shot. Due to the reliability of a CRT’s timing, and how the beam draws one scanline at a time from top to bottom, this can be very accurate. No such luck for LCD’s or other screen types. While a CRT redraws the entire image for every frame… at a reliable frequency, an LCD will set pixels individually anywhere on the screen… when they need to change. That compounded with an always-on back light renders the light gun pretty useless.

The XE, along with all future 8bit Atari consoles and computers, featured special hardware support for light pens, and, by extension, light guns. Retrieving the horizontal and vertical values to calculate the screen’s X and Y coordinates; where the shot was fired, was as simple as PEEKing at a couple of memory addresses. With the Atari 2600, we have no such support. If we want the X Y coordinates, we need to handle everything ourselves… let’s break down the components we’ll use to do this. This section talks about using the joy stick input registers to read the gun. For more information on this, check out our episode where we learn about all the switches and controller registers to move a ghost around the screen. First things first, everything starts with the trigger, and strangely enough, the engineer designing the gun chose to use the Joystick UP pin for a trigger pull. That’s the Switch A register, with either BIT 4 high for a player 1 trigger, or BIT 0 for player 2. The second part is detecting a hit. This time the designer chose to use the fire button on the joysticks. This part makes sense because this register can be latched… which means that when set, it remains that way until you unlatch it. This helps with hit detection in certain circumstances. These registers are BIT 7 of INPUT 4 for player 1, or BIT 7 of INPUT 5 for player 2. These bits are normally HI when the fire buttons are NOT pressed, and go low when pressed. So when we’re checking for a hit, we’re watching for BIT 7 to go LOW. That happens when the sensor in the barrel of the gun detects light. When we’re done checking for a hit and waiting for the next pull of the trigger… we can clear INPUT 4 and 5. We do this by setting BIT 6 of VBLANK to LOW to disable latching, later when the trigger is pulled again, in VBLANK we set the BIT to HIGH to re-enable latching. That’s all there is to it… except figuring out where the gun is pointed. Unfortunately for us, this next part is super complicated. So much so, that all the available Atari 2600 light gun programs basically copy the same piece of code. So much so, that the Atari Stella emulator only works with this one method, as far as I can tell. Let’s have a go at trying to explain what’s happening after you press the trigger, and see why it is, the way it is. Everything comes down to precise timing. Trust me I fiddled with the code, just a little, and even a couple cycles off just ruins your day. For this explanation I’ll stick with describing the timing code and skip past any game related logic. We’ll go over the main game loop a little later. To start on the right foot, we need to make sure that all the related code fits in the same page of memory. This is required because crossing a page boundary can cost you a machine cycle or two. For this to work, we need to be accurate down to the cycle. We’ll cover pages and memory addresses in a future video so make sure you poke that subscribe button to get a peek at new episodes. This all starts after the trigger is pulled and we’ve already begun VBLANK on a new frame. The first few lines are handling the remainder of VBLANK Next, this is perhaps the most crucial part of the process. We set the background color to YELLOW… but, it can be any bright color you want. If you’ve been following along with the other episodes in this series, you’ll know by now that your display kernel is drawing one scanline at a time, starting at the top left of your CRT screen and working its way from left to right on each scanline all the way to the bottom right. After we set the background color we don’t have to do anything else in terms of drawing the screen. We literally want to draw a solid color, and nothing else. Now after starting a new scanline with a WSYNC, and then wasting a few cycles to get the electron beam in the right place, we’ve primed our loop so each iteration will start with the beam in the same location when we start to check for light detection. Entering that loop starts our Course Test, this is used to get a general horizontal position where the gun was aimed. It takes 5 machine cycles to check if we’ve detected light, and due to the speed of the Atari 2600 processor, we can only check 11 times per scanline. After detecting light, we jump down to where we assign a seemingly magic number into the accumulator register. These are actually the horizontal pixel locations aligning to the 11 read positions. At this point our Vertical Y position value will be correct. However, our Horizontal X position value still needs refining to better narrow down exactly where the gun was pointed. We were limited to the 11 position granularity because we could only check the input every 5 machine cycles, that’s a span of 15 pixels. This code is going to check for 5 more scanlines, with a timing that will read the sensor 1 machine cycle earlier than the previous scanline. This will refine the span down to 1 machine cycle, which is 3 screen pixels. m:code, overlay 11 dots animation over the code, and then again on next five lines All this gives us the X and Y screen positions where the gun was pointed moments after the trigger was pulled. Now all we need to do is use those values to check if it hits any targets. Let’s have a look at this again to break down all the steps visually.
This is a representation of the 11 course horizontal positions. The last one on the scanline would actually occur during horizontal blank so it’s not shown here. When we see our robot on the screen, we carefully aim, and then pull the trigger. Let’s put a blue box up on the screen to show where our gun was pointed. At this time we’re only concerned with detecting light, so let’s hide our robot for now. As the beam is moving across the screen, we’re checking at each coarse horizontal position to see if we see light. If not we move on to the next. If we saw light during a check, like we have in this example, then we remember which scanline this is to use as the vertical Y position of our shot. We also keep track of which coarse horizontal X position detected the light. Before we move on to the next scanline, we enter a specially timed loop that will check for light again, exactly one machine cycle earlier than our coarse position. Which will be 3 pixels to the left. This loop continues checking 1 machine cycle each scanline, or until no light is detected. This continues for up to 5 scanlines. When our loop is completed we know the Horizontal X position of the last time we detected light, along with the Vertical Y position of the first scanline detected. All that’s left for us is to draw our screen normally, and place our graphic object, like the player, missile or ball graphic at that location on our screen. After the screen is drawn we check for a collision between our object, and our robot using the collision registers. For more information on the collision registers, check out our episode where we break down how the game Tank bounces missiles around the playfield.

This episode comes with two fully working examples done using different approaches. They both have their upsides and downsides, as you’ll soon see. Each frame is made up of two tracks, where the robots will run across the screen in a randomized direction and speed. There is only 1 active robot per track, and when it’s hit, a new robot will spawn after a randomized interval. It will continue on like this forever. Except for how the examples look, that is pretty much the only similarities between the two. The example we’ve been looking at uses collision detection to determine if a robot has been hit. When the trigger is pulled, we jump to that alternative kernel that sets the background color to yellow, and then begins drawing the screen and calculating the horizontal and vertical position of the shot. On the next frame during VBLANK, we set the horizontal position of the Ball Graphic to the position we detected our hit. Then we resume drawing our screen as normal. When the tracks are drawn, we’ll also draw our ball at the vertical Y position of the shot. During overscan, after the screen finishes drawing, we’ll check the collision registers to see if there was a collision between the first robots player ZERO graphic, and the Ball graphic, or the second robots player ONE graphic and the Ball graphic. If there was a collision then that robot was hit, so it’s reset to be respawned later. This method requires you to know exactly where the gun was pointed, and keep track of which scanline you’re drawing so you can draw the BALL graphic, and then perform collision detection. That was a little fussy for me, so I decided to try this a different way. A better way… from a certain point of view. We’ll get to that. This time we don’t need to know the HORIZONTAL X or VERTICAL Y position of the shot, or even where vertically on the screen we’re placing our tracks. We also don’t need to do any timing calculations, or collision detection. Here’s how it works. When the trigger is pulled, and the next frame starts we turn on LATCHING for the INPUT 4 and 5 registers. This is done by setting bit 6 of VBLANK. This will remember if the light sensor detects a hit until we turn off latching. We then use the next two frames to check if one of our robots was hit. In the first frame we draw the first track, but replace our robot’s player graphic with solid white. On the second track we don’t draw the robot at all. This means the only thing displayed in this frame is a white box where the first robot was located. During overscan we simply check if the light sensor registered a hit. If so, then we kill the first robot and set him to respawn later. If not then we do the same for the next frame. This time track one is empty, and track two has the white box. Let’s have a quick look at that visually. Here we have our robot waiting patiently for us to scramble his circuits. We point the gun at him, and pull the trigger. In the next frame we replace his graphic with a white block, and simply check once if we detected light. If we have, then we know the bot has been hit. But… What happens if we have more than one target on the screen? Simple, we show only the white box for the target we want to check on individual frames. When we detect light, we know which robot was hit. We do that until we get a hit, or we’ve been through one frame per object. It’s really THAT simple! There’s just one small problem with this approach. To my knowledge, it doesn’t work on ANY Atari 2600 emulators… but, it does work perfectly on REAL hardware. In Stella, we use the mouse to act as our light gun, we simply point at where we want to shoot, and click the mouse button. However, no matter where we click, we’ll never hit the robot. I don’t know exactly how the Stella emulation handles the light gun, but the code is open source so if anyone wants to dig into that and report back, I would greatly appreciate it. I suspect it’s only checking for the background pixels rather than any pixels, like the player graphics objects. Whatever it is, it made it really difficult to figure out why the code wasn’t working when I was making that example. While it would have been nice to play the game in Stella, that wasn’t the only difficulty. Debugging, and stepping through your code is a real hassle. In the first example, the game runs fine in Stella, However, the moment you set a break point, and land on it. The debugger seems to forget what it was doing. If you break after the point where the light was detected, then back track and move forward again, it’s as if the light was never detected in the first place. I imagine supporting the light gun would not have been very easy due to it being completely different than any other controller. Also, there’s only four programs for it, so the demand is very limited. At least it works for the existing games… and it does that very well.

Lightguns offer a very rare, but very interesting control mechanism for your game. They provide a simple human interface that gives your players the ability to make lightning fast movements that are as quick as their reflexes allow. Best of all, it’s easy to implement… once you get the hang of it. We’ll keep refining this new concept into a solid game, and more episodes will be coming soon. We’ll even show you how to use the Sega Master Systems Light Phaser on the Atari 2600. So remember to subscribe if you haven’t already done so. As always, all the example code used in our episodes are available in our code repo located at the link in the episode description. Have you programmed Atari today? That’s all for now, thanks for watching, and I’ll catch you later!

Back to top of page