mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-06 12:45:21 +02:00
New BlackberryMain class, separated in to main, display and audio. Multiple display support (such as HDMI, AV out or Blackberry dock). Switchable display support. Starts in internal display for menus. Switches to external display for in game. Currently does not work properly for hotplugging screens so the switchable displays is disabled.
177 lines
5.9 KiB
C++
177 lines
5.9 KiB
C++
/*
|
|
* Copyright (c) 2013 Sacha Refshauge
|
|
*
|
|
*/
|
|
// Blackberry implementation of the framework.
|
|
#include "BlackberryMain.h"
|
|
|
|
char* BlackberryMain::displayTypeString(int type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case SCREEN_DISPLAY_TYPE_INTERNAL:
|
|
return "Internal"; break;
|
|
case SCREEN_DISPLAY_TYPE_COMPOSITE:
|
|
return "Composite"; break;
|
|
case SCREEN_DISPLAY_TYPE_DVI:
|
|
return "DVI"; break;
|
|
case SCREEN_DISPLAY_TYPE_HDMI:
|
|
return "HDMI"; break;
|
|
case SCREEN_DISPLAY_TYPE_DISPLAYPORT:
|
|
return "DisplayPort"; break;
|
|
case SCREEN_DISPLAY_TYPE_OTHER:
|
|
default:
|
|
break;
|
|
}
|
|
return "Unknown Port";
|
|
}
|
|
|
|
void BlackberryMain::startDisplays() {
|
|
screen_get_context_property_iv(screen_cxt, SCREEN_PROPERTY_DISPLAY_COUNT, &ndisplays);
|
|
egl_disp = (EGLDisplay*)calloc(ndisplays, sizeof(EGLDisplay));
|
|
egl_surf = (EGLSurface*)calloc(ndisplays, sizeof(EGLSurface));
|
|
egl_cont = (EGLContext*)calloc(ndisplays, sizeof(EGLContext));
|
|
displays = (dispdata_t*)calloc(ndisplays, sizeof(dispdata_t));
|
|
screen_win = (screen_window_t *)calloc(ndisplays, sizeof(screen_window_t ));
|
|
screen_dpy = (screen_display_t*)calloc(ndisplays, sizeof(screen_display_t));
|
|
screen_get_context_property_pv(screen_cxt, SCREEN_PROPERTY_DISPLAYS, (void **)screen_dpy);
|
|
|
|
// Common data
|
|
int usage = SCREEN_USAGE_ROTATION | SCREEN_USAGE_OPENGL_ES2;
|
|
int format = SCREEN_FORMAT_RGBX8888;
|
|
int sensitivity = SCREEN_SENSITIVITY_ALWAYS;
|
|
|
|
// Initialise every display
|
|
emulating = false;
|
|
screen_ui = 0;
|
|
screen_emu = 0;
|
|
for (int i = 0; i < ndisplays; i++) {
|
|
screen_get_display_property_iv(screen_dpy[i], SCREEN_PROPERTY_TYPE, &(displays[i].type));
|
|
screen_get_display_property_iv(screen_dpy[i], SCREEN_PROPERTY_ATTACHED, &(displays[i].attached));
|
|
|
|
screen_create_window(&screen_win[i], screen_cxt);
|
|
screen_set_window_property_iv(screen_win[i], SCREEN_PROPERTY_FORMAT, &format);
|
|
screen_set_window_property_iv(screen_win[i], SCREEN_PROPERTY_USAGE, &usage);
|
|
screen_set_window_property_iv(screen_win[i], SCREEN_PROPERTY_SENSITIVITY, &sensitivity);
|
|
screen_set_window_property_pv(screen_win[i], SCREEN_PROPERTY_DISPLAY, (void **)&screen_dpy[i]);
|
|
|
|
egl_disp[i] = eglGetDisplay((EGLNativeDisplayType)i);
|
|
eglInitialize(egl_disp[i], NULL, NULL);
|
|
fprintf(stderr, "Display %i: %s, %s\n", i, displayTypeString(displays[i].type), displays[i].attached ? "Attached" : "Detached");
|
|
if (displays[i].attached)
|
|
realiseDisplay(i);
|
|
}
|
|
screen_get_display_property_iv(screen_dpy[0], SCREEN_PROPERTY_DPI, &dpi); // Only internal display has DPI
|
|
dpi_scale = ((pixel_xres == pixel_yres) ? 300.0f : 213.6f) / dpi;
|
|
switchDisplay(screen_ui);
|
|
}
|
|
|
|
void BlackberryMain::realiseDisplay(int idx) {
|
|
EGLConfig egl_conf;
|
|
int num_configs;
|
|
EGLint attrib_list[]= {
|
|
EGL_RED_SIZE, 8,
|
|
EGL_GREEN_SIZE, 8,
|
|
EGL_BLUE_SIZE, 8,
|
|
EGL_DEPTH_SIZE, 24,
|
|
EGL_STENCIL_SIZE, 8,
|
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
|
EGL_NONE};
|
|
|
|
const EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
|
|
const EGLint egl_surfaceAttr[] = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE };
|
|
|
|
int size[2] = { atoi(getenv("WIDTH")), atoi(getenv("HEIGHT")) };
|
|
if (idx != 0)
|
|
screen_get_display_property_iv(screen_dpy[idx], SCREEN_PROPERTY_SIZE, size);
|
|
displays[idx].width = size[0];
|
|
displays[idx].height = size[1];
|
|
screen_set_window_property_iv(screen_win[idx], SCREEN_PROPERTY_BUFFER_SIZE, size);
|
|
screen_create_window_buffers(screen_win[idx], 2); // Double buffered
|
|
fprintf(stderr, "Display %i realised with %ix%i\n", idx, size[0], size[1]);
|
|
|
|
eglChooseConfig(egl_disp[idx], attrib_list, &egl_conf, 1, &num_configs);
|
|
if (!egl_cont[idx])
|
|
egl_cont[idx] = eglCreateContext(egl_disp[idx], egl_conf, EGL_NO_CONTEXT, attributes);
|
|
egl_surf[idx] = eglCreateWindowSurface(egl_disp[idx], egl_conf, screen_win[idx], egl_surfaceAttr);
|
|
eglSwapInterval(egl_disp[idx], 1);
|
|
// Temporarily disabled
|
|
#if 0
|
|
if (displays[idx].type != SCREEN_DISPLAY_TYPE_INTERNAL)
|
|
{
|
|
screen_emu = idx;
|
|
if (emulating)
|
|
switchDisplay(idx);
|
|
}
|
|
#endif
|
|
displays[idx].realised = true;
|
|
}
|
|
|
|
// Note: Only hotpluggable displays can unrealise. Internal (0) is not possible.
|
|
void BlackberryMain::unrealiseDisplay(int idx) {
|
|
killDisplay(idx, false);
|
|
screen_destroy_window_buffers(screen_win[idx]);
|
|
screen_flush_context(screen_cxt, 0);
|
|
if (displays[idx].type != SCREEN_DISPLAY_TYPE_INTERNAL)
|
|
{
|
|
screen_emu = screen_ui;
|
|
if (emulating)
|
|
switchDisplay(screen_ui);
|
|
eglMakeCurrent(egl_disp[screen_ui], egl_surf[screen_ui], egl_surf[screen_ui], egl_cont[screen_ui]);
|
|
}
|
|
displays[idx].realised = false;
|
|
}
|
|
|
|
void BlackberryMain::switchDisplay(int idx) {
|
|
static int screen_curr = -1;
|
|
if (idx != screen_curr) {
|
|
pixel_xres = displays[idx].width;
|
|
pixel_yres = displays[idx].height;
|
|
dp_xres = (int)(pixel_xres * dpi_scale);
|
|
dp_yres = (int)(pixel_yres * dpi_scale);
|
|
if (emulating) {
|
|
PSP_CoreParameter().pixelWidth = pixel_xres;
|
|
PSP_CoreParameter().pixelHeight = pixel_yres;
|
|
PSP_CoreParameter().outputWidth = dp_xres;
|
|
PSP_CoreParameter().outputHeight = dp_yres;
|
|
}
|
|
screen_curr = idx;
|
|
eglMakeCurrent(egl_disp[idx], egl_surf[idx], egl_surf[idx], egl_cont[idx]);
|
|
}
|
|
}
|
|
|
|
void BlackberryMain::killDisplays() {
|
|
for (int i = 0; i < ndisplays; i++) {
|
|
killDisplay(i, true);
|
|
}
|
|
free(egl_disp);
|
|
free(egl_surf);
|
|
eglReleaseThread();
|
|
free(screen_dpy);
|
|
}
|
|
|
|
void BlackberryMain::killDisplay(int idx, bool killContext) {
|
|
if (egl_disp[idx] != EGL_NO_DISPLAY) {
|
|
eglMakeCurrent(egl_disp[idx], EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
|
if (egl_surf[idx] != EGL_NO_SURFACE) {
|
|
eglDestroySurface(egl_disp[idx], egl_surf[idx]);
|
|
egl_surf[idx] = EGL_NO_SURFACE;
|
|
}
|
|
if (killContext && egl_cont[idx] != EGL_NO_CONTEXT) {
|
|
eglDestroyContext(egl_disp[idx], egl_cont[idx]);
|
|
egl_cont[idx] = EGL_NO_CONTEXT;
|
|
}
|
|
if (killContext)
|
|
{
|
|
eglTerminate(egl_disp[idx]);
|
|
egl_disp[idx] = EGL_NO_DISPLAY;
|
|
}
|
|
}
|
|
if (killContext && screen_win[idx] != NULL) {
|
|
screen_destroy_window(screen_win[idx]);
|
|
screen_win[idx] = NULL;
|
|
}
|
|
}
|
|
|