http://wiki.intellivision.us/index.php?title=Tagalong_Todd_Tutorial:_Part_3&feed=atom&action=historyTagalong Todd Tutorial: Part 3 - Revision history2024-03-28T15:27:38ZRevision history for this page on the wikiMediaWiki 1.30.0http://wiki.intellivision.us/index.php?title=Tagalong_Todd_Tutorial:_Part_3&diff=15016&oldid=prevRickreynolds: /* That's it! */2012-12-08T18:54:14Z<p><span dir="auto"><span class="autocomment">That's it!</span></span></p>
<table class="diff diff-contentalign-left" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr style="vertical-align: top;" lang="en">
<td colspan="2" style="background-color: white; color:black; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: white; color:black; text-align: center;">Revision as of 18:54, 8 December 2012</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l259" >Line 259:</td>
<td colspan="2" class="diff-lineno">Line 259:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>== That's it! ==</div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>== That's it! ==</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'>−</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>We're really close to having this demo fully functional. With the player moving around, we really only need to add <del class="diffchange diffchange-inline">code to programmatically move </del>Todd.</div></td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>We're really close to having this demo fully functional. With the player moving around, we really only need to add Todd.</div></td></tr>
</table>Rickreynoldshttp://wiki.intellivision.us/index.php?title=Tagalong_Todd_Tutorial:_Part_3&diff=15015&oldid=prevRickreynolds: /* Introducing scanhand */2012-12-08T18:51:23Z<p><span dir="auto"><span class="autocomment">Introducing scanhand</span></span></p>
<table class="diff diff-contentalign-left" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr style="vertical-align: top;" lang="en">
<td colspan="2" style="background-color: white; color:black; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: white; color:black; text-align: center;">Revision as of 18:51, 8 December 2012</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l46" >Line 46:</td>
<td colspan="2" class="diff-lineno">Line 46:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>Here we're setting up the dispatch table that the scanhand routine expects. This probably warrants a bit of explanation. scanhand wants the addresses of three routines:</div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>Here we're setting up the dispatch table that the scanhand routine expects. This probably warrants a bit of explanation. scanhand wants the addresses of three routines:</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'>−</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div><del class="diffchange diffchange-inline">1. </del>a routine to call when someone presses a button on the keypad</div></td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins class="diffchange diffchange-inline"># </ins>a routine to call when someone presses a button on the keypad</div></td></tr>
<tr><td class='diff-marker'>−</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div><del class="diffchange diffchange-inline">2. </del>a routine to call when someone presses a side action button</div></td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins class="diffchange diffchange-inline"># </ins>a routine to call when someone presses a side action button</div></td></tr>
<tr><td class='diff-marker'>−</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div><del class="diffchange diffchange-inline">3. </del>a routine to call when someone presses a disc direction</div></td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins class="diffchange diffchange-inline"># </ins>a routine to call when someone presses a disc direction</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>The addresses of those routines need to be provided in that order. So we see this chunk of code later in the file:</div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>The addresses of those routines need to be provided in that order. So we see this chunk of code later in the file:</div></td></tr>
</table>Rickreynoldshttp://wiki.intellivision.us/index.php?title=Tagalong_Todd_Tutorial:_Part_3&diff=15014&oldid=prevRickreynolds: /* Introducing scanhand */2012-12-08T18:50:13Z<p><span dir="auto"><span class="autocomment">Introducing scanhand</span></span></p>
<table class="diff diff-contentalign-left" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr style="vertical-align: top;" lang="en">
<td colspan="2" style="background-color: white; color:black; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: white; color:black; text-align: center;">Revision as of 18:50, 8 December 2012</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l44" >Line 44:</td>
<td colspan="2" class="diff-lineno">Line 44:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>             MVII    #HAND,  R0      ;\__ Set up scanhand dispatch table</div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>             MVII    #HAND,  R0      ;\__ Set up scanhand dispatch table</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>             MVO    R0,    SHDISP  ;/</pre></div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>             MVO    R0,    SHDISP  ;/</pre></div></td></tr>
<tr><td class='diff-marker'>−</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>Here we're setting up the dispatch table that the scanhand routine expects. This probably warrants a bit of explanation. scanhand wants the addresses of three routines: <del class="diffchange diffchange-inline">(</del>1<del class="diffchange diffchange-inline">) </del>a routine to call when someone presses a button on the keypad<del class="diffchange diffchange-inline">, (</del>2<del class="diffchange diffchange-inline">) </del>a routine to call when someone presses a side action button<del class="diffchange diffchange-inline">, and (</del>3<del class="diffchange diffchange-inline">) </del>a routine to call when someone presses a disc direction<del class="diffchange diffchange-inline">. </del>The addresses of those routines need to be provided in that order. So we see this chunk of code later in the file:</div></td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>Here we're setting up the dispatch table that the scanhand routine expects. This probably warrants a bit of explanation. scanhand wants the addresses of three routines:</div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>1<ins class="diffchange diffchange-inline">. </ins>a routine to call when someone presses a button on the keypad</div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>2<ins class="diffchange diffchange-inline">. </ins>a routine to call when someone presses a side action button</div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>3<ins class="diffchange diffchange-inline">. </ins>a routine to call when someone presses a disc direction</div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>The addresses of those routines need to be provided in that order. So we see this chunk of code later in the file:</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div><pre>;; ======================================================================== ;;</div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div><pre>;; ======================================================================== ;;</div></td></tr>
</table>Rickreynoldshttp://wiki.intellivision.us/index.php?title=Tagalong_Todd_Tutorial:_Part_3&diff=15012&oldid=prevRickreynolds: /* Tagalong Todd Tutorial: Part 3 */2012-12-08T18:41:06Z<p><span dir="auto"><span class="autocomment">Tagalong Todd Tutorial: Part 3</span></span></p>
<table class="diff diff-contentalign-left" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr style="vertical-align: top;" lang="en">
<td colspan="2" style="background-color: white; color:black; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: white; color:black; text-align: center;">Revision as of 18:41, 8 December 2012</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>
<td colspan="2" class="diff-lineno">Line 1:</td></tr>
<tr><td class='diff-marker'>−</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div><del class="diffchange diffchange-inline">= Tagalong Todd </del>Tutorial<del class="diffchange diffchange-inline">: Part 3 =</del></div></td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins class="diffchange diffchange-inline">[[Category: Programming]][[Category: </ins>Tutorial<ins class="diffchange diffchange-inline">]]</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins class="diffchange diffchange-inline">In this part of the tutorial, we'll add code that will read the hand controller and move our player figure around the screen in response.</ins></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'>−</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div><del class="diffchange diffchange-inline">In </del>this <del class="diffchange diffchange-inline">part of the </del>tutorial<del class="diffchange diffchange-inline">, we</del>'<del class="diffchange diffchange-inline">ll add code that will read </del>the <del class="diffchange diffchange-inline">hand controller and move our player figure around </del>the <del class="diffchange diffchange-inline">screen in response</del>.</div></td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins class="diffchange diffchange-inline">The complete source for </ins>this tutorial <ins class="diffchange diffchange-inline">(it</ins>'<ins class="diffchange diffchange-inline">s a subset of </ins>the <ins class="diffchange diffchange-inline">full tagalong.asm </ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins class="diffchange diffchange-inline">found in </ins>the <ins class="diffchange diffchange-inline">SDK) is [[Tagalong Todd Tutorial: Part 3 - Files|here]]</ins>.</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'>−</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div><del style="font-weight: bold; text-decoration: none;">The complete source for this tutorial (it's a subset of the full tagalong.asm found in the SDK) is in the file tag3.asm.</del></div></td><td colspan="2"> </td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>== Changes to our movement routine ==</div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>== Changes to our movement routine ==</div></td></tr>
</table>Rickreynoldshttp://wiki.intellivision.us/index.php?title=Tagalong_Todd_Tutorial:_Part_3&diff=15010&oldid=prevRickreynolds: Created page with "= Tagalong Todd Tutorial: Part 3 = In this part of the tutorial, we'll add code that will read the hand controller and move our player figure around the screen in response. The..."2012-12-08T18:38:26Z<p>Created page with "= Tagalong Todd Tutorial: Part 3 = In this part of the tutorial, we'll add code that will read the hand controller and move our player figure around the screen in response. The..."</p>
<p><b>New page</b></p><div>= Tagalong Todd Tutorial: Part 3 =<br />
<br />
In this part of the tutorial, we'll add code that will read the hand controller and move our player figure around the screen in response.<br />
<br />
The complete source for this tutorial (it's a subset of the full tagalong.asm found in the SDK) is in the file tag3.asm.<br />
<br />
== Changes to our movement routine ==<br />
<br />
In order to move the character figure around in a believable manner, we'll change the algorithm we've been using for the movement. Our last update just moved the figure via an offset. We'll change that here to include a velocity measure. As the user presses the disc, we'll speed up the character movement until it hits a maximum speed.<br />
<br />
== Introducing scanhand ==<br />
<br />
A set of routines that read the hand controllers is provided with the SDK in a library file called scanhand.asm. It is built to be used with the TASKQ library and both pieces make assumptions about the other. At this point, it's enough to know that we need to allocate specifically named chunks of memory for the library routines.<br />
<br />
<pre> ; Hand-controller 8-bit variables<br />
SH_TMP RMB 1 ; Temp storage.<br />
SH_LR0 RMB 3 ;\<br />
SH_FL0 EQU SH_LR0 + 1 ; |-- Three bytes for left controller<br />
SH_LV0 EQU SH_LR0 + 2 ;/<br />
SH_LR1 RMB 3 ;\<br />
SH_FL1 EQU SH_LR1 + 1 ; |-- Three bytes for right controller<br />
SH_LV1 EQU SH_LR1 + 2 ;/<br />
<br />
; Hand-controller 16-bit variables<br />
SHDISP RMB 1 ; ScanHand dispatch</pre><br />
We're also going to need more variables to store the new velocity measures we'll be manipulating.<br />
<br />
<pre>PLYR PROC<br />
@@XP RMB 1 ; X position<br />
@@YP RMB 1 ; Y position<br />
@@XV RMB 1 ; X velocity<br />
@@YV RMB 1 ; Y velocity<br />
@@TXV RMB 1 ; Target X velocity<br />
@@TYV RMB 1 ; Target Y velocity<br />
ENDP</pre><br />
The XP and YP variable should look familiar from part 2 of the tutorial. We're introducing two new pairs of values: a current velocity and a target velocity in each of the X and Y directions.<br />
<br />
After those pieces of setup are done, we can get into the algorithm changes.<br />
<br />
<pre> ;; ------------------------------------------------------------ ;;<br />
;; Set up our hand-controller dispatch. ;;<br />
;; ------------------------------------------------------------ ;;<br />
MVII #HAND, R0 ;\__ Set up scanhand dispatch table<br />
MVO R0, SHDISP ;/</pre><br />
Here we're setting up the dispatch table that the scanhand routine expects. This probably warrants a bit of explanation. scanhand wants the addresses of three routines: (1) a routine to call when someone presses a button on the keypad, (2) a routine to call when someone presses a side action button, and (3) a routine to call when someone presses a disc direction. The addresses of those routines need to be provided in that order. So we see this chunk of code later in the file:<br />
<br />
<pre>;; ======================================================================== ;;<br />
;; HAND Dispatch table. ;;<br />
;; ======================================================================== ;;<br />
HAND PROC<br />
DECLE HIT_KEYPAD<br />
DECLE HIT_ACTION<br />
DECLE HIT_DISC<br />
ENDP</pre><br />
These lines setup the three routines that scanhand should call. Those routines need to be defined in our code - after all, scanhand doesn't know what we want to do when the player presses buttons or disc.<br />
<br />
== Precomputing velocities for various angles ==<br />
<br />
<pre>;; ======================================================================== ;;<br />
;; SINTBL -- Sine table. sin(disc_dir) * 511 ;;<br />
;; ======================================================================== ;;<br />
SINTBL PROC<br />
DECLE $0000<br />
DECLE $00C3<br />
DECLE $0169<br />
DECLE $01D8<br />
DECLE $01FF<br />
DECLE $01D8<br />
DECLE $0169<br />
DECLE $00C3<br />
DECLE $0000<br />
DECLE $FF3D<br />
DECLE $FE97<br />
DECLE $FE28<br />
DECLE $FE01<br />
DECLE $FE28<br />
DECLE $FE97<br />
DECLE $FF3D<br />
ENDP</pre><br />
This is a lookup table that defines the values for sin(x) * 511 for the 16 directions that the directional disc can input. These will be the values we'll apply to the Y direction velocity as we move the player around the screen. Note that we don't need a cos(x) table because cos(x) = sin(90 - x) (for values of x in degrees). For our purposes here, since there are 16 directions: cos(direction) = sin(direction - 4). That is to say that the cosine value for a disc direction can be found by looking 4 entries earlier in this table (16 directions covers 360 degrees, so 4 directions covers 90 degrees).<br />
<br />
== Defining the three scanhand callbacks ==<br />
<br />
<pre>;; ======================================================================== ;;<br />
;; HIT_KEYPAD -- Someone hit a key on a keypad. ;;<br />
;; ======================================================================== ;;<br />
HIT_KEYPAD PROC<br />
JR R5<br />
ENDP<br />
<br />
;; ======================================================================== ;;<br />
;; HIT_ACTION -- Someone hit an action button ;;<br />
;; ======================================================================== ;;<br />
HIT_ACTION PROC<br />
JR R5<br />
ENDP</pre><br />
These two routines just return immediately when called. Basically, our game will do nothing on keypad presses or action button presses.<br />
<br />
That leaves the directional disc algorithm.<br />
<br />
When discussing the decoding of the information coming from scanhand, it is really kind of hard to make much sense without rewriting the documentation that comes in scanhand. When reading along with this part of the write-up, I suggest having the source code for scanhand.asm nearby. I'll be duplicating a small amount of what is written there just to make the tutorial simpler to follow, but there is a lot of good info in the comments in scanhand.asm.<br />
<br />
Here's the short version (put together from choice info in scanhand.asm). Our routine will be given a control word, from which we can determine what occured. It will look like this:<br />
<br />
<pre> 15 9 8 7 0<br />
+---------------------+-------+---+------------------------+<br />
| RESERVED |CTRL # |RLS| Input Number |<br />
+---------------------+-------+---+------------------------+</pre><br />
* The Input Number bit pattern will tell us what was pressed.<br />
* The RLS bit tells us if this is a &quot;press down&quot; or a &quot;release up&quot; event.<br />
* The CTRL # bits tell us which controller was pressed.<br />
<br />
On to the code.<br />
<br />
<pre>;; ======================================================================== ;;<br />
;; HIT_DISC -- Someone hit a directional disc ;;<br />
;; ======================================================================== ;;<br />
HIT_DISC PROC<br />
PSHR R5</pre><br />
The standard saving of R5 onto the stack so we know where to return.<br />
<br />
<pre> ANDI #$FF, R2 ; Ignore controller number</pre><br />
scanhand puts the control word into R2. For our demo, we don't care about left vs. right controller, so we'll just wipe out the top half of the word - that includes the RESERVED area as well as the two controller number bits.<br />
<br />
<pre> CMPI #$80, R2<br />
BLT @@pressed</pre><br />
Here we'll check the RLS bit to see if this is a &quot;press down&quot; event. If it is, we should process movement one way; if this is a &quot;release up&quot; event, we'll do something different. The logic for release is coming next, we'll branch to @@pressed for a disc press.<br />
<br />
<pre> CLRR R0<br />
MVO R0, PLYR.TXV<br />
MVO R0, PLYR.TYV<br />
PULR PC</pre><br />
In the event of a disc release, we'll set our target velocity to zero in both the X and Y directions. If the player releases the disc, he is indicating a desire to stop movement. That's all we need to do in the case of a release, so we use PULR PC to bail out of this routine immediately.<br />
<br />
The next chunk of code takes the direction the player is pressing on the directional disc and sets the X and Y target velocity values accordingly. Line by line, it goes like this:<br />
<br />
<pre>@@pressed: MOVR R2, R1</pre><br />
Make a copy of the direction data (in R1). We'll use this copy for the cosine value.<br />
<br />
<pre> ADDI #4, R1</pre><br />
Adjust the R1 (cosine pointer) by 4 entries in the sine table. Again, that works because cos(x) = sin(90 - x).<br />
<br />
<pre> ANDI #$F, R1</pre><br />
If we moved off the end of the 16 values in the sine table, this operation handles the wrap-around because of the way that binary numbers work in this case. (clever!)<br />
<br />
<pre> ADDI #SINTBL,R2 ; sine pointer</pre><br />
R2 contains the POSITION in the table of sine values for the value that we care about. By adding the base address of the table itself, we get a memory pointer to the sine value we want.<br />
<br />
<pre> ADDI #SINTBL,R1 ; cosine pointer</pre><br />
Do the same as above for R1 (the cosine value).<br />
<br />
<pre> MVI@ R2, R2 ; sine for our direction</pre><br />
Here we overwrite the R2 value with the sine value we are fetching. Before this operation, R2 was pointing at the value we wanted, now it contains the value.<br />
<br />
<pre> MVI@ R1, R1 ; cosine for our direction</pre><br />
Again, the same for R1.<br />
<br />
<pre> NEGR R2</pre><br />
We negate the velocity value for sine just to make it consistent with the addressing scheme of the screen. Y values start at 0 at the top of the screen and get larger as you go down.<br />
<br />
<pre> MVO R2, PLYR.TYV ; Set our target Y velocity to sine</pre><br />
And finally, take the computed target Y velocity (really just the adjusted lookup value from the sine table) and stick it into our data structure.<br />
<br />
<pre> MVO R1, PLYR.TXV ; Set our target X velocity to cosine</pre><br />
Again, the same for R1 - this time for the X velocity.<br />
<br />
<pre> PULR PC<br />
ENDP</pre><br />
End procedure as normal.<br />
<br />
That routine really only computed a current &quot;target velocity.&quot; So we know what the player is attempting to do by looking at PLYR.TXV and PLYR.TYV. We'll make changes to our MOB_UPDATE function that will incorporate those values and move the player on the screen.<br />
<br />
== Positioning the player ==<br />
<br />
<pre>;; ======================================================================== ;;<br />
;; MOB_UPDATE -- This updates the player's position ;;<br />
;; ======================================================================== ;;<br />
MOB_UPDATE PROC<br />
PSHR R5</pre><br />
This procedure opening should look very familiar.<br />
<br />
<pre> ;; ------------------------------------------------------------ ;;<br />
;; Bring our actual velocity closer to our target velocity, ;;<br />
;; and apply the velocity to our position. ;;<br />
;; ------------------------------------------------------------ ;;</pre><br />
As can be seen from this comment, we're going to do the math necessary to bring our current velocity closer to the target that we've computed in the scanhand call-back routine. The approach we'll take here will be to compute the difference between the target velocity and the current velocity, then adjust the velocity towards the target by 1/4 of that difference. That way the speed of the player adjusts in a way that is noticeable in gameplay.<br />
<br />
The first chunk deals with the X direction.<br />
<br />
<pre> MVI PLYR.TXV, R0<br />
SUB PLYR.XV, R0</pre><br />
Put the target velocity into R0, then subtract the actual velocity. R0 will now contain the difference between them.<br />
<br />
<pre> SARC R0</pre><br />
SARC is shift right, which effects a divide by 2. It also shifts the right-most bit into the carry flag. In terms of the math, that works just fine except for the case when the difference is very small, i.e. only 1. When we SARC the value of 1 (computing 1/2), we'll get 0 left in our register as our value to adjust by, and that will mean that the actual velocity will never really converge on the target velocity. So in that case, we'll just add that 1 back to our register as a way of rounding that 1/2 value back up.<br />
<br />
However if the value is negative we don't want to add one back for the rounding effect. We'll just let that value fall away (rounding down).<br />
<br />
<pre> BMI @@nr0</pre><br />
BMI branches on &quot;minus&quot; which skips over the add carry. This is the rounding down effect for a negative number.<br />
<br />
<pre> ADCR R0</pre><br />
Here we're adding the 1 back to our number -- rounding up.<br />
<br />
<pre>@@nr0 SARC R0<br />
BMI @@nr1<br />
ADCR R0</pre><br />
And these three instructions do it all again, making our adjustment 1/4 of the overall difference we computed.<br />
<br />
<pre>@@nr1 ADD PLYR.XV, R0<br />
MVO R0, PLYR.XV<br />
ADD PLYR.XP, R0<br />
MVO R0, PLYR.XP</pre><br />
Now we add this computed difference to the player X velocity, and then add that velocity value to the player's X position. So we now have a new position for the player that is reflective of how the player has pressed the directional disc!<br />
<br />
<pre> MVI PLYR.TYV, R0<br />
SUB PLYR.YV, R0<br />
SARC R0<br />
BMI @@nr2<br />
ADCR R0<br />
@@nr2 SARC R0<br />
BMI @@nr3<br />
ADCR R0<br />
@@nr3 ADD PLYR.YV, R0<br />
MVO R0, PLYR.YV<br />
ADD PLYR.YP, R0<br />
MVO R0, PLYR.YP</pre><br />
And there is a second set of identical operations for the Y velocity.<br />
<br />
== And the rest... ==<br />
<br />
The rest of the routine hasn't changed from the last tutorial part. We just changed out how we calculated the positions and our rendering of the player graphic is exactly the same.<br />
<br />
== Wrapping it up ==<br />
<br />
<pre>;; ======================================================================== ;;<br />
;; LIBRARY INCLUDES ;;<br />
;; ======================================================================== ;;<br />
INCLUDE &quot;print.asm&quot; ; PRINT.xxx routines<br />
INCLUDE &quot;fillmem.asm&quot; ; CLRSCR/FILLZERO/FILLMEM<br />
INCLUDE &quot;memcpy.asm&quot; ; MEMCPY<br />
INCLUDE &quot;hexdisp.asm&quot; ; HEX16/HEX12<br />
INCLUDE &quot;scanhand.asm&quot; ; SCANHAND<br />
INCLUDE &quot;timer.asm&quot; ; Timer-based task stuff<br />
INCLUDE &quot;taskq.asm&quot; ; RUNQ/QTASK</pre><br />
The library includes.<br />
<br />
=== Build it and try it! ===<br />
<br />
You should now be able to move the character around the screen via the hand controllers.<br />
<br />
== That's it! ==<br />
<br />
We're really close to having this demo fully functional. With the player moving around, we really only need to add code to programmatically move Todd.</div>Rickreynolds