zoukankan      html  css  js  c++  java
  • 三星S6D1121主控彩屏(240*320*18bit,262K)图形设备接口(GDI)实现

      上一篇随笔贴出了驱动程序, 这篇文章的代码主要就是针对上层的调用了, 但是, 其实, 只要是底层的驱动程序能能够工作了, 图形设备接口应该就可以随便移植的咯~
    一般彩屏的操作方式应该都是差不多的吧?
      上一篇随笔:http://www.cnblogs.com/nbsofer/archive/2012/11/26/2789239.html
      说明下, 本人不是很擅长图形方面的算法设计,  有些程序采用了大师们写的程序, 有些则是我自己写的(写得很差), 不过还是能够实现功能的哈~
      我测试程序时是用的死太惨的51单片机测试的, ROM比较小, 只有60KB(整个字库有大约225KB), 完全没法装进去的, 所以就把要用的保存进去了, 所以会有ascii.c/.h文件的存在, 当然, 如果后来会用SD/MMC/U盘, 那就太好了, 不过, 很遗憾的是, SD卡我一直没有能够成功读取~ 慢慢来吧.
      代码文件:
        ascii.c/ascii.h:字库文件
        common.c/common.h:一些公共的头文件/类型声明等等(和前面那篇随笔是一样的,没贴出)
        gdi.c/gdi.h:图形设备接口的实现
      有了这四个文件, 再加上前面的驱动程序, 把她们放到一个项目下, 就可以写程序调用了哈, 很方便的说~  

    该代码仅供51单片机测试使用, 需要大量的优化, 我已经把优化后的代码移植到MSP430上去了.
      由于51刷屏太慢,加上没时间,所以没有更新51版本的源代码,见谅~


    //ascii.h
    #ifndef __ASCIII_H__
    #define __ASCIII_H__
    
    uchar* asc_get_char(uchar uch);
    uchar* asc_get_word(uchar* word);
    uchar* asc_tpow(void);
    
    #endif// !__ASCIII_H__
    //ascii.c
    #include "common.h"
    
    //这个是two's pow(2的次方), 其实没什么必要的, 可以忽略
    uchar code t_p[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
    
    //这个是标准ASCII字符对应的像素值了
    //应该有注意到, 我这里是宽8*高12的, 而我却在上下各加
    //两个空行, 形成了宽8*高16的字符, 这样做的目的主要是为了方便
    //因为我的中文字库是用的16*16(不是很小)
    //是我从别人那里直接拷过来的, 看起来字体不是很好看
    //这个是不需要程序获取的, 程序只需做的是调用asc_get_char(your_char)
    //来得到一个字符数组的偏移就行了
    uchar code ascii[][12] = {
    /*   */{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
    /* ! */{0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00},
    /* " */{0x00,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
    /* # */{0x00,0x00,0x28,0x28,0xFC,0x28,0x50,0xFC,0x50,0x50,0x00,0x00},
    /* $ */{0x00,0x20,0x78,0xA8,0xA0,0x60,0x30,0x28,0xA8,0xF0,0x20,0x00},
    /* % */{0x00,0x00,0x48,0xA8,0xB0,0x50,0x28,0x34,0x54,0x48,0x00,0x00},
    /* & */{0x00,0x00,0x20,0x50,0x50,0x78,0xA8,0xA8,0x90,0x6C,0x00,0x00},
    /* ' */{0x00,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
    /* ( */{0x00,0x04,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x04,0x00},
    /* ) */{0x00,0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x00},
    /* * */{0x00,0x00,0x00,0x20,0xA8,0x70,0x70,0xA8,0x20,0x00,0x00,0x00},
    /* + */{0x00,0x00,0x20,0x20,0x20,0xF8,0x20,0x20,0x20,0x00,0x00,0x00},
    /* , */{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x80},
    /* - */{0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00},
    /* . */{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00},
    /* / */{0x00,0x08,0x10,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x80,0x00},
    /* 0 */{0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00},
    /* 1 */{0x00,0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00},
    /* 2 */{0x00,0x00,0x70,0x88,0x88,0x10,0x20,0x40,0x80,0xF8,0x00,0x00},
    /* 3 */{0x00,0x00,0x70,0x88,0x08,0x30,0x08,0x08,0x88,0x70,0x00,0x00},
    /* 4 */{0x00,0x00,0x10,0x30,0x50,0x50,0x90,0x78,0x10,0x18,0x00,0x00},
    /* 5 */{0x00,0x00,0xF8,0x80,0x80,0xF0,0x08,0x08,0x88,0x70,0x00,0x00},
    /* 6 */{0x00,0x00,0x70,0x90,0x80,0xF0,0x88,0x88,0x88,0x70,0x00,0x00},
    /* 7 */{0x00,0x00,0xF8,0x90,0x10,0x20,0x20,0x20,0x20,0x20,0x00,0x00},
    /* 8 */{0x00,0x00,0x70,0x88,0x88,0x70,0x88,0x88,0x88,0x70,0x00,0x00},
    /* 9 */{0x00,0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x48,0x70,0x00,0x00},
    /* : */{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x20,0x00,0x00},
    /* ; */{0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x20,0x00},
    /* < */{0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00},
    /* = */{0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0x00,0x00},
    /* > */{0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00},
    /* ? */{0x00,0x00,0x70,0x88,0x88,0x10,0x20,0x20,0x00,0x20,0x00,0x00},
    /* @ */{0x00,0x00,0x70,0x88,0x98,0xA8,0xA8,0xB8,0x80,0x78,0x00,0x00},
    /* A */{0x00,0x00,0x20,0x20,0x30,0x50,0x50,0x78,0x48,0xCC,0x00,0x00},
    /* B */{0x00,0x00,0xF0,0x48,0x48,0x70,0x48,0x48,0x48,0xF0,0x00,0x00},
    /* C */{0x00,0x00,0x78,0x88,0x80,0x80,0x80,0x80,0x88,0x70,0x00,0x00},
    /* D */{0x00,0x00,0xF0,0x48,0x48,0x48,0x48,0x48,0x48,0xF0,0x00,0x00},
    /* E */{0x00,0x00,0xF8,0x48,0x50,0x70,0x50,0x40,0x48,0xF8,0x00,0x00},
    /* F */{0x00,0x00,0xF8,0x48,0x50,0x70,0x50,0x40,0x40,0xE0,0x00,0x00},
    /* G */{0x00,0x00,0x38,0x48,0x80,0x80,0x9C,0x88,0x48,0x30,0x00,0x00},
    /* H */{0x00,0x00,0xCC,0x48,0x48,0x78,0x48,0x48,0x48,0xCC,0x00,0x00},
    /* I */{0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00},
    /* J */{0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0xE0,0x00},
    /* K */{0x00,0x00,0xEC,0x48,0x50,0x60,0x50,0x50,0x48,0xEC,0x00,0x00},
    /* L */{0x00,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0x44,0xFC,0x00,0x00},
    /* M */{0x00,0x00,0xD8,0xD8,0xD8,0xD8,0xA8,0xA8,0xA8,0xA8,0x00,0x00},
    /* N */{0x00,0x00,0xDC,0x48,0x68,0x68,0x58,0x58,0x48,0xE8,0x00,0x00},
    /* O */{0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00},
    /* P */{0x00,0x00,0xF0,0x48,0x48,0x70,0x40,0x40,0x40,0xE0,0x00,0x00},
    /* Q */{0x00,0x00,0x70,0x88,0x88,0x88,0x88,0xE8,0x98,0x70,0x18,0x00},
    /* R */{0x00,0x00,0xF0,0x48,0x48,0x70,0x50,0x48,0x48,0xEC,0x00,0x00},
    /* S */{0x00,0x00,0x78,0x88,0x80,0x60,0x10,0x08,0x88,0xF0,0x00,0x00},
    /* T */{0x00,0x00,0xF8,0xA8,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00},
    /* U */{0x00,0x00,0xCC,0x48,0x48,0x48,0x48,0x48,0x48,0x30,0x00,0x00},
    /* V */{0x00,0x00,0xCC,0x48,0x48,0x50,0x50,0x30,0x20,0x20,0x00,0x00},
    /* W */{0x00,0x00,0xA8,0xA8,0xA8,0x70,0x50,0x50,0x50,0x50,0x00,0x00},
    /* X */{0x00,0x00,0xD8,0x50,0x50,0x20,0x20,0x50,0x50,0xD8,0x00,0x00},
    /* Y */{0x00,0x00,0xD8,0x50,0x50,0x20,0x20,0x20,0x20,0x70,0x00,0x00},
    /* Z */{0x00,0x00,0xF8,0x90,0x10,0x20,0x20,0x40,0x48,0xF8,0x00,0x00},
    /* [ */{0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00},
    /* \ */{0x00,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x10,0x08,0x00,0x00},
    /* ] */{0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00},
    /* ^ */{0x00,0x20,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
    /* _ */{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC},
    /* ` */{0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
    /* a */{0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x38,0x48,0x3C,0x00,0x00},
    /* b */{0x00,0x00,0xC0,0x40,0x40,0x70,0x48,0x48,0x48,0x70,0x00,0x00},
    /* c */{0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x40,0x40,0x38,0x00,0x00},
    /* d */{0x00,0x00,0x18,0x08,0x08,0x38,0x48,0x48,0x48,0x3C,0x00,0x00},
    /* e */{0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x78,0x40,0x38,0x00,0x00},
    /* f */{0x00,0x00,0x1C,0x20,0x20,0x78,0x20,0x20,0x20,0x78,0x00,0x00},
    /* g */{0x00,0x00,0x00,0x00,0x00,0x3C,0x48,0x30,0x40,0x78,0x44,0x38},
    /* h */{0x00,0x00,0xC0,0x40,0x40,0x70,0x48,0x48,0x48,0xEC,0x00,0x00},
    /* i */{0x00,0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x70,0x00,0x00},
    /* j */{0x00,0x00,0x10,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0xE0},
    /* k */{0x00,0x00,0xC0,0x40,0x40,0x5C,0x50,0x70,0x48,0xEC,0x00,0x00},
    /* l */{0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00},
    /* m */{0x00,0x00,0x00,0x00,0x00,0xF0,0xA8,0xA8,0xA8,0xA8,0x00,0x00},
    /* n */{0x00,0x00,0x00,0x00,0x00,0xF0,0x48,0x48,0x48,0xEC,0x00,0x00},
    /* o */{0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x48,0x48,0x30,0x00,0x00},
    /* p */{0x00,0x00,0x00,0x00,0x00,0xF0,0x48,0x48,0x48,0x70,0x40,0xE0},
    /* q */{0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x48,0x48,0x38,0x08,0x1C},
    /* r */{0x00,0x00,0x00,0x00,0x00,0xD8,0x60,0x40,0x40,0xE0,0x00,0x00},
    /* s */{0x00,0x00,0x00,0x00,0x00,0x78,0x40,0x30,0x08,0x78,0x00,0x00},
    /* t */{0x00,0x00,0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x18,0x00,0x00},
    /* u */{0x00,0x00,0x00,0x00,0x00,0xD8,0x48,0x48,0x48,0x3C,0x00,0x00},
    /* v */{0x00,0x00,0x00,0x00,0x00,0xEC,0x48,0x50,0x30,0x20,0x00,0x00},
    /* w */{0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x70,0x50,0x50,0x00,0x00},
    /* x */{0x00,0x00,0x00,0x00,0x00,0xD8,0x50,0x20,0x50,0xD8,0x00,0x00},
    /* y */{0x00,0x00,0x00,0x00,0x00,0xEC,0x48,0x50,0x30,0x20,0x20,0xC0},
    /* z */{0x00,0x00,0x00,0x00,0x00,0x78,0x10,0x20,0x20,0x78,0x00,0x00},
    /* { */{0x00,0x18,0x10,0x10,0x10,0x20,0x10,0x10,0x10,0x10,0x18,0x00},
    /* | */{0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10},
    /* } */{0x00,0x60,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0x60,0x00},
    /* ~ */{0x40,0xA4,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
    };
    
    //用了一个结构体来索引
    //因为没有足够的空间来保存字库
    //所以就不能按照平常的区位码来索引汉字的代码了
    //which[3]:保存一个中文汉字,what[32]:保存的代码
    //生成方式:http://www.cnblogs.com/nbsofer/archive/2012/11/01/2749026.html
    //同样是内部使用, 外部程序只需要调用 asc_get_word(相对于*_char而言)(见下)
    struct wmap_s{
        uchar which[3];
        uchar what[32];
    } code wmap[] = {
        {"",{0x04,0x80,0x0E,0xA0,0x78,0x90,0x08,0x90,0x08,0x84,0xFF,0xFE,0x08,0x80,0x08,0x90,0x0A,0x90,0x0C,0x60,0x18,0x40,0x68,0xA0,0x09,0x20,0x0A,0x14,0x28,0x14,0x10,0x0C}},
        {"",{0x10,0x40,0x10,0x40,0x22,0x44,0x7F,0x7E,0x42,0x84,0x43,0x04,0x42,0x04,0x42,0x84,0x7E,0x64,0x42,0x24,0x42,0x04,0x42,0x04,0x42,0x04,0x7E,0x04,0x42,0x28,0x00,0x10}},
        {"",{0x0F,0xE0,0x08,0x20,0x08,0x20,0x0F,0xE0,0x08,0x20,0x08,0x20,0x0F,0xE0,0x00,0x04,0xFF,0xFE,0x01,0x00,0x09,0x20,0x09,0xF0,0x09,0x00,0x15,0x00,0x23,0x06,0x40,0xFC}},
        {"",{0x00,0x08,0x09,0xFC,0xFD,0x08,0x11,0x28,0x11,0x28,0x11,0x28,0x11,0x28,0x7D,0x48,0x11,0x48,0x11,0x48,0x10,0x40,0x1C,0xA0,0xF0,0xA0,0x41,0x22,0x02,0x22,0x0C,0x1E}},
        {"",{0x02,0x00,0x02,0x00,0x02,0x04,0xFF,0xFE,0x04,0x00,0x04,0x40,0x08,0x40,0x08,0x50,0x13,0xF8,0x30,0x40,0x50,0x40,0x90,0x40,0x10,0x40,0x10,0x44,0x17,0xFE,0x10,0x00}},
        {"",{0x00,0x08,0x04,0x08,0x7E,0x08,0x44,0x08,0x47,0xFE,0x44,0x08,0x44,0x08,0x7C,0x88,0x44,0x48,0x44,0x48,0x44,0x08,0x44,0x08,0x7C,0x08,0x44,0x48,0x00,0x28,0x00,0x10}},
        {"",{0x20,0x04,0x1B,0xFE,0x08,0x04,0x40,0x24,0x4F,0xF4,0x48,0x24,0x48,0x24,0x48,0x24,0x4F,0xE4,0x48,0x24,0x48,0x24,0x48,0x24,0x4F,0xE4,0x48,0x24,0x40,0x14,0x40,0x08}},
        {"",{0x00,0x08,0x43,0xFC,0x32,0x08,0x12,0x08,0x83,0xF8,0x62,0x08,0x22,0x08,0x0B,0xF8,0x10,0x00,0x27,0xFC,0xE4,0xA4,0x24,0xA4,0x24,0xA4,0x24,0xA4,0x2F,0xFE,0x20,0x00}},
        {"",{0x01,0x00,0x00,0x84,0x3F,0xFE,0x22,0x20,0x22,0x28,0x3F,0xFC,0x22,0x20,0x23,0xE0,0x20,0x00,0x2F,0xF0,0x22,0x20,0x21,0x40,0x20,0x80,0x43,0x60,0x8C,0x1E,0x30,0x04}},
        {"",{0x20,0x00,0x10,0x00,0x10,0x04,0x05,0xFE,0xFC,0x44,0x08,0x44,0x10,0x44,0x34,0x44,0x58,0x44,0x94,0x44,0x10,0x44,0x10,0x84,0x10,0x84,0x11,0x04,0x12,0x28,0x14,0x10}},
        {"",{0x10,0x40,0x10,0x40,0x10,0x40,0x10,0x80,0xFC,0x88,0x25,0x04,0x27,0xFE,0x24,0x02,0x24,0x04,0x49,0xFE,0x29,0x04,0x11,0x04,0x29,0x04,0x45,0x04,0x85,0xFC,0x01,0x04}},
        {"",{0x08,0x80,0x08,0x80,0x08,0x80,0x10,0x88,0x10,0x98,0x30,0xA0,0x50,0xC0,0x90,0x80,0x11,0x80,0x12,0x80,0x14,0x80,0x10,0x80,0x10,0x82,0x10,0x82,0x10,0x7E,0x10,0x00}},
    };
    
    
    //函数:asc_get_word(uchar* pword)
    //用来获取一个中文汉字的代码保存位置偏移
    //如果不存在, 返回NULL了(这里直接用0代替了)
    uchar* asc_get_word(uchar* pword)
    {
        uint k;
        uint len = sizeof(wmap)/sizeof(wmap[0]);
        for(k=0; k<len; k++){
            if(wmap[k].which[0] == pword[0] &&
                wmap[k].which[1] == pword[1])
            {
                return &wmap[k].what[0];
            }
        }
        return 0;
    }
    
    
    //同上, 不过这个是用来获取ASCII字符的
    //应该注意到的是:我是根据标准ASCII的顺序来索引ASCII字符的
    //所以,上面的ASCII字符代码表不能再添加/删除
    //当然, 中文字库不存在这个限制
    //使用:传入一个ASCII字符,返回编码的偏移(没有的话返回0)
    uchar* asc_get_char(char uch)
    {
        char idx;
        idx = (uch-32);//从空格算起, 控制字符就没用了,回车在其它程序中已经单独处理
        if(idx<0 || idx>sizeof(ascii)/sizeof(ascii[0]))
            return 0;
        return &ascii[idx][0];
    }
    
    //返回2的次方, 用得着的时候就用吧
    //比如: uchar* tp = asc_tpow();
    //tp[0]=2^7,tp[1]=2^6, ...
    uchar* asc_tpow(void)
    {
        return &t_p[0];
    }
    //gdi.h
    #ifndef __GDI_H__
    #define __GDI_H__
    
    #include "common.h"
    #include "s6d1121.h"
    
    //颜色描述表(前景色, 背景色)
    typedef struct color_table_s{
        uint fgc;
        uint bgc;
    }color_table;
    
    //很有用的rgb(r,g,b) 宏 rgb(红,绿,蓝)
    #define rgb(r,g,b) ((uint)(\
        ((uint)(uchar)(r)<<8 & 0xf800|(uchar)(r)>>7)|\
        ((uint)(uchar)(g)<<3 & 0x7e00)|\
        ((uint)(uchar)(b)>>2 | (uchar)(b)>>7)))
    
    //function prototype
    //函数的说明直接见各函数
    void rectangle(int left, int top, int width, int height, uint color);
    void line(int x1, int y1, int x2, int y2, uint color);
    void triangle(int x1, int y1, int x2, int y2, int x3, int y3, uint color);
    void set_pixel(uint x, uint y, uint color);
    void fill_rect(uint left, uint top, uint width, uint height, uint color);
    void clear_screen(uint color);
    void char_out(int x, int y, char ch, uint fgc, uint bgc);
    void word_out(int x, int y, uchar* pword, uint fgc, uint bgc);
    void text_out(int x, int y, uchar* str, uint fgc, uint bgc, color_table* pct);
    int cirpot(int x0,int y0,int x,int y,uint color);
    void circle(int x0,int y0,int r,uint color);
    float sin(float rad);
    uchar* itoa(int x);
    
    //some useful function macros
    //一些有用的宏,主要是用于把应用层的程序和驱动层的程序隔离
    //其实还是是调用的该驱动层的函数
    /* 设定待写入/读取数据的缓冲区:X坐标,Y坐标,宽,高 */
    #define set_area(x,y,width,height) LCD_SetAddress((x),(y),(width),(height))
    /* 在 set_area 调用后, 写入数据的操作 */
    #define set_data(dat) LCD_WriteData((dat))
    //初始化彩屏
    #define init_lcd LCD_Init
    //清屏
    #define clr_scr clear_screen
    //设定彩屏主控内部寄存器的值(不应该暴露给应用层的,以后再更新,必然的)
    #define set_reg(reg,value) LCD_WriteCmdWithData((reg),(value))
    #endif// !__GDI_H__
     
    //gdi.c
    #include "common.h"
    #include "gdi.h"
    #include "s6d1121.h"
    #include "ascii.h"
    
    //用来把指定的整数转换为字符串
    //保存在静态变量buf中并返回给调用者
    //显示0还是显示空格在于自己了
    uchar* itoa(int x)
    {
        static uchar buf[6];
        buf[0] = x/10000+'0';
        x %= 10000;
        buf[1] = x/1000+'0';
        x %= 1000;
        buf[2] = x/100+'0';
        x %= 100;
        buf[3] = x/10+'0';
        x %= 10;
        buf[4] = x+'0';
        buf[5] = 0;
        return &buf[0];
    }
    
    //画矩形的函数
    //参数:左上角的X坐标,左上角的Y坐标, 宽, 高, 颜色(有一些常用的颜色应该被定义,
    //下次再修改, 51的刷屏速度忍无可忍)
    void rectangle(int left, int top, int width, int height, uint color)
    {
        int x2,y2;
        x2 = left+width-1;
        y2 = top+height-1;
        //必须保存在有效范围内
        if(left<0 || top<0 || x2>239 || y2>319)
            return;
        //看到了吧, 实现就是转换成画直线
        //所以:最关键的怎样画点,直线
        line(left, top, x2, top, color);
        line(x2, top, x2, y2, color);
        line(x2, y2, left, y2, color);
        line(left, y2, left, top, color);
    }
    
    //画三角形, 参数为三个坐标点+颜色
    //其实还是是转换成画三条直线
    void triangle(int x1, int y1, int x2, int y2, int x3, int y3,uint color)
    {
        line(x1,y1,x2,y2, color);
        line(x2,y2,x3,y3, color);
        line(x1,y1,x3,y3, color);
    }
    
    //画直线, 可怜这是我自己写的算法, 效率太低了
    //而且,如果不仔细读读代码, 很难明白的
    //以后还是换成大师们已经写好了的吧
    //参数:两点成线, 不用多说, 当然, 颜色有要有的
    //画线就是转换成画点,所以关键是怎么画点,set_pixel再介绍
    void line(int x1, int y1, int x2, int y2, uint color)
    {
        int w,h;//记录长宽
        float rate1,rate2;//高与宽的比率
        int xaxis, yaxis, k;                                                              
        int ffalling = 0;//直线是否为下降沿
        if(x1>x2){
            k = x1; x1 = x2; x2 = k;
            k = y1; y1 = y2; y2 = k;
        }
        w = x2-x1+1;//get horizontal distance
        h = y2-y1;//get vertical distance
        if(h<0) h = -h;
        h = h+1;
        rate1 = (float)h/w;//根据相似三角形计算坐标
        rate2 = (float)w/h;
        if(w>h){//宽大于高
            ffalling = y1-y2;
            if(y1 == y2)
                ffalling = 0;
            for(k=0; k<w; k++){
                if(ffalling<0){
                    //+0.5是作四四舍五入
                    yaxis = y2-(uint)((w-k)*rate1+0.5)+1;
                }else if(ffalling>0){
                    yaxis = y1-(uint)(k*rate1+0.5)+1;
                }else{
                    yaxis = y1;
                }
                set_pixel(k+x1,yaxis, color);
            }
        }else{ //h>w
            ffalling = y1-y2;
            if(x1==x2)
                ffalling = 0;
            for(k=0; k<h; k++){
                if(ffalling<0){
                    xaxis = x1+(uint)(k*rate2+0.5)+1;
                }else if(ffalling>0){
                    xaxis = x1+((h-k)*rate2+0.5)+1;
                }else{
                    xaxis = x1;
                }
                set_pixel(xaxis, (y1<y2?y1:y2)+k, color);
            }   
        }
    }
    
    
    //这个就是画点函数了
    //set_area,set_data 完工
    void set_pixel(uint x, uint y, uint color)
    {
        if(x>239 || y>319) return;
        set_area(x, y, 1, 1);
        set_data(color);
    }
    
    //填充一块矩形为指定颜色
    void fill_rect(uint left, uint top, uint width, uint height, uint color)
    {
        uint a,b;
        if(left>239 || top>319) return;
        if(left+width-1>239) width = 239-left+1;//clip x border
        if(top+height-1>319) height = 319-top+1;//clip y border
        set_area(left, top, width, height);
        for(a=0; a<height; a++){
            for(b=0; b<width; b++){
                set_data(color);
            }
        }
    }
    
    //用 颜色 color 清屏
    void clear_screen(uint color)
    {
        uint i,j;
        set_area(0,0,240,320);
        for(i=0;i<320;i++){
            for (j=0;j<240;j++){
                set_data(color);
            }
        }
    }
    
    //在指定位置输出一个ASCII字符
    //属于内部调用函数
    //参数:X坐标,Y坐标,字符,前景色,背景色
    //如果不知道是怎样写字的, 看去看看我那篇
    //介绍字库的使用的文章吧(在前面)
    void char_out(int x, int y, char ch, uint fgc, uint bgc)
    {
        char k,i;
        uchar* pch = 0;
        uchar* t_p = asc_tpow();
        pch = asc_get_char(ch);
        if(!pch) return;
        //我的字库是8*12的
        //但是我把它转换成了8*16
        set_area(x, y, 8, 16);
        //所以我先写三行空白行
        for(k=0; k<24; k++){
            set_data(bgc);
        }
        for(k=0; k<12; k++){
            for(i=0; i<8; i++){
                set_data(*pch&t_p[i]?fgc:bgc);
            }
            pch++;
        }
        //再写一行空白行,用背景色填充
        for(k=0; k<8; k++){
            set_data(bgc);
        }
    }
    
    //前面是输出ASCII字符
    //这个是在指定位置输出指定的汉字
    //属于内部调用函数
    //参数:X坐标,Y坐标,一个汉字的数组(uchar数组,3个字符,2个最好,节约嘛),前景色,背景色
    void word_out(int x, int y, uchar* pword, uint fgc, uint bgc)
    {
        uchar xx,k,yy;
        uchar* pch = 0;
        uchar* t_p = asc_tpow();
        //"汉字两个都>=0xa0, 不然就是错的"
        if(pword[0]<0xa0 || pword[1]<0xa0)
            return;
        pch = asc_get_word(pword);
        if(!pch) return;
        //"需要检测x+15,y+15是否出界,则k应为实际打印的行/列数"
        //"并设定一个参数为是否依然打印不能完整打印的char/word"
        set_area(x,y,16,16);
        //16*2*8:32个字节就这样写进去咯
        for(k=0; k<16; k++){//16行
            for(yy=0; yy<2; yy++){//一行2个字节(16位)
                for(xx=0; xx<8; xx++){//一个字节8个位
                    set_data(*pch&t_p[xx]?fgc:bgc);
                }
                pch++;
            }
        }
    }
    
    //这个都是真正的输出文本的函数的
    //参数:X坐标,Y坐标,字符串指针,前景色,背景色,颜色索引表(可选)
    //说明:如果x,y均等于-1,则程序在上一次的结尾接着输出
    //仅可用的控制字符:'\n',换行
    void text_out(int x, int y, uchar* str, uint fgc, uint bgc, color_table* pct)
    {
        uchar* pch = str;
        uint k;
        uint fgcolor, bgcolor;
        //保存最近一次调用时的坐标
        static uchar lastx=0;
        static uint lasty=0;
        //判断是否为接着输出
        if(x==-1 && y==-1){
            x = lastx;
            y = lasty;
        }
        if(!pch) return;
        //遍历每个字符调用
        //  char_out 进行字符输出
        //  word_out 进行中文输出
        for(;*pch;){
            if(pct){
                fgcolor = pct->fgc;
                bgcolor = pct->bgc;
            }else{
                fgcolor = fgc;
                bgcolor = bgc;
            }
            if(*pch >= 0xa0){//word
                word_out(x, y, pch, fgcolor, bgcolor);
                x += 16;//more 8 pixels than chars
                pch++;
            }else if(*pch == '\n'){//换行处理
                x = 0;
                y += 16;
            }else{//char
                char_out(x, y, *pch, fgcolor, bgcolor);
                x += 8;
            }
            pch++;
            //check if return
            //word to next line
            //这里是当输出的汉字/字符不能完全显示是的处理(换行)
            if(/*x==240*/(*pch>=0xa0&&x>224) || x>232){//to next line
                if(*pch){
                    set_area(x,y,240,320);
                    for(k=0; k<16*(239-x+1); k++){
                        set_data(bgcolor);
                    }
                }
                x = 0;
                y += 16;
            }
            if(/*y==320*/y>304){//is bottom
                if(*pch){
                    set_area(x,y,240,320);
                    for(k=0; k<240*(319-y+1); k++){
                        set_data(bgcolor);
                    }               
                }
                y = 0;
            }
            if(pct) pct++;
        }
        lastx = x;
        lasty = y;
    }
    
    /*
    float sin(float rad)
    {
        float x1 = rad;
        float x3 = x1*rad*rad;
        float x5 = x3*rad*rad;
        float x7 = x5*rad*rad;
        return x1/1-x3/6+x5/120-x7/5040;
    }
    */
    /*float cos(float rad)
    {
        
    }*/
    
    //画圆函数
    //大师写的哦~ 膜拜
    //基本没看懂
    //不记得名字了, 好像是叫Bruce...画圆算法
    void circle(int x0,int y0, int r,uint color) 
    { 
        int x,y,d; 
        x=0; 
        y=(int)r; 
        d=(int)(3-2*r); 
        while(x<y){ 
            cirpot(x0,y0,x,y,color); 
            if(d<0){ 
                d+=4*x+6; 
            }else{ 
                d+=4*(x-y)+10; 
                y--; 
            } 
            x++; 
        } 
        if(x==y) 
            cirpot(x0,y0,x,y,color); 
    }
    
    int cirpot(int x0,int y0,int x,int y,uint color) 
    { 
        set_pixel((x0+x),(y0+y), color); 
        set_pixel((x0+y),(y0+x), color); 
        set_pixel((x0+y),(y0-x), color); 
        set_pixel((x0+x),(y0-y), color); 
        set_pixel((x0-x),(y0-y), color); 
        set_pixel((x0-y),(y0-x), color); 
        set_pixel((x0-y),(y0+x), color); 
        set_pixel((x0-x),(y0+y), color); 
        return 0; 
    } 
    
    /*int abs(int a, int b)
    {
        if(a>b) return a-b;
        else return b-a;
    }*/


    2013-04-20:
      更新一个小错误,上面的rgb貌似有点问题, 看起来也很复杂,换用下面这个代替之~

    //"rgb(r,g,b) 宏 rgb(红,绿,蓝)"
    #define rgb(r,g,b) ((uint)(\
        ((((uint)(r)&0xff)>>3)<<11)|\
        ((((uint)(g)&0xff)>>2)<<5)|\
        (((uint)(b)&0xff)>>3)))





    女孩不哭(QQ:191035066)@2012-12-09 00:12:55 http://www.cnblogs.com/nbsofer
    这篇随笔就至此结束吧, 还有一篇随笔, 有空再弄出来, 当然, 驱动层和中间层都写好了, 那就该写示例调用程序来应用下了.
    晚安!

  • 相关阅读:
    记一道乘法&加法线段树(模版题)
    2021CCPC网络赛(重赛)题解
    Codeforces Round #747 (Div. 2)题解
    F. Mattress Run 题解
    Codeforces Round #744 (Div. 3) G题题解
    AtCoder Beginner Contest 220部分题(G,H)题解
    Educational Codeforces Round 114 (Rated for Div. 2)题解
    Codeforces Global Round 16题解
    Educational Codeforces Round 113 (Rated for Div. 2)题解
    AtCoder Beginner Contest 182 F
  • 原文地址:https://www.cnblogs.com/memset/p/2809401.html
Copyright © 2011-2022 走看看