Skip to main content

Overview

DevCPC includes powerful graphics conversion tools that automatically convert modern PNG images into Amstrad CPC formats. The tools handle palette conversion, format encoding, and optimization.

Components

png2asm.py

Converts PNG images to ASM sprite data:
  • Input: PNG images (any size)
  • Output: Z80 assembly sprite data
  • Features: Automatic palette detection, mode validation, label generation

img.py (ABASM)

Converts PNG to SCN screen files:
  • Input: PNG images (160×200, 320×200, or 640×200)
  • Output: 16KB SCN screen files
  • Features: Full-screen conversion with palette info

Pillow (PIL)

Python Imaging Library for image processing:
pip3 install Pillow

Sprite Conversion

Configuration

Enable sprite conversion in devcpc.conf:
devcpc.conf
# Sprite conversion settings
SPRITES_PATH="assets/sprites"
SPRITES_OUT_FILE="ASM/sprites.asm"
MODE=0
SPRITES_TOLERANCE=8
SPRITES_TRANSPARENT_INK=""

Directory Structure

my-game/
├── assets/
│   └── sprites/
│       ├── player.png      # 16×16 sprite
│       ├── enemies/
│       │   ├── enemy1.png
│       │   └── enemy2.png
│       └── tiles/
│           ├── tile1.png
│           └── tile2.png
└── ASM/
    └── sprites.asm         # Generated

PNG Requirements

  • Resolution: 160×200 max
  • Sprite width: Multiple of 2 pixels
  • Colors: Up to 16 colors from CPC palette
  • Encoding: 2 pixels per byte (4 bits each)

CPC Palette

The converter maps RGB colors to the 27-color CPC palette:
INKRGBName
0(0,0,0)Black
1(0,0,128)Blue
2(0,0,255)Bright Blue
6(255,0,0)Red
24(255,255,0)Yellow
26(255,255,255)White
See full palette

Tolerance

The SPRITES_TOLERANCE setting controls color matching:
# Exact match only (RGB must match exactly)
SPRITES_TOLERANCE=0

# Recommended (allows small variations)
SPRITES_TOLERANCE=8

# Always find closest color
SPRITES_TOLERANCE=-1

Generated ASM Format

ASM/sprites.asm
; MODE 0
; Generated by png2asm.py

PLAYER
;------ BEGIN IMAGE --------
  db 2      ; width in bytes
  db 16     ; height in pixels
  db 0, 0
  db 85, 85
  db 170, 170
  ; ... sprite data
;------ END IMAGE --------
  ; Palette detected:
  ; INK 0,0   (Black)
  ; INK 1,24  (Yellow)
  ; INK 2,6   (Red)

ENEMY1
;------ BEGIN IMAGE --------
  db 2
  db 16
  ; ... sprite data
;------ END IMAGE --------

Using Sprites in Code

include "sprites.asm"

; Draw player sprite
ld hl, PLAYER
call |PSPRITE

; Draw enemy sprite
ld hl, ENEMY1
call |PSPRITE

Screen Conversion

Configuration

Enable screen conversion in devcpc.conf:
devcpc.conf
# Screen conversion settings
LOADER_SCREEN="assets/screen"
MODE=0

Directory Structure

my-game/
├── assets/
│   └── screen/
│       ├── title.png       # 160×200 Mode 0
│       └── loading.png     # 160×200 Mode 0
├── obj/
│   ├── title.scn           # Generated
│   ├── title.scn.info      # Palette info
│   ├── loading.scn
│   └── loading.scn.info
└── dist/
    └── my-game.dsk         # SCN files included

PNG Requirements

Screen PNGs must be exact dimensions:
  • Mode 0: 160×200 pixels (16 colors)
  • Mode 1: 320×200 pixels (4 colors)
  • Mode 2: 640×200 pixels (2 colors)

Generated Files

SCN File

title.scn       # 16384 bytes (16 KB)
                # Direct screen memory dump
                # Load to &C000

Info File

title.scn.info  # Palette information
Example info contents:
FILE: title.scn
WIDTH: 160
HEIGHT: 200
MODE: 0
PALETTE COLORS: 8

FW              HW              RGB
0               0x14            (0, 0, 0)
24              0x0A            (255, 255, 0)
6               0x04            (255, 0, 0)

; ASM HW palette
db 0x14, 0x0A, 0x04

' BASIC palette
INK 0,0: INK 1,24: INK 2,6

Loading Screens

From BASIC:
10 MODE 0
20 LOAD"TITLE.SCN",&C000
30 INK 0,0: INK 1,24: INK 2,6
40 PAUSE 100
From ASM:
; Load screen from binary
ld hl, title_scn
ld de, &C000
ld bc, 16384
ldir

; Set palette (from .info file)
ld bc, &7F00
ld a, 0
out (c), a
ld bc, &7F01
ld a, &14    ; INK 0 = Black
out (c), a
; ... continue for all inks

title_scn:
incbin "title.scn"

Manual Conversion

Run converters manually:

Sprites

python3 ~/.DevCPC/tools/8bp-graphics-converter/png2asm.py \
    --mode 0 \
    --tolerance 8 \
    --input assets/sprites \
    --output ASM/sprites.asm

Screens

python3 ~/.DevCPC/tools/abasm/src/img.py \
    --input assets/screen/title.png \
    --output obj/title.scn \
    --mode 0

Creating Graphics

GIMP Workflow

1

Create image

  • File → New
  • Set dimensions (e.g., 160×200 for Mode 0)
  • Image → Mode → RGB color
2

Use CPC palette

Import CPC palette:
  • Windows → Dockable Dialogs → Palettes
  • Import CPC.gpl palette file
  • Use Colors from palette only
3

Draw graphics

  • Use Pencil tool (hard edges)
  • Zoom in for pixel-perfect editing
  • Use only colors from CPC palette
4

Export

  • File → Export As
  • Choose PNG format
  • Save to assets/sprites/ or assets/screen/

Aseprite Workflow

For sprite animation:
  1. Create sprite at correct size (e.g., 16×16)
  2. Set palette to CPC colors
  3. Draw frames
  4. Export each frame as separate PNG
  5. Place in assets/sprites/ directory

Troubleshooting

pip3 install Pillow
python3 -c "import PIL; print('Pillow OK')"
Sprite width must be:
  • Mode 0: multiple of 2 (2, 4, 6, 8, 10, 12, 14, 16…)
  • Mode 1: multiple of 4 (4, 8, 12, 16, 20…)
  • Mode 2: multiple of 8 (8, 16, 24, 32…)
Resize your PNG to match requirements.
Increase tolerance:
SPRITES_TOLERANCE=16
Or use automatic:
SPRITES_TOLERANCE=-1
Reduce colors in your image:
  • Mode 0: max 16 colors
  • Mode 1: max 4 colors
  • Mode 2: max 2 colors
Use GIMP or Aseprite to reduce palette.

Resources

Graphics Guide

Complete graphics conversion guide

Loading Screens Recipe

Create and load screen graphics

Sprite Animation Recipe

Animate sprites in your games

Configuration

Graphics configuration reference

Credits

Build docs developers (and LLMs) love