ALBERT
======

Welcome to ALBERT, the pixel art editor for creating extended Commodore 64 images. In case you were wondering, ALBERT was named after Albert Charpentier, one of the VIC-II designers. However, ALBERT is also an acronym that stands for "Advanced Lightweight Bitmap Extender with Raster Tech".

ALBERT provides pixel artists with a single editor to create artwork that can only be displayed with the support of native code for the Commodore 64, without requiring the assistance of an assembly coder.
Users can create hires and multicolor images that extend into the left and right borders of the visible screen, using sprites to display the extra pixels.
Individual sprite colors can be set on a per-sprite basis with just two exceptions, due to the so-called "bad lines". In fact, there are no demo-style nearly-whole-RAM-consuming tricks at play here.

The technical details in a nutshell:

	- 2 whole columns of sprites in each side-border, for a total of 96 extra pixels (48 fat pixels) that get the total image width to 416 pixels (208 fat pixels),
	- for hires mode the above figures have to be reduced by 8 pixels (see "Hires mode caveats" below)
	- no glitches and no bugs in any of the sprites all the way to the external edges (try "Debug borders" in VICE's Commodore 64 emulator),
	- stable code for PAL, NTSC, and Drean machines.


Hires mode caveats
==================

In hires mode, due to the method used to avoid the color associated with the high nybble of the last character in a screen row from bleeding into the background, the last column of the screen area is not in use and sprites are positioned over it so that users can set pixels there.
Furthermore, due to the way the VIC-II hardware works, in hires mode black bleeds into the right border on raster line $32 and into the left border on raster line $33. For this reason, side borders are opened starting from raster line $33 instead of $32, the latter being what happens for multicolor mode. This lets users choose any border color that's not just black, but results in the first rasterline in the left border being hidden on a Commodore 64 and therefore not editable in ALBERT.


Projects
========

Designs can be saved to project files for later modification. In fact, the application ships with a few example projects under the "sample-projects" folder.
A project contains all workstages, unless these were explicitly flattened by the user using the "Edit -> Clear History" menu item.


Saving Workstages
=================

Workstages, also referred to as checkpoints in the history of changes, can be saved to PNG images. These can then be used to produce a timelapse and illustrate all production stages of the creative process behind a project.
Workstages can be collated into a timelapse video using off-the-shelf utilities, such as "ffmpeg". As an example, the following command creates a video consisting of all workstages in the current folder at a frame rate of 25 fps and using the x264 library:

	ffmpeg -i %08d.png -r 25 -vcodec libx264 timelapse.mp4

Joachim Ljunggren has published a playlist of timelapses for his own artwork here: https://www.youtube.com/playlist?list=PLBs-cTl5xpX2Mlai26mo1Zuz52lZzlweh


Importing Native Images
=======================

ALBERT can import native Commodore 64 images encoded using one of the supported formats. This is useful if work on an image was started with a different pixel art editor and users wish to use ALBERT to complete and extend it.

In hires mode, the following formats are supported:

	- Art Studio 1.x (by OCP)
	- Doodle (by OMNI)
	- Image System
	- Interpaint Hires

In multicolor mode, the following formats are supported:

	- Advanced Art Studio 2.0 (by OCP)
	- Blazing Paddles
	- Koala Painter 2 (by Audio Light)
	- Vidcom 64 (by Omega)
	- Wigmore Artist 64 (by Wigmore)


Importing Native Sprites
========================

ALBERT can import native Commodore 64 sprites from flat PRG or PMAP files. PMAP files are saved by Pixcen and have the same internal structure as PRG files'.


Importing Reference Images
==========================

ALBERT can import transparent 24/32-Bit PNG images into a separate layer to be used as a drawing reference. Currently PNG images must have a width of 416 (320 in non-extended mode) pixels and a height of 200 pixels. Some of these restrictions will be lifted in future versions.


Converting PNG Images
=====================

Currently ALBERT can convert non-native images as long as they are 24/32-Bit PNG images with a width of 416 (320 in non-extended mode) pixels and a height of 200 pixels. Some of these restrictions will be lifted in future versions.
Multiple palette conversion methods are available: nearest match, error diffusion (Floyd-Steinberg) dithering, and ordered (Bayer) dithering. Each of them references the Commodore 64 palette currently active: different palettes will produce different results at conversion time.
Furthermore, whereas the natural (Euclidean) distance is found to be unsuitable for color matching, a weighted alternative is available. The latter should produce results in line with expectations based on the luminance values of Commodore 64 palette colors.
Finally, a "curves adjustment" widget is provided in order to adjust each color channel separately and/or all of them at the same time.


Exporting to Executable PRG
===========================

The current contents of the drawing canvas can be exported to executable PRG files, which include the necessary support code for PAL, NTSC, and Drean machines.
Executable PRG files are compressed using Exomizer, whose binaries are included in the distribution archive of this application in order to ensure a seamless and consistent experience for end-users across a variety of supported operating systems.


Exporting to Ultimate device
============================

Executable PRG files can be uploaded to and run by an Ultimate device, leveraging its REST API, provided by firmware 3.11 or later. In order to do so, ALBERT has to be configured with the remote IP address or hostname of the Ultimate device to integrate with.
On macOS, applications that need to communicate with other devices on the network require explicit permission. When you export to an Ultimate device for the first time, macOS may display a prompt asking whether to allow ALBERT to access the network for discovery purposes. Please select "Allow" to enable these features. If you need to adjust this setting later, go to "System Settings -> Privacy & Security -> Local Network" and ensure that ALBERT is enabled in the list of applications with local network access.


Exporting to PNG
================

The current contents of the drawing canvas can be exported to PNG images, handy for being used as screenshots e.g. when uploading a release to CSDb.


Exporting to Native Images
==========================

In non-extended mode, the current contents of the drawing canvas can be exported to native formats: Koala Painter 2 for multicolor artwork and Art Studio 1.x for hires artwork.


Aspect Ratio
============

ALBERT can display graphics according to the aspect ratio of pixels on PAL or NTSC displays. This is not limited to the preview window as it applies to the drawing canvas too.


Selections
==========

ALBERT supports the definition of rectangular selections that can be either dragged, cut, or copied to the program's internal clipboard. If users hold the Alt key upon starting to drag a selection, then the selection is treated as transparent, otherwise it is treated as solid.
Likewise, users can paste the contents of the clipboard as a solid or transparent floating object. Whether users are dragging a selection or working with a floating object they will be able to appreciate the result in real-time, including color clashes.


Symmetry Draw
=============

ALBERT offers users the ability to draw symmetric scenes according to different patterns:

	- horizontal symmetry: anything users draw in the top half of the drawing canvas is mirrored in real-time in the bottom half, and the other way around
	- vertical symmetry: anything users draw in the left half of the drawing canvas is mirrored in real-time in the right half, and the other way around
	- quadrant symmetry: the drawing canvas is split into four partitions and anything users draw in one partition is mirrored in real-time in all other partitions
	- bisected-quadrant symmetry: same as quadrant symmetry but each quadrant is further split into two partitions diagonally, with the splitting diagonal serving as an additional symmetry line
	- kaleidoscope symmetry: replicates anything users draw across eight axes of symmetry

Note that symmetry drawing applies to the pen, eraser, and fill tools only.


Pareidolia
==========

ALBERT allows users to look for inspiration in randomness, leveraging what is known as pareidolia, i.e. the tendency humans have to perceive a meaningful image in random or ambiguous visual patterns.
In practice, this means that through the "Pareidolia" menu item ALBERT draws 50 random shapes, including: lines, hollow rectangles, hollow and solid circles and ellipses. Internally Albert uses Lua to achieve the desired outcome, so the note about Lua function aggressivity applies to the output of this feature verbatim.


CRT Emulation
=============

ALBERT allows users to enable a CRT emulation filter in its preview window, to replicate the visual characteristics of vintage CRT monitors, enhancing the nostalgia of retro aesthetics.

The filter:
	- introduces subtle chromatic aberration, mimicking the misalignment of RGB color channels found in older displays, 
	- adds a slight blur to replicate the softer focus of CRT screens,
	- adds scanline artifacts, and
	- enables a bilinear filter for image scaling

These elements come together to provide an authentic recreation of classic display imperfections while adding a unique charm to the rendered visuals of the preview window.


Keyboard Keys
=============

The available key shortcuts, which are not already menu item accelerators, are detailed below:

	Keys 1-8 (optionally with a Shift key pressed for some keyboard layouts): set color for the pen associated to the left mouse button
	Keys , and .: decrease and increase brush size for freehand drawing
	Keys [ and ]: decrease and increase brush size for freehand drawing
	Key b: activates the pen tool
	Key e: activates the erase tool
	Key g: activates the flood fill tool
	Key space: activates the pan tool, until released; left click and drag the canvas around to move it while active
	Key r: activates the rotation tool, until released; left click and drag the canvas around to rotate it while active
	Key Alt (left): temporarily activates the color picker tool if it makes sense based on the currently active tool (pen, erase, fill, pan)
	Key Shift (left or right): enables multiline mode if the pen tool is active or snaps the rotation angle by the nearest multiple of 15 degrees if the rotation tool is active (r key)
	Key z: when reference grids are active, press it to switch their color between two different shades of grey and improve cell grid visibility
	Key Shift (left or right) + z: when reference grids are active, press both to toggle the pixel grid on and off
	Key Delete: deletes the currently selected region, if one is active
	Key Escape: disables the current selection, if one is active
	Cursor Keys: translate the canvas
	Key Tab: toggle the CRT emulation filter for the preview window


Lua Functions
=============

A number of Lua functions are provided for programmatic drawing. Here's a comprehensive list:

	drawclear (): clears the canvas using the current background color
	drawfill (pos_x, pos_y, color): flood fills starting at the given coordinates
	drawbrush (pos_x, pos_y, color): draws a brush at the given coordinates
	drawline (from_x, from_y, to_x, to_y, color): draws a line with width 1 connecting the given coordinates
	drawrect (pos_x, pos_y, width, height, color): draws a hollow rectangle with line width 1, upper left corner at the given coordinates, and the given extents
	drawrectf (pos_x, pos_y, width, height, color): draws a filled rectangle with upper left corner at the given coordinates and the given extents
	drawcircle (center_x, center_y, radius, color): draws a hollow circle with line width 1, the given radius, and centered at the given coordinates
	drawcirclef (center_x, center_y, radius, color): draws a filled circle with the given radius and centered at the given coordinates
	drawellipse (center_x, center_y, radius_x, radius_y, color): draws a hollow ellipse with line width 1, given radiuses, and centered at the given coordinates
	drawellipsef (center_x, center_y, radius_x, radius_y, color): draws a filled circle with given radiuses centered at the given coordinates
	drawstar (top_left_x, top_left_y, width, color): draws a hollow star
	brushsize (size): sets brush size; valid values are 1 through 24
	checkpointon (): enables the creation of checkpoints in the history of changes after a drawing operation, if it modifies the contents of the canvas
	checkpointoff (): disables the creation of checkpoints in the history of changes after a drawing operation
	checkpointsave (): creates a checkpoint in the history of changes, which is useful to compound multile drawing operations in a single checkpoint while checkpointing is globally disabled
	exportpng (full_path[, include_borders=true]): saves the contents of the canvas to a PNG image, optionally excluding borders for non-extended modes
	invalidateon (): enables the automatic refresh of the canvas display after a drawing operation, if it modifies the contents of the canvas
	invalidateoff (): disables the automatic refresh of the canvas display after a drawing operation
	drawrefresh (): causes a refresh of the canvas display
	bgcolor (color): replaces the background color
	bordercolor (color): replaces the border color in non-extended multicolor mode and all hires modes
	mcspritecolors (color_1, color_2): replaces common multi-color sprite colors in multicolor mode

Educational Lua scripts for ALBERT are published on GitHub: https://github.com/luigidifraia/lua-scripts-for-albert

Note that Lua drawing functions are not aggressive: in case of color clashes and sprite color limitations, and especially with filled shapes whose construction leverages their symmetry, the resulting drawing might be incomplete. In such circumstances, drawing the same shape twice can be used as a mitigation.
Furthermore, Lua drawing functions, with the exception of drawfill, are not mirrored when a symmetry drawing mode is active. This is the intended behaviour.
Finally, the properties of the fontset used in the scripting window can be configured within the "Preferences" dialog.


Known Issues
============

Under macOS:

	- The radio menu items do not update based on the currently active item.

Unfortunately there is no obvious workaround for this issue.


Future Plans / Unfinished Features
==================================

The following items are almost entirely based on our availability of free time:

	- Additional extended modes: mixed mode sprites, expanded sprites, overlapping sprites, etc.
	- Additional key shortcuts
	- Additional brush shapes and outlines
	- Further handling of selections: clip drawing operations to the current selection, complex selections
	- Handling of OS clipboard contents
	- Bespoke canvas size upon creating a new project
	- A version based on GTK 3 is not entirely out of question as I've been careful to minimize migration efforts required to upgrade
	- A version based on Qt would probably make sense
	- Multiple image editing mode


Reporting Issues
================

Until I get a chance to set up an issue tracker, you can use my contact form for reporting issues with ALBERT: https://www.luigidifraia.com/contact/
Remember that if an issue can't be repeated at will by the individual who reports it, then it might be quite hard for me to find its root cause and fix it.


Credits
=======

ALBERT and the supporting Commodore 64 "stable" code were written by Luigi Di Fraia a.k.a. TCE.
UI design, UX, and help testing was provided by Joachim Ljunggren a.k.a The Sarge.
Help, suggestions, and ideas for the Commodore 64 code were contributed by Flavioweb.
Exomizer was written by Zagon. For additional information visit: https://csdb.dk/release/?id=238365