Time to take control

So far, we have concentrated on output – so you should now be comfortable with controlling the screen and creating and moving sprites around on the display. Fine for demos or exposition, but we’re not writing a presentation here, this is a game console. And what use is a game console without being able to interact with it.

The NGPC, as you should know if you’ve got this far, has a joystick, two action buttons and an option/start button. Compared to modern games consoles, it’s all a bit basic, but actually that makes your life as a developer a lot simpler. You only basically have seven inputs to deal with. No shoulder buttons, no touch screens, no analog controllers, just a joystick and three buttons.

In short, player interaction with the NGPC is pretty simple – it’s all exposed via the JOYPAD structure. This is simply an unsigned byte which contains a number – you can examine this with the following code – if you ran this and moved the joystick around you’ll see the numbers changing as you press buttons:

void main()
{
InitNGPC();
SysSetSystemFont();
ClearScreen(SCR_1_PLANE);
ClearScreen(SCR_2_PLANE);
SetBackgroundColour(RGB(0, 0, 0));
SetPalette(SCR_1_PLANE, 0, 0, 0, 0, RGB(15,15,15));

while(1)
{
 PrintDecimal(SCR_1_PLANE, 0, 4, 9, JOYPAD, 8);
} // never fall out of main!!!
}

These numbers equate to the contols as per the below image:

ngpcbuttons

So, if you press the joystick UP you should see the number change to 1, down becomes 2, left is 4, right is 8 etc. The fun begins if you press buttons together, if you press UP and button A, or move the joystick in a diagonal then you’ll see 3, or 9 or 17.

All this means is that the numbers are adding up – in coding terms, it’s a bitmap mask. Lets look at it a different way

NGPCButtonTable

These numbers can be added up – so if you press UP and A, you will get 0x11, UP, A & B all together would give you 0x31 etc. Importantly, you cannot get the same result by adding up different buttons (so 0x31 can ONLY be obtained by Up+A+B etc). Even it was possible to push every button simultaneously you would still get a unique code – 0xFF if you care. Okay smartase, it is possible, but only in emulation. Try it if you like.

So, how to deal with in code. That sort of depends on which kind of game you’re writing – at the most basic level, you probably want to move your “player” sprite around the screen using the joystick and use the A and B buttons to fire or jump or do some other actions.

The most basic way of dealing with input then is to use a binary AND (or &) operation and to check the JOYPAD structure against that, like the below snippet:

    if (JOYPAD & J_UP) 
    {
        iYpos--;
    }
    if (JOYPAD & J_DOWN)
    {
        iYpos++;
    }
    if (JOYPAD & J_LEFT)
    {
        iXpos--;
    }
    if (JOYPAD & J_RIGHT)
    {
        iXpos++;
    }
    if (JOYPAD & J_A)
    {
        PRINTSTRING(SCR_1_PLANE, 0, 4, 9, "FIRE");
    }

    if (JOYPAD & J_B)
    {
        PRINTSTRING(SCR_1_PLANE, 0, 4, 9, "BOMB");
    }

This would get you running, but there’s a few things you might – depending on the style of game you’re writing – need to keep an eye on. For instance, if you implement the above exactly as described, then your player would potentially be able to “fire” 60 times a second. Pretty neat, but could cause you problems. So, you might need to watch for the player releasing the button rather than pressing it, or check for a “first press”, or put a timer in place or… One way of doing this that I often use is to copy the JOYPAD structure and then compare the previous state with the current state – a bit like this:

    if (JOYPAD & J_A && !(prevJOYPAD & J_A))
    {
        PRINTSTRING(SCR_1_PLANE, 0, 4, 9, "FIRE");
    }

    if (JOYPAD & J_B && !(prevJOYPAD & J_B))
    {
        PRINTSTRING(SCR_1_PLANE, 0, 4, 9, "BOMB");
    }

    prevJOYPAD = JOYPAD;

 

The exact method you choose to deal with inputs is up to you, and even with only four directions and three action buttons, you still have lots of options – you might want to initiate a timer when one combination is pressed and give the player a time limit to get to the next combination for a sequence, you might indirectly control the player object with a velocity or power gauge rather than directly control the position. There really isn’t a “right” way to deal with input, as it all depends on what kind of game you’re writing… An RPG is different to a shooter is different to a card game is different to an RTS etc, but this should get you moving. Literally.
Next time. Make it pretty…
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s