2 * display.c - handling the display
4 * author: hackbard@hackdaworld.org
9 * some comments on alpha blending!
10 * ################################
12 * if c is the result of layer a over layer b with opacity alpha:
14 * c=alpha*a+(1-alpha)*b and if alpha is a byte (0-255)
15 * => c=alpha*a+(255-alpha)*b
28 void display_fill_screen(u8 fill) {
52 for(page=0;page<DISPLAY_PAGE_MAX;page++) {
53 DISPLAY_SET_COL_ADDR(0);
54 DISPLAY_SET_PAGE_ADDR(page);
55 for(width=0;width<DISPLAY_DIMX;width++) {
62 void display_clear_screen(void) {
64 display_fill_screen(DISPLAY_FILL_W);
67 void display_init(void) {
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);
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);
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
88 /* switch on the display */
92 void display_logo(u8 *src) {
96 for(page=0;page<DISPLAY_PAGE_MAX;page++) {
97 DISPLAY_SET_COL_ADDR(0);
98 DISPLAY_SET_PAGE_ADDR(page);
99 for(width=0;width<DISPLAY_DIMX;width++) {
106 #define display_m2i(m,r) (((((m)[0]>>r)&1)<<1)|(((m)[1]>>r)&1))
108 void display_draw_rectangle(u8 x,u8 y,u8 w,u8 h,u8 fill,u8 alpha) {
110 u8 page,col,row,rmax,cnt;
113 u8 a,b,c; // c = a over b
117 for(cnt=0;cnt<a;cnt++) // contribution of a: alpha*a
120 for(page=(y>>3);page<=((y+h)>>3);page++) { // page = y/8
121 DISPLAY_SET_PAGE_ADDR(page);
122 rmax=(page+1)<<3; // row max
125 for(col=x;col<x+w;col++) {
126 DISPLAY_SET_COL_ADDR(col);
127 d[0]=DISPLAY_DATA; // dummy read (p.16)
130 row=DISPLAY_DATA; // aligne
131 for(row=y;row<rmax;row++) {
132 // contribution of b: (255-alpha)*b
133 b=display_m2i(d,row);
135 for(cnt=0;cnt<b;cnt++)
137 // finally there is c
141 d[0]|=((c>>1)&1)<<row;
144 DISPLAY_SET_COL_ADDR(col);
153 void display_rectangle_page(u8 x,u8 p,u8 w,u8 h,u8 fill,u8 alpha) {
159 for(page=p;page<p+h;page++) {
160 DISPLAY_SET_PAGE_ADDR(page);
161 for(col=x;col<x+w;col++) {
162 DISPLAY_SET_COL_ADDR(col);
163 buf[0]=DISPLAY_DATA; // dummy read
166 row=DISPLAY_DATA; // aligne dummy read
167 for(row=0;row<8;row++) {
168 b=display_m2i(buf,row);
169 c=(b*(255-alpha)+fill*alpha)>>8;
177 DISPLAY_SET_COL_ADDR(col);
184 void display_font_page(u8 x,u8 page,u8 *font,u8 fill) {
186 /* this only draws page aligned fonts! */
191 DISPLAY_SET_PAGE_ADDR(page);
193 /* read old content */
194 DISPLAY_SET_COL_ADDR(x);
195 c[0]=DISPLAY_DATA; // dummy read
196 for(cnt=0;cnt<16;cnt++) {
197 c[cnt++]=DISPLAY_DATA;
200 cnt=DISPLAY_DATA; // 2 byte aligne dummy read
202 /* write new content */
203 DISPLAY_SET_COL_ADDR(x);
204 for(cnt=0;cnt<16;cnt++) {
205 for(row=0;row<8;row++) {
206 if((font[cnt>>1]>>row)&1) {
209 c[cnt]|=(((fill>>1)&1)<<row);
210 c[cnt+1]|=((fill&1)<<row);
213 DISPLAY_DATA=c[cnt++];
218 void display_draw_font(u8 x,u8 y,u8 *font,u8 fill,u8 alpha) {
220 u8 page,col,row,rmax,cnt,left,cf,rf;
223 u8 a,b,c; // c = a over b
229 for(cnt=0;cnt<a;cnt++) // contribution of a: alpha*a
232 for(page=(y>>3);page<=((y+8)>>3);page++) { // page = y/8
233 DISPLAY_SET_PAGE_ADDR(page);
234 rmax=(page+1)<<3; // row max
238 for(col=x;col<x+8;col++) {
239 DISPLAY_SET_COL_ADDR(col);
240 d[0]=DISPLAY_DATA; // dummy read (p.16)
244 for(row=y;row<rmax;row++) {
245 // contribution of b: (255-alpha)*b
246 b=display_m2i(d,row);
248 for(cnt=0;cnt<b;cnt++)
250 // finally there is c
251 if((font[cf]>>row)&1) {
255 d[0]|=((c>>1)&1)<<row;
260 DISPLAY_SET_COL_ADDR(col);
270 void display_bl_init(void) {
273 IOSET0=(1<<4); // off by default
276 void display_bl_toggle(void) {
284 void display_bl_on(void) {
289 void display_bl_off(void) {