Skip to content

Tutorial) 2. Getting Input

BtheDestroyer edited this page Jan 1, 2017 · 1 revision

Note: This tutorial is specifically geared towards beginners who have little to no programming experience. Because of this, a lot of simple stuff will be explained. These explanations will become more scarce as the tutorial goes on as every section expects the reader to have read everything prior to it, so repetition is not needed.

2.0. Input: Then and Now

Before we start dealing with player input, it should be noted that standard ctrulib methods can be used with SpriteTools, but they are a bit awkward when you have these new options. Here is an example of using ctrulib for input:

#include <3ds.h>
#include <spritetools.h>
#include <stdio.h>

int main(void)
{
  ST_Init();
  while (aptMainLoop())
  {
    consoleInit(GFX_TOP, NULL);
    u32 kHeld = hidKeysHeld();
    if (kHeld & KEY_A)
      printf("\x1b[0;0HA is pressed");
    else
      printf("\x1b[2J");
  }
  ST_Fini();
  return 0;
}
#include <3ds.h>
#include <spritetools.h>
#include <stdio.h>

int main(void)
{
  ST_Init();
  while (aptMainLoop())
  {
    consoleInit(GFX_TOP, NULL);
    ST_InputScan()
    if (ST_InputButtonDown(KEY_A))
      printf("\x1b[0;0HA is pressed");
    else
      printf("\x1b[2J");
  }
  ST_Fini();
  return 0;
}

The difference seems slight, but when dealing with multiple different buttons being pressed and touchscreen input etc. SpriteTools should have everything you need from ctrulib (including gyroscope and accelerometer 👍).

2.1. Buttons

Let's make our character from the debugger tutorial D-Pad controlled. First, we need to scan all inputs using ST_InputScan(). Next, we can use the functions ST_InputButtonPressed(u32 key), ST_InputButtonDown(u32 key) and ST_InputButtonReleased(u32 key) to detect when a button was just pressed, is currently held, or was just released respectively. In our case, we want 4 if statements to replace our current ones to move our character and one replacement to exit the program. We will also need an if statement before we print our character to ensure it is on screen. Our while loop should now look like this

while (aptMainLoop())
{
  consoleInit(GFX_TOP, NULL);
  ST_InputScan();
  if (ST_InputButtonDown(KEY_DUP))
    linkY--;
  if (ST_InputButtonDown(KEY_DDOWN))
    linkY++;
  if (ST_InputButtonDown(KEY_DLEFT))
    linkX--;
  if (ST_InputButtonDown(KEY_DRIGHT))
    linkX++;
  if (ST_InputButtonPressed(KEY_START))
    break;

  if (linkY > 0 && linkX > 0 && linkY < 30 && linkX < 50)
    printf("\x1b[%d;%dHL", linkY, linkX);

  consoleInit(GFX_BOTTOM, NULL);
  ST_DebugDisplay();
}

make and run your program and you should have your character's position controlled by the D-Pad buttons and Start should close out your program.

See ctrulib's documentation for a full list of key macros.

2.2. Touch Screen

You may have already noticed that because we are now scanning inputs, the debugger's touch screen information is updating when there is a touch. It is displaying the following information using the following functions:

Debugger Function Description
Current (1st num) ST_InputTouchX() X position currently being touched on the touchscreen
Current (2nd num) ST_InputTouchY() Y position currently being touched on the touchscreen
Origin (1st num) ST_InputTouchOriginX() X position where the current touch started on the touchscreen
Origin (2nd num) ST_InputTouchOriginY() Y position where the current touch started on the touchscreen
Dist ST_InputTouchDistance() Diagonal distance between the current and origin positions
ST_InputTouchDistanceX() Horizontal distance between the current and origin positions
ST_InputTouchDistanceY() Vertical distance between the current and origin positions
Len ST_InputTouchLength() Length of the shape being drawn on the touch screen

Using these functions we can display another set of characters using the touch's positions like this:

if (ST_InputTouchX() != -1)
  printf("\x1b[%d;%dHT", ST_InputTouchY() / 8, ST_InputTouchX() / 8 + 5);

if (ST_InputTouchOriginX() != -1)
  printf("\x1b[%d;%dHS", ST_InputTouchOriginY() / 8,
    ST_InputTouchOriginX() / 8 + 5);

Touch characters

Our final code should look like this:

#include <3ds.h>
#include <spritetools.h>
#include <stdio.h>

int main(void)
{
  int linkX = 5;
  int linkY = 5;

  ST_Init();
  ST_DebugSetOn();
  ST_DebugAddVar("Link X",(void *)&linkX, INT);
  ST_DebugAddVar("Link Y",(void *)&linkY, INT);
  while (aptMainLoop())
  {
    consoleInit(GFX_TOP, NULL);
    ST_InputScan();
    if (ST_InputButtonDown(KEY_DUP))
      linkY--;
    if (ST_InputButtonDown(KEY_DDOWN))
      linkY++;
    if (ST_InputButtonDown(KEY_DLEFT))
      linkX--;
    if (ST_InputButtonDown(KEY_DRIGHT))
      linkX++;
    if (ST_InputButtonPressed(KEY_START))
      break;

    if (linkY > 0 && linkX > 0 && linkY < 30 && linkX < 50)
      printf("\x1b[%d;%dHL", linkY, linkX);

    if (ST_InputTouchX() != -1)
      printf("\x1b[%d;%dHT", ST_InputTouchY() / 8, ST_InputTouchX() / 8 + 5);

    if (ST_InputTouchOriginX() != -1)
      printf("\x1b[%d;%dHS", ST_InputTouchOriginY() / 8,
        ST_InputTouchOriginX() / 8 + 5);

    consoleInit(GFX_BOTTOM, NULL);
    ST_DebugDisplay();
  }
  ST_Fini();
  return 0;
}

2.3. Other Input Functions

You can also get other inputs using the following functions:

Function Description
ST_InputCirclePadX() Returns X of the circle pad
ST_InputCirclePadY() Returns Y of the circle pad
ST_InputAccel() Returns the Accelerometer Vector as an accelVector
ST_InputAccelX() Returns the X of the Accelerometer Vector
ST_InputAccelY() Returns the Y of the Accelerometer Vector
ST_InputAccelZ() Returns the Z of the Accelerometer Vector
ST_InputGyro() Returns the Gyroscope's Angular Rate as an angularRate
ST_InputGyroRoll() Returns roll of the Gyroscope's Angular Rate
ST_InputGyroYaw() Returns yaw of the Gyroscope's Angular Rate
ST_InputGyroPitch() Returns pitch of the Gyroscope's Angular Rate