Monday, December 21, 2015

3D Christmas

Growing up we had dated Christmas ornaments on the tree for a number of years. They were silver or crystal. I think one was cross-stitched. I thought it would be good to restart that tradition in my own family - we have a couple dated ones already. So this year, I made a Christmas 2015 3D-printed wreath ornament. This is the second 3D-printed ornament on our tree.
Last year, the White House sponsored a 3D ornament contest. The contest rules required the entry to be put up on Instructables - here’s our’s. The wife and I designed the ubiquitous red ball, but embossed the first stanza of The First Snowfall by American poet James Russel Lowell into the surface:

The snow had begun in the gloaming,
   And busily all the night
Had been heaping field and highway
   With a silence deep and white.

We didn’t win. Although there was no contest this year, I went ahead and made one for ourselves.


The design is pretty much monolithic and made of three colors dictated by my stock of filament. Because my simple printer only has one print head, I had to make three jobs of it and glue the results together. I’m a bit enamored with extruded text like Robert Indiana’s LOVE sculpture. I used Inkscape to create an SVG file of the text and extruded it in Autodesk 123D. One thing I learned was I liked the text sized larger when it came to printing and building the model vs. the size it looked on the screen. Maybe it's "the camera adds 10 pounds" phenomenon. I printed the characters 30% larger than I designed them.

Not sure what will be next year’s creation. Probably something smaller so it doesn't crowd out the other ornaments we’ve collected over the years.


Monday, November 30, 2015

READY (Atari BASIC Redux)

READYI recently found an active online community of Atari 8-bit computer retro enthusiasts. Having grown up playing games on and programming an Atari 400 (1982-1985) and an 800XL (1985-1989), it’s been fun getting back into it. A couple years ago I loaded the Atari800XL emulator on my Raspberry PI to show the kids the games I used to play. They were unimpressed. Too bad, because I could beat them at Asteroids. More recently, I’ve been working on a BASIC program using the Altirra emulator on my Windows 7/10 desktop. I learned about a 10-line BASIC game programming competition on the ANTIC podcast, which gave me a goal for my retro ruminations. I’m hoping they’ll rerun the competition in 2016 so I can enter.



To prepare, I decided to brush up on my BASIC. I only ever used Atari’s BASIC (cart. on the 400 and built-in on the 800XL), but have since learned there are many more BASICs from which to choose. For this program, I’m using Turbo BASIC XL because it’s faster and supports block memory copies. When I tried to write games in junior high, I didn't know about Atari's player-missile graphics (hardware based sprites) although I did learn a little of the C64 sprites in 8th grade computer programming. This time around, I set out to learn a couple of the things I missed growing up: page flipping and hardware sprites. To use these techniques in Atari BASIC requires lots of PEEKs and POKEs and some understanding of the memory map, which probably explains why I didn't get it back then.

I asked the boy what kind of game I should write and he thought "20-ball Pong" would be hilarious. I prototyped it in Python to get the game logic down so I wouldn't have to design the game while relearning BASIC. The concept is pretty easy and Python on a modern machine is speedy. Coding up the ball motion in an emulator, I quickly re-discovered how slow Atari BASIC was and abandoned trying to use hires graphics. The game(I call this version LMNOPing!) is now in text mode with 5 inverse ATASCII characters (L-P) standing in for software sprites and a player-missile paddle. The ball motion is not smooth moving 1 space per frame, but the paddle is speedy. The game play is still really slow, but has served the purpose of learning some new (to me) programming.

Page Flipping

To create motion, an object on the screen needs to be redrawn every frame at a new location while erasing the old location. This algorithm can easily create a flickering effect. The way around it is to draw the new frame while displaying the current frame and then flipping the page to show the updated screen. My Python prototype uses this technique. Because the Atari uses memory mapped graphics in RAM, it's pretty straightforward to implement in BASIC - a number of old magazine articles cover the topic (links are below). Point the graphics chip to display buffer A while filling in buffer B. Then flip the screen by pointing to B while filling in A.

