// =======================================
//  Spinner / Atari Driving Controller Code Example
//
//  C.Malcolm 2017
//
// C translation gtoal 2025
// =======================================

#include <vectrex.h>

struct cartridge_t {
  char copyright[11];        // copyright string, must start with "g GCE" and must end with "\x80"
  const void* music;         // 16 bit memory adress of title music data
  signed int title_height;   // signed 8 bit value, height of game title letters
  unsigned int title_width;  // unsigned 8 bit value, width of game title letters
  int title_y;               // signed 8 bit value, y coordinate of game title
  int title_x;               // signed 8 bit value, x coordinate of game title
  char title[13];            // game title string, must end with "\x80" only
  signed int title_height2;  // signed 8 bit value, height of game title letters
  unsigned int title_width2; // unsigned 8 bit value, width of game title letters
  int title_y2;              // signed 8 bit value, y coordinate of game title
  int title_x2;              // signed 8 bit value, x coordinate of game title
  char title2[13];           // game title string, must end with "\x80"
};

const struct cartridge_t game_header __attribute__((section(".cartridge"), used)) = {
	.copyright        = "g GCE 2017\x80",    // change year if necessary, do not change "g GCE"
	.music            = &Vec_Music_1,        // taken from included headers
	.title_height     = -8,
	.title_width      = 80,
	.title_y          = 96,
	.title_x          = -80,
	.title            = "SPINNER TEST\x80",  // note that \x00 is automatically appended!
	.title_height2    = -8,
	.title_width2     = 80,
	.title_y2         = -80,
	.title_x2         = -80,
	.title2           = "g C.MALCOLM\x80"    // note that \x00 is automatically appended!
};

