|
爱科技、爱创意、爱折腾、爱极致,我们都是技术控
您需要 登录 才可以下载或查看,没有账号?立即注册
x
SDL 是跨平台的,各种Linux平台、包括ARM-Linux、Os、Windows、WindowsCE等等,都可以。并且支持多种显示驱动。还有各种多媒体功能。关于怎么编译,这就不多说。
(先前用过MiniGUI,应该是有些坑)
(话说这分类,虽然ARM-LINUX也是ARM,但好像和论坛的ARM不是同一类)
下边是源码,后附编译参数
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <SDL/SDL.h>
#include <SDL/SDL_draw.h>
#include <SDL/SDL_ttf.h>
#include <SDL/SDL_thread.h>
struct POINT{
int x;
int y;
};
//==========================================================
SDL_Color colorWhite = {0xff, 0xff, 0xff}; //文字颜色
//画线用的几个颜色
Uint32 c_black, //底色,
c_white,
c_green,
c_red, //秒之色
c_cyan; //表盘上点的颜色
#define _UIx 0 //mainwindow left x
#define _UIy 0 //mainwindow topp y
#define _UIw 240 //width
#define _UIh 320 //height
#define _ClockX 81 //离左边
#define _ClockY 60 //离顶端,33刚好在双线下边
#define _R 40 //圆的直径
#define CNT 2 //表盘数
static int rx=_ClockX+_R, ry=_ClockY+_R, //表盘的中心
yO[]={0, 120}, //各表盘的偏移,这只偏移Y
oldHx[CNT]={0}, oldHy[CNT]={0}, //上次的坐标
oldMx[CNT]={0}, oldMy[CNT]={0},
oldSx[CNT]={0}, oldSy[CNT]={0};
#define _Text1_X 50 //第1行文字
#define _Text2_X 85 //第2行文字
//字体路径。个人用,字体就是windows\fonts目录拷贝过来
#ifdef __ARM_EABI__ //ARM
const char fntPath[] = "/mnt/sd/font/msyh.ttf";
#else //PC
const char fntPath[] = "/opt/msyh.ttf";
#endif
SDL_Surface *screen; //主界面
TTF_Font *font14; //显示文字的字体
SDL_TimerID tmr1; //定时器id
time_t tNow; //即时时间
struct tm *mytime;
const char *WK[]={"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
//==========================================================
void applySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination){
SDL_Rect offset; //Temporary rectangle to hold the offsets
offset.x = x; offset.y = y;//Get the offsets
SDL_BlitSurface(source, NULL, destination, &offset);//Blit the surface
}
void fillRectColor(SDL_Surface* destination, Uint32 color, int x, int y, int w, int h){
SDL_Rect rect;rect.x=x;rect.y=y;rect.w=w; rect.h=h;
// Uint32 color = SDL_MapRGB(destination->format, r, g, b); //蓝色
SDL_FillRect(screen, &rect, color); //整个屏幕填充颜色
}
void textOut(const char*text, TTF_Font *font1, int x, int y){
SDL_Surface * surface1 = TTF_RenderText_Solid(font1, text, colorWhite);
applySurface(x,y,surface1, screen);
SDL_FreeSurface(surface1);
}
//==========================================================
//模拟时钟的算法,来自网络,在这做了简化。
//==========================================================
//round's radius is 40 ,twelve point of it's 30 degree 表盘各字
const struct POINT PD_R40D30[]={ {40,0},{34,19},{20,34},{0,39},
{-19,34},{-34,20},{-40,0},{-34,-20},
{-19,-34},{0,-39},{20,-34},{34,-19}
};
const struct POINT PD_R30D6[]={
{30,0},{29,3},{29,6},{28,9},{27,12},{25,14},{24,17},{22,20},{20,22},{17,24},
{15,25},{12,27},{9,28},{6,29},{3,29},{0,29},{-3,29},{-6,29},{-9,28},{-12,27},
{-14,25},{-17,24},{-20,22},{-22,20},{-27,17},{-25,15},{-27,12},{-28,9},{-29,6},{-29,3},
{-29,0},{-29,-3},{-29,-6},{-28,-9},{-27,-12},{-25,-14},{-24,-17},{-22,-20},{-20,-22},{-17,-24},
{-15,-25},{-12,-27},{-9,-28},{-6,-29},{-3,-29},{0,-29},{3,-29},{6,-29},{9,-28},{12,-27},
{14,-25},{17,-24},{20,-22},{22,-20},{24,-17},{25,-15},{27,-12},{28,-9},{29,-6},{29,-3}
};
const struct POINT PD_R20D5[]={
{20,0},{19,1},{19,3},{19,5},{18,6},{18,8},{17,9},{16,11},{15,12},{14,14},
{12,15},{11,16},{10,17},{8,18},{6,18},{5,19},{3,19},{1,19},{0,19},{-1,19},
{-3,19},{-5,19},{-6,18},{-8,18},{-9,17},{-11,16},{-12,15},{-14,14},{-15,12},{-16,11},
{-17,10},{-18,8},{-18,6},{-19,5},{-19,3},{-19,1},{-19,0},{-19,-1},{-19,-3},{-19,-5},
{-18,-6},{-18,-8},{-17,-9},{-16,-11},{-15,-12},{-14,-14},{-12,-15},{-11,-16},{-10,-17},{-8,-18},
{-6,-18},{-5,-19},{-3,-19},{-1,-19},{0,-19},{1,-19},{3,-19},{5,-19},{6,-18},{8,-18},
{9,-17},{11,-16},{12,-15},{14,-14},{15,-12},{16,-11},{17,-10},{18,-8},{18,-6},{19,-5},
{19,-3},{19,-1}
};
//draw point(x,y) and four point side of it
void DispTimeSub(int x, int y, int r){
x=_ClockX+r+x;
y=_ClockY+r+y;
Draw_Pixel(screen, x,y, c_cyan);
Draw_Pixel(screen, x+1,y,c_cyan);
Draw_Pixel(screen, x-1,y,c_cyan);
Draw_Pixel(screen, x,y+1,c_cyan);
Draw_Pixel(screen, x,y-1,c_cyan);
}
//draw point(x,y)'s top and under line
void DispTimeSubHL(int x, int y, int r){
x=_ClockX+r+x;
y=_ClockY+r+y;
Draw_Line(screen, x, y-1, x-3, y-1, c_cyan);
Draw_Line(screen, x, y+1, x-3, y+1, c_cyan);
}
//draw point(x,y)'s top and under line
void DispTimeSubHR(int x, int y, int r){
x=_ClockX+r+x;
y=_ClockY+r+y;
Draw_Line(screen, x, y-1, x+3, y-1, c_cyan);
Draw_Line(screen, x, y+1, x+3, y+1, c_cyan);
}
void DispTimeSubLT(int x, int y, int r){
x=_ClockX+r+x;
y=_ClockY+r+y;
Draw_Line(screen, x-1, y, x-1, y-4, c_cyan);
Draw_Line(screen, x+1, y, x+1, y-4, c_cyan);
}
void DispTimeSubLB(int x, int y, int r){
x=_ClockX+r+x;
y=_ClockY+r+y;
Draw_Line(screen, x-1, y, x-1, y+4, c_cyan);
Draw_Line(screen, x+1, y, x+1, y+4, c_cyan);
}
void DrawTimeFrame(int y){ //画表盘
Draw_Line(screen, 0, y, 240, y, c_green);
Draw_Line(screen, 0, y+2, 240, y+2, c_cyan);
int i, j;
for(j=0; j<CNT; j++){
for(i=0; i<12; i++){
switch(i){
case 0: DispTimeSubHL(PD_R40D30.x,PD_R40D30.y+yO[j],40);break; //Right
case 3: DispTimeSubLT(PD_R40D30.x,PD_R40D30.y+yO[j],40);break; //Bottom
case 6: DispTimeSubHR(PD_R40D30.x,PD_R40D30.y+yO[j],40);break; //Left
case 9: DispTimeSubLB(PD_R40D30.x,PD_R40D30.y+yO[j],40);break; //TOP
default:
DispTimeSub(PD_R40D30.x, PD_R40D30.y+yO[j],40);
}
}
}
}
void DrawClock(int i){ //画时钟针
int x, y, n, m;
if((oldSx+oldSy) != 0){
Draw_Line(screen, rx,ry+yO,oldSx,oldSy, c_black);
Draw_Line(screen, rx,ry+yO,oldMx,oldMy, c_black);
Draw_Line(screen, rx,ry+yO,oldHx,oldHy, c_black);
}
n=(mytime->tm_sec+45)%60;
x=_ClockX+_R+PD_R30D6[n].x;
y=_ClockY+_R+PD_R30D6[n].y+yO;
//show second hand
Draw_Line(screen, rx, ry+yO,x,y, c_red);
oldSx=x; oldSy=y;
//calculate min whether or not move
//note: the array of PD_R30D6 begin at right place,that the place of 3 hour.
//mytime->tm_min/60 is percent the first 60 is clock divide up 60 part
//see above note,when n is 0,it must add 45 from 3 hour place.
n=(mytime->tm_min+45)%60;
x=_ClockX+_R+PD_R30D6[n].x;
y=_ClockY+_R+PD_R30D6[n].y+yO;
Draw_Line(screen, rx, ry+yO,x,y, c_green);
oldMx=x; oldMy=y;
//calculate hour*60+minute.
//the 72 is clock divide up 72 part. the same as minute disposal
m=mytime->tm_min+(mytime->tm_hour%12)*60;
n=(m/10+54)%72;
x=_ClockX+_R+PD_R20D5[n].x;
y=_ClockY+_R+PD_R20D5[n].y+yO;
Draw_Line(screen, rx, ry+yO,x,y, c_white);
oldHx=x; oldHy=y;
}
void DrawTimeText(int i){ //文字
char buf[21];
sprintf(buf, "%d-%02d-%02d %s",
mytime->tm_year+1900, mytime->tm_mon+1,mytime->tm_mday, WK[mytime->tm_wday]);
if(0==i)
fillRectColor(screen, c_black, _Text1_X, 1+yO[0], 200, 20); //清除旧字
fillRectColor(screen, c_black, _Text2_X, 30+yO, 200, 20);
if(0==i)
textOut(buf, font14, _Text1_X, 1+yO[0]); //年月日
memset(buf, 0, 21);
sprintf(buf, "%02d:%02d:%02d",mytime->tm_hour,mytime->tm_min,mytime->tm_sec);
textOut(buf, font14, _Text2_X, 30+yO); //时分秒
SDL_UpdateRect(screen, _Text1_X, 1, _UIw-_Text1_X, 50+yO); //局部更新屏幕
}
//==========================================================
static Uint32 SDLCALL timerProc(Uint32 interval, void *param){ // SDL_AddTimer()
// printf("timerProc:%d, %d\n", interval, (int)(uintptr_t)param);
time(&tNow);
mytime=localtime(&tNow);
DrawClock(0);
DrawTimeText(0);
tNow=tNow-8*3600;
mytime=localtime(&tNow);
DrawClock(1);
DrawTimeText(1);
SDL_UpdateRect(screen, _ClockX, _ClockY, _UIw-_ClockX, _UIh-_ClockY); //局部更新屏幕
return interval;
}
//==========================================================
int main(int argc, char *argv[]){
int bStop = 0;
SDL_Event event;
if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTTHREAD) < 0 ) {
fprintf(stderr, "SDL_Init(): %s", SDL_GetError());
exit(1);
}
atexit(SDL_Quit); //退出"事件"
screen = SDL_SetVideoMode(_UIw, _UIh, 16, SDL_SWSURFACE); //Video mode activation
if (!screen) {
fprintf(stderr, "Video mode: %dx%d %s\n",_UIw,_UIh,SDL_GetError());
exit(2);
}
c_black = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
c_white = SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF);
c_green = SDL_MapRGB(screen->format, 0x00, 0xFF, 0x00);
c_cyan = SDL_MapRGB(screen->format, 0x00, 0xFF, 0xFF);
c_red = SDL_MapRGB(screen->format, 0xFF, 0x00, 0x00);
if(TTF_Init()==-1){
printf("TTF_Init: %s\n", TTF_GetError());
}
font14 = TTF_OpenFont((const char *)fntPath, 18); //字体大小,随要求改变
if(!font14){
printf("TTF_OpenFont: Open .ttf %s\n", TTF_GetError());
TTF_Quit();
return 1;
}
fillRectColor(screen, c_black, 0, 0, _UIw, _UIh);
DrawTimeFrame(27); //上2行
SDL_UpdateRect(screen,0,0,0,0); //更新整个屏幕
tmr1=SDL_AddTimer(995, timerProc, (void*)1);
/* 事件处理,鼠标点击、任意按键、点击X,或控制台CTRL+C,都退出程序 */
while( ! bStop ){
if(SDL_PollEvent(&event) ){
switch (event.type) {
case SDL_MOUSEBUTTONDOWN: /*break;*/
case SDL_KEYDOWN: /*break;*/
case SDL_QUIT:
bStop = 1;
break;
default:
break;
}
}
if(bStop)break;
SDL_Delay(20);
}
if(tmr1)SDL_RemoveTimer(tmr1);
if(font14 )TTF_CloseFont(font14);
TTF_Quit();
return 0;
}
/*
编译、执行
假设 SDL 1.2 默认安装
OPT_xib=-lpthread\ -lm\ -O3\ -Wall\ -ldl\ -liconv\ -lz\ -lfreetype
OPT_xib=${OPT_xib}\ -lSDL\ -lSDL_image\ -lSDL_net\ -lSDL_ttf\ -lSDL_mixer\ -lSDL_draw
gcc ${OPT_xib} sdl_clock.c -o sdl_clock && ./sdl_clock
SDL是跨平台的。如,arm就是引用不同的include和lib。
*/
|
|