Merge branch 'master' into armjit

This commit is contained in:
Henrik Rydgard 2013-01-11 18:01:32 +01:00
commit 2e6063d084
17 changed files with 217 additions and 41 deletions

View File

@ -56,6 +56,7 @@ public:
bool bUseVBO;
int iWindowZoom; // for Windows
bool SSAntiAlaising; //for Windows, too
bool bDisableG3DLog;
// Sound
bool bEnableSound;

View File

@ -17,6 +17,7 @@
#include <set>
#include "Common/StringUtil.h"
#include "../HLE/sceKernelThread.h"
#include "MetaFileSystem.h"
static bool ApplyPathStringToComponentsVector(std::vector<std::string> &vector, const std::string &pathString)
@ -163,7 +164,6 @@ IFileSystem *MetaFileSystem::GetHandleOwner(u32 handle)
bool MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpath, IFileSystem **system)
{
//TODO: implement current directory per thread (NOT per drive)
std::string realpath;
// Special handling: host0:command.txt (as seen in Super Monkey Ball Adventures, for example)
@ -174,7 +174,22 @@ bool MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpat
inpath = inpath.substr(6);
}
if ( RealPath(currentDirectory, inpath, realpath) )
const std::string *currentDirectory = &startingDirectory;
int currentThread = __KernelGetCurThread();
currentDir_t::iterator i = currentDir.find(currentThread);
if (i == currentDir.end())
{
//TODO: emulate PSP's error 8002032C: "no current working directory" if relative... may break things requiring fixes elsewhere
if (inpath.find(':') == std::string::npos /* means path is relative */)
WARN_LOG(HLE, "Path is relative, but current directory not set for thread %i. Should give error, instead falling back to %s", currentThread, startingDirectory.c_str());
}
else
{
currentDirectory = &(i->second);
}
if ( RealPath(*currentDirectory, inpath, realpath) )
{
for (size_t i = 0; i < fileSystems.size(); i++)
{
@ -203,7 +218,7 @@ void MetaFileSystem::Mount(std::string prefix, IFileSystem *system)
fileSystems.push_back(x);
}
void MetaFileSystem::UnmountAll()
void MetaFileSystem::Shutdown()
{
current = 6;
@ -220,7 +235,8 @@ void MetaFileSystem::UnmountAll()
}
fileSystems.clear();
currentDirectory = "";
currentDir.clear();
startingDirectory = "";
}
u32 MetaFileSystem::OpenFile(std::string filename, FileAccess access)
@ -278,6 +294,31 @@ std::vector<PSPFileInfo> MetaFileSystem::GetDirListing(std::string path)
}
}
void MetaFileSystem::ThreadEnded(int threadID)
{
currentDir.erase(threadID);
}
void MetaFileSystem::ChDir(const std::string &dir)
{
int curThread = __KernelGetCurThread();
std::string of;
IFileSystem *system;
if (MapFilePath(dir, of, &system))
{
currentDir[curThread] = of;
//return true;
}
else
{
//TODO: PSP's sceIoChdir seems very forgiving, but does it always accept bad paths and what happens when it does?
WARN_LOG(HLE, "ChDir failed to map path \"%s\", saving as current directory anyway", dir.c_str());
currentDir[curThread] = dir;
//return false;
}
}
bool MetaFileSystem::MkDir(const std::string &dirname)
{
std::string of;
@ -372,9 +413,34 @@ size_t MetaFileSystem::SeekFile(u32 handle, s32 position, FileMove type)
void MetaFileSystem::DoState(PointerWrap &p)
{
p.Do(current);
p.Do(currentDirectory);
int n = (int) fileSystems.size();
// Save/load per-thread current directory map
u32 n = (u32) currentDir.size();
p.Do(n);
if (p.mode == p.MODE_READ)
{
std::string dir;
currentDir.clear();
for (u32 i = 0; i < n; ++i)
{
int threadID;
p.Do(threadID);
p.Do(dir);
currentDir[threadID] = dir;
}
}
else
{
currentDir_t::iterator i = currentDir.begin(), end = currentDir.end();
for (; i != end; ++i)
{
p.Do(i->first);
p.Do(i->second);
}
}
n = (u32) fileSystems.size();
p.Do(n);
if (n != fileSystems.size())
{
@ -382,7 +448,7 @@ void MetaFileSystem::DoState(PointerWrap &p)
return;
}
for (int i = 0; i < n; ++i)
for (u32 i = 0; i < n; ++i)
fileSystems[i].system->DoState(p);
p.DoMarker("MetaFileSystem");

View File

@ -30,8 +30,9 @@ public:
void Mount(std::string prefix, IFileSystem *system);
void Unmount(IFileSystem *system);
// Effectively "Shutdown".
void UnmountAll();
void ThreadEnded(int threadID);
void Shutdown();
u32 GetNewHandle() {return current++;}
void FreeHandle(u32 handle) {}
@ -57,7 +58,7 @@ public:
return SeekFile(handle, 0, FILEMOVE_CURRENT);
}
virtual void ChDir(std::string dir) {currentDirectory = dir;}
virtual void ChDir(const std::string &dir);
virtual bool MkDir(const std::string &dirname);
virtual bool RmDir(const std::string &dirname);
@ -66,8 +67,8 @@ public:
// TODO: void IoCtl(...)
void SetCurrentDirectory(const std::string &dir) {
currentDirectory = dir;
void SetStartingDirectory(const std::string &dir) {
startingDirectory = dir;
}
private:
u32 current;
@ -78,5 +79,8 @@ private:
};
std::vector<System> fileSystems;
std::string currentDirectory;
typedef std::map<int, std::string> currentDir_t;
currentDir_t currentDir;
std::string startingDirectory;
};

