1 /*  RetroArch - A frontend for libretro.
2  *  Copyright (C) 2010-2014 - Hans-Kristian Arntzen
3  *  Copyright (C) 2011-2017 - Daniel De Matteis
4  *
5  *  RetroArch is free software: you can redistribute it and/or modify it under the terms
6  *  of the GNU General Public License as published by the Free Software Found-
7  *  ation, either version 3 of the License, or (at your option) any later version.
8  *
9  *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10  *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11  *  PURPOSE.  See the GNU General Public License for more details.
12  *
13  *  You should have received a copy of the GNU General Public License along with RetroArch.
14  *  If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 #include <stdint.h>
18 
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22 
23 #include <compat/strl.h>
24 
25 #include "../../configuration.h"
26 #include "../../retroarch.h"
27 #include "../../verbosity.h"
28 #include <defines/ps3_defines.h>
29 #include "../../frontend/frontend_driver.h"
30 #include <rsx/rsx.h>
31 
32 typedef struct gfx_ctx_psl1ght_data
33 {
34 #if defined(HAVE_PSGL)
35    PSGLdevice* gl_device;
36    PSGLcontext* gl_context;
37 #else
38    gcmContextData *rx_context;
39 #endif
40 } gfx_ctx_psl1ght_data_t;
41 
42 /* TODO/FIXME - static global */
43 static enum gfx_ctx_api ps3_api = GFX_CTX_RSX_API;
44 
gfx_ctx_psl1ght_get_resolution(unsigned idx,unsigned * width,unsigned * height)45 static void gfx_ctx_psl1ght_get_resolution(unsigned idx,
46       unsigned *width, unsigned *height)
47 {
48    CellVideoOutResolution resolution;
49    cellVideoOutGetResolution(idx, &resolution);
50 
51    *width  = resolution.width;
52    *height = resolution.height;
53 }
54 
gfx_ctx_psl1ght_get_aspect_ratio(void * data)55 static float gfx_ctx_psl1ght_get_aspect_ratio(void *data)
56 {
57    CellVideoOutState videoState;
58 
59    cellVideoOutGetState(CELL_VIDEO_OUT_PRIMARY, 0, &videoState);
60 
61    switch (videoState.displayMode.aspect)
62    {
63       case CELL_VIDEO_OUT_ASPECT_4_3:
64          return 4.0f/3.0f;
65       case CELL_VIDEO_OUT_ASPECT_16_9:
66          break;
67    }
68 
69    return 16.0f/9.0f;
70 }
71 
gfx_ctx_psl1ght_get_available_resolutions(void)72 static void gfx_ctx_psl1ght_get_available_resolutions(void)
73 {
74    unsigned i;
75    uint32_t videomode[] = {
76       CELL_VIDEO_OUT_RESOLUTION_480,
77       CELL_VIDEO_OUT_RESOLUTION_576,
78       CELL_VIDEO_OUT_RESOLUTION_960x1080,
79       CELL_VIDEO_OUT_RESOLUTION_720,
80       CELL_VIDEO_OUT_RESOLUTION_1280x1080,
81       CELL_VIDEO_OUT_RESOLUTION_1440x1080,
82       CELL_VIDEO_OUT_RESOLUTION_1600x1080,
83       CELL_VIDEO_OUT_RESOLUTION_1080
84    };
85    uint32_t resolution_count = 0;
86    bool defaultresolution    = true;
87    uint16_t num_videomodes   = sizeof(videomode) / sizeof(uint32_t);
88    global_t       *global    = global_get_ptr();
89 
90    if (global->console.screen.resolutions.check)
91       return;
92 
93    for (i = 0; i < num_videomodes; i++)
94    {
95       if (cellVideoOutGetResolutionAvailability(
96                CELL_VIDEO_OUT_PRIMARY, videomode[i],
97                CELL_VIDEO_OUT_ASPECT_AUTO, 0))
98          resolution_count++;
99    }
100 
101    global->console.screen.resolutions.count = 0;
102    global->console.screen.resolutions.list  =
103       malloc(resolution_count * sizeof(uint32_t));
104 
105    for (i = 0; i < num_videomodes; i++)
106    {
107       if (cellVideoOutGetResolutionAvailability(
108                CELL_VIDEO_OUT_PRIMARY,
109                videomode[i],
110                CELL_VIDEO_OUT_ASPECT_AUTO, 0))
111       {
112          global->console.screen.resolutions.list[
113             global->console.screen.resolutions.count++] = videomode[i];
114          global->console.screen.resolutions.initial.id = videomode[i];
115 
116          if (global->console.screen.resolutions.current.id == videomode[i])
117          {
118             defaultresolution = false;
119             global->console.screen.resolutions.current.idx =
120                global->console.screen.resolutions.count-1;
121          }
122       }
123    }
124 
125    /* In case we didn't specify a resolution -
126     * make the last resolution
127       that was added to the list (the highest resolution)
128       the default resolution */
129    if (global->console.screen.resolutions.current.id > num_videomodes || defaultresolution)
130     {
131       global->console.screen.resolutions.current.idx = resolution_count - 1;
132       global->console.screen.resolutions.current.id = global->console.screen.resolutions.list[global->console.screen.resolutions.current.idx];
133     }
134 
135    global->console.screen.resolutions.check = true;
136 }
137 
gfx_ctx_psl1ght_set_swap_interval(void * data,int interval)138 static void gfx_ctx_psl1ght_set_swap_interval(void *data, int interval)
139 {
140 #if defined(HAVE_PSGL)
141    if (interval == 1)
142       glEnable(GL_VSYNC_SCE);
143    else
144       glDisable(GL_VSYNC_SCE);
145 #endif
146 }
147 
gfx_ctx_psl1ght_check_window(void * data,bool * quit,bool * resize,unsigned * width,unsigned * height)148 static void gfx_ctx_psl1ght_check_window(void *data, bool *quit,
149       bool *resize, unsigned *width, unsigned *height)
150 {
151 
152 }
153 
gfx_ctx_psl1ght_has_focus(void * data)154 static bool gfx_ctx_psl1ght_has_focus(void *data) { return true; }
gfx_ctx_psl1ght_suppress_screensaver(void * data,bool enable)155 static bool gfx_ctx_psl1ght_suppress_screensaver(void *data, bool enable) { return false; }
156 
gfx_ctx_psl1ght_swap_buffers(void * data)157 static void gfx_ctx_psl1ght_swap_buffers(void *data)
158 {
159 #ifdef HAVE_PSGL
160    psglSwap();
161 #endif
162 #ifdef HAVE_SYSUTILS
163    cellSysutilCheckCallback();
164 #endif
165 }
166 
gfx_ctx_psl1ght_get_video_size(void * data,unsigned * width,unsigned * height)167 static void gfx_ctx_psl1ght_get_video_size(void *data,
168       unsigned *width, unsigned *height)
169 {
170    gfx_ctx_psl1ght_data_t *psl1ght = (gfx_ctx_psl1ght_data_t*)data;
171 
172 #if defined(HAVE_PSGL)
173    if (psl1ght)
174       psglGetDeviceDimensions(ps3->gl_device, width, height);
175 #endif
176 }
177 
gfx_ctx_psl1ght_init(void * video_driver)178 static void *gfx_ctx_psl1ght_init(void *video_driver)
179 {
180    printf("gfx_ctx_psl1ght_init: %p\n", video_driver);
181    global_t *global = global_get_ptr();
182    gfx_ctx_psl1ght_data_t *psl1ght = (gfx_ctx_psl1ght_data_t*)
183       calloc(1, sizeof(gfx_ctx_psl1ght_data_t));
184 
185    if (!psl1ght)
186       return NULL;
187 
188 
189 
190    global->console.screen.pal_enable =
191       cellVideoOutGetResolutionAvailability(
192             CELL_VIDEO_OUT_PRIMARY, CELL_VIDEO_OUT_RESOLUTION_576,
193             CELL_VIDEO_OUT_ASPECT_AUTO, 0);
194 
195    gfx_ctx_psl1ght_get_available_resolutions();
196 
197    return psl1ght;
198 }
199 
gfx_ctx_psl1ght_set_video_mode(void * data,unsigned width,unsigned height,bool fullscreen)200 static bool gfx_ctx_psl1ght_set_video_mode(void *data,
201       unsigned width, unsigned height,
202       bool fullscreen) { return true; }
203 
gfx_ctx_psl1ght_destroy_resources(gfx_ctx_psl1ght_data_t * ps3)204 static void gfx_ctx_psl1ght_destroy_resources(gfx_ctx_psl1ght_data_t *ps3)
205 {
206    if (!ps3)
207       return;
208 
209 #if defined(HAVE_PSGL)
210    psglDestroyContext(ps3->gl_context);
211    psglDestroyDevice(ps3->gl_device);
212 
213    psglExit();
214 #endif
215 }
216 
gfx_ctx_psl1ght_destroy(void * data)217 static void gfx_ctx_psl1ght_destroy(void *data)
218 {
219    gfx_ctx_psl1ght_data_t *ps3 = (gfx_ctx_psl1ght_data_t*)data;
220 
221    if (!ps3)
222       return;
223 
224    gfx_ctx_psl1ght_destroy_resources(ps3);
225    free(data);
226 }
227 
gfx_ctx_psl1ght_input_driver(void * data,const char * joypad_name,input_driver_t ** input,void ** input_data)228 static void gfx_ctx_psl1ght_input_driver(void *data,
229       const char *joypad_name,
230       input_driver_t **input, void **input_data)
231 {
232    void *ps3input       = input_driver_init_wrap(&input_ps3, joypad_name);
233 
234    *input               = ps3input ? &input_ps3 : NULL;
235    *input_data          = ps3input;
236 }
237 
gfx_ctx_psl1ght_get_api(void * data)238 static enum gfx_ctx_api gfx_ctx_psl1ght_get_api(void *data) { return ps3_api; }
239 
gfx_ctx_psl1ght_bind_api(void * data,enum gfx_ctx_api api,unsigned major,unsigned minor)240 static bool gfx_ctx_psl1ght_bind_api(void *data,
241       enum gfx_ctx_api api, unsigned major, unsigned minor)
242 {
243    ps3_api = api;
244 
245    if (api == GFX_CTX_RSX_API)
246       return true;
247 
248    return false;
249 }
250 
gfx_ctx_psl1ght_get_video_output_size(void * data,unsigned * width,unsigned * height)251 static void gfx_ctx_psl1ght_get_video_output_size(void *data,
252       unsigned *width, unsigned *height)
253 {
254    global_t *global = global_get_ptr();
255 
256    if (!global)
257       return;
258 
259    gfx_ctx_psl1ght_get_resolution(global->console.screen.resolutions.current.id,
260          width, height);
261 
262    if (*width == 720 && *height == 576)
263    {
264       if (global->console.screen.pal_enable)
265          global->console.screen.pal60_enable = true;
266    }
267    else
268    {
269       global->console.screen.pal_enable = false;
270       global->console.screen.pal60_enable = false;
271    }
272 }
273 
gfx_ctx_psl1ght_get_video_output_prev(void * data)274 static void gfx_ctx_psl1ght_get_video_output_prev(void *data)
275 {
276    global_t *global = global_get_ptr();
277 
278    if (!global)
279       return;
280 
281    if (global->console.screen.resolutions.current.idx)
282    {
283       global->console.screen.resolutions.current.idx--;
284       global->console.screen.resolutions.current.id =
285          global->console.screen.resolutions.list
286          [global->console.screen.resolutions.current.idx];
287    }
288 }
289 
gfx_ctx_psl1ght_get_video_output_next(void * data)290 static void gfx_ctx_psl1ght_get_video_output_next(void *data)
291 {
292    global_t *global = global_get_ptr();
293 
294    if (!global)
295       return;
296 
297    if (global->console.screen.resolutions.current.idx + 1 <
298          global->console.screen.resolutions.count)
299    {
300       global->console.screen.resolutions.current.idx++;
301       global->console.screen.resolutions.current.id =
302          global->console.screen.resolutions.list
303          [global->console.screen.resolutions.current.idx];
304    }
305 }
306 
gfx_ctx_psl1ght_get_flags(void * data)307 static uint32_t gfx_ctx_psl1ght_get_flags(void *data)
308 {
309    uint32_t flags = 0;
310 
311 #ifdef HAVE_CG
312    BIT32_SET(flags, GFX_CTX_FLAGS_SHADERS_CG);
313 #endif
314 
315    return flags;
316 }
317 
gfx_ctx_psl1ght_set_flags(void * data,uint32_t flags)318 static void gfx_ctx_psl1ght_set_flags(void *data, uint32_t flags) { }
319 
320 const gfx_ctx_driver_t gfx_ctx_psl1ght = {
321    gfx_ctx_psl1ght_init,
322    gfx_ctx_psl1ght_destroy,
323    gfx_ctx_psl1ght_get_api,
324    gfx_ctx_psl1ght_bind_api,
325    gfx_ctx_psl1ght_set_swap_interval,
326    gfx_ctx_psl1ght_set_video_mode,
327    gfx_ctx_psl1ght_get_video_size,
328    NULL, /* get_refresh_rate */
329    gfx_ctx_psl1ght_get_video_output_size,
330    gfx_ctx_psl1ght_get_video_output_prev,
331    gfx_ctx_psl1ght_get_video_output_next,
332    NULL, /* get_metrics */
333    NULL,
334    NULL, /* update_title */
335    gfx_ctx_psl1ght_check_window,
336    NULL, /* set_resize */
337    gfx_ctx_psl1ght_has_focus,
338    gfx_ctx_psl1ght_suppress_screensaver,
339    false, /* has_windowed */
340    gfx_ctx_psl1ght_swap_buffers,
341    gfx_ctx_psl1ght_input_driver,
342    NULL,
343    NULL,
344    NULL,
345    NULL,
346    "psl1ght",
347    gfx_ctx_psl1ght_get_flags,
348    gfx_ctx_psl1ght_set_flags,
349    NULL,
350    NULL
351 };
352