2012-11-01 15:19:01 +00:00
|
|
|
// Copyright (c) 2012- PPSSPP Project.
|
|
|
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
2012-11-04 22:01:49 +00:00
|
|
|
// the Free Software Foundation, version 2.0 or later versions.
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
|
|
|
|
// Official git repository and contact information can be found at
|
|
|
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
|
|
|
|
2013-07-06 17:08:59 +00:00
|
|
|
#include "android/app-android.h"
|
2013-03-06 23:10:53 +00:00
|
|
|
#include "base/logging.h"
|
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
#include "gfx_es2/glsl_program.h"
|
2012-12-05 03:45:28 +00:00
|
|
|
#include "gfx_es2/gl_state.h"
|
2012-11-19 22:29:14 +00:00
|
|
|
#include "gfx_es2/fbo.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
#include "input/input_state.h"
|
|
|
|
#include "ui/ui.h"
|
2013-05-27 12:25:30 +00:00
|
|
|
#include "i18n/i18n.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-07-01 04:43:01 +00:00
|
|
|
#include "Common/KeyMap.h"
|
|
|
|
|
2013-03-29 19:51:14 +00:00
|
|
|
#include "Core/Config.h"
|
|
|
|
#include "Core/CoreTiming.h"
|
|
|
|
#include "Core/CoreParameter.h"
|
|
|
|
#include "Core/Core.h"
|
|
|
|
#include "Core/Host.h"
|
|
|
|
#include "Core/System.h"
|
|
|
|
#include "Core/MIPS/MIPS.h"
|
|
|
|
#include "GPU/GPUState.h"
|
|
|
|
#include "GPU/GPUInterface.h"
|
|
|
|
#include "Core/HLE/sceCtrl.h"
|
2013-04-07 20:43:23 +00:00
|
|
|
#include "Core/HLE/sceDisplay.h"
|
2013-03-29 19:51:14 +00:00
|
|
|
#include "Core/Debugger/SymbolMap.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-05-22 16:00:06 +00:00
|
|
|
#include "UI/OnScreenDisplay.h"
|
2013-04-07 20:43:23 +00:00
|
|
|
#include "UI/ui_atlas.h"
|
|
|
|
#include "UI/GamepadEmu.h"
|
|
|
|
#include "UI/UIShader.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-06-10 20:06:51 +00:00
|
|
|
#include "UI/MainScreen.h"
|
2013-04-07 20:43:23 +00:00
|
|
|
#include "UI/MenuScreens.h"
|
|
|
|
#include "UI/EmuScreen.h"
|
2013-04-13 19:24:07 +00:00
|
|
|
#include "UI/GameInfoCache.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-03-29 20:21:27 +00:00
|
|
|
EmuScreen::EmuScreen(const std::string &filename) : invalid_(true) {
|
2013-01-10 22:49:33 +00:00
|
|
|
CheckGLExtensions();
|
2012-11-01 15:19:01 +00:00
|
|
|
std::string fileToStart = filename;
|
|
|
|
// This is probably where we should start up the emulated PSP.
|
|
|
|
INFO_LOG(BOOT, "Starting up hardware.");
|
|
|
|
|
|
|
|
CoreParameter coreParam;
|
2013-02-16 08:49:33 +00:00
|
|
|
coreParam.cpuCore = g_Config.bJit ? CPU_JIT : CPU_INTERPRETER;
|
2012-11-01 15:19:01 +00:00
|
|
|
coreParam.gpuCore = GPU_GLES;
|
|
|
|
coreParam.enableSound = g_Config.bEnableSound;
|
|
|
|
coreParam.fileToStart = fileToStart;
|
|
|
|
coreParam.mountIso = "";
|
|
|
|
coreParam.startPaused = false;
|
|
|
|
coreParam.enableDebugging = false;
|
|
|
|
coreParam.printfEmuLog = false;
|
|
|
|
coreParam.headLess = false;
|
2013-03-29 18:32:20 +00:00
|
|
|
#ifndef _WIN32
|
2013-01-03 11:04:00 +00:00
|
|
|
if (g_Config.iWindowZoom < 1 || g_Config.iWindowZoom > 2)
|
|
|
|
g_Config.iWindowZoom = 1;
|
2013-03-29 18:32:20 +00:00
|
|
|
#endif
|
2013-01-03 11:04:00 +00:00
|
|
|
coreParam.renderWidth = 480 * g_Config.iWindowZoom;
|
|
|
|
coreParam.renderHeight = 272 * g_Config.iWindowZoom;
|
2012-11-19 20:23:29 +00:00
|
|
|
coreParam.outputWidth = dp_xres;
|
|
|
|
coreParam.outputHeight = dp_yres;
|
2012-11-20 15:48:24 +00:00
|
|
|
coreParam.pixelWidth = pixel_xres;
|
|
|
|
coreParam.pixelHeight = pixel_yres;
|
2013-04-11 19:04:02 +00:00
|
|
|
if (g_Config.SSAntiAliasing) {
|
|
|
|
coreParam.renderWidth *= 2;
|
|
|
|
coreParam.renderHeight *= 2;
|
|
|
|
}
|
2012-11-01 15:19:01 +00:00
|
|
|
std::string error_string;
|
|
|
|
if (PSP_Init(coreParam, &error_string)) {
|
|
|
|
invalid_ = false;
|
|
|
|
} else {
|
|
|
|
invalid_ = true;
|
|
|
|
errorMessage_ = error_string;
|
|
|
|
ERROR_LOG(BOOT, "%s", errorMessage_.c_str());
|
|
|
|
return;
|
|
|
|
}
|
2013-05-16 15:18:29 +00:00
|
|
|
|
2013-04-01 02:25:30 +00:00
|
|
|
globalUIState = UISTATE_INGAME;
|
2013-03-29 18:52:32 +00:00
|
|
|
host->BootDone();
|
2013-03-29 19:51:14 +00:00
|
|
|
host->UpdateDisassembly();
|
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
LayoutGamepad(dp_xres, dp_yres);
|
|
|
|
|
2013-04-13 19:24:07 +00:00
|
|
|
g_gameInfoCache.FlushBGs();
|
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
NOTICE_LOG(BOOT, "Loading %s...", fileToStart.c_str());
|
2013-06-10 22:51:10 +00:00
|
|
|
I18NCategory *s = GetI18NCategory("Screen");
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
if (g_Config.bFirstRun) {
|
|
|
|
osm.Show(s->T("PressESC", "Press ESC to open the pause menu"), 3.0f);
|
|
|
|
}
|
|
|
|
#endif
|
2013-07-06 17:08:59 +00:00
|
|
|
memset(analog_, 0, sizeof(analog_));
|
2013-07-06 18:44:34 +00:00
|
|
|
memset(&fakeInputState, 0, sizeof(fakeInputState));
|
|
|
|
memset(virtKeys, 0, sizeof(virtKeys));
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
|
2013-03-29 20:21:27 +00:00
|
|
|
EmuScreen::~EmuScreen() {
|
2012-11-01 15:19:01 +00:00
|
|
|
if (!invalid_) {
|
|
|
|
// If we were invalid, it would already be shutdown.
|
|
|
|
PSP_Shutdown();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EmuScreen::dialogFinished(const Screen *dialog, DialogResult result) {
|
|
|
|
if (result == DR_OK) {
|
2013-06-10 20:06:51 +00:00
|
|
|
if (g_Config.bNewUI)
|
|
|
|
screenManager()->switchScreen(new MainScreen());
|
|
|
|
else
|
|
|
|
screenManager()->switchScreen(new MenuScreen());
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-29 20:21:27 +00:00
|
|
|
void EmuScreen::sendMessage(const char *message, const char *value) {
|
2013-03-29 17:50:08 +00:00
|
|
|
// External commands, like from the Windows UI.
|
|
|
|
if (!strcmp(message, "pause")) {
|
|
|
|
screenManager()->push(new PauseScreen());
|
|
|
|
} else if (!strcmp(message, "stop")) {
|
2013-06-10 20:06:51 +00:00
|
|
|
if (g_Config.bNewUI)
|
|
|
|
screenManager()->switchScreen(new MainScreen());
|
|
|
|
else
|
|
|
|
screenManager()->switchScreen(new MenuScreen());
|
2013-03-29 19:51:14 +00:00
|
|
|
} else if (!strcmp(message, "reset")) {
|
|
|
|
PSP_Shutdown();
|
|
|
|
std::string resetError;
|
|
|
|
if (!PSP_Init(PSP_CoreParameter(), &resetError)) {
|
2013-03-29 20:21:27 +00:00
|
|
|
ELOG("Error resetting: %s", resetError.c_str());
|
2013-06-10 20:06:51 +00:00
|
|
|
if (g_Config.bNewUI)
|
|
|
|
screenManager()->switchScreen(new MainScreen());
|
|
|
|
else
|
|
|
|
screenManager()->switchScreen(new MenuScreen());
|
2013-03-29 19:51:14 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
host->BootDone();
|
|
|
|
host->UpdateDisassembly();
|
|
|
|
#ifdef _WIN32
|
|
|
|
if (g_Config.bAutoRun) {
|
|
|
|
Core_EnableStepping(false);
|
|
|
|
} else {
|
|
|
|
Core_EnableStepping(true);
|
|
|
|
}
|
|
|
|
#endif
|
2013-03-29 17:50:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-10 12:21:36 +00:00
|
|
|
inline float curve1(float x) {
|
|
|
|
const float deadzone = 0.15f;
|
|
|
|
const float factor = 1.0f / (1.0f - deadzone);
|
|
|
|
if (x > deadzone) {
|
|
|
|
return (x - deadzone) * (x - deadzone) * factor;
|
|
|
|
} else if (x < -0.1f) {
|
|
|
|
return -(x + deadzone) * (x + deadzone) * factor;
|
|
|
|
} else {
|
|
|
|
return 0.0f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline float clamp1(float x) {
|
|
|
|
if (x > 1.0f) return 1.0f;
|
|
|
|
if (x < -1.0f) return -1.0f;
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
2013-07-06 17:08:59 +00:00
|
|
|
void EmuScreen::touch(const TouchInput &touch) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-07-07 08:42:39 +00:00
|
|
|
void EmuScreen::onVKeyDown(int virtualKeyCode) {
|
2013-07-07 12:08:08 +00:00
|
|
|
I18NCategory *s = GetI18NCategory("Screen");
|
|
|
|
|
2013-07-07 08:42:39 +00:00
|
|
|
switch (virtualKeyCode) {
|
|
|
|
case VIRTKEY_UNTHROTTLE:
|
|
|
|
PSP_CoreParameter().unthrottle = true;
|
|
|
|
break;
|
2013-07-07 12:08:08 +00:00
|
|
|
case VIRTKEY_SPEED_TOGGLE:
|
|
|
|
if (PSP_CoreParameter().fpsLimit == 0) {
|
|
|
|
PSP_CoreParameter().fpsLimit = 1;
|
|
|
|
osm.Show(s->T("fixed", "Speed: fixed"), 1.0);
|
|
|
|
}
|
|
|
|
else if (PSP_CoreParameter().fpsLimit == 1) {
|
|
|
|
PSP_CoreParameter().fpsLimit = 2;
|
|
|
|
osm.Show(s->T("unlimited", "Speed: unlimited!"), 1.0, 0x50E0FF);
|
|
|
|
}
|
|
|
|
else if (PSP_CoreParameter().fpsLimit == 2) {
|
|
|
|
PSP_CoreParameter().fpsLimit = 0;
|
|
|
|
osm.Show(s->T("standard", "Speed: standard"), 1.0);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case VIRTKEY_PAUSE:
|
|
|
|
fbo_unbind();
|
|
|
|
screenManager()->push(new PauseScreen());
|
|
|
|
break;
|
2013-07-07 08:42:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EmuScreen::onVKeyUp(int virtualKeyCode) {
|
|
|
|
switch (virtualKeyCode) {
|
|
|
|
case VIRTKEY_UNTHROTTLE:
|
|
|
|
PSP_CoreParameter().unthrottle = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-06 17:08:59 +00:00
|
|
|
void EmuScreen::key(const KeyInput &key) {
|
|
|
|
int result = KeyMap::KeyToPspButton(key.deviceId, key.keyCode);
|
|
|
|
if (result == KEYMAP_ERROR_UNKNOWN_KEY)
|
|
|
|
return;
|
|
|
|
|
2013-07-06 18:44:34 +00:00
|
|
|
if (result >= VIRTKEY_FIRST) {
|
2013-07-07 08:42:39 +00:00
|
|
|
int vk = result - VIRTKEY_FIRST;
|
|
|
|
if (key.flags & KEY_DOWN) {
|
|
|
|
virtKeys[vk] = true;
|
2013-07-07 09:14:46 +00:00
|
|
|
onVKeyDown(result);
|
2013-07-07 08:42:39 +00:00
|
|
|
}
|
|
|
|
if (key.flags & KEY_UP) {
|
|
|
|
virtKeys[vk] = false;
|
2013-07-07 09:14:46 +00:00
|
|
|
onVKeyUp(result);
|
2013-07-07 08:42:39 +00:00
|
|
|
}
|
2013-07-06 18:44:34 +00:00
|
|
|
} else {
|
|
|
|
if (key.flags & KEY_DOWN)
|
|
|
|
__CtrlButtonDown(result);
|
|
|
|
if (key.flags & KEY_UP)
|
|
|
|
__CtrlButtonUp(result);
|
|
|
|
}
|
2013-07-06 17:08:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EmuScreen::axis(const AxisInput &axis) {
|
|
|
|
// TODO: Apply some form of axis mapping
|
|
|
|
switch (axis.axisId) {
|
|
|
|
case JOYSTICK_AXIS_X: analog_[0].x = axis.value; break;
|
|
|
|
case JOYSTICK_AXIS_Y: analog_[0].y = axis.value; break;
|
|
|
|
case JOYSTICK_AXIS_Z: analog_[1].x = axis.value; break;
|
|
|
|
case JOYSTICK_AXIS_RZ: analog_[1].y = axis.value; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: Get rid of this.
|
|
|
|
static const struct { int from, to; } legacy_touch_mapping[12] = {
|
|
|
|
{PAD_BUTTON_A, CTRL_CROSS},
|
|
|
|
{PAD_BUTTON_B, CTRL_CIRCLE},
|
|
|
|
{PAD_BUTTON_X, CTRL_SQUARE},
|
|
|
|
{PAD_BUTTON_Y, CTRL_TRIANGLE},
|
|
|
|
{PAD_BUTTON_START, CTRL_START},
|
|
|
|
{PAD_BUTTON_BACK, CTRL_SELECT},
|
|
|
|
{PAD_BUTTON_LBUMPER, CTRL_LTRIGGER},
|
|
|
|
{PAD_BUTTON_RBUMPER, CTRL_RTRIGGER},
|
|
|
|
{PAD_BUTTON_UP, CTRL_UP},
|
|
|
|
{PAD_BUTTON_RIGHT, CTRL_RIGHT},
|
|
|
|
{PAD_BUTTON_DOWN, CTRL_DOWN},
|
|
|
|
{PAD_BUTTON_LEFT, CTRL_LEFT},
|
|
|
|
};
|
|
|
|
|
2013-03-29 20:21:27 +00:00
|
|
|
void EmuScreen::update(InputState &input) {
|
2013-03-29 18:32:20 +00:00
|
|
|
globalUIState = UISTATE_INGAME;
|
2012-11-01 15:19:01 +00:00
|
|
|
if (errorMessage_.size()) {
|
|
|
|
screenManager()->push(new ErrorScreen(
|
|
|
|
"Error loading file",
|
|
|
|
errorMessage_));
|
|
|
|
errorMessage_ = "";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (invalid_)
|
|
|
|
return;
|
2012-12-26 07:51:03 +00:00
|
|
|
|
2013-07-06 18:44:34 +00:00
|
|
|
float leftstick_x = analog_[0].x;
|
|
|
|
float leftstick_y = analog_[0].y;
|
|
|
|
float rightstick_x = analog_[1].x;
|
|
|
|
float rightstick_y = analog_[1].y;
|
|
|
|
|
|
|
|
// Virtual keys.
|
|
|
|
if (virtKeys[VIRTKEY_AXIS_X_MIN - VIRTKEY_FIRST])
|
|
|
|
leftstick_x -= 1.0f;
|
|
|
|
if (virtKeys[VIRTKEY_AXIS_X_MAX - VIRTKEY_FIRST])
|
|
|
|
leftstick_x += 1.0f;
|
|
|
|
if (virtKeys[VIRTKEY_AXIS_Y_MIN - VIRTKEY_FIRST])
|
|
|
|
leftstick_y -= 1.0f;
|
|
|
|
if (virtKeys[VIRTKEY_AXIS_Y_MAX - VIRTKEY_FIRST])
|
|
|
|
leftstick_y += 1.0f;
|
2013-07-07 02:41:28 +00:00
|
|
|
__CtrlSetRapidFire(virtKeys[VIRTKEY_RAPID_FIRE - VIRTKEY_FIRST]);
|
2013-07-06 18:44:34 +00:00
|
|
|
|
2013-03-10 12:21:36 +00:00
|
|
|
// First translate touches into native pad input.
|
2013-04-09 22:59:52 +00:00
|
|
|
// Do this no matter the value of g_Config.bShowTouchControls, some people
|
|
|
|
// like to use invisible controls...
|
2013-06-14 07:45:03 +00:00
|
|
|
// Don't force on platforms that likely don't have a touchscreen, like Win32, OSX, and Linux...
|
2013-06-14 17:07:13 +00:00
|
|
|
// TODO: What are good ifdefs for OSX and Linux, without breaking other mobile platforms?
|
|
|
|
#ifdef _WIN32
|
|
|
|
if(g_Config.bShowTouchControls) {
|
2013-06-14 07:45:03 +00:00
|
|
|
#endif
|
2013-07-06 17:08:59 +00:00
|
|
|
// TODO: Make new better touch buttons so we don't have to do this crap.
|
|
|
|
|
|
|
|
// Copy over the mouse data from the real inputstate.
|
|
|
|
fakeInputState.mouse_valid = input.mouse_valid;
|
|
|
|
fakeInputState.pad_last_buttons = fakeInputState.pad_buttons;
|
|
|
|
fakeInputState.pad_buttons = 0;
|
|
|
|
memcpy(fakeInputState.pointer_down, input.pointer_down, sizeof(input.pointer_down));
|
|
|
|
memcpy(fakeInputState.pointer_x, input.pointer_x, sizeof(input.pointer_x));
|
|
|
|
memcpy(fakeInputState.pointer_y, input.pointer_y, sizeof(input.pointer_y));
|
2013-07-06 19:56:14 +00:00
|
|
|
fakeInputState.pad_lstick_x = 0.0f;
|
|
|
|
fakeInputState.pad_lstick_y = 0.0f;
|
|
|
|
fakeInputState.pad_rstick_x = 0.0f;
|
|
|
|
fakeInputState.pad_rstick_y = 0.0f;
|
2013-07-06 17:08:59 +00:00
|
|
|
UpdateGamepad(fakeInputState);
|
|
|
|
UpdateInputState(&fakeInputState);
|
|
|
|
|
|
|
|
for (int i = 0; i < ARRAY_SIZE(legacy_touch_mapping); i++) {
|
|
|
|
if (fakeInputState.pad_buttons_down & legacy_touch_mapping[i].from)
|
|
|
|
__CtrlButtonDown(legacy_touch_mapping[i].to);
|
|
|
|
if (fakeInputState.pad_buttons_up & legacy_touch_mapping[i].from)
|
|
|
|
__CtrlButtonUp(legacy_touch_mapping[i].to);
|
|
|
|
}
|
2013-07-06 18:44:34 +00:00
|
|
|
leftstick_x += fakeInputState.pad_lstick_x;
|
|
|
|
leftstick_y += fakeInputState.pad_lstick_y;
|
|
|
|
rightstick_x += fakeInputState.pad_rstick_x;
|
|
|
|
rightstick_y += fakeInputState.pad_rstick_y;
|
2013-06-14 17:07:13 +00:00
|
|
|
|
2013-07-07 03:20:25 +00:00
|
|
|
// Also send the special buttons to input, since that's where they're handled.
|
|
|
|
input.pad_buttons_down |= fakeInputState.pad_buttons_down & (PAD_BUTTON_MENU | PAD_BUTTON_BACK | PAD_BUTTON_RIGHT_THUMB | PAD_BUTTON_LEFT_THUMB);
|
|
|
|
input.pad_buttons_up |= fakeInputState.pad_buttons_up & (PAD_BUTTON_MENU | PAD_BUTTON_BACK | PAD_BUTTON_RIGHT_THUMB | PAD_BUTTON_LEFT_THUMB);
|
|
|
|
|
2013-06-14 17:11:35 +00:00
|
|
|
#ifdef _WIN32
|
2013-06-14 17:07:13 +00:00
|
|
|
}
|
2013-06-14 17:11:35 +00:00
|
|
|
#endif
|
|
|
|
|
2013-04-28 20:07:02 +00:00
|
|
|
// Apply tilt to left stick
|
2013-03-10 12:21:36 +00:00
|
|
|
if (g_Config.bAccelerometerToAnalogHoriz) {
|
|
|
|
// TODO: Deadzone, etc.
|
2013-07-06 17:08:59 +00:00
|
|
|
leftstick_x += clamp1(curve1(input.acc.y) * 2.0f);
|
|
|
|
leftstick_x = clamp1(leftstick_x);
|
2013-03-10 12:21:36 +00:00
|
|
|
}
|
|
|
|
|
2013-07-07 01:54:33 +00:00
|
|
|
__CtrlSetAnalogX(clamp1(leftstick_x), CTRL_STICK_LEFT);
|
|
|
|
__CtrlSetAnalogY(clamp1(leftstick_y), CTRL_STICK_LEFT);
|
|
|
|
__CtrlSetAnalogX(clamp1(rightstick_x), CTRL_STICK_RIGHT);
|
|
|
|
__CtrlSetAnalogY(clamp1(rightstick_y), CTRL_STICK_RIGHT);
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-05-10 00:36:23 +00:00
|
|
|
// Make sure fpsLimit starts at 0
|
|
|
|
if (PSP_CoreParameter().fpsLimit != 0 && PSP_CoreParameter().fpsLimit != 1 && PSP_CoreParameter().fpsLimit != 2) {
|
|
|
|
PSP_CoreParameter().fpsLimit = 0;
|
|
|
|
}
|
2013-06-17 18:28:22 +00:00
|
|
|
|
2013-07-07 12:08:08 +00:00
|
|
|
// This is still here to support the iOS on screen back button.
|
|
|
|
if (input.pad_buttons_down & (PAD_BUTTON_BACK)) {
|
2013-07-07 08:42:39 +00:00
|
|
|
fbo_unbind();
|
2013-03-29 17:50:08 +00:00
|
|
|
screenManager()->push(new PauseScreen());
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-29 20:21:27 +00:00
|
|
|
void EmuScreen::render() {
|
2012-11-01 15:19:01 +00:00
|
|
|
if (invalid_)
|
|
|
|
return;
|
|
|
|
|
2012-11-25 16:21:23 +00:00
|
|
|
// Reapply the graphics state of the PSP
|
|
|
|
ReapplyGfxState();
|
|
|
|
|
2012-12-01 22:20:08 +00:00
|
|
|
// We just run the CPU until we get to vblank. This will quickly sync up pretty nicely.
|
2012-11-20 10:35:48 +00:00
|
|
|
// The actual number of cycles doesn't matter so much here as we will break due to CORE_NEXTFRAME, most of the time hopefully...
|
2013-02-18 22:22:41 +00:00
|
|
|
int blockTicks = usToCycles(1000000 / 10);
|
2012-11-19 13:16:37 +00:00
|
|
|
|
2012-11-19 13:51:47 +00:00
|
|
|
// Run until CORE_NEXTFRAME
|
|
|
|
while (coreState == CORE_RUNNING) {
|
2012-11-19 13:16:37 +00:00
|
|
|
u64 nowTicks = CoreTiming::GetTicks();
|
2012-11-20 10:35:48 +00:00
|
|
|
mipsr4k.RunLoopUntil(nowTicks + blockTicks);
|
2012-11-19 13:51:47 +00:00
|
|
|
}
|
|
|
|
// Hopefully coreState is now CORE_NEXTFRAME
|
|
|
|
if (coreState == CORE_NEXTFRAME) {
|
|
|
|
// set back to running for the next frame
|
|
|
|
coreState = CORE_RUNNING;
|
2013-03-06 23:10:53 +00:00
|
|
|
} else if (coreState == CORE_POWERDOWN) {
|
|
|
|
ILOG("SELF-POWERDOWN!");
|
2013-06-10 20:06:51 +00:00
|
|
|
if (g_Config.bNewUI)
|
|
|
|
screenManager()->switchScreen(new MainScreen());
|
|
|
|
else
|
|
|
|
screenManager()->switchScreen(new MenuScreen());
|
2012-11-19 13:16:37 +00:00
|
|
|
}
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-03-06 23:10:53 +00:00
|
|
|
if (invalid_)
|
|
|
|
return;
|
|
|
|
|
2013-01-14 18:38:02 +00:00
|
|
|
if (g_Config.bBufferedRendering)
|
|
|
|
fbo_unbind();
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2012-11-20 10:35:48 +00:00
|
|
|
UIShader_Prepare();
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2012-11-20 10:35:48 +00:00
|
|
|
uiTexture->Bind(0);
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-01-06 22:23:36 +00:00
|
|
|
glstate.viewport.set(0, 0, pixel_xres, pixel_yres);
|
|
|
|
glstate.viewport.restore();
|
2012-11-20 10:35:48 +00:00
|
|
|
|
2013-03-30 18:23:20 +00:00
|
|
|
ui_draw2d.Begin(UIShader_Get(), DBMODE_NORMAL);
|
2012-11-20 10:35:48 +00:00
|
|
|
|
2013-06-17 18:28:22 +00:00
|
|
|
float touchOpacity = g_Config.iTouchButtonOpacity / 100.0f;
|
2012-12-01 22:20:08 +00:00
|
|
|
if (g_Config.bShowTouchControls)
|
2013-06-17 18:28:22 +00:00
|
|
|
DrawGamepad(ui_draw2d, touchOpacity);
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2012-11-20 10:35:48 +00:00
|
|
|
DrawWatermark();
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-05-22 16:00:06 +00:00
|
|
|
if (!osm.IsEmpty()) {
|
|
|
|
osm.Draw(ui_draw2d);
|
|
|
|
}
|
|
|
|
|
2013-04-07 20:43:23 +00:00
|
|
|
if (g_Config.bShowDebugStats) {
|
2013-04-07 21:02:33 +00:00
|
|
|
char statbuf[4096] = {0};
|
2013-04-07 20:43:23 +00:00
|
|
|
__DisplayGetDebugStats(statbuf);
|
2013-04-07 21:02:33 +00:00
|
|
|
if (statbuf[4095])
|
|
|
|
ERROR_LOG(HLE, "Statbuf too big");
|
2013-04-07 20:43:23 +00:00
|
|
|
ui_draw2d.SetFontScale(.7f, .7f);
|
2013-04-08 18:59:45 +00:00
|
|
|
ui_draw2d.DrawText(UBUNTU24, statbuf, 11, 11, 0xc0000000);
|
2013-04-07 20:43:23 +00:00
|
|
|
ui_draw2d.DrawText(UBUNTU24, statbuf, 10, 10, 0xFFFFFFFF);
|
|
|
|
ui_draw2d.SetFontScale(1.0f, 1.0f);
|
|
|
|
}
|
|
|
|
|
2013-06-19 05:08:29 +00:00
|
|
|
if (g_Config.iShowFPSCounter) {
|
2013-04-07 20:43:23 +00:00
|
|
|
float vps, fps;
|
|
|
|
__DisplayGetFPS(&vps, &fps);
|
|
|
|
char fpsbuf[256];
|
2013-06-19 05:08:29 +00:00
|
|
|
switch (g_Config.iShowFPSCounter) {
|
2013-06-19 07:24:35 +00:00
|
|
|
case 1:
|
2013-06-30 02:57:25 +00:00
|
|
|
sprintf(fpsbuf, "Speed: %0.1f", vps); break;
|
2013-06-19 07:24:35 +00:00
|
|
|
case 2:
|
2013-06-19 05:08:29 +00:00
|
|
|
sprintf(fpsbuf, "FPS: %0.1f", fps); break;
|
2013-06-19 07:24:35 +00:00
|
|
|
case 3:
|
2013-06-30 07:03:32 +00:00
|
|
|
sprintf(fpsbuf, "Speed: %5.1f\nFPS: %0.1f", vps, fps); break;
|
2013-06-19 05:08:29 +00:00
|
|
|
}
|
2013-04-08 18:59:45 +00:00
|
|
|
ui_draw2d.DrawText(UBUNTU24, fpsbuf, dp_xres - 8, 12, 0xc0000000, ALIGN_TOPRIGHT);
|
2013-04-07 20:43:23 +00:00
|
|
|
ui_draw2d.DrawText(UBUNTU24, fpsbuf, dp_xres - 10, 10, 0xFF3fFF3f, ALIGN_TOPRIGHT);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-20 10:35:48 +00:00
|
|
|
glsl_bind(UIShader_Get());
|
|
|
|
ui_draw2d.End();
|
2013-03-30 18:23:20 +00:00
|
|
|
ui_draw2d.Flush();
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
// Tiled renderers like PowerVR should benefit greatly from this. However - seems I can't call it?
|
2012-11-26 03:25:14 +00:00
|
|
|
#if defined(USING_GLES2)
|
2013-04-11 19:04:02 +00:00
|
|
|
bool hasDiscard = gl_extensions.EXT_discard_framebuffer; // TODO
|
2012-11-01 15:19:01 +00:00
|
|
|
if (hasDiscard) {
|
2013-04-11 19:04:02 +00:00
|
|
|
//const GLenum targets[3] = { GL_COLOR_EXT, GL_DEPTH_EXT, GL_STENCIL_EXT };
|
|
|
|
//glDiscardFramebufferEXT(GL_FRAMEBUFFER, 3, targets);
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-03-29 20:21:27 +00:00
|
|
|
void EmuScreen::deviceLost() {
|
2013-03-06 23:10:53 +00:00
|
|
|
ILOG("EmuScreen::deviceLost()");
|
2012-12-25 14:28:34 +00:00
|
|
|
gpu->DeviceLost();
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|