NAVER

질문 코드비전용 코드를 avr studio 4 로 변환해주세요 내공30
tktq**** 조회수 1,106 작성일2012.12.24

 //#include <mega128.h>
//#include <delay.h>
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/pgmspace.h> // flash 함수를 사용 하기 위한 헤더 파일입니다.


#define SIZE  16   // LDM사이즈

#define LINE_ADDR PORTG  // Line Address
#define RED   PORTA.0  // Red LED Data
#define GREEN  PORTA.1  // Green LED Data
#define ENABLE  PORTA.2  // Output Enable
#define LATCH  PORTA.3  // Latch
#define CLOCK  PORTA.4  // Clock

typedef unsigned int uint;
typedef unsigned char uchar;


uint com;    // LDM 출력행
uint level = 22;  // 블록 이동 속도 조절
uint start = 0;   // 게임 시작(0:대기, 1:시작)
uint wait = 0;   // "승리", "패" 출력시 스위치 입력 금지 변수

// Player1 변수
uint p1_stage = 0;  // 스테이지 번호
uint p1_stage_cnt = 0; // 현 스테이지에서 지운 라인수
uint p1_pat_cnt = 0; // 블록 랜덤 발생을 위한 카운터
uint p1_by = 0;   // 블록 좌상 Y좌표
uint p1_bx = 0;   // 블록 좌상 X좌표
uint p1_turn = 0;  // 현재 블록 패턴 회전 번호
uint p1_next_pat = 0; // 다음 블록 패턴 번호
uint p1_pat = 0;  // 현재 블록 패턴 번호
uint p1_down_cnt;  // 이동속도 카운터 변수

// 7가지의 블록을 4가지 패턴으로 정의
// block[블록번호][회전번호][수직좌표][수평좌표]
unsigned char block[7][4][4][4] = {
        {{{0,0,0,0},{0,0,0,0},{1,1,1,1},{0,0,0,0}},
        {{0,1,0,0},{0,1,0,0},{0,1,0,0},{0,1,0,0}},
        {{0,0,0,0},{0,0,0,0},{1,1,1,1},{0,0,0,0}},
        {{0,1,0,0},{0,1,0,0},{0,1,0,0},{0,1,0,0}}},

        {{{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}},
        {{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}},
        {{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}},
        {{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}}},

        {{{0,0,0,0},{0,0,1,1},{0,1,1,0},{0,0,0,0}},
        {{0,0,0,0},{0,1,0,0},{0,1,1,0},{0,0,1,0}},
        {{0,0,0,0},{0,0,1,1},{0,1,1,0},{0,0,0,0}},
        {{0,0,0,0},{0,1,0,0},{0,1,1,0},{0,0,1,0}}},

        {{{0,0,0,0},{0,1,1,0},{0,0,1,1},{0,0,0,0}},
        {{0,0,0,0},{0,0,0,1},{0,0,1,1},{0,0,1,0}},
        {{0,0,0,0},{0,1,1,0},{0,0,1,1},{0,0,0,0}},
        {{0,0,0,0},{0,0,0,1},{0,0,1,1},{0,0,1,0}}},

        {{{0,1,0,0},{0,1,1,1},{0,0,0,0},{0,0,0,0}},
        {{0,0,1,1},{0,0,1,0},{0,0,1,0},{0,0,0,0}},
        {{0,0,0,0},{0,1,1,1},{0,0,0,1},{0,0,0,0}},
        {{0,0,1,0},{0,0,1,0},{0,1,1,0},{0,0,0,0}}},

        {{{0,0,0,1},{0,1,1,1},{0,0,0,0},{0,0,0,0}},
        {{0,0,1,0},{0,0,1,0},{0,0,1,1},{0,0,0,0}},
        {{0,0,0,0},{0,0,1,0},{0,0,1,0},{0,0,0,0}},
        {{0,1,1,0},{0,0,1,0},{0,0,1,0},{0,0,0,0}}},

        {{{0,0,0,0},{0,0,1,0},{0,1,1,0},{0,0,1,0}},
        {{0,0,0,0},{0,0,1,0},{0,0,1,1},{0,0,1,0}},
        {{0,0,0,0},{0,0,0,0},{0,1,1,1},{0,0,1,0}},
        {{0,0,0,0},{0,0,1,0},{0,1,1,0},{0,0,1,0}}} };
