shithub: m8c

ref: 2e61bdb89a80d84475f81de711069624424cf355
dir: /command.c/

View raw version

#include <stdio.h>
#include <string.h>

#include "command.h"
#include "render.h"

#define DEBUG 1

// Convert 2 little-endian 8bit bytes to a 16bit integer
static uint16_t decodeInt16(uint8_t *data, uint8_t start) {
  return data[start] | (uint16_t)data[start + 1] << 8;
}

enum m8_command_bytes {
  draw_rectangle_command = 0xFE,
  draw_rectangle_command_datalength = 12,
  draw_character_command = 0xFD,
  draw_character_command_datalength = 12,
  draw_oscilloscope_waveform_command = 0xFC,
  draw_oscilloscope_waveform_command_mindatalength = 1 + 3,
  draw_oscilloscope_waveform_command_maxdatalength = 1 + 3 + 320,
  joypad_keypressedstate_command = 0xFB,
  joypad_keypressedstate_command_datalength = 2
};

static inline void dump_packet(uint32_t size, uint8_t *recv_buf) {
  for (uint16_t a = 0; a < size; a++) {
    fprintf(stderr, "0x%02X ", recv_buf[a]);
  }
  fprintf(stderr, "\n");
}

void process_command(uint8_t *data, uint32_t size) {

  uint8_t recv_buf[size + 1];

  memcpy(recv_buf, data, size);
  recv_buf[size] = 0;

  switch (recv_buf[0]) {

  case draw_rectangle_command:

    if (size != draw_rectangle_command_datalength) {
      fprintf(stderr,
              "Invalid draw rectangle packet: expected length %d, got %d\n",
              draw_rectangle_command_datalength, size);
      dump_packet(size, recv_buf);
      break;
    }

    struct draw_rectangle_command rectcmd = {
        {decodeInt16(recv_buf, 1), decodeInt16(recv_buf, 3)}, // position x/y
        {decodeInt16(recv_buf, 5), decodeInt16(recv_buf, 7)}, // size w/h
        {recv_buf[9], recv_buf[10], recv_buf[11]}};           // color r/g/b

    draw_rectangle(&rectcmd);

    break;

  case draw_character_command:

    if (size != draw_character_command_datalength) {
      fprintf(stderr,
              "Invalid draw character packet: expected length %d, got %d\n",
              draw_character_command_datalength, size);
      dump_packet(size, recv_buf);
      break;
    }

    struct draw_character_command charcmd = {
        recv_buf[1],                                          // char
        {decodeInt16(recv_buf, 2), decodeInt16(recv_buf, 4)}, // position x/y
        {recv_buf[6], recv_buf[7], recv_buf[8]},    // foreground r/g/b
        {recv_buf[9], recv_buf[10], recv_buf[11]}}; // background r/g/b
    draw_character(&charcmd);

    break;

  case draw_oscilloscope_waveform_command:

    if (size < draw_oscilloscope_waveform_command_mindatalength ||
        size > draw_oscilloscope_waveform_command_maxdatalength) {
      fprintf(stderr,
              "Invalid draw oscilloscope packet: expected length between %d "
              "and %d, got "
              "%d\n",
              draw_oscilloscope_waveform_command_mindatalength,
              draw_oscilloscope_waveform_command_maxdatalength, size);
      dump_packet(size, recv_buf);
      break;
    }

    struct draw_oscilloscope_waveform_command osccmd;

    osccmd.color =
        (struct color){recv_buf[1], recv_buf[2], recv_buf[3]}; // color r/g/b
    memcpy(osccmd.waveform, &recv_buf[4], size - 4);

    osccmd.waveform_size = size - 4;

    draw_waveform(&osccmd);

    break;

  case joypad_keypressedstate_command:

    if (size != joypad_keypressedstate_command_datalength) {
      fprintf(stderr,
              "Invalid joypad keypressed state packet: expected length %d, "
              "got %d\n",
              joypad_keypressedstate_command_datalength, size);
      dump_packet(size, recv_buf);
      break;
    }

    // nothing is done with joypad key pressed packets for now

    break;

  default:

    fprintf(stderr, "Invalid packet\n");
    dump_packet(size, recv_buf);

    break;
  }
}