Skip to content

Commit

Permalink
another editing pass on docs
Browse files Browse the repository at this point in the history
  • Loading branch information
yeastplume committed Feb 19, 2020
1 parent f77f011 commit 3cf1169
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 40 deletions.
12 changes: 6 additions & 6 deletions docs/ex_001.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ In Aseprite, create a new image of any size and shape. It's generally far easier

![palette](images/01-palette-001.png)

All asset development projects will start by crafting a palette targeted for the intended display modes, and need to take considerations such as pixel depth into account. For instance, images displayed in 4 BPP (i.e. 16-Colour) modes will need to ensure that all of their pixels are selected from a range of colours no more than 15 indices apart on the palette, and that these indicies are aligned to a multiple of 16. Colours in 2 BPP (8 Colour) modes need to be 3 indices apart, while 8 BPP (256-Colour) modes can use the entire range of the palette.
All asset development projects will start by crafting a palette targeted for the intended display modes, and need to take considerations such as pixel depth into account. For instance, images displayed in 4 BPP (i.e. 16-Colour) modes will need to ensure that all of their pixels are selected from a range of colours no more than 15 indices apart on the palette, and that these indices are aligned to a multiple of 16. Colours in 2 BPP (8 Colour) modes need to be 3 indices apart, while 8 BPP (256-Colour) modes can use the entire range of the palette.

There will be much more on what this means and how it affects our development pipeline later, but for now let's carefully create our palette by clicking on the foldery-thingy on top of the palette display and selecting a NES palette, which gives us a few nice default gradients to work with:

Expand Down Expand Up @@ -82,14 +82,14 @@ Now, a couple of important things that should be noted about your palette image

* If the source `.png` file uses RGB colour, the palette infomation will be derived from contents of the image itself. Each palette entry will be created from the first pixel of each colour that exists in the source image (read left to right, top to bottom). If the number of colours that exists in the image is greater than 256, the operation will fail. In our example above, the image data is laid out to ensure the result of reading it in RGB mode would result in the same information as reading the palette indices. In most cases, you'd only want to derive the palette from an image in RGB mode if you're using 8BPP images and don't need to consider the palette of other image files too carefully.

* Aloevera stores palette data internally as 24 bits per pixel, one byte each for the red, green and blue channels (alpha in the source image is ignored). However, VERA palette entries are stored as 4 bits each for the red, green and blue channels. Therefore, when Aloevera outputs VERA palette data, the 4 least signficant bits of each color index is truncated. In practical terms, this means that a value of, e.g. #45D3F8 becomes #4DF, and all 'shades' in image files that result in #4DF will be treated as one and the same by future Aloevera operations.
* Aloevera stores palette data internally as 24 bits per pixel, one byte each for the red, green and blue channels (alpha in the source image is ignored). However, VERA palette entries are stored as 4 bits each for the red, green and blue channels. Therefore, when Aloevera outputs VERA palette data, the 4 least signficant bits of each color index is truncated. In practical terms, this means that a value of, e.g. #45D3F8 becomes #4DF, and all 'shades' in image files that result in #4DF will be treated as one and the same by future Aloevera commands.

Now we have a palette imported, ready for future operations. We'll get to those operations later, but first let's take the opportunity to demonstrate the rest of Aloevera's workfow in a minimal example by assembling the palette information and poking it into the x16 emulator.
Now we have a palette imported, ready for future operations. But first let's take the opportunity to demonstrate the rest of Aloevera's workfow in a minimal example that assembles the palette information and pokes it into the x16 emulator.

The ultimate output of Aloevera is assembled data ready for inclusion by popular assemblers or concatenated into a BASIC program. This is done with the `asm` command as follows:

```.sh
aloevera -p project.av ./output
aloevera -p project.av asm ./output
```