//#include "ospin.h"
static const int oSpin_0[]  = { 0,32,0,-1,-48,-32,-1,16,32,-1,-16,32,-1,48,-32,1};
static const int oSpin_1[]  = { 0,32,-3,-1,-51,-27,-1,19,30,-1,-13,33,-1,45,-37,1};
static const int oSpin_2[]  = { 0,31,-6,-1,-53,-22,-1,22,28,-1,-9,35,-1,41,-41,1};
static const int oSpin_3[]  = { 0,31,-9,-1,-55,-17,-1,25,26,-1,-6,35,-1,37,-45,1};
static const int oSpin_4[]  = { 0,30,-12,-1,-57,-11,-1,27,23,-1,-3,36,-1,32,-48,1};
static const int oSpin_5[]  = { 0,28,-15,-1,-57,-6,-1,29,21,-1,1,36,-1,27,-51,1};
static const int oSpin_6[]  = { 0,27,-18,-1,-58,0,-1,31,18,-1,4,35,-1,22,-53,1};
static const int oSpin_7[]  = { 0,25,-20,-1,-57,6,-1,33,15,-1,8,35,-1,17,-55,1};
static const int oSpin_8[]  = { 0,23,-23,-1,-57,11,-1,34,11,-1,11,34,-1,11,-57,1};
static const int oSpin_9[]  = { 0,20,-25,-1,-55,17,-1,35,8,-1,15,33,-1,6,-57,1};
static const int oSpin_10[] = { 0,18,-27,-1,-53,22,-1,35,4,-1,18,31,-1,0,-58,1};
static const int oSpin_11[] = { 0,15,-28,-1,-51,27,-1,36,1,-1,21,29,-1,-6,-57,1};
static const int oSpin_12[] = { 0,12,-30,-1,-48,32,-1,36,-3,-1,23,27,-1,-11,-57,1};
static const int oSpin_13[] = { 0,9,-31,-1,-45,37,-1,35,-6,-1,26,25,-1,-17,-55,1};
static const int oSpin_14[] = { 0,6,-31,-1,-41,41,-1,35,-9,-1,28,22,-1,-22,-53,1};
static const int oSpin_15[] = { 0,3,-32,-1,-37,45,-1,33,-13,-1,30,19,-1,-27,-51,1};
static const int oSpin_16[] = { 0,0,-32,-1,-32,48,-1,32,-16,-1,32,16,-1,-32,-48,1};
static const int oSpin_17[] = { 0,-3,-32,-1,-27,51,-1,30,-19,-1,33,13,-1,-37,-45,1};
static const int oSpin_18[] = { 0,-6,-31,-1,-22,53,-1,28,-22,-1,35,9,-1,-41,-41,1};
static const int oSpin_19[] = { 0,-9,-31,-1,-17,55,-1,26,-25,-1,35,6,-1,-45,-37,1};
static const int oSpin_20[] = { 0,-12,-30,-1,-11,57,-1,23,-27,-1,36,3,-1,-48,-32,1};
static const int oSpin_21[] = { 0,-15,-28,-1,-6,57,-1,21,-29,-1,36,-1,-1,-51,-27,1};
static const int oSpin_22[] = { 0,-18,-27,-1,0,58,-1,18,-31,-1,35,-4,-1,-53,-22,1};
static const int oSpin_23[] = { 0,-20,-25,-1,6,57,-1,15,-33,-1,35,-8,-1,-55,-17,1};
static const int oSpin_24[] = { 0,-23,-23,-1,11,57,-1,11,-34,-1,34,-11,-1,-57,-11,1};
static const int oSpin_25[] = { 0,-25,-20,-1,17,55,-1,8,-35,-1,33,-15,-1,-57,-6,1};
static const int oSpin_26[] = { 0,-27,-18,-1,22,53,-1,4,-35,-1,31,-18,-1,-58,0,1};
static const int oSpin_27[] = { 0,-28,-15,-1,27,51,-1,1,-36,-1,29,-21,-1,-57,6,1};
static const int oSpin_28[] = { 0,-30,-12,-1,32,48,-1,-3,-36,-1,27,-23,-1,-57,11,1};
static const int oSpin_29[] = { 0,-31,-9,-1,37,45,-1,-6,-35,-1,25,-26,-1,-55,17,1};
static const int oSpin_30[] = { 0,-31,-6,-1,41,41,-1,-9,-35,-1,22,-28,-1,-53,22,1};
static const int oSpin_31[] = { 0,-32,-3,-1,45,37,-1,-13,-33,-1,19,-30,-1,-51,27,1};
static const int oSpin_32[] = { 0,-32,0,-1,48,32,-1,-16,-32,-1,16,-32,-1,-48,32,1};
static const int oSpin_33[] = { 0,-32,3,-1,51,27,-1,-19,-30,-1,13,-33,-1,-45,37,1};
static const int oSpin_34[] = { 0,-31,6,-1,53,22,-1,-22,-28,-1,9,-35,-1,-41,41,1};
static const int oSpin_35[] = { 0,-31,9,-1,55,17,-1,-25,-26,-1,6,-35,-1,-37,45,1};
static const int oSpin_36[] = { 0,-30,12,-1,57,11,-1,-27,-23,-1,3,-36,-1,-32,48,1};
static const int oSpin_37[] = { 0,-28,15,-1,57,6,-1,-29,-21,-1,-1,-36,-1,-27,51,1};
static const int oSpin_38[] = { 0,-27,18,-1,58,0,-1,-31,-18,-1,-4,-35,-1,-22,53,1};
static const int oSpin_39[] = { 0,-25,20,-1,57,-6,-1,-33,-15,-1,-8,-35,-1,-17,55,1};
static const int oSpin_40[] = { 0,-23,23,-1,57,-11,-1,-34,-11,-1,-11,-34,-1,-11,57,1};
static const int oSpin_41[] = { 0,-20,25,-1,55,-17,-1,-35,-8,-1,-15,-33,-1,-6,57,1};
static const int oSpin_42[] = { 0,-18,27,-1,53,-22,-1,-35,-4,-1,-18,-31,-1,0,58,1};
static const int oSpin_43[] = { 0,-15,28,-1,51,-27,-1,-36,-1,-1,-21,-29,-1,6,57,1};
static const int oSpin_44[] = { 0,-12,30,-1,48,-32,-1,-36,3,-1,-23,-27,-1,11,57,1};
static const int oSpin_45[] = { 0,-9,31,-1,45,-37,-1,-35,6,-1,-26,-25,-1,17,55,1};
static const int oSpin_46[] = { 0,-6,31,-1,41,-41,-1,-35,9,-1,-28,-22,-1,22,53,1};
static const int oSpin_47[] = { 0,-3,32,-1,37,-45,-1,-33,13,-1,-30,-19,-1,27,51,1};
static const int oSpin_48[] = { 0,0,32,-1,32,-48,-1,-32,16,-1,-32,-16,-1,32,48,1};
static const int oSpin_49[] = { 0,3,32,-1,27,-51,-1,-30,19,-1,-33,-13,-1,37,45,1};
static const int oSpin_50[] = { 0,6,31,-1,22,-53,-1,-28,22,-1,-35,-9,-1,41,41,1};
static const int oSpin_51[] = { 0,9,31,-1,17,-55,-1,-26,25,-1,-35,-6,-1,45,37,1};
static const int oSpin_52[] = { 0,12,30,-1,11,-57,-1,-23,27,-1,-36,-3,-1,48,32,1};
static const int oSpin_53[] = { 0,15,28,-1,6,-57,-1,-21,29,-1,-36,1,-1,51,27,1};
static const int oSpin_54[] = { 0,18,27,-1,0,-58,-1,-18,31,-1,-35,4,-1,53,22,1};
static const int oSpin_55[] = { 0,20,25,-1,-6,-57,-1,-15,33,-1,-35,8,-1,55,17,1};
static const int oSpin_56[] = { 0,23,23,-1,-11,-57,-1,-11,34,-1,-34,11,-1,57,11,1};
static const int oSpin_57[] = { 0,25,20,-1,-17,-55,-1,-8,35,-1,-33,15,-1,57,6,1};
static const int oSpin_58[] = { 0,27,18,-1,-22,-53,-1,-4,35,-1,-31,18,-1,58,0,1};
static const int oSpin_59[] = { 0,28,15,-1,-27,-51,-1,-1,36,-1,-29,21,-1,57,-6,1};
static const int oSpin_60[] = { 0,30,12,-1,-32,-48,-1,3,36,-1,-27,23,-1,57,-11,1};
static const int oSpin_61[] = { 0,31,9,-1,-37,-45,-1,6,35,-1,-25,26,-1,55,-17,1};
static const int oSpin_62[] = { 0,31,6,-1,-41,-41,-1,9,35,-1,-22,28,-1,53,-22,1};
static const int oSpin_63[] = { 0,32,3,-1,-45,-37,-1,13,33,-1,-19,30,-1,51,-27,1};