I learned an interesting feature of the clear screen (CLS) command that is probably documented somewhere, but wasn't obvious to me. In GRAPHICS 0 (text mode), and maybe in others although I didn't test it, the CLS command will put 0's into the memory starting at the graphics map pointer filling in all the way to another pointer called RAMTOP (top of memory). I thought it would just clear out 4 pages (1 KByte) of RAM. The consequences are if one points to buffer A and doesn't update RAMTOP to point to the end of buffer A, CLS will clear both A & B. (Thanks to Wade Ripkowski for pointing out this was indeed documented.)

Player Missile Graphics (Hardware Sprites)

My 8th grade computer programming teacher taught us about C64 sprites near the end of the semester. I used them in my final project, which was a Simon game. For some reason, I never learned them on the Atari. I guess I never really understood why one would want to use some blocky single color thing when there are some great graphics modes to use. Obviously, I never tried to write a program with a software sprite back then; otherwise, I would have seen them for the genius they were.

For this game, I’m going pretty simple with a basic bar that is moved vertically on the screen using the paddle controller. To move the graphic, the bytes have to be copied from one location to another and erased from their old location. Instead of tracking the move, it’s easier just to rewrite the whole column by copying a buffer with the appropriate offset. This is OK since I have plenty of RAM. I suppose in a tight 8K cartridge game this would be wasteful since I use 256 bytes just for the buffer and another 256 bytes for the sprites.

What’s Next

I squeezed this program into 8 lines for practice and might add some sound. Not sure if it’ll be an entry to the 10-liner competition, but it’s been a fun challenge.

Resources



Saturday, November 7, 2015

Destiny Ghost - 3D Print for Halloween Costume

The boy really really likes to play Destiny. So for Halloween, it was an obvious costume choice. The only real important thing to him was the Ghost - an electronic companion that floats by your side in the game. Thinking I might draw one up in SketchUp to print, I started looking at images. But, then I found a really nice design at Thingiverse and ended up printing it instead.

Searching images for Destiny cosplay yields several characters with Ghosts. Most of them are holding the little light in their hand, but some had it hanging above their shoulder. To hang our Ghost, I designed a hanger insert and glued it between the Ghost halves during assembly. Wife made a cross-body harness to hold the boom for suspending the piece above the boy’s shoulder. It worked pretty well.





Clogged Printer Nozzle

Halfway through printing the second half, the printhead clogged. I learned to change out the nozzle. At first, I thought I could just melt it out at 250-C, but that didn’t clear the plug. I tried a couple other techniques I found online to no avail. I broke down and ordered a new nozzle. After clearing the stuck filament, replacing the nozzle, and hacking the G-Code, I was able to finish the print in progress. It was already 5 hours in and I didn’t want to have to start over. The piece has a little dislocation because I didn’t get the restart layer exactly right, but it’s acceptable. 

I had to recalibrate the printer before printing anything else. It took a while to figure out how to make the prints stick with the new head - I think because it’s an aftermarket part and is a different shape from the original. I suspect it transfers heat away from the filament because the tip has a large cross section. To get the first layer to stick to the blue tape, I have to really get a good squish. For more testing, I printed my go-to calibration cube and saw that bridges were sagging. Lowering the temperature 5 degrees helped (maybe the different nozzle shape blocks the cooling fan airflow), but then the prints had trouble sticking on the first layer. I discovered in Slic3r, there’s an option to print the first layer at a different temperature - bumping it up 5 degrees solved my problem. Now I’m back in business.

Sunday, October 25, 2015

pencilWars using PyGame in Python

 About two years ago, Congress gave me some forced time off so I decided to learn some Python in addition to working on the house. Ever since learning BASIC on my Atari 400 (with the Atari 410 cassette drive!), I’ve liked interpreted languages. I probably inherited that from my dad who was an APL and SAS programmer back in the day. I still only program in Matlab for work. When I (tried) learning C++ and Java, I felt the same frustration recently expressed by Wil Wheaton. So Python had its appeal - interpreted, seemingly widespread, and free. I wrote a game because I didn’t have a particular problem I wanted to solve other than having fun and learning something new - just like when I banged away on my Atari, except now I don’t have to use a membrane keyboard and black and white television.

PencilWars is based on a paper-and-pencil game of the same name detailed in Tom Angleberger's Oragami Yoda. It is built using the pygame 1.9 package and runs in either Python 2.7 or 3.4. You can download the source code here.

