2012-12-13 16:38:33 +10:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2012 Sacha Refshauge
|
|
|
|
*
|
|
|
|
*/
|
2013-10-29 11:23:42 +10:00
|
|
|
// Qt 4.7+ / 5.0+ implementation of the framework.
|
2014-06-26 17:58:05 +10:00
|
|
|
// Currently supports: Android, Symbian, Blackberry, Maemo/Meego, Linux, Windows, Mac OSX
|
2012-12-13 16:38:33 +10:00
|
|
|
|
2013-10-19 05:21:44 +10:00
|
|
|
#include <QApplication>
|
2012-12-13 16:38:33 +10:00
|
|
|
#include <QUrl>
|
2013-02-20 00:18:13 +10:00
|
|
|
#include <QDir>
|
2012-12-13 16:38:33 +10:00
|
|
|
#include <QDesktopWidget>
|
|
|
|
#include <QDesktopServices>
|
2013-10-19 05:21:44 +10:00
|
|
|
#include <QLocale>
|
2013-10-22 14:52:14 +10:00
|
|
|
#include <QThread>
|
2012-12-13 16:38:33 +10:00
|
|
|
|
2014-06-25 15:40:28 +10:00
|
|
|
#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
|
2014-06-03 10:02:24 +10:00
|
|
|
#include <QStandardPaths>
|
2014-07-25 14:41:23 +10:00
|
|
|
#ifdef QT_HAS_SYSTEMINFO
|
2014-07-22 16:03:42 +10:00
|
|
|
#include <QScreenSaver>
|
2014-06-03 10:02:24 +10:00
|
|
|
#endif
|
2014-07-25 14:41:23 +10:00
|
|
|
#endif
|
2014-06-03 10:02:24 +10:00
|
|
|
|
2012-12-13 16:38:33 +10:00
|
|
|
#ifdef __SYMBIAN32__
|
2013-04-18 00:22:38 +10:00
|
|
|
#include <QSystemScreenSaver>
|
2013-10-27 05:32:31 +10:00
|
|
|
#include <QFeedbackHapticsEffect>
|
2013-10-26 17:20:08 +03:00
|
|
|
#include "SymbianMediaKeys.h"
|
2012-12-13 16:38:33 +10:00
|
|
|
#endif
|
2014-12-18 23:57:59 +01:00
|
|
|
#ifdef SDL
|
2013-11-22 01:59:18 +01:00
|
|
|
#include "SDL/SDLJoystick.h"
|
2014-06-25 13:00:42 +10:00
|
|
|
#include "SDL_audio.h"
|
2013-11-22 01:59:18 +01:00
|
|
|
#endif
|
2012-12-13 16:38:33 +10:00
|
|
|
#include "QtMain.h"
|
2014-07-16 23:50:49 +10:00
|
|
|
#include "math/math_util.h"
|
2012-12-13 16:38:33 +10:00
|
|
|
|
2014-09-23 22:30:50 +02:00
|
|
|
#include <string.h>
|
2014-02-12 11:54:53 +01:00
|
|
|
|
2013-04-01 22:42:40 +10:00
|
|
|
InputState* input_state;
|
|
|
|
|
2014-12-18 23:57:59 +01:00
|
|
|
#ifdef SDL
|
2014-06-25 13:00:42 +10:00
|
|
|
extern void mixaudio(void *userdata, Uint8 *stream, int len) {
|
|
|
|
NativeMix((short *)stream, len / 4);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-09-04 11:28:19 +02:00
|
|
|
std::string System_GetProperty(SystemProperty prop) {
|
|
|
|
switch (prop) {
|
|
|
|
case SYSPROP_NAME:
|
2013-08-18 17:28:34 +10:00
|
|
|
#ifdef __SYMBIAN32__
|
2013-09-04 11:28:19 +02:00
|
|
|
return "Qt:Symbian";
|
2013-08-18 17:28:34 +10:00
|
|
|
#elif defined(BLACKBERRY)
|
2013-11-26 16:38:00 +10:00
|
|
|
return "Qt:Blackberry";
|
2014-01-05 10:53:47 +10:00
|
|
|
#elif defined(MAEMO)
|
|
|
|
return "Qt:Maemo";
|
2014-06-03 10:02:24 +10:00
|
|
|
#elif defined(ANDROID)
|
|
|
|
return "Qt:Android";
|
2013-10-20 05:03:31 +10:00
|
|
|
#elif defined(Q_OS_LINUX)
|
2013-09-04 11:28:19 +02:00
|
|
|
return "Qt:Linux";
|
2013-08-18 17:28:34 +10:00
|
|
|
#elif defined(_WIN32)
|
2013-09-04 11:28:19 +02:00
|
|
|
return "Qt:Windows";
|
2013-12-08 20:14:49 +10:00
|
|
|
#elif defined(Q_OS_MAC)
|
|
|
|
return "Qt:Mac";
|
2013-08-18 17:28:34 +10:00
|
|
|
#else
|
2013-09-04 11:28:19 +02:00
|
|
|
return "Qt";
|
2013-08-18 17:28:34 +10:00
|
|
|
#endif
|
2013-10-17 18:41:00 +10:00
|
|
|
case SYSPROP_LANGREGION:
|
|
|
|
return QLocale::system().name().toStdString();
|
2013-09-04 11:28:19 +02:00
|
|
|
default:
|
|
|
|
return "";
|
|
|
|
}
|
2013-08-18 17:28:34 +10:00
|
|
|
}
|
|
|
|
|
2015-01-11 14:17:23 +01:00
|
|
|
int System_GetPropertyInt(SystemProperty prop) {
|
|
|
|
switch (prop) {
|
|
|
|
case SYSPROP_AUDIO_SAMPLE_RATE:
|
|
|
|
return 44100;
|
2015-01-14 00:27:21 +01:00
|
|
|
case SYSPROP_DISPLAY_REFRESH_RATE:
|
|
|
|
return 60000;
|
2015-04-03 11:13:38 +02:00
|
|
|
case SYSPROP_DEVICE_TYPE:
|
|
|
|
#ifdef __SYMBIAN32__
|
|
|
|
return DEVICE_TYPE_MOBILE;
|
|
|
|
#elif defined(BLACKBERRY)
|
|
|
|
return DEVICE_TYPE_MOBILE;
|
|
|
|
#elif defined(MAEMO)
|
|
|
|
return DEVICE_TYPE_MOBILE;
|
|
|
|
#elif defined(ANDROID)
|
|
|
|
return DEVICE_TYPE_MOBILE;
|
|
|
|
#elif defined(Q_OS_LINUX)
|
|
|
|
return DEVICE_TYPE_DESKTOP;
|
|
|
|
#elif defined(_WIN32)
|
|
|
|
return DEVICE_TYPE_DESKTOP;
|
|
|
|
#elif defined(Q_OS_MAC)
|
|
|
|
return DEVICE_TYPE_DESKTOP;
|
|
|
|
#else
|
|
|
|
return DEVICE_TYPE_DESKTOP;
|
|
|
|
#endif
|
2015-01-11 14:17:23 +01:00
|
|
|
default:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2014-07-20 12:04:22 +02:00
|
|
|
|
2013-12-04 18:12:57 +01:00
|
|
|
void System_SendMessage(const char *command, const char *parameter) {
|
2014-02-15 01:42:48 -08:00
|
|
|
if (!strcmp(command, "finish")) {
|
2014-05-15 17:47:33 +10:00
|
|
|
qApp->exit(0);
|
2014-02-15 01:42:48 -08:00
|
|
|
}
|
2013-12-04 18:12:57 +01:00
|
|
|
}
|
|
|
|
|
2015-12-17 22:41:50 +01:00
|
|
|
void System_AskForPermission(SystemPermission permission) {}
|
|
|
|
PermissionStatus System_GetPermissionStatus(SystemPermission permission) { return PERMISSION_STATUS_GRANTED; }
|
|
|
|
|
2014-02-15 01:46:47 -08:00
|
|
|
bool System_InputBoxGetString(const char *title, const char *defaultValue, char *outValue, size_t outLength)
|
2013-12-08 20:14:49 +10:00
|
|
|
{
|
|
|
|
QString text = emugl->InputBoxGetQString(QString(title), QString(defaultValue));
|
|
|
|
if (text.isEmpty())
|
|
|
|
return false;
|
|
|
|
strcpy(outValue, text.toStdString().c_str());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-10-11 02:49:09 +10:00
|
|
|
void Vibrate(int length_ms) {
|
|
|
|
if (length_ms == -1 || length_ms == -3)
|
|
|
|
length_ms = 50;
|
|
|
|
else if (length_ms == -2)
|
|
|
|
length_ms = 25;
|
2013-10-27 05:32:31 +10:00
|
|
|
// Symbian only for now
|
|
|
|
#if defined(__SYMBIAN32__)
|
|
|
|
QFeedbackHapticsEffect effect;
|
2013-11-04 23:49:30 +10:00
|
|
|
effect.setIntensity(0.8);
|
2013-10-27 05:32:31 +10:00
|
|
|
effect.setDuration(length_ms);
|
|
|
|
effect.start();
|
2013-10-11 02:49:09 +10:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2012-12-13 16:38:33 +10:00
|
|
|
void LaunchBrowser(const char *url)
|
|
|
|
{
|
|
|
|
QDesktopServices::openUrl(QUrl(url));
|
|
|
|
}
|
|
|
|
|
2012-12-13 17:05:12 +10:00
|
|
|
float CalculateDPIScale()
|
|
|
|
{
|
2013-04-07 00:34:46 +10:00
|
|
|
// Sane default rather than check DPI
|
2012-12-13 17:05:12 +10:00
|
|
|
#ifdef __SYMBIAN32__
|
2013-03-20 05:26:53 +10:00
|
|
|
return 1.4f;
|
2013-12-08 20:14:49 +10:00
|
|
|
#elif defined(USING_GLES2)
|
2012-12-16 19:47:51 +10:00
|
|
|
return 1.2f;
|
2013-10-29 11:23:42 +10:00
|
|
|
#else
|
|
|
|
return 1.0f;
|
2012-12-13 17:05:12 +10:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2014-02-15 01:42:48 -08:00
|
|
|
static int mainInternal(QApplication &a)
|
|
|
|
{
|
2014-06-17 23:45:04 +10:00
|
|
|
#ifdef MOBILE_DEVICE
|
2014-02-15 01:42:48 -08:00
|
|
|
emugl = new MainUI();
|
|
|
|
emugl->resize(pixel_xres, pixel_yres);
|
|
|
|
emugl->showFullScreen();
|
|
|
|
#endif
|
2014-07-16 23:50:49 +10:00
|
|
|
EnableFZ();
|
2014-02-15 01:42:48 -08:00
|
|
|
// Disable screensaver
|
2014-07-22 16:03:42 +10:00
|
|
|
#ifdef __SYMBIAN32__
|
|
|
|
QSystemScreenSaver ssObject(emugl);
|
|
|
|
ssObject.setScreenSaverInhibit();
|
2014-02-15 01:42:48 -08:00
|
|
|
QScopedPointer<SymbianMediaKeys> mediakeys(new SymbianMediaKeys());
|
2014-07-25 14:41:23 +10:00
|
|
|
#elif defined(QT_HAS_SYSTEMINFO)
|
2014-07-22 16:03:42 +10:00
|
|
|
QScreenSaver ssObject(emugl);
|
|
|
|
ssObject.setScreenSaverEnabled(false);
|
2014-02-15 01:42:48 -08:00
|
|
|
#endif
|
|
|
|
|
2014-12-18 23:57:59 +01:00
|
|
|
#ifdef SDL
|
2014-06-25 13:00:42 +10:00
|
|
|
SDLJoystick joy(true);
|
|
|
|
joy.startEventLoop();
|
|
|
|
SDL_Init(SDL_INIT_AUDIO);
|
|
|
|
SDL_AudioSpec fmt, ret_fmt;
|
|
|
|
memset(&fmt, 0, sizeof(fmt));
|
|
|
|
fmt.freq = 44100;
|
|
|
|
fmt.format = AUDIO_S16;
|
|
|
|
fmt.channels = 2;
|
|
|
|
fmt.samples = 2048;
|
|
|
|
fmt.callback = &mixaudio;
|
|
|
|
fmt.userdata = (void *)0;
|
|
|
|
|
|
|
|
if (SDL_OpenAudio(&fmt, &ret_fmt) < 0) {
|
|
|
|
ELOG("Failed to open audio: %s", SDL_GetError());
|
|
|
|
} else {
|
2014-06-25 15:40:28 +10:00
|
|
|
if (ret_fmt.samples != fmt.samples) // Notify, but still use it
|
|
|
|
ELOG("Output audio samples: %d (requested: %d)", ret_fmt.samples, fmt.samples);
|
|
|
|
if (ret_fmt.freq != fmt.freq || ret_fmt.format != fmt.format || ret_fmt.channels != fmt.channels) {
|
2014-06-25 13:00:42 +10:00
|
|
|
ELOG("Sound buffer format does not match requested format.");
|
2014-06-25 15:40:28 +10:00
|
|
|
ELOG("Output audio freq: %d (requested: %d)", ret_fmt.freq, fmt.freq);
|
|
|
|
ELOG("Output audio format: %d (requested: %d)", ret_fmt.format, fmt.format);
|
|
|
|
ELOG("Output audio channels: %d (requested: %d)", ret_fmt.channels, fmt.channels);
|
2014-06-25 13:00:42 +10:00
|
|
|
ELOG("Provided output format does not match requirement, turning audio off");
|
|
|
|
SDL_CloseAudio();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
SDL_PauseAudio(0);
|
|
|
|
#else
|
2014-02-15 01:42:48 -08:00
|
|
|
QScopedPointer<MainAudio> audio(new MainAudio());
|
2014-08-21 03:46:00 +10:00
|
|
|
audio->run();
|
2014-06-25 13:00:42 +10:00
|
|
|
#endif
|
2014-08-21 03:46:00 +10:00
|
|
|
return a.exec();
|
2014-02-15 01:42:48 -08:00
|
|
|
}
|
|
|
|
|
2014-12-18 23:57:59 +01:00
|
|
|
#ifndef SDL
|
2013-11-22 01:59:18 +01:00
|
|
|
Q_DECL_EXPORT
|
|
|
|
#endif
|
|
|
|
int main(int argc, char *argv[])
|
2012-12-13 16:38:33 +10:00
|
|
|
{
|
2014-01-05 10:53:47 +10:00
|
|
|
#if defined(Q_OS_LINUX) && !defined(MAEMO)
|
2013-01-14 19:20:28 +10:00
|
|
|
QApplication::setAttribute(Qt::AA_X11InitThreads, true);
|
|
|
|
#endif
|
2012-12-13 16:38:33 +10:00
|
|
|
QApplication a(argc, argv);
|
|
|
|
QSize res = QApplication::desktop()->screenGeometry().size();
|
|
|
|
if (res.width() < res.height())
|
|
|
|
res.transpose();
|
|
|
|
pixel_xres = res.width();
|
|
|
|
pixel_yres = res.height();
|
2013-08-20 20:30:03 +10:00
|
|
|
g_dpi_scale = CalculateDPIScale();
|
|
|
|
dp_xres = (int)(pixel_xres * g_dpi_scale); dp_yres = (int)(pixel_yres * g_dpi_scale);
|
2012-12-13 17:05:12 +10:00
|
|
|
net::Init();
|
2014-06-25 15:40:28 +10:00
|
|
|
std::string savegame_dir = ".";
|
|
|
|
std::string assets_dir = ".";
|
|
|
|
#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
|
|
|
|
savegame_dir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation).toStdString();
|
2014-06-26 17:58:05 +10:00
|
|
|
assets_dir = QStandardPaths::writableLocation(QStandardPaths::DataLocation).toStdString();
|
2014-06-25 15:40:28 +10:00
|
|
|
#elif defined(__SYMBIAN32__)
|
|
|
|
savegame_dir = "E:/PPSSPP";
|
|
|
|
assets_dir = "E:/PPSSPP";
|
2012-12-23 17:47:52 +10:00
|
|
|
#elif defined(BLACKBERRY)
|
2014-06-25 15:40:28 +10:00
|
|
|
savegame_dir = "/accounts/1000/shared/misc";
|
|
|
|
assets_dir = "app/native/assets";
|
2014-06-18 03:41:20 +10:00
|
|
|
#elif defined(MAEMO)
|
2014-06-25 15:40:28 +10:00
|
|
|
savegame_dir = "/home/user/MyDocs/PPSSPP";
|
|
|
|
assets_dir = "/opt/PPSSPP";
|
2012-12-13 16:38:33 +10:00
|
|
|
#endif
|
2014-06-25 15:40:28 +10:00
|
|
|
savegame_dir += "/";
|
|
|
|
assets_dir += "/";
|
2014-09-23 22:29:02 +02:00
|
|
|
|
2014-09-24 23:23:25 +02:00
|
|
|
bool fullscreenCLI=false;
|
2014-09-23 22:29:02 +02:00
|
|
|
for (int i = 1; i < argc; i++)
|
|
|
|
{
|
|
|
|
if (!strcmp(argv[i],"--fullscreen"))
|
|
|
|
fullscreenCLI=true;
|
|
|
|
}
|
2014-09-24 23:23:25 +02:00
|
|
|
NativeInit(argc, (const char **)argv, savegame_dir.c_str(), assets_dir.c_str(), "BADCOFFEE",fullscreenCLI);
|
2014-09-22 20:08:02 +02:00
|
|
|
|
2014-02-15 01:42:48 -08:00
|
|
|
int ret = mainInternal(a);
|
2012-12-16 19:47:51 +10:00
|
|
|
|
2014-06-25 13:00:42 +10:00
|
|
|
#ifndef MOBILE_DEVICE
|
|
|
|
exit(0);
|
|
|
|
#endif
|
|
|
|
NativeShutdownGraphics();
|
2014-12-18 23:57:59 +01:00
|
|
|
#ifdef SDL
|
2014-06-25 13:00:42 +10:00
|
|
|
SDL_PauseAudio(1);
|
|
|
|
SDL_CloseAudio();
|
2014-06-25 13:26:43 +10:00
|
|
|
#endif
|
2012-12-13 16:38:33 +10:00
|
|
|
NativeShutdown();
|
|
|
|
net::Shutdown();
|
|
|
|
return ret;
|
|
|
|
}
|
2013-10-29 11:23:42 +10:00
|
|
|
|