ce8fd7c1aeca22236c863598c9b64fb350360b3b
[my-code/arm.git] / betty / display.c
1 /*
2  * display.c - handling the display
3  *
4  * author: hackbard@hackdaworld.org
5  *
6  */
7
8 /*
9  * some comments on alpha blending!
10  * ################################
11  *
12  * if c is the result of layer a over layer b with opacity alpha:
13  * 
14  * c=alpha*a+(1-alpha)*b and if alpha is a byte (0-255)
15  * => c=alpha*a+(255-alpha)*b
16  * 
17  */
18
19 #include "display.h"
20 #include "system.h"
21 #include "default_logo.h"
22 #include "uart.h"
23
24 /*
25  * functions
26  */
27
28 void display_fill_screen(u8 fill) {
29
30         u8 page,width;
31         u8 buf[2];
32
33         buf[0]=0;
34         buf[1]=0;
35
36         switch(fill) {
37                 case DISPLAY_FILL_LG:
38                         buf[1]=0xff;
39                         break;
40                 case DISPLAY_FILL_DG:
41                         buf[0]=0xff;
42                         break;
43                 case DISPLAY_FILL_B:
44                         buf[0]=0xff;
45                         buf[1]=0xff;
46                         break;
47                 case DISPLAY_FILL_W:
48                 default:
49                         break;
50         }
51
52         for(page=0;page<DISPLAY_PAGE_MAX;page++) {
53                 DISPLAY_SET_C_ADDR(0);
54                 DISPLAY_SET_PAGE_ADDR(page);
55                 for(width=0;width<DISPLAY_DIMX;width++) {
56                         DISPLAY_DATA=buf[0];
57                         DISPLAY_DATA=buf[1];
58                 }
59         }
60 }
61
62 void display_clear_screen(void) {
63
64         display_fill_screen(DISPLAY_FILL_W);
65 }
66
67 void display_init(void) {
68
69         /* oscillator, regulator, boost, opamp, contrast */
70         DISPLAY_START_OSCILLATOR;
71         DISPLAY_SET_REGULATOR(7);
72         DISPLAY_SET_CONTRAST(0x38);
73         DISPLAY_SET_CONV_FACTOR(0x01);
74         DISPLAY_SET_POWER(DISPLAY_V_BOOST|DISPLAY_REGULATOR|DISPLAY_OPAMP);
75
76         // gray scale palette
77         DISPLAY_SET_WHITE(0,0,0,0);
78         DISPLAY_SET_LGRAY(5,5,5,5);     // obviously 3, but it's too bright!
79         DISPLAY_SET_DGRAY(7,7,7,7);     // obviously 6, but again too bright!
80         DISPLAY_SET_BLACK(9,9,9,9);
81
82         /* normal mode, display depending ram content */
83         DISPLAY_RAM_CONTENTS_ON;
84         display_clear_screen();
85         DISPLAY_NORMAL;                 // 00 -> white, 11 -> black
86         DISPLAY_SET_COM_ODIR_REMAPPED;  // start counting at the top
87
88         /* switch on the display */
89         DISPLAY_SET_ON;
90 }
91
92 void display_load_logo(u8 *src) {
93
94         u8 *s;
95         u8 page,width;
96
97         s=src;
98         if(s==0)
99                 s=default_logo;
100
101         for(page=0;page<DISPLAY_PAGE_MAX;page++) {
102                 DISPLAY_SET_C_ADDR(0);
103                 DISPLAY_SET_PAGE_ADDR(page);
104                 for(width=0;width<DISPLAY_DIMX;width++) {
105                         DISPLAY_DATA=*s++;
106                         DISPLAY_DATA=*s++;
107                 }
108         }
109 }
110
111 #define display_m2i(m,r) (((((m)[0]>>r)&1)<<1)|(((m)[1]>>r)&1))
112
113 void display_draw_rectangle(u8 x,u8 y,u8 w,u8 h,u8 fill,u8 alpha) {
114
115         u8 page,col,row,rmax,cnt;
116         u8 d[2];
117         int ca,cb;
118         u8 a,b,c;                       // c = a over b
119
120         a=fill&0x03;
121         ca=0;
122         for(cnt=0;cnt<a;cnt++)          // contribution of a: alpha*a
123                 ca+=alpha;
124
125         for(page=(y>>3);page<=((y+h)>>3);page++) {      // page = y/8
126                 DISPLAY_SET_PAGE_ADDR(page);
127                 rmax=(page+1)<<3;                       // row max
128                 if(rmax>y+h)
129                         rmax=y+h;
130                 for(col=x;col<x+w;col++) {
131                         DISPLAY_SET_C_ADDR(col);
132                         d[0]=DISPLAY_DATA;              // dummy read (p.16)
133                         d[0]=DISPLAY_DATA;
134                         d[1]=DISPLAY_DATA;
135                         for(row=y;row<rmax;row++) {
136                                 // contribution of b: (255-alpha)*b
137                                 b=display_m2i(d,row);
138                                 cb=0;
139                                 for(cnt=0;cnt<b;cnt++)
140                                         cb+=(255-alpha);
141                                 // finally there is c
142                                 c=(ca+cb)>>8;
143                                 d[0]&=~(1<<row);
144                                 d[1]&=~(1<<row);
145                                 d[0]|=((c>>1)&1)<<row;
146                                 d[1]|=(c&1)<<row;
147                         }
148                         DISPLAY_SET_C_ADDR(col);
149                         DISPLAY_DATA=b[0];
150                         DISPLAY_DATA=b[1];
151                 }
152                 y=rmax;
153         }
154 }
155
156 void display_draw_buf(u8 x,u8 y,u8 w,u8 h,u8 *buf,u8 alpha) {
157
158 }
159
160 void display_bl_init(void) {
161
162         IODIR0|=(1<<4);
163         IOSET0=(1<<4);  // off by default
164 }
165
166 void display_bl_toggle(void) {
167
168         if(IOPIN0&(1<<4))
169                 IOCLR0=(1<<4);
170         else
171                 IOSET0=(1<<4);
172 }
173
174 void display_bl_on(void) {
175
176         IOCLR0=(1<<4);
177 }
178
179 void display_bl_off(void) {
180
181         IOSET0=(1<<4);
182 }
183