// THIS IS CURRENTLY UNDER DEVELOPMENT!  Don't expect to see much
// happening right now.  At the moment I'm just testing the intro
// sequence, so it does not start the game play!

void Reinitialise_nearly_everything(void); // except 'First_player_was'

#define HUMAN 1
#define COMPUTER 2
#define MESSAGE_Y (0)   // centerline of messages.

#ifdef PIZERO
#include <stdio.h>
#include <stdlib.h>
#include <pitrex/pitrexio-gpio.h>
#include <vectrex/vectrexInterface.h>
extern int optimizationON; // 0 force Reset0Ref on every line  1 optimise.
#undef MAX

FILE *logfile = NULL;

#define INFTY 30000
typedef short int16_t;
typedef short INTEGER;
typedef signed char int8_t;
typedef unsigned char uint8_t;

// These procedures approximate the Vectrex (6809) routines as used in Vide
// and allow us to run the same code on 32 bit ARM as we do on the 6809.

// This will let us add more useful diagnostics.

static int8_t current_intensity = 0x7F;
static int8_t current_scale = 0x7f;
static int8_t current_buttons = 0;
static int Pos_X = 0, Pos_Y = 0;

static inline void Wait_Recal(void) {
  v_WaitRecal();
}
static inline void Moveto_d(int8_t y, int8_t x) { // rel
  Pos_X += x*current_scale; Pos_Y += y*current_scale;
}
static inline void Draw_Line_d(int8_t y, int8_t x) { // rel
  v_directDraw32(Pos_X, Pos_Y, Pos_X + x*current_scale, Pos_Y + y*current_scale, current_intensity);
  Pos_X += x*current_scale; Pos_Y += y*current_scale;
}
static inline void Reset0Ref(void) {
  Pos_X = 0; Pos_Y = 0;
}
static inline void Intensity_7F(void) {
  v_setBrightness(current_intensity = 0x7F);
}
static inline void Intensity_a(int8_t A) {
  v_setBrightness(current_intensity = A);
}
static inline void Print_Str_d(int8_t y, int8_t x, char *ends_x80) {
  v_printStringRaster(x,y,ends_x80, 80, -9, 0x80);
}

void Draw_VLp(int8_t *list) {
  for (;;) {
    switch (*list) {
    case -1: // linetorel
      v_directDraw32(Pos_X, Pos_Y, Pos_X + list[2]*current_scale, Pos_Y + list[1]*current_scale, current_intensity);
      Pos_X += list[2]*current_scale; Pos_Y += list[1]*current_scale;
      break;
    case 0: // movetorel
      Pos_X += list[2]*current_scale; Pos_Y += list[1]*current_scale;
      break;
    case 1:
      return;
    }
    list += 3;
  }
}

// Not the same algorithm as the Vectrex Random() but doesn't matter for our
// purposes since the calls to Random() are timing-dependent.
uint8_t _x = 12;
uint8_t _a = 34;
uint8_t _b = 56; 
uint8_t _c = 78; 

static inline void initRandom(uint8_t s1, uint8_t s2, uint8_t s3, uint8_t x0) {
  _x = x0;
  _a = s1; _b = s2; _c = s3;
  _x++;
  _a = (_a^_c^_x); _b = (_b+_a); _c = ((_c+(_b>>1))^_a);
}

static inline uint8_t Random(void)
{
  _x++; _a = (_a^_c^_x); _b = (_b+_a); _c = ((_c+(_b>>1))^_a);
  return _c;
}

static int8_t Vec_Joy_1_X = 0, Vec_Joy_1_Y = 0;
static inline void Joy_Digital(void) { // must be called on each frame
  v_readJoystick1Digital();
  Vec_Joy_1_X = currentJoy1X;
  Vec_Joy_1_Y = currentJoy1Y;
}

static inline void Read_Btns(void) {
  v_readButtons();
  current_buttons = currentButtonState;
#if defined(DIAGNOSTICS) && DIAGNOSTICS == 2
  if (current_buttons & 0x1) {
    Intensity_7F();
    Print_Str_d(-128,-16, "1  \x80");
  }
  if (current_buttons & 0x2) {
    Intensity_7F();
    Print_Str_d(-128,-8, "2  \x80");
  }
  if (current_buttons & 0x4) {
    Intensity_7F();
    Print_Str_d(-128,0, "3  \x80");
  }
  if (current_buttons & 0x8) {
    Intensity_7F();
    Print_Str_d(-128,8, "4  \x80");
  }
#endif
}

static inline int8_t buttons_pressed (void) {
  //static int8_t bit[5] = { 0x88, 0x44, 0x22, 0x11, 0xFF };
  return current_buttons;
}

static int8_t button_1_1_held (void) {
#if defined(DIAGNOSTICS) && DIAGNOSTICS == 2
  if (current_buttons & 0x1) {
    Intensity_7F();
    Print_Str_d(-118,-16, "1  \x80");
  }
#endif
  return current_buttons & 0x1;
}

static int8_t button_1_2_held (void) {
#if defined(DIAGNOSTICS) && DIAGNOSTICS == 2
  if (current_buttons & 0x2) {
    Intensity_7F();
    Print_Str_d(-118,-8, "2  \x80");
  }
#endif
  return current_buttons & 0x2;
}

static int8_t button_1_3_held (void) {
#if defined(DIAGNOSTICS) && DIAGNOSTICS == 2
  if (current_buttons & 0x4) {
    Intensity_7F();
    Print_Str_d(-118,0, "3  \x80");
  }
#endif
  return current_buttons & 0x4;
}

static int8_t button_1_4_held (void) {
#if defined(DIAGNOSTICS) && DIAGNOSTICS == 2
  if (current_buttons & 0x8) {
    Intensity_7F();
    Print_Str_d(-118,8, "4  \x80");
  }
#endif
  return current_buttons & 0x8;
}

static inline void enable_controller_1_x (void) {
}

static inline void enable_controller_1_y (void) {
}

#else

#define INFTY 30000L
typedef long int16_t;
typedef long INTEGER;
typedef int int8_t;
typedef unsigned int uint8_t;

#endif