Jump to content
IGNORED

Atari Lynx Game Creator?


Recommended Posts

All joking aside LX.NET has a tutorial/diary of an Atari Lynx developer.

The link is in this forum section.http://atariage.com/forums/topic/206456-atari-lynx-programming-tutorial/page-1

I found it quite difficult to get to grips with so eventually gave up. It would be nice if the more experienced Lynx programmers could do a simple step by step tutorial for the people that want to try and learn. I know it'll take time but it might help a lot of people. I'm not talking a full game but some essentials like, here's your sprite, here's how he moves/shoots, here's a back ground, here's how it moves, here's an enemy here's how he moves/shoots.

Rgds

BadPricey

Edited by BadPricey
Link to comment
Share on other sites

I've shared some source code for a simple board game (Peg Solitaire) on this forum which compiles out-of-the-box with the cc65 compiler and the sprite-tool sprpck, on Ubuntu or Cygwin environment.

 

It uses Chipper for music, TGI from cc65 for sprite drawing and some other drivers provided by cc65 for input. It's written in a template that's good for a puzzle game, but also sufficient for more complex games.

 

Tutorials on actual game development are a topic that doesn't require the Atari Lynx at all. You can build anything once you figure out how to draw sprites and get input, whether its C/Assembler on the Lynx or JavaScript in a browser, any game dev tutorial on making a platformer/puzzle game/shooter will do. On the Lynx the real challenge is to deal with the hardware-specifics.

 

Platform preferences aside, LX's tutorials are probably the most structured explanation out there.

Link to comment
Share on other sites

Just a small overview of some of the logic behind creating Lynx games/demos, from the top of my head:

 

All graphics on the Lynx are sprites. Even the backgrounds. Sprites can be upto 511 pixels wide at a height only limited by memory. You could write directly to the display buffer using the CPU (at four bits per pixel for sixteen colors), but this will be much slower for most purposes.

 

Your sprites can be anywhere in memory. Sprites have a small header of data telling them where they should be positioned within a 32K x 32K pixel area. This header also contains the settings for x/y scaling, tapering, sheering, collision settings, x/y mirroring, positioning from top-left or another position, transparent color, RLE compression* and color remapping.

In this header you also set a pointer to the next sprite to be drawn, creating a linked list of sprites only limited by memory. In this header you also set a pointer to the actual pixel image of your sprite.

 

Then you tell the graphics chip where the top-left position of your display in this 32K x 32K 'world' currently is (by setting an x and y position hardware register). By changing this position each frame, you can scroll the display in all directions. After that you tell the graphics chip to start drawing your sprites (after you have pointed it to the first sprite in your list). It will start with the first sprite and then draw all the other sprites in the order your list is in.

So it will draw your sprites back to front, each next sprite in the list on top of the previous (which you will only notice if they are at overlapping positions ofcourse).

 

A way to make sure everything moves fluidly is to use the vertical blanking interrupt. This will call the function you point it to every time the display has finished displaying one frame. If you change all your sprite positions and anything else you want to animate in that function and then draw your sprites, things will move smoothly (if it is able to handle all that in 1/60th of a second for a single frame).

 

To support lower or unstable framerates, have more time to draw your frames and avoid flickering, you can use double buffering. This means you have one display buffer that is currently being shown on the display, while your sprites are being drawn to another display buffer that isn't visible yet. Then when the vertical blank interrupt calls your function and your sprites have all been drawn, you can swap both buffers, showing your newly drawn buffer on the display.

 

Apart from the vertical blank interrupt, there is also a horizontal blank interrupt. This is called every time a horizontal line (scanline) on the display has been displayed. The time you have here to do something before the next is displayed is much shorter than with the vertical blank interrupt. A common function to use with this interrupt is to change the color of the background for each scanline, this way you can make smooth gradients for a sky or ground (like in Shadow of the Beast and Roadblasters).

Changing the whole palette (or any amount of it) at a certain scanline (vertical position) is also possible, but there is not enough time to do this. A solution is to show one or two empty lines while you are updating your palette. The graphics below those lines can then be displayed using this different palette. IIRC Roadblasters does this.

 

Drawing vector lines and filled polygons on the Lynx is all done by scaling, tapering and sheering one or two single pixel sprites. There is some math involved in converting the vector coordinates to these scale, taper and sheer settings.

 

*RLE compression stands for Run Lenght Encoding. A very simple way of making your sprite data smaller in memory. The way this works is you set how many pixels of the following color the sprite engine should draw horizontally. So for instance you would tell it to draw 64 red pixels, followed by 32 blue pixels, followed by 50 green pixels. Which would be much smaller than telling it which pixel color to draw 146 times.

This only works well for sprites that have large areas of the same color, like cartoony looking sprites for instance.

If your sprite has lots of small detail, meaning the color changes almost every pixel horizontally, RLE compression will actually make the data larger than when not using it. In this case you would be saying: Draw an orange pixel one time, then draw a white pixel two times, draw a blue pixel one time, which would be really inefficient.

 

I hope this information will be useful to someone. I only programmed the Lynx in assembly, which is really close to the hardware. Programming it in C will probably have some different logic here and there.

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...