国旗表示プログラム
少し動きのあるプログラム作ろうと考えました。
1カ月前に、サッカーのワールドカップがありました。
決勝は、フランスとイタリアでした。
2つ国の国旗は、トリコロールで、左の色が青と緑かの
違いでした。
そこで、時間差で、国旗が変化していくプログラムを作成しました。
仕様
仕様を決めて作成しないと、バグの温床になるので、
メモをとりながら、仕様を決めていきます。
- 3色で構成されているものを国旗を利用する。
- 3色は、水平でも、垂直でもよい。
- 10カ国の国旗を表示する。
- 画面表示中は、端末に国名を表示する。
- 1カ国の国旗表示は、3秒とする。
- 構造体変数を1個用意し、それを表示関数に渡す。
ここまで、決めてから、必要な関数を作成し
実行してみました。
表示の変化を、確認できました。
ソースコード
/*
File name => cflags1.c
*/
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <linux/fs.h>
#include <sys/mman.h>
#define DEVICE_NAME "/dev/fb0"
#define DIV_BYTE 8
#define X_PIXEL_MAX 320
#define Y_LINE_MAX 240
#define X_BOUNDRY1 107
#define X_BOUNDRY2 214
#define Y_BOUNDRY1 79
#define Y_BOUNDRY2 159
/* 色定義 */
#define COLOR_RED 0xf800
#define COLOR_GREEN 0x07e0
#define COLOR_BLUE 0x001f
#define COLOR_WHITE 0xffff
#define COLOR_BLACK 0x0000
#define COLOR_YELLOW 0xffe0
/* 転送用の構造体変数定義 */
typedef struct {
int number ; /* 番号指定 */
int horizontal ; /* choose hozizontal , set 1 */
char national[25] ;
unsigned short int first_color ;
unsigned short int second_color ;
unsigned short int last_color ;
} NFLAGP ;
/* function prototype */
void send_current_error_msg(char *ptr);
void send_current_information(char *ptr);
void set_nflag_init(NFLAGP *ptr,int count);
void show_flag(char *ptr,NFLAGP nflg,int xoff,int yoff,int bpp,int len);
int main(void)
{
int fd_framebuffer ;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
long int screensize ;
char *fbptr ;
char tmp[DIV_BYTE*10];
NFLAGP nflag[10] ;
NFLAGP bflag ;
int xres,yres,vbpp,line_len;
int state ;
/* データ初期化 */
set_nflag_init(&nflag[0],10);
bflag.horizontal = 1 ;
bflag.first_color = COLOR_BLACK;
bflag.second_color = COLOR_BLACK;
bflag.last_color = COLOR_BLACK;
/* 読み書き用にファイルを開く */
fd_framebuffer = open( DEVICE_NAME , O_RDWR);
if ( !fd_framebuffer ) {
send_current_error_msg("Framebuffer device open error !");
exit(1);
}
/* send_current_information("The framebuffer device was opened !"); */
/* 固定スクリーン情報取得 */
if ( ioctl( fd_framebuffer , FBIOGET_FSCREENINFO , &finfo ) ) {
send_current_error_msg("Fixed information not gotton !");
exit(2);
}
/* 変動スクリーン情報取得 */
if ( ioctl( fd_framebuffer , FBIOGET_VSCREENINFO , &vinfo ) ) {
send_current_error_msg("Variable information not gotton !");
exit(3);
}
xres = vinfo.xres ; yres = vinfo.yres ; vbpp = vinfo.bits_per_pixel ;
line_len = finfo.line_length ;
/*
sprintf( tmp , "%d(pixel)x%d(line), %dbpp(bits per pixel)",xres,yres,vbpp);
send_current_information( tmp );
*/
/* バイト単位でのスクリーンのサイズを計算 */
screensize = xres * yres * vbpp / DIV_BYTE ;
/* デバイスをメモリにマップする */
fbptr = (char *)mmap(0,screensize,PROT_READ | PROT_WRITE,MAP_SHARED,fd_framebuffer,0);
if ( (int)fbptr == -1 ) {
send_current_error_msg("Don't get framebuffer device to memory !");
exit(4);
}
/* send_current_information("The framebuffer device was mapped !"); */
/* loop */
state = 0 ;
while ( 1 ) {
/* 国旗出力 */
show_flag(fbptr,nflag[state],vinfo.xoffset,vinfo.yoffset,vbpp,line_len);
/* 待ち */
sleep(3);
/* 更新 */
state++ ;
/* 終了チェック */
if ( state > 9 ) break ;
}
/* クリア */
show_flag(fbptr,bflag,vinfo.xoffset,vinfo.yoffset,vbpp,line_len);
/* */
munmap(fbptr,screensize);
close(fd_framebuffer);
return 0;
}
void send_current_error_msg(char *ptr)
{
fprintf( stderr , "%s\n" , ptr );
}
void send_current_information(char *ptr)
{
fprintf( stdout , "%s\n" , ptr );
}
void set_nflag_init(NFLAGP *ptr,int count)
{
/* check error */
if ( count < 1 ) return ;
/* 0 Netherlands */
ptr->number = 0 ; /* 番号指定 */
ptr->horizontal = 1 ; /* choose hozizontal , set 1 */
strcpy(ptr->national,"Netherlands");
ptr->first_color = COLOR_RED ;
ptr->second_color = COLOR_WHITE ;
ptr->last_color = COLOR_BLUE ;
ptr++ ;
/* 1 Germany */
ptr->number = 1 ; /* 番号指定 */
ptr->horizontal = 1 ; /* choose hozizontal , set 1 */
strcpy(ptr->national,"Germany");
ptr->first_color = COLOR_BLACK ;
ptr->second_color = COLOR_RED ;
ptr->last_color = COLOR_YELLOW ;
ptr++ ;
/* 2 Hungary */
ptr->number = 2 ; /* 番号指定 */
ptr->horizontal = 1 ; /* choose hozizontal , set 1 */
strcpy(ptr->national,"Hungary");
ptr->first_color = COLOR_RED ;
ptr->second_color = COLOR_WHITE ;
ptr->last_color = COLOR_GREEN ;
ptr++ ;
/* 3 Bulgaria */
ptr->number = 3 ; /* 番号指定 */
ptr->horizontal = 1 ; /* choose hozizontal , set 1 */
strcpy(ptr->national,"Bulgaria");
ptr->first_color = COLOR_WHITE ;
ptr->second_color = COLOR_GREEN ;
ptr->last_color = COLOR_RED ;
ptr++ ;
/* 4 Austria */
ptr->number = 4 ; /* 番号指定 */
ptr->horizontal = 1 ; /* choose hozizontal , set 1 */
strcpy(ptr->national,"Austria");
ptr->first_color = COLOR_RED ;
ptr->second_color = COLOR_WHITE ;
ptr->last_color = COLOR_RED ;
ptr++ ;
/* 5 Romania */
ptr->number = 5 ; /* 番号指定 */
ptr->horizontal = 0 ; /* choose hozizontal , set 1 */
strcpy(ptr->national,"Romania");
ptr->first_color = COLOR_BLUE ;
ptr->second_color = COLOR_YELLOW ;
ptr->last_color = COLOR_RED ;
ptr++ ;
/* 6 France */
ptr->number = 6 ; /* 番号指定 */
ptr->horizontal = 0 ; /* choose hozizontal , set 1 */
strcpy(ptr->national,"France");
ptr->first_color = COLOR_BLUE ;
ptr->second_color = COLOR_WHITE ;
ptr->last_color = COLOR_RED ;
ptr++ ;
/* 7 Italy */
ptr->number = 7 ; /* 番号指定 */
ptr->horizontal = 0 ; /* choose hozizontal , set 1 */
strcpy(ptr->national,"Italy");
ptr->first_color = COLOR_GREEN ;
ptr->second_color = COLOR_WHITE ;
ptr->last_color = COLOR_RED ;
ptr++ ;
/* 8 Mali */
ptr->number = 8 ; /* 番号指定 */
ptr->horizontal = 0 ; /* choose hozizontal , set 1 */
strcpy(ptr->national,"Mali");
ptr->first_color = COLOR_GREEN ;
ptr->second_color = COLOR_YELLOW ;
ptr->last_color = COLOR_RED ;
ptr++ ;
/* 9 Belgium */
ptr->number = 9 ; /* 番号指定 */
ptr->horizontal = 0 ; /* choose hozizontal , set 1 */
strcpy(ptr->national,"Belgium");
ptr->first_color = COLOR_BLACK ;
ptr->second_color = COLOR_YELLOW ;
ptr->last_color = COLOR_RED ;
}
void show_flag(char *ptr,NFLAGP nflg,int xoff,int yoff,int bpp,int len)
{
int x,y ;
unsigned short tcolor ;
unsigned short fcolor,scolor,lcolor ;
long int location ;
/* 国名出力 */
fprintf( stdout , "%s\n\r" , nflg.national );
fcolor = nflg.first_color ;
scolor = nflg.second_color ;
lcolor = nflg.last_color ;
/* 国旗出力 */
for ( y = 0 ; y < Y_LINE_MAX ; y++ ) {
if ( nflg.horizontal ) {
tcolor = fcolor ;
if ( y > Y_BOUNDRY2 ) tcolor = lcolor ;
else {
if ( y > Y_BOUNDRY1 ) tcolor = scolor ;
}
for ( x = 0 ; x < X_PIXEL_MAX ; x++ ) {
location = ((x+xoff) * bpp / DIV_BYTE) + (y+yoff) * len ;
*((unsigned short *)(ptr + location)) = tcolor;
}
} else {
for ( x = 0 ; x < X_PIXEL_MAX ; x++ ) {
tcolor = fcolor ;
if ( x > X_BOUNDRY2 ) tcolor = lcolor ;
else {
if ( x > X_BOUNDRY1 ) tcolor = scolor ;
}
location = ((x+xoff) * bpp / DIV_BYTE) + (y+yoff) * len ;
*((unsigned short *)(ptr + location)) = tcolor;
}
}
}
}