<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Sprites: Players &amp; Missiles on Programming the Atari VCS in Assembly</title><link>https://cdeever.github.io/atari-vcs/docs/sprites/</link><description>Recent content in Sprites: Players &amp; Missiles on Programming the Atari VCS in Assembly</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://cdeever.github.io/atari-vcs/docs/sprites/index.xml" rel="self" type="application/rss+xml"/><item><title>Drawing a Player</title><link>https://cdeever.github.io/atari-vcs/docs/sprites/drawing-a-player/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/atari-vcs/docs/sprites/drawing-a-player/</guid><description>&lt;h1 id="drawing-a-player"&gt;Drawing a Player&lt;a class="anchor" href="#drawing-a-player"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The two &lt;strong&gt;players&lt;/strong&gt; (P0 and P1) are the TIA&amp;rsquo;s real sprites: 8-pixel-wide bitmaps you can move anywhere and color independently. A player is how you draw the tank, the spaceship, the character. Drawing one is, like everything on the VCS, a matter of feeding the right register at the right scanline.&lt;/p&gt;
&lt;h2 id="one-byte-one-row"&gt;One byte, one row&lt;a class="anchor" href="#one-byte-one-row"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A player&amp;rsquo;s shape lives in a single register — &lt;code&gt;GRP0&lt;/code&gt; for player 0, &lt;code&gt;GRP1&lt;/code&gt; for player 1. Its &lt;strong&gt;8 bits are 8 pixels&lt;/strong&gt;: a &lt;code&gt;1&lt;/code&gt; lights a pixel in the player&amp;rsquo;s color (&lt;a href="https://cdeever.github.io/atari-vcs/docs/tia-racing-the-beam/color/"&gt;&lt;code&gt;COLUP0&lt;/code&gt; / &lt;code&gt;COLUP1&lt;/code&gt;&lt;/a&gt;), a &lt;code&gt;0&lt;/code&gt; is transparent. But a register holds only &lt;em&gt;one row&lt;/em&gt;, so — exactly like the &lt;a href="https://cdeever.github.io/atari-vcs/docs/playfield/symmetry/"&gt;playfield kernel&lt;/a&gt; — you rewrite &lt;code&gt;GRP0&lt;/code&gt; on each scanline the sprite occupies, walking down a bitmap table:&lt;/p&gt;</description></item><item><title>Horizontal Positioning</title><link>https://cdeever.github.io/atari-vcs/docs/sprites/horizontal-positioning/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/atari-vcs/docs/sprites/horizontal-positioning/</guid><description>&lt;h1 id="horizontal-positioning"&gt;Horizontal Positioning&lt;a class="anchor" href="#horizontal-positioning"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This is the technique that defines VCS sprite work, and the first place every beginner hits the cycle wall. A player has &lt;strong&gt;no X-coordinate register.&lt;/strong&gt; You cannot write &amp;ldquo;put P0 at column 40.&amp;rdquo; Instead you position it by &lt;em&gt;timing&lt;/em&gt; — and then nudge it into place.&lt;/p&gt;
&lt;h2 id="step-one-strobe-to-a-coarse-position"&gt;Step one: strobe to a coarse position&lt;a class="anchor" href="#step-one-strobe-to-a-coarse-position"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Writing to &lt;code&gt;RESP0&lt;/code&gt; is a &lt;a href="https://cdeever.github.io/atari-vcs/docs/prerequisites/memory-mapped/"&gt;strobe&lt;/a&gt;: the value doesn&amp;rsquo;t matter, the &lt;em&gt;act&lt;/em&gt; of writing does. It snaps player 0&amp;rsquo;s horizontal position to &lt;strong&gt;wherever the beam happens to be&lt;/strong&gt; at the moment the store executes. So you move a sprite by choosing &lt;em&gt;when&lt;/em&gt; in the scanline to run &lt;code&gt;STA RESP0&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Size &amp; Copies (NUSIZ)</title><link>https://cdeever.github.io/atari-vcs/docs/sprites/size-and-copies/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/atari-vcs/docs/sprites/size-and-copies/</guid><description>&lt;h1 id="size--copies-nusiz"&gt;Size &amp;amp; Copies (NUSIZ)&lt;a class="anchor" href="#size--copies-nusiz"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;There are only &lt;a href="https://cdeever.github.io/atari-vcs/docs/sprites/drawing-a-player/"&gt;two players&lt;/a&gt;, but a single register stretches what they can do. &lt;code&gt;NUSIZ0&lt;/code&gt; and &lt;code&gt;NUSIZ1&lt;/code&gt; (one per player) set a player&amp;rsquo;s &lt;strong&gt;width&lt;/strong&gt; &lt;em&gt;and&lt;/em&gt; let the TIA stamp out &lt;strong&gt;multiple copies&lt;/strong&gt; of it across the line — and the same register sizes that player&amp;rsquo;s missile. It&amp;rsquo;s the cheapest way to get more than two objects on screen at once.&lt;/p&gt;
&lt;h2 id="player-width-and-copies"&gt;Player width and copies&lt;a class="anchor" href="#player-width-and-copies"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The low three bits of &lt;code&gt;NUSIZ&lt;/code&gt; choose one of eight modes:&lt;/p&gt;</description></item><item><title>Missiles &amp; the Ball</title><link>https://cdeever.github.io/atari-vcs/docs/sprites/missiles-and-ball/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/atari-vcs/docs/sprites/missiles-and-ball/</guid><description>&lt;h1 id="missiles--the-ball"&gt;Missiles &amp;amp; the Ball&lt;a class="anchor" href="#missiles--the-ball"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The other three movable objects — two &lt;strong&gt;missiles&lt;/strong&gt; and one &lt;strong&gt;ball&lt;/strong&gt; — are the TIA&amp;rsquo;s single-bit shapes. They have no bitmap; each is just a solid colored rectangle whose only graphic choice is its &lt;a href="https://cdeever.github.io/atari-vcs/docs/sprites/size-and-copies/"&gt;width&lt;/a&gt;. That makes them cheap to position and toggle, which is exactly what you want for bullets, balls, and small markers.&lt;/p&gt;
&lt;h2 id="the-missiles"&gt;The missiles&lt;a class="anchor" href="#the-missiles"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Missile 0 and missile 1 are turned on by &lt;code&gt;ENAM0&lt;/code&gt; / &lt;code&gt;ENAM1&lt;/code&gt; and positioned with the same &lt;a href="https://cdeever.github.io/atari-vcs/docs/sprites/horizontal-positioning/"&gt;strobe-and-&lt;code&gt;HMOVE&lt;/code&gt;&lt;/a&gt; dance as the players (&lt;code&gt;RESM0&lt;/code&gt;/&lt;code&gt;RESM1&lt;/code&gt;, &lt;code&gt;HMM0&lt;/code&gt;/&lt;code&gt;HMM1&lt;/code&gt;). The catch — and the convenience — is &lt;strong&gt;color&lt;/strong&gt;: a missile has none of its own. &lt;strong&gt;M0 always draws in player 0&amp;rsquo;s color (&lt;code&gt;COLUP0&lt;/code&gt;), M1 in player 1&amp;rsquo;s.&lt;/strong&gt; A missile is, by design, &lt;em&gt;this player&amp;rsquo;s&lt;/em&gt; projectile.&lt;/p&gt;</description></item><item><title>Object Priority</title><link>https://cdeever.github.io/atari-vcs/docs/sprites/priority/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/atari-vcs/docs/sprites/priority/</guid><description>&lt;h1 id="object-priority"&gt;Object Priority&lt;a class="anchor" href="#object-priority"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;When two objects cover the same pixel, one of them has to win — and which one shows in front is &lt;strong&gt;object priority&lt;/strong&gt;. This is a separate question from &lt;a href="https://cdeever.github.io/atari-vcs/docs/collisions/"&gt;collisions&lt;/a&gt;: collision detection only tells you &lt;em&gt;that&lt;/em&gt; two objects overlapped, never which was drawn on top. Priority is what decides the picture.&lt;/p&gt;
&lt;h2 id="the-default-order"&gt;The default order&lt;a class="anchor" href="#the-default-order"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The TIA ranks the six things it can draw in a fixed order. Highest priority is drawn in front:&lt;/p&gt;</description></item><item><title>Sprite Multiplexing</title><link>https://cdeever.github.io/atari-vcs/docs/sprites/sprite-multiplexing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/atari-vcs/docs/sprites/sprite-multiplexing/</guid><description>&lt;h1 id="sprite-multiplexing"&gt;Sprite Multiplexing&lt;a class="anchor" href="#sprite-multiplexing"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The TIA gives you &lt;strong&gt;two &lt;a href="https://cdeever.github.io/atari-vcs/docs/sprites/drawing-a-player/"&gt;players&lt;/a&gt;&lt;/strong&gt;, and — unlike ROM or RAM — &lt;em&gt;no &lt;a href="https://cdeever.github.io/atari-vcs/docs/cartridge-hardware/"&gt;cartridge hardware&lt;/a&gt; adds more.&lt;/em&gt; The two-sprite limit is one you beat in &lt;strong&gt;software&lt;/strong&gt;. Yet games routinely show a screen full of enemies, shots, and characters; they do it by &lt;strong&gt;time-sharing&lt;/strong&gt; the two players — reusing each one to be several different things, either down the screen or across frames.&lt;/p&gt;
&lt;h2 id="reuse-down-the-screen"&gt;Reuse down the screen&lt;a class="anchor" href="#reuse-down-the-screen"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The key realization: a player only occupies the scanlines you actually draw it on. If two objects never share a scanline, &lt;strong&gt;one player can be both of them&lt;/strong&gt; — enemy A in the top third of the screen, enemy B in the middle, enemy C at the bottom, all drawn by the &lt;em&gt;same&lt;/em&gt; player 0 in a single kernel.&lt;/p&gt;</description></item></channel></rss>