335 lines
21 KiB
HTML
335 lines
21 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
|
<meta name="generator" content="Doxygen 1.9.1"/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
<title>PicoVGA: Sprites</title>
|
|
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="jquery.js"></script>
|
|
<script type="text/javascript" src="dynsections.js"></script>
|
|
<link href="navtree.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="resize.js"></script>
|
|
<script type="text/javascript" src="navtreedata.js"></script>
|
|
<script type="text/javascript" src="navtree.js"></script>
|
|
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="search/searchdata.js"></script>
|
|
<script type="text/javascript" src="search/search.js"></script>
|
|
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
|
<link href="doxygen-awesome.css" rel="stylesheet" type="text/css"/>
|
|
<link href="custom.css" rel="stylesheet" type="text/css"/>
|
|
</head>
|
|
<body>
|
|
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
|
<div id="titlearea">
|
|
<table cellspacing="0" cellpadding="0">
|
|
<tbody>
|
|
<tr style="height: 56px;">
|
|
<td id="projectlogo"><img alt="Logo" src="logo.png"/></td>
|
|
<td id="projectalign" style="padding-left: 0.5em;">
|
|
<div id="projectname">PicoVGA
|
|
 <span id="projectnumber">1.2-cmake</span>
|
|
</div>
|
|
<div id="projectbrief">VGA/TV display on Raspberry Pico</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<!-- end header part -->
|
|
<!-- Generated by Doxygen 1.9.1 -->
|
|
<script type="text/javascript">
|
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
|
var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
|
|
/* @license-end */
|
|
</script>
|
|
<script type="text/javascript" src="menudata.js"></script>
|
|
<script type="text/javascript" src="menu.js"></script>
|
|
<script type="text/javascript">
|
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
|
$(function() {
|
|
initMenu('',true,false,'search.php','Search');
|
|
$(document).ready(function() { init_search(); });
|
|
});
|
|
/* @license-end */</script>
|
|
<div id="main-nav"></div>
|
|
</div><!-- top -->
|
|
<div id="side-nav" class="ui-resizable side-nav-resizable">
|
|
<div id="nav-tree">
|
|
<div id="nav-tree-contents">
|
|
<div id="nav-sync" class="sync"></div>
|
|
</div>
|
|
</div>
|
|
<div id="splitbar" style="-moz-user-select:none;"
|
|
class="ui-resizable-handle">
|
|
</div>
|
|
</div>
|
|
<script type="text/javascript">
|
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
|
$(document).ready(function(){initNavTree('group__SpriteGroup.html',''); initResizable(); });
|
|
/* @license-end */
|
|
</script>
|
|
<div id="doc-content">
|
|
<!-- window showing the filter options -->
|
|
<div id="MSearchSelectWindow"
|
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
|
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
|
</div>
|
|
|
|
<!-- iframe showing the search results (closed by default) -->
|
|
<div id="MSearchResultsWindow">
|
|
<iframe src="javascript:void(0)" frameborder="0"
|
|
name="MSearchResults" id="MSearchResults">
|
|
</iframe>
|
|
</div>
|
|
|
|
<div class="header">
|
|
<div class="summary">
|
|
<a href="#func-members">Functions</a> </div>
|
|
<div class="headertitle">
|
|
<div class="title">Sprites</div> </div>
|
|
</div><!--header-->
|
|
<div class="contents">
|
|
<a name="details" id="details"></a><h2 class="groupheader">Description</h2>
|
|
<p>Sprites can be used in overlay planes with KEY, BLACK and WHITE programs. There are two ways to use the sprites:</p>
|
|
<ol type="1">
|
|
<li>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.</li>
|
|
<li>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 <a class="el" href="group__SpriteGroup.html#ga63d71d933e8f5e7b47b139f61d1186fe" title="Prepare array of start and length of lines (detects transparent pixels)">SpritePrepLines()</a> 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 <a class="el" href="group__SpriteGroup.html#gaee253aa5119f5c51858b19fb65843fc2" title="Sort fast sprite list by X coordinate.">SortSprite()</a> support function is used for this purpose.</li>
|
|
</ol>
|
|
<p>When using sprites, the first step will be to specify the LAYERMODE_*SPRITE* layer mode for the <a class="el" href="group__VideoModeGroup.html#ga5a8c9c954becaf3532bb45f3801ca916" title="Calculate the structure for setting up the video mode.">VgaCfg()</a> initialization function.</p>
|
|
<p>The second step will be to build an array of sprite pattern line starts and lengths using the <a class="el" href="group__SpriteGroup.html#ga63d71d933e8f5e7b47b139f61d1186fe" title="Prepare array of start and length of lines (detects transparent pixels)">SpritePrepLines()</a> 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.</p>
|
|
<p>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.</p>
|
|
<p>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.</p>
|
|
<p>Fast sprites require sorting the list by the X coordinate. This is done by the <a class="el" href="group__SpriteGroup.html#gaee253aa5119f5c51858b19fb65843fc2" title="Sort fast sprite list by X coordinate.">SortSprite()</a> 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).</p>
|
|
<p>The last step is the initialization of the layer with the sprite. The function was described in the previous chapter.</p>
|
|
<p>The next step is to turn on layer visibility with <a class="el" href="group__LayersGroup.html#gaf95ad14e461311fde045530e4fbc8c9f" title="Set overlapped layer 1..3 ON.">LayerOn()</a> and control the sprites by changing their X and Y coordinates and changing their img images. </p>
|
|
<table class="memberdecls">
|
|
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
|
|
Functions</h2></td></tr>
|
|
<tr class="memitem:ga3335f2de0489fb2ceaa2641822b37872"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__SpriteGroup.html#ga3335f2de0489fb2ceaa2641822b37872">LayerSpriteSetup</a> (u8 inx, <a class="el" href="structsSprite.html">sSprite</a> **sprite, u16 spritenum, const <a class="el" href="structsVmode.html">sVmode</a> *vmode, s16 x, s16 y, u16 w, u16 h, u8 col=0)</td></tr>
|
|
<tr class="memdesc:ga3335f2de0489fb2ceaa2641822b37872"><td class="mdescLeft"> </td><td class="mdescRight">Setup overlapped layer 1..3 for LAYERMODE_SPRITE* and LAYERMODE_FASTSPRITE* modes. <a href="group__SpriteGroup.html#ga3335f2de0489fb2ceaa2641822b37872">More...</a><br /></td></tr>
|
|
<tr class="separator:ga3335f2de0489fb2ceaa2641822b37872"><td class="memSeparator" colspan="2"> </td></tr>
|
|
<tr class="memitem:ga63d71d933e8f5e7b47b139f61d1186fe"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__SpriteGroup.html#ga63d71d933e8f5e7b47b139f61d1186fe">SpritePrepLines</a> (const u8 *img, u8 *x0, u8 *w0, u16 w, u16 h, u16 wb, u8 col, Bool fast)</td></tr>
|
|
<tr class="memdesc:ga63d71d933e8f5e7b47b139f61d1186fe"><td class="mdescLeft"> </td><td class="mdescRight">Prepare array of start and length of lines (detects transparent pixels) <a href="group__SpriteGroup.html#ga63d71d933e8f5e7b47b139f61d1186fe">More...</a><br /></td></tr>
|
|
<tr class="separator:ga63d71d933e8f5e7b47b139f61d1186fe"><td class="memSeparator" colspan="2"> </td></tr>
|
|
<tr class="memitem:gaee253aa5119f5c51858b19fb65843fc2"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__SpriteGroup.html#gaee253aa5119f5c51858b19fb65843fc2">SortSprite</a> (<a class="el" href="structsSprite.html">sSprite</a> **list, int num)</td></tr>
|
|
<tr class="memdesc:gaee253aa5119f5c51858b19fb65843fc2"><td class="mdescLeft"> </td><td class="mdescRight">Sort fast sprite list by X coordinate. <a href="group__SpriteGroup.html#gaee253aa5119f5c51858b19fb65843fc2">More...</a><br /></td></tr>
|
|
<tr class="separator:gaee253aa5119f5c51858b19fb65843fc2"><td class="memSeparator" colspan="2"> </td></tr>
|
|
</table>
|
|
<h2 class="groupheader">Function Documentation</h2>
|
|
<a id="ga3335f2de0489fb2ceaa2641822b37872"></a>
|
|
<h2 class="memtitle"><span class="permalink"><a href="#ga3335f2de0489fb2ceaa2641822b37872">◆ </a></span>LayerSpriteSetup()</h2>
|
|
|
|
<div class="memitem">
|
|
<div class="memproto">
|
|
<table class="memname">
|
|
<tr>
|
|
<td class="memname">void LayerSpriteSetup </td>
|
|
<td>(</td>
|
|
<td class="paramtype">u8 </td>
|
|
<td class="paramname"><em>inx</em>, </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="paramkey"></td>
|
|
<td></td>
|
|
<td class="paramtype"><a class="el" href="structsSprite.html">sSprite</a> ** </td>
|
|
<td class="paramname"><em>sprite</em>, </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="paramkey"></td>
|
|
<td></td>
|
|
<td class="paramtype">u16 </td>
|
|
<td class="paramname"><em>spritenum</em>, </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="paramkey"></td>
|
|
<td></td>
|
|
<td class="paramtype">const <a class="el" href="structsVmode.html">sVmode</a> * </td>
|
|
<td class="paramname"><em>vmode</em>, </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="paramkey"></td>
|
|
<td></td>
|
|
<td class="paramtype">s16 </td>
|
|
<td class="paramname"><em>x</em>, </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="paramkey"></td>
|
|
<td></td>
|
|
<td class="paramtype">s16 </td>
|
|
<td class="paramname"><em>y</em>, </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="paramkey"></td>
|
|
<td></td>
|
|
<td class="paramtype">u16 </td>
|
|
<td class="paramname"><em>w</em>, </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="paramkey"></td>
|
|
<td></td>
|
|
<td class="paramtype">u16 </td>
|
|
<td class="paramname"><em>h</em>, </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="paramkey"></td>
|
|
<td></td>
|
|
<td class="paramtype">u8 </td>
|
|
<td class="paramname"><em>col</em> = <code>0</code> </td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td>)</td>
|
|
<td></td><td></td>
|
|
</tr>
|
|
</table>
|
|
</div><div class="memdoc">
|
|
|
|
<p>Setup overlapped layer 1..3 for LAYERMODE_SPRITE* and LAYERMODE_FASTSPRITE* modes. </p>
|
|
<p>It differs from the other setup functions by specifying the coordinate of the sprite area, the pointer to the sprite address array and the number of sprites. </p><dl class="params"><dt>Parameters</dt><dd>
|
|
<table class="params">
|
|
<tr><td class="paramname">inx</td><td>Layer index 1..3 </td></tr>
|
|
<tr><td class="paramname">sprite</td><td>Pointer to list of sprites (array of pointers to sprites; sorted by X on LAYERMODE_FASTSPRITE* modes) </td></tr>
|
|
<tr><td class="paramname">spritenum</td><td>Number of sprites in the list (to turn sprite off, you can set its coordinate Y out of the screen) </td></tr>
|
|
<tr><td class="paramname">vmode</td><td>Pointer to initialized video configuration </td></tr>
|
|
<tr><td class="paramname">x</td><td>Start coordinate X of area with sprites </td></tr>
|
|
<tr><td class="paramname">y</td><td>Start coordinate Y of area with sprites </td></tr>
|
|
<tr><td class="paramname">w</td><td>Width of area with sprites (must be multiple of 4) </td></tr>
|
|
<tr><td class="paramname">h</td><td>Height of area with sprites </td></tr>
|
|
<tr><td class="paramname">col</td><td>Key color (needed for LAYERMODE_SPRITEKEY and LAYERMODE_FASTSPRITEKEY layer mode) </td></tr>
|
|
</table>
|
|
</dd>
|
|
</dl>
|
|
<dl class="section see"><dt>See also</dt><dd><a class="el" href="group__LayersGroup.html">Overlay Layers</a> </dd></dl>
|
|
|
|
</div>
|
|
</div>
|
|
<a id="ga63d71d933e8f5e7b47b139f61d1186fe"></a>
|
|
<h2 class="memtitle"><span class="permalink"><a href="#ga63d71d933e8f5e7b47b139f61d1186fe">◆ </a></span>SpritePrepLines()</h2>
|
|
|
|
<div class="memitem">
|
|
<div class="memproto">
|
|
<table class="memname">
|
|
<tr>
|
|
<td class="memname">void SpritePrepLines </td>
|
|
<td>(</td>
|
|
<td class="paramtype">const u8 * </td>
|
|
<td class="paramname"><em>img</em>, </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="paramkey"></td>
|
|
<td></td>
|
|
<td class="paramtype">u8 * </td>
|
|
<td class="paramname"><em>x0</em>, </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="paramkey"></td>
|
|
<td></td>
|
|
<td class="paramtype">u8 * </td>
|
|
<td class="paramname"><em>w0</em>, </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="paramkey"></td>
|
|
<td></td>
|
|
<td class="paramtype">u16 </td>
|
|
<td class="paramname"><em>w</em>, </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="paramkey"></td>
|
|
<td></td>
|
|
<td class="paramtype">u16 </td>
|
|
<td class="paramname"><em>h</em>, </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="paramkey"></td>
|
|
<td></td>
|
|
<td class="paramtype">u16 </td>
|
|
<td class="paramname"><em>wb</em>, </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="paramkey"></td>
|
|
<td></td>
|
|
<td class="paramtype">u8 </td>
|
|
<td class="paramname"><em>col</em>, </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="paramkey"></td>
|
|
<td></td>
|
|
<td class="paramtype">Bool </td>
|
|
<td class="paramname"><em>fast</em> </td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td>)</td>
|
|
<td></td><td></td>
|
|
</tr>
|
|
</table>
|
|
</div><div class="memdoc">
|
|
|
|
<p>Prepare array of start and length of lines (detects transparent pixels) </p>
|
|
<p>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. </p><dl class="params"><dt>Parameters</dt><dd>
|
|
<table class="params">
|
|
<tr><td class="paramname">img</td><td>Pointer to image </td></tr>
|
|
<tr><td class="paramname">x0</td><td>Array of start of lines </td></tr>
|
|
<tr><td class="paramname">w0</td><td>Array of length of lines </td></tr>
|
|
<tr><td class="paramname">w</td><td>Sprite width (slow sprite: max. width 255) </td></tr>
|
|
<tr><td class="paramname">h</td><td>Sprite height </td></tr>
|
|
<tr><td class="paramname">wb</td><td>Sprite pitch (bytes between lines) </td></tr>
|
|
<tr><td class="paramname">col</td><td>Key color </td></tr>
|
|
<tr><td class="paramname">fast</td><td>Fast sprite, divide start and length of line by 4 </td></tr>
|
|
</table>
|
|
</dd>
|
|
</dl>
|
|
|
|
</div>
|
|
</div>
|
|
<a id="gaee253aa5119f5c51858b19fb65843fc2"></a>
|
|
<h2 class="memtitle"><span class="permalink"><a href="#gaee253aa5119f5c51858b19fb65843fc2">◆ </a></span>SortSprite()</h2>
|
|
|
|
<div class="memitem">
|
|
<div class="memproto">
|
|
<table class="memname">
|
|
<tr>
|
|
<td class="memname">void SortSprite </td>
|
|
<td>(</td>
|
|
<td class="paramtype"><a class="el" href="structsSprite.html">sSprite</a> ** </td>
|
|
<td class="paramname"><em>list</em>, </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="paramkey"></td>
|
|
<td></td>
|
|
<td class="paramtype">int </td>
|
|
<td class="paramname"><em>num</em> </td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td>)</td>
|
|
<td></td><td></td>
|
|
</tr>
|
|
</table>
|
|
</div><div class="memdoc">
|
|
|
|
<p>Sort fast sprite list by X coordinate. </p>
|
|
<p>Fast sprites require sorting the list by the X coordinate. Pass 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). </p><dl class="params"><dt>Parameters</dt><dd>
|
|
<table class="params">
|
|
<tr><td class="paramname">list</td><td>Sprite list </td></tr>
|
|
<tr><td class="paramname">num</td><td>Number of sprites </td></tr>
|
|
</table>
|
|
</dd>
|
|
</dl>
|
|
|
|
</div>
|
|
</div>
|
|
</div><!-- contents -->
|
|
</div><!-- doc-content -->
|
|
<!-- start footer part -->
|
|
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
|
|
<ul>
|
|
<li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
|
|
</ul>
|
|
</div>
|
|
</body>
|
|
</html>
|