View File

@ -159,6 +159,10 @@ public:
PSPFileInfo info;
};
static void TellFsThreadEnded (SceUID threadID) {
pspFileSystem.ThreadEnded(threadID);
}
void __IoInit() {
INFO_LOG(HLE, "Starting up I/O...");
@ -199,6 +203,8 @@ void __IoInit() {
pspFileSystem.Mount("fatms:", memstick);
pspFileSystem.Mount("flash0:", flash);
pspFileSystem.Mount("flash1:", flash);
__KernelListenThreadEnd(&TellFsThreadEnded);
}
void __IoDoState(PointerWrap &p) {

View File

@ -423,7 +423,7 @@ extern KernelObjectPool kernelObjects;
struct KernelStats {
void Reset() {
memset(this, 0, sizeof(this));
memset(this, 0, sizeof(*this));
}
void ResetFrame() {
msInSyscalls = 0;

View File

@ -1022,6 +1022,10 @@ int sceMpegGetAvcAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr)
if (!ctx->mediaengine->readVideoAu(&sceAu) || true) {
// Only return this after the video already ended.
if (ctx->endOfVideoReached) {
if (mpegRingbuffer.packetsFree < mpegRingbuffer.packets) {
mpegRingbuffer.packetsFree = mpegRingbuffer.packets;
Memory::WriteStruct(ctx->mpegRingbufferAddr, &mpegRingbuffer);
}
result = PSP_ERROR_MPEG_NO_DATA;
}
if (ctx->mpegLastTimestamp < 0 || sceAu.pts >= ctx->mpegLastTimestamp) {

View File

@ -22,8 +22,22 @@
#include "scePower.h"
#include "sceKernelThread.h"
const int PSP_POWER_ERROR_TAKEN_SLOT = 0x80000020;
const int PSP_POWER_ERROR_SLOTS_FULL = 0x80000022;
const int PSP_POWER_ERROR_PRIVATE_SLOT = 0x80000023;
const int PSP_POWER_ERROR_EMPTY_SLOT = 0x80000025;
const int PSP_POWER_ERROR_INVALID_CB = 0x80000100;
const int PSP_POWER_ERROR_INVALID_SLOT = 0x80000102;
const int PSP_POWER_ERROR_INVALID_TYPE = 0x80000107;
const int PSP_POWER_CB_AC_POWER = 0x00001000;
const int PSP_POWER_CB_BATTERY_EXIST = 0x00000080;
const int PSP_POWER_CB_BATTERY_FULL = 0x00000064;
const int POWER_CB_AUTO = -1;
const int numberOfCBPowerSlots = 16;
const int numberOfCBPowerSlotsPrivate = 32;
static bool volatileMemLocked;
static int powerCbSlots[numberOfCBPowerSlots];
@ -44,6 +58,12 @@ int scePowerGetBatteryLifePercent() {
return 100;
}
int scePowerGetBatteryLifeTime() {
DEBUG_LOG(HLE, "0=scePowerGetBatteryLifeTime()");
// 0 means we're on AC power.
return 0;
}
int scePowerIsPowerOnline() {
DEBUG_LOG(HLE, "1=scePowerIsPowerOnline");
return 1;
@ -70,61 +90,90 @@ int scePowerIsLowBattery() {
}
int scePowerRegisterCallback(int slot, int cbId) {
DEBUG_LOG(HLE,"0=scePowerRegisterCallback(%i, %i)", slot, cbId);
int foundSlot = -1;
DEBUG_LOG(HLE, "0=scePowerRegisterCallback(%i, %i)", slot, cbId);
if (slot < -1 || slot >= numberOfCBPowerSlotsPrivate) {
return PSP_POWER_ERROR_INVALID_SLOT;
}
if (slot >= numberOfCBPowerSlots) {
return PSP_POWER_ERROR_PRIVATE_SLOT;
}
// TODO: If cbId is invalid return PSP_POWER_ERROR_INVALID_CB.
if (cbId == 0) {
return PSP_POWER_ERROR_INVALID_CB;
}
int retval = -1;
if (slot == POWER_CB_AUTO) { // -1 signifies auto select of bank
for (int i=0; i < numberOfCBPowerSlots; i++) {
if ((powerCbSlots[i]==0) && (foundSlot == POWER_CB_AUTO)) { // found an empty slot
if (powerCbSlots[i] == 0 && retval == -1) { // found an empty slot
powerCbSlots[i] = cbId;
foundSlot = i;
retval = i;
}
}
if (retval == -1) {
return PSP_POWER_ERROR_SLOTS_FULL;
}
} else {
if (powerCbSlots[slot] == 0) {
powerCbSlots[slot] = cbId;
foundSlot = 0;
retval = 0;
} else {
// slot already in use!
foundSlot = POWER_CB_AUTO;
return PSP_POWER_ERROR_TAKEN_SLOT;
}
}
if (foundSlot>=0) {
if (retval >= 0) {
__KernelRegisterCallback(THREAD_CALLBACK_POWER, cbId);
__KernelNotifyCallbackType(THREAD_CALLBACK_POWER, cbId, 0x185); // TODO: I have no idea what the 0x185 is from the flags, but its needed for the test to pass. Need another example of it being called
int arg = PSP_POWER_CB_AC_POWER | PSP_POWER_CB_BATTERY_EXIST | PSP_POWER_CB_BATTERY_FULL;
__KernelNotifyCallbackType(THREAD_CALLBACK_POWER, cbId, arg);
}
return foundSlot;
return retval;
}
int scePowerUnregisterCallback(int slotId) {
if (slotId < 0 || slotId >= numberOfCBPowerSlots) {
return -1;
DEBUG_LOG(HLE, "0=scePowerUnregisterCallback(%i)", slotId);
if (slotId < 0 || slotId >= numberOfCBPowerSlotsPrivate) {
return PSP_POWER_ERROR_INVALID_SLOT;
}
if (slotId >= numberOfCBPowerSlots) {
return PSP_POWER_ERROR_PRIVATE_SLOT;
}
if (powerCbSlots[slotId] != 0) {
int cbId = powerCbSlots[slotId];
DEBUG_LOG(HLE,"0=scePowerUnregisterCallback(%i) (cbid = %i)", slotId, cbId);
DEBUG_LOG(HLE, "0=scePowerUnregisterCallback(%i) (cbid = %i)", slotId, cbId);
__KernelUnregisterCallback(THREAD_CALLBACK_POWER, cbId);
powerCbSlots[slotId] = 0;
} else {
return 0x80000025; // TODO: docs say a value less than 0, test checks for this specifically. why??
return PSP_POWER_ERROR_EMPTY_SLOT;
}
return 0;
}
int sceKernelPowerLock(int lockType) {
DEBUG_LOG(HLE,"0=sceKernelPowerLock(%i)", lockType);
return 0;
DEBUG_LOG(HLE, "0=sceKernelPowerLock(%i)", lockType);
if (lockType == 0) {
return 0;
} else {
return PSP_POWER_ERROR_INVALID_TYPE;
}
}
int sceKernelPowerUnlock(int lockType) {
DEBUG_LOG(HLE,"0=sceKernelPowerUnlock(%i)", lockType);
return 0;
DEBUG_LOG(HLE, "0=sceKernelPowerUnlock(%i)", lockType);
if (lockType == 0) {
return 0;
} else {
return PSP_POWER_ERROR_INVALID_TYPE;
}
}
int sceKernelPowerTick(int flag) {
DEBUG_LOG(HLE,"UNIMPL 0=sceKernelPowerTick(%i)", flag);
DEBUG_LOG(HLE, "UNIMPL 0=sceKernelPowerTick(%i)", flag);
return 0;
}
@ -217,7 +266,7 @@ static const HLEFunction scePower[] = {
{0x94F5A53F,0,"scePowerGetBatteryRemainCapacity"},
{0xFD18A0FF,0,"scePowerGetBatteryFullCapacity"},
{0x2085D15D,&WrapI_V<scePowerGetBatteryLifePercent>,"scePowerGetBatteryLifePercent"},
{0x8EFB3FA2,0,"scePowerGetBatteryLifeTime"},
{0x8EFB3FA2,&WrapI_V<scePowerGetBatteryLifeTime>,"scePowerGetBatteryLifeTime"},
{0x28E12023,0,"scePowerGetBatteryTemp"},
{0x862AE1A6,0,"scePowerGetBatteryElec"},
{0x483CE86B,0,"scePowerGetBatteryVolt"},

View File

@ -92,11 +92,11 @@ bool LoadFile(const char *filename, std::string *error_string)
// If loading from memstick...
size_t pos = path.find("/PSP/GAME/");
if (pos != std::string::npos)
pspFileSystem.SetCurrentDirectory("ms0:" + path.substr(pos));
pspFileSystem.SetStartingDirectory("ms0:" + path.substr(pos));
return Load_PSP_ELF_PBP(filename, error_string);
}
case FILETYPE_PSP_ISO:
pspFileSystem.SetCurrentDirectory("disc0:/PSP_GAME/USRDIR");
pspFileSystem.SetStartingDirectory("disc0:/PSP_GAME/USRDIR");
return Load_PSP_ISO(filename, error_string);
case FILETYPE_ERROR:
ERROR_LOG(LOADER, "Could not file");

View File

@ -64,7 +64,7 @@ bool PSP_Init(const CoreParameter &coreParam, std::string *error_string)
if (!LoadFile(coreParameter.fileToStart.c_str(), error_string))
{
pspFileSystem.UnmountAll();
pspFileSystem.Shutdown();
CoreTiming::ClearPendingEvents();
CoreTiming::UnregisterAllEvents();
__KernelShutdown();
@ -90,7 +90,7 @@ bool PSP_IsInited()
void PSP_Shutdown()
{
pspFileSystem.UnmountAll();
pspFileSystem.Shutdown();
TextureCache_Clear(true);

View File

@ -147,6 +147,8 @@ const int flushBeforeCommandList[] = {
GLES_GPU::GLES_GPU(int renderWidth, int renderHeight)
: interruptsEnabled_(true),
displayFramebufPtr_(0),
prevDisplayFramebufPtr_(0),
prevPrevDisplayFramebufPtr_(0),
renderWidth_(renderWidth),
renderHeight_(renderHeight)
{
@ -235,6 +237,8 @@ void GLES_GPU::BeginFrame() {
void GLES_GPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, int format) {
if (framebuf & 0x04000000) {
//DEBUG_LOG(G3D, "Switch display framebuffer %08x", framebuf);
prevPrevDisplayFramebufPtr_ = prevDisplayFramebufPtr_;
prevDisplayFramebufPtr_ = displayFramebufPtr_;
displayFramebufPtr_ = framebuf;
displayStride_ = stride;
displayFormat_ = format;
@ -283,8 +287,20 @@ void GLES_GPU::CopyDisplayToOutput() {
BeginDebugDraw();
}
static bool MaskedEqual(u32 addr1, u32 addr2) {
return (addr1 & 0x3FFFFFF) == (addr2 & 0x3FFFFFF);
}
void GLES_GPU::DecimateFBOs() {
for (auto iter = vfbs_.begin(); iter != vfbs_.end();) {
VirtualFramebuffer *v = *iter;
if (MaskedEqual(v->fb_address, displayFramebufPtr_) ||
MaskedEqual(v->fb_address, prevDisplayFramebufPtr_) ||
MaskedEqual(v->fb_address, prevPrevDisplayFramebufPtr_)) {
++iter;
continue;
}
if ((*iter)->last_frame_used + FBO_OLD_AGE < gpuStats.numFrames) {
fbo_destroy((*iter)->fbo);
vfbs_.erase(iter++);
@ -296,7 +312,7 @@ void GLES_GPU::DecimateFBOs() {
GLES_GPU::VirtualFramebuffer *GLES_GPU::GetDisplayFBO() {
for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter) {
if (((*iter)->fb_address & 0x3FFFFFF) == (displayFramebufPtr_ & 0x3FFFFFF)) {
if (MaskedEqual((*iter)->fb_address, displayFramebufPtr_)) {
// Could check w to but whatever
return *iter;
}

View File

@ -73,6 +73,8 @@ private:
bool interruptsEnabled_;
u32 displayFramebufPtr_;
u32 prevDisplayFramebufPtr_;
u32 prevPrevDisplayFramebufPtr_;
u32 displayStride_;
int displayFormat_;

View File

@ -54,7 +54,7 @@ INCLUDEPATH += ../ext/snappy
# Zlib
!symbian: {
SOURCES += ../ext/zlib/adler32.c \
SOURCES += ../ext/zlib/adler32.c \
../ext/zlib/compress.c \
../ext/zlib/crc32.c \
../ext/zlib/deflate.c \

View File

@ -1,3 +1,4 @@
DEFINES += USING_QT_UI
blackberry|symbian|contains(MEEGO_EDITION,harmattan): CONFIG += mobile_platform
unix:!blackberry:!symbian:!macx: CONFIG += linux

View File

@ -507,6 +507,14 @@ namespace MainWindow
g_Config.SSAntiAlaising = !g_Config.SSAntiAlaising;
UpdateMenus();
break;
case ID_OPTIONS_DISABLEG3DLOG:
g_Config.bDisableG3DLog = !g_Config.bDisableG3DLog;
if (!g_Config.bDisableG3DLog )
LogManager::GetInstance()->SetEnable(LogTypes::G3D, true);
else
LogManager::GetInstance()->SetEnable(LogTypes::G3D, false);
UpdateMenus();
break;
case ID_OPTIONS_CONTROLS:
DialogManager::EnableAll(FALSE);
DialogBox(hInst, (LPCTSTR)IDD_CONTROLS, hWnd, (DLGPROC)Controls);
@ -653,6 +661,7 @@ namespace MainWindow
CHECKITEM(ID_OPTIONS_SIMPLE2XSSAA, g_Config.SSAntiAlaising);
CHECKITEM(ID_EMULATION_RUNONLOAD, g_Config.bAutoRun);
CHECKITEM(ID_OPTIONS_USEVBO, g_Config.bUseVBO);
CHECKITEM(ID_OPTIONS_DISABLEG3DLOG, g_Config.bDisableG3DLog);
UINT enable = !Core_IsStepping() ? MF_GRAYED : MF_ENABLED;
EnableMenuItem(menu,ID_EMULATION_RUN, g_State.bEmuThreadStarted ? enable : MF_GRAYED);

View File

@ -261,6 +261,7 @@ BEGIN
MENUITEM "&Wireframe (experimental)", ID_OPTIONS_WIREFRAME
MENUITEM "&Display Raw Framebuffer", ID_OPTIONS_DISPLAYRAWFRAMEBUFFER
MENUITEM "&Show Debug Statistics", ID_OPTIONS_SHOWDEBUGSTATISTICS
MENUITEM "&Disable G3D Log", ID_OPTIONS_DISABLEG3DLOG
MENUITEM SEPARATOR
MENUITEM "Screen &1x\tCtrl+1", ID_OPTIONS_SCREEN1X
MENUITEM "Screen &2x\tCtrl+2", ID_OPTIONS_SCREEN2X

View File

@ -256,6 +256,7 @@
#define ID_DEBUG_DUMPNEXTFRAME 40132
#define ID_OPTIONS_SIMPLE2XSSAA 40133
#define ID_OPTIONS_USEVBO 40134
#define ID_OPTIONS_DISABLEG3DLOG 40135
#define IDC_STATIC -1
// Next default values for new objects

View File

@ -42,6 +42,12 @@
#include "MenuScreens.h"
#include "EmuScreen.h"
#ifdef USING_QT_UI
#include <QFileDialog>
#include <QFile>
#include <QDir>
#endif
// Ugly communication with NativeApp
extern std::string game_title;
@ -163,6 +169,15 @@ void MenuScreen::render() {
if (UIButton(GEN_ID, vlinear, w, "Load...", ALIGN_RIGHT)) {
#if defined(USING_QT_UI) && defined(__SYMBIAN32__)
QString fileName = QFileDialog::getOpenFileName(NULL, "Load ROM", g_Config.currentDirectory.c_str(), "PSP ROMs (*.iso *.cso *.pbp *.elf)");
if (QFile::exists(fileName)) {
QDir newPath;
g_Config.currentDirectory = newPath.filePath(fileName).toStdString();
g_Config.Save();
screenManager()->switchScreen(new EmuScreen(fileName.toStdString()));
}
#else
FileSelectScreenOptions options;
options.allowChooseDirectory = true;
options.filter = "iso:cso:pbp:elf:prx:";
@ -172,6 +187,7 @@ void MenuScreen::render() {
options.iconMapping["pbp"] = I_ICON_EXE;
options.iconMapping["elf"] = I_ICON_EXE;
screenManager()->switchScreen(new FileSelectScreen(options));
#endif
UIReset();
}
@ -437,7 +453,7 @@ static const char *credits[] =
"Android SDK + NDK",
#elif defined(BLACKBERRY)
"Blackberry NDK",
#elif defined(__SYMBIAN32__)
#elif defined(USING_QT_UI)
"Qt",
#else
"SDL",