//게임 플레이시 바닥에 깔리는 게임틀과 승리, 패를 표시하는 데이터
flash uchar stage[6][16][16] =
     {{{1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0}, // 스테이지1 게임틀
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}},

     {{1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},  // 스테이지 2 게임틀
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0},
     {1,0,0,1,1,0,0,1,1,0,0,1,0,0,0,0},
     {1,0,1,1,1,1,1,1,1,1,0,1,0,0,0,0},
     {1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}},

     {{1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},  // 스테이지 3 게임틀
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,1,0,1,0,1,0,1,0,1,1,0,0,0,0},
     {1,1,0,1,0,1,0,1,0,1,0,1,0,0,0,0},
     {1,0,1,0,1,0,1,0,1,0,1,1,0,0,0,0},
     {1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}},

     {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},  // "승리"
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0},
     {0,0,0,1,0,1,0,0,0,1,1,1,1,0,1,0},
     {0,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0},
     {0,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0},
     {0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,0},
     {0,1,1,1,1,1,1,1,0,1,0,0,0,0,1,0},
     {0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0},
     {0,0,0,1,1,1,0,0,0,1,1,1,1,0,1,0},
     {0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0},
     {0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},

     {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},  // "패"
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0},
     {0,0,1,1,1,1,1,1,1,1,0,1,0,1,0,0},
     {0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0},
     {0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0},
     {0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0},
     {0,0,0,0,1,0,0,1,0,0,0,1,1,1,0,0},
     {0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0},
     {0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0},
     {0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0},
     {0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0},
     {0,0,1,1,1,1,1,1,1,1,0,1,0,1,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},

     {{0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0},  // "테트리스"
     {0,1,1,1,0,0,1,1,0,0,1,1,1,1,1,0},
     {0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0},
     {0,1,1,1,0,0,1,1,0,0,1,1,1,1,1,0},
     {0,1,0,0,1,1,1,1,0,0,1,0,0,0,0,0},
     {0,1,0,0,0,0,1,1,0,0,1,1,1,1,1,0},
     {0,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,1},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,1,1,1,1,0,1,0,0,0,0,0,1,0,0,0},
     {0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0},
     {0,0,0,0,1,0,1,0,0,0,1,0,0,0,1,0},
     {0,1,1,1,1,0,1,0,0,1,0,0,0,0,0,1},
     {0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0},
     {0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0},
     {0,1,1,1,1,0,1,0,0,1,1,1,1,1,1,1}}};

// 게임 플레이시 적색 게임틀, 승리, 패를 표시하는 데이터
flash uchar red_stage[3][16][16]=
     {{{1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0}, // 스테이지1 게임틀
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}},

     {{1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},  // 스테이지2 게임틀
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}},

     {{1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},  // 스테이지3 게임틀
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}}};

// 떨어지는 블록 데이터 저장
// p1_data와 함께 OR하여 LDM 출력
uchar p1_table[16][16];    // 떨어지는 블록 데이터 저장
uchar p1_data[16][16];    // 게임틀과 떨어진 블록 데이터 저장

// 함수
void one_play(void);    // 1인용 게임
int p1_blk_check(int, int);   // Player1 블록 닿는지 조사
void p1_blk_clear(void);   // Player1 블록 테이블 클리어
void p1_blk_copy(void);    // Player1 블록 테이블 복사
void stage_out(void);    // 스테이지 게임틀 데이터 설정
void init_set(void);    // 초기화면 표시 데이터 설정

int main(void)
{
 // 포트 입출력 설정
 DDRA = 0x1F;       // PORTA 출력 설정(LDM 제어핀)
 DDRG = 0x1F;       // PORTA 출력설정(LDM 어드레스 A0-A3)
 DDRE = 0x00;       // PORTE 입력설정(스위치)
 
 // LDM 제어신호 출력
 PORTA = 0b00001100;      // Enable High
 PORTG = 0x0F;       // A0-A3 = 1111
 PORTA = 0b000010000;     // Enable Low

 // 외부 인터럽트 설정
 EICRB = 0b10101010;      // 외부인터럽트 4-7 하강에지
 EIMSK = 0b11110000;      // 외부인터럽트 4-7 인에이블

 // 타이머/카운터 설정
 ASSR = 0x00;       // 타이머/카운터0 타이머 모드
 TCCR0 = 0x04;       // 일반모드, 프리스케일 = CK/64
 TCNT0 = 0x00;       // 타이머/카운터0 레지스터 초기값

 TCCR1A = 0x00;       // 타이머/카운터1 인에이블
 TCCR1B = 0x05;       // 1024분주
 TCCR1C = 0x00;
 TCNT1 = 0xfe00;       // 1/16 us x 1024 x (0xffff -0xfe00) = 32ms
 TIMSK = 0x05;       // 타이머/카운터0, 1 인터럽트 인에이블

 init_set();

 SREG = 0x80;       // 전역 인터럽트 인에이블 비트셋

 while(1){
  while(!start){  // 대기 상태
   p1_pat = p1_next_pat;  // 새로 나올 블록을 계속 해서 바꿔준다.
   p1_next_pat = p1_pat_cnt; // 다음 블록은 다른 랜덤값을 취한다.
  }

  one_play();    // 1인용 게임
 }
}
// "테트리스" 패턴 저장, 블록 저장 테이블 클리어
void init_set(void)
{
 int i,j;

 // "테트리스" 패턴 저장
 for(j=0;j<16;j++){
  for(i=0;i<16;i++){
   p1_data[j][i] = stage[5][j][i];
   p1_table[j][i] = 0;  // 블록 저장 테이블 클리어
  }
 }
}

