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