Puregrain.Machine.C64
- Package
- purescript-puregrain
- Repository
- roman-mkh/puregrain
The Commodore 64's hires bitmap screen: 320 × 200 pixels in cells of
8 × 8, each cell with two of the machine's 16 colors, a foreground and
a background, chosen freely. With Puregrain.Cells, that gives
pictures the C64 could show:
import Puregrain.Cells (ditherCells, nearestInCell, orderedInCell)
import Puregrain.Machine.C64 as C64
-- ordered dithering inside the cells, with a threshold map m
{ cells, image } = ditherCells noDiffusion (orderedInCell m) C64.hiresScreen picture
-- error diffusion inside the cells
{ cells, image } = ditherCells atkinson nearestInCell C64.hiresScreen picture
cells holds each cell's HiresCell: its foreground and background,
as the machine's screen memory needs them; toHiresPrg turns the
whole result into a C64 program that shows it, and toArtStudio into
an Art Studio picture file. The colors are those of
Puregrain.Palette.Presets.c64. The C64's multicolor mode isn't
supported yet.
#HiresCell Source
newtype HiresCellOne hires cell's colors: the foreground, the color of the cell's 1
bits, and the background, the color of its 0 bits, as C64 color codes
(0 black, 1 white, 2 red, 3 cyan, 4 purple, 5 green, 6 blue, 7 yellow,
8 orange, 9 brown, 10 light red, 11 dark grey, 12 grey, 13 light
green, 14 light blue, 15 light grey). Only the 136 values in
hiresCells exist.
Instances
#foreground Source
foreground :: HiresCell -> IntThe foreground's color code, 0 to 15: the color of the cell's 1 bits.
#background Source
background :: HiresCell -> IntThe background's color code, 0 to 15: the color of the cell's 0 bits.
#hiresCells Source
hiresCells :: NonEmptyArray HiresCellEvery hires cell that looks different: the 16 single colors and the 120 pairs, 136 in all. In a pair, the foreground is the darker color and the background the lighter, as with the ZX Spectrum's black ink on white paper. Darker means a lower luma, 0.299 R + 0.587 G + 0.114 B, since the C64's color codes aren't in order of brightness. A single-color cell has foreground = background.
They're listed in the order Puregrain.Cells tries them, where the
earlier wins a tie: the single colors first, by code, then the pairs by
the distance between their two colors, nearest first (at equal
distances, by foreground, then by background). A cell that several
palettes fit equally well thus gets the narrowest, the calmest.
#hiresPalette Source
hiresPalette :: HiresCell -> CellPaletteThe cell's colors, for Puregrain.Cells: the foreground, then the
background, or the one color of a single-color cell. With
orderedInCell, the order means that a cell is foreground, with
background dots added as a pixel nears the background.
#hiresScreen Source
hiresScreen :: CellMode HiresCellThe C64's hires screen mode, for Puregrain.Cells: cells of 8 × 8
pixels, each using one of the hiresCells, tried in their order, with
hiresPalette's colors.
#toHiresPrg Source
toHiresPrg :: { cells :: Array (Array HiresCell), image :: Array (Array RGB) } -> Either String (Array Int)A dithered hires screen as a .prg file: a C64 program that shows the
picture by itself. Open it in an emulator, which starts it, or load
and run it on a C64 (LOAD "name",8 and RUN). The picture stays
until a key is pressed; then the screen is as it was.
{ cells, image }: whatPuregrain.Cells.ditherCellsreturns with this module'shiresScreen, for a 320 × 200 picture.
bytes = toHiresPrg (ditherCells noDiffusion (orderedInCell m) hiresScreen picture)
The file is 14,145 bytes: the address it loads at, 2049 ($0801), where BASIC programs start, and from there a short BASIC program, the viewer; the cells' colors at 3072 ($0C00), one byte per cell, row by row: foreground × 16 + background; and the bitmap at 8192 ($2000), one bit per pixel (1 for the foreground, 0 for the background, the leftmost pixel in the highest bit), each cell's 8 bytes in a row, the cells row by row. Zeros fill the gaps. A single-color cell has all its bits 0. The viewer points the video chip at the colors and the bitmap where they are, with a black border, and puts everything back after a key.
Left, with a message, for an image that isn't 320 × 200, for cells
that don't form the matching 40 × 25 grid, or for a pixel that isn't
one of its cell's colors: then the cells weren't chosen for this image.
#toArtStudio Source
toArtStudio :: { cells :: Array (Array HiresCell), image :: Array (Array RGB) } -> Either String (Array Int)A dithered hires screen as an Art Studio file, .art: the format of
the C64's best-known hires paint program, which many viewers and
converters open.
{ cells, image }: whatPuregrain.Cells.ditherCellsreturns with this module'shiresScreen, for a 320 × 200 picture.
bytes = toArtStudio (ditherCells noDiffusion (orderedInCell m) hiresScreen picture)
The file is 9009 bytes: the address it loads at, 8192 ($2000); the
bitmap, 8000 bytes; the cells' colors, 1000 bytes, both as in
toHiresPrg; and 7 filler bytes, zeros, as long as Art Studio's own
files.
Left, with a message, as for toHiresPrg.
- Modules
- Puregrain
- Puregrain.
Cells - Puregrain.
Dither - Puregrain.
Internal. Fifo - Puregrain.
Internal. Image - Puregrain.
Internal. Kernel - Puregrain.
Internal. Row - Puregrain.
Internal. State - Puregrain.
Internal. Step - Puregrain.
Internal. Util - Puregrain.
Kernel - Puregrain.
Machine. C64 - Puregrain.
Machine. ZxSpectrum - Puregrain.
Ordered - Puregrain.
Palette - Puregrain.
Palette. Presets - Puregrain.
Pixel - Puregrain.
Quantize