<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tummai Games &#187; controller</title>
	<atom:link href="http://www.tummaigames.com/blog/tag/controller/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.tummaigames.com/blog</link>
	<description>NES homebrew! Development blog for homebrew NES games</description>
	<lastBuildDate>Tue, 16 Mar 2010 13:23:53 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Ramses Game: 2 &#8211; Reading NES Button Combinations</title>
		<link>http://www.tummaigames.com/blog/2010/02/14/ramses-game-2-reading-nes-button-combinations/</link>
		<comments>http://www.tummaigames.com/blog/2010/02/14/ramses-game-2-reading-nes-button-combinations/#comments</comments>
		<pubDate>Sun, 14 Feb 2010 15:42:15 +0000</pubDate>
		<dc:creator>Thomas</dc:creator>
				<category><![CDATA[Ramses Game]]></category>
		<category><![CDATA[button combinations]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[controller]]></category>
		<category><![CDATA[dpad]]></category>
		<category><![CDATA[input]]></category>

		<guid isPermaLink="false">http://www.tummaigames.com/blog/?p=219</guid>
		<description><![CDATA[In Ramses Game, monsters pop out of holes and the player needs to whack them.  There are only 8 buttons on the NES controller, really 7 if you reserve Start for pausing the game.  This means that if I want more than 7 holes, I need to assign the holes to combinations of [...]]]></description>
			<content:encoded><![CDATA[<p>In <strong>Ramses Game</strong>, monsters pop out of holes and the player needs to whack them.  There are only 8 buttons on the <strong>NES controller</strong>, really 7 if you reserve Start for pausing the game.  This means that if I want more than 7 holes, I need to assign the holes to combinations of buttons rather than individual buttons.</p>
<p>To me the most obvious way to do this is to look for combinations like <strong>up+A</strong>, <strong>down+A</strong>, <strong>left+A</strong>, <strong>right+A</strong>.  Even if I reserve the Start button for pausing, that still leaves me with 12 combinations (4 each for A, B and Select).  12 holes is plenty for this kind of game, and actually due to screen space limitations I&#8217;ve decided to limit myself to 10 holes.</p>
<p><strong>Detecting button combinations on the NES</strong> is a little bit tricky.  I don&#8217;t want to allow the player to hold down B and spam the dpad to hit many holes very quickly.  Also, if the player presses up+left at the same time while pressing B, I don&#8217;t want two holes to be hit simulataneously.  On the other hand, it would be unreasonable to expect the player to hit two buttons at once in the exact same frame.  Nobody is that fast.  So I have to allow some leeway.  With that in mind, here is how my Button Combo routine works.</p>
<h2>Button Combo Routine</h2>
<h3>Output</h3>
<p>My button combo routine takes what the user has pressed and outputs a value 0-12.  The output possibilities are laid out like this:</p>
<ul>
<li>0: no combination was pressed.</li>
<li>1-4: B+dpad was pressed (in order: up, down, left, right)</li>
<li>5-8: A+dpad</li>
<li>9-12: Select+dpad</li>
</ul>
<p>Each of these values is mapped to a hole, and I use the outputted value to index into hole-related tables.  For example, here is a table that I use to determine if a valid hole was whacked:</p>
<pre>
<code>valid_holes:
    .byte 0             ;unused (no combo)
    .byte 1, 1, 1, 1    ;B (up, down, left, right order)
    .byte 1, 1, 1, 1    ;A
    .byte 1, 1, 0, 0    ;Select
    .byte 0, 0, 0       ;unused (select+left, select+right unused)</code>
</pre>
<p>I have tables for attribute table PPU addresses and the like as well.</p>
<h3>Input</h3>
<p>When I read the controller every frame, I store two sets of data in RAM.  One is the current button states (pressed or not pressed), which I store in a variable called <em>joypad1</em>.  The other is off-to-on transitions, ie what was unpressed last frame but is pressed this frame.  Off-to-on transitions are stored in a variable called <em>joypad1_pressed</em>.</p>
<p>Each variable is one byte, basically a bitflag with each bit corresponding to a button.  My controller reading routine stores button information in this order:</p>
<pre>
<code>joypad1 and joypad1_pressed bits:

76543210
||||||||
|||||||+- right
||||||+-- left
|||||+--- down
||||+---- up
|||+----- start
||+------ select
|+------- B
+-------- A</code>
</pre>
<h3>Logic</h3>
<p>The first thing I do in my button combo routine is to check if A, B or select is pressed.  If not, obviously we can&#8217;t have a combo, so skip to the end.</p>
<pre>
<code>;---------------------------------------------------
; check for dpad+button combos
.proc check_combos
    lda joypad1
    and #%11100000      ;isolate A, B, select
    beq @somewhere_near_the_end
    ;....snip</code>
</pre>
<p>If a button is pressed, I want to grab its combo value and store it in RAM:</p>
<pre>
<code>.proc check_combos
    lda joypad1
    and #%11100000      ;isolate A, B, select
    beq @clear_btn_val  ;if not pressed, clear btn_val
    lda joypad1_pressed
    and #%11100000      ;if off_to_on, we need to set the flag, else skip to dpad check
    beq @check_dpad
@set_btn_val:
    asl                 ;shift the A button bit to the CF
    bcc @B
    lda #$05            ;if A bit is set, store 5 in btn_flag  (5, 6, 7, 8 = A combo)
    bne @store
@B:
    asl                 ;shift the B button bit to the CF
    bcc @Select
    lda #$01            ;else if B bit is set, store 1 in btn_flag (1, 2, 3, 4 = B combo)
    bne @store
@Select:
    lda #$09            ;else Select bit must be set, so store 9 in btn_flag (9, 10, 11, 12 = Select combo)
@store:
    sta btn_val         ;add dpad value to this to get index
@check_dpad:
    ;.....snip

@clear_btn_val:
    lda #$00
    sta btn_val
@end:
    rts
.endproc
    </code>
</pre>
<p>Notice that I check if the button is newly pressed or if it was held from last frame.  This check is for a special case.  Say the user is holding A.  Then say a monster they want to smack appears in the up+B hole.  The player will press up+B, but there is a chance that there will be several frames of A+B as the player slides their thumb from A to B.  I want to catch the newest button press (B), not the older one (A).  So I check <em>joypad1_pressed</em>.  If a button is newly pressed this frame, I set btn_val.  If not, I skip straight to the dpad (btn_val having been set in a previous frame).</p>
<p>To say it another way, I only alter the value of btn_val in two cases: when a new button is pressed, or when no buttons are pressed.  This is important for another case too, which I will get to in a moment.</p>
<p>Note that if on the off-chance that B, A or Select are newly pressed simultaneous in the same frame, A takes precedence over B, which takes precedence over Select.  Not going to happen often, and when it does it&#8217;s not a big deal &#8211; the player will know they mashed both buttons.</p>
<p>Finally we check the dpad to complete the combo:</p>
<pre>
<code>@check_dpad:
    lda btn_val
    beq @end            ;if A, B, Select not pressed, no combo
    lda joypad1
    and #%00001111      ;isolate dpad
    beq @end            ;if no arrows pressed, no combo
    tay
    lda dpad_add, y     ;else, grab arrow value from table (up = 0, down=1, left=2, right=3)
    clc
    adc btn_val         ;add arrow value to button value.  Results in a number 1-12
    sta joypad1_combo
    jsr do_button_combo
@clear_btn_val:
    lda #$00
    sta btn_val
@end:
    rts</code>
</pre>
<p>First thing I check is if btn_val is 0.  But if we made it this far, shouldn&#8217;t this be non-zero?  The player is definitely holding down either A, B or Select afterall.  Yes they are, but btn_val could still be zero.  After a button combo is registered, I process the combo via do_button_combo and then I clear btn_val.  This check for btn_val == 0 covers the case that a button combination was recently processed (say last frame), but the player hasn&#8217;t released the buttons yet.  It took me some bug-hunting before I realized I needed this check.  Button Combinations are tricky, aren&#8217;t they?</p>
<p>The rest is pretty straightforward.  I check the dpad.  If no arrow is pressed, there is no combo so I return.  If an arrow is pressed, I grab its value from a table and add it to btn_val to get the final combo value.  The reason for the dpad_add table is to protect against cases of multiple arrows being pressed at the same time.  If up+left is pressed, for example, I resolve it to up.  If left+right is pressed, I resolve it to left.  If you&#8217;re curious, my table looks like this:</p>
<pre>
<code>;this table maps each possible d-pad combination to a single d-pad direction
;   0 = up, 1 = down, 2  = left, 3 = right
dpad_add:
    .byte 0     ;unused (will never be read)
    .byte 3     ;r -&gt; right
    .byte 2     ;l -&gt; left
    .byte 2     ;r+l -&gt; left
    .byte 1     ;d -&gt; down
    .byte 1     ;d+r -&gt; down
    .byte 1     ;d+l -&gt; down
    .byte 1     ;d+r+l -&gt; down
    .byte 0     ;u -&gt; up
    .byte 0     ;u+r -&gt; up
    .byte 0     ;u+l -&gt; up
    .byte 0     ;u+r+l -&gt; up
    .byte 0     ;u+d -&gt; up
    .byte 0     ;u+d+r -&gt; up
    .byte 0     ;u+d+l -&gt; up
    .byte 0     ;u+d+r+l -&gt; up</code>
</pre>
<p>Having this in table form makes it easy to modify in the future if I need to tweak some of the values (poor right arrow gets overruled a lot, doesn&#8217;t he?).  If you want to know more about this technique, I have written about <a href="http://www.tummaigames.com/blog/2009/07/24/explorer-8-sprite-direction/">protecting against odd dpad combinations using tables</a> before.</p>
<p>That&#8217;s it.  It&#8217;s a little complicated but it works.  I haven&#8217;t optimized this routine, so it&#8217;s possible that I could improve it somehow.  I&#8217;d rather move forward though, since this works fine the way it is.</p>
<p>Incidentally, the player is allowed to hold a dpad arrow and spam A/B/Select.  Doing so is of such limited use that I don&#8217;t see it being abusive.  If testing reveals otherwise though, I&#8217;ll rewrite the routine to protect against that.</p>
<h2>Full Routine</h2>
<p>Here&#8217;s the full routine in case anyone wants to copy/paste it into their game.  If you do, I will feel really happy if you mention me in the credits somewhere. :)</p>
<pre>
<code>;---------------------------------------------------
; check for dpad+button combos
.proc check_combos
    lda joypad1
    and #%11100000      ;isolate A, B, select
    beq @clear_btn_val  ;if not pressed, clear btn_val
    lda joypad1_pressed
    and #%11100000      ;if off_to_on, we need to set the flag, else skip to dpad check
    beq @check_dpad
@set_btn_val:
    asl                 ;shift the A button bit to the CF
    bcc @B
    lda #$05            ;if A bit is set, store 5 in btn_flag  (5, 6, 7, 8 = A combo)
    bne @store
@B:
    asl                 ;shift the B button bit to the CF
    bcc @Select
    lda #$01            ;else if B bit is set, store 1 in btn_flag (1, 2, 3, 4 = B combo)
    bne @store
@Select:
    lda #$09            ;else Select bit must be set, so store 9 in btn_flag (9, 10, 11, 12 = Select combo)
@store:
    sta btn_val         ;add dpad value to this to get index
@check_dpad:
    lda btn_val
    beq @end            ;if A, B, Select not pressed, no combo
    lda joypad1
    and #%00001111      ;isolate dpad
    beq @end            ;if no arrows pressed, no combo
    tay
    lda dpad_add, y     ;else, grab arrow value from table (up = 0, down=1, left=2, right=3)
    clc
    adc btn_val         ;add arrow value to button value.  Results in a number 1-12
    sta joypad1_combo
    jsr do_button_combo
@clear_btn_val:
    lda #$00
    sta btn_val
@end:
    rts
.endproc

;this table maps each possible d-pad combination to a single d-pad direction
;   0 = up, 1 = down, 2  = left, 3 = right
dpad_add:
    .byte 0     ;unused
    .byte 3     ;r -&gt; right
    .byte 2     ;l -&gt; left
    .byte 2     ;r+l -&gt;left
    .byte 1     ;d -&gt; down
    .byte 1     ;d+r -&gt; down
    .byte 1     ;d+l -&gt; down
    .byte 1     ;d+r+l -&gt; down
    .byte 0     ;u -&gt; up
    .byte 0     ;u+r -&gt; up
    .byte 0     ;u+l -&gt; up
    .byte 0     ;u+r+l -&gt; up
    .byte 0     ;u+d -&gt; up
    .byte 0     ;u+d+r -&gt; up
    .byte 0     ;u+d+l -&gt; up
    .byte 0     ;u+d+r+l -&gt; up</code>
</pre>
<h2>Conclusion</h2>
<p>So button combinations are done with, and if you watched the video embedded in the <a href="http://www.tummaigames.com/blog/2010/02/11/ramses-game-1-introduction/">last post</a> you will see that they work quite well!  This game is really coming along.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tummaigames.com/blog/2010/02/14/ramses-game-2-reading-nes-button-combinations/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Button Combos, Sound Engines and Scopes</title>
		<link>http://www.tummaigames.com/blog/2010/02/08/button-combos-sound-engines-and-scopes/</link>
		<comments>http://www.tummaigames.com/blog/2010/02/08/button-combos-sound-engines-and-scopes/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 17:06:51 +0000</pubDate>
		<dc:creator>Thomas</dc:creator>
				<category><![CDATA[NES]]></category>
		<category><![CDATA[code cleanup]]></category>
		<category><![CDATA[controller]]></category>
		<category><![CDATA[input]]></category>
		<category><![CDATA[scope]]></category>
		<category><![CDATA[sound engine]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.tummaigames.com/blog/?p=208</guid>
		<description><![CDATA[It&#8217;s been a while since I posted here.  I took a break from my homebrew to write some tutorials on how to code a sound engine for the NES.  You can find them here: NES Sound Tutorials.
After a long break I finally got back to some homebrew coding.  I worked in 6502 [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I posted here.  I took a break from my homebrew to write some tutorials on how to code a <strong>sound engine</strong> for the <strong>NES</strong>.  You can find them here: <a href="http://nintendoage.com/forum/messageview.cfm?catid=22&#038;threadid=7155">NES Sound Tutorials</a>.</p>
<p>After a long break I finally got back to some homebrew coding.  I worked in <strong>6502</strong> for a few hours today.  I didn&#8217;t work on <a href="http://www.tummaigames.com/blog/category/development/nes/explorer/">Explorer</a>, but rather a different game project that is less ambitious.  I&#8217;ll introduce the game properly in a future post.</p>
<h2>What I Did Today</h2>
<h3>Button Combos</h3>
<p>One thing that I needed for the new game project was a way to detect <strong>button combinations</strong> like up+A or right+B &#8211; the kind that you use to select plays in TecmoBowl.  It was a little tricky to pull off.  For one thing, if the player presses something like up+left+A, I need to resolve that to either up+A or left+A.  I need to work that out for all possible combinations of button presses.  This includes taking care of cases where A+B are pressed at the same time.</p>
<p>Another issue is with <strong>holding buttons</strong>.  If the player holds B down and makes circles around the dpad, I only want it to catch the first combination.  To do two combos in a row, they should release the B button and press it again.  But what if the player hits up+B, and then while still holding B they press A+left?  Does the holding of B stop the 2nd combination from being picked up or not?  There are a lot of possible cases since the controller reading routine is called 60 times per second.  The player can&#8217;t control their input on a frame-by-frame scale.  Sliding from B to A might very well contain several frames (fraction of a second) where both buttons are held down before the B button is released.  Not impossible to solve, but it wasn&#8217;t as straightforward as I had expected.</p>
<h3>Sound Engine</h3>
<p>Another thing I did today was port my sound engine to <a href="http://www.cc65.org/doc/ca65.html">ca65</a>.  I wrote my <a href="http://nintendoage.com/forum/messageview.cfm?catid=22&#038;threadid=7155">NES sound tutorials</a> for the <strong>NESASM</strong> assembler.  My tutorials are a continuation of another set of tutorials which use NESASM and I wanted to stay consistent.  Plus most new nesdevers start with NESASM as it is very newbie-friendly.</p>
<p>My tutorial sound engine was an improvement over the one I had previously written in ca65, so I wanted to replace the old with the new.  So I spent some time today porting my sound engine from NESASM to ca65.  I was sure everything was going to break as soon as I got all the syntax converted.  But it didn&#8217;t!  Once I got it to assemble it worked perfectly on the first try!  That was a relief.</p>
<h3>Scopes</h3>
<p>ca65 lets you define <strong>scopes</strong>.  Scopes enable you to keep parts of your program hidden from the other parts of your program.  It&#8217;s good to separate modules, especially in large programs, so that you don&#8217;t have variable conflicts and the like.  These bugs are the hardest to trace in assembly language.</p>
<p>I didn&#8217;t use scopes before because I didn&#8217;t really know how.  But I found a great thread on <a href="http://nesdev.parodius.com/bbs/viewtopic.php?t=5481">nesdev about ca65 scopes</a> that told me how to do it, so I spent some time today separating my sound and controller reading modules from the main program.  Everything feels much &#8230; cleaner now.  Like washing your hands after working outside on a summer day.  I can physically feel how much easier things are going to be in the future for me with scopes.</p>
<h2>New NES</h2>
<p>I bought an NES!  Ordered it on Yahoo Auctions on Saturday and it arrived at my house on Sunday!  All I need now is a <a href="http://www.retrousb.com/product_info.php?cPath=24&#038;products_id=34">PowerPak</a> and I can start testing my programs on real hardware.  I can&#8217;t wait!</p>
<p>I&#8217;m too lazy to upload pictures here, but you can see the ones I posted to twitter here:</p>
<p><a href="http://twitpic.com/11ucz8">My new NES 1</a><br />
<a href="http://twitpic.com/11udov">My new NES 2</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.tummaigames.com/blog/2010/02/08/button-combos-sound-engines-and-scopes/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
