tile2sam
A Python script to convert SAM Coupé graphics images to Z80 code or data.
Generated code is sprite-specific and highly optimised. Or provide your own drawing routines for the extracted graphics data.
Installation
Installing the tool doesn't require the source code or even Python, just uv.
Install uv if not already installed. Windows users can do that using:
winget install --id=astral-sh.uv -e
Then install the tile2sam command using:
uv tool install tile2sam
Command-line Options
usage: tile2sam [-h] [-m MODE] [-c CLUT] [-o OUTPUT] [-a] [-p] [-i] [-b BKGCOL] [-t TILES] [-z CODE] [-n NAMES] [-0]
[-v] [--version] [--crop CROP] [--scale SCALE] [--shift SHIFT] [--share] [--timings]
image [tilesize]
Convert SAM Coupé graphics images to Z80 code or data.
positional arguments:
image
tilesize tile size (WxH or W) (default: None)
options:
-h, --help show this help message and exit
-m MODE, --mode MODE output data screen mode (1-4) (default: 4)
-c CLUT, --clut CLUT custom colour file or list (default: None)
-o OUTPUT, --output OUTPUT
custom output filename (default: None)
-a, --append append to existing output file (default: False)
-p, --pal write clut to .pal file (default: False)
-i, --index write offsets index to .idx (default: False)
-b BKGCOL, --bkgcol BKGCOL
background colour (0-127) (default: None)
-t TILES, --tiles TILES
tile count or list of ranges (N-M) (default: None)
-z CODE, --code CODE Z80 routines to generate (default: None)
-n NAMES, --names NAMES
Names for sprite labels (default: None)
-0, --low screen at 0 instead of 0x8000 (default: False)
-v, --verbose verbose mode (default: False)
--version show program's version number and exit
--crop CROP crop region (WxH or WxH+X+Y) (default: None)
--scale SCALE scale region (S or HxV) (default: None)
--shift SHIFT pixels to shift right (default: None)
--share share even/odd save/restore code (default: False)
--timings show nominal code timings (default: False)
The -q, --quiet option in earlier versions is now the default behaviour. Use
the new -v, --verbose options to display conversion details.
Required Arguments
image
An image file containing the graphics data. Most image file formats are supported, but it's recommended you use an efficient lossless format such as PNG.
Image colours are mapped to the nearest SAM palette colour, without any dithering. Images with too many source colours may be rejected. Typically you'll want to author graphics directly using the original SAM palette colours:
Tiles are extracted starting from the top-left of the image. Use the --crop
and --scale options to limit the area of interest. Use --tiles to select the
tiles of interest, and the order they're extracted. The extracted graphics may
also be pre-shifted using --shift.
tilesize
Specifies the dimensions of the tiles to extract, in pixels. If a single value
N is given it's treated as having a size of NxN. If both dimensions are
specified they should be in the format WxH.
If the tile width does not result in an exact number of output bytes, the right edge is padded with background pixels. To be aligned to byte boundaries, mode 4 tile width should be a multiple of 2, mode 3 a multiple of 4, and modes 1 and 2 a multiple of 8.
Optional Arguments
-z, --code CODE
Specifies a comma-separated list of Z80 routines to generate for each sprite, instead of binary graphics data. The available routines are:
masked- draw to display with partial byte masking [label: masked_name]unmasked- draw to display without masking partial bytes [label: unmasked_name]save- save display area affected by drawn sprite [label: save_name]restore- restore previously saved area [label: restore_name]copy- remove drawn sprite by copying from alternate screen [label: copy_name]clear- clear display area affected by drawn sprite [label: clear_name]rect- clear routine for rectangle covering the sprite area [label: clear_rect_WBxH]
Notes
- Specifying
saveorrestoregenerates both routines. - A save_name_size symbol is defined to hold the save buffer size in bytes.
- 'copy' expects a screen source in the opposite 32K from the drawn display.
rectgenerates a label name using the width (in bytes) and height of the sprite. To avoid duplicate labels and code this should generally be given as the only routine, once per sprite size.- See my blog article for more details on code generation.
--names NAMES
Specifies a comma-separated list of names to use for sprite code labels. Missing
names are assigned spriteN, where N is the zero-based index of the sprite in
the image file.
--low
Convert coordinates to display addresses in low memory (based at address 0). The default generates addresses in high memory (based at address 0x8000).
-m MODE, --mode MODE
Selects the SAM screen mode (1 to 4) used for both output data format and colour selection. Modes 1 and 2 are produce the same 1-bit format, with only 2 colours. Mode 3 is a 2-bit mode with 4 colours. Mode 4 is a 4-bit mode with 16 colours.
The default screen mode is 4.
-c CLUT, --clut CLUT
Specifies either a comma-separated list of colours, or the name of a .pal file
containing the palette. Each colour should be in the range 0-127.
A complete palette is not required, but those specified will be assigned to the first CLUT slots. Any additional colours required by the image will be automatically assigned to later positions. The final CLUT size must be within the limit for the screen mode (sixteen colours for mode 4, four colours for mode 3, and two colours for modes 1 and 2).
If no CLUT is provided and the image colours are a subset of the BASIC mode 4 colours, they will be used instead. Otherwise a CLUT will be generated from the colours in the source image.
-o OUTPUT, --output OUTPUT
Specify a custom output file, which defaults to a .bin extension for data
output and .asm for code output. The same basename is also used for .pal and
.idx files if they are enabled.
The default behaviour uses the basename of the input image, so image.png will
generate image.dat.
With code generation, using an output file of - will write the code to stdout.
-p, --pal
Write the corresponding palette to a .pal file, which is a binary file
containing 1 byte per colour. The palette file may then be used as an input file
using the --clut option, or imported into source code using using MDAT.
The default behaviour displays the list of colours to the console but does not save it to a file.
-i, --index
Generate an index of data offsets to each output tile. Each entry is a 16-bit value in little-endian format. While the entries are simple multiples of the tile data size, multiple index files from different invocations may be combined to give a more useful look-up table.
The default behaviour is not to output an index.
-b, --bkgcol
Specifies a SAM palette colour to treat as the background of the source image. The background colour is treated as transparent, and is not added to the CLUT colours. All other colours are treated as opaque foreground colours.
If no background colour is specified but the source image contains a palette with alpha transparecy, any colours with zero alpha are treated as background. Otherwise palette colour 0 (black) is treated as transparent.
-t TILES, --tiles TILES
Selects the tiles to extract from the image. If a single value is given it's treated as a count of tiles to extract from the top-left of the image. You may also specify a comma-separated list of tile numbers, which can include ranges of tiles in an A-B (inclusive) notation. If the range start is greater than the end that portion is extracted in reverse order.
The default behaviour is to extract as many complete tiles from the image as possible.
-a, --append
Append to any existing output file, rather than creating a new file.
-v, --verbose
Show details about processing, which are hidden by default. Error messages are always shown.
--crop CROP
Crop the input image so tiles are only extracted from a specific portion of it. The crop region can be just a size in WxH format, or a size and a top-left coordinate in WxH+X+Y format. Cropping is performed before any scaling (see below).
The default behaviour is not to crop the input image.
--scale SCALE
Scale the input image before extraction, which is useful for pixel-doubled and mode 3 content. Scaling uses a nearest neighbour pixel matching, and is performed after any cropping (see above).
The default behaviour is not to scale the input image.
--shift SHIFT
Specifies the number of pixels to shift each tile to the right in the output data. This will add padding to the left of the data, and may also result in additional alignment padding to the right. All padding uses CLUT entry zero, which will usually be black.
This option can be used to create pre-shifted versions of graphics for optimised drawing routines. The default behaviour is not to shift content.
Using --shift 0 with code generation will suppress the code for odd x
positions. The default behaviour generates code for both even and odd positions.
--share
Used by code generation, causing the code generated by save/restore to cover both even and odd shift positions. This reduces the amount of code generated with only a small increase in execution time.
Note: If your sprite use a full even width the shifted odd position will spill into a new display byte. Restoring a drawn sprite at the extreme right edge of the display may overflow into the next screen row, or a byte beyond the end of the display file. Use with care!
--timings
Shows the nominal code timings in t-states for each type of code generation routine, to help compare different methods.
Examples
Extract all 16x16 tiles from sprites.png, write the graphics data to
sprites.bin and palette to sprites.pal:
tile2sam --pal sprites.png 16x16
Extract the first 100 6x6 tiles from tiles.png, using the colours from
sprites.pal:
tile2sam --clut sprites.pal --tiles 100 tiles.png 6x6
Extract a non-contiguous selection of 6x6 tiles from tiles.png:
tile2sam --tiles 10-19,99-90,42 tiles.png 6
Extract a 6x8 1-bit font from font.png, write the data to font.bin:
tile2sam --mode 2 font.png 6x8
Extract a 6x8 1-bit font from font.png, shifting the data 2 positions to
right-align it, then write to font_centre.bin:
tile2sam --mode 2 --shift 2 -o font_centre.bin font.png 6x8
Extract all 12x12 sprites from sprites.png, fixing only the first 4 CLUT
colours so the rest are automatically assigned:
tile2sam --clut 0,127,25,126 sprites.png 12
Extract a mode 4 screen from a 576x480 SimCoupe screenshot to mode4.bin and
mode4.pal:
tile2sam --crop 512x384+32+48 --scale 0.5 --pal mode4.png 256x192
Extract a mode 3 screen from a 576x480 SimCoupe screenshot to mode3.bin and
mode3.pal:
tile2sam --crop 512x384+32+48 --scale 1.0x0.5 --mode 3 --pal mode3.png 512x192
Extract a mode 2 screen from a 576x480 SimCoupe screenshot to mode2.bin:
tile2sam --crop 512x384+32+48 --scale 0.5x0.5 --mode 2 mode2.png 256x192
Generate code to draw masked 11x11 sprites from a mode 4 image:
tile2sam --code masked,save --names cherry,strawb,orange --pal sprites.png 11x11
Generate and append code to draw unmasked 11x11 tiles from a mode 4 image:
tile2sam -a --code unmasked,clear --names cherry,strawb,orange --pal sprites.png 11
Generate code to draw a masked 11x11 sprite only at even x positions:
tile2sam --code masked,save --names ghost --shift 0 --pal ghost.png 11x11
Generate code to draw a masked 11x11 sprite, restoring from clean screen copy:
tile2sam --code masked,copy --names ghost --pal ghost.png 11x11
Full example programs are available from the tile2sam GitHub repository, under the demos directory.
License
This project is licensed under the MIT License - see the LICENSE.md file for details
Author
Simon Owen
https://simonowen.com
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tile2sam-1.3.0.tar.gz.
File metadata
- Download URL: tile2sam-1.3.0.tar.gz
- Upload date:
- Size: 110.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ce171d7d5dff7ba287c3fc87bf6a0a80d2e7c421a522c161b350d7fd65d94898
|
|
| MD5 |
ed0cdbe17b7bc9546f9342fc134598cf
|
|
| BLAKE2b-256 |
2d86ea1bd85041a834b623f0259bf006c97164f9c2c8a4689eb6e0f3ef610aa2
|
File details
Details for the file tile2sam-1.3.0-py3-none-any.whl.
File metadata
- Download URL: tile2sam-1.3.0-py3-none-any.whl
- Upload date:
- Size: 16.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
67c5f92959c99fc1a349689db2def254b498a3db839b98638f8747a6f5d191ce
|
|
| MD5 |
2880ed54f179e278d1469855a2c4a56f
|
|
| BLAKE2b-256 |
6e9dee9f6dddc2b4f013a688042ad061e0251f68cda9679b7b6d32a5ed750225
|