Documentation improvements
This commit is contained in:
@@ -83,7 +83,7 @@ Run the command `cmake .` to generate the makefiles for the project and `make` t
|
||||
The `vga_config.h` contains the PicoVGA library settings, such as the size of the render buffers. You usually do not need to pay attention to this file. You usually only have to modify it in the following cases:
|
||||
|
||||
* When you use a display resolution greater than 640x480 pixels. Typically, the configuration file sets the maximum resolution to 640x480. This must be adjusted at higher resolutions to allow the library to reserve larger buffers for rendering functions.
|
||||
* If there is not enough RAM. There is still some headroom where you can save some memory. First, you can reduce the MAXX, MAXY, and MAXLINE resolution settings down to a real values. Next, you can reduce the number of LAYERS down to the actual value used (in the range of 1 to 4). Finally, you can reduce the number of segments and stripes to the actual value SEGMAX and STRIPMAX (minimum is 1).
|
||||
* If there is not enough RAM. There is still some headroom where you can save some memory. First, you can reduce the `MAXX`, `MAXY`, and `MAXLINE` resolution settings down to a real values. Next, you can reduce the number of LAYERS down to the actual value used (in the range of 1 to 4). Finally, you can reduce the number of segments and stripes to the actual value `SEGMAX` and `STRIPMAX` (minimum is 1).
|
||||
* The third case is to use of a large number of display stripes and segments. Normally, the values here are set to 8 stripes (=horizontal strips) and 8 segments (=vertical division of each strip).
|
||||
|
||||
If you have an older monitor that requires VGA VSync, uncomment the line the `CMakeLists.txt` file that sets the vsync pin:
|
||||
|
||||
@@ -6,24 +6,24 @@ The generated arrays provide graphics and audio data in formats tailored for the
|
||||
|
||||
All tools are lightweight console applications that should compile for all platforms. Building the library will build these applications into the `tools` folder.
|
||||
|
||||
* [picovga_img](#picovga_img--image-conversion-tool) – Image Conversion Tool
|
||||
* [picovga_rle](#picovga_rle--rle-compression-tool) – RLE Compression Tool
|
||||
* [picovga_snd](#picovga_snd--sound-import-tool) – Sound Import Tool
|
||||
* [picvovga_pal332](#picvovga_pal332--picovga-8-bit-palette-generator) – PicoVGA 8-bit Palette Generator
|
||||
* [palettes](#palettes-1) - A collection of `.act` palette files for use in image editors.
|
||||
* [picovga_img](#picovga_img) – Image Conversion Tool
|
||||
* [picovga_rle](#picovga_rle) – RLE Compression Tool
|
||||
* [picovga_snd](#picovga_snd) – Sound Import Tool
|
||||
* [picvovga_pal332](#picvovga_pal332) – 8-bit Palette Generator
|
||||
* [palettes](#palettes) - A collection of `.act` palette files for use in image editors.
|
||||
|
||||
## picovga_img – Image Conversion Tool
|
||||
## Image Conversion Tool {#picovga_img}
|
||||
|
||||
**picovga_img** is a command-line utility that converts Windows BMP images into C array data for use with the PicoVGA library on the Raspberry Pi Pico. It ensures that images are properly formatted and optimized for 8-bit, 4-bit, 2-bit, or 1-bit palette graphics.
|
||||
`picovga_img` is a command-line utility that converts Windows BMP images into C array data for use with the PicoVGA library on the Raspberry Pi Pico. It ensures that images are properly formatted and optimized for 8-bit, 4-bit, 2-bit, or 1-bit palette graphics.
|
||||
|
||||
### Usage
|
||||
```bash
|
||||
picovga_img input.bmp output.cpp arrayname
|
||||
```
|
||||
|
||||
- **input.bmp** – Source image file (must be a Windows BMP format).
|
||||
- **output.cpp** – Destination C++ file containing the image data.
|
||||
- **arrayname** – Name of the C++ array that will hold the image data.
|
||||
- `input.bmp` – Source image file (must be a Windows BMP format).
|
||||
- `output.cpp` – Destination C++ file containing the image data.
|
||||
- `arrayname` – Name of the C++ array that will hold the image data.
|
||||
|
||||
The tool reads the BMP image, validates its format, and writes the pixel data into a `const u8[]` array that can be directly included in PicoVGA projects.
|
||||
|
||||
@@ -67,19 +67,19 @@ const u8 myimage[8192] __attribute__ ((aligned(4))) = {
|
||||
|
||||
This array can be included in your PicoVGA project and drawn directly to the screen.
|
||||
|
||||
## picovga_rle – RLE Compression Tool
|
||||
## RLE Compression Tool {#picovga_rle}
|
||||
|
||||
**picovga_rle** is a command-line utility that compresses 8-bit PicoVGA images into a run-length encoded (RLE) format suitable for use with the PicoVGA library on the Raspberry Pi Pico. The compression significantly reduces image size while maintaining compatibility with the RLE PIO routines in PicoVGA.
|
||||
`picovga_rle` is a command-line utility that compresses 8-bit PicoVGA images into a run-length encoded (RLE) format suitable for use with the PicoVGA library on the Raspberry Pi Pico. The compression significantly reduces image size while maintaining compatibility with the RLE PIO routines in PicoVGA.
|
||||
|
||||
### Usage
|
||||
```bash
|
||||
picovga_rle input.bmp output.c arrayname transparent_color
|
||||
```
|
||||
|
||||
- **input.bmp** – Source image file (must be an 8-bit BMP using the PicoVGA palette `pal332.act`).
|
||||
- **output.cpp** – Destination C++ file containing the compressed image data.
|
||||
- **arrayname** – Name of the generated C array.
|
||||
- **transparent_color** – Index of the color to be used as transparency (0–255). Use `-1` for no transparency.
|
||||
- `input.bmp` – Source image file (must be an 8-bit BMP using the PicoVGA palette `pal332.act`).
|
||||
- `output.cpp` – Destination C++ file containing the compressed image data.
|
||||
- `arrayname` – Name of the generated C array.
|
||||
- `transparent_color` – Index of the color to be used as transparency (0–255). Use `-1` for no transparency.
|
||||
|
||||
The tool reads the BMP image, compresses it using RLE, and outputs a set of C arrays containing both pixel data and row offsets.
|
||||
|
||||
@@ -140,18 +140,18 @@ Each scanline is terminated with an `idle` command and aligned to 32-bit boundar
|
||||
### Compatibility Warning
|
||||
The compressed output is tightly coupled with the **RLE PIO program** in PicoVGA. Since the instruction format may change between library versions, **always use picovga_rle from the same release as your PicoVGA library** to avoid incompatibility issues.
|
||||
|
||||
## picovga_snd – Sound Import Tool
|
||||
## Sound Import Tool {#picovga_snd}
|
||||
|
||||
**picovga_snd** is a command-line utility that converts WAV audio files into C array data for playback with the PicoVGA library on the Raspberry Pi Pico. It ensures that sound effects or music are properly formatted for the Pico’s audio playback routines.
|
||||
`picovga_snd` is a command-line utility that converts WAV audio files into C array data for playback with the PicoVGA library on the Raspberry Pi Pico. It ensures that sound effects or music are properly formatted for the Pico’s audio playback routines.
|
||||
|
||||
### Usage
|
||||
```bash
|
||||
picovga_snd input.wav output.cpp arrayname
|
||||
```
|
||||
|
||||
- **input.wav** – Source WAV file.
|
||||
- **output.cpp** – Destination C++ file containing the audio data array.
|
||||
- **arrayname** – Name of the generated C array.
|
||||
- `input.wav` – Source WAV file.
|
||||
- `output.cpp` – Destination C++ file containing the audio data array.
|
||||
- `arrayname` – Name of the generated C array.
|
||||
|
||||
The tool validates the WAV file format and writes its sample data into a `const u8[]` array that can be directly included in PicoVGA projects.
|
||||
|
||||
@@ -185,9 +185,9 @@ const u8 mysound[1024] __attribute__ ((aligned(4))) = {
|
||||
|
||||
This array can be compiled into your PicoVGA program and played back using the sound routines in the library.
|
||||
|
||||
## picvovga_pal332 – PicoVGA 8-bit Palette Generator
|
||||
## 8-bit Palette Generator {#picvovga_pal332}
|
||||
|
||||
**picvovga_pal332** is a utility program used to generate the standard 8-bit PicoVGA palette. This palette is the foundation for all 8-bit graphics in PicoVGA and defines a total of 256 colors based on a **3-3-2 bit RGB model**:
|
||||
`picvovga_pal332` is a utility program used to generate the standard 8-bit PicoVGA palette. This palette is the foundation for all 8-bit graphics in PicoVGA and defines a total of 256 colors based on a **3-3-2 bit RGB model**:
|
||||
- **3 bits red (0–7 levels)**
|
||||
- **3 bits green (0–7 levels)**
|
||||
- **2 bits blue (0–3 levels)**
|
||||
@@ -195,10 +195,10 @@ This array can be compiled into your PicoVGA program and played back using the s
|
||||
This RGB332 format allows compact color representation while providing a broad enough spectrum for retro-style graphics.
|
||||
|
||||
### Output Files
|
||||
When you run **picvovga_pal332**, it generates two important files:
|
||||
When you run `picvovga_pal332`, it generates two important files:
|
||||
|
||||
- **pal332.act** – Adobe Color Table file containing the 256-color PicoVGA palette. This file can be imported into image editors such as Photoshop or GIMP to ensure images are created using PicoVGA’s 8-bit colors.
|
||||
- **pal332.csv** – A CSV table with detailed color information. Each row includes:
|
||||
- `pal332.act` – Adobe Color Table file containing the 256-color PicoVGA palette. This file can be imported into image editors such as Photoshop or GIMP to ensure images are created using PicoVGA’s 8-bit colors.
|
||||
- `pal332.csv` – A CSV table with detailed color information. Each row includes:
|
||||
- **Palette index (0–255)**
|
||||
- **RGB hex value**
|
||||
- **Individual red, green, and blue component values**
|
||||
@@ -216,22 +216,22 @@ Index, HEX, R, G, B
|
||||
- In **Photoshop** or **GIMP**, load `pal332.act` as the palette before saving your image as an 8-bit BMP. This ensures the image uses the exact PicoVGA colors.
|
||||
- If you identify a color in an image by its **HEX code** (e.g., `#8080FF`), you can use `pal332.csv` to look up which PicoVGA color index corresponds to that HEX value.
|
||||
|
||||
This is especially useful when working with transparency or when preparing assets for use with other PicoVGA tools such as [picovga_img](#picovga_img--image-conversion-tool) or [picovga_rle](#picovga_rle--rle-compression-tool).
|
||||
This is especially useful when working with transparency or when preparing assets for use with other PicoVGA tools such as `picovga_img` or `picovga_rle`.
|
||||
|
||||
## Palettes
|
||||
## Palettes {#palettes}
|
||||
The PicoVGA project includes a set of predefined palettes located in the `tools\palettes` folder. These palettes (`*.act` files) can be used in Photoshop, GIMP, or other graphics editors to ensure images match PicoVGA’s supported color sets.
|
||||
|
||||
### Available Palettes
|
||||
- **pal332.act** – The primary 8-bit PicoVGA palette. This file defines the 256 standard colors used by PicoVGA.
|
||||
- **pal4_PC.act** – Standard CGA 16-color palette.
|
||||
- **pal4_ZX.act** – ZX Spectrum–style 16-color palette.
|
||||
- **palcga\*.act** – Variants of CGA palettes for different modes (used for 2-bit conversions).
|
||||
- **pal1.act** – Black & white palette for 1-bit images.
|
||||
- `pal332.act` – The primary 8-bit PicoVGA palette. This file defines the 256 standard colors used by PicoVGA.
|
||||
- `pal4_PC.act` – Standard CGA 16-color palette.
|
||||
- `pal4_ZX.act` – ZX Spectrum–style 16-color palette.
|
||||
- `palcga*.act` – Variants of CGA palettes for different modes (used for 2-bit conversions).
|
||||
- `pal1.act` – Black & white palette for 1-bit images.
|
||||
|
||||
### Palette Details
|
||||
The most important palette is **pal332.act**, which represents the 3-3-2 bit RGB layout (3 bits red, 3 bits green, 2 bits blue). It is generated by the `pal332.exe` tool and comes with an additional CSV file:
|
||||
The most important palette is `pal332.act`, which represents the 3-3-2 bit RGB layout (3 bits red, 3 bits green, 2 bits blue). It is generated by the `picovga_pal332` tool and comes with an additional CSV file:
|
||||
|
||||
- **pal332.csv** – Contains detailed information about each color entry:
|
||||
- `pal332.csv` – Contains detailed information about each color entry:
|
||||
- Color index (palette order number).
|
||||
- RGB value of the color.
|
||||
- Separate red, green, and blue component values.
|
||||
|
||||
@@ -1,19 +1,58 @@
|
||||
# Usage Rules {#usagerules}
|
||||
|
||||
Image generation on the Raspberry Pico is a matter of processor utilization limits and other processor activities must be subordinated to it. When using the PicoVGA library, there are several principles to keep in mind:
|
||||
Image generation on the Raspberry Pi Pico with PicoVGA is highly demanding on processor resources. The VGA signal must always be generated on time, which means other processor activities must be carefully designed around it. The following principles are critical for stable and reliable operation of the library:
|
||||
|
||||
The library always runs on the second core of the processor and the program on the first core. Rendering the image can completely overload the CPU core and is usually unusable for other use. The separation of core functions also has the advantage that the cores do not affect each other and there is no need for mutual locking. The first core simply uses write to the frame buffers and the second core displays the contents of the frame buffers without any communication between them. This makes the overall work easier and faster.
|
||||
## Core Utilization
|
||||
- The PicoVGA library always runs on the **second core (core 1)**, while your application code runs on the **first core (core 0)**. This separation ensures that rendering does not interfere with your main program logic.
|
||||
- Rendering can fully saturate core 1, making it unsuitable for other tasks in most cases. Your main program should interact with PicoVGA by writing to frame buffers on core 0, while core 1 continuously handles video output without synchronization overhead.
|
||||
- In lightweight modes (e.g., 8-bit graphics rendered via DMA transfers), core 1 may have spare capacity. Code dispatched to core 1 through the library should not use interrupts, be careful with the interpolation unit (its state is not preserved by the renderer), and never disable interrupts.
|
||||
|
||||
If the second core is not very busy (e.g. when displaying 8-bit graphics that are simply transferred using DMA transfer), it can also be used for the main program work. However, some limitations should be taken into account - the program in the second core should not use interrupts (it would interfere with the rendering function), the interpolation unit should be used with caution (the rendering function does not save its state) and it must not disable interrupts.
|
||||
## Memory Rules
|
||||
- All data accessed by PicoVGA (images, fonts, tile patterns, etc.) must be stored in **RAM**, not flash. Flash memory is too slow and will cause video dropouts.
|
||||
- If assets are stored in external flash, copy them into a RAM buffer before passing them to the rendering functions.
|
||||
|
||||
An important rule is that all data to be accessed by the PicoVGA library **must be stored in the RAM memory**. External flash memory is slow and cannot be used for rendering functions. For example, if a flash image is to be displayed, it must first be copied to a buffer in RAM, and then a pointer to the RAM copy of the image will be passed to the rendering function. If a pointer to the image in flash were passed to it, slow access to flash would cause video dropouts. In addition to images, this also applies to fonts and tile patterns, for example.
|
||||
## Rendering Performance
|
||||
- Some modes (e.g., 8-bit DMA transfers) render very quickly, while others (e.g., sprite rendering in slow mode) are CPU-intensive.
|
||||
- Rendering is performed per line. If a mode is too demanding, individual scanlines may fail to render on time, breaking video synchronization.
|
||||
- **If rendering is too slow:**
|
||||
- Switch to a faster video mode.
|
||||
- Reduce the resolution or rendered area.
|
||||
- Mix modes (e.g., add tile borders around the display area).
|
||||
- Increase the CPU clock speed.
|
||||
|
||||
The limited rendering speed must be taken into account when scheduling screen layout. Some modes render very fast (e.g. 8-bit graphics are just transferred from the frame buffer using DMA) and some modes are very rendering intensive - e.g. rendering sprites in slow mode. When using demanding rendering, some video lines may not render fast enough in the required time and the video image will break (drop out of sync). In such cases, it is necessary to use another mode, or to reduce the rendered area (add other modes, faster ones - e.g. add tile controls on the sides of the screen), reduce the screen resolution or increase the CPU clock speed. Video lines are rendered separately and therefore it is always just content on one video line about, video lines do not affect each other. For example, you can test the speed of sprite rendering by placing all the sprites horizontally next to each other (the most challenging case) and check if the video synchronization fails.
|
||||
A good stress test is to render many sprites side by side horizontally, which creates the most demanding case.
|
||||
|
||||
Care must also be taken when using DMA transfer. DMA is used to transfer data to the PIO. Although the transfer uses a FIFO cache, using a different DMA channel may cause the render DMA channel to be delayed and thus cause the video to drop out. A DMA overload can occur, for example, when a large block of data in RAM is transferred quickly. However, the biggest load is the DMA transfer of data from flash memory. In this case, the DMA channel waits for data to be read from flash via QSPI and thus blocks the DMA render channel.
|
||||
## DMA Considerations
|
||||
- PicoVGA uses DMA to stream pixel data into the PIO. Even though the PIO has a TX **FIFO**, competing DMA traffic can delay the render DMA and cause **video dropouts**.
|
||||
- **Conflicts to watch:**
|
||||
- Large, fast **RAM↔RAM** transfers on other DMA channels.
|
||||
- **QSPI flash** reads (e.g., XIP or DMA from external flash). In these cases, the non-render DMA may stall waiting on flash, effectively **blocking** the render DMA channel.
|
||||
- Minimize or schedule other DMA operations so they do not overlap with active rendering.
|
||||
|
||||
The CPU clock frequency must also be subordinated to the image generator. Before initializing the video node, the library calculates the required system clock frequency so that the timing matches the requirements and the processor speed is sufficient for the required image resolution. It is a good idea to initially print out the calculated clock frequency for checking on the console. It is possible to prohibit the library from changing the system clock, or to prescribe only a certain range, in which case some modes may be unreachable (or the video image may break up).
|
||||
## CPU Clock Frequency
|
||||
- Before initializing video output, PicoVGA calculates and sets the required system clock frequency to ensure precise timing.
|
||||
- You should print the calculated frequency to the console at startup to verify configuration.
|
||||
- You may restrict the library from changing the system clock or limit its range. However, this can make some video modes unavailable or unstable.
|
||||
|
||||
Image buffers must be aligned to 4 bytes (32-bit CPU word) and image segments must be horizontally aligned to 4 pixels - this refers to the horizontal position of the segment, its width, alignment (wrapx) and offset (offx). Alignment does not apply to the vertical direction. This restriction is necessary because the image information is transferred to the PIO controller using a 32-bit DMA transfer, and this must be aligned to a 32-bit word. One 32-bit word contains 4 pixels (1 pixel has 8 bits), so the horizontal data in the image must also be aligned to 4 pixels. So you cannot do fine horizontal scrolling of the image in 1 pixel increments (the restriction does not apply to vertical scrolling), but only in 4 pixel increments. The exception to this is slow sprites, which are software rendered to the video line and can therefore be scrolled in 1 pixel increments. Similarly, the restriction does not apply to software rendering to framebuffer (e.g. rendering an image to video memory can be done to any coordinate).
|
||||
## Memory Alignment
|
||||
- Image buffers must be aligned to **4 bytes** (32-bit words).
|
||||
- Image **segments must be horizontally aligned to 4 pixels**. This applies to the segment’s **X position**, **width**, **wrapping** (**wrapx**), and **horizontal offset** (**offx**). Vertical alignment has no such restriction.
|
||||
- Pixel data is transferred to the PIO using 32‑bit DMA words; each word packs **4× 8‑bit pixels**, so horizontal data must start on a 4‑pixel boundary.
|
||||
- Horizontal scrolling is limited to **4‑pixel steps**. Exceptions:
|
||||
- **Slow sprites** – software-rendered per scanline; can scroll at **1‑pixel** precision.
|
||||
- **Framebuffer software rendering** – drawing directly into video memory allows **any pixel coordinate**.
|
||||
|
||||
## PIO Usage
|
||||
- PicoVGA exclusively uses **PIO0** for video output.
|
||||
- The second controller, **PIO1**, remains free and can be used for other purposes in your program.
|
||||
|
||||
## Summary
|
||||
To use PicoVGA effectively:
|
||||
1. Treat core 1 as dedicated to rendering.
|
||||
2. Keep all rendering assets in RAM.
|
||||
3. Match your rendering mode to the available performance.
|
||||
4. Avoid DMA conflicts and verify clock settings.
|
||||
5. Respect memory alignment rules (including **wrapx** and **offx**) for stable operation.
|
||||
|
||||
Following these principles ensures smooth VGA output and stable integration of PicoVGA into your Raspberry Pi Pico projects.
|
||||
|
||||
The display of the image by the PicoVGA library is performed by the PIO controller (PIO0). The other controller, PIO1, is unused and can be used for other purposes.
|
||||
|
||||
Reference in New Issue
Block a user