581064d372e56a8075e1ab33b3658bf99791ae60
[mw/milkymist.git] / software / demo / osd.c
1 /*
2  * Milkymist VJ SoC (Software)
3  * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, version 3 of the License.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include <hal/vga.h>
19 #include <hal/tmu.h>
20 #include <math.h>
21 #include <hw/sysctl.h>
22 #include <hw/gpio.h>
23
24 #include "osd.h"
25 #include "font.h"
26 #include "logo.h"
27
28 int osd_x;
29 int osd_y;
30 #define OSD_W 600
31 #define OSD_H 160
32 #define OSD_CORNER 15
33 #define OSD_CHROMAKEY 0x001f
34
35 static struct tmu_vertex osd_vertices[TMU_MESH_MAXSIZE][TMU_MESH_MAXSIZE] __attribute__((aligned(8)));
36
37 static unsigned short int osd_fb[OSD_W*OSD_H] __attribute__((aligned(32)));
38
39 static struct font_context osd_font;
40
41 static void round_corners()
42 {
43         int i;
44         int d;
45         int x;
46
47         for(i=0;i<OSD_CORNER;i++) {
48                 d = OSD_CORNER - sqrtf(2*OSD_CORNER*i - i*i);
49                 for(x=0;x<d;x++) {
50                         osd_fb[i*OSD_W+x] = OSD_CHROMAKEY;
51                         osd_fb[i*OSD_W+(OSD_W-1-x)] = OSD_CHROMAKEY;
52                         osd_fb[(OSD_H-1-i)*OSD_W+x] = OSD_CHROMAKEY;
53                         osd_fb[(OSD_H-1-i)*OSD_W+(OSD_W-1-x)] = OSD_CHROMAKEY;
54                 }
55         }
56 }
57
58 #define LOGO_W 46
59 #define LOGO_H 46
60
61 static void logo()
62 {
63         int x, y;
64
65         for(y=0;y<LOGO_H;y++)
66                 for(x=0;x<LOGO_W;x++)
67                         osd_fb[(x+OSD_W-LOGO_W-OSD_CORNER)+OSD_W*(y+OSD_CORNER)] = ((unsigned short *)logo_raw)[x+LOGO_W*y];
68 }
69
70 static int previous_keys;
71 static int osd_alpha;
72 static int osd_timer;
73
74 #define OSD_MAX_ALPHA 40
75
76 void osd_init()
77 {
78         osd_x = (vga_hres - OSD_W) >> 1;
79         osd_y = vga_vres - OSD_H - 20;
80         
81         osd_vertices[0][0].x = 0;
82         osd_vertices[0][0].y = 0;
83         osd_vertices[0][1].x = OSD_W << TMU_FIXEDPOINT_SHIFT;
84         osd_vertices[0][1].y = 0;
85         osd_vertices[1][0].x = 0;
86         osd_vertices[1][0].y = OSD_H << TMU_FIXEDPOINT_SHIFT;
87         osd_vertices[1][1].x = OSD_W << TMU_FIXEDPOINT_SHIFT;
88         osd_vertices[1][1].y = OSD_H << TMU_FIXEDPOINT_SHIFT;
89
90         round_corners();
91         logo();
92
93         previous_keys = 0;
94         osd_alpha = OSD_MAX_ALPHA;
95         osd_timer = 125;
96
97         font_init_context(&osd_font, vera20_tff, osd_fb, OSD_W, OSD_H);
98         font_draw_string(&osd_font, OSD_CORNER, OSD_CORNER, "Rovastar - Touchdown on Mars");
99 }
100
101 static void process_keys(unsigned int keys)
102 {
103 }
104
105 static void osd_service()
106 {
107         unsigned int keys;
108         unsigned int new_keys;
109
110         keys = CSR_GPIO_IN & (GPIO_BTN1|GPIO_BTN2|GPIO_BTN3);
111         new_keys = keys & ~previous_keys;
112         previous_keys = keys;
113
114         if(new_keys) {
115                 osd_timer = 125;
116                 if(osd_alpha != 0)
117                         process_keys(new_keys);
118         }
119
120         osd_timer--;
121         if(osd_timer > 0) {
122                 osd_alpha += 4;
123                 if(osd_alpha > OSD_MAX_ALPHA)
124                         osd_alpha = OSD_MAX_ALPHA;
125         } else {
126                 osd_alpha--;
127                 if(osd_alpha < 0)
128                         osd_alpha = 0;
129         }
130 }
131
132 int osd_fill_blit_td(struct tmu_td *td, tmu_callback callback, void *user)
133 {
134         osd_service();
135
136         td->flags = TMU_CTL_CHROMAKEY;
137         td->hmeshlast = 1;
138         td->vmeshlast = 1;
139         td->brightness = TMU_BRIGHTNESS_MAX;
140         td->chromakey = OSD_CHROMAKEY;
141         td->vertices = &osd_vertices[0][0];
142         td->texfbuf = osd_fb;
143         td->texhres = OSD_W;
144         td->texvres = OSD_H;
145         td->texhmask = TMU_MASK_NOFILTER;
146         td->texvmask = TMU_MASK_NOFILTER;
147         td->dstfbuf = vga_backbuffer;
148         td->dsthres = vga_hres;
149         td->dstvres = vga_vres;
150         td->dsthoffset = osd_x;
151         td->dstvoffset = osd_y;
152         td->dstsquarew = OSD_W;
153         td->dstsquareh = OSD_H;
154         td->alpha = osd_alpha;
155         td->callback = callback;
156         td->user = user;
157
158         return osd_alpha != 0;
159 }