// Black and white NTSC video
generation with fixed point animation
// D.0 is sync
// D.1 is video
// Mega644 version by Shane Pryor
// mod by brl4@cornell.edu:
//
for mega1284
//
for resolution 160 horizontal x 200 vertical
//
plays a musical scale from port B.3
//
UART SPI-mode video output from Morgan D. Jones
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <math.h>
#include <util/delay.h>
#include <avr/sleep.h>
#include "app_fontset.h"
#include "functions.h"
//#include
"app_video_ball.h"
//#include "app_fix_math.h"
//#include "bsp_adc.h"
// optional, if preferred///
#define begin {
#define end }
////////////////////////////
//timeout values for each task
#define t1 200
#define t2 50
#define t3 50
#define t4 200
#define t5 50
#define t6 50
//State machine state names
#define NoPush 1
#define MaybePush 2
#define Pushed 3
#define MaybeNoPush 4
//cycles = 63.625 * 16 Note NTSC is
63.55
//but this line duration makes each
frame exactly 1/60 sec
//which is nice for keeping a
realtime clock
// video timing
#define LINE_TIME 1018 // 20 MHz 1271
#define SLEEP_TIME 999 // 20 MHz 1250
#define bytes_per_line 20
#define screen_width (bytes_per_line*8)
#define screen_height 200
#define screen_array_size screen_width*screen_height/8
#define right_wall 150
#define left_wall 49
#define right_wall_A 60
#define left_wall_A 0
#define right_wall_B 95
#define left_wall_B 156
#define ground 190
#define ground_tp 156
#define ScreenTop 30
#define ScreenBot (ScreenTop+screen_height)
#define maxkeys 16
#define PORTDIR DDRA
#define PORTDATA PORTA
#define PORTIN PINA
#define PORTDIRB DDRB
#define PORTDATAB PORTB
#define PORTINB PINB
#define right 20
#define down 30
#define left 40
#define cw 50
#define ccw 60
#define swap 70
char
str;
//uint8_t screen[screen_array_size];
//One bit masks
//uint8_t pos[8] =
{0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
int cri; //change to floats
int no_syl;
int syl_dur;
int sri;
int bf;
int dc;
int calc_val[8];
int index;
int cnt;
int fp;
//timeout value for LCD task
#define t2 100
// The raw keyscan
volatile unsigned char key, debounce_key, key1, keyB, debounce_keyB, key1B ;
// The decoded button number
unsigned char butnum = 2;
unsigned char butnumB = 2;
int enter;
int butval, butvalB;
unsigned char keytbl[16]={0xee, 0xed, 0xeb, 0xe7,
0xde, 0xdd, 0xdb, 0xd7,
0xbe, 0xbd, 0xbb, 0xb7,
0x7e, 0x7d, 0x7b, 0x77};
//sync
char syncON, syncOFF;
volatile unsigned char time1, time2, time3, time4, time5, time6; //timeout counters
unsigned char PushFlag = 0; //message indicating
a button push
unsigned char PushFlagB = 0;
unsigned char led; //LED count
unsigned char PushState = NoPush; //state machine
unsigned char PushStateB = NoPush;
//current line number in the current
frame
volatile int LineCount;
volatile int update_piece = 0;
volatile int timer1 = 0;
volatile int timer2 = 0;
volatile int timer3 = 0;
//volatile space s;
//160h x 160v - screen buffer and
pointer
//char screen[screen_array_size];
int* screenindex;
//One bit masks
//char pos[8] =
{0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
// Musical note values
// middle-C to C-above-middle-C
// zeros are rests
char notes[] = {150,132,117,112,100,89,79,75,0,0,0,0};
char note, musicT;
/*ISR (TIMER0_COMPA_vect)
begin
//Decrement the three times if they are not already zero
if (time1>0) --time1;
if (time2>0) --time2;
if (time3>0) --time3;
end
*/
// put the MCU to sleep JUST before
the CompA ISR goes off
ISR(TIMER1_COMPB_vect, ISR_NAKED)
{
sei();
sleep_cpu();
reti();
}
//==================================
//This is the sync generator and
raster generator. It MUST be entered from
//sleep mode to get accurate timing
of the sync pulses
ISR (TIMER1_COMPA_vect) {
int s, screenStart ;
//start the
Horizontal sync pulse
PORTD
= syncON;
//update the current
scanline number
LineCount++;
/* if (time1>0) --time1;
if (time2>0) --time2;
if (time3>0) --time3;
*/
//begin inverted
(Vertical) synch after line 247
if (LineCount==248) {
syncON = 0b00000001;
syncOFF = 0;
}
//back to regular
sync after line 250
if (LineCount==251) {
syncON
= 0;
syncOFF
= 0b00000001;
}
//start new frame after line 262
if (LineCount==263)
{
LineCount
= 1;
/*if (timer1 == 12
&& time1 > 0)
{
time1--;
timer1
= 0;
}
if
(timer2 == 3 && time2 > 0)
{
time2--;
timer2
= 0;
}
if
(timer2 == 3 && time3 > 0)
{
time3--;
timer3
= 0;
}*/
}
//adjust to make 5
us pulses
_delay_us(3);
//end sync pulse
PORTD
= syncOFF;
if (LineCount < ScreenBot && LineCount >= ScreenTop) {
//compute offset
into screen array
//screenindex =
screen + ((LineCount - ScreenTop) << 4) + ((LineCount - ScreenTop)
<< 3);
//compute offset
into screen array
//screenStart =
((LineCount - ScreenTop) << 4) + ((LineCount - ScreenTop) << 3) ;
screenStart
= (LineCount - ScreenTop) * bytes_per_line;
//center image on
screen
_delay_us(7);
//blast the data to
the screen
// We can load UDR
twice because it is double-bufffered
UDR0
= screen[screenStart] ;
UCSR0B
= _BV(TXEN0);
UDR0
= screen[screenStart+1] ;
for (s = 2; s < bytes_per_line; s++)
begin
while (!(UCSR0A & _BV(UDRE0))) ;
UDR0
= screen[screenStart+s] ;
end
UCSR0B
= 0 ;
}
}
//=== fixed conversion macros
=========================================
#define int2fix(a) (((int)(a))<<8) //Convert char to fix. a is a char
#define fix2int(a) ((signed char)((a)>>8))
//Convert
fix to int. a is an int
#define float2fix(a) ((int)((a)*256.0)) //Convert float to fix. a is a float
#define fix2float(a) (((float)(a))/256.0) //Convert fix to float. a is an int
//=== animation stuff
==================================================
char r;
int vx, vy, g, drag;
char cu1[]="Cornell ECE 4760";
char cu2[]="COPYRIGHT:2012";
char cu5[]="HOW MANY PLAYERS?";
///////////////
//==================================
// set up the ports and timers
int main() {
//set
up the ports
PORTDIR = 0x00; // PORT D is an
input
DDRC = 0xff; // PORT C is an
ouput
PORTC = 0xff ; // turn off leds
/*
//set up timer 0 for 1 mSec timebase
OCR0A = 249; //set the compare re to 250 time
ticks
TIMSK0= (1<<OCIE0A); //turn
on timer 0 cmp match ISR
//set prescalar to divide by 64
TCCR0B= 3; //0b00000011;
// turn on clear-on-match
TCCR0A= (1<<WGM01) ;
*/
//init
the LED status (all off)
led=0x00;
PORTC = ~led;
//init
the task timers
time1=t1;
time2=t2;
time3=t3;
//init
the message
//for
no button push
PushFlag = 0;
//init
the state machine
PushState = NoPush;
//init
timer 1 to generate sync
//OCR1A
= lineTime; //One NTSC line
//
TIMER 1: OC1* disconnected, CTC mode, fosc/1 (20MHz), OC1A and OC1B
// interrupts enabled
TCCR1B = _BV(WGM12) | _BV(CS10);
OCR1A = LINE_TIME; // time for one NTSC
line
OCR1B = SLEEP_TIME; // time to go to
sleep
TIMSK1 = _BV(OCIE1B) | _BV(OCIE1A);
//init
ports
DDRD = 0x03; //video out
//
USART in MSPIM mode, transmitter enabled, frequency fosc/4
UCSR0B = _BV(TXEN0);
UCSR0C = _BV(UMSEL01) | _BV(UMSEL00);
UBRR0 = 1 ;
//initialize
synch constants
LineCount = 1;
syncON = 0b00000000;
syncOFF = 0b00000001;
//Print
"CORNELL" message
//video_puts(30,2,cu1);
//Print
"Copyright" message
//video_putsmalls(screen_width-70,screen_height-10,cu2);
//side
lines
#define width
screen_width-1
#define height
screen_height-1
/*Different
variables used throughout code*/
space s, sB;
row r, rB;
int x = 10;
int y = 1;
int xA = 5;
int yA = 1;
int xB = 22;
int yB = 1;
int turn, turnB, x1A, x1B, y1A, y1B;
int random_save = 10;
int random_saveB = 10;
int spin_save;
int spin_saveB;
int temp;
int tempB;
int speed = 80;
int speed_counter = 0;
int two_player = 1;
int pit;
int left_A;
int right_A;
int left_B;
int right_B;
/*
Initialize coordinates depending on amount of players*/
if (two_player)
{
x1A = xA;
x1B
= xB;
y1A
= yA;
y1B
= yB;
pit
= 25;
left_A
= 0;
right_A
= 9;
left_B
= 16;
right_B
= 25;
}
else
{
x1A = x;
x1B
= x;
y1A
= y;
y1B
= y;
pit
= 18;
left_A
= 5;
right_A
= 14;
xA
= x;
yA
= y;
}
//init
musical scale
note = 0;
musicT = 0;
//use
OC0A (pin B.3) for music
DDRB = (1<<PORTB3) ;
///////////////////////
//
Set up single video line timing
sei();
set_sleep_mode(SLEEP_MODE_IDLE);
sleep_enable();
int random = rand() % 7;
int randomB = rand() % 7;
int bottom = 0;
int bottomB = 0;
int game_over = 0;
matrix board, new_board, boardB, new_boardB;
//initialize
matrix
for (int i = 0; i < 26; i++){
for (int j = 0; j < 10; j++){
board.b[i][j] = 0;
}
}
for (int i = 0; i < 26; i++){
for (int j = 0; j < 10; j++){
boardB.b[i][j] = 0;
}
}
int spin = 0;
int spinB = 0;
int button = 0;
int buttonB = 0;
char winner = 0;
char cu3[] = "WINNER IS:";
char cu4;
if (two_player)
{
video_line(left_wall_A,ground_tp,right_wall_A,ground_tp,1);
video_line(right_wall_A,ground_tp,right_wall_A,0,1);
video_line(left_wall_B,0,left_wall_B,ground_tp,1);
video_line(left_wall_B,ground_tp,right_wall_B,ground_tp,1);
video_line(right_wall_B,ground_tp,right_wall_B,0,1);
}
else
{
video_line(left_wall,0,left_wall,ground,1);
video_line(left_wall,ground,right_wall,ground,1);
video_line(right_wall,ground,right_wall,0,1);
}
//
The following loop executes the if-block
//
when the screen refresh is done
//
then does all of the frame-end processing
while(game_over == 0) {
button
= 0;
buttonB
= 0;
timer1++;
if (timer1 == 65)
{
if (time1>0) --time1;
if (time2>0) --time2;
if (time3>0) --time3;
if (time4>0) --time4;
if (time5>0) --time5;
if (time6>0) --time6;
timer1
= 0;
}
if (LineCount == ScreenBot) {
update_piece++;
speed_counter++;
if (speed_counter == 120 && speed > 10)
{
speed_counter
= 0;
speed--;
}
//Play a note
//prescaler=256 so 1 tick is 12.8 microsec
TCCR0B = 4;
// toggle OC0A on compare match and turn on
comp-match
TCCR0A = (1<<COM0A0) | (1<<WGM01) ;
if((musicT++) > 15) {
//each
note 1/4 second
musicT
= 0;
OCR0A
= notes[note++] ;
if (note>18) note = 0; //test for end of scale
}
//Draw shape
s
= draw_shape(x1A, y1A, random, spin, two_player);
if(two_player) //Draw Shape for 2nd
player
{
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
if (update_piece >= speed-1) { //move the piece
down one space
bottom
= check_matrix(board, s);
bottomB
= check_matrix_tp(boardB, sB);
if (y1A + s.floor < pit && bottom == 0) { //If we have not hit
the floor or another piece, keep going
delete_shape(x1A, y1A, random, spin, two_player);
y1A
= y1A + 1;
//s = draw_shape(x,
y, random);
}
else {
board
= update_matrix(board, s, 1); //Add piece to the matrix
r
= check_matrix_row(board, s, two_player); //Check whether we
need to clear a row
if(r.clear == 1)
{
new_board = row_deleter(r, s, board, two_player, 1); //Clear row in
matrix
if(new_board.k != 0)
{
for(int g = 0; g < 26-new_board.k; g++)
{
for(int d = 0; d < 10; d++)
{
new_boardB.b[g][d] = boardB.b[g+new_board.k][d];
}
}
for(int g = 26-new_board.k; g < 26; g++)
{
for(int d = 0; d < 10; d++)
{
new_boardB.b[g][d] = 1;
}
}
delete_shape(x1B, y1B, randomB, spinB, two_player);
sB = draw_shape(x1B, y1B - new_board.k, randomB, spinB, two_player);
y1B = y1B-new_board.k;
draw_board_tp(boardB, new_boardB); //Draw's opponent's
board with added rows
boardB = new_boardB;
}
draw_board(board, new_board,two_player);
board
= new_board;
}
//y = 1;
random
= rand() % 7; //Start a new piece
x1A
= xA;
y1A
= yA;
spin
= 0;
s
= draw_shape(x1A, y1A, random, spin, two_player);
game_over
= check_matrix(board, s); //Check if we have hit the top
if (game_over == 1)
{
winner
= 2;
cu4
= 2;
}
}
if (y1B + sB.floor < pit && bottomB == 0 && two_player) {
delete_shape(x1B, y1B, randomB, spinB, two_player);
y1B
= y1B + 1;
}
else if (two_player){
boardB
= update_matrix(boardB, sB, 2);
rB
= check_matrix_row(boardB, sB, two_player);
if(rB.clear == 1)
{
new_boardB = row_deleter(rB, sB, boardB, two_player, 2);
if(new_boardB.k != 0)
{
for(int g = 0; g < 26-new_boardB.k; g++)
{
for(int d = 0; d < 10; d++)
{
new_board.b[g][d] = board.b[g+new_boardB.k][d];
}
}
for(int g = 26-new_boardB.k; g < 26; g++)
{
for(int d = 0; d < 10; d++)
{
new_board.b[g][d] = 1;
}
}
delete_shape(x1A, y1A, random, spin, two_player);
s = draw_shape(x1A, y1A - new_boardB.k, random, spin, two_player);
y1A = y1A-new_boardB.k;
draw_board(board, new_board,two_player);
board = new_board;
}
draw_board_tp(boardB, new_boardB);
boardB
= new_boardB;
}
randomB
= rand() % 7;
x1B
= xB;
y1B
= yB;
spinB
= 0;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
game_over
= check_matrix_tp(boardB, sB);
if (game_over == 1)
{
winner
= 1;
cu4
= 1;
}
}
update_piece
= 0;
}
if (time1==0) task1();
if (time2==0)
{
task2();
}
if (time3==0)
{
button
= task3();
}
if (time4==0) task4();
if (time5==0)
{
task5();
}
if (time6==0)
{
buttonB
= task6();
}
if (button == right) //Move right
{
bottom
= check_matrix_wall(board, s, 1);
if(s.r_wall + x1A < right_A && bottom == 0)
{
delete_shape(x1A, y1A, random, spin, two_player);
x1A
= x1A + 1;
s
= draw_shape(x1A, y1A, random, spin, two_player);
button
= 0;
}
bottom
= 0;
}
if (button == left) //Move left
{
bottom
= check_matrix_wall(board, s, -1);
if(x1A - s.l_wall > left_A && bottom == 0)
{
delete_shape(x1A, y1A, random, spin, two_player);
x1A
= x1A - 1;
s
= draw_shape(x1A, y1A, random, spin, two_player);
button = 0;
}
bottom
= 0;
}
if (button == down) //Move down
{
bottom
= check_matrix(board, s);
if (y1A + s.floor < pit && bottom == 0) {
delete_shape(x1A, y1A, random, spin, two_player);
y1A
= y1A + 1;
s
= draw_shape(x1A, y1A, random, spin, two_player);
}
bottom
= 0;
}
if (button == swap) //Store current
piece
{
if(random_save == 10)
{
random_save
= random;
delete_shape(x1A, y1A, random, spin, two_player);
if(!two_player)
{
s
= draw_shape(2, 5, random, spin, two_player);
}
else
{
s
= draw_shape(13, 5, random, spin, two_player);
}
spin_save
= spin;
random
= rand() % 7;
x1A
= xA;
y1A
= yA;
spin
= 0;
s
= draw_shape(xA, yA, random, spin, two_player);
game_over
= check_matrix(board, s);
}
else
{
delete_shape(x1A, y1A, random, spin, two_player);
if(!two_player)
{
delete_shape(2, 5, random_save, spin_save, two_player);
s
= draw_shape(2, 5, random, spin, two_player);
s
= draw_shape(xA, yA, random_save, spin_save, two_player);
}
else
{
delete_shape(13, 5, random_save, spin_save, two_player);
s
= draw_shape(13, 5, random, spin, two_player);
s
= draw_shape(xA, yA, random_save, spin_save, two_player);
}
s
= draw_shape(xA, yA, random_save, spin_save, two_player);
x1A
= xA;
y1A
= yA;
temp
= random;
random
= random_save;
random_save
= temp;
temp
= spin;
spin
= spin_save;
spin_save
= temp;
}
}
if (button == cw) //Rotate clockwise
{
if( spin == 3)
{
spin
= 0;
s
= spin_shape(x1A, y1A, random, spin);
turn
= check_matrix_spin(board, s, two_player);
if(turn == 0)
{
spin
= 3;
delete_shape(x1A, y1A, random, spin, two_player);
spin
= 0;
s
= draw_shape(x1A, y1A, random, spin, two_player);
}
else if(turn == 2)
{
spin
= 3;
delete_shape(x1A, y1A, random, spin, two_player);
spin
= 0;
x1A
= left_A + s.l_wall;
s
= draw_shape(x1A, y1A, random, spin, two_player);
}
else if(turn == 3)
{
spin
= 3;
delete_shape(x1A, y1A, random, spin, two_player);
spin
= 0;
x1A
= right_A - s.r_wall;
s
= draw_shape(x1A, y1A, random, spin, two_player);
}
else if(turn == 4)
{
spin
= 3;
delete_shape(x1A, y1A, random, spin, two_player);
spin
= 0;
y1A
= y1A - s.floor;
s
= draw_shape(x1A, y1A, random, spin, two_player);
}
else
{
spin
= 3;
}
}
else
{
spin++;
s
= spin_shape(x1A, y1A, random, spin);
turn
= check_matrix_spin(board, s, two_player);
if(turn == 0)
{
spin--;
delete_shape(x1A, y1A, random, spin, two_player);
spin++;
s
= draw_shape(x1A, y1A, random, spin, two_player);
}
else if(turn == 2)
{
spin--;
delete_shape(x1A, y1A, random, spin, two_player);
spin++;
x1A
= left_A + s.l_wall;
s
= draw_shape(x1A, y1A, random, spin, two_player);
}
else if(turn == 3)
{
spin--;
delete_shape(x1A, y1A, random, spin, two_player);
spin++;
x1A
= right_A - s.r_wall;
s
= draw_shape(x1A, y1A, random, spin, two_player);
}
else if(turn == 4)
{
spin--;
delete_shape(x1A, y1A, random, spin, two_player);
spin++;
y1A
= y1A - s.floor;
s
= draw_shape(x1A, y1A, random, spin, two_player);
}
else
{
spin--;
}
}
}
if (button == ccw) //Rotate counter
clocwise
{
if( spin == 0)
{
spin
= 3;
s
= spin_shape(x1A, y1A, random, spin);
turn
= check_matrix_spin(board, s, two_player);
if(turn == 0)
{
spin
= 0;
delete_shape(x1A, y1A, random, spin, two_player);
spin
= 3;
s
= draw_shape(x1A, y1A, random, spin, two_player);
}
else if(turn == 2)
{
spin
= 0;
delete_shape(x1A, y1A, random, spin, two_player);
spin
= 3;
x1A
= left_A + s.l_wall;
s
= draw_shape(x1A, y1A, random, spin, two_player);
}
else if(turn == 3)
{
spin
= 0;
delete_shape(x1A, y1A, random, spin, two_player);
spin
= 3;
x1A
= right_A - s.r_wall;
s
= draw_shape(x1A, y1A, random, spin, two_player);
}
else if(turn == 4)
{
spin
= 0;
delete_shape(x1A, y1A, random, spin, two_player);
spin
= 3;
y1A
= y1A - s.floor;
s
= draw_shape(x1A, y1A, random, spin, two_player);
}
else
{
spin
= 0;
}
}
else
{
spin--;
s
= spin_shape(x1A, y1A, random, spin);
turn
= check_matrix_spin(board, s, two_player);
if(turn == 0)
{
spin++;
delete_shape(x1A, y1A, random, spin, two_player);
spin--;
s
= draw_shape(x1A, y1A, random, spin, two_player);
}
else if(turn == 2)
{
spin++;
delete_shape(x1A, y1A, random, spin, two_player);
spin--;
x1A
= left_A + s.l_wall;
s
= draw_shape(x1A, y1A, random, spin, two_player);
}
else if(turn == 3)
{
spin++;
delete_shape(x1A, y1A, random, spin, two_player);
spin--;
x1A
= right_A - s.r_wall;
s
= draw_shape(x1A, y1A, random, spin, two_player);
}
else if(turn == 4)
{
spin++;
delete_shape(x1A, y1A, random, spin, two_player);
spin--;
y1A
= y1A - s.floor;
s
= draw_shape(x1A, y1A, random, spin, two_player);
}
else
{
spin++;
}
}
}
/*Second Player
controls same as First Player*/
if (buttonB == right)
{
bottomB
=
check_matrix_wall_tp(boardB, sB, 1);
if(sB.r_wall + x1B < right_B && bottomB == 0)
{
delete_shape(x1B, y1B, randomB, spinB, two_player);
x1B
= x1B + 1;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
buttonB
= 0;
}
bottomB
= 0;
}
if (buttonB == left)
{
bottomB
=
check_matrix_wall_tp(boardB, sB, -1);
if(x1B - sB.l_wall > left_B && bottomB == 0)
{
delete_shape(x1B, y1B, randomB, spinB, two_player);
x1B
= x1B - 1;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
buttonB
= 0;
}
bottomB
= 0;
}
if (buttonB == down)
{
bottomB
= check_matrix_tp(boardB, sB);
if (y1B + sB.floor < pit && bottomB == 0) {
delete_shape(x1B, y1B, randomB, spinB, two_player);
y1B
= y1B + 1;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
bottomB
= 0;
}
if (buttonB == swap)
{
if(random_saveB == 10)
{
random_saveB
= randomB;
delete_shape(x1B, y1B, randomB, spinB, two_player);
sB
= draw_shape(13, 10, randomB, spinB, two_player);
spin_saveB
= spinB;
randomB
= rand() % 7;
x1B
= xB;
y1B
= yB;
spinB
= 0;
sB
= draw_shape(xB, yB, randomB, spinB, two_player);
game_over
= check_matrix_tp(boardB, sB);
}
else
{
delete_shape(x1B, y1B, randomB, spinB, two_player);
delete_shape(13, 10, random_saveB, spin_saveB, two_player);
sB
= draw_shape(13, 10, randomB, spinB, two_player);
sB
= draw_shape(xB, yB, random_saveB, spin_saveB, two_player);
sB
= draw_shape(xB, yB, random_saveB, spin_saveB, two_player);
x1B
= xB;
y1B
= yB;
tempB
= randomB;
randomB
= random_saveB;
random_saveB
= tempB;
tempB
= spinB;
spinB
= spin_saveB;
spin_saveB
= tempB;
}
}
if (buttonB == cw)
{
if( spinB == 3)
{
spinB
= 0;
sB
= spin_shape(x1B, y1B, randomB, spinB);
turnB
=
check_matrix_spin_B(boardB, sB);
if(turnB == 0)
{
spinB
= 3;
delete_shape(x1B, y1B, randomB, spinB, two_player);
spinB
= 0;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
else if(turnB == 2)
{
spinB
= 3;
delete_shape(x1B, y1B, randomB, spinB, two_player);
spinB
= 0;
x1B
= left_B + sB.l_wall;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
else if(turnB == 3)
{
spinB
= 3;
delete_shape(x1B, y1B, randomB, spinB, two_player);
spinB
= 0;
x1B
= right_B - sB.r_wall;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
else if(turnB == 4)
{
spinB
= 3;
delete_shape(x1B, y1B, randomB, spinB, two_player);
spinB
= 0;
y1B
= y1B - sB.floor;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
else
{
spinB
= 3;
}
}
else
{
spinB++;
sB
= spin_shape(x1B, y1B, randomB, spinB);
turnB
=
check_matrix_spin_B(boardB, sB);
if(turnB == 0)
{
spinB--;
delete_shape(x1B, y1B, randomB, spinB, two_player);
spinB++;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
else if(turnB == 2)
{
spinB--;
delete_shape(x1B, y1B, randomB, spinB, two_player);
spinB++;
x1B
= left_B + sB.l_wall;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
else if(turnB == 3)
{
spinB--;
delete_shape(x1B, y1B, randomB, spinB, two_player);
spinB++;
x1B
= right_B - sB.r_wall;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
else if(turn == 4)
{
spinB--;
delete_shape(x1B, y1B, randomB, spinB, two_player);
spinB++;
y1B
= y1B - sB.floor;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
else
{
spinB--;
}
}
}
if (buttonB == ccw)
{
if( spinB == 0)
{
spinB
= 3;
sB
= spin_shape(x1B, y1B, randomB, spinB);
turnB
=
check_matrix_spin_B(boardB, sB);
if(turnB == 0)
{
spinB
= 0;
delete_shape(x1B, y1B, randomB, spinB, two_player);
spinB
= 3;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
else if(turnB == 2)
{
spinB
= 0;
delete_shape(x1B, y1B, randomB, spinB, two_player);
spinB
= 3;
x1B
= left_B + sB.l_wall;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
else if(turnB == 3)
{
spinB
= 0;
delete_shape(x1B, y1B, randomB, spinB, two_player);
spinB
= 3;
x1B
= right_B - sB.r_wall;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
else if(turnB == 4)
{
spinB
= 0;
delete_shape(x1B, y1B, randomB, spinB, two_player);
spinB
= 3;
y1B
= y1B - sB.floor;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
else
{
spinB
= 0;
}
}
else
{
spinB--;
sB
= spin_shape(x1B, y1B, randomB, spinB);
turnB
=
check_matrix_spin_B(boardB, sB);
if(turnB == 0)
{
spinB++;
delete_shape(x1B, y1B, randomB, spinB, two_player);
spinB--;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
else if(turnB == 2)
{
spinB++;
delete_shape(x1B, y1B, randomB, spinB, two_player);
spinB--;
x1B
= left_B + sB.l_wall;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
else if(turnB == 3)
{
spinB++;
delete_shape(x1B, y1B, randomB, spinB, two_player);
spinB--;
x1B
= right_B - sB.r_wall;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
else if(turnB == 4)
{
spinB++;
delete_shape(x1B, y1B, randomB, spinB, two_player);
spinB--;
y1B
= y1B - sB.floor;
sB
= draw_shape(x1B, y1B, randomB, spinB, two_player);
}
else
{
spinB++;
}
}
}
while (LineCount != ScreenTop) ;
} //line 231
} //for
while(1){
//video_putsmalls(screen_width-70,10,cu3);
if(two_player)
{
video_puts(70,2,cu3);
if( winner == 1 ) //Say Player 1 wins!
{
video_line (75, 20, 85, 20, 1);
video_line (85, 20, 85, 110, 1);
video_line (65, 110, 105, 110, 1);
}
else if( winner == 2 ) //Say Player 2 Wins!
{
video_line (65, 20, 105, 20, 1);
video_line (105, 20, 105, 65, 1);
video_line (105, 65, 65, 65, 1);
video_line (65, 65, 65, 110, 1);
video_line (65, 110, 105, 110, 1);
}
}
}
} //main
//the three task subroutines
//void task1(void); //inc
LEDs
//void task2(void); //non-debounced button 0
//int task3(void); //debounced button 1
//**********************************************************
//Task subroutines
//Task 1
void task1(void)
begin
time1=t1; //reset the task
timer
if (PushFlag) //check for a button press
begin
//reset flag
PushFlag = 0;
key
= 0xff;
//increment the LEDs
//++led;
//PORTC = ~led;
end
end
//*******************************
//Task 2
void task2(void)
begin
time2=t2; //reset the task
timer
//get lower nibble
PORTDIR = 0x0f;
PORTDATA = 0xf0;
_delay_us(5);
key = PORTIN;
//get upper nibble
PORTDIR = 0xf0;
PORTDATA = 0x0f;
_delay_us(5);
key = key | PORTIN;
if (key != 0xff)//~PIND &
0x01) //button push
{
PushFlag = 1;
}
else
{
PushFlag = 0;
}
end
//*******************************
//Task 3
int task3(void)
begin
time3=t3; //reset the task
timer
butval = 17;
//get
lower nibble
PORTDIR = 0x0f;
PORTDATA = 0xf0;
_delay_us(5);
key1 = PORTIN;
//get upper nibble
PORTDIR = 0xf0;
PORTDATA = 0x0f;
_delay_us(5);
key1 = key1 | PORTIN;
switch (PushState)
begin
case NoPush:
if (key1 == key && PushFlag == 1)
{
PushState=MaybePush;
}
else
{
PushState=NoPush;
}
break;
case MaybePush:
if (key1 == key && PushFlag == 1)
begin
PushState=Pushed;
end
else PushState=NoPush;
break;
case Pushed:
if (key1 == key && PushFlag == 1)
{
PushState=Pushed;
}
else PushState=MaybeNoPush;
break;
case MaybeNoPush:
if (key1 == key && PushFlag == 1) PushState=Pushed;
else
begin
PushState=NoPush;
end
break;
end
if(PushState == Pushed)
{
for (butnum=0; butnum<maxkeys; butnum++)
{
if (keytbl[butnum]==key1) break;
}
if (butnum==maxkeys) butnum=0;
else butnum++; //adjust by one to
make range 1-16
switch(butnum)
{
case 10: butval = right; break;
case 11: butval = down; break;
case 12: butval = left; break;
case 14: butval = cw; break;
case 15: butval = swap; break;
case 16: butval = ccw; break;
}
}
return butval;
end
//**********************************************************
//Task subroutines
//Task 4
void task4(void)
begin
time4=t4; //reset the task
timer
if (PushFlagB) //check for a button press
begin
//reset flag
PushFlagB = 0;
keyB
= 0xff;
//increment the LEDs
//++led;
//PORTC = ~led;
end
end
//*******************************
//Task 5
void task5(void)
begin
time5=t5; //reset the task
timer
//get lower nibble
PORTDIRB = 0x0f;
PORTDATAB = 0xf0;
_delay_us(5);
keyB = PORTINB;
//get upper nibble
PORTDIRB = 0xf0;
PORTDATAB = 0x0f;
_delay_us(5);
keyB = keyB | PORTINB;
if (keyB != 0xff)//~PIND &
0x01) //button push
{
PushFlagB = 1;
}
else
{
PushFlagB = 0;
}
end
//*******************************
//Task 6
int task6(void)
begin
time6=t6; //reset the task
timer
butvalB = 17;
//get
lower nibble
PORTDIRB = 0x0f;
PORTDATAB = 0xf0;
_delay_us(5);
key1B = PORTINB;
//get upper nibble
PORTDIRB = 0xf0;
PORTDATAB = 0x0f;
_delay_us(5);
key1B = key1B | PORTINB;
switch (PushStateB)
begin
case NoPush:
if (key1B == keyB && PushFlagB == 1)
{
PushStateB=MaybePush;
}
else
{
PushStateB=NoPush;
}
break;
case MaybePush:
if (key1B == keyB && PushFlagB == 1)
begin
PushStateB=Pushed;
end
else PushStateB=NoPush;
break;
case Pushed:
if (key1B == keyB && PushFlagB == 1)
{
PushStateB=Pushed;
}
else PushStateB=MaybeNoPush;
break;
case MaybeNoPush:
if (key1B == key && PushFlagB == 1) PushStateB=Pushed;
else
begin
PushStateB=NoPush;
end
break;
end
if(PushStateB == Pushed)
{
for (butnumB=0; butnumB<maxkeys; butnumB++)
{
if (keytbl[butnumB]==key1B) break;
}
if (butnumB==maxkeys) butnum=0;
else butnumB++; //adjust by one to
make range 1-16
switch(butnumB)
{
case 9: butvalB = right; break;
case 10: butvalB = down; break;
case 11: butvalB = left; break;
case 13: butvalB = cw; break;
case 14: butvalB = swap; break;
case 15: butvalB = ccw; break;
}
}
return butvalB;
end