This assembles all the resources in the project file (which in this example is only a palette), and places them into the target directory in the order in which they were included. There should now be a directory `output` which should contain a `palette` directory that contains a single file with the ID of the palette we imported earlier, that is to say `palette_1.ca65.inc`. Let's look at the contents of this file:
Expand Down Expand Up @@ -117,7 +117,7 @@ This assembles all the resources in the project file (which in this example is o

That's our palette information formatted for VERA and ready to be incorporated into our assembly project via a simple include statement.

Code that does exactly this along with instructions on how to run the sample, can be found in the [samples/palette](../samples/palette) directory of this project. The sample also includes a makefile that pulls in changes to resources, so changes to the image file are automatically picked up by the build process. Since Aloevera works like any other command, is can be integrated into your build or development pipeline however you see fit.
Code that does exactly this, along with instructions on how to run the sample, can be found in the [samples/palette](../samples/palette) directory of this repository. The sample also includes a makefile that pulls in changes to resources, so changes to the image file are automatically picked up by the build process. Since Aloevera works like any other command, it can be integrated into your build or development pipeline however you see fit.

Let's take a quick look at the result of poking this data into VERA's palette location:

Expand All @@ -130,7 +130,7 @@ To make it simpler to play around with VERA concepts, Aloevera can also 'assembl
To assemble data into basic, use the `--format, -f` command with the `asm` command as follows:

```.sh
aloevera -p project.av -f basic ./output
aloevera -p project.av asm -f basic ./output
```

This will create a file called `./output/palettes/palette_1.basic.inc`, that looks much like this:
Expand Down
6 changes: 3 additions & 3 deletions docs/ex_002.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ Since all display modes use the same type of underlying data, all image data is

When an Imageset is first imported from a PNG file, it doesn't attempt to match any RGB values to a particular palette, nor does it need to know about the target screen mode or pixel-depth. This means you can store palette files separately, and use a single imported palette for a range of different Imageset files.

Transforming Imagesets for use in at a particular screen mode and colour depth is done later on during a separate `format` step. Formatting an Imageset does the hard work of validation and selecting the correct palette indicies for your screen targets. It ensures that all the indicies in the image data match what's in the given palette and it enforces any constraints that may be in place due to the target screen mode. If there is a problem with the Imageset data you're trying to format, Aloevera will tell you all about it long before it turns up as garbage on the actual X16.
Transforming Imagesets for use in a particular screen mode and colour depth is done later on during a separate `format` step. Formatting an Imageset does the hard work of validation and selecting the correct palette indices for your screen targets. It ensures that all the indices in the image data match what's in the given palette and it enforces any constraints that may be in place due to the target screen mode. If there is a problem with the Imageset data you're trying to format, Aloevera will tell you all about it long before it turns up as garbage on the actual X16.

This should all become much more clear throughout these examples, but the basic Aloevera workflow is:

* `import` a Palette
* `import` an Imageset
* `format` the Imageset to a target palette and colour depth
* (optionally) `import` Tilesets, Sprites or Bitmap Images that reference the Imageset
* (optionally) `import` (or `init`) Tilesets, Sprites or Bitmap Images that reference the Imageset

Let's get started with a simple example:

Expand Down Expand Up @@ -87,7 +87,7 @@ aloevera -p project.av asm ./output/
aloevera -p project.av asm -f basic./output/
```

Since the X16 starts up in Mode 0, i.e. 1BPP Tiled-Text Mode, we should just be able to replace the cold-boot tileset data with our assembled data and watch the font change. Code to do this is found in the [tile_text sample](../samples/palette), and the results are as follows:
Since the X16 starts up in Mode 0, i.e. 1BPP Tiled-Text Mode, we should just be able to replace the cold-boot tileset data with our assembled data and watch the font change. Code to do this is found in the [tile_text sample](../samples/tile_text), and the results are as follows:

First, in assembly: Note the new, 'improved' (i.e. much-harder-to-read) font:

Expand Down
8 changes: 4 additions & 4 deletions docs/ex_003.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@

In [the previous example](./ex_002.md), we learned how to use Aloevera to create, import and poke a new imageset into the Commander X16, replacing the default character set with our custom designed one. In this example, we're going to introduce the concept of an Aloevera **Tilemap**, which allows you to reference frames from that Imageset to 'paint' the screen.

If you view an Imagemap as a set of tiles, then a Tilemap is a picture painted with those tiles. Aloevera can take a tiled image created with frames matching an existing Imageset and, so long as it respects the Imageset's formatting and constraints, it can assemble a Tilemap ready for poking into VERA.
If you view an Imageset as a set of tiles, then a Tilemap is a picture painted with those tiles. Aloevera can take a tiled image created with frames matching an existing Imageset and, so long as it respects the Imageset's formatting and constraints, it can assemble a Tilemap ready for poking into VERA.

Without further ado, here's an example of a tile 'banner' painted with frames from the previous Imageset. (This is all being performed within the same [tile_text sample](../samples/tile_text)):

## Creating a Tilemap

![banner](images/03-banner-001.png)

Every 8 by 8 pixel tile in this Image matches a tile in the previously imported Imageset. Since this is intended for use in a 1 BPP mode, the coloured pixels you might have spotted on some of the 'painted' tiles don't matter when it comes to matching Imageset frames. Tilemaps in 1BPP modes are only concerned with whether pixels are "on" or "off" and will reconcile to the source Imagemap so long as the same pixels are "on" or "off", regardless of the colour of an "on" pixel. More on this in a little bit.
Every 8 by 8 pixel tile in this Image matches a tile in the previously imported Imageset. Since this is intended for use in a 1 BPP mode, the coloured pixels you might have spotted on some of the 'painted' tiles don't matter when it comes to matching Imageset frames. Tilemaps in 1BPP modes are only concerned with whether pixels are "on" or "off" and will reconcile to the source Imageset so long as the same pixels are "on" or "off", regardless of the colour of an "on" pixel. More on this in a little bit.

For flavour, we've also included a palette in this image that corresponds to the first 16 entries in VERA's default palette (which is also the C64 default palette). As stated in the previous example, foreground and background colours are applied by Tilemaps in 1 BPP modes, whereas at higher pixel-depths this information would be contained in the Imagemap itself. Since we're still using a 1BPP mode for our example we'll import this new palette for use with our Tilemap.
For flavour, we've also included a palette in this image that corresponds to the first 16 entries in VERA's default palette (which is also the C64 default palette). As stated in the previous example, foreground and background colours are applied by Tilemaps in 1 BPP modes, whereas at higher pixel-depths this information would be contained in the Imageset itself. Since we're still using a 1BPP mode for our example we'll import this new palette for use with our Tilemap.

## Importing the Tilemap

Expand All @@ -30,7 +30,7 @@ And with a new palette imported, we `init` a new Tilemap. We can't just import a
aloevera -p project.av tilemap init tilemap_1 text_set_1 128 64 text_16
```

`tilemap_1` is, as with all previous commands, the id of the new Tilemap. `text_set_1` is the id of the previously imported Imagemap. All Tilemap frames (which we'll load in the next step,) must only contain tiles that correspond to the frames of this Imagemap.
`tilemap_1` is, as with all previous commands, the id of the new Tilemap. `text_set_1` is the id of the previously imported Imageset. All Tilemap frames (which we'll load in the next step,) must only contain tiles that correspond to the frames of this Imageset.

`128 64` is the target map width and height. This just happens to be the size of the Tilemap in the X16's default display. `text_16` is the target layer mode, also corresponding to the X16 default. We'll look at a few other modes in later examples, but for know just know this means that all map data entries in this mode are stored as an 8 bit tile index followed by a 4 bit background colour index and a 4 bit foreground colour index.

Expand Down
16 changes: 8 additions & 8 deletions docs/ex_004.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

### BASIC and CA65 Assembly Code for this example can be found in the [samples/tile_wall](../samples/tile_wall) directory.

Now that we've worked through an Imagemap and Tilemap example at 1BPP, it should be very straightforward to move to some higher pixel-depth tiled modes. In fact, the only real difference between 'Text' and 'Tile' modes is how colour data is handled, otherwise, they work more or less identically. There are however a few additional palette constaints you need to be aware of which we'll outline during this example.
Now that we've worked through an Imageset and Tilemap example at 1BPP, it should be fairly straightforward to move to some higher pixel-depth tiled modes. In fact, the only real difference between 'Text' and 'Tile' modes is how colour data is handled, otherwise, they work more or less identically. There are however a few additional palette constaints you need to be aware of which we'll outline during this example.

## The Tileset

Expand All @@ -15,11 +15,11 @@ I have vague notions of one day re-creating an enhanced version of my personal C
Now is as good a time as any to go over the rules for formatting imagesets in 2-8 BPP Modes, so let's just dive in:

* In 2-8 BPP modes, the formatting process is as follows:
* Each pixel in the image is checked to ensure it's RGB values exist somwhere in the target palette.
* The pixels in each frame are checked to ensure they can all be found within a specific range in the target palette, which depends on the target depth. More specifically.
* Each pixel in the image is checked to ensure there is an index that contains corresponding RGB values somewhere in the target palette.
* The pixels in each frame are checked to ensure they can all be found within a specific range in the target palette, which depends on the target depth. More specifically:
* In 8BPP mode, all colour entires for each pixel within a single frame must exist anywhere in the palette.
* In 4BPP mode, all colour entires for each pixel in a single frame must exist within 15 indices of each other somewhere in the palette. Further, these indicies must all lie in a range starting from a multiple of 16, e.g. 0, 16, 32, 48, 64.. etc
* In 2BPP mode, all colour entires for each pixel in a single frame must exist within 3 indices of each other somewhere in the palette. These indicies must all line in a range starting from a multiple of 16 rule.
* In 4BPP mode, all colour entires for each pixel in a single frame must exist within 15 indices of each other somewhere in the palette. Further, these indices must all lie in a range starting from a multiple of 16, e.g. 0, 16, 32, 48, 64.. etc
* In 2BPP mode, all colour entires for each pixel in a single frame must exist within 3 indices of each other somewhere in the palette. These indices must all line in a range starting from a multiple of 16 rule.
* If any of these conditions fail, the format will fail, and the source image must be edited to fix the inconsistencies.

The 'multiple of 16' rule is perhaps the most confusing here. VERA stores palette offsets for each tile in a tilemap using only 4 bits, so there are only 16 'starting' palette locations to work with. At the end of this example we'll have a quick demonstration of what this means in practical terms when you're designing your Imageset, but rest assured that Aloevera will let you know if your Imageset violates any of these rules.
Expand Down Expand Up @@ -51,7 +51,7 @@ And here's the result of assembling and poking all this data via the [tile_wall

![tile_wall tiles](images/04-tile_wall-003.png)

The end result in both the BASIC and Assembly versions are the same. The assembly version is nice and fast. The BASIC version reminds me of a Next Generation episode where Picard experienced an entire lifetime in about 15 minutes elapesed time. You should have time to go and do something similar while you wait for the BASIC version to finish doing its thing.
The end result in both the BASIC and Assembly versions are the same. The assembly version is nice and fast. The BASIC version reminds me of a Next Generation episode where Picard experienced an entire lifetime in about 15 minutes elapsed time. You should have time to go and do something similar while you wait for the BASIC version to finish doing its thing.

## More on Palette Alignment

Expand All @@ -71,9 +71,9 @@ Look at those rogue pixel! It's at index 26, well outside our range (and isn't w
No range in palette found for frame set_1_1 suiting bit depth 2 (all palette entries must be within 3 indices of a multiple of 16)
```

We'd also get this message if all the shades of blue in the palette started at index 17 instead of 16. Just a quick example of how Aloevera can help you ensure your image data is correct long before it turns up as garbage on the X16.
We'd also get this message if all the shades of blue in the palette started at index 17 instead of 16. Just a quick example of how Aloevera can help you ensure your image data is correct long before it turns up on the X16.

Once you have a good grasp on how Imagesets and Tilemaps work in Aloevera, the rest is just shouting. Aloevera's functionality is rounded off with support for Sprites and Bitmap images, but both are just simple cases of Imagemap loading and formatting:
Once you have a good grasp on how Imagesets and Tilemaps work in Aloevera, the rest is just shouting. Aloevera's functionality is rounded off with support for Sprites and Bitmap images, but both are just simple cases of Imageset loading and formatting:

### [Example 5: Sprites](./ex_005.md)

Expand Down
Loading

0 comments on commit 3cf1169

Please sign in to comment.