Files
ppsspp/base/BlackberryMain.cpp
T
Sacha e2378dd970 New Blackberry 10 frontend
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.
2013-06-01 16:04:10 +10:00

299 lines
8.9 KiB
C++

/*
* Copyright (c) 2013 Sacha Refshauge
*
*/
// Blackberry implementation of the framework.
#include <pwd.h>
#include <unistd.h>
#include <string>
#include "BlackberryMain.h"
// Simple implementations of System functions
void SystemToast(const char *text) {
dialog_instance_t dialog = 0;
dialog_create_toast(&dialog);
dialog_set_toast_message_text(dialog, text);
dialog_set_toast_position(dialog, DIALOG_POSITION_TOP_CENTER);
dialog_show(dialog);
}
void ShowAd(int x, int y, bool center_x) {
}
void ShowKeyboard() {
virtualkeyboard_show();
}
void Vibrate(int length_ms) {
vibration_request(VIBRATION_INTENSITY_LOW, 200 /* intensity (1-100), duration (ms) */);
}
void LaunchBrowser(const char *url)
{
char* error;
navigator_invoke(url, &error);
}
void LaunchMarket(const char *url)
{
char* error;
navigator_invoke(url, &error);
}
void LaunchEmail(const char *email_address)
{
char* error;
navigator_invoke((std::string("mailto:") + email_address).c_str(), &error);
}
InputState input_state;
// Input
const unsigned int buttonMappings[18] = {
KEYCODE_K, //Cross
KEYCODE_L, //Circle
KEYCODE_J, //Square
KEYCODE_I, //Triangle
KEYCODE_Q, //LBUMPER
KEYCODE_P, //RBUMPER
KEYCODE_SPACE, //START
KEYCODE_ZERO, //SELECT
KEYCODE_W, //UP
KEYCODE_S, //DOWN
KEYCODE_A, //LEFT
KEYCODE_D, //RIGHT
0, //MENU (SwipeDown)
KEYCODE_BACKSPACE, //BACK
KEYCODE_W, //JOY UP
KEYCODE_S, //JOY DOWN
KEYCODE_A, //JOY LEFT
KEYCODE_D, //JOY RIGHT
};
void SimulateGamepad(InputState *input) {
input->pad_lstick_x = 0;
input->pad_lstick_y = 0;
input->pad_rstick_x = 0;
input->pad_rstick_y = 0;
if (input->pad_buttons & PAD_BUTTON_JOY_UP)
input->pad_lstick_y=1;
else if (input->pad_buttons & PAD_BUTTON_JOY_DOWN)
input->pad_lstick_y=-1;
if (input->pad_buttons & PAD_BUTTON_JOY_LEFT)
input->pad_lstick_x=-1;
else if (input->pad_buttons & PAD_BUTTON_JOY_RIGHT)
input->pad_lstick_x=1;
}
void BlackberryMain::handleInput(screen_event_t screen_event)
{
int val, buttons, pointerId;
int pair[2];
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &val);
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_SOURCE_POSITION, pair);
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TOUCH_ID, &pointerId);
input_state.mouse_valid = true;
switch(val)
{
// Touchscreen
case SCREEN_EVENT_MTOUCH_TOUCH:
case SCREEN_EVENT_MTOUCH_RELEASE: // Up, down
input_state.pointer_down[pointerId] = (val == SCREEN_EVENT_MTOUCH_TOUCH);
case SCREEN_EVENT_MTOUCH_MOVE:
input_state.pointer_x[pointerId] = pair[0] * dpi_scale;
input_state.pointer_y[pointerId] = pair[1] * dpi_scale;
break;
// Mouse, Simulator
case SCREEN_EVENT_POINTER:
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_BUTTONS,
&buttons);
if (buttons == SCREEN_LEFT_MOUSE_BUTTON) { // Down
input_state.pointer_x[pointerId] = pair[0] * dpi_scale;
input_state.pointer_y[pointerId] = pair[1] * dpi_scale;
input_state.pointer_down[pointerId] = true;
} else if (input_state.pointer_down[pointerId]) { // Up
input_state.pointer_x[pointerId] = pair[0] * dpi_scale;
input_state.pointer_y[pointerId] = pair[1] * dpi_scale;
input_state.pointer_down[pointerId] = false;
}
break;
// Keyboard
case SCREEN_EVENT_KEYBOARD:
int flags, value;
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_FLAGS, &flags);
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_SYM, &value);
for (int b = 0; b < 14; b++) {
if (value == buttonMappings[b] & 0xFF) {
if (flags & KEY_DOWN)
pad_buttons |= (1<<b);
else
pad_buttons &= ~(1<<b);
}
}
break;
// Gamepad
case SCREEN_EVENT_GAMEPAD:
case SCREEN_EVENT_JOYSTICK:
char device_id[16];
#define DIR_KEYS SCREEN_DPAD_UP_GAME_BUTTON | SCREEN_DPAD_DOWN_GAME_BUTTON | SCREEN_DPAD_LEFT_GAME_BUTTON | SCREEN_DPAD_RIGHT_GAME_BUTTON
screen_device_t device;
screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_DEVICE, (void**)&device);
screen_get_device_property_cv(device, SCREEN_PROPERTY_ID_STRING, sizeof(device_id), device_id);
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_BUTTONS, &buttons);
// Map the buttons integer to our mappings
if (strstr(device_id, "057E-0306")) // Wiimote
controller_buttons = (buttons & (SCREEN_A_GAME_BUTTON | SCREEN_B_GAME_BUTTON)) << 2 |
(buttons & (SCREEN_X_GAME_BUTTON | SCREEN_Y_GAME_BUTTON)) >> 3;
else
controller_buttons = (buttons & (SCREEN_A_GAME_BUTTON | SCREEN_B_GAME_BUTTON)) |
(buttons & (SCREEN_X_GAME_BUTTON | SCREEN_Y_GAME_BUTTON)) >> 1;
controller_buttons |= (buttons & (SCREEN_MENU1_GAME_BUTTON | SCREEN_MENU2_GAME_BUTTON)) |
(buttons & SCREEN_L1_GAME_BUTTON) >> 6 | (buttons & SCREEN_R1_GAME_BUTTON) >> 8 |
(buttons & DIR_KEYS) >> 8 |
(buttons & DIR_KEYS) >> 2;
break;
case SCREEN_EVENT_DISPLAY:
screen_display_t new_dpy = NULL;
screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_DISPLAY, (void **)&new_dpy);
static int hits = 0;
hits++;
for (int i = 0; i < ndisplays; i++) {
if (new_dpy != screen_dpy[i])
continue;
int active = 0;
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_ATTACHED, &active);
if (active) {
int size[2];
screen_get_display_property_iv(screen_dpy[i], SCREEN_PROPERTY_SIZE, size);
if (size[0] == 0 || size[1] == 0)
active = 0;
}
if (active && !displays[i].attached)
realiseDisplay(i);
else if (!active && displays[i].attached && displays[i].realised)
unrealiseDisplay(i);
displays[i].attached = active;
}
break;
}
}
void BlackberryMain::startMain(int argc, char *argv[]) {
// Receive events from window manager
screen_create_context(&screen_cxt, 0);
// Initialise Blackberry Platform Services
bps_initialize();
// TODO: Enable/disable based on setting
sensor_set_rate(SENSOR_TYPE_ACCELEROMETER, 25000);
sensor_request_events(SENSOR_TYPE_ACCELEROMETER);
net::Init();
startDisplays();
//eglMakeCurrent(egl_disp[0], egl_surf[0], egl_surf[0], egl_ctx[0]);
NativeInit(argc, (const char **)argv, "/accounts/1000/shared/misc/", "data/", "BADCOFFEE");
NativeInitGraphics();
screen_request_events(screen_cxt);
navigator_request_events(0);
dialog_request_events(0);
vibration_request_events(0);
audio = new BlackberryAudio();
runMain();
}
void BlackberryMain::runMain() {
bool running = true;
while (running) {
input_state.mouse_valid = false;
input_state.accelerometer_valid = false;
SimulateGamepad(&input_state);
while (true) {
// Handle Blackberry events
bps_event_t *event = NULL;
bps_get_event(&event, 0);
if (event == NULL)
break; // Ran out of events
int domain = bps_event_get_domain(event);
if (domain == screen_get_domain()) {
handleInput(screen_event_get_event(event));
} else if (domain == navigator_get_domain()) {
switch(bps_event_get_code(event))
{
case NAVIGATOR_BACK:
case NAVIGATOR_SWIPE_DOWN:
pad_buttons |= PAD_BUTTON_MENU;
break;
case NAVIGATOR_EXIT:
NativeShutdown();
exit(0);
break;
}
} else if (domain == sensor_get_domain()) {
if (SENSOR_ACCELEROMETER_READING == bps_event_get_code(event)) {
float x, y, z;
sensor_event_get_xyz(event, &x, &y, &z);
if (pixel_xres == 1024 || pixel_xres == 720) // Q10 has this negative and reversed
{
input_state.acc.x = -y;
input_state.acc.y = -x;
} else {
input_state.acc.x = x;
input_state.acc.y = y;
}
input_state.acc.z = z;
}
}
}
input_state.pad_buttons = pad_buttons | controller_buttons;
pad_buttons &= ~PAD_BUTTON_MENU;
UpdateInputState(&input_state);
NativeUpdate(input_state);
EndInputState(&input_state);
// Work in Progress
// Currently: Render to HDMI port (eg. 1080p) when in game. Render to device when in menu.
// Right now, hotswapping displays is not working. Temporarily disable.
// Idea: Render to all displays. Controls go to internal, game goes to external(s).
#if 0
if (globalUIState == UISTATE_INGAME && !emulating)
{
emulating = true;
switchDisplay(screen_emu);
} else if (globalUIState != UISTATE_INGAME && emulating) {
emulating = false;
switchDisplay(screen_ui);
}
#endif
NativeRender();
time_update();
// This handles VSync
if (false && emulating) // Temporarily disable
eglSwapBuffers(egl_disp[screen_emu], egl_surf[screen_emu]);
else
eglSwapBuffers(egl_disp[screen_ui], egl_surf[screen_ui]);
}
endMain();
}
void BlackberryMain::endMain() {
screen_stop_events(screen_cxt);
bps_shutdown();
NativeShutdownGraphics();
delete audio;
NativeShutdown();
killDisplays();
net::Shutdown();
screen_destroy_context(screen_cxt);
}
// Entry Point
int main(int argc, char *argv[]) {
BlackberryMain emu;
emu.startMain(argc, argv);
exit(0);
return 0;
}