Skip to content

Working with the keyboard

This tutorial will guide you through creating a “TouchRectangle” demo for your Classpad calculator using C++. Even if you’re new to C development, we’ll take it step by step.

Step 1: Empty base

Start with the “Application Template”.

Go to your codespace and open the “main.cpp” file. Delete all of its content (Ctrl-a → Delete) and start by adding only the needed imports :

#include <appdef.hpp>
#include <sdk/calc/calc.hpp>
#include <sdk/os/input.hpp>
#include <sdk/os/lcd.hpp>
#include <sdk/os/debug.hpp>

Here, we’ll need:

  • input to manage the key and touchscreen events
  • lcd to draw on the screen
  • debug to do Debug_Printf when debugging your application

Final Code

You can drag a rectangle on screen and move it with the arrow keys. Use the “Clear” button to exit.

#include <appdef.hpp>
#include <sdk/calc/calc.hpp>
#include <sdk/os/debug.hpp>
#include <sdk/os/input.hpp>
#include <sdk/os/lcd.hpp>

APP_NAME("TouchRectangle")
APP_DESCRIPTION("Move a rectangle based on touch and key input.")
APP_AUTHOR("Your Name")
APP_VERSION("1.0.0")

#define COLOR_BACKGROUND RGB_TO_RGB565(0, 0, 0)
#define COLOR_RECTANGLE RGB_TO_RGB565(0x1F, 0, 0)

#define RECT_SIZE 20
#define MOVE_STEP 5

extern uint16_t *vram;
int lcdWidth, lcdHeight;
int rectX, rectY;

void drawRectangle(int x, int y, uint16_t color) {
  for (int i = x; i < x + RECT_SIZE; ++i) {
    for (int j = y; j < y + RECT_SIZE; ++j) {
      if (i >= 0 && i < lcdWidth && j >= 0 && j < lcdHeight) {
        vram[i + (j + 24) * lcdWidth] = color;
      }
    }
  }
}

void draw() {
  LCD_ClearScreen();
  drawRectangle(rectX, rectY, COLOR_RECTANGLE);
  LCD_Refresh();
}

void main() {
  LCD_VRAMBackup();
  vram = LCD_GetVRAMAddress();
  LCD_GetSize(&lcdWidth, &lcdHeight);

  rectX = lcdWidth / 2 - RECT_SIZE / 2;
  rectY = lcdHeight / 2 - RECT_SIZE / 2;

  struct InputEvent event;

  bool running = true;
  while (running) {
    draw();

    GetInput(&event, 0xFFFFFFFF, 0x10);

    switch (event.type) {
    case EVENT_TOUCH:
      if (event.data.touch_single.direction == TOUCH_DOWN ||
          event.data.touch_single.direction == TOUCH_HOLD_DRAG) {
        rectX = event.data.touch_single.p1_x;
        rectY = event.data.touch_single.p1_y;
      }
      break;

    case EVENT_KEY:
      switch (event.data.key.keyCode) {
        case KEYCODE_UP:
          rectY -= MOVE_STEP;
          break;
        case KEYCODE_RIGHT:
          rectX += MOVE_STEP;
          break;
        case KEYCODE_DOWN:
          rectY += MOVE_STEP;
          break;
        case KEYCODE_LEFT:
          rectX -= MOVE_STEP;
          break;
        case KEYCODE_POWER_CLEAR:
          running = false;
          break;
      }
      break;
    }

    // Ensure the rectangle stays within the screen boundaries
    if (rectX < 0)
      rectX = 0;
    if (rectY < 0)
      rectY = 0;
    if (rectX + RECT_SIZE > lcdWidth)
      rectX = lcdWidth - RECT_SIZE;
    if (rectY + RECT_SIZE > lcdHeight)
      rectY = lcdHeight - RECT_SIZE;
  }

  LCD_VRAMRestore();
  LCD_Refresh();
}