martes, 8 de octubre de 2013

steampong

steampong is about two cats playing pong in kind of a steampunk universe.
usb powered, 8x8 led matrix, with extra cats that celebrates.

--*--* imgs











--*--*video


--*--* code:

// -*- STEAM_PONG:
//     two cats playing pong with potentiometers.
//    
/*
 -*- MAIN
 10 inicio
 20 leer movimiento
     21 filtrar (dentro de paredes)
 30 mover paletas
 40 mover bola
 50 dibujar
 60 return
*/

/***************************************\
 * scene(8x8 matrix):
 * 0 - - - - - - - -
 *   - - - - - - - -
 *   - - - - + - - -
 *   + - - - - - - -
 *   + - - - - - - +
 *   - - - - - - - +
 *   - - - - - - - -
 * 7 - - - - - - - -
 *   0             7  <-scene[0..7]
 \***************************************/


volatile unsigned char framebuffer_pos = 0x00;
volatile unsigned char scene[8]; // a char for each column

volatile signed char o_x, o_y;          // ball x & y positions
volatile signed char o_dx, o_dy;        // ball x & y directions
volatile signed char i1_p, i2_p;        // players positions
volatile signed char redraw, speed_counter, current_speed;    // 1 if must redraw; increasing speed as game goes on; actual speed; and score.
const char speed_bumper = 10;    // increase speed after this cycles
//const unsigned char d1[] = {0x00, 0x10, 0x20, 0x7f, 0x00}; /* the number 1 */
//const unsigned char d2[] = {0x47, 0x49, 0x49, 0x49, 0x31}; /* the number 2 */

signed char ctrl01, ctrl02, analog_val01, analog_val02, ant_analog_val01, ant_analog_val02, aux_portB, aux_portC, i,j, aux_a, aux_b;
signed char suelta, rebote_paleta, pos;
unsigned int k;                  // counter
unsigned char period=30;         // period <- can control velocity with this

/* *************************************** */
/* *************************************** */

void set_ports()
  // initialize control registers and ports
  {
  ADCON1 = 0x00;   // portA is full analog
  TRISA  = 0xFF;   // portA is input
  TRISB = 0x00;    // portB is ROWS
  PORTB = 0x00;    // initialize portB
  TRISC = 0x00;    // portC is COLUMNS
  PORTC = 0xFF;    // initialize portC
  }

void read_controls()
  // read analog_val and compares with ant_analog_val
  // sets ctrl01 and ctrl02 according to difference
  {
  analog_val01 = Adc_Read(0)>>6; // it needs just 4 msb
  analog_val02 = Adc_Read(1)>>6;
 
  aux_a = analog_val01 - ant_analog_val01;
  aux_b = analog_val02 - ant_analog_val02;

  if (aux_a == 0) ctrl01 = 0;
  else ctrl01 = (aux_a > 0) ? 1 : -1;
  if (aux_b == 0) ctrl02 = 0;
  else ctrl02 = (aux_b > 0) ? 1 : -1;
 
  ant_analog_val01 = analog_val01;
  ant_analog_val02 = analog_val02;
  }

void mover_paletas()
  // actualiza posición de las paletas en función de ctrl0X
  // 1 : inc y, scene <<
  // -1: dec y, scene >>
  // 0 : keep
  {
  if (ctrl01 == 1)
    {
    if (i1_p < 6)
      {
      i1_p++;
      scene[0] = scene[0]<<1;
      }
    }
  if (ctrl01 == -1)
    {
    if (i1_p > 0)
      {
      i1_p--;
      scene[0] = scene[0]>>1;
      }
    }
  if (ctrl01 == 0)
    {
    i1_p = i1_p;
    }

  if (ctrl02 == 1)
    {
    if (i2_p < 6)
      {
      i2_p++;
      scene[7] = scene[7]<<1;
      }
    }
  if (ctrl02 == -1)
    {
    if (i2_p > 0)
      {
      i2_p--;
      scene[7] = scene[7]>>1;
      }
    }
  if (ctrl02 == 0)
    {
    i2_p = i2_p;
    }
  }


void init_scene()
  {
  scene[0] = 0b00011000;    // player 01
  scene[1] = 0b00000000;    //
  scene[2] = 0b00010000;    //
  scene[3] = 0b00000000;    //
  scene[4] = 0b00000000;    //
  scene[5] = 0b00000000;    //
  scene[6] = 0b00000000;    //
  scene[7] = 0b00011000;    // player 02
  i1_p = 3;                 // positions of p1
  i2_p = 3;                 // positions of p2
  o_x = 2;                  // ball x coo
  o_y = 4;                  // ball y coo
  o_dx = 1;                 // ball x dir
  o_dy = 0;                 // ball y dir
  }

void show_scene()
  {
  for (i=0; i<8; i++)       // columns x
    {
    aux_portB = scene[i];   //   put the row vector in column i
    PORTB = aux_portB;      //   set the ports
    if (i==0)               //     initialize
      {aux_portC = 1;}
    else                    //     shift previous val
      {aux_portC = aux_portC << 1;}
    PORTC = ~aux_portC;
    Delay_ms(1);
    }
  }

