frontend: move layer size code
[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 "common/input.h"
19 #include "linux/fbdev.h"
20 #include "linux/xenv.h"
21 #include "plugin_lib.h"
22 #include "pl_gun_ts.h"
23 #include "plat.h"
24 #include "plat_omap.h"
25 #include "menu.h"
26
27 static struct vout_fbdev *main_fb, *layer_fb;
28
29 static int omap_setup_layer_(int fd, int enabled, int x, int y, int w, int h)
30 {
31         struct omapfb_plane_info pi = { 0, };
32         struct omapfb_mem_info mi = { 0, };
33         int ret;
34
35         ret = ioctl(fd, OMAPFB_QUERY_PLANE, &pi);
36         if (ret != 0) {
37                 perror("QUERY_PLANE");
38                 return -1;
39         }
40
41         ret = ioctl(fd, OMAPFB_QUERY_MEM, &mi);
42         if (ret != 0) {
43                 perror("QUERY_MEM");
44                 return -1;
45         }
46
47         /* must disable when changing stuff */
48         if (pi.enabled) {
49                 pi.enabled = 0;
50                 ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
51                 if (ret != 0)
52                         perror("SETUP_PLANE");
53         }
54
55         if (mi.size < 640*512*3*3) {
56                 mi.size = 640*512*3*3;
57                 ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi);
58                 if (ret != 0) {
59                         perror("SETUP_MEM");
60                         return -1;
61                 }
62         }
63
64         pi.pos_x = x;
65         pi.pos_y = y;
66         pi.out_width = w;
67         pi.out_height = h;
68         pi.enabled = enabled;
69
70         ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
71         if (ret != 0) {
72                 perror("SETUP_PLANE");
73                 return -1;
74         }
75
76         return 0;
77 }
78
79 static int omap_enable_layer(int enabled)
80 {
81         if (enabled)
82                 pl_set_gun_rect(g_layer_x, g_layer_y, g_layer_w, g_layer_h);
83
84         return omap_setup_layer_(vout_fbdev_get_fd(layer_fb), enabled,
85                 g_layer_x, g_layer_y, g_layer_w, g_layer_h);
86 }
87
88 void plat_omap_gvideo_open(void)
89 {
90         omap_enable_layer(1);
91
92         // try to align redraws to vsync
93         vout_fbdev_wait_vsync(layer_fb);
94 }
95
96 void *plat_gvideo_set_mode(int *w, int *h, int *bpp)
97 {
98         int l = 0, r = 0, t = 0, b = 0;
99         void *buf;
100
101         if (g_scaler == SCALE_1_1) {
102                 if (*w > g_menuscreen_w)
103                         l = r = (*w - g_menuscreen_w) / 2;
104                 if (*h > g_menuscreen_h)
105                         t = b = (*h - g_menuscreen_h) / 2;
106         }
107
108         vout_fbdev_clear(layer_fb);
109         buf = vout_fbdev_resize(layer_fb, *w, *h, *bpp,
110                 l, r, t, b, 3);
111
112         omap_enable_layer(1);
113
114         return buf;
115 }
116
117 void *plat_gvideo_flip(void)
118 {
119         return vout_fbdev_flip(layer_fb);
120 }
121
122 void plat_gvideo_close(void)
123 {
124         omap_enable_layer(0);
125 }
126
127 void plat_video_menu_enter(int is_rom_loaded)
128 {
129         g_menuscreen_ptr = vout_fbdev_resize(main_fb,
130                 g_menuscreen_w, g_menuscreen_h, 16, 0, 0, 0, 0, 3);
131         if (g_menuscreen_ptr == NULL)
132                 fprintf(stderr, "warning: vout_fbdev_resize failed\n");
133
134         xenv_update(NULL, NULL, NULL, NULL);
135 }
136
137 void plat_video_menu_begin(void)
138 {
139 }
140
141 void plat_video_menu_end(void)
142 {
143         g_menuscreen_ptr = vout_fbdev_flip(main_fb);
144 }
145
146 void plat_video_menu_leave(void)
147 {
148         /* have to get rid of panning so that plugins that
149          * use fb0 and don't ever pan can work. */
150         vout_fbdev_clear(main_fb);
151         g_menuscreen_ptr = vout_fbdev_resize(main_fb,
152                 g_menuscreen_w, g_menuscreen_h, 16, 0, 0, 0, 0, 1);
153         if (g_menuscreen_ptr == NULL)
154                 fprintf(stderr, "warning: vout_fbdev_resize failed\n");
155 }
156
157 void plat_minimize(void)
158 {
159         int ret;
160
161         ret = vout_fbdev_save(layer_fb);
162         if (ret != 0) {
163                 printf("minimize: layer/fb handling failed\n");
164                 return;
165         }
166
167         xenv_minimize();
168
169         in_set_config_int(0, IN_CFG_BLOCKING, 0); /* flush event queue */
170         omap_enable_layer(0); /* restore layer mem */
171         vout_fbdev_restore(layer_fb);
172 }
173
174 void *plat_prepare_screenshot(int *w, int *h, int *bpp)
175 {
176         return NULL;
177 }
178
179 void plat_omap_init(void)
180 {
181         const char *main_fb_name, *layer_fb_name;
182         int fd, ret, w, h;
183
184         main_fb_name = getenv("FBDEV_MAIN");
185         if (main_fb_name == NULL)
186                 main_fb_name = "/dev/fb0";
187
188         layer_fb_name = getenv("FBDEV_LAYER");
189         if (layer_fb_name == NULL)
190                 layer_fb_name = "/dev/fb1";
191
192         // must set the layer up first to be able to use it
193         fd = open(layer_fb_name, O_RDWR);
194         if (fd == -1) {
195                 fprintf(stderr, "%s: ", layer_fb_name);
196                 perror("open");
197                 exit(1);
198         }
199
200         g_layer_x = 80, g_layer_y = 0;
201         g_layer_w = 640, g_layer_h = 480;
202
203         ret = omap_setup_layer_(fd, 0, g_layer_x, g_layer_y, g_layer_w, g_layer_h);
204         close(fd);
205         if (ret != 0) {
206                 fprintf(stderr, "failed to set up layer, exiting.\n");
207                 exit(1);
208         }
209
210         xenv_init(NULL, "PCSX-ReARMed");
211
212         w = h = 0;
213         main_fb = vout_fbdev_init(main_fb_name, &w, &h, 16, 2);
214         if (main_fb == NULL) {
215                 fprintf(stderr, "couldn't init fb: %s\n", main_fb_name);
216                 exit(1);
217         }
218
219         g_menuscreen_w = w;
220         g_menuscreen_h = h;
221         g_menuscreen_ptr = vout_fbdev_flip(main_fb);
222         pl_rearmed_cbs.screen_w = w;
223         pl_rearmed_cbs.screen_h = h;
224
225         w = 640;
226         h = 512;
227         layer_fb = vout_fbdev_init(layer_fb_name, &w, &h, 16, 3);
228         if (layer_fb == NULL) {
229                 fprintf(stderr, "couldn't init fb: %s\n", layer_fb_name);
230                 goto fail0;
231         }
232
233         return;
234
235 fail0:
236         vout_fbdev_finish(main_fb);
237         exit(1);
238 }
239
240 void plat_omap_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