Screen shot of pencilWars. Player 2 just moved indicated by the red pencil stroke and it's now Player 1's turn.
The architecture of the game is very similar to my last blog post Arduino Pong, although pencilWars has more states. In pencilWars, the user clicks the mouse - depending upon the state of the game this either selects a ship or moves the ship. To move the ship, the user "flicks" the mouse while holding down the mouse button in the desired direction of motion. The distance the ship moves is based on the velocity of the mouse during the click and not the distance moved. This action is the challenge.

The users take turns. If one hits an asteroid, they lose a turn. If one hits the space station in the middle of the page, they lose their ship. The first to destroy their opponent's ships wins.

One of the more interesting things I had to figure out was a function to determine the distance between the location of an sprite (ship, asteroid, station) and a line segment (the path taken by another ship). If the distance is less than sum of the two sprites' radii, there was a collision. 

I hope you enjoy playing. 

Thursday, October 15, 2015

Arduino Pong

While on summer vacation I ordered an Arduino kit when my oldest nephew expressed some interest in programming and electronics. We worked our way up to wiring the 8x8 LED matrix display. He had a fun time plugging wires into the solderless breadboard. Since he’s a gamer, I wrote up a single-player pong game to show him the basics of video game programming. A demo is on YouTube and the sketch is available on GitHub. Read on for a description of the software.



The sketch’s loop() contains three sections. The first updates the ball's direction based on its position. For example, if it hits the left wall, the horizontal direction is reversed. When the ball hits the paddle, the vertical direction is reversed upwards. To add some chance to the game (and make it nontrivial), the horizontal direction is randomized when the ball strikes the paddle. On a second variation, nephew suggested the ball direction depend on where it hits the paddle. In that version, the ball goes up if it hits the middle and left and right at 45 degree angles when it hits either end. Finally, if the ball misses the paddle, it’s position is reset to above the play field with a random direction so it enters the screen in a surprise location.

The second section in loop() updates the ball’s position based on the direction settings. To make it simple, the ball has one speed and can only move in 8 directions (up, up & right, right, down & right, and so on), The ball and paddle geometry are also matched to the 8x8 display, i.e. they are constrained from 0 to 7 in x and y coordinates. After the ball position is updated, the paddle position is read from analog pin 0. Arduino C’s handy map() function is used to determine the location of the paddle along the bottom row. Because the paddle is 3 pixels wide, the middle pixel position can vary from 1 to 6.  

The third part of loop() updates the bitmap and then pushes the bitmap to the display. The bitmap is an array of 8 unsigned ints inherited from the demo code for the 8x8 LED dot-matrix. In hindsight, it should strictly be bytes to fully realize the 64-bit video buffer. Fortunately, the shiftOut() function outputs the lower byte of an int. But first, the ball and paddle are inserted into the bit map. The video memory is arranged with each byte representing a column on the display. To draw the paddle, a for-loop iterates through each column of the memory and zeroes out the display memory. At the loop iteration where the paddle is located, the bit 0’s of the three columns for the paddle are set to 1. To draw the ball, a 1 is XOR’d into the horizontal position of the ball’s column byte. The XOR operator is used so the ball will light up an LED when it’s in the air and will blank out the LED if it hits the paddle. (Interestingly, the use of XOR on CRTs for this purpose was patented.) You can see this effect in the video -- it adds a little visual interest and increases the play area by an entire row (which is 12.5% of the available area).

Finally, the video memory is pushed to the LED matrix using shiftOut(). The functional purpose of this code is equivalent to the video card on a modern machine, but of course is much simpler. The LED matrix is controlled by scanning through the columns and selecting the rows to be lit. The code loops through each column of the display and uses two shiftOut() calls to select the column and the push the rows of that column. The shiftOut() sends the data serially to a pair of 8-bit serial to parallel converters, which latch the outputs to drive the LED array. Each column is held on for 1 millisecond and the display loop is repeated 10 times, for an elapsed time of about 80 milliseconds per frame or 12.5 frames per second. Then it starts all over again.

We made a second version of the game that uses a rotary encoder to control the paddle instead of the potentiometer. That's interesting because the encoder provides relative motion rather than absolute position and doesn’t have physical stops to limit the turning. By using modulo arithmetic, the paddle can then wrap around the display. A third variation adds a row of dots to the top of the display and becomes a breakout style game.