// 1인용 게임
void one_play(void)
{
 int j, k, m, n, p1_stop;

 p1_down_cnt = 0;

 while(start){ // 게임 시작
  if(p1_down_cnt > level){   // level로 블록이 떨어지는 속도 제어
   p1_down_cnt = 0;    // 이동속도 조절 변수 리셋

   // 한 칸 아래 이동 가능한지 조사(시간이 되면 자동 하강)
   p1_stop = p1_blk_check(0, 1);

   if(p1_stop != 0){
    p1_blk_clear();    // 한 칸 아래 자동 이동 가능
    p1_by += 1;     // 블록 한줄 아래로 이동
   }

   // 블록이 바닥에 닿았을 때 처리 함수
   if(p1_stop == 0){
    // 게임판 데이터와 움직이는 블록(테이블) 합성
    for(j = 0;j < 16;j++){
     for(k = 0;k < 16; k++)
      p1_data[j][k] != p1_table[j][k];
    }

    for(j = 0;j < 15;j++){  // 한줄 채우면 지우기
       // 줄이 모두 채워져 있는지 조사
       // 채워져 있으면 곱은 1이 되고,
       // 하나라도 비어 있으면 0이 된다.
       n = 1;
       for(k = 1;k < 11;k++) n = n * p1_data[j][k];

       if(n == 1){  // 한 줄 채워짐
        // 윗 줄 아래로 당기기
        for(m = j;m > 1;m--){
         for(k = 1;k < 11;k++){
          p1_data[m][k] = p1_data[m-1][k];
         }
        }
        p1_stage_cnt++; // 줄 지울 때마다 증가

        // 제거 라인 수 LED 표시
        for(m = 0;m < 2;m++){
         for(k = 0;k < 4;k++){
          if((k + m * 4) < (p1_stage_cnt))
           p1_data[m+11][k+12] = 1;
          else p1_data[m+11][k+12] = 0;
         }
        }
        if(p1_stage_cnt > 7){
         // 8칸 지우면 다음 단계로 이동
         p1_stage++;  // 다음 스테이지로
         level -= 7;   // 속도증가

         if(p1_stage > 2){
          wait = 1;
          start = 0;
          // 스테이지3 클리어 "승리" 표시
          for(m = 0;m < 16;m++){
           for(k = 0;k < 16;k++){
            p1_data[m][k] = stage[3][m][k];
            p1_table[m][k] = 0;
           }
          }
          _delay_ms(2000);
          p1_stage = 0;
          init_set();
          wait = 0;
          return;
         }
         else {
          stage_out();
          _delay_ms(1000);
         }
        }
       }
    }

    // table 클리어
    for(j = 0;j < 16;j++){
     for(k = 0;k < 16;k++) p1_table[j][k] = 0;
    }

    p1_by = 0;    // 블록의 table에 위치하는 곳 초기화
    p1_bx = 4;   
    p1_turn = 0;    // 블록 기본형으로
    p1_pat = p1_next_pat;   // next패턴을 현재 패턴으로
    p1_next_pat = p1_pat_cnt;  // next패턴 새로운 값
   // 새로운 블록이 놓이는 영역에 하나라도 블록이 있으면 종료
    for(m = 3;m >= 0;m--){
     for(n = 4;n < 8;n++){
      if(p1_data[m][n] == 1){
       wait = 1;
       start = 0;

       // "패" 패턴 저장
       for(j = 0;j < 16;j++){
        for(k = 0;k < 16;k++){
         p1_data[j][k] = stage[4][j][k];
         p1_table[j][k] = 0;
        }
       }
       _delay_ms(2000);
       p1_stage = 0;
       init_set();
       wait = 0;
       return;
      }
     }
    }
   }

   // 새로운 블록 불러오는 중에 블록을 이동 못하게
   // 외부인터럽트 디스에이블

   EIMSK = 0;

   if(start){
    p1_blk_clear();
    p1_blk_copy();   // 새로운 블록 복사

    // 다음 블록 패턴 표시를 위한 저장
    for(j = 0;j < 4;j++){
     for(k = 0;k < 4;k++){
      p1_data[j][k+12] = block[p1_next_pat][0][j][k];
     }
    }
   }
   EIMSK = 0xf0;    // 외부인터럽트 인에이블
  }
 }
}

// Player1 떨어진 블록과 떨어지는 블록 충돌 체크
// ox : p1_bx와의 차이값, oy : p1_by와 차이값
int p1_blk_check(int ox, int oy)
{
 int j, k, p1_y, p1_x;

 for(j = 0;j < 4;j++){
  p1_y = j + p1_by;
  for(k = 0;k < 4;k++){
   p1_x = k + p1_bx;
   // table과 table의 수평 ox 옆, 수직 oy 아랫부분의
   // data가 모두 1인지 조사
   if((p1_table[p1_y][p1_x] & p1_data[p1_y+oy][p1_x+ox])==1)  return(0);
  }
 }
}

// Player1 블록 table 클리어
void p1_blk_clear()
{
 int j, k, p1_x, p1_y;

 for(j = 0;j < 4;j++){  // 현재 블록 지우기
  p1_y = j + p1_by;
  for(k = 0;k < 4;k++){
   p1_x = k+ p1_bx;
   p1_table[p1_y][p1_x] = 0;
  }
 }
}

// Player1 블록 -> table 복사
void p1_blk_copy()
{
 int j, k, p1_x, p1_y;

 for(j = 0;j < 4;j++){
  p1_y = j + p1_by;
  for(k = 0;k < 4;k++){ // 새로운 블록 불러오기
   p1_x = k + p1_bx;
   p1_table[p1_y][p1_x] |= block[p1_pat][p1_turn][j][k];
  }
 }
}

// 게임틀 및 파라미터 초기 설정
void stage_out()
{
 int i, j;

 for(j = 0;j < 16;j++){
  for(i = 0;i < 16;i++){
   p1_data[j][i] = stage[p1_stage][j][i];
   p1_table[j][i] = 0;
  }
 }

 p1_pat = 0;
 p1_next_pat = 0;
 p1_stage_cnt = 0;
 p1_bx = 4;
 p1_by = 0;
 p1_turn = 0;
}

// 타이머/카운터0 인터럽트 처리함수(LDM 출력)
// (256 - 0) * 64 / 16 us = 1.024ms
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
 int di = 0;

 com = (com + 1) % 16;   // 출력행 +1

 for(di = 0;di < SIZE;di++)
 {
  if(start == 1) RED = red_stage[p1_stage][com][di];  // RED_data
  else RED = 0;

  GREEN = p1_data[com][di] | p1_table[com][di];   // Green_data

  // 1비트 데이터 입력을 위한 클럭 입력
  CLOCK = 1;
  _delay_us(1);
  CLOCK = 0;
  _delay_us(1);
 }

 _delay_us(1);
 ENABLE = 1;    // Output Enable
 LATCH = 0;    // 데이터 래치 저장
 _delay_us(1);
 LATCH = 1;    // 데이터 입력과 표시

 LINE_ADDR = com;  // 어드레스 출력

 _delay_us(1);
 ENABLE = 0;    // 입력된 데이터 표시
}

// 타이머/카운터1 인터럽트 처리함수
// 1/16us x 1024 x (65536 -65024) = 32ms
interrupt [TIM1_OVF] void timer1_int(void)
{
 p1_down_cnt++;       // 블록이 떨어지는 시간 카운트.
 p1_pat_cnt = (p1_pat_cnt + 1) % 7;  // 패턴의 랜덤 추출.

 TCNT1 = 0Xfe00;       // 초기값 재설정
}

// 외부 인터럽트4, 스위치1 : Play1용 블록 회전 SW
interrupt [EXT_INT4] void external_int4(void)
{
 int stop;

 if(start){  // 게임중이면
  p1_blk_clear();      // 현재 블록 지우기

  p1_turn = (p1_turn + 1) % 4;  // 블록 90도 회전

  // 회전시킨 블록 데이터 복사
  p1_blk_copy();

  // 회전가능한지 조사
  stop = p1_blk_check(0, 0);

  if(stop == 0){  // 회전 불가
   p1_blk_clear();     // 새로운 블록 데이터 클리어
   p1_turn = (p1_turn +3) % 4;  // 블록 270도 회전
   p1_blk_copy();     // 원래 패턴 복귀
  }
 }
}

// 외부 인터럽트5, 스위치2 : Play1용 블록 왼쪽 이동 SW
interrupt [EXT_INT5] void external_int6(void)
{
 int stop;

 if(start){
  // 왼쪽으로 이동후 data와 table이 겹치는지 검사
  stop = p1_blk_check(-1, 0);

  if(stop != 0){   // 안 겹치면 현재 블록 지우고 이동
   p1_blk_clear();  // 현재 블록 데이터 클리어
   p1_bx -= 1;   // 블록 X 좌표 -1
   p1_blk_copy();  // 블록 데이터 복사
  }
 }
}

// 외부 인터럽트6, 스위치3 : Play1용 블록 오른쪽 이동 SW
interrupt [EXT_INT6] void external_int5(void)
{
 int stop;

 if(start){ // 게임중이면
  // 이동할 수 있는지 조사
  stop = p1_blk_check(1, 0);

  if(stop != 0){   // 안 겹치면 현재 블록 지우고 이동
   p1_blk_clear();   // 현재 블록 데이터 클리어

   p1_bx += 1;    // 블록 X 좌표 +1

   p1_blk_copy();   // 블록 데이터 복사
  }
 }
}

//외부 인터럽트7, 스위치4/5 : Play1용 블록 한 줄 내리기/바닥까지 내리기 SW
interrupt [EXT_INT7] void external_int7(void)
{
 int stop = 1;

 if(start){
  if(!(PINE & 0b00000001){  // 스위치4(PE0 비트 0인지 조사)
   // 아래 이동 가능한지 조사(아래 한 줄 내리기)
   stop = p1_blk_check(0, 1);

   if(stop != 0){   // 안 겹치면 현지블록 지우고 이동
    p1_blk_clear();  // 현재 블록 데이터 클리어

    p1_by += 1;   // 블록 Y 좌표 +1

    p1_blk_copy();  // 블록 데이터 복사
   }
  }
  else if(!(PINE & 0b00000010)){  //스위치5(PE1 비트 0인지 조사)
     // 바닥까지 내리기
   while(stop){
    // 아래 한 칸 이동 가능한지 조사
    stop = p1_blk_check(0, 1);

    if(stop != 0){  // 안 겹치면 현지블록 지우고 이동
     p1_blk_clear();  // 현재 블록 데이터 클리어

     p1_by += 1;   // 블록 Y 좌표 +1

     p1_blk_copy();  // 블록 데이터 복사
    }
    p1_down_cnt = 100;
   }
  }
  else {
   if(wait == 0){
    p1_stage = 0;
    level = 22;   // 블록 이동 속도 초기 설정
    tage_out();
    start = 1;   // 대기상태에서 게임시작
   }
 }
}

프로필 사진

답변자님,

정보를 공유해 주세요.

1 개 답변
1번째 답변
프로필 사진
키트 박옥현
우주신
전기, 전자 공학 6위, 프로그래머 1위, 프로그래밍 22위 분야에서 활동
본인 입력 포함 정보
 

 
//#define F_CPU 16000000     // 외부 오실레이터 클럭 16Mhz
#include <avr/io.h>        // avr input output 헤더
#include <util/delay.h>    // 딜레이 헤더
#include <avr/interrupt.h> // 인터럽트 헤더
//
#define SIZE      16         // LDM사이즈
#define LINE_ADDR PORTG      // Line Address
#define RED_1     PORTA|=1   // Red LED Data
#define RED_0     PORTA&=~1  // Red LED Data
#define GREEN_1   PORTA|=2   // Green LED Data
#define GREEN_0   PORTA&=~2  // Green LED Data
#define ENABLE_1  PORTA|=4   // Output Enable
#define ENABLE_0  PORTA&=~4  // Output Enable
#define LATCH_1   PORTA|=8   // Latch
#define LATCH_0   PORTA&=~8  // Latch
#define CLOCK_1   PORTA|=0x10 // Clock
#define CLOCK_0   PORTA&=~0x10 // Clock
typedef unsigned int uint;
typedef unsigned char uchar;

uint com;    // LDM 출력행
uint level = 22;  // 블록 이동 속도 조절
uint start = 0;   // 게임 시작(0:대기, 1:시작)
uint wait = 0;   // "승리", "패" 출력시 스위치 입력 금지 변수
// Player1 변수
uint p1_stage = 0;  // 스테이지 번호
uint p1_stage_cnt = 0; // 현 스테이지에서 지운 라인수
uint p1_pat_cnt = 0; // 블록 랜덤 발생을 위한 카운터
uint p1_by = 0;   // 블록 좌상 Y좌표
uint p1_bx = 0;   // 블록 좌상 X좌표
uint p1_turn = 0;  // 현재 블록 패턴 회전 번호
uint p1_next_pat = 0; // 다음 블록 패턴 번호
uint p1_pat = 0;  // 현재 블록 패턴 번호
uint p1_down_cnt;  // 이동속도 카운터 변수
// 7가지의 블록을 4가지 패턴으로 정의
// block[블록번호][회전번호][수직좌표][수평좌표]
unsigned char block[7][4][4][4] = {
        {{{0,0,0,0},{0,0,0,0},{1,1,1,1},{0,0,0,0}},
        {{0,1,0,0},{0,1,0,0},{0,1,0,0},{0,1,0,0}},
        {{0,0,0,0},{0,0,0,0},{1,1,1,1},{0,0,0,0}},
        {{0,1,0,0},{0,1,0,0},{0,1,0,0},{0,1,0,0}}},
        {{{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}},
        {{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}},
        {{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}},
        {{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}}},
        {{{0,0,0,0},{0,0,1,1},{0,1,1,0},{0,0,0,0}},
        {{0,0,0,0},{0,1,0,0},{0,1,1,0},{0,0,1,0}},
        {{0,0,0,0},{0,0,1,1},{0,1,1,0},{0,0,0,0}},
        {{0,0,0,0},{0,1,0,0},{0,1,1,0},{0,0,1,0}}},
        {{{0,0,0,0},{0,1,1,0},{0,0,1,1},{0,0,0,0}},
        {{0,0,0,0},{0,0,0,1},{0,0,1,1},{0,0,1,0}},
        {{0,0,0,0},{0,1,1,0},{0,0,1,1},{0,0,0,0}},
        {{0,0,0,0},{0,0,0,1},{0,0,1,1},{0,0,1,0}}},
        {{{0,1,0,0},{0,1,1,1},{0,0,0,0},{0,0,0,0}},
        {{0,0,1,1},{0,0,1,0},{0,0,1,0},{0,0,0,0}},
        {{0,0,0,0},{0,1,1,1},{0,0,0,1},{0,0,0,0}},
        {{0,0,1,0},{0,0,1,0},{0,1,1,0},{0,0,0,0}}},
        {{{0,0,0,1},{0,1,1,1},{0,0,0,0},{0,0,0,0}},
        {{0,0,1,0},{0,0,1,0},{0,0,1,1},{0,0,0,0}},
        {{0,0,0,0},{0,0,1,0},{0,0,1,0},{0,0,0,0}},
        {{0,1,1,0},{0,0,1,0},{0,0,1,0},{0,0,0,0}}},
        {{{0,0,0,0},{0,0,1,0},{0,1,1,0},{0,0,1,0}},
        {{0,0,0,0},{0,0,1,0},{0,0,1,1},{0,0,1,0}},
        {{0,0,0,0},{0,0,0,0},{0,1,1,1},{0,0,1,0}},
        {{0,0,0,0},{0,0,1,0},{0,1,1,0},{0,0,1,0}}} };
//게임 플레이시 바닥에 깔리는 게임틀과 승리, 패를 표시하는 데이터
uchar stage[6][16][16] =
     {{{1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0}, // 스테이지1 게임틀
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}},
     {{1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},  // 스테이지 2 게임틀
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0},
     {1,0,0,1,1,0,0,1,1,0,0,1,0,0,0,0},
     {1,0,1,1,1,1,1,1,1,1,0,1,0,0,0,0},
     {1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}},
     {{1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},  // 스테이지 3 게임틀
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,1,0,1,0,1,0,1,0,1,1,0,0,0,0},
     {1,1,0,1,0,1,0,1,0,1,0,1,0,0,0,0},
     {1,0,1,0,1,0,1,0,1,0,1,1,0,0,0,0},
     {1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}},
     {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},  // "승리"
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0},
     {0,0,0,1,0,1,0,0,0,1,1,1,1,0,1,0},
     {0,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0},
     {0,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0},
     {0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,0},
     {0,1,1,1,1,1,1,1,0,1,0,0,0,0,1,0},
     {0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0},
     {0,0,0,1,1,1,0,0,0,1,1,1,1,0,1,0},
     {0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0},
     {0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
     {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},  // "패"
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0},
     {0,0,1,1,1,1,1,1,1,1,0,1,0,1,0,0},
     {0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0},
     {0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0},
     {0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0},
     {0,0,0,0,1,0,0,1,0,0,0,1,1,1,0,0},
     {0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0},
     {0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0},
     {0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0},
     {0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0},
     {0,0,1,1,1,1,1,1,1,1,0,1,0,1,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
     {{0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0},  // "테트리스"
     {0,1,1,1,0,0,1,1,0,0,1,1,1,1,1,0},
     {0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0},
     {0,1,1,1,0,0,1,1,0,0,1,1,1,1,1,0},
     {0,1,0,0,1,1,1,1,0,0,1,0,0,0,0,0},
     {0,1,0,0,0,0,1,1,0,0,1,1,1,1,1,0},
     {0,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,1},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,1,1,1,1,0,1,0,0,0,0,0,1,0,0,0},
     {0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0},
     {0,0,0,0,1,0,1,0,0,0,1,0,0,0,1,0},
     {0,1,1,1,1,0,1,0,0,1,0,0,0,0,0,1},
     {0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0},
     {0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0},
     {0,1,1,1,1,0,1,0,0,1,1,1,1,1,1,1}}};
// 게임 플레이시 적색 게임틀, 승리, 패를 표시하는 데이터
uchar red_stage[3][16][16]={
    {{1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0}, // 스테이지1 게임틀
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}},
    {{1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},  // 스테이지2 게임틀
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}},
    {{1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},  // 스테이지3 게임틀
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
     {1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}}
};
// 떨어지는 블록 데이터 저장
// p1_data와 함께 OR하여 LDM 출력
uchar p1_table[16][16];    // 떨어지는 블록 데이터 저장
uchar p1_data[16][16];    // 게임틀과 떨어진 블록 데이터 저장
// 함수
void one_play(void);    // 1인용 게임
int p1_blk_check(int, int);   // Player1 블록 닿는지 조사
void p1_blk_clear(void);   // Player1 블록 테이블 클리어
void p1_blk_copy(void);    // Player1 블록 테이블 복사
void stage_out(void);    // 스테이지 게임틀 데이터 설정
void init_set(void);    // 초기화면 표시 데이터 설정
//
// 타이머/카운터0 인터럽트 처리함수(LDM 출력)
// (256 - 0) * 64 / 16 us = 1.024ms
ISR(TIMER0_OVF_vect){
 int di = 0;
 com = (com + 1) % 16;   // 출력행 +1
 for(di=0;di<SIZE;di++){
  if(start==1){
      if(red_stage[p1_stage][com][di])RED_1;  // RED_data
 else RED_0;
  }
  else RED_0;
  if(p1_data[com][di] | p1_table[com][di])GREEN_1;   // Green_data
  else GREEN_0;
  // 1비트 데이터 입력을 위한 클럭 입력
  CLOCK_1;
  _delay_us(1);
  CLOCK_0;
  _delay_us(1);
 }
 _delay_us(1);
 ENABLE_1;    // Output Enable
 LATCH_0;    // 데이터 래치 저장
 _delay_us(1);
 LATCH_1;    // 데이터 입력과 표시
 LINE_ADDR = com;  // 어드레스 출력
 _delay_us(1);
 ENABLE_0;    // 입력된 데이터 표시
}
//
int main(void){
 // 포트 입출력 설정
 DDRA = 0x1F;       // PORTA 출력 설정(LDM 제어핀)
 DDRG = 0x1F;       // PORTA 출력설정(LDM 어드레스 A0-A3)
 DDRE = 0x00;       // PORTE 입력설정(스위치)
 
 // LDM 제어신호 출력
 PORTA = 0b00001100;      // Enable High
 PORTG = 0x0F;       // A0-A3 = 1111
 PORTA = 0b000010000;     // Enable Low
 // 외부 인터럽트 설정
 EICRB = 0b10101010;      // 외부인터럽트 4-7 하강에지
 EIMSK = 0b11110000;      // 외부인터럽트 4-7 인에이블
 // 타이머/카운터 설정
 ASSR = 0x00;       // 타이머/카운터0 타이머 모드
 TCCR0 = 0x04;       // 일반모드, 프리스케일 = CK/64
 TCNT0 = 0x00;       // 타이머/카운터0 레지스터 초기값
 TCCR1A = 0x00;       // 타이머/카운터1 인에이블
 TCCR1B = 0x05;       // 1024분주
 TCCR1C = 0x00;
 TCNT1 = 0xfe00;       // 1/16 us x 1024 x (0xffff -0xfe00) = 32ms
 TIMSK = 0x05;       // 타이머/카운터0, 1 인터럽트 인에이블
 init_set();
 SREG = 0x80;       // 전역 인터럽트 인에이블 비트셋
 while(1){
  while(!start){  // 대기 상태
   p1_pat = p1_next_pat;  // 새로 나올 블록을 계속 해서 바꿔준다.
   p1_next_pat = p1_pat_cnt; // 다음 블록은 다른 랜덤값을 취한다.
  }
  one_play();    // 1인용 게임
 }
}
// "테트리스" 패턴 저장, 블록 저장 테이블 클리어
void init_set(void)
{
 int i,j;
 // "테트리스" 패턴 저장
 for(j=0;j<16;j++){
  for(i=0;i<16;i++){
   p1_data[j][i] = stage[5][j][i];
   p1_table[j][i] = 0;  // 블록 저장 테이블 클리어
  }
 }
}
// 1인용 게임
void one_play(void)
{
 int j, k, m, n, p1_stop;
 p1_down_cnt = 0;
 while(start){ // 게임 시작
  if(p1_down_cnt > level){   // level로 블록이 떨어지는 속도 제어
   p1_down_cnt = 0;    // 이동속도 조절 변수 리셋
   // 한 칸 아래 이동 가능한지 조사(시간이 되면 자동 하강)
   p1_stop = p1_blk_check(0, 1);
   if(p1_stop != 0){
    p1_blk_clear();    // 한 칸 아래 자동 이동 가능
    p1_by += 1;     // 블록 한줄 아래로 이동
   }
   // 블록이 바닥에 닿았을 때 처리 함수
   if(p1_stop == 0){
    // 게임판 데이터와 움직이는 블록(테이블) 합성
    for(j = 0;j < 16;j++){
     for(k = 0;k < 16; k++)
      p1_data[j][k] != p1_table[j][k];
    }
    for(j = 0;j < 15;j++){  // 한줄 채우면 지우기
       // 줄이 모두 채워져 있는지 조사
       // 채워져 있으면 곱은 1이 되고,
       // 하나라도 비어 있으면 0이 된다.
       n = 1;
       for(k = 1;k < 11;k++) n = n * p1_data[j][k];
       if(n == 1){  // 한 줄 채워짐
        // 윗 줄 아래로 당기기
        for(m = j;m > 1;m--){
         for(k = 1;k < 11;k++){
          p1_data[m][k] = p1_data[m-1][k];
         }
        }
        p1_stage_cnt++; // 줄 지울 때마다 증가
        // 제거 라인 수 LED 표시
        for(m = 0;m < 2;m++){
         for(k = 0;k < 4;k++){
          if((k + m * 4) < (p1_stage_cnt))
           p1_data[m+11][k+12] = 1;
          else p1_data[m+11][k+12] = 0;
         }
        }
        if(p1_stage_cnt > 7){
         // 8칸 지우면 다음 단계로 이동
         p1_stage++;  // 다음 스테이지로
         level -= 7;   // 속도증가
         if(p1_stage > 2){
          wait = 1;
          start = 0;
          // 스테이지3 클리어 "승리" 표시
          for(m = 0;m < 16;m++){
           for(k = 0;k < 16;k++){
            p1_data[m][k] = stage[3][m][k];
            p1_table[m][k] = 0;
           }
          }
          _delay_ms(2000);
          p1_stage = 0;
          init_set();
          wait = 0;
          return;
         }
         else {
          stage_out();
          _delay_ms(1000);
         }
        }
       }
    }
    // table 클리어
    for(j = 0;j < 16;j++){
     for(k = 0;k < 16;k++) p1_table[j][k] = 0;
    }
    p1_by = 0;    // 블록의 table에 위치하는 곳 초기화
    p1_bx = 4;   
    p1_turn = 0;    // 블록 기본형으로
    p1_pat = p1_next_pat;   // next패턴을 현재 패턴으로
    p1_next_pat = p1_pat_cnt;  // next패턴 새로운 값
   // 새로운 블록이 놓이는 영역에 하나라도 블록이 있으면 종료
    for(m = 3;m >= 0;m--){
     for(n = 4;n < 8;n++){
      if(p1_data[m][n] == 1){
       wait = 1;
       start = 0;
       // "패" 패턴 저장
       for(j = 0;j < 16;j++){
        for(k = 0;k < 16;k++){
         p1_data[j][k] = stage[4][j][k];
         p1_table[j][k] = 0;
        }
       }
       _delay_ms(2000);
       p1_stage = 0;
       init_set();
       wait = 0;
       return;
      }
     }
    }
   }
   // 새로운 블록 불러오는 중에 블록을 이동 못하게
   // 외부인터럽트 디스에이블
   EIMSK = 0;
   if(start){
    p1_blk_clear();
    p1_blk_copy();   // 새로운 블록 복사
    // 다음 블록 패턴 표시를 위한 저장
    for(j = 0;j < 4;j++){
     for(k = 0;k < 4;k++){
      p1_data[j][k+12] = block[p1_next_pat][0][j][k];
     }
    }
   }
   EIMSK = 0xf0;    // 외부인터럽트 인에이블
  }
 }
}
// Player1 떨어진 블록과 떨어지는 블록 충돌 체크
// ox : p1_bx와의 차이값, oy : p1_by와 차이값
int p1_blk_check(int ox, int oy){
    int j, k, p1_y, p1_x;
    for(j = 0;j < 4;j++){
        p1_y = j + p1_by;
        for(k = 0;k < 4;k++){
            p1_x = k + p1_bx;
            // table과 table의 수평 ox 옆, 수직 oy 아랫부분의
            // data가 모두 1인지 조사
            if((p1_table[p1_y][p1_x] & p1_data[p1_y+oy][p1_x+ox])==1)return(0);
        }
    }
}
// Player1 블록 table 클리어
void p1_blk_clear()
{
 int j, k, p1_x, p1_y;
 for(j = 0;j < 4;j++){  // 현재 블록 지우기
  p1_y = j + p1_by;
  for(k = 0;k < 4;k++){
   p1_x = k+ p1_bx;
   p1_table[p1_y][p1_x] = 0;
  }
 }
}
// Player1 블록 -> table 복사
void p1_blk_copy()
{
 int j, k, p1_x, p1_y;
 for(j = 0;j < 4;j++){
  p1_y = j + p1_by;
  for(k = 0;k < 4;k++){ // 새로운 블록 불러오기
   p1_x = k + p1_bx;
   p1_table[p1_y][p1_x] |= block[p1_pat][p1_turn][j][k];
  }
 }
}
// 게임틀 및 파라미터 초기 설정
void stage_out()
{
 int i, j;
 for(j = 0;j < 16;j++){
  for(i = 0;i < 16;i++){
   p1_data[j][i] = stage[p1_stage][j][i];
   p1_table[j][i] = 0;
  }
 }
 p1_pat = 0;
 p1_next_pat = 0;
 p1_stage_cnt = 0;
 p1_bx = 4;
 p1_by = 0;
 p1_turn = 0;
}





