lunes, 14 de octubre de 2013

Anarchist [7x5 led matrix shooter]

The anarchist must be kept safe from the waves of pigs who want to capture him, by throwing molotov cocktails.
LED 7x5 Matrix controlled by a PIC16F876A + joystick and button, powered by USB or 4 AA cased in a little plastic box.

-*-* Photos













*-*- Code

// -*- ANARCHIST:
//     the A-guy is surrounded by the pigs. help him be free.
//


/*
-*- MAIN
 10 inicio
 20 leer movimiento
    21 filtrar (dentro de paredes)
 30 mover chico
    31 dibujar
 40 leer disparo
    41 ejecutar rutina de disparo
    42 destruir cerdos afectados
 60 victoria?
 70 verificar avance de cerdos
 80 derrota?
 90 return


-*-* SCENE
* y0 - - o o o
*    - - o o o
*    - - o o -
*    + - - o o
*    - - o o o
*    - - - - o
* y6 - - - - o
*   x0      x4  <-scene[0..4]

 \***************************************/


volatile unsigned char scene[5];         // a char for each column
volatile signed char a_p;                // anarchist position
volatile signed char cuenta_ciclos;      // for increasing speed as game goes on;
signed char ctrl, movimiento_x,  movimiento_y, ref_x, ref_y, aux_row, aux_col, i, j, a, b, sh, jp;
unsigned int k;                          // counter
signed char disparo, salto, movimiento, collision, victoria, captura;    // FLGS
unsigned char buffer, period_dif, period_ref;         // period <- can control velocity with this
unsigned int score;
/* *************************************** */
/* *************************************** */

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 ONE  (verde)
  PORTC = 0xFF;    // initialize portC
  }

void read_controls()
  // read analog_val and compares with prev_analog_val
  // sets ctrl01 and ctrl02 according to difference
  {
  a = Adc_Read(0)>>6; // it needs just 4 msb
  if ((a - ref_x) == 0){movimiento_x = 0;}
  else { movimiento_x = (a - ref_x)>0 ? 1: -1; }
  b = Adc_Read(1)>>6; // it needs just 4 msb
  if ((b - ref_y) == 0){movimiento_y = 0;}
  else { movimiento_y = (b - ref_y)>0 ? 1: -1; }

  sh = Adc_Read(2)>>4;
  disparo = (sh > 0) ? 1 : 0;
  jp = Adc_Read(3)>>4;
  salto = (jp > 0) ? 1 : 0;
  }


void show_scene()                        // HOW TO SHOW
  {
  for (i=0; i<=4; i++)       // each column as an array of x
    {
    aux_col = scene[i];     //   put the row vector in column i
    PORTB = aux_col;        //   set the ports
    if (i==0)               //     initialize
      {aux_row = 1;}
    else                    //     shift previous val
      {aux_row = aux_row << 1;}
    PORTC = ~aux_row;
    Delay_ms(1);
    }
  }


void mover_chico_x()
  // actualiza posición del anarquista en funcion del movimiento
  // 1 : inc y, scene[0] <<
  // -1: dec y, scene[0] >>
  // 0 : keep
  {
  if (movimiento_x == 1)
    {
    if (a_p < 6)
      {
      a_p++;
      scene[0] = scene[0]<<1;
      }
    }
  if (movimiento_x == -1)
    {
    if (a_p > 0)
      {
      a_p--;
      scene[0] = scene[0]>>1;
      }
    }
  if (movimiento_x == 0)
    {
    a_p = a_p;
    }
  }


void disparo_routine()
  {
  collision = 0;                                 // initialize
  victoria = 0;
  buffer = 1;
  for (j=0; j<5; j++)                       // sweep the scene
    {
    if (j==0) { show_scene(); }             // if a-guy col just show scene
    // A. shot_propagation_routine
    else
      {
      if ((scene[j] & scene[0]) == scene[0])// B. collision_routine
        {
        scene[j] = scene[j] ^ scene[0];     // i. scene with destruction
        show_scene;
        break;                              // break the for
        }
      else                                  // -*-*traspaso
        {
        buffer = scene[j];
        scene[j] = scene[j] | scene[0];     // i. combine the scene
        show_scene();
        scene[j] = buffer;
        }
      }
    }
  /*
  for (j=1; j<5 ;j++)
    {
    victoria = (victoria | scene[j]);
    }
  if (victoria == 0) {victoria = 1;}
  else {victoria = 0;}
  */
  }


void avance_tirania()
  {
  captura = 0;                                   // capture flag
  for(j=1; j<5; j++)
    {
    if ((j == 1) & (scene[j]!=0)) {captura = 1;} // you lose
    else;
    scene[j] = scene[j+1];                       // else shift policemen and reinforce
    if (j == 4) { scene[j] = 0x7F; }
    else;
    cuenta_ciclos = 0;
    }
  // if (captura == 1): you lose; else continue;
  }

void init_scene()
  {
  scene[0] = 0b00001000;    // here there is an anarchist
  scene[1] = 0b00000000;    //
  scene[2] = 0b00001000;    //
  scene[3] = 0b00011100;    //
  scene[4] = 0b00111110;    // and here the first line of pigs
  a_p = 3;                  // position of anarchy
  victoria = 0;
  disparo = 0;
  cuenta_ciclos = 0;
  period_dif=50;
  }

void victory_routine()
  {
  unsigned int d;
  // begins victory display
  scene[4] = 0x00;
  scene[3] = ((score<<8)>>9);
  scene[2] = 0x00;
  scene[1] = (score>>9);
  scene[0] = 0x00;
  for (d=0; d<200; d++) { show_scene(); }
  PORTC = 0xFF;
  Delay_ms(500);
  for (d=0; d<200; d++) { show_scene(); }
  // end of victory display
  // maintenance routines
  victoria = 0;
  Delay_ms(500);
  init_scene();
  score = 0;
  }

void capture_routine()
  {
  unsigned int d;
  // begins capture display
  scene[4] = 0x00;
  scene[3] = ((score<<8)>>9);
  scene[2] = 0x00;
  scene[1] = (score>>9);
  scene[0] = 0x00;
  for (d=0; d<200; d++) { show_scene(); }
  PORTC = 0xFF;
  Delay_ms(500);
  for (d=0; d<200; d++) { show_scene(); }
  // end of capture display
  // maintenance routines
  captura = 0;
  Delay_ms(500);
  init_scene();
  score = 0;
  }

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

void main()
  {
  // SETUP
  set_ports();
  ref_x = Adc_Read(0)>>6;
  ref_y = Adc_Read(1)>>6;
  period_dif=50;
  period_ref=12;
  score=0;
  init_scene();                  // 10 init

  // LOOP
  while (1)
    {
    read_controls();             // 20 read controls
    mover_chico_x();             // 30 mover anarquista

    if (disparo==1)              // 40 rutina arrojar_molotov
      {
      disparo_routine();
      }
    else;

    if (victoria==1)             // 50 rutina de la victoria
      {
      victory_routine();
      }
    else;

    if (cuenta_ciclos > period_dif)   // 60 avance de tirania
      {
      avance_tirania();
      score++;
      if (captura == 1)          // 70 rutina de captura
        {
        capture_routine();
        }
      else;
      }
    else;
    cuenta_ciclos++;
    if (((score << 11) >> 11) == 0x10 )
      {
      period_dif -= 1;
      }
    else;
    for (k=0; k<=period_ref; k++)    // 80 dibuja un rato
      {
      show_scene();
      }
    }
  }


*--**-- Video

No hay comentarios.:

Publicar un comentario