void point_for_one()
  {
  volatile unsigned char catscene[28] = {0x00, 0x18, 0x24, 0x00,
                                         0x04, 0x02, 0x14, 0x00,
                                         0x20, 0x20, 0x00, 0x14,
                                         0x02, 0x04, 0x00, 0x24,
                                         0x18, 0x00, 0x20, 0x1C,
                                         0x00, 0x04, 0x0A, 0x00,
                                         0x00, 0x00, 0x00, 0x00};
  unsigned int d;
  for (d=0; d<24;d++)
    {
    j = 0;
    while(j<10)
      {
      for (i=d; i<d+8; i++)       // columns x
        {
        aux_portB = catscene[i];   //   put the row vector in column i
        PORTB = aux_portB;      //   set the ports
        if (i==d)               //     initialize
          {aux_portC = 1;}
        else                    //     shift previous val
          {aux_portC = aux_portC << 1;}
        PORTC = ~aux_portC;
        Delay_ms(1);
        }
      j++;
      }
    }
  init_scene();
  }

void point_for_two()
  {
  volatile unsigned char catscene[28] = {0x00, 0x18, 0x24, 0x00,
                                         0x04, 0x02, 0x14, 0x00,
                                         0x20, 0x20, 0x00, 0x14,
                                         0x02, 0x04, 0x00, 0x24,
                                         0x18, 0x00, 0x20, 0x1C,
                                         0x00, 0x0A, 0x04, 0x00,
                                         0x00, 0x00, 0x00, 0x00};
  unsigned int d;
  for (d=0; d<24; d++)
    {
    j = 0;
   
    while(j<10)
      {
      for (i=d; i<d+8; i++)         // columns x
        {
        aux_portB = catscene[i];   //   put the row vector in column i
        PORTB = aux_portB;         //   set the ports
        if (i==d) aux_portC = 1;   //     initialize
        else aux_portC = aux_portC << 1; //     shift previous val
        PORTC = ~aux_portC;
        Delay_ms(1);
        }
      j++;
      }
    }
  init_scene();
  }


void mover_bola()
  // mover bola en función de dx, dy, i1_p, i2_p
  //   41 si golpea pared: pared()
  //   42 si golpea paleta: casos{esquina_up, esquina_dn, simple}
  //   43 si bola suelta: casos{win01, win02, simple}
  {
  // pared
  if (o_y == 0) o_dy = -o_dy;
  if (o_y == 7) o_dy = -o_dy;
 
  // golpe_paleta
  suelta = 0;
  rebote_paleta = 0;
  pos = (o_x == 1) ? i1_p : i2_p;
  if (o_x == 1 || o_x == 6)            // detecta x
    {
    suelta = 1;
    if (o_y == pos || o_y == pos+1)    // rebote normal
      {
      o_dx = -o_dx;
      suelta = 0;
      rebote_paleta = 1;
      }
    else if (o_y == pos-1 && o_dy == 1)// esquina_up
      {
      o_dx = -o_dx;
      o_dy = -o_dy;
      suelta = 0;
      rebote_paleta = 1;
      }
    else if (o_y == pos+2 && o_dy == -1)//esquina_dn
      {
      o_dx = -o_dx;
      o_dy = -o_dy;
      suelta = 0;
      rebote_paleta = 1;
      }
    }
 
  // suelta
  if (suelta)
    {
    if (o_x == 1)                      // *point for 2!
      {
      o_x += o_dx;
      o_y += o_dy;
      point_for_two();
      }
    else                               // *point for 1!
      {
      o_x += o_dx;
      o_y += o_dy;
      point_for_one();
      }
    }
 
  //si fue rebote en paleta ajusta direcciones
  if (rebote_paleta)
      {
      if (o_x == 1 && (ctrl01 == 1)  && (o_dy <  1)) o_dy++;
      if (o_x == 1 && (ctrl01 == -1) && (o_dy > -1)) o_dy--;
      if (o_x == 6 && (ctrl02 == 1)  && (o_dy <  1)) o_dy++;
      if (o_x == 6 && (ctrl02 == -1) && (o_dy > -1)) o_dy--;
      }
   
  // si hay pared después de rebote
  if (o_y == 0 && o_dy == -1) o_dy = -o_dy;
  if (o_y == 7 && o_dy ==  1) o_dy = -o_dy;

  // y finalmente mueve la bolita
  o_x += o_dx;
  o_y += o_dy;
  scene[1]=0x00; scene[2]=0x00; scene[3]=0x00;
  scene[4]=0x00; scene[5]=0x00; scene[6]=0x00;
  scene[o_x] = 0x01<<o_y;
  }


/* *************************************** */
// MAIN

/* *************************************** */

void main()
  {
  // SETUP
  set_ports();
 
  ant_analog_val01 = Adc_Read(0)>>6;
  ant_analog_val02 = Adc_Read(1)>>6;
  init_scene();                  // 10 init

  // LOOP
  while (1)
    {
    read_controls();             // 20 read controls
    mover_paletas();             // 30 mover paletas
    mover_bola();                // 40 mover bola
   
    for (k=0; k<=period; k++)    // 50 dibujar por un rato
      {
      show_scene();
      }
    }
  }

No hay comentarios.:

Publicar un comentario