Additional documentation

This commit is contained in:
Wayne Venables
2023-03-07 23:30:05 -08:00
parent 5ea720d635
commit ebe6230f3e
7 changed files with 223 additions and 20 deletions

View File

@@ -4,7 +4,7 @@
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="modules" visible="yes" title="Functions" intro=""/>
<tab type="modules" visible="yes" title="API Modules" intro=""/>
<tab type="namespaces" visible="yes" title="">
<tab type="namespacelist" visible="yes" title="" intro=""/>
<tab type="namespacemembers" visible="yes" title="" intro=""/>
@@ -167,7 +167,7 @@
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="no"/>
<detaileddescription title="Introduction" />
<detaileddescription title="Description" />
<groupgraph visible="$GROUP_GRAPHS"/>
<memberdecl>
<nestedgroups visible="yes" title=""/>

View File

@@ -1,3 +1,4 @@
# Wiring diagram {#wiring}
I don't present here the overall circuit I used, because the library was created as part of a retro gaming computer with Raspberry Pico and is still under development. Here is a simplified wiring diagram of the VGA monitor output (with added audio PWM output):

3
custom.css Normal file
View File

@@ -0,0 +1,3 @@
.image {
text-align: left;
}

View File

@@ -5,7 +5,7 @@ https://github.com/jothepro/doxygen-awesome-css
MIT License
Copyright (c) 2021 - 2022 jothepro
Copyright (c) 2021 - 2023 jothepro
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -160,7 +160,7 @@ html {
--toc-background: var(--side-nav-background);
--toc-foreground: var(--side-nav-foreground);
/* height of an item in any tree / collapsable table */
/* height of an item in any tree / collapsible table */
--tree-item-height: 30px;
--memname-font-size: var(--code-font-size);
@@ -790,6 +790,7 @@ html.dark-mode iframe#MSearchResults {
#nav-tree {
background: transparent;
margin-right: 1px;
}
#nav-tree .label {
@@ -956,8 +957,9 @@ div.contents div.dyncontent {
html:not(.light-mode) div.contents > table img,
html:not(.light-mode) div.contents div.dyncontent iframe,
html:not(.light-mode) div.contents center iframe,
html:not(.light-mode) div.contents table iframe {
filter: hue-rotate(180deg) invert();
html:not(.light-mode) div.contents table iframe,
html:not(.light-mode) div.contents .dotgraph iframe {
filter: brightness(89%) hue-rotate(180deg) invert();
}
}
@@ -966,8 +968,10 @@ html.dark-mode div.contents center img,
html.dark-mode div.contents > table img,
html.dark-mode div.contents div.dyncontent iframe,
html.dark-mode div.contents center iframe,
html.dark-mode div.contents table iframe {
filter: hue-rotate(180deg) invert();
html.dark-mode div.contents table iframe,
html.dark-mode div.contents .dotgraph iframe
{
filter: brightness(89%) hue-rotate(180deg) invert();
}
h2.groupheader {
@@ -1056,6 +1060,21 @@ h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow {
color: var(--page-foreground-color);
}
.dotgraph {
max-width: 100%;
overflow-x: scroll;
}
.dotgraph .caption {
position: sticky;
left: 0;
}
/* Wrap Graphviz graphs with the `interactive_dotgraph` class if `INTERACTIVE_SVG = YES` */
.interactive_dotgraph .dotgraph iframe {
max-width: 100%;
}
/*
Table of Contents
*/
@@ -1322,7 +1341,7 @@ dl.bug dt a, dl.deprecated dt a, dl.todo dt a {
font-weight: bold !important;
}
dl.warning, dl.attention, dl.note, dl.deprecated, dl.bug, dl.invariant, dl.pre, dl.todo, dl.remark {
dl.warning, dl.attention, dl.note, dl.deprecated, dl.bug, dl.invariant, dl.pre, dl.post, dl.todo, dl.remark {
padding: var(--spacing-medium);
margin: var(--spacing-medium) 0;
color: var(--page-background-color);
@@ -1393,13 +1412,13 @@ dl.section dd, dl.bug dd, dl.deprecated dd, dl.todo dd {
margin-inline-start: 0px;
}
dl.invariant, dl.pre {
dl.invariant, dl.pre, dl.post {
background: var(--invariant-color);
border-left: 8px solid var(--invariant-color-dark);
color: var(--invariant-color-darker);
}
dl.invariant dt, dl.pre dt {
dl.invariant dt, dl.pre dt, dl.post dt {
color: var(--invariant-color-dark);
}
@@ -1603,6 +1622,10 @@ table.doxtable tbody {
border-radius: var(--border-radius-small);
}
table.markdownTable, table.doxtable, table.fieldtable {
padding: 1px;
}
table.doxtable caption {
display: block;
}
@@ -1693,6 +1716,15 @@ table.markdownTable tr:last-child, table.doxtable tr:last-child {
border-bottom: none;
}
.full_width_table table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) {
display: block;
}
.full_width_table table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) tbody {
display: table;
width: 100%;
}
table.fieldtable th {
font-size: var(--page-font-size);
font-weight: 600;
@@ -2195,7 +2227,9 @@ div.memproto::-webkit-scrollbar,
.contents center::-webkit-scrollbar,
.contents .center::-webkit-scrollbar,
.contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) tbody::-webkit-scrollbar,
div.contents .toc::-webkit-scrollbar {
div.contents .toc::-webkit-scrollbar,
.contents .dotgraph::-webkit-scrollbar,
.contents .tabs-overview-container::-webkit-scrollbar {
background: transparent;
width: calc(var(--webkit-scrollbar-size) + var(--webkit-scrollbar-padding) + var(--webkit-scrollbar-padding));
height: calc(var(--webkit-scrollbar-size) + var(--webkit-scrollbar-padding) + var(--webkit-scrollbar-padding));
@@ -2208,7 +2242,9 @@ div.memproto::-webkit-scrollbar-thumb,
.contents center::-webkit-scrollbar-thumb,
.contents .center::-webkit-scrollbar-thumb,
.contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) tbody::-webkit-scrollbar-thumb,
div.contents .toc::-webkit-scrollbar-thumb {
div.contents .toc::-webkit-scrollbar-thumb,
.contents .dotgraph::-webkit-scrollbar-thumb,
.contents .tabs-overview-container::-webkit-scrollbar-thumb {
background-color: transparent;
border: var(--webkit-scrollbar-padding) solid transparent;
border-radius: calc(var(--webkit-scrollbar-padding) + var(--webkit-scrollbar-padding));
@@ -2222,7 +2258,9 @@ div.memproto:hover::-webkit-scrollbar-thumb,
.contents center:hover::-webkit-scrollbar-thumb,
.contents .center:hover::-webkit-scrollbar-thumb,
.contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) tbody:hover::-webkit-scrollbar-thumb,
div.contents .toc:hover::-webkit-scrollbar-thumb {
div.contents .toc:hover::-webkit-scrollbar-thumb,
.contents .dotgraph:hover::-webkit-scrollbar-thumb,
.contents .tabs-overview-container:hover::-webkit-scrollbar-thumb {
background-color: var(--webkit-scrollbar-color);
}
@@ -2233,7 +2271,9 @@ div.memproto::-webkit-scrollbar-track,
.contents center::-webkit-scrollbar-track,
.contents .center::-webkit-scrollbar-track,
.contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) tbody::-webkit-scrollbar-track,
div.contents .toc::-webkit-scrollbar-track {
div.contents .toc::-webkit-scrollbar-track,
.contents .dotgraph::-webkit-scrollbar-track,
.contents .tabs-overview-container::-webkit-scrollbar-track {
background: transparent;
}
@@ -2270,7 +2310,9 @@ div.memproto,
.contents center,
.contents .center,
.contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) tbody,
div.contents .toc {
div.contents .toc,
.contents .dotgraph,
.contents .tabs-overview-container {
scrollbar-width: thin;
}
@@ -2403,3 +2445,78 @@ a.anchorlink:hover {
h2:hover a.anchorlink, h1:hover a.anchorlink, h3:hover a.anchorlink, h4:hover a.anchorlink {
display: inline-block;
}
/*
Optional tab feature
*/
.tabbed ul {
padding-inline-start: 0px;
margin: 0;
padding: var(--spacing-small) 0;
border-bottom: 1px solid var(--separator-color);
}
.tabbed li {
display: none;
}
.tabbed li.selected {
display: block;
}
.tabs-overview-container {
overflow-x: auto;
display: block;
overflow-y: visible;
}
.tabs-overview {
border-bottom: 1px solid var(--separator-color);
display: flex;
flex-direction: row;
}
.tabs-overview button.tab-button {
color: var(--page-foreground-color);
margin: 0;
border: none;
background: transparent;
padding: var(--spacing-small) 0;
display: inline-block;
font-size: var(--page-font-size);
cursor: pointer;
box-shadow: 0 1px 0 0 var(--separator-color);
}
.tabs-overview button.tab-button .tab-title {
float: left;
white-space: nowrap;
padding: var(--spacing-small) var(--spacing-large);
border-radius: var(--border-radius-medium);
}
.tabs-overview button.tab-button:not(:last-child) .tab-title {
box-shadow: 8px 0 0 -7px var(--separator-color);
}
.tabs-overview button.tab-button:hover .tab-title {
background: var(--primary-color);
color: var(--page-background-color);
box-shadow: none;
}
.tabs-overview button.tab-button.active {
color: var(--primary-color);
box-shadow: 0 1px 0 0 var(--primary-color), inset 0 -1px 0 0 var(--primary-color);
}
@media (prefers-color-scheme: dark) {
html:not(.light-mode) .tabs-overview button.tab-button:hover .tab-title {
color: var(--page-foreground-color);
}
}
html.dark-mode .tabs-overview button.tab-button:hover .tab-title {
color: var(--page-foreground-color);
}

View File

@@ -951,7 +951,7 @@ EXCLUDE_SYMBOLS =
# that contain example code fragments that are included (see the \include
# command).
EXAMPLE_PATH =
EXAMPLE_PATH = .
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
@@ -1248,7 +1248,7 @@ HTML_STYLESHEET =
# This tag requires that the tag GENERATE_HTML is set to YES.
FULL_SIDEBAR = NO
HTML_EXTRA_STYLESHEET = doxygen-awesome.css
HTML_EXTRA_STYLESHEET = doxygen-awesome.css custom.css
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the HTML output directory. Note

View File

@@ -10,7 +10,8 @@
/// @defgroup VideoInitGroup Video/Library Initialization
/// @defgroup VideoModeGroup Configurating Video Mode
/// @defgroup ScreenGroup Screen Layout
/// @defgroup LayersGroup Overlay Layers and Sprites
/// @defgroup LayersGroup Overlay Layers
/// @defgroup SpriteGroup Sprites
/// @defgroup ColorsGroup Colors and Palettes
/// @defgroup CanvasGroup Canvas
/// @defgroup OverclockGroup CPU Overclocking
@@ -20,6 +21,7 @@
/// @defgroup Core1Group Second Core
/// @defgroup UtilsGroup Utility Functions
/// @defgroup TypesGroup Base types and Constants
/// @defgroup FontsGroup Fonts
/**
* @addtogroup TypesGroup
@@ -119,7 +121,20 @@ typedef unsigned char Bool;
// Includes
// ----------------------------------------------------------------------------
// fonts
/**
* @addtogroup FontsGroup
* @brief Included fonts
* @details The following fonts are ready to use in programs. The fonts in PicoVGA are in monochrome image format
* (i.e. 1 pixel is 1 bit) with 256 characters per line and a character width of 8 pixels. The total width of the
* image is therefore 2048 pixels (256 bytes). The height of the font can be arbitrary, but by default there are 8,
* 14 and 16 line fonts in the library. Fonts are exported by the RaspPicoImg utility to *.cpp source text format,
* and are added to the program as a byte array.
*
* Example of font font_bold_8x8:
* ![](www/img/font1.jpg)
* @{
*/
extern const ALIGNED u8 FontBold8x8[2048];
extern const ALIGNED u8 FontBold8x14[3584];
extern const ALIGNED u8 FontBold8x16[4096];
@@ -133,6 +148,9 @@ extern const ALIGNED u8 FontIbmTiny8x8[2048];
extern const ALIGNED u8 FontItalic8x8[2048];
extern const ALIGNED u8 FontThin8x8[2048];
/// @}
// PicoVGA includes
#include "define.h" // common definitions of C and ASM
#include "util/canvas.h" // canvas

View File

@@ -311,6 +311,69 @@ void LayerSetup(u8 inx, const u8* img, const sVmode* vmode, u16 w, u16 h, u8 col
void LayerPerspSetup(u8 inx, const u8* img, const sVmode* vmode, u16 w, u16 h, u8 xbits, u8 ybits,
s8 horiz, const int* mat, u8 col = 0);
/// @}
/**
* @addtogroup SpriteGroup
* @details Sprites can be used in overlay planes with KEY, BLACK and WHITE programs. There are two ways to use the sprites:
*
* 1. Slow sprites, LAYERMODE_SPRITE* modes. Sprites are software generated. The line rendering function first clears the line
* buffer with a transparent color and then sequentially passes through the array of sprites. It looks for which sprites overlap
* a given Y address and, if so, renders the line into the buffer. Sprites in this mode have the advantage that they can overlap
* arbitrarily (the order of overlapping is based on the order of location in the address array) and can scroll subtly pixel by
* pixel. The main disadvantage is the high rendering overhead. Even a small number of sprites can cause a line rendering time
* overflow and thus an video dropout. However, it is important to note that the number of sprites (and their dimensions) on the
* same video line is involved. Sprites at distant Y-coordinates are not affected. To check if the rendering function will
* handle a given number of sprites, place the sprites horizontally next to each other. Conversely, if you want to ensure low
* rendering requirements, ensure that the sprites are not in the same vertical Y coordinates. Or reduce the width of the sprites.
*
* 2. Fast sprites, LAYERMODE_FASTSPRITE* modes. Sprites are not software rendered to the render buffer, but are sent directly to
* PIO via DMA transfer. This makes the rendering of sprites very fast and allows multiple sprites to be displayed side by side.
* Of course, this brings disadvantages on the other side. The X-coordinate of the sprites and their width must be a multiple of 4,
* and the sprites cannot be scrolled finely on the screen (does not apply to the Y-coordinate). But most importantly, the sprites
* cannot directly overlap. One sprite can continue rendering where the previous sprite left off. Thus, the previous sprite can cut
* off the beginning of the next sprite. There is a treatment that can slightly improve the situation. To improve overlays (and
* speed up rendering), the sprite includes a table that indicates how many pixels from the edge the opaque sprite line starts
* and how long it is. The SpritePrepLines() function can be used to generate the table. For fast sprites, this information must be
* a multiple of 4. Thus, if we ensure that the beginnings and ends of the image lines start and end at multiples of 4, the
* sprites will overlap almost correctly (unless they have internal transparency). Otherwise, transparent holes may appear at
* the point of overlap. One of the requirements for fast sprites is that the list of sprites must be sorted by the X coordinate.
* The SortSprite() support function is used for this purpose.
*
* When using sprites, the first step will be to specify the LAYERMODE_*SPRITE* layer mode for the VgaCfg() initialization
* function.
*
* The second step will be to build an array of sprite pattern line starts and lengths using the SpritePrepLines() function.
* The function will be passed a pointer to the image of each sprite (only 8-bit sprites are supported), the image dimensions,
* the pointers to the array of origin and line lengths (the array dimensions correspond to the height of the sprite), and the
* key transparency color. The function searches for line starts and line ends and writes them into the fields. The 'fast'
* parameter specifies whether the tables are generated for fast sprites, in which case the line starts and lengths are divided
* by 4. For slow sprites, the sprite width must be limited to 255 pixels.
*
* The third step is to build a list of sprites and initialize the sprites - especially the pointer to the image, the dimensions
* and coordinates of the sprites. The sprite list is an array of pointers to the sprite. Each sprite can only be in the list
* once, but multiple sprite can share the same sprite image and the same array of line starts and lengths. Slow sprites can have
* coordinates outside the allowed range (they will be cropped), but for fast sprites I recommend not to exceed the horizontal
* limits of the screen, the cropping of the image is not yet properly tuned and the program might crash.
*
* While the sprites don't have a parameter to turn them off, they can be turned off by setting the Y coordinate out off screen.
* During rendering, visible sprites are searched for by the Y coordinate, an invalid Y coordinate will ensure that the sprite
* is safely disabled.
*
* Fast sprites require sorting the list by the X coordinate. This is done by the SortSprite() function, which is passed a pointer
* to the list of sprites and the number of sprites in the list. This function should be called whenever you change the X
* coordinate of the sprite. Transient conditions (e.g. momentary mis-overlapping of sprites) do not matter, they are just
* short-term optical errors, they do not compromise the program. The function sorts using the bubble method, so it is quite
* slow, but so far it does not seem to harm anything (there are not many sprays).
*
* The last step is the initialization of the layer with the sprite. The function was described in the previous chapter.
*
* The next step is to turn on layer visibility with LayerOn() and control the sprites by changing their X and Y coordinates and
* changing their img images.
*
* @{
*/
/**
* @brief Setup overlapped layer 1..3 for LAYERMODE_SPRITE* and LAYERMODE_FASTSPRITE* modes
* @details It differs from the other setup functions by specifying the coordinate of the sprite area, the pointer to the
@@ -324,6 +387,7 @@ void LayerPerspSetup(u8 inx, const u8* img, const sVmode* vmode, u16 w, u16 h, u
* @param w Width of area with sprites (must be multiple of 4)
* @param h Height of area with sprites
* @param col Key color (needed for LAYERMODE_SPRITEKEY and LAYERMODE_FASTSPRITEKEY layer mode)
* @see LayersGroup
*/
void LayerSpriteSetup(u8 inx, sSprite** sprite, u16 spritenum, const sVmode* vmode,
s16 x, s16 y, u16 w, u16 h, u8 col = 0);