static const int *oSpin[] = {
 oSpin_0,  oSpin_1,  oSpin_2,  oSpin_3,  oSpin_4,  oSpin_5,  oSpin_6,  oSpin_7,
 oSpin_8,  oSpin_9,  oSpin_10, oSpin_11, oSpin_12, oSpin_13, oSpin_14, oSpin_15,
 oSpin_16, oSpin_17, oSpin_18, oSpin_19, oSpin_20, oSpin_21, oSpin_22, oSpin_23,
 oSpin_24, oSpin_25, oSpin_26, oSpin_27, oSpin_28, oSpin_29, oSpin_30, oSpin_31,
 oSpin_32, oSpin_33, oSpin_34, oSpin_35, oSpin_36, oSpin_37, oSpin_38, oSpin_39,
 oSpin_40, oSpin_41, oSpin_42, oSpin_43, oSpin_44, oSpin_45, oSpin_46, oSpin_47,
 oSpin_48, oSpin_49, oSpin_50, oSpin_51, oSpin_52, oSpin_53, oSpin_54, oSpin_55,
 oSpin_56, oSpin_57, oSpin_58, oSpin_59, oSpin_60, oSpin_61, oSpin_62, oSpin_63
};
// end of ospin.h

static const int  tblSpin[4] = { 0,3,1,2 };
static const int  tblSpin0[4] = { 0,1,0,-1 }, tblSpin1[4] = { -1,0,1,0 },
                  tblSpin2[4] = { 0,-1,0,1 }, tblSpin3[4] = { 1,0,-1,0 };
static const int *tblSpinPrev[4] = {tblSpin0,tblSpin1,tblSpin2,tblSpin3};

int spinCurrent, spinPrevious, spinDCurrent, spinDPrevious; // current/previous value/direction
int spinVal; // rotation

void Read_Spinner(void) {
  spinPrevious = spinCurrent; // save last vals
  spinDPrevious = spinDCurrent;
  Read_Btns();
  spinCurrent = tblSpin[(Vec_Btn_State&0xC0 /*filter - only buttons 1+2*/)>>4]; // get from table using button state
  spinDCurrent = tblSpinPrev[spinPrevious][spinCurrent];
  spinVal = (spinVal-spinDCurrent)&63;
}

int main(void) {
  spinVal = spinCurrent = spinPrevious = spinDCurrent = spinDPrevious = 0; // init vals

  {
    register unsigned int A = 8, B = 0;
    Sound_Byte(A++,B);  // set ch1 vol (mute)
    Sound_Byte(A++,B);  // set ch2 vol (mute)
    Sound_Byte(A,B);    // set ch3 vol (mute)
  }

  Read_Btns(); //read buttons

  for (;;) {

    Wait_Recal();
    Read_Spinner(); // (do this often to catch transitions)

    Intensity_7F(); // full beam
    Vec_Pattern = 0xFF; // set line pattern
    Read_Spinner();

    VIA_t1_cnt_lo = 127; // set scale
    Reset0Ref();
    Print_Str_hwyx((void *)&game_header.title_height);
    Read_Spinner();

    // draw spinner
    VIA_t1_cnt_lo = 127; // set scale
    Reset0Ref();
    Moveto_dd(0);
    Draw_VL_mode(oSpin[spinVal]); // get frame
    Read_Spinner();
  }
}
