Working Python version for Commodore.
This commit is contained in:
commit
2a48f52979
51 changed files with 3095 additions and 0 deletions
125
README.md
Normal file
125
README.md
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
# c64view
|
||||
|
||||
Convert a modern image (PNG/JPG/GIF/BMP/WEBP) into a **Commodore 64 disk image**
|
||||
(`.d64` / `.d71` / `.d81`) containing a self-contained viewer that displays the
|
||||
picture on a real C64 or in an emulator. The converter works hard to preserve
|
||||
quality within the VIC-II's tight colour and resolution limits.
|
||||
|
||||

|
||||
|
||||
## Highlights
|
||||
|
||||
- **Five display modes** (auto-selectable):
|
||||
- **Hires** — 320×200, 2 colours per 8×8 cell. Best for sharp line art.
|
||||
- **Multicolor** — 160×200, 1 shared background + 3 colours per 4×8 cell
|
||||
(the classic "Koala" format). Best general-purpose photo mode.
|
||||
- **FLI** — re-points the video matrix every scanline for per-line (4×1) colour.
|
||||
- **Interlace** — two multicolor frames blended at 50 Hz for ~136 apparent colours.
|
||||
- **Mono** — highest-resolution path: 320×200 matched by *luminance* to a colour
|
||||
ramp, so detail is carried by intense dithering. Greyscale by default, or pick
|
||||
any palette colour as the base for a tinted monochrome (black → blue → light
|
||||
blue → white, etc.).
|
||||
- **Perceptual conversion.** All colour decisions are made in CIELAB. Each screen
|
||||
cell's colour set is chosen by an exhaustive, vectorised search that minimises
|
||||
reproduction error; an *Intensive* mode additionally searches the global
|
||||
background colour.
|
||||
- **Selectable dithering** — ordered Bayer (default, artifact-free), Floyd–Steinberg,
|
||||
Atkinson, and the larger Stucki / Jarvis error-diffusion kernels (smoothest
|
||||
gradients, ideal for mono), or none — all constrained so a cell never shows a
|
||||
colour it can't.
|
||||
- **Explore variations.** One click renders every Mode × Palette × Dither
|
||||
combination as a contact sheet (parallelised across CPU cores); pick the best,
|
||||
then fine-tune brightness/contrast/saturation/gamma on that choice.
|
||||
- **PAL / NTSC.** Choose the target video standard. Static and interlace viewers
|
||||
work on both (interlace flips per frame, so it flickers at the standard's field
|
||||
rate automatically); FLI ships a separately-timed viewer for each.
|
||||
- **Run in VICE.** One click builds the disk and launches it in VICE in the chosen
|
||||
standard (warp mode, except interlace which needs real-time for its flicker): it
|
||||
lists the directory, then `LOAD"*",8,1` + `RUN` to show the picture.
|
||||
- **On-disk info program.** When there's room, a colourful BASIC program is added
|
||||
that prints the original name, dimensions, format, colour depth, oldest EXIF date,
|
||||
file date, EXIF comment, when the C64 version was made, the host platform, and the
|
||||
Linux distribution/version.
|
||||
- **Self-contained viewers.** Each disk's first program embeds the picture and loads
|
||||
in a single pass, so `LOAD"*",8,1` then `RUN` just works — no second disk access,
|
||||
no emulator-config surprises.
|
||||
- **Standard interchange files.** Multicolor exports also drop a `PICTURE.KOA`
|
||||
(Koala) and hires a `PICTURE.ART` (OCP Art Studio) file for use in other C64 tools.
|
||||
- **GUI and CLI.**
|
||||
|
||||
## Requirements
|
||||
|
||||
- Python 3.9+, with `numpy` and `Pillow`.
|
||||
- `PyQt5` (GUI only).
|
||||
- [`xa`](https://www.floodgap.com/retrotech/xa/) (xa65) — assembles the 6502 viewers.
|
||||
- [VICE](https://vice-emu.sourceforge.io/)'s `c1541` — builds the disk images.
|
||||
|
||||
On Debian/Ubuntu:
|
||||
|
||||
```sh
|
||||
sudo apt install python3-numpy python3-pil python3-pyqt5 xa65 vice
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### GUI
|
||||
|
||||
```sh
|
||||
python -m c64view.gui # or: c64view
|
||||
```
|
||||
|
||||
Open an image, pick a mode / disk format / dithering, watch the live C64 preview,
|
||||
then **Export**.
|
||||
|
||||
### Command line
|
||||
|
||||
```sh
|
||||
# Multicolor picture onto a .d64, plus a preview PNG of how it will look:
|
||||
python -m c64view.cli photo.jpg -m multicolor -o photo.d64 --preview photo.png
|
||||
|
||||
# Let the tool pick the best standard mode, write a .d81:
|
||||
python -m c64view.cli photo.jpg -m auto -o photo.d81
|
||||
|
||||
# Best quality (slower) FLI with error-diffusion dithering:
|
||||
python -m c64view.cli photo.jpg -m fli -d floyd --intensive -o photo.d64
|
||||
|
||||
# High-res greyscale with smooth Stucki dithering:
|
||||
python -m c64view.cli photo.jpg -m mono -d stucki -o photo.d64
|
||||
# ...or tinted monochrome in blue:
|
||||
python -m c64view.cli photo.jpg -m mono --mono-base blue -d jarvis -o photo.d64
|
||||
```
|
||||
|
||||
Options: `-m/--mode {auto,hires,multicolor,fli,interlace,mono}`,
|
||||
`-f/--format {d64,d71,d81}`, `-p/--palette {colodore,pepto}`,
|
||||
`-d/--dither {bayer,floyd,atkinson,stucki,jarvis,none}`,
|
||||
`--mono-base {grayscale,<colour name>}`, `--video {pal,ntsc}`,
|
||||
`-a/--aspect {fit,fill,stretch}`, `--intensive`,
|
||||
`--brightness/--contrast/--saturation/--gamma`, `--preview`.
|
||||
|
||||
### On the C64 / in an emulator
|
||||
|
||||
Attach the disk to drive 8 and:
|
||||
|
||||
```
|
||||
LOAD"*",8,1
|
||||
RUN
|
||||
```
|
||||
|
||||
Press any key to return to BASIC (hires/multicolor). For FLI/interlace, reset to exit.
|
||||
|
||||
## Notes on the advanced modes
|
||||
|
||||
- **FLI** is timing-critical: the viewer runs a cycle-stable raster loop. Expect a
|
||||
small settling artifact in the top rows (a well-known FLI characteristic) and the
|
||||
leftmost few pixels reserved by the hardware "FLI bug".
|
||||
- **Interlace** flickers at 25 Hz on a CRT; it looks best in an emulator or on an LCD.
|
||||
- Multicolor and Hires are the universally safe, flicker-free choices.
|
||||
|
||||
## How conversion works
|
||||
|
||||
`c64view/convert/` holds one encoder per mode on top of a shared core
|
||||
(`convert/base.py` + `dither.py`). The pipeline: prepare & resize the image to the
|
||||
mode's pixel grid (`imageprep.py`), convert to CIELAB (`palette.py`), choose each
|
||||
cell's legal colour set by exhaustive search, dither within those sets, then pack the
|
||||
VIC-II bytes. `viewer/*.s` are the 6502 viewers (assembled by `xa`), combined with the
|
||||
picture data and written to a disk image by `diskimage.py` / `exporter.py`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue