?? fk.c
字號:
#include <excalibur.h>
#include <system.h>
#include "altera_avalon_dma.h"
#include "altera_avalon_cfi_flash.h"
#include "altera_avalon_timer.h"
#define VGA_WIDTH 640
#define VGA_HEIGHT 480
#define H_FKN 10
#define V_FKN 18
#define FK_SIZE 16
const int FK_RAWS[28][4][4]={
{{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}},
{{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}},
{{0,1,0,0},{0,1,1,0},{0,0,1,0},{0,0,0,0}},
{{0,0,0,0},{0,1,1,0},{1,1,0,0},{0,0,0,0}},
{{0,0,1,0},{0,1,1,0},{0,1,0,0},{0,0,0,0}},
{{0,0,0,0},{1,1,0,0},{0,1,1,0},{0,0,0,0}},
{{0,1,0,0},{1,1,0,0},{1,0,0,0},{0,0,0,0}},
{{1,1,0,0},{0,1,1,0},{0,0,0,0},{0,0,0,0}},
{{0,1,0,0},{1,1,1,0},{0,0,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,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},{1,1,1,0},{1,0,0,0},{0,0,0,0}},
{{1,1,0,0},{0,1,0,0},{0,1,0,0},{0,0,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,0,0},{1,1,1,1},{0,0,0,0},{0,0,0,0}},
{{0,1,0,0},{0,1,0,0},{0,1,0,0},{0,1,0,0}},
{{0,0,0,0},{1,1,1,1},{0,0,0,0},{0,0,0,0}},
{{0,1,0,0},{0,1,0,0},{0,1,0,0},{0,1,0,0}}
};
typedef struct{
int data[4][4];
int index;
int x,y;
}FK_STRUCT;
static unsigned int V_nWidth = H_FKN*FK_SIZE;
static unsigned int V_nHeight =V_FKN*FK_SIZE;
static unsigned char FK_DATA[V_FKN][H_FKN];
static FK_STRUCT FK_CUR, FK_NEXT;
static volatile unsigned char *p_VGA_RAM= (unsigned char *)na_sdram+0x0100;
const unsigned long TLENGTH = VGA_WIDTH * VGA_HEIGHT;
static np_timer *timer = na_timer1;
const int LEVEL[10] = {2000, 1500, 1000, 3000, 600, 500, 400, 300, 200, 100};
const long SCORE[10]= {0, 100, 300, 1000, 3000, 10000, 30000, 100000, 300000, 1000000};
static int G_nRows, G_nScore, G_nBestScore, G_nLevel;
static int G_nRunning;
void clear_bk (unsigned int left, unsigned int top, unsigned int width, unsigned int height, unsigned char color);
void draw_pixel (unsigned int x, unsigned int y, unsigned char color);
void clear_fkdata(void);
void rand_fk(FK_STRUCT *fk);
void rotate_fk(FK_STRUCT *fk, int bT);
void add_cur_fk(FK_STRUCT *fk);
void copy_fk_next();
void move_fk_left();
void move_fk_right();
void move_fk_down();
void move_fk_rotate();
int check_fk(FK_STRUCT *fk);
int clear_full_row ();
void draw_fkdata (unsigned int left , unsigned int top, unsigned char color);
void draw_cur_fk(unsigned int left, unsigned int top, FK_STRUCT *fk, unsigned char color);
void update_score( int rows);
void init_fk (void);
void init_dma (void);
void isr_dma (int context);
int main (void)
{
np_pio *pbtn = na_pio_0;
int curValue, lastValue = pbtn->np_piodata;
int count = 0;
init_fk();
init_dma();
while (1)
{
curValue = pbtn->np_piodata;
if ((curValue !=lastValue)&& (lastValue == 0x000F))
{
draw_cur_fk((VGA_WIDTH - V_nWidth)/2,
(VGA_HEIGHT - V_nHeight)/2, &FK_CUR, 0x00);
switch (curValue & 0x000F)
{
case 0x000E:
if(G_nRunning) move_fk_right();
break;
case 0x000D:
if(G_nRunning) move_fk_left();
break;
case 0x000B:
if (G_nRunning) move_fk_down();
break ;
case 0x0007:
if (G_nRunning) move_fk_rotate();
else
{
G_nRunning = 1;
clear_bk((VGA_WIDTH - V_nWidth)/2 + 1,
(VGA_HEIGHT -V_nHeight)/2 + 1,
V_nWidth-2, V_nHeight-2, 0x00);
srand (count);
}
break;
default: break; }
}
if (G_nRunning)
draw_cur_fk((VGA_WIDTH-V_nWidth)/2,
(VGA_HEIGHT-V_nHeight)/2, &FK_CUR, 0x02);
nr_delay (20);
lastValue = curValue;
if(G_nRunning&&(timer->np_timerstatus & np_timerstatus_to_mask))
{
if(++count>=LEVEL[G_nLevel])
{
draw_cur_fk((VGA_WIDTH -V_nWidth)/2,
(VGA_HEIGHT-V_nHeight)/2, &FK_CUR, 0x00);
move_fk_down();
draw_cur_fk((VGA_WIDTH-V_nWidth)/2,
(VGA_HEIGHT-V_nHeight)/2, &FK_CUR, 0x02);
count=0;
}
timer->np_timerstatus=0;
}
}
};
void draw_pixel(unsigned int x, unsigned int y, unsigned char color)
{
unsigned long addr;
if(x > VGA_WIDTH)
x %= VGA_WIDTH;
if(y > VGA_HEIGHT)
y %= VGA_HEIGHT;
addr = VGA_WIDTH*y+x;
p_VGA_RAM[addr]=color;
};
void clear_bk( unsigned int left, unsigned int top,
unsigned int width, unsigned int height, unsigned char color)
{
unsigned long addr;
unsigned int i, j;
for(i=0; i<height; ++i)
{
for(j =0; j<width; ++j)
{
addr = (VGA_WIDTH * (top + i)) + left + j;
if (addr > TLENGTH)
addr %= TLENGTH;
p_VGA_RAM[addr] =color ;
}
}
};
void clear_fkdata(void)
{
int i, j;
for (i = 0; i<V_FKN; ++i)
for(j=0;j<H_FKN; ++j)
FK_DATA[i][j]=0;
};
void rand_fk(FK_STRUCT *fk)
{
int i, index;
if (!fk)
return;
srand(timer->np_timersnapl);
index = rand() % 28;
for (i=0;i<16; ++i)
fk->data[i/4][1%4]=FK_RAWS[index][i/4][i%4];
fk->index = index;
fk->x =H_FKN/2-2;
fk->y = 0;
for(i=0; i<16; ++i)
{
if(fk->data[i/4][i%4] > 0)
break;
}
fk->y-= i/4;
};
void draw_fkdata(unsigned int left, unsigned int top,
unsigned char color)
{int i, j;
for (i = 0; i < V_FKN; ++i)
for(j = 0; j < H_FKN; ++j)
{
if(FK_DATA[i][j]>0)
clear_bk(left + (j * FK_SIZE) + 1,
top+(i * FK_SIZE) + 1,
FK_SIZE-2, FK_SIZE-2, color);
}
};
void draw_cur_fk( unsigned int left, unsigned int top,
FK_STRUCT *fk, unsigned char color)
{
int i, j, px, py;
if(!fk)
return;
for (i = 0; i < 4; ++i)
{
py = fk->y + i;
for (j = 0; j < 4; ++j)
{
px = fk->x + j;
if (fk->data[i][j]>0 && px >=0 &&
px < H_FKN && py >=0 && py<V_FKN)
clear_bk(left + px * FK_SIZE + 1,
top + py * FK_SIZE + 1,
FK_SIZE-2, FK_SIZE-2, color);
}
}
};
void rotate_fk(FK_STRUCT *fk, int bT)
{
int i, index =fk->index;
if (!fk)
return;
if(bT > 0)
index = ((index >> 2) << 2) + (((index % 4) + 1) % 4);
else
index = ((index >> 2) << 2) + (((index % 4) + 3) % 4);
for(i =0; i<16; ++i)
fk->data[i/4][i%4]=FK_RAWS [index] [i/4][i%4];
fk->index =index;
for(i =0;i<16; ++i)
{
if(fk->data[i%4][i/4]>0)
break;
}
if(fk->x + i/4<0)
fk->x = 0-i/4;
for(i=0; i<16; ++i)
{
if(fk->data[i%4][4-i/4-1]> 0)
break;
}
if(fk->x+4-i/4 >= H_FKN)
fk->x = H_FKN-4+i/4;
};
int check_fk(FK_STRUCT *fk)
{
int i, j, py, px;
if(!fk)
return 0;
for(i = 0; i < 4; ++i)
{
py = fk->y + i;
for (j = 0; j < 4; ++j)
{
px = fk->x + j;
if(fk->data[i][j] > 0 && px >= 0 &&
px<H_FKN && py >= 0 &&py <= V_FKN)
{
if (py == V_FKN||FK_DATA[py][px] >0)
{
while (i>0 && fk->data[--i][j]>0)
--py;
if(py<=1)
return V_FKN;
else
return 1;
}
}
}
}
return 0;
}
void add_cur_fk(FK_STRUCT *fk)
{
int i, j, px, py;
if(!fk)
return;
for (i = 0; i < 4; ++i)
{
py = fk->y +i;
for(j=0; j<4; ++j)
{
px = fk->x +j;
if (fk->data[i][j] > 0 && px >= 0 &&
px < H_FKN && py >= 0 && py < V_FKN)
FK_DATA[py][px] = fk->data[i][j];
}
}
};
void copy_fk_next ()
{int i;
for(i=0; i<16; ++i)
FK_CUR.data[i/4][i%4] = FK_NEXT.data[i/4][i&4];
FK_CUR.index = FK_NEXT.index;
FK_CUR.x = H_FKN/2 - 2;
FK_CUR.y = 0;
for (i = 0; i < 16; ++i)
{
if(FK_CUR.data[i/4][i%4] > 0)
break;
}
FK_CUR.y-= i/4;
}
int clear_full_row ()
{
int i, j, k, c = 0;
int bFull ;
for (i=V_FKN-1; i >0;--i)
{
bFull = 1;
for(j = 0;j<H_FKN;++j)
if(FK_DATA[i][j] == 0)
{
bFull = 0;
break;
}
if(bFull)
{
k = i;
while (k > 0)
{
for(j =0; j<H_FKN; ++j)
FK_DATA[k][j] = FK_DATA[k -1] [j];
k--;
}
c++;
i++;
}
}
update_score(c);
return c;
};
void update_score(int rows)
{
int i;
if (rows < 0)
return;
G_nRows += rows;
switch(rows)
{
case 1:
G_nScore += 10 + (1 << G_nLevel);
break;
case 2:
G_nScore += 20 + (2 << G_nLevel);
break;
case 3:
G_nScore += 50 + (4 << G_nLevel);
break ;
case 4:
G_nScore += 100 + (8 << G_nLevel);
break ;
default:
break ;
}
if (G_nScore > G_nBestScore)
G_nBestScore = G_nScore;
for(i = 9; i >= 0;--i)
{
if (G_nScore > SCORE[i]|| i == 0)
break;
}
G_nLevel = i;
clear_bk((VGA_WIDTH+V_nWidth) / 2 + 50,
(VGA_HEIGHT - V_nHeight) / 2 + (6* FK_SIZE),
100, 8 * FK_SIZE, 0x00);
};
void move_fk_left(void)
{
int i, ret;
FK_CUR.x--;
ret = check_fk(&FK_CUR);
if (ret > 0)
FK_CUR.x++;
for (i = 0; i < 16; ++i)
{
if(FK_CUR.data[i%4][i/4] > 0 )
break ;
}
if(FK_CUR.x + i/4 < 0)
FK_CUR.x = 0 - i/4;
};
void move_fk_right (void)
{
int i, ret;
FK_CUR.x++;
ret = check_fk(&FK_CUR);
if (ret > 0)
FK_CUR.x--;
for (i = 0; i < 16; ++i)
{
if(FK_CUR.data[i%4] [4-i/4-1] > 0)
break;
}
if (FK_CUR.x + 4 - i/4 >= H_FKN)
FK_CUR.x = H_FKN - 4 + i/4;
};
void move_fk_down (void)
{
int ret ;
FK_CUR.y++ ;
ret = check_fk(&FK_CUR);
if (ret == 1)
{
FK_CUR.y--;
add_cur_fk(&FK_CUR);
draw_fkdata( (VGA_WIDTH -V_nWidth) /2,
(VGA_HEIGHT -V_nHeight) /2, 0x06);
if (clear_full_row() > 0)
{
clear_bk((VGA_WIDTH -V_nWidth) / 2 +1,
(VGA_HEIGHT - V_nHeight) / 2 + 1,
V_nWidth -2, V_nHeight-2, 0x00);
draw_fkdata((VGA_WIDTH -V_nWidth) / 2,
(VGA_HEIGHT - V_nHeight) / 2 , 0x06);
}
copy_fk_next();
draw_cur_fk((VGA_WIDTH + V_nWidth) / 2,
(VGA_HEIGHT -V_nHeight) / 2 +20, &FK_NEXT, 0x00);
rand_fk(&FK_NEXT);
draw_cur_fk((VGA_WIDTH + V_nWidth) / 2,
(VGA_HEIGHT -V_nHeight) / 2 + 20, &FK_NEXT, 0x02);
}
else if (ret == V_FKN)
{
clear_fkdata () ;
copy_fk_next () ;
draw_cur_fk((VGA_WIDTH + V_nWidth) / 2,
(VGA_HEIGHT -V_nHeight) / 2 + 20, &FK_NEXT, 0x00);
rand_fk(&FK_NEXT);
draw_cur_fk((VGA_WIDTH + V_nWidth) / 2,
(VGA_HEIGHT -V_nHeight) / 2 + 20, &FK_NEXT, 0x02);
G_nRunning = 0;
G_nRows = G_nScore = G_nBestScore = G_nLevel = 0;
}
};
void move_fk_rotate(void)
{
int i, ret;
i = FK_CUR.x;
rotate_fk(&FK_CUR, 1);
ret = check_fk(&FK_CUR);
if (ret > 0)
{
rotate_fk(&FK_CUR, 0);
FK_CUR.x = i;
}
};
void init_fk (void)
{
unsigned int i;
nr_timer_milliseconds();
timer->np_timercontrol = np_timercontrol_start_mask +
np_timercontrol_cont_mask;
G_nRows = G_nScore = G_nBestScore = G_nLevel = 0;
clear_bk(0, 0, VGA_WIDTH, VGA_HEIGHT, 0);
for(i=0; i < V_nWidth; ++i)
{
draw_pixel((VGA_WIDTH - V_nWidth) /2+ i,
(VGA_HEIGHT - V_nHeight) / 2, 0x02);
draw_pixel ((VGA_WIDTH - V_nWidth)/2 +i,
(VGA_HEIGHT + V_nHeight) / 2, 0x02);
}
for(i = 0; i < V_nHeight; ++i)
{
draw_pixel((VGA_WIDTH - V_nWidth) / 2,
(VGA_HEIGHT - V_nHeight) / 2 + i, 0x02);
draw_pixel((VGA_WIDTH +V_nWidth) / 2,
(VGA_HEIGHT - V_nHeight) / 2 + i, 0x02);
}
rand_fk(&FK_CUR);
rand_fk(&FK_NEXT);
update_score (0) ;
draw_cur_fk((VGA_WIDTH - V_nWidth) / 2,
(VGA_HEIGHT - V_nHeight) / 2+20, &FK_NEXT, 0x02);
}
void init_dma (void)
{np_dma *pdma = na_dma;
nr_installuserisr(na_dma_irq,
(nios_isrhandlerproc) isr_dma, (int) pdma );
pdma->np_dmacontrol = 0;
pdma->np_dmastatus = 0 ;
pdma->np_dmalength = TLENGTH;
pdma->np_dmareadaddress = (int)p_VGA_RAM;
pdma->np_dmawriteaddress = (int)na_vgastream;
pdma->np_dmacontrol = np_dmacontrol_go_mask |
np_dmacontrol_i_en_mask |
np_dmacontrol_hw_mask |
np_dmacontrol_ween_mask |
np_dmacontrol_wcon_mask |
np_dmacontrol_leen_mask ;
};
void isr_dma (int dma)
{
np_dma *pdma = (np_dma *)dma;
if (pdma->np_dmastatus & np_dmastatus_done_mask)
{
pdma->np_dmacontrol = 0;
pdma->np_dmastatus = 0;
pdma->np_dmalength = TLENGTH;
pdma->np_dmareadaddress = (int)p_VGA_RAM;
pdma->np_dmawriteaddress = (int)na_vgastream;
pdma->np_dmacontrol = np_dmacontrol_i_en_mask |
np_dmacontrol_go_mask |
np_dmacontrol_hw_mask |
np_dmacontrol_ween_mask |
np_dmacontrol_wcon_mask |
np_dmacontrol_leen_mask ;
}
};
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -