96f75cec471b3dde4d3b6e138818dde840b2bd6d
[pcsx_rearmed.git] / frontend / plat_omap.c
1 /*
2  * (C) GraÅžvydas "notaz" Ignotas, 2010-2012
3  *
4  * This work is licensed under the terms of the GNU GPLv2 or later.
5  * See the COPYING file in the top-level directory.
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
13 #include <sys/ioctl.h>
14 #include <unistd.h>
15 #include <linux/omapfb.h>
16
17 #include "common/menu.h"
18 #include "linux/fbdev.h"
19 #include "linux/xenv.h"
20 #include "plugin_lib.h"
21 #include "pl_gun_ts.h"
22 #include "plat.h"
23 #include "menu.h"
24
25 static struct vout_fbdev *main_fb, *layer_fb;
26
27 static int omap_setup_layer_(int fd, int enabled, int x, int y, int w, int h)
28 {
29         struct omapfb_plane_info pi = { 0, };
30         struct omapfb_mem_info mi = { 0, };
31         int ret;
32
33         ret = ioctl(fd, OMAPFB_QUERY_PLANE, &pi);
34         if (ret != 0) {
35                 perror("QUERY_PLANE");
36                 return -1;
37         }
38
39         ret = ioctl(fd, OMAPFB_QUERY_MEM, &mi);
40         if (ret != 0) {
41                 perror("QUERY_MEM");
42                 return -1;
43         }
44
45         /* must disable when changing stuff */
46         if (pi.enabled) {
47                 pi.enabled = 0;
48                 ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
49                 if (ret != 0)
50                         perror("SETUP_PLANE");
51         }
52
53         if (mi.size < 640*512*3*3) {
54                 mi.size = 640*512*3*3;
55                 ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi);
56                 if (ret != 0) {
57                         perror("SETUP_MEM");
58                         return -1;
59                 }
60         }
61
62         pi.pos_x = x;
63         pi.pos_y = y;
64         pi.out_width = w;
65         pi.out_height = h;
66         pi.enabled = enabled;
67
68         ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
69         if (ret != 0) {
70                 perror("SETUP_PLANE");
71                 return -1;
72         }
73
74         return 0;
75 }
76
77 static int omap_enable_layer(int enabled)
78 {
79         if (enabled)
80                 pl_set_gun_rect(g_layer_x, g_layer_y, g_layer_w, g_layer_h);
81
82         return omap_setup_layer_(vout_fbdev_get_fd(layer_fb), enabled,
83                 g_layer_x, g_layer_y, g_layer_w, g_layer_h);
84 }
85
86 void plat_gvideo_open(void)
87 {
88         omap_enable_layer(1);
89
90         // try to align redraws to vsync
91         vout_fbdev_wait_vsync(layer_fb);
92 }
93
94 void *plat_gvideo_set_mode(int *w, int *h, int *bpp)
95 {
96         void *buf;
97
98         vout_fbdev_clear(layer_fb);
99         buf = vout_fbdev_resize(layer_fb, *w, *h, *bpp, 0, 0, 0, 0, 3);
100
101         omap_enable_layer(1);
102
103         return buf;
104 }
105
106 void *plat_gvideo_flip(void)
107 {
108         return vout_fbdev_flip(layer_fb);
109 }
110
111 void plat_gvideo_close(void)
112 {
113         omap_enable_layer(0);
114 }
115
116 void plat_video_menu_enter(int is_rom_loaded)
117 {
118         g_menuscreen_ptr = vout_fbdev_resize(main_fb,
119                 g_menuscreen_w, g_menuscreen_h, 16, 0, 0, 0, 0, 3);
120         if (g_menuscreen_ptr == NULL)
121                 fprintf(stderr, "warning: vout_fbdev_resize failed\n");
122
123         xenv_update(NULL, NULL, NULL, NULL);
124 }
125
126 void plat_video_menu_begin(void)
127 {
128 }
129
130 void plat_video_menu_end(void)
131 {
132         g_menuscreen_ptr = vout_fbdev_flip(main_fb);
133 }
134
135 void plat_video_menu_leave(void)
136 {
137         /* have to get rid of panning so that plugins that
138          * use fb0 and don't ever pan can work. */
139         vout_fbdev_clear(main_fb);
140         g_menuscreen_ptr = vout_fbdev_resize(main_fb,
141                 g_menuscreen_w, g_menuscreen_h, 16, 0, 0, 0, 0, 1);
142         if (g_menuscreen_ptr == NULL)
143                 fprintf(stderr, "warning: vout_fbdev_resize failed\n");
144 }
145
146 void plat_minimize(void)
147 {
148         omap_enable_layer(0);
149         xenv_minimize();
150         omap_enable_layer(1);
151 }
152
153 void plat_step_volume(int is_up)
154 {
155 }
156
157 void plat_trigger_vibrate(int is_strong)
158 {
159 }
160
161 void *plat_prepare_screenshot(int *w, int *h, int *bpp)
162 {
163         return NULL;
164 }
165
166 void plat_init(void)
167 {
168         const char *main_fb_name, *layer_fb_name;
169         void *temp_frame;
170         int fd, ret, w, h;
171
172         main_fb_name = getenv("FBDEV_MAIN");
173         if (main_fb_name == NULL)
174                 main_fb_name = "/dev/fb0";
175
176         layer_fb_name = getenv("FBDEV_LAYER");
177         if (layer_fb_name == NULL)
178                 layer_fb_name = "/dev/fb1";
179
180         // must set the layer up first to be able to use it
181         fd = open(layer_fb_name, O_RDWR);
182         if (fd == -1) {
183                 fprintf(stderr, "%s: ", layer_fb_name);
184                 perror("open");
185                 exit(1);
186         }
187
188         g_layer_x = 80, g_layer_y = 0;
189         g_layer_w = 640, g_layer_h = 480;
190
191         ret = omap_setup_layer_(fd, 0, g_layer_x, g_layer_y, g_layer_w, g_layer_h);
192         close(fd);
193         if (ret != 0) {
194                 fprintf(stderr, "failed to set up layer, exiting.\n");
195                 exit(1);
196         }
197
198         xenv_init(NULL, "PCSX-ReARMed");
199
200         w = h = 0;
201         main_fb = vout_fbdev_init(main_fb_name, &w, &h, 16, 2);
202         if (main_fb == NULL) {
203                 fprintf(stderr, "couldn't init fb: %s\n", main_fb_name);
204                 exit(1);
205         }
206
207         g_menuscreen_w = w;
208         g_menuscreen_h = h;
209         g_menuscreen_ptr = vout_fbdev_flip(main_fb);
210         pl_rearmed_cbs.screen_w = w;
211         pl_rearmed_cbs.screen_h = h;
212
213         w = 640;
214         h = 512;
215         layer_fb = vout_fbdev_init(layer_fb_name, &w, &h, 16, 3);
216         if (layer_fb == NULL) {
217                 fprintf(stderr, "couldn't init fb: %s\n", layer_fb_name);
218                 goto fail0;
219         }
220
221         temp_frame = calloc(g_menuscreen_w * g_menuscreen_h * 2, 1);
222         if (temp_frame == NULL) {
223                 fprintf(stderr, "OOM\n");
224                 goto fail1;
225         }
226         g_menubg_ptr = temp_frame;
227
228         plat_pandora_init(); // XXX
229
230         return;
231
232 fail1:
233         vout_fbdev_finish(layer_fb);
234 fail0:
235         vout_fbdev_finish(main_fb);
236         exit(1);
237
238 }
239
240 void plat_finish(void)
241 {
242         omap_enable_layer(0);
243         vout_fbdev_finish(layer_fb);
244         vout_fbdev_finish(main_fb);
245         xenv_finish();
246 }
247