Introduction

FASE is a ZX Spectrum engine that helps you to create a specific type of game. The game must be a platform game without scrolling at 50fps. The major advantage in this engine is a very fast sprite painting routine, that allows you a big number of simultaneos sprites on screen without flickering. The engine is located in the upper side of the memory and the contened memory is occupied by graphics data, so you have from 0x8000 to write your own code. The demo code is written with SDCC compiler, but you can use the compiler or the language that you want, the only restriction is that your code must start at 0x8000.

Multi Machine

The engine detect your machine at loader stage and put the code that offers better non-flickering results depends on your machine. There are three cases:
  1. Machines with floating bus like Sinclair 48K
  2. In this case we need a precise synchronization in the frame time (69888 cycles). The exact point is below the playing area, and the only way to do this is by putting special values at the video memory and detect reading in the floating bus. By this reason in this mode you'll see a bar, the "sync bar", that has a size of 32x1 cells (256x8 pixels).
  3. Machines with 128K memory paging
  4. Now the trick is very different. We use double buffering because we have a second screen (shadow video) at page 7. So the key is to show always the other screen while writting into the hidden one. That is, if we show the page 5 (normal screen) we write on page 7 (shadow screen) and vice versa.
    In this case we make the sync at the start of the frame via interrupt code.
  5. Rest of machines
  6. This is the worst case because we have only about 14400 cycles to paint flicker free sprites. We do the sync at start of the frame (as in 128K mode) but always write on the same screen. The good news is that there are few cases, always non original Sinclair machines (also called clones). If you want to try it just for curiosity, launch your emulator in 128K mode and choose 48K basic in the menu.

How to use

Basically you must provide three kinds of elements. Graphics elements like sprites, tiles, bullet an map. Also code elements as your convenience, we put a simple demo in main.c but you must need more files when your game grows in complexity. And finally configuration elements. The configuration elements are part of the engine itself, but we facilitate the task by grouping the most part on config.def file (the rest are in engine.asm and loader.asm).

When all elements are ready you must compile the project, generating a file called game.tap. There are 3 ways of generate game.tap. Just execute fase.bat with zero or one of these parameters:
  1. fase gfx
  2. Will compile all files. Type this if you modify map.tmx or any png file or tmode constant in config.def. You can modify the png files with any image editor (I use GIMP) and map.tmx with Tiled (www.mapeditor.org/). To ensure legal ZX Spectrum colors filter it with PosterizeZX
  3. fase config
  4. If you change one of the options into config.def (except tmode)
  5. fase
  6. Without parameters just compile main.c (or main.bas) and generate game.tap

Modifing graphics

Just modify png files as in the example with your favorite image editor, I use GIMP. They are sprites.png, tiles.png, bullet.png and loading.png. We use the same format that Churrera. That is 256x32 sprites image in black/with with separate mask in black/red, and 256x[multiple of 16] tiles image, with a limit of 256 tiles. Remember that your pallette is limited to the 15 ZX Spectrum colors, if you are not sure pass your file by PosterizeZX (in util folder).

The map file is stored in map.tmx, to open and change the file use Tiled. To create an empty map type employ GenTmx (also in util folder). If you want to create an empty screen (not accessible in the game) put the left upper tile with a tile different than zero, and the rest with tile zero. This won't encode this screen and it will cost only a byte.

Another trick is in the tile definition. You can use the same tile with different colors or different tiles with the same colors, in both cases you'll save many bytes in memory. During compilation you'll see a message with the different size of the tileset depending on the tile mode. There are 4 tile modes, depending if you index bitmap, attribute, both or none.

Modifing code

You have a complete example in SDCC. The only requirement is that your compiler generates Z80 machine code starting at 0x8000, and that it communicates with the engine by the small memory area located between 0x5b00 and 0x5c07. In the demo, the interface definition is located into fase.h and it's based on mapped variables, for example:
  unsigned char __at (0x5b00) sprites[12][4];
With this code if I write sprites[2][1] I am refering to the X coordinate in the third (first one is zero) sprite. Note that writting in the screen is a little awkward, for example if you want to update the scoreboard. You must write a function and write to 5c06-5c07 (mapped in drwout) every time that you need to call the function:
  drwout= (unsigned int)update_scoreboard;
Also don't assume that the video memory is on 0x4000. You must add shadow<<8 to the address before write because in 128K mode there is another screen between 0xc000 and 0xdaff.

Take care about heavy task if you want mantain the 50fps. Sprite painting is about 3500 cycles per sprite, so if for example you have four sprites that's 14000 cycles of almost 70000 (20% of the frame). So in this example you have up to 56000 cycles to do non graphic stuff like collision management, inertia and gravity calculation and game logic. If you surpases this number you'll miss a frame.

Modifing configuration

The main part of the useful constants are grouped in config.def file: Another useful constants outside the config.def are scolor and ccolor in engine.asm to configure the color of sync and clipping bars, and border_loading in loader.asm to put the color in the border after the tape loading.

Advanced stuff

As said before the interface between game and engine is by memory, exactly the area area located between 0x5b00 and 0x5c07. In this section I'll explain the structure in detail.
If you want to know the internals of the engine, this memory map will be useful for you before reading the assembly code in engine.asm.


Credits


FASE 0.99 / 2014-01-28