#include <vectrex.h>
#include "controller.h"

static inline void set_scale(unsigned int s) {
  VIA_t1_cnt_lo = s;
}

static void sprintl(char *dest, long num) { // left-aligned
#define show_digit(x) *dest++ = (char)((x)+'0')
  int digit, zeroes;

  // This replaces code that used divide by 10 and modulo 10.  Much faster.

  // handles full 16 bit range of -32768:32767  -  Uses negative numbers to avoid the issue of negating -32768

  if (num >= 0) num = -num; else *dest++ = '-';
  digit = 0;
  zeroes = 1; // CLRing is shorter
  // max 11 add/subtracts...
  if (num <= -20000) { num += 20000; digit += 2; zeroes = 0; }
  if (num <= -10000) { num += 10000; digit += 1; zeroes = 0; }
  if (!zeroes) show_digit(digit);
  digit = 0;
  if (num <= -8000) { num += 8000; digit += 8; zeroes = 0; } else if (num <= -4000) { num += 4000; digit += 4; zeroes = 0; }
  if (num <= -2000) { num += 2000; digit += 2; zeroes = 0; }
  if (num <= -1000) { num += 1000; digit += 1; zeroes = 0; }
  if (!zeroes) show_digit(digit);
  digit = 0;
  if (num <= -800) { num += 800; digit += 8; zeroes = 0; } else if (num <= -400) { num += 400; digit += 4; zeroes = 0; }
  if (num <= -200) { num += 200; digit += 2; zeroes = 0; }
  if (num <= -100) { num += 100; digit += 1; zeroes = 0; }
  if (!zeroes) show_digit(digit);
  digit = 0;
  if (num <= -80) { num += 80; digit += 8; zeroes = 0; } else if (num <= -40) { num += 40; digit += 4; zeroes = 0; }
  if (num <= -20) { num += 20; digit += 2; zeroes = 0; }
  if (num <= -10) { num += 10; digit += 1; zeroes = 0; }
  if (!zeroes) show_digit(digit);
  show_digit((int)-num);
  show_digit(0x80-'0');
  show_digit(0-'0');
  //*dest = 0x80;
}

int main(void) {
  static char Text[85];
  static char Num[11];
  unsigned int textp = 2;
  unsigned int these_buttons = 0;
  unsigned int key = 0;

  Text[0] = Text[1] = ' '; Text[2] = 0x80; Text[3] = '\0';
  Num[0] = '0'; Num[1] = Num[2] = ' '; Num[3] = 0x80; Num[4] = '\0';
  enable_controller_1_x();
  enable_controller_1_y();

  // buttons to press in order to enter a character by hand, to check algorithm!

  //        \ \ \ \ \ \ \ 1
  //         \ \ \ \ 1 3 6 2
  //          1 2 4 8 6 2 4 8
  //  data W:  1 0 0 0 0 0 1 0
  // clock Q:   1 0 1 0 1 0 1 0 


  for (;;) {
    Wait_Recal();
    Joy_Analog ();
    Intensity_7F ();
    Reset0Ref (); 
    set_scale(127);
    Moveto_d(0,0);

    // When the strobe is asserted ((these_buttons & 16) != 0) the data bit is
    // already in place, as the data bit is always written first and then the strobe.

    Read_Btns (); these_buttons = buttons_held(); // start bit *not* in a loop so that
                                                  // screen doesn't blank...

    if ((these_buttons & 16) != 0) { // Rising edge - bit 0

      key = ((these_buttons&32U) ? 1U : 0);      // Wait for next trigger = falling edge - bit 1
      do { Read_Btns (); these_buttons = buttons_held(); } while ((these_buttons & 16) != 0);

      key |= ((these_buttons&32U) ? 2U : 0);      // Wait for next trigger = rising edge - bit 2
      do { Read_Btns (); these_buttons = buttons_held(); } while ((these_buttons & 16) == 0);

      key |= ((these_buttons&32U) ? 4U : 0);      // Wait for next trigger = falling edge - bit 3
      do { Read_Btns (); these_buttons = buttons_held(); } while ((these_buttons & 16) != 0);

      key |= ((these_buttons&32U) ? 8U : 0);      // Wait for next trigger = rising edge - bit 4
      do { Read_Btns (); these_buttons = buttons_held(); } while ((these_buttons & 16) == 0);

      key |= ((these_buttons&32U) ? 16U : 0);      // Wait for next trigger = falling edge - bit 5
      do { Read_Btns (); these_buttons = buttons_held(); } while ((these_buttons & 16) != 0);

      key |= ((these_buttons&32U) ? 32U : 0);      // Wait for next trigger = rising edge - bit 6
      do { Read_Btns (); these_buttons = buttons_held(); } while ((these_buttons & 16) == 0);

      key |= ((these_buttons&32U) ? 64U : 0);      // Wait for next trigger = falling edge - bit 7
      do { Read_Btns (); these_buttons = buttons_held(); } while ((these_buttons & 16) != 0);

      key |= ((these_buttons&32U) ? 128U : 0);

      if (key >= 'a' && key <= 'z') key = key - 'a' + 'A';

      if (key == 10 || key == 13) {
        textp = 2; Text[textp] = 0x80; Text[textp+1] = '\0';
      } else if ((key == 127 || key == 8) && (textp > 2)) {
        textp -= 1; Text[textp] = 0x80; Text[textp+1] = '\0';
      } else {
        if (textp == 80) {
          textp = 2;
        }
        Text[textp++] = key; Text[textp] = 0x80; Text[textp+1] = '\0';
      }

      sprintl(Num, (long)key);
    }
    Print_Str_d(-4, -120, Text);
    Print_Str_d(-32, -4, Num);
  }

  return 0;
}