// 타이머/카운터1 인터럽트 처리함수
// 1/16us x 1024 x (65536 -65024) = 32ms
ISR(TIMER1_OVF_vect){
 p1_down_cnt++;       // 블록이 떨어지는 시간 카운트.
 p1_pat_cnt = (p1_pat_cnt + 1) % 7;  // 패턴의 랜덤 추출.
 TCNT1 = 0Xfe00;       // 초기값 재설정
}
// 외부 인터럽트4, 스위치1 : Play1용 블록 회전 SW
ISR(INT4_vect){
 int stop;
 if(start){  // 게임중이면
  p1_blk_clear();      // 현재 블록 지우기
  p1_turn = (p1_turn + 1) % 4;  // 블록 90도 회전
  // 회전시킨 블록 데이터 복사
  p1_blk_copy();
  // 회전가능한지 조사
  stop = p1_blk_check(0, 0);
  if(stop == 0){  // 회전 불가
   p1_blk_clear();     // 새로운 블록 데이터 클리어
   p1_turn = (p1_turn +3) % 4;  // 블록 270도 회전
   p1_blk_copy();     // 원래 패턴 복귀
  }
 }
}
// 외부 인터럽트5, 스위치2 : Play1용 블록 왼쪽 이동 SW
ISR(INT5_vect){
 int stop;
 if(start){
  // 왼쪽으로 이동후 data와 table이 겹치는지 검사
  stop = p1_blk_check(-1, 0);
  if(stop != 0){   // 안 겹치면 현재 블록 지우고 이동
   p1_blk_clear();  // 현재 블록 데이터 클리어
   p1_bx -= 1;   // 블록 X 좌표 -1
   p1_blk_copy();  // 블록 데이터 복사
  }
 }
}
// 외부 인터럽트6, 스위치3 : Play1용 블록 오른쪽 이동 SW
ISR(INT6_vect){
 int stop;
 if(start){ // 게임중이면
  // 이동할 수 있는지 조사
  stop = p1_blk_check(1, 0);
  if(stop != 0){   // 안 겹치면 현재 블록 지우고 이동
   p1_blk_clear();   // 현재 블록 데이터 클리어
   p1_bx += 1;    // 블록 X 좌표 +1
   p1_blk_copy();   // 블록 데이터 복사
  }
 }
}
//외부 인터럽트7, 스위치4/5 : Play1용 블록 한 줄 내리기/바닥까지 내리기 SW
ISR(INT7_vect){
    int stop = 1;
    if(start){
        if(!(PINE & 0b00000001)){  // 스위치4(PE0 비트 0인지 조사)
            // 아래 이동 가능한지 조사(아래 한 줄 내리기)
            stop = p1_blk_check(0, 1);
            if(stop != 0){   // 안 겹치면 현지블록 지우고 이동
                p1_blk_clear();  // 현재 블록 데이터 클리어
                p1_by += 1;   // 블록 Y 좌표 +1
                p1_blk_copy();  // 블록 데이터 복사
            }
        }
        else if(!(PINE & 0b00000010)){  //스위치5(PE1 비트 0인지 조사)
            // 바닥까지 내리기
            while(stop){
                // 아래 한 칸 이동 가능한지 조사
                stop = p1_blk_check(0, 1);
                if(stop != 0){  // 안 겹치면 현지블록 지우고 이동
                    p1_blk_clear();  // 현재 블록 데이터 클리어
                    p1_by += 1;   // 블록 Y 좌표 +1
                    p1_blk_copy();  // 블록 데이터 복사
                }
                p1_down_cnt = 100;
            }
        }
        else{
            if(wait == 0){
                p1_stage = 0;
                level = 22;   // 블록 이동 속도 초기 설정
                stage_out();
                start = 1;   // 대기상태에서 게임시작
            }
       }
    }
}

코드비젼 상태에서도 미완성 소스군요
참고하세요
추가문의는 네이버카페 전자공작 http://cafe.naver.com/circuitsmanual.cafe

2012.12.25.

  • 채택

    질문자가 채택한 답변입니다.

도움이 되었다면 UP 눌러주세요!
UP이 많은 답변일수록 사용자들에게 더 많이 노출됩니다.