mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge branch 'master' of github.com:hrydgard/ppsspp
This commit is contained in:
commit
eefcc9ba83
55 changed files with 1072 additions and 793 deletions
|
@ -128,8 +128,8 @@ void CPUInfo::Detect()
|
||||||
// Get the information about the CPU
|
// Get the information about the CPU
|
||||||
num_cores = GetCoreCount();
|
num_cores = GetCoreCount();
|
||||||
#if defined(__SYMBIAN32__) || defined(BLACKBERRY) || defined(IOS)
|
#if defined(__SYMBIAN32__) || defined(BLACKBERRY) || defined(IOS)
|
||||||
bool isVFP3 = false;
|
bool isVFP3 = false;
|
||||||
bool isVFP4 = false;
|
bool isVFP4 = false;
|
||||||
#ifdef IOS
|
#ifdef IOS
|
||||||
isVFP3 = true;
|
isVFP3 = true;
|
||||||
// TODO: Check for swift arch (VFP4)
|
// TODO: Check for swift arch (VFP4)
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "ChunkFile.h"
|
#include "ChunkFile.h"
|
||||||
|
#include "MemoryUtil.h"
|
||||||
|
|
||||||
// STL-look-a-like interface, but name is mixed case to distinguish it clearly from the
|
// STL-look-a-like interface, but name is mixed case to distinguish it clearly from the
|
||||||
// real STL classes.
|
// real STL classes.
|
||||||
|
@ -30,11 +31,15 @@ template <class T, int N>
|
||||||
class FixedSizeQueue {
|
class FixedSizeQueue {
|
||||||
public:
|
public:
|
||||||
FixedSizeQueue() {
|
FixedSizeQueue() {
|
||||||
|
// Allocate aligned memory, just because.
|
||||||
|
//int sizeInBytes = N * sizeof(T);
|
||||||
|
//storage_ = (T *)AllocateMemoryPages(sizeInBytes);
|
||||||
storage_ = new T[N];
|
storage_ = new T[N];
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
~FixedSizeQueue() {
|
~FixedSizeQueue() {
|
||||||
|
// FreeMemoryPages((void *)storage_, N * sizeof(T));
|
||||||
delete [] storage_;
|
delete [] storage_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +57,45 @@ public:
|
||||||
count_++;
|
count_++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gets pointers to write to directly.
|
||||||
|
void pushPointers(size_t size, T **dest1, size_t *sz1, T **dest2, size_t *sz2) {
|
||||||
|
if (tail_ + size < N) {
|
||||||
|
*dest1 = &storage_[tail_];
|
||||||
|
*sz1 = size;
|
||||||
|
tail_ += (int)size;
|
||||||
|
if (tail_ == N) tail_ = 0;
|
||||||
|
*dest2 = 0;
|
||||||
|
*sz2 = 0;
|
||||||
|
} else {
|
||||||
|
*dest1 = &storage_[tail_];
|
||||||
|
*sz1 = N - tail_;
|
||||||
|
tail_ = (int)(size - *sz1);
|
||||||
|
*dest2 = &storage_[0];
|
||||||
|
*sz2 = tail_;
|
||||||
|
}
|
||||||
|
count_ += (int)size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void popPointers(size_t size, const T **src1, size_t *sz1, const T **src2, size_t *sz2) {
|
||||||
|
if (size > count_) size = count_;
|
||||||
|
|
||||||
|
if (head_ + size < N) {
|
||||||
|
*src1 = &storage_[head_];
|
||||||
|
*sz1 = size;
|
||||||
|
head_ += (int)size;
|
||||||
|
if (head_ == N) head_ = 0;
|
||||||
|
*src2 = 0;
|
||||||
|
*sz2 = 0;
|
||||||
|
} else {
|
||||||
|
*src1 = &storage_[head_];
|
||||||
|
*sz1 = N - head_;
|
||||||
|
head_ = (int)(size - *sz1);
|
||||||
|
*src2 = &storage_[0];
|
||||||
|
*sz2 = head_;
|
||||||
|
}
|
||||||
|
count_ -= (int)size;
|
||||||
|
}
|
||||||
|
|
||||||
void pop() {
|
void pop() {
|
||||||
head_++;
|
head_++;
|
||||||
if (head_ == N)
|
if (head_ == N)
|
||||||
|
@ -125,5 +169,61 @@ private:
|
||||||
FixedSizeQueue(FixedSizeQueue &other) { }
|
FixedSizeQueue(FixedSizeQueue &other) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// I'm not sure this is 100% safe but it might be "Good Enough" :)
|
||||||
|
// TODO: Use this, maybe make it safer first by using proper atomics
|
||||||
|
// instead of volatile
|
||||||
|
template<class T, int blockSize, int numBlocks>
|
||||||
|
class LockFreeBlockQueue {
|
||||||
|
public:
|
||||||
|
LockFreeBlockQueue() {
|
||||||
|
curReadBlock = 0;
|
||||||
|
curWriteBlock = 0;
|
||||||
|
for (size_t i = 0; i < numBlocks; i++) {
|
||||||
|
blocks[i] = new T[blockSize];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~LockFreeBlockQueue() {
|
||||||
|
for (size_t i = 0; i < numBlocks; i++) {
|
||||||
|
delete [] blocks[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write to the returned pointer then call EndPush to finish the push.
|
||||||
|
T *BeginPush() {
|
||||||
|
return blocks[curWriteBlock];
|
||||||
|
}
|
||||||
|
void EndPush() {
|
||||||
|
curWriteBlock++;
|
||||||
|
if (curWriteBlock == NUM_BLOCKS)
|
||||||
|
curWriteBlock = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanPush() {
|
||||||
|
int nextBlock = curWriteBlock + 1;
|
||||||
|
if (nextBlock == NUM_BLOCKS) nextBlock = 0;
|
||||||
|
return nextBlock != curReadBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanPop() { return curReadBlock != curWriteBlock; }
|
||||||
|
|
||||||
|
// Read from the returned pointer then call EndPush to finish the pop.
|
||||||
|
T *BeginPop() {
|
||||||
|
return blocks[curReadBlock];
|
||||||
|
}
|
||||||
|
T *EndPop() {
|
||||||
|
curReadBlock++;
|
||||||
|
if (curReadBlock == NUM_BLOCKS)
|
||||||
|
curReadBlock = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum { NUM_BLOCKS = 16 };
|
||||||
|
T **blocks[NUM_BLOCKS];
|
||||||
|
|
||||||
|
volatile int curReadBlock;
|
||||||
|
volatile int curWriteBlock;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // _FIXED_SIZE_QUEUE_H_
|
#endif // _FIXED_SIZE_QUEUE_H_
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,7 @@ void* AllocateExecutableMemory(size_t size, bool low)
|
||||||
|
|
||||||
void* AllocateMemoryPages(size_t size)
|
void* AllocateMemoryPages(size_t size)
|
||||||
{
|
{
|
||||||
|
size = (size + 4095) & (~4095);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
||||||
#elif defined(__SYMBIAN32__)
|
#elif defined(__SYMBIAN32__)
|
||||||
|
@ -169,6 +170,7 @@ void* AllocateAlignedMemory(size_t size,size_t alignment)
|
||||||
|
|
||||||
void FreeMemoryPages(void* ptr, size_t size)
|
void FreeMemoryPages(void* ptr, size_t size)
|
||||||
{
|
{
|
||||||
|
size = (size + 4095) & (~4095);
|
||||||
if (ptr)
|
if (ptr)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
|
@ -87,7 +87,7 @@ void Config::Load(const char *iniFileName)
|
||||||
cpu->Get("FastMemory", &bFastMemory, false);
|
cpu->Get("FastMemory", &bFastMemory, false);
|
||||||
|
|
||||||
IniFile::Section *graphics = iniFile.GetOrCreateSection("Graphics");
|
IniFile::Section *graphics = iniFile.GetOrCreateSection("Graphics");
|
||||||
graphics->Get("ShowFPSCounter", &bShowFPSCounter, false);
|
graphics->Get("ShowFPSCounter", &iShowFPSCounter, false);
|
||||||
graphics->Get("DisplayFramebuffer", &bDisplayFramebuffer, false);
|
graphics->Get("DisplayFramebuffer", &bDisplayFramebuffer, false);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
graphics->Get("ResolutionScale", &iWindowZoom, 2);
|
graphics->Get("ResolutionScale", &iWindowZoom, 2);
|
||||||
|
@ -138,15 +138,16 @@ void Config::Load(const char *iniFileName)
|
||||||
control->Get("ForceInputDevice", &iForceInputDevice, -1);
|
control->Get("ForceInputDevice", &iForceInputDevice, -1);
|
||||||
control->Get("RightStickBind", &iRightStickBind, 0);
|
control->Get("RightStickBind", &iRightStickBind, 0);
|
||||||
control->Get("TouchButtonOpacity", &iTouchButtonOpacity, 65);
|
control->Get("TouchButtonOpacity", &iTouchButtonOpacity, 65);
|
||||||
|
control->Get("ButtonScale", &fButtonScale, 1.15);
|
||||||
|
|
||||||
IniFile::Section *pspConfig = iniFile.GetOrCreateSection("SystemParam");
|
IniFile::Section *pspConfig = iniFile.GetOrCreateSection("SystemParam");
|
||||||
pspConfig->Get("NickName", &sNickName, "shadow");
|
pspConfig->Get("NickName", &sNickName, "shadow");
|
||||||
pspConfig->Get("Language", &ilanguage, PSP_SYSTEMPARAM_LANGUAGE_ENGLISH);
|
pspConfig->Get("Language", &ilanguage, PSP_SYSTEMPARAM_LANGUAGE_ENGLISH);
|
||||||
pspConfig->Get("TimeFormat", &itimeformat, PSP_SYSTEMPARAM_TIME_FORMAT_24HR);
|
pspConfig->Get("TimeFormat", &iTimeFormat, PSP_SYSTEMPARAM_TIME_FORMAT_24HR);
|
||||||
pspConfig->Get("DateFormat", &iDateFormat, PSP_SYSTEMPARAM_DATE_FORMAT_YYYYMMDD);
|
pspConfig->Get("DateFormat", &iDateFormat, PSP_SYSTEMPARAM_DATE_FORMAT_YYYYMMDD);
|
||||||
pspConfig->Get("TimeZone", &iTimeZone, 0);
|
pspConfig->Get("TimeZone", &iTimeZone, 0);
|
||||||
pspConfig->Get("DayLightSavings", &bDayLightSavings, PSP_SYSTEMPARAM_DAYLIGHTSAVINGS_STD);
|
pspConfig->Get("DayLightSavings", &bDayLightSavings, PSP_SYSTEMPARAM_DAYLIGHTSAVINGS_STD);
|
||||||
pspConfig->Get("ButtonPreference", &bButtonPreference, PSP_SYSTEMPARAM_BUTTON_CROSS);
|
pspConfig->Get("ButtonPreference", &iButtonPreference, PSP_SYSTEMPARAM_BUTTON_CROSS);
|
||||||
pspConfig->Get("LockParentalLevel", &iLockParentalLevel, 0);
|
pspConfig->Get("LockParentalLevel", &iLockParentalLevel, 0);
|
||||||
pspConfig->Get("WlanAdhocChannel", &iWlanAdhocChannel, PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC);
|
pspConfig->Get("WlanAdhocChannel", &iWlanAdhocChannel, PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC);
|
||||||
pspConfig->Get("WlanPowerSave", &bWlanPowerSave, PSP_SYSTEMPARAM_WLAN_POWERSAVE_OFF);
|
pspConfig->Get("WlanPowerSave", &bWlanPowerSave, PSP_SYSTEMPARAM_WLAN_POWERSAVE_OFF);
|
||||||
|
@ -195,7 +196,7 @@ void Config::Save()
|
||||||
cpu->Set("FastMemory", bFastMemory);
|
cpu->Set("FastMemory", bFastMemory);
|
||||||
|
|
||||||
IniFile::Section *graphics = iniFile.GetOrCreateSection("Graphics");
|
IniFile::Section *graphics = iniFile.GetOrCreateSection("Graphics");
|
||||||
graphics->Set("ShowFPSCounter", bShowFPSCounter);
|
graphics->Set("ShowFPSCounter", iShowFPSCounter);
|
||||||
graphics->Set("DisplayFramebuffer", bDisplayFramebuffer);
|
graphics->Set("DisplayFramebuffer", bDisplayFramebuffer);
|
||||||
graphics->Set("ResolutionScale", iWindowZoom);
|
graphics->Set("ResolutionScale", iWindowZoom);
|
||||||
graphics->Set("BufferedRendering", bBufferedRendering);
|
graphics->Set("BufferedRendering", bBufferedRendering);
|
||||||
|
@ -232,16 +233,16 @@ void Config::Save()
|
||||||
control->Set("ForceInputDevice", iForceInputDevice);
|
control->Set("ForceInputDevice", iForceInputDevice);
|
||||||
control->Set("RightStickBind", iRightStickBind);
|
control->Set("RightStickBind", iRightStickBind);
|
||||||
control->Set("TouchButtonOpacity", iTouchButtonOpacity);
|
control->Set("TouchButtonOpacity", iTouchButtonOpacity);
|
||||||
|
control->Set("ButtonScale", fButtonScale);
|
||||||
|
|
||||||
IniFile::Section *pspConfig = iniFile.GetOrCreateSection("SystemParam");
|
IniFile::Section *pspConfig = iniFile.GetOrCreateSection("SystemParam");
|
||||||
pspConfig->Set("NickName", sNickName.c_str());
|
pspConfig->Set("NickName", sNickName.c_str());
|
||||||
pspConfig->Set("Language", ilanguage);
|
pspConfig->Set("Language", ilanguage);
|
||||||
pspConfig->Set("TimeFormat", itimeformat);
|
pspConfig->Set("TimeFormat", iTimeFormat);
|
||||||
pspConfig->Set("DateFormat", iDateFormat);
|
pspConfig->Set("DateFormat", iDateFormat);
|
||||||
pspConfig->Set("TimeZone", iTimeZone);
|
pspConfig->Set("TimeZone", iTimeZone);
|
||||||
pspConfig->Set("DayLightSavings", bDayLightSavings);
|
pspConfig->Set("DayLightSavings", bDayLightSavings);
|
||||||
pspConfig->Set("ButtonPreference", bButtonPreference);
|
pspConfig->Set("ButtonPreference", iButtonPreference);
|
||||||
pspConfig->Set("LockParentalLevel", iLockParentalLevel);
|
pspConfig->Set("LockParentalLevel", iLockParentalLevel);
|
||||||
pspConfig->Set("WlanAdhocChannel", iWlanAdhocChannel);
|
pspConfig->Set("WlanAdhocChannel", iWlanAdhocChannel);
|
||||||
pspConfig->Set("WlanPowerSave", bWlanPowerSave);
|
pspConfig->Set("WlanPowerSave", bWlanPowerSave);
|
||||||
|
|
|
@ -95,7 +95,7 @@ public:
|
||||||
bool bShowTouchControls;
|
bool bShowTouchControls;
|
||||||
bool bShowDebuggerOnLoad;
|
bool bShowDebuggerOnLoad;
|
||||||
bool bShowAnalogStick;
|
bool bShowAnalogStick;
|
||||||
bool bShowFPSCounter;
|
int iShowFPSCounter;
|
||||||
bool bShowDebugStats;
|
bool bShowDebugStats;
|
||||||
bool bLargeControls;
|
bool bLargeControls;
|
||||||
bool bAccelerometerToAnalogHoriz;
|
bool bAccelerometerToAnalogHoriz;
|
||||||
|
@ -110,21 +110,24 @@ public:
|
||||||
std::map<int,int> iMappingMap; // Can be used differently depending on systems
|
std::map<int,int> iMappingMap; // Can be used differently depending on systems
|
||||||
int iForceInputDevice;
|
int iForceInputDevice;
|
||||||
int iTouchButtonOpacity;
|
int iTouchButtonOpacity;
|
||||||
|
float fButtonScale;
|
||||||
|
|
||||||
// SystemParam
|
// SystemParam
|
||||||
std::string sNickName;
|
std::string sNickName;
|
||||||
int ilanguage;
|
int ilanguage;
|
||||||
int itimeformat;
|
int iTimeFormat;
|
||||||
int iDateFormat;
|
int iDateFormat;
|
||||||
int iTimeZone;
|
int iTimeZone;
|
||||||
bool bDayLightSavings;
|
bool bDayLightSavings;
|
||||||
bool bButtonPreference;
|
bool bButtonPreference;
|
||||||
|
int iButtonPreference;
|
||||||
int iLockParentalLevel;
|
int iLockParentalLevel;
|
||||||
bool bEncryptSave;
|
bool bEncryptSave;
|
||||||
int iWlanAdhocChannel;
|
int iWlanAdhocChannel;
|
||||||
bool bWlanPowerSave;
|
bool bWlanPowerSave;
|
||||||
|
|
||||||
std::string currentDirectory;
|
std::string currentDirectory;
|
||||||
|
std::string externalDirectory;
|
||||||
std::string memCardDirectory;
|
std::string memCardDirectory;
|
||||||
std::string flashDirectory;
|
std::string flashDirectory;
|
||||||
std::string internalDataDirectory;
|
std::string internalDataDirectory;
|
||||||
|
|
|
@ -356,14 +356,24 @@ void PSPSaveDialog::DisplaySaveDataInfo1()
|
||||||
char hour_time[10] ;
|
char hour_time[10] ;
|
||||||
int hour = param.GetFileInfo(currentSelectedSave).modif_time.tm_hour;
|
int hour = param.GetFileInfo(currentSelectedSave).modif_time.tm_hour;
|
||||||
int min = param.GetFileInfo(currentSelectedSave).modif_time.tm_min;
|
int min = param.GetFileInfo(currentSelectedSave).modif_time.tm_min;
|
||||||
if (g_Config.itimeformat == PSP_SYSTEMPARAM_TIME_FORMAT_12HR) {
|
switch (g_Config.iTimeFormat) {
|
||||||
|
case 1:
|
||||||
if (hour > 12) {
|
if (hour > 12) {
|
||||||
strcpy(am_pm, "PM");
|
strcpy(am_pm, "PM");
|
||||||
hour -= 12;
|
hour -= 12;
|
||||||
}
|
}
|
||||||
snprintf(hour_time,10,"%02d:%02d %s", hour, min, am_pm);
|
snprintf(hour_time,10,"%02d:%02d %s", hour, min, am_pm);
|
||||||
} else
|
break;
|
||||||
snprintf(hour_time,10,"%02d:%02d", hour, min);
|
case 2:
|
||||||
|
snprintf(hour_time,10,"%02d:%02d", hour, min);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (hour > 12) {
|
||||||
|
strcpy(am_pm, "PM");
|
||||||
|
hour -= 12;
|
||||||
|
}
|
||||||
|
snprintf(hour_time,10,"%02d:%02d %s", hour, min, am_pm);
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(title, 512, "%s", param.GetFileInfo(currentSelectedSave).title);
|
snprintf(title, 512, "%s", param.GetFileInfo(currentSelectedSave).title);
|
||||||
int day = param.GetFileInfo(currentSelectedSave).modif_time.tm_mday;
|
int day = param.GetFileInfo(currentSelectedSave).modif_time.tm_mday;
|
||||||
|
@ -371,14 +381,15 @@ void PSPSaveDialog::DisplaySaveDataInfo1()
|
||||||
int year = param.GetFileInfo(currentSelectedSave).modif_time.tm_year + 1900;
|
int year = param.GetFileInfo(currentSelectedSave).modif_time.tm_year + 1900;
|
||||||
s64 sizeK = param.GetFileInfo(currentSelectedSave).size / 1024;
|
s64 sizeK = param.GetFileInfo(currentSelectedSave).size / 1024;
|
||||||
switch (g_Config.iDateFormat) {
|
switch (g_Config.iDateFormat) {
|
||||||
case PSP_SYSTEMPARAM_DATE_FORMAT_DDMMYYYY:
|
case 1:
|
||||||
snprintf(time, 512, "%02d/%02d/%d %s %lld KB", day, month, year, hour_time, sizeK);
|
snprintf(time, 512, "%d/%02d/%02d %s %lld KB", year, month, day, hour_time, sizeK);
|
||||||
break;
|
break;
|
||||||
case PSP_SYSTEMPARAM_DATE_FORMAT_MMDDYYYY:
|
case 2:
|
||||||
snprintf(time, 512, "%02d/%02d/%d %s %lld KB", month, day, year, hour_time, sizeK);
|
snprintf(time, 512, "%02d/%02d/%d %s %lld KB", month, day, year, hour_time, sizeK);
|
||||||
break;
|
break;
|
||||||
case PSP_SYSTEMPARAM_DATE_FORMAT_YYYYMMDD:
|
case 3:
|
||||||
// fall through
|
snprintf(time, 512, "%02d/%02d/%d %s %lld KB", day, month, year, hour_time, sizeK);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
snprintf(time, 512, "%d/%02d/%02d %s %lld KB", year, month, day, hour_time, sizeK);
|
snprintf(time, 512, "%d/%02d/%02d %s %lld KB", year, month, day, hour_time, sizeK);
|
||||||
}
|
}
|
||||||
|
@ -408,14 +419,24 @@ void PSPSaveDialog::DisplaySaveDataInfo2()
|
||||||
char hour_time[10] ;
|
char hour_time[10] ;
|
||||||
int hour = param.GetFileInfo(currentSelectedSave).modif_time.tm_hour;
|
int hour = param.GetFileInfo(currentSelectedSave).modif_time.tm_hour;
|
||||||
int min = param.GetFileInfo(currentSelectedSave).modif_time.tm_min;
|
int min = param.GetFileInfo(currentSelectedSave).modif_time.tm_min;
|
||||||
if (g_Config.itimeformat == PSP_SYSTEMPARAM_TIME_FORMAT_12HR) {
|
switch (g_Config.iTimeFormat) {
|
||||||
|
case 1:
|
||||||
if (hour > 12) {
|
if (hour > 12) {
|
||||||
strcpy(am_pm, "PM");
|
strcpy(am_pm, "PM");
|
||||||
hour -= 12;
|
hour -= 12;
|
||||||
}
|
}
|
||||||
snprintf(hour_time,10,"%02d:%02d %s", hour, min, am_pm);
|
snprintf(hour_time,10,"%02d:%02d %s", hour, min, am_pm);
|
||||||
} else
|
break;
|
||||||
snprintf(hour_time,10,"%02d:%02d", hour, min);
|
case 2:
|
||||||
|
snprintf(hour_time,10,"%02d:%02d", hour, min);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (hour > 12) {
|
||||||
|
strcpy(am_pm, "PM");
|
||||||
|
hour -= 12;
|
||||||
|
}
|
||||||
|
snprintf(hour_time,10,"%02d:%02d %s", hour, min, am_pm);
|
||||||
|
}
|
||||||
|
|
||||||
const char *saveTitle = param.GetFileInfo(currentSelectedSave).saveTitle;
|
const char *saveTitle = param.GetFileInfo(currentSelectedSave).saveTitle;
|
||||||
int day = param.GetFileInfo(currentSelectedSave).modif_time.tm_mday;
|
int day = param.GetFileInfo(currentSelectedSave).modif_time.tm_mday;
|
||||||
|
@ -423,14 +444,14 @@ void PSPSaveDialog::DisplaySaveDataInfo2()
|
||||||
int year = param.GetFileInfo(currentSelectedSave).modif_time.tm_year + 1900;
|
int year = param.GetFileInfo(currentSelectedSave).modif_time.tm_year + 1900;
|
||||||
s64 sizeK = param.GetFileInfo(currentSelectedSave).size / 1024;
|
s64 sizeK = param.GetFileInfo(currentSelectedSave).size / 1024;
|
||||||
switch (g_Config.iDateFormat) {
|
switch (g_Config.iDateFormat) {
|
||||||
case PSP_SYSTEMPARAM_DATE_FORMAT_DDMMYYYY:
|
case 1:
|
||||||
snprintf(date, 256, "%02d/%02d/%d", day, month, year);
|
snprintf(date, 256, "%d/%02d/%02d", year, month, day);
|
||||||
break;
|
case 2:
|
||||||
case PSP_SYSTEMPARAM_DATE_FORMAT_MMDDYYYY:
|
|
||||||
snprintf(date, 256, "%02d/%02d/%d", month, day, year);
|
snprintf(date, 256, "%02d/%02d/%d", month, day, year);
|
||||||
break;
|
break;
|
||||||
case PSP_SYSTEMPARAM_DATE_FORMAT_YYYYMMDD:
|
case 3:
|
||||||
// fall through
|
snprintf(date, 256, "%02d/%02d/%d", day, month, year);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
snprintf(date, 256, "%d/%02d/%02d", year, month, day);
|
snprintf(date, 256, "%d/%02d/%02d", year, month, day);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,19 +34,18 @@ BlockDevice *constructBlockDevice(const char *filename) {
|
||||||
return 0;
|
return 0;
|
||||||
char buffer[4];
|
char buffer[4];
|
||||||
auto size = fread(buffer, 1, 4, f); //size_t
|
auto size = fread(buffer, 1, 4, f); //size_t
|
||||||
fclose(f);
|
fseek(f, 0, SEEK_SET);
|
||||||
if (!memcmp(buffer, "CISO", 4) && size == 4)
|
if (!memcmp(buffer, "CISO", 4) && size == 4)
|
||||||
return new CISOFileBlockDevice(filename);
|
return new CISOFileBlockDevice(f);
|
||||||
else if (!memcmp(buffer, "\x00PBP", 4) && size == 4)
|
else if (!memcmp(buffer, "\x00PBP", 4) && size == 4)
|
||||||
return new NPDRMDemoBlockDevice(filename);
|
return new NPDRMDemoBlockDevice(f);
|
||||||
else
|
else
|
||||||
return new FileBlockDevice(filename);
|
return new FileBlockDevice(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileBlockDevice::FileBlockDevice(std::string _filename)
|
FileBlockDevice::FileBlockDevice(FILE *file)
|
||||||
: filename(_filename)
|
: f(file)
|
||||||
{
|
{
|
||||||
f = fopen(_filename.c_str(), "rb");
|
|
||||||
fseek(f,0,SEEK_END);
|
fseek(f,0,SEEK_END);
|
||||||
filesize = ftell(f);
|
filesize = ftell(f);
|
||||||
fseek(f,0,SEEK_SET);
|
fseek(f,0,SEEK_SET);
|
||||||
|
@ -94,12 +93,12 @@ typedef struct ciso_header
|
||||||
|
|
||||||
// TODO: Need much better error handling.
|
// TODO: Need much better error handling.
|
||||||
|
|
||||||
CISOFileBlockDevice::CISOFileBlockDevice(std::string _filename)
|
CISOFileBlockDevice::CISOFileBlockDevice(FILE *file)
|
||||||
: filename(_filename)
|
: f(file)
|
||||||
{
|
{
|
||||||
// CISO format is EXTREMELY crappy and incomplete. All tools make broken CISO.
|
// CISO format is EXTREMELY crappy and incomplete. All tools make broken CISO.
|
||||||
|
|
||||||
f = fopen(_filename.c_str(), "rb");
|
f = file;
|
||||||
CISO_H hdr;
|
CISO_H hdr;
|
||||||
size_t readSize = fread(&hdr, sizeof(CISO_H), 1, f);
|
size_t readSize = fread(&hdr, sizeof(CISO_H), 1, f);
|
||||||
if (readSize != 1 || memcmp(hdr.magic, "CISO", 4) != 0)
|
if (readSize != 1 || memcmp(hdr.magic, "CISO", 4) != 0)
|
||||||
|
@ -206,8 +205,8 @@ bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NPDRMDemoBlockDevice::NPDRMDemoBlockDevice(std::string _filename)
|
NPDRMDemoBlockDevice::NPDRMDemoBlockDevice(FILE *file)
|
||||||
: filename_(_filename)
|
: f(file)
|
||||||
{
|
{
|
||||||
MAC_KEY mkey;
|
MAC_KEY mkey;
|
||||||
CIPHER_KEY ckey;
|
CIPHER_KEY ckey;
|
||||||
|
@ -215,8 +214,6 @@ NPDRMDemoBlockDevice::NPDRMDemoBlockDevice(std::string _filename)
|
||||||
u32 tableOffset, tableSize;
|
u32 tableOffset, tableSize;
|
||||||
u32 lbaStart, lbaEnd;
|
u32 lbaStart, lbaEnd;
|
||||||
|
|
||||||
f = fopen(_filename.c_str(), "rb");
|
|
||||||
|
|
||||||
fseek(f, 0x24, SEEK_SET);
|
fseek(f, 0x24, SEEK_SET);
|
||||||
fread(&psarOffset, 1, 4, f);
|
fread(&psarOffset, 1, 4, f);
|
||||||
fseek(f, psarOffset, SEEK_SET);
|
fseek(f, psarOffset, SEEK_SET);
|
||||||
|
|
|
@ -39,13 +39,12 @@ public:
|
||||||
class CISOFileBlockDevice : public BlockDevice
|
class CISOFileBlockDevice : public BlockDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CISOFileBlockDevice(std::string _filename);
|
CISOFileBlockDevice(FILE *file);
|
||||||
~CISOFileBlockDevice();
|
~CISOFileBlockDevice();
|
||||||
bool ReadBlock(int blockNumber, u8 *outPtr);
|
bool ReadBlock(int blockNumber, u8 *outPtr);
|
||||||
u32 GetNumBlocks() { return numBlocks;}
|
u32 GetNumBlocks() { return numBlocks;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string filename;
|
|
||||||
FILE *f;
|
FILE *f;
|
||||||
u32 *index;
|
u32 *index;
|
||||||
int indexShift;
|
int indexShift;
|
||||||
|
@ -57,13 +56,12 @@ private:
|
||||||
class FileBlockDevice : public BlockDevice
|
class FileBlockDevice : public BlockDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FileBlockDevice(std::string _filename);
|
FileBlockDevice(FILE *file);
|
||||||
~FileBlockDevice();
|
~FileBlockDevice();
|
||||||
bool ReadBlock(int blockNumber, u8 *outPtr);
|
bool ReadBlock(int blockNumber, u8 *outPtr);
|
||||||
u32 GetNumBlocks() {return (u32)(filesize / GetBlockSize());}
|
u32 GetNumBlocks() {return (u32)(filesize / GetBlockSize());}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string filename;
|
|
||||||
FILE *f;
|
FILE *f;
|
||||||
size_t filesize;
|
size_t filesize;
|
||||||
};
|
};
|
||||||
|
@ -82,14 +80,13 @@ struct table_info {
|
||||||
class NPDRMDemoBlockDevice : public BlockDevice
|
class NPDRMDemoBlockDevice : public BlockDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NPDRMDemoBlockDevice(std::string _filename);
|
NPDRMDemoBlockDevice(FILE *file);
|
||||||
~NPDRMDemoBlockDevice();
|
~NPDRMDemoBlockDevice();
|
||||||
|
|
||||||
bool ReadBlock(int blockNumber, u8 *outPtr);
|
bool ReadBlock(int blockNumber, u8 *outPtr);
|
||||||
u32 GetNumBlocks() {return (u32)lbaSize;}
|
u32 GetNumBlocks() {return (u32)lbaSize;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string filename_;
|
|
||||||
FILE *f;
|
FILE *f;
|
||||||
u32 lbaSize;
|
u32 lbaSize;
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,8 @@ const int audioHostIntervalUs = (int)(1000000ULL * hostAttemptBlockSize / hwSamp
|
||||||
const int chanQueueMaxSizeFactor = 2;
|
const int chanQueueMaxSizeFactor = 2;
|
||||||
const int chanQueueMinSizeFactor = 1;
|
const int chanQueueMinSizeFactor = 1;
|
||||||
|
|
||||||
|
// TODO: Need to replace this with something lockless. Mutexes in the audio pipeline
|
||||||
|
// is bad mojo.
|
||||||
FixedSizeQueue<s16, hostAttemptBlockSize * 16> outAudioQueue;
|
FixedSizeQueue<s16, hostAttemptBlockSize * 16> outAudioQueue;
|
||||||
|
|
||||||
static inline s16 clamp_s16(int i) {
|
static inline s16 clamp_s16(int i) {
|
||||||
|
@ -70,6 +72,8 @@ void hleAudioUpdate(u64 userdata, int cyclesLate)
|
||||||
|
|
||||||
void hleHostAudioUpdate(u64 userdata, int cyclesLate)
|
void hleHostAudioUpdate(u64 userdata, int cyclesLate)
|
||||||
{
|
{
|
||||||
|
// Not all hosts need this call to poke their audio system once in a while, but those that don't
|
||||||
|
// can just ignore it.
|
||||||
host->UpdateSound();
|
host->UpdateSound();
|
||||||
CoreTiming::ScheduleEvent(usToCycles(audioHostIntervalUs) - cyclesLate, eventHostAudioUpdate, 0);
|
CoreTiming::ScheduleEvent(usToCycles(audioHostIntervalUs) - cyclesLate, eventHostAudioUpdate, 0);
|
||||||
}
|
}
|
||||||
|
@ -166,10 +170,33 @@ u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking)
|
||||||
// Walking a pointer for speed. But let's make sure we wouldn't trip on an invalid ptr.
|
// Walking a pointer for speed. But let's make sure we wouldn't trip on an invalid ptr.
|
||||||
if (Memory::IsValidAddress(chan.sampleAddress + (totalSamples - 1) * sizeof(s16)))
|
if (Memory::IsValidAddress(chan.sampleAddress + (totalSamples - 1) * sizeof(s16)))
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
for (u32 i = 0; i < totalSamples; i += 2) {
|
for (u32 i = 0; i < totalSamples; i += 2) {
|
||||||
chan.sampleQueue.push(adjustvolume(*sampleData++, chan.leftVolume));
|
chan.sampleQueue.push(adjustvolume(*sampleData++, chan.leftVolume));
|
||||||
chan.sampleQueue.push(adjustvolume(*sampleData++, chan.rightVolume));
|
chan.sampleQueue.push(adjustvolume(*sampleData++, chan.rightVolume));
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
s16 *buf1 = 0, *buf2 = 0;
|
||||||
|
size_t sz1, sz2;
|
||||||
|
chan.sampleQueue.pushPointers(totalSamples, &buf1, &sz1, &buf2, &sz2);
|
||||||
|
int leftVol = chan.leftVolume;
|
||||||
|
int rightVol = chan.rightVolume;
|
||||||
|
|
||||||
|
// TODO: SSE/NEON implementations
|
||||||
|
for (u32 i = 0; i < sz1; i += 2)
|
||||||
|
{
|
||||||
|
buf1[i] = adjustvolume(sampleData[i], leftVol);
|
||||||
|
buf1[i + 1] = adjustvolume(sampleData[i + 1], rightVol);
|
||||||
|
}
|
||||||
|
if (buf2) {
|
||||||
|
sampleData += sz1;
|
||||||
|
for (u32 i = 0; i < sz2; i += 2)
|
||||||
|
{
|
||||||
|
buf2[i] = adjustvolume(sampleData[i], leftVol);
|
||||||
|
buf2[i + 1] = adjustvolume(sampleData[i + 1], rightVol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -227,56 +254,74 @@ void __AudioWakeThreads(AudioChannel &chan, int result)
|
||||||
__AudioWakeThreads(chan, result, 0x7FFFFFFF);
|
__AudioWakeThreads(chan, result, 0x7FFFFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __AudioSetOutputFrequency(int freq)
|
||||||
|
{
|
||||||
|
WARN_LOG(HLE, "Switching audio frequency to %i", freq);
|
||||||
|
mixFrequency = freq;
|
||||||
|
}
|
||||||
|
|
||||||
// Mix samples from the various audio channels into a single sample queue.
|
// Mix samples from the various audio channels into a single sample queue.
|
||||||
// This single sample queue is where __AudioMix should read from. If the sample queue is full, we should
|
// This single sample queue is where __AudioMix should read from. If the sample queue is full, we should
|
||||||
// just sleep the main emulator thread a little.
|
// just sleep the main emulator thread a little.
|
||||||
void __AudioUpdate()
|
void __AudioUpdate() {
|
||||||
{
|
|
||||||
// Audio throttle doesn't really work on the PSP since the mixing intervals are so closely tied
|
// Audio throttle doesn't really work on the PSP since the mixing intervals are so closely tied
|
||||||
// to the CPU. Much better to throttle the frame rate on frame display and just throw away audio
|
// to the CPU. Much better to throttle the frame rate on frame display and just throw away audio
|
||||||
// if the buffer somehow gets full.
|
// if the buffer somehow gets full.
|
||||||
|
|
||||||
s32 mixBuffer[hwBlockSize * 2];
|
s32 mixBuffer[hwBlockSize * 2];
|
||||||
memset(mixBuffer, 0, sizeof(mixBuffer));
|
bool firstChannel = true;
|
||||||
|
|
||||||
for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++)
|
for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++) {
|
||||||
{
|
|
||||||
if (!chans[i].reserved)
|
if (!chans[i].reserved)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
__AudioWakeThreads(chans[i], 0, hwBlockSize);
|
__AudioWakeThreads(chans[i], 0, hwBlockSize);
|
||||||
|
|
||||||
if (!chans[i].sampleQueue.size()) {
|
if (!chans[i].sampleQueue.size()) {
|
||||||
// ERROR_LOG(HLE, "No queued samples, skipping channel %i", i);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int s = 0; s < hwBlockSize; s++)
|
if (hwBlockSize * 2 > chans[i].sampleQueue.size()) {
|
||||||
{
|
ERROR_LOG(HLE, "Channel %i buffer underrun at %i of %i", i, (int)chans[i].sampleQueue.size() / 2, hwBlockSize);
|
||||||
if (chans[i].sampleQueue.size() >= 2)
|
}
|
||||||
{
|
|
||||||
s16 sampleL = chans[i].sampleQueue.pop_front();
|
const s16 *buf1 = 0, *buf2 = 0;
|
||||||
s16 sampleR = chans[i].sampleQueue.pop_front();
|
size_t sz1, sz2;
|
||||||
mixBuffer[s * 2 + 0] += sampleL;
|
|
||||||
mixBuffer[s * 2 + 1] += sampleR;
|
chans[i].sampleQueue.popPointers(hwBlockSize * 2, &buf1, &sz1, &buf2, &sz2);
|
||||||
}
|
|
||||||
else
|
if (firstChannel) {
|
||||||
{
|
for (int s = 0; s < sz1; s++)
|
||||||
ERROR_LOG(HLE, "Channel %i buffer underrun at %i of %i", i, s, hwBlockSize);
|
mixBuffer[s] = buf1[s];
|
||||||
break;
|
if (buf2) {
|
||||||
|
for (int s = 0; s < sz2; s++)
|
||||||
|
mixBuffer[s + sz1] = buf2[s];
|
||||||
|
}
|
||||||
|
firstChannel = false;
|
||||||
|
} else {
|
||||||
|
for (int s = 0; s < sz1; s++)
|
||||||
|
mixBuffer[s] += buf1[s];
|
||||||
|
if (buf2) {
|
||||||
|
for (int s = 0; s < sz2; s++)
|
||||||
|
mixBuffer[s + sz1] += buf2[s];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (firstChannel) {
|
||||||
|
memset(mixBuffer, 0, sizeof(mixBuffer));
|
||||||
|
}
|
||||||
|
|
||||||
if (g_Config.bEnableSound) {
|
if (g_Config.bEnableSound) {
|
||||||
lock_guard guard(section);
|
lock_guard guard(section);
|
||||||
if (outAudioQueue.room() >= hwBlockSize * 2) {
|
if (outAudioQueue.room() >= hwBlockSize * 2) {
|
||||||
// Push the mixed samples onto the output audio queue.
|
s16 *buf1 = 0, *buf2 = 0;
|
||||||
for (int i = 0; i < hwBlockSize; i++) {
|
size_t sz1, sz2;
|
||||||
s16 sampleL = clamp_s16(mixBuffer[i * 2 + 0]);
|
outAudioQueue.pushPointers(hwBlockSize * 2, &buf1, &sz1, &buf2, &sz2);
|
||||||
s16 sampleR = clamp_s16(mixBuffer[i * 2 + 1]);
|
for (int s = 0; s < sz1; s++)
|
||||||
|
buf1[s] = clamp_s16(mixBuffer[s]);
|
||||||
outAudioQueue.push((s16)sampleL);
|
if (buf2) {
|
||||||
outAudioQueue.push((s16)sampleR);
|
for (int s = 0; s < sz2; s++)
|
||||||
|
buf2[s] = clamp_s16(mixBuffer[s + sz1]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// This happens quite a lot. There's still something slightly off
|
// This happens quite a lot. There's still something slightly off
|
||||||
|
@ -284,13 +329,6 @@ void __AudioUpdate()
|
||||||
DEBUG_LOG(HLE, "Audio outbuffer overrun! room = %i / %i", outAudioQueue.room(), (u32)outAudioQueue.capacity());
|
DEBUG_LOG(HLE, "Audio outbuffer overrun! room = %i / %i", outAudioQueue.room(), (u32)outAudioQueue.capacity());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void __AudioSetOutputFrequency(int freq)
|
|
||||||
{
|
|
||||||
WARN_LOG(HLE, "Switching audio frequency to %i", freq);
|
|
||||||
mixFrequency = freq;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// numFrames is number of stereo frames.
|
// numFrames is number of stereo frames.
|
||||||
|
@ -298,28 +336,28 @@ void __AudioSetOutputFrequency(int freq)
|
||||||
int __AudioMix(short *outstereo, int numFrames)
|
int __AudioMix(short *outstereo, int numFrames)
|
||||||
{
|
{
|
||||||
// TODO: if mixFrequency != the actual output frequency, resample!
|
// TODO: if mixFrequency != the actual output frequency, resample!
|
||||||
lock_guard guard(section);
|
|
||||||
int underrun = -1;
|
int underrun = -1;
|
||||||
s16 sampleL = 0;
|
s16 sampleL = 0;
|
||||||
s16 sampleR = 0;
|
s16 sampleR = 0;
|
||||||
bool anythingToPlay = false;
|
|
||||||
for (int i = 0; i < numFrames; i++) {
|
const s16 *buf1 = 0, *buf2 = 0;
|
||||||
if (outAudioQueue.size() >= 2) {
|
size_t sz1, sz2;
|
||||||
sampleL = outAudioQueue.pop_front();
|
{
|
||||||
sampleR = outAudioQueue.pop_front();
|
lock_guard guard(section);
|
||||||
outstereo[i * 2 + 0] = sampleL;
|
outAudioQueue.popPointers(numFrames * 2, &buf1, &sz1, &buf2, &sz2);
|
||||||
outstereo[i * 2 + 1] = sampleR;
|
memcpy(outstereo, buf1, sz1 * sizeof(s16));
|
||||||
anythingToPlay = true;
|
if (buf2) {
|
||||||
} else {
|
memcpy(outstereo + sz1, buf2, sz2 * sizeof(s16));
|
||||||
if (underrun == -1) underrun = i;
|
|
||||||
outstereo[i * 2 + 0] = sampleL; // repeat last sample, can reduce clicking
|
|
||||||
outstereo[i * 2 + 1] = sampleR; // repeat last sample, can reduce clicking
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (anythingToPlay && underrun >= 0) {
|
|
||||||
|
int remains = (int)(numFrames * 2 - sz1 - sz2);
|
||||||
|
if (remains > 0)
|
||||||
|
memset(outstereo + numFrames * 2 - remains, 0, remains);
|
||||||
|
|
||||||
|
if (sz1 + sz2 < numFrames) {
|
||||||
|
underrun = (int)(sz1 + sz2) / 2;
|
||||||
DEBUG_LOG(HLE, "Audio out buffer UNDERRUN at %i of %i", underrun, numFrames);
|
DEBUG_LOG(HLE, "Audio out buffer UNDERRUN at %i of %i", underrun, numFrames);
|
||||||
} else {
|
|
||||||
// DEBUG_LOG(HLE, "No underrun, mixed %i samples fine", numFrames);
|
|
||||||
}
|
}
|
||||||
return underrun >= 0 ? underrun : numFrames;
|
return underrun >= 0 ? underrun : numFrames;
|
||||||
}
|
}
|
||||||
|
|
|
@ -339,6 +339,7 @@ int createAtrac(Atrac *atrac, int codecType) {
|
||||||
for (int i = 0; i < (int)ARRAY_SIZE(atracIDs); ++i) {
|
for (int i = 0; i < (int)ARRAY_SIZE(atracIDs); ++i) {
|
||||||
if (atracIDTypes[i] == codecType && atracIDs[i] == 0) {
|
if (atracIDTypes[i] == codecType && atracIDs[i] == 0) {
|
||||||
atracIDs[i] = atrac;
|
atracIDs[i] = atrac;
|
||||||
|
atrac->atracID = i;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -483,7 +484,7 @@ void Atrac::Analyze()
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 sceAtracGetAtracID(int codecType) {
|
u32 sceAtracGetAtracID(int codecType) {
|
||||||
if (codecType != PSP_MODE_AT_3 && codecType > PSP_MODE_AT_3_PLUS) {
|
if (codecType != PSP_MODE_AT_3 && codecType != PSP_MODE_AT_3_PLUS) {
|
||||||
ERROR_LOG_REPORT(HLE, "sceAtracGetAtracID(%i): invalid codecType", codecType);
|
ERROR_LOG_REPORT(HLE, "sceAtracGetAtracID(%i): invalid codecType", codecType);
|
||||||
return ATRAC_ERROR_INVALID_CODECTYPE;
|
return ATRAC_ERROR_INVALID_CODECTYPE;
|
||||||
}
|
}
|
||||||
|
@ -527,7 +528,7 @@ u32 _AtracAddStreamData(int atracID, u8 *buf, u32 bytesToAdd) {
|
||||||
// because that function would tell games how to add the left stream data.
|
// because that function would tell games how to add the left stream data.
|
||||||
u32 sceAtracAddStreamData(int atracID, u32 bytesToAdd)
|
u32 sceAtracAddStreamData(int atracID, u32 bytesToAdd)
|
||||||
{
|
{
|
||||||
INFO_LOG(HLE, "sceAtracAddStreamData(%i, %08x)", atracID, bytesToAdd);
|
DEBUG_LOG(HLE, "sceAtracAddStreamData(%i, %08x)", atracID, bytesToAdd);
|
||||||
Atrac *atrac = getAtrac(atracID);
|
Atrac *atrac = getAtrac(atracID);
|
||||||
if (!atrac) {
|
if (!atrac) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -579,7 +580,11 @@ u32 _AtracDecodeData(int atracID, u8* outbuf, u32 *SamplesNum, u32* finish, int
|
||||||
if (avret < 0) {
|
if (avret < 0) {
|
||||||
ERROR_LOG(HLE, "avcodec_decode_audio4: Error decoding audio %d", avret);
|
ERROR_LOG(HLE, "avcodec_decode_audio4: Error decoding audio %d", avret);
|
||||||
av_free_packet(&packet);
|
av_free_packet(&packet);
|
||||||
break;
|
// Avoid getting stuck in a loop (Virtua Tennis)
|
||||||
|
*SamplesNum = 0;
|
||||||
|
*finish = 1;
|
||||||
|
*remains = 0;
|
||||||
|
return ATRAC_ERROR_ALL_DATA_DECODED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (got_frame) {
|
if (got_frame) {
|
||||||
|
|
|
@ -27,321 +27,217 @@ extern "C"
|
||||||
u8 dataBuf[2048+20];
|
u8 dataBuf[2048+20];
|
||||||
u8* dataBuf2 = dataBuf + 20;
|
u8* dataBuf2 = dataBuf + 20;
|
||||||
|
|
||||||
static const u8 hash198C[16] = {0xFA, 0xAA, 0x50, 0xEC, 0x2F, 0xDE, 0x54, 0x93, 0xAD, 0x14, 0xB2, 0xCE, 0xA5, 0x30, 0x05, 0xDF };
|
static const u8 hash198C[16] = {0xFA, 0xAA, 0x50, 0xEC, 0x2F, 0xDE, 0x54, 0x93, 0xAD, 0x14, 0xB2, 0xCE, 0xA5, 0x30, 0x05, 0xDF};
|
||||||
static const u8 hash19BC[16] = {0xCB, 0x15, 0xF4, 0x07, 0xF9, 0x6A, 0x52, 0x3C, 0x04, 0xB9, 0xB2, 0xEE, 0x5C, 0x53, 0xFA, 0x86 };
|
static const u8 hash19BC[16] = {0xCB, 0x15, 0xF4, 0x07, 0xF9, 0x6A, 0x52, 0x3C, 0x04, 0xB9, 0xB2, 0xEE, 0x5C, 0x53, 0xFA, 0x86};
|
||||||
|
|
||||||
static const u8 key000019CC[16] = {0x70, 0x44, 0xA3, 0xAE, 0xEF, 0x5D, 0xA5, 0xF2, 0x85, 0x7F, 0xF2, 0xD6, 0x94, 0xF5, 0x36, 0x3B};
|
static const u8 key19CC[16] = {0x70, 0x44, 0xA3, 0xAE, 0xEF, 0x5D, 0xA5, 0xF2, 0x85, 0x7F, 0xF2, 0xD6, 0x94, 0xF5, 0x36, 0x3B};
|
||||||
static const u8 key000019DC[16] = {0xEC, 0x6D, 0x29, 0x59, 0x26, 0x35, 0xA5, 0x7F, 0x97, 0x2A, 0x0D, 0xBC, 0xA3, 0x26, 0x33, 0x00};
|
static const u8 key19DC[16] = {0xEC, 0x6D, 0x29, 0x59, 0x26, 0x35, 0xA5, 0x7F, 0x97, 0x2A, 0x0D, 0xBC, 0xA3, 0x26, 0x33, 0x00};
|
||||||
static const u8 key0000199C[16] = {0x36, 0xA5, 0x3E, 0xAC, 0xC5, 0x26, 0x9E, 0xA3, 0x83, 0xD9, 0xEC, 0x25, 0x6C, 0x48, 0x48, 0x72};
|
static const u8 key199C[16] = {0x36, 0xA5, 0x3E, 0xAC, 0xC5, 0x26, 0x9E, 0xA3, 0x83, 0xD9, 0xEC, 0x25, 0x6C, 0x48, 0x48, 0x72};
|
||||||
static const u8 key000019AC[16] = {0xD8, 0xC0, 0xB0, 0xF3, 0x3E, 0x6B, 0x76, 0x85, 0xFD, 0xFB, 0x4D, 0x7D, 0x45, 0x1E, 0x92, 0x03};
|
static const u8 key19AC[16] = {0xD8, 0xC0, 0xB0, 0xF3, 0x3E, 0x6B, 0x76, 0x85, 0xFD, 0xFB, 0x4D, 0x7D, 0x45, 0x1E, 0x92, 0x03};
|
||||||
|
|
||||||
int sub_000014BC(u8* data, int length)
|
void *memxor(void * dest, const void * src, size_t n)
|
||||||
{
|
{
|
||||||
*(s32*)(data + 0) = 5;
|
char const *s = (char const*)src;
|
||||||
*(s32*)(data + 12) = 256;
|
char *d = (char*)dest;
|
||||||
*(s32*)(data + 4) = 0;
|
|
||||||
*(s32*)(data + 8) = 0;
|
for (; n > 0; n--)
|
||||||
*(s32*)(data + 16) = length;
|
*d++ ^= *s++;
|
||||||
int res = sceUtilsBufferCopyWithRange(data, length + 20, data, length + 20, 8);
|
|
||||||
if (res == 0)
|
return dest;
|
||||||
return 0;
|
|
||||||
return -258;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sub_00001418(u8* data, int length, int val2)
|
// The reason for the values from *FromMode calculations are not known.
|
||||||
|
int numFromMode(int mode)
|
||||||
{
|
{
|
||||||
*(s32*)(data + 12) = val2;
|
|
||||||
*(s32*)(data + 0) = 5;
|
|
||||||
*(s32*)(data + 4) = 0;
|
|
||||||
*(s32*)(data + 8) = 0;
|
|
||||||
*(s32*)(data + 16) = length;
|
|
||||||
int res = sceUtilsBufferCopyWithRange(data, length + 20, data, length + 20, 7);
|
|
||||||
if (res == 0)
|
|
||||||
return 0;
|
|
||||||
return -257;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int sub_000015B0(u8* data, int alignedLen, u8* buf, int val)
|
|
||||||
{
|
|
||||||
u8 sp0[16];
|
|
||||||
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
sp0[i] = data[alignedLen+i+4];
|
|
||||||
}
|
|
||||||
int res = sub_00001418(data, alignedLen, val);
|
|
||||||
if (res != 0)
|
|
||||||
{
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
data[i] = data[i] ^ buf[i];
|
|
||||||
}
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
buf[i] = sp0[i];
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sub_00000000(u8* data_out, u8* data, int alignedLen, u8* data2, int& data3, int mode)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
data_out[20+i] = data2[i];
|
|
||||||
}
|
|
||||||
int valS4 = 100;
|
|
||||||
int res;
|
|
||||||
if (mode == 6)
|
|
||||||
{
|
|
||||||
valS4 = 100;
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
data_out[20+i] = data_out[20+i] ^ key000019DC[i];
|
|
||||||
}
|
|
||||||
res = sub_000014BC(data_out, 16);
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
data_out[i] = data_out[i] ^ key000019CC[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (mode == 4)
|
|
||||||
{
|
|
||||||
valS4 = 87;
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
data_out[20+i] = data_out[20+i] ^ key000019AC[i];
|
|
||||||
}
|
|
||||||
res = sub_000014BC(data_out, 16);
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
data_out[i] = data_out[i] ^ key0000199C[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (mode == 2)
|
|
||||||
{
|
|
||||||
res = sub_000014BC(data_out, 16);
|
|
||||||
valS4 = 83;
|
|
||||||
}
|
|
||||||
else if (mode == 1)
|
|
||||||
{
|
|
||||||
res = sub_00001418(data_out, 16, 4);
|
|
||||||
valS4 = 83;
|
|
||||||
}
|
|
||||||
else if (mode == 3)
|
|
||||||
{
|
|
||||||
valS4 = 87;
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
data_out[i+20] = data_out[i+20] ^ key000019AC[i];
|
|
||||||
}
|
|
||||||
res = sub_00001418(data_out, 16, 14);
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
data_out[i] = data_out[i] ^ key0000199C[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
valS4 = 100;
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
data_out[i + 20] = data_out[i + 20] ^ key000019DC[i];
|
|
||||||
}
|
|
||||||
res = sub_00001418(data_out, 16, 18);
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
data_out[i] = data_out[i] ^ key000019CC[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 sp16[16];
|
|
||||||
if (res != 0)
|
|
||||||
{
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
sp16[i] = data_out[i];
|
|
||||||
}
|
|
||||||
u8 sp0[16];
|
|
||||||
if (data3 == 1)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
sp0[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(int i = 0; i < 12; i++)
|
|
||||||
{
|
|
||||||
sp0[i] = sp16[i];
|
|
||||||
}
|
|
||||||
sp0[12] = (data3-1) & 0xFF ;
|
|
||||||
sp0[13] = ((data3-1) >> 8) & 0xFF;
|
|
||||||
sp0[14] = ((data3-1) >> 16) & 0xFF;
|
|
||||||
sp0[15] = ((data3-1) >> 24) & 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((u32)20 < (u32)alignedLen + 20)
|
|
||||||
{
|
|
||||||
for(int i = 20; i < alignedLen + 20; i += 16)
|
|
||||||
{
|
|
||||||
for(int j = 0; j < 12; j++)
|
|
||||||
{
|
|
||||||
data_out[i+j] = sp16[j];
|
|
||||||
}
|
|
||||||
data_out[12+i] = data3;
|
|
||||||
data_out[13+i] = (data3 >> 8) & 0xFF;
|
|
||||||
data_out[14+i] = (data3 >> 16) & 0xFF;
|
|
||||||
data_out[15+i] = (data3 >> 24) & 0xFF;
|
|
||||||
data3++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res = sub_000015B0(data_out, alignedLen, sp0, valS4);
|
|
||||||
if (res != 0)
|
|
||||||
{
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
if (res >= alignedLen)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
for(int i = 0; i < alignedLen; i++)
|
|
||||||
{
|
|
||||||
data[i] = data[i] ^ data_out[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sub_000013C8(u8* data, int size, int num)
|
|
||||||
{
|
|
||||||
*(int*)(data+0) = 4;
|
|
||||||
*(int*)(data+4) = 0;
|
|
||||||
*(int*)(data+8) = 0;
|
|
||||||
*(int*)(data+12) = num;
|
|
||||||
*(int*)(data+16) = size;
|
|
||||||
size = size + 20;
|
|
||||||
|
|
||||||
int res = sceUtilsBufferCopyWithRange(data,size,data,size,4);
|
|
||||||
if(res != 0)
|
|
||||||
{
|
|
||||||
return -257;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sub_00001468(u8* data, int size)
|
|
||||||
{
|
|
||||||
*(int*)(data+0) = 4;
|
|
||||||
*(int*)(data+12) = 256;
|
|
||||||
*(int*)(data+4) = 0;
|
|
||||||
*(int*)(data+8) = 0;
|
|
||||||
*(int*)(data+16) = size;
|
|
||||||
size = size + 20;
|
|
||||||
|
|
||||||
int res = sceUtilsBufferCopyWithRange(data,size,data,size,5);
|
|
||||||
if(res != 0)
|
|
||||||
{
|
|
||||||
return -258;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sub_00001510(u8* data, int size, u8* result , int num)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
int v1 = data[i+20];
|
|
||||||
v1 = v1 ^ result[i];
|
|
||||||
data[i+20] = v1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int res = sub_000013C8(data, size, num);
|
|
||||||
if(res != 0)
|
|
||||||
{
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
result[i] = data[size + i + 4];
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sub_000017A8(u8* data)
|
|
||||||
{
|
|
||||||
int res = sceUtilsBufferCopyWithRange(data, 20, 0, 0, 14);
|
|
||||||
if (res == 0)
|
|
||||||
return 0;
|
|
||||||
return -261;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sceSdGetLastIndex(u32 addressCtx,u32 addressHash, u32 addressKey)
|
|
||||||
{
|
|
||||||
pspChnnlsvContext1 ctx;
|
|
||||||
Memory::ReadStruct(addressCtx,&ctx);
|
|
||||||
u8* in_hash;
|
|
||||||
u8* in_key;
|
|
||||||
in_hash = Memory::GetPointer(addressHash);
|
|
||||||
in_key = Memory::GetPointer(addressKey);
|
|
||||||
|
|
||||||
int res = sceSdGetLastIndex_(ctx, in_hash, in_key);
|
|
||||||
|
|
||||||
Memory::WriteStruct(addressCtx,&ctx);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
int sceSdGetLastIndex_(pspChnnlsvContext1& ctx, u8* in_hash, u8* in_key)
|
|
||||||
{
|
|
||||||
if(ctx.keyLength >= 17)
|
|
||||||
{
|
|
||||||
return -1026;
|
|
||||||
}
|
|
||||||
int num = 0;
|
int num = 0;
|
||||||
switch(ctx.mode)
|
switch(mode)
|
||||||
{
|
{
|
||||||
case 6:
|
case 1:
|
||||||
num = 17;
|
num = 3;
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
num = 13;
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
num = 5;
|
num = 5;
|
||||||
break;
|
break;
|
||||||
case 1:
|
|
||||||
num = 3;
|
|
||||||
break;
|
|
||||||
case 3:
|
case 3:
|
||||||
num = 12;
|
num = 12;
|
||||||
break;
|
break;
|
||||||
|
case 4:
|
||||||
|
num = 13;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
num = 17;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
num = 16;
|
num = 16;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
int numFromMode2(int mode)
|
||||||
|
{
|
||||||
|
int num = 18;
|
||||||
|
if (mode == 1)
|
||||||
|
num = 4;
|
||||||
|
else if (mode == 3)
|
||||||
|
num = 14;
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
memset(dataBuf2,0,16);
|
int typeFromMode(int mode)
|
||||||
|
{
|
||||||
|
return (mode == 1 || mode == 2) ? 83 :
|
||||||
|
((mode == 3 || mode == 4) ? 87 : 100);
|
||||||
|
}
|
||||||
|
|
||||||
int res = sub_000013C8(dataBuf,16,num);
|
int kirkSendCmd(u8* data, int length, int num, bool encrypt)
|
||||||
if(res != 0)
|
{
|
||||||
{
|
*(int*)(data+0) = encrypt ? KIRK_MODE_ENCRYPT_CBC : KIRK_MODE_DECRYPT_CBC;
|
||||||
|
*(int*)(data+4) = 0;
|
||||||
|
*(int*)(data+8) = 0;
|
||||||
|
*(int*)(data+12) = num;
|
||||||
|
*(int*)(data+16) = length;
|
||||||
|
|
||||||
|
if (sceUtilsBufferCopyWithRange(data, length + 20, data, length + 20, encrypt ? KIRK_CMD_ENCRYPT_IV_0 : KIRK_CMD_DECRYPT_IV_0))
|
||||||
|
return -257;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int kirkSendFuseCmd(u8* data, int length, bool encrypt)
|
||||||
|
{
|
||||||
|
*(int*)(data+0) = encrypt ? KIRK_MODE_ENCRYPT_CBC : KIRK_MODE_DECRYPT_CBC;
|
||||||
|
*(int*)(data+4) = 0;
|
||||||
|
*(int*)(data+8) = 0;
|
||||||
|
*(int*)(data+12) = 256;
|
||||||
|
*(int*)(data+16) = length;
|
||||||
|
|
||||||
|
// Note: CMD 5 and 8 are not available, will always return -1
|
||||||
|
if (sceUtilsBufferCopyWithRange(data, length + 20, data, length + 20, encrypt ? KIRK_CMD_ENCRYPT_IV_FUSE : KIRK_CMD_DECRYPT_IV_FUSE))
|
||||||
|
return -258;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sub_15B0(u8* data, int alignedLen, u8* buf, int val)
|
||||||
|
{
|
||||||
|
u8 sp0[16];
|
||||||
|
memcpy(sp0, data+alignedLen+4, 16);
|
||||||
|
|
||||||
|
int res = kirkSendCmd(data, alignedLen, val, false);
|
||||||
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
memxor(data, buf, 16);
|
||||||
|
memcpy(buf, sp0, 16);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sub_0000(u8* data_out, u8* data, int alignedLen, u8* data2, int& data3, int mode)
|
||||||
|
{
|
||||||
|
memcpy(data_out+20, data2, 16);
|
||||||
|
// Mode 1:2 is 83, 3:4 is 87, 5:6 is 100
|
||||||
|
int type = typeFromMode(mode);
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (type == 87)
|
||||||
|
memxor(data_out+20, key19AC, 16);
|
||||||
|
else if (type == 100)
|
||||||
|
memxor(data_out+20, key19DC, 16);
|
||||||
|
|
||||||
|
// Odd is Cmd, Even is FuseCmd
|
||||||
|
switch(mode)
|
||||||
|
{
|
||||||
|
case 2: case 4: case 6: res = kirkSendFuseCmd(data_out, 16, false);
|
||||||
|
break;
|
||||||
|
case 1: case 3: default:res = kirkSendCmd(data_out, 16, numFromMode2(mode), false);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 data1[16];
|
if (type == 87)
|
||||||
u8 data2[16];
|
memxor(data_out, key199C, 16);
|
||||||
|
else if (type == 100)
|
||||||
|
memxor(data_out, key19CC, 16);
|
||||||
|
|
||||||
memcpy(data1,dataBuf2,16);
|
if (res)
|
||||||
int tmp1 = 0;
|
return res;
|
||||||
if((s8)data1[0] < 0)
|
|
||||||
tmp1 = 135;
|
u8 sp0[16], sp16[16];
|
||||||
|
memcpy(sp16, data_out, 16);
|
||||||
|
if (data3 == 1)
|
||||||
|
{
|
||||||
|
memset(sp0, 0, 16);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(sp0, sp16, 12);
|
||||||
|
*(u32*)(sp0+12) = data3-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alignedLen > 0)
|
||||||
|
{
|
||||||
|
for(int i = 20; i < alignedLen + 20; i += 16)
|
||||||
|
{
|
||||||
|
memcpy(data_out+i, sp16, 12);
|
||||||
|
*(u32*)(data_out+12+i) = data3;
|
||||||
|
data3++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res = sub_15B0(data_out, alignedLen, sp0, type);
|
||||||
|
if (res)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
if (alignedLen > 0)
|
||||||
|
memxor(data, data_out, alignedLen);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sub_1510(u8* data, int size, u8* result , int num)
|
||||||
|
{
|
||||||
|
memxor(data+20, result, 16);
|
||||||
|
|
||||||
|
int res = kirkSendCmd(data, size, num, true);
|
||||||
|
if(res)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
memcpy(result, data+size+4, 16);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sub_17A8(u8* data)
|
||||||
|
{
|
||||||
|
if (sceUtilsBufferCopyWithRange(data, 20, 0, 0, 14) == 0)
|
||||||
|
return 0;
|
||||||
|
return -261;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sceSdGetLastIndex(u32 addressCtx, u32 addressHash, u32 addressKey)
|
||||||
|
{
|
||||||
|
pspChnnlsvContext1 ctx;
|
||||||
|
Memory::ReadStruct(addressCtx, &ctx);
|
||||||
|
int res = sceSdGetLastIndex_(ctx, Memory::GetPointer(addressHash), Memory::GetPointer(addressKey));
|
||||||
|
Memory::WriteStruct(addressCtx, &ctx);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sceSdGetLastIndex_(pspChnnlsvContext1& ctx, u8* in_hash, u8* in_key)
|
||||||
|
{
|
||||||
|
if(ctx.keyLength >= 17)
|
||||||
|
return -1026;
|
||||||
|
|
||||||
|
int num = numFromMode(ctx.mode);
|
||||||
|
|
||||||
|
memset(dataBuf2, 0, 16);
|
||||||
|
|
||||||
|
int res = kirkSendCmd(dataBuf, 16, num, true);
|
||||||
|
if(res)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
u8 data1[16], data2[16];
|
||||||
|
|
||||||
|
memcpy(data1, dataBuf2, 16);
|
||||||
|
int tmp1 = (data1[0] & 0x80) ? 135 : 0;
|
||||||
|
|
||||||
for(int i = 0; i < 15; i++)
|
for(int i = 0; i < 15; i++)
|
||||||
{
|
{
|
||||||
|
@ -373,72 +269,37 @@ int sceSdGetLastIndex_(pspChnnlsvContext1& ctx, u8* in_hash, u8* in_key)
|
||||||
|
|
||||||
int oldKeyLength = ctx.keyLength;
|
int oldKeyLength = ctx.keyLength;
|
||||||
*(s8*)(ctx.key + ctx.keyLength) = -128;
|
*(s8*)(ctx.key + ctx.keyLength) = -128;
|
||||||
if(oldKeyLength + 1 < 16)
|
int i = oldKeyLength + 1;
|
||||||
{
|
if(i < 16)
|
||||||
for(int i = oldKeyLength + 1; i < 16; i++)
|
memset(ctx.key + i, 0, 16 - i);
|
||||||
{
|
|
||||||
*(s8*)(ctx.key + i) = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < 16; i++)
|
memxor(ctx.key, data1, 16);
|
||||||
{
|
memcpy(dataBuf2, ctx.key, 16);
|
||||||
ctx.key[i] = ctx.key[i] ^ data1[i];
|
memcpy(data2, ctx.result, 16);
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < 16; i++)
|
int ret = sub_1510(dataBuf, 16, data2, num);
|
||||||
{
|
if(ret)
|
||||||
dataBuf2[i] = ctx.key[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
data2[i] = ctx.result[i];
|
|
||||||
}
|
|
||||||
int ret = sub_00001510(dataBuf,16,data2,num);
|
|
||||||
if(ret != 0)
|
|
||||||
{
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
if((u32)(ctx.mode-3) < 2)
|
if(ctx.mode == 3 || ctx.mode == 4)
|
||||||
{
|
memxor(data2, hash198C, 16);
|
||||||
for(int i = 0; i < 16; i++)
|
else if(ctx.mode == 5 || ctx.mode == 6)
|
||||||
{
|
memxor(data2, hash19BC, 16);
|
||||||
data2[i] = data2[i] ^ hash198C[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if((u32)(ctx.mode-5) < 2)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
data2[i] = data2[i] ^ hash19BC[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int cond = ((ctx.mode ^ 0x2) < 1 || (ctx.mode ^ 0x4) < 1 || ctx.mode == 6);
|
int cond = ((ctx.mode ^ 0x2) < 1 || (ctx.mode ^ 0x4) < 1 || ctx.mode == 6);
|
||||||
if(cond != 0)
|
if(cond != 0)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < 16; i++)
|
memcpy(dataBuf2, data2, 16);
|
||||||
{
|
int ret = kirkSendFuseCmd(dataBuf, 16, true);
|
||||||
dataBuf2[i] = data2[i];
|
if(ret)
|
||||||
}
|
|
||||||
int ret = sub_00001468(dataBuf,16);
|
|
||||||
if(ret != 0)
|
|
||||||
{
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
int res = sub_000013C8(dataBuf,16,num);
|
|
||||||
if(res != 0)
|
|
||||||
{
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < 16; i++)
|
int res = kirkSendCmd(dataBuf, 16, num, true);
|
||||||
{
|
if(res)
|
||||||
data2[i] = dataBuf2[i];
|
return res;
|
||||||
}
|
|
||||||
|
memcpy(data2, dataBuf2, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(in_key != 0)
|
if(in_key != 0)
|
||||||
|
@ -448,37 +309,16 @@ int sceSdGetLastIndex_(pspChnnlsvContext1& ctx, u8* in_hash, u8* in_key)
|
||||||
data2[i] = in_key[i] ^ data2[i];
|
data2[i] = in_key[i] ^ data2[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < 16; i++)
|
memcpy(dataBuf2, data2, 16);
|
||||||
{
|
|
||||||
dataBuf2[i] = data2[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
int res = sub_000013C8(dataBuf,16,num);
|
int res = kirkSendCmd(dataBuf, 16, num, true);
|
||||||
if(res != 0)
|
if(res)
|
||||||
{
|
|
||||||
return res;
|
return res;
|
||||||
}
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
data2[i] = dataBuf2[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
in_hash[i] = data2[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < 16; i++)
|
memcpy(data2, dataBuf2, 16);
|
||||||
{
|
|
||||||
ctx.result[i] = 0;
|
|
||||||
}
|
}
|
||||||
|
memcpy(in_hash, data2, 16);
|
||||||
for(int i = 0; i < 16; i++)
|
sceSdSetIndex_(ctx, 0);
|
||||||
{
|
|
||||||
ctx.key[i] = 0;
|
|
||||||
}
|
|
||||||
ctx.keyLength = 0;
|
|
||||||
ctx.mode = 0;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -495,8 +335,8 @@ int sceSdSetIndex(u32 addressCtx, int value)
|
||||||
int sceSdSetIndex_(pspChnnlsvContext1& ctx, int value)
|
int sceSdSetIndex_(pspChnnlsvContext1& ctx, int value)
|
||||||
{
|
{
|
||||||
ctx.mode = value;
|
ctx.mode = value;
|
||||||
memset(ctx.result,0,16);
|
memset(ctx.result, 0, 16);
|
||||||
memset(ctx.key,0,16);
|
memset(ctx.key, 0, 16);
|
||||||
ctx.keyLength = 0;
|
ctx.keyLength = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -505,104 +345,52 @@ int sceSdSetIndex_(pspChnnlsvContext1& ctx, int value)
|
||||||
int sceSdRemoveValue(u32 addressCtx, u32 addressData, int length)
|
int sceSdRemoveValue(u32 addressCtx, u32 addressData, int length)
|
||||||
{
|
{
|
||||||
pspChnnlsvContext1 ctx;
|
pspChnnlsvContext1 ctx;
|
||||||
Memory::ReadStruct(addressCtx,&ctx);
|
Memory::ReadStruct(addressCtx, &ctx);
|
||||||
u8* data;
|
int res = sceSdRemoveValue_(ctx, Memory::GetPointer(addressData), length);
|
||||||
data = Memory::GetPointer(addressData);
|
Memory::WriteStruct(addressCtx, &ctx);
|
||||||
|
|
||||||
int res = sceSdRemoveValue_(ctx, data, length);
|
|
||||||
|
|
||||||
Memory::WriteStruct(addressCtx,&ctx);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sceSdRemoveValue_(pspChnnlsvContext1& ctx, u8* data, int length)
|
int sceSdRemoveValue_(pspChnnlsvContext1& ctx, u8* data, int length)
|
||||||
{
|
{
|
||||||
if(ctx.keyLength >= 17)
|
if(ctx.keyLength >= 17)
|
||||||
{
|
|
||||||
return -1026;
|
return -1026;
|
||||||
}
|
|
||||||
if(ctx.keyLength + length < 17)
|
if(ctx.keyLength + length < 17)
|
||||||
{
|
{
|
||||||
if(length == 0)
|
memcpy(ctx.key+ctx.keyLength, data, length);
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
for(int i = 0; i < length; i++)
|
|
||||||
{
|
|
||||||
ctx.key[ctx.keyLength+i] = data[i];
|
|
||||||
}
|
|
||||||
ctx.keyLength = ctx.keyLength + length;
|
ctx.keyLength = ctx.keyLength + length;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int mode = ctx.mode;
|
int num = numFromMode(ctx.mode);
|
||||||
int num = 0;
|
|
||||||
switch(mode)
|
|
||||||
{
|
|
||||||
case 6:
|
|
||||||
num = 17;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
num = 13;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
num = 5;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
num = 3;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
num = 12;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
num = 16;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(dataBuf2,0,2048);
|
memset(dataBuf2, 0, 2048);
|
||||||
|
memcpy(dataBuf2, ctx.key, ctx.keyLength);
|
||||||
|
|
||||||
if(ctx.keyLength > 0)
|
|
||||||
{
|
|
||||||
memcpy(dataBuf2,ctx.key,ctx.keyLength);
|
|
||||||
}
|
|
||||||
int len = (ctx.keyLength + length) & 0xF;
|
int len = (ctx.keyLength + length) & 0xF;
|
||||||
if(len == 0) len = 16;
|
if(len == 0) len = 16;
|
||||||
|
|
||||||
int oldLength = ctx.keyLength;
|
int newSize = ctx.keyLength;
|
||||||
ctx.keyLength = len;
|
ctx.keyLength = len;
|
||||||
|
|
||||||
int diff = length - len;
|
int diff = length - len;
|
||||||
if(len != 0)
|
memcpy(ctx.key, data+diff, len);
|
||||||
|
for(int i = 0; i < diff; i++)
|
||||||
{
|
{
|
||||||
memcpy(ctx.key,data+diff,len);
|
if(newSize == 2048)
|
||||||
}
|
|
||||||
|
|
||||||
int newSize = oldLength;
|
|
||||||
if(diff != 0)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < diff; i++)
|
|
||||||
{
|
{
|
||||||
if(newSize == 2048)
|
int res = sub_1510(dataBuf, 2048, ctx.result, num);
|
||||||
{
|
if(res)
|
||||||
int res = sub_00001510(dataBuf,2048,ctx.result,num);
|
return res;
|
||||||
if(res != 0)
|
newSize = 0;
|
||||||
{
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
newSize = 0;
|
|
||||||
}
|
|
||||||
dataBuf2[newSize] = data[i];
|
|
||||||
newSize++;
|
|
||||||
}
|
}
|
||||||
|
dataBuf2[newSize] = data[i];
|
||||||
|
newSize++;
|
||||||
}
|
}
|
||||||
if(newSize == 0)
|
if(newSize)
|
||||||
{
|
sub_1510(dataBuf, newSize, ctx.result, num);
|
||||||
return 0;
|
// The RE code showed this always returning 0. I suspect it would want to return res instead.
|
||||||
}
|
|
||||||
int res = sub_00001510(dataBuf,newSize,ctx.result, num);
|
|
||||||
if(res == 0)
|
|
||||||
{
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -626,116 +414,49 @@ int sceSdCreateList_(pspChnnlsvContext2& ctx2, int mode, int uknw, u8* data, u8*
|
||||||
ctx2.unkn = 1;
|
ctx2.unkn = 1;
|
||||||
if (uknw == 2)
|
if (uknw == 2)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < 16; i++)
|
memcpy(ctx2.cryptedData, data, 16);
|
||||||
{
|
if (cryptkey)
|
||||||
ctx2.unknown[i] = data[i];
|
memxor(ctx2.cryptedData, cryptkey, 16);
|
||||||
}
|
|
||||||
if (cryptkey == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
ctx2.unknown[i] = ctx2.unknown[i] ^ cryptkey[i];
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (uknw == 1)
|
else if (uknw == 1)
|
||||||
{
|
{
|
||||||
u8 kirkHeader[37];
|
u8 kirkHeader[37];
|
||||||
u8* kirkData = kirkHeader+20;
|
u8* kirkData = kirkHeader+20;
|
||||||
int res = sub_000017A8(kirkHeader);
|
int res = sub_17A8(kirkHeader);
|
||||||
if (res != 0)
|
if (res)
|
||||||
{
|
|
||||||
return res;
|
return res;
|
||||||
}
|
|
||||||
for(int i = 15; i >= 0 ; i--)
|
memcpy(kirkHeader+20, kirkHeader, 16);
|
||||||
|
memset(kirkHeader+32, 0, 4);
|
||||||
|
|
||||||
|
int type = typeFromMode(mode);
|
||||||
|
if (type == 87)
|
||||||
|
memxor(kirkData, key199C, 16);
|
||||||
|
else if (type == 100)
|
||||||
|
memxor(kirkData, key19CC, 16);
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
{
|
{
|
||||||
kirkHeader[i+20] = kirkHeader[i];
|
case 2: case 4: case 6: res = kirkSendFuseCmd(kirkHeader, 16, true);
|
||||||
}
|
break;
|
||||||
for(int i = 0; i < 4; i++)
|
case 1: case 3: default:res = kirkSendCmd(kirkHeader, 16, numFromMode2(mode), true);
|
||||||
{
|
break;
|
||||||
kirkHeader[i+32] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == 6)
|
if (type == 87)
|
||||||
{
|
memxor(kirkData, key19AC, 16);
|
||||||
for(int i = 0; i < 16; i++)
|
else if (type == 100)
|
||||||
{
|
memxor(kirkData, key19DC, 16);
|
||||||
kirkData[i] = kirkData[i] ^ key000019CC[i];
|
|
||||||
}
|
|
||||||
res = sub_00001468(kirkHeader, 16);
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
kirkData[i] = kirkData[i] ^ key000019DC[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (mode == 4)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
kirkData[i] = kirkData[i] ^ key0000199C[i];
|
|
||||||
}
|
|
||||||
res = sub_00001468(kirkHeader, 16);
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
kirkData[i] = kirkData[i] ^ key000019AC[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (mode == 2)
|
|
||||||
{
|
|
||||||
res = sub_00001468(kirkHeader, 16);
|
|
||||||
}
|
|
||||||
else if (mode == 1)
|
|
||||||
{
|
|
||||||
res = sub_000013C8(kirkHeader, 16, 4);
|
|
||||||
}
|
|
||||||
else if (mode == 3)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
kirkData[i] = kirkData[i] ^ key0000199C[i];
|
|
||||||
}
|
|
||||||
res = sub_000013C8(kirkHeader, 16, 14);
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
kirkData[i] = kirkData[i] ^ key000019AC[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
kirkData[i] = kirkData[i] ^ key000019CC[i];
|
|
||||||
}
|
|
||||||
res = sub_000013C8(kirkHeader, 16, 18);
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
kirkData[i] = kirkData[i] ^ key000019DC[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != 0)
|
if (res)
|
||||||
{
|
|
||||||
return res;
|
return res;
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < 16; i++)
|
memcpy(ctx2.cryptedData, kirkData, 16);
|
||||||
{
|
memcpy(data, kirkData, 16);
|
||||||
ctx2.unknown[i] = kirkData[i];
|
if (cryptkey)
|
||||||
}
|
memxor(ctx2.cryptedData, cryptkey, 16);
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
data[i] = kirkData[i];
|
|
||||||
}
|
|
||||||
if (cryptkey != 0)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
ctx2.unknown[i] = ctx2.unknown[i] ^ cryptkey[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -770,12 +491,10 @@ int sceSdSetMember_(pspChnnlsvContext2& ctx, u8* data, int alignedLen)
|
||||||
{
|
{
|
||||||
for(i = 0; alignedLen >= 2048; i += 2048)
|
for(i = 0; alignedLen >= 2048; i += 2048)
|
||||||
{
|
{
|
||||||
int res = sub_00000000(kirkData, data + i, 2048, ctx.unknown, ctx.unkn, ctx.mode);
|
int res = sub_0000(kirkData, data + i, 2048, ctx.cryptedData, ctx.unkn, ctx.mode);
|
||||||
alignedLen = alignedLen - 2048;
|
alignedLen -= 2048;
|
||||||
if (res != 0)
|
if (res)
|
||||||
{
|
|
||||||
return res;
|
return res;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (alignedLen == 0)
|
if (alignedLen == 0)
|
||||||
|
@ -783,8 +502,7 @@ int sceSdSetMember_(pspChnnlsvContext2& ctx, u8* data, int alignedLen)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = sub_00000000(kirkData, data + i, alignedLen, ctx.unknown, ctx.unkn, ctx.mode);
|
return sub_0000(kirkData, data + i, alignedLen, ctx.cryptedData, ctx.unkn, ctx.mode);
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sceChnnlsv_21BE78B4(u32 ctxAddr)
|
int sceChnnlsv_21BE78B4(u32 ctxAddr)
|
||||||
|
@ -800,10 +518,7 @@ int sceChnnlsv_21BE78B4(u32 ctxAddr)
|
||||||
|
|
||||||
int sceChnnlsv_21BE78B4_(pspChnnlsvContext2& ctx)
|
int sceChnnlsv_21BE78B4_(pspChnnlsvContext2& ctx)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < 16; i++)
|
memset(ctx.cryptedData, 0, 16);
|
||||||
{
|
|
||||||
ctx.unknown[i] = 0;
|
|
||||||
}
|
|
||||||
ctx.unkn = 0;
|
ctx.unkn = 0;
|
||||||
ctx.mode = 0;
|
ctx.mode = 0;
|
||||||
|
|
||||||
|
@ -822,6 +537,6 @@ const HLEFunction sceChnnlsv[] =
|
||||||
|
|
||||||
void Register_sceChnnlsv()
|
void Register_sceChnnlsv()
|
||||||
{
|
{
|
||||||
RegisterModule("sceChnnlsv",ARRAY_SIZE(sceChnnlsv),sceChnnlsv);
|
RegisterModule("sceChnnlsv", ARRAY_SIZE(sceChnnlsv), sceChnnlsv);
|
||||||
kirk_init();
|
kirk_init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ typedef struct _pspChnnlsvContext1 {
|
||||||
|
|
||||||
/** Context data */
|
/** Context data */
|
||||||
u8 result[0x10];
|
u8 result[0x10];
|
||||||
u8 key[0x10];
|
u8 key[0x10];
|
||||||
int keyLength;
|
int keyLength;
|
||||||
} pspChnnlsvContext1;
|
} pspChnnlsvContext1;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ typedef struct _pspChnnlsvContext2 {
|
||||||
/** Context data */
|
/** Context data */
|
||||||
int mode;
|
int mode;
|
||||||
int unkn;
|
int unkn;
|
||||||
u8 unknown[0x92];
|
u8 cryptedData[0x92];
|
||||||
} pspChnnlsvContext2;
|
} pspChnnlsvContext2;
|
||||||
|
|
||||||
int sceSdSetIndex_(pspChnnlsvContext1& ctx, int value);
|
int sceSdSetIndex_(pspChnnlsvContext1& ctx, int value);
|
||||||
|
|
|
@ -161,11 +161,11 @@ void __CtrlSetAnalog(float x, float y, int stick)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> guard(ctrlMutex);
|
std::lock_guard<std::recursive_mutex> guard(ctrlMutex);
|
||||||
if (stick == 0) {
|
if (stick == 0) {
|
||||||
ctrlCurrent.analog[0] = (u8)(x * 127.f + 128.f);
|
ctrlCurrent.analog[0] = (u8)ceilf(x * 127.5f + 127.5f);
|
||||||
ctrlCurrent.analog[1] = (u8)(-y * 127.f + 128.f);
|
ctrlCurrent.analog[1] = (u8)ceilf(-y * 127.5f + 127.5f);
|
||||||
} else {
|
} else {
|
||||||
ctrlCurrent.analogRight[0] = (u8)(x * 127.f + 128.f);
|
ctrlCurrent.analogRight[0] = (u8)ceilf(x * 127.5f + 127.5f);
|
||||||
ctrlCurrent.analogRight[1] = (u8)(-y * 127.f + 128.f);
|
ctrlCurrent.analogRight[1] = (u8)ceilf(-y * 127.5f + 127.5f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -426,7 +426,7 @@ void hleEnterVblank(u64 userdata, int cyclesLate) {
|
||||||
|
|
||||||
gpuStats.numFrames++;
|
gpuStats.numFrames++;
|
||||||
|
|
||||||
if (g_Config.bShowFPSCounter) {
|
if (g_Config.iShowFPSCounter) {
|
||||||
CalculateFPS();
|
CalculateFPS();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,14 +25,24 @@ int sceHttpSetResolveRetry(int connectionID, int retryCount)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sceHttpInit() {
|
||||||
|
ERROR_LOG(HLE, "UNIMPL sceHttpInit()");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sceHttpEnd() {
|
||||||
|
ERROR_LOG(HLE, "UNIMPL sceHttpInit()");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 0x62411801 sceSircsInit
|
* 0x62411801 sceSircsInit
|
||||||
0x19155a2f sceSircsEnd
|
0x19155a2f sceSircsEnd
|
||||||
0x71eef62d sceSircsSend
|
0x71eef62d sceSircsSend
|
||||||
*/
|
*/
|
||||||
const HLEFunction sceHttp[] = {
|
const HLEFunction sceHttp[] = {
|
||||||
{0xab1abe07,0,"sceHttpInit"},
|
{0xab1abe07,WrapI_V<sceHttpInit>,"sceHttpInit"},
|
||||||
{0xd1c8945e,0,"sceHttpEnd"},
|
{0xd1c8945e,WrapI_V<sceHttpEnd>,"sceHttpEnd"},
|
||||||
{0xa6800c34,0,"sceHttpInitCache"},
|
{0xa6800c34,0,"sceHttpInitCache"},
|
||||||
{0x78b54c09,0,"sceHttpEndCache"},
|
{0x78b54c09,0,"sceHttpEndCache"},
|
||||||
{0x59e6d16f,0,"sceHttpEnableCache"},
|
{0x59e6d16f,0,"sceHttpEnableCache"},
|
||||||
|
|
|
@ -158,6 +158,7 @@ public:
|
||||||
sprintf(ptr, "Seekpos: %08x", (u32)pspFileSystem.GetSeekPos(handle));
|
sprintf(ptr, "Seekpos: %08x", (u32)pspFileSystem.GetSeekPos(handle));
|
||||||
}
|
}
|
||||||
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_BADF; }
|
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_BADF; }
|
||||||
|
static int GetStaticIDType() { return PPSSPP_KERNEL_TMID_File; }
|
||||||
int GetIDType() const { return PPSSPP_KERNEL_TMID_File; }
|
int GetIDType() const { return PPSSPP_KERNEL_TMID_File; }
|
||||||
|
|
||||||
virtual void DoState(PointerWrap &p) {
|
virtual void DoState(PointerWrap &p) {
|
||||||
|
@ -1441,6 +1442,7 @@ public:
|
||||||
const char *GetName() {return name.c_str();}
|
const char *GetName() {return name.c_str();}
|
||||||
const char *GetTypeName() {return "DirListing";}
|
const char *GetTypeName() {return "DirListing";}
|
||||||
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_BADF; }
|
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_BADF; }
|
||||||
|
static int GetStaticIDType() { return PPSSPP_KERNEL_TMID_DirList; }
|
||||||
int GetIDType() const { return PPSSPP_KERNEL_TMID_DirList; }
|
int GetIDType() const { return PPSSPP_KERNEL_TMID_DirList; }
|
||||||
|
|
||||||
virtual void DoState(PointerWrap &p) {
|
virtual void DoState(PointerWrap &p) {
|
||||||
|
|
|
@ -404,6 +404,7 @@ public:
|
||||||
|
|
||||||
// Implement this in all subclasses:
|
// Implement this in all subclasses:
|
||||||
// static u32 GetMissingErrorCode()
|
// static u32 GetMissingErrorCode()
|
||||||
|
// static int GetStaticIDType()
|
||||||
|
|
||||||
virtual void DoState(PointerWrap &p)
|
virtual void DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
|
@ -443,7 +444,7 @@ public:
|
||||||
if (handle < handleOffset || handle >= handleOffset+maxCount || !occupied[handle-handleOffset])
|
if (handle < handleOffset || handle >= handleOffset+maxCount || !occupied[handle-handleOffset])
|
||||||
{
|
{
|
||||||
ERROR_LOG(HLE, "Kernel: Bad object handle %i (%08x)", handle, handle);
|
ERROR_LOG(HLE, "Kernel: Bad object handle %i (%08x)", handle, handle);
|
||||||
outError = T::GetMissingErrorCode(); // ?
|
outError = T::GetMissingErrorCode();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -452,10 +453,10 @@ public:
|
||||||
// it just acted as a static case and everything worked. This means that we will never
|
// it just acted as a static case and everything worked. This means that we will never
|
||||||
// see the Wrong type object error below, but we'll just have to live with that danger.
|
// see the Wrong type object error below, but we'll just have to live with that danger.
|
||||||
T* t = static_cast<T*>(pool[handle - handleOffset]);
|
T* t = static_cast<T*>(pool[handle - handleOffset]);
|
||||||
if (t == 0)
|
if (t == 0 || t->GetIDType() != T::GetStaticIDType())
|
||||||
{
|
{
|
||||||
ERROR_LOG(HLE, "Kernel: Wrong type object %i (%08x)", handle, handle);
|
ERROR_LOG(HLE, "Kernel: Wrong object type for %i (%08x)", handle, handle);
|
||||||
outError = T::GetMissingErrorCode(); //FIX
|
outError = T::GetMissingErrorCode();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
outError = SCE_KERNEL_ERROR_OK;
|
outError = SCE_KERNEL_ERROR_OK;
|
||||||
|
@ -477,8 +478,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, typename ArgT>
|
template <class T, typename ArgT>
|
||||||
void Iterate(bool func(T *, ArgT), ArgT arg, int type)
|
void Iterate(bool func(T *, ArgT), ArgT arg)
|
||||||
{
|
{
|
||||||
|
int type = T::GetStaticIDType();
|
||||||
for (int i = 0; i < maxCount; i++)
|
for (int i = 0; i < maxCount; i++)
|
||||||
{
|
{
|
||||||
if (!occupied[i])
|
if (!occupied[i])
|
||||||
|
@ -491,8 +493,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 GetMissingErrorCode() { return -1; } // TODO
|
|
||||||
|
|
||||||
bool GetIDType(SceUID handle, int *type) const
|
bool GetIDType(SceUID handle, int *type) const
|
||||||
{
|
{
|
||||||
if (handle < handleOffset || handle >= handleOffset+maxCount || !occupied[handle-handleOffset])
|
if (handle < handleOffset || handle >= handleOffset+maxCount || !occupied[handle-handleOffset])
|
||||||
|
|
|
@ -40,6 +40,7 @@ struct Alarm : public KernelObject
|
||||||
const char *GetName() {return "[Alarm]";}
|
const char *GetName() {return "[Alarm]";}
|
||||||
const char *GetTypeName() {return "Alarm";}
|
const char *GetTypeName() {return "Alarm";}
|
||||||
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_ALMID; }
|
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_ALMID; }
|
||||||
|
static int GetStaticIDType() { return SCE_KERNEL_TMID_Alarm; }
|
||||||
int GetIDType() const { return SCE_KERNEL_TMID_Alarm; }
|
int GetIDType() const { return SCE_KERNEL_TMID_Alarm; }
|
||||||
|
|
||||||
virtual void DoState(PointerWrap &p)
|
virtual void DoState(PointerWrap &p)
|
||||||
|
|
|
@ -64,6 +64,7 @@ public:
|
||||||
static u32 GetMissingErrorCode() {
|
static u32 GetMissingErrorCode() {
|
||||||
return SCE_KERNEL_ERROR_UNKNOWN_EVFID;
|
return SCE_KERNEL_ERROR_UNKNOWN_EVFID;
|
||||||
}
|
}
|
||||||
|
static int GetStaticIDType() { return SCE_KERNEL_TMID_EventFlag; }
|
||||||
int GetIDType() const { return SCE_KERNEL_TMID_EventFlag; }
|
int GetIDType() const { return SCE_KERNEL_TMID_EventFlag; }
|
||||||
|
|
||||||
virtual void DoState(PointerWrap &p)
|
virtual void DoState(PointerWrap &p)
|
||||||
|
|
|
@ -53,6 +53,7 @@ struct Mbx : public KernelObject
|
||||||
const char *GetName() {return nmb.name;}
|
const char *GetName() {return nmb.name;}
|
||||||
const char *GetTypeName() {return "Mbx";}
|
const char *GetTypeName() {return "Mbx";}
|
||||||
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_MBXID; }
|
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_MBXID; }
|
||||||
|
static int GetStaticIDType() { return SCE_KERNEL_TMID_Mbox; }
|
||||||
int GetIDType() const { return SCE_KERNEL_TMID_Mbox; }
|
int GetIDType() const { return SCE_KERNEL_TMID_Mbox; }
|
||||||
|
|
||||||
void AddWaitingThread(SceUID id, u32 addr)
|
void AddWaitingThread(SceUID id, u32 addr)
|
||||||
|
|
|
@ -72,6 +72,7 @@ struct FPL : public KernelObject
|
||||||
const char *GetName() {return nf.name;}
|
const char *GetName() {return nf.name;}
|
||||||
const char *GetTypeName() {return "FPL";}
|
const char *GetTypeName() {return "FPL";}
|
||||||
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_FPLID; }
|
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_FPLID; }
|
||||||
|
static int GetStaticIDType() { return SCE_KERNEL_TMID_Fpl; }
|
||||||
int GetIDType() const { return SCE_KERNEL_TMID_Fpl; }
|
int GetIDType() const { return SCE_KERNEL_TMID_Fpl; }
|
||||||
|
|
||||||
int findFreeBlock() {
|
int findFreeBlock() {
|
||||||
|
@ -133,6 +134,7 @@ struct VPL : public KernelObject
|
||||||
const char *GetName() {return nv.name;}
|
const char *GetName() {return nv.name;}
|
||||||
const char *GetTypeName() {return "VPL";}
|
const char *GetTypeName() {return "VPL";}
|
||||||
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_VPLID; }
|
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_VPLID; }
|
||||||
|
static int GetStaticIDType() { return SCE_KERNEL_TMID_Vpl; }
|
||||||
int GetIDType() const { return SCE_KERNEL_TMID_Vpl; }
|
int GetIDType() const { return SCE_KERNEL_TMID_Vpl; }
|
||||||
|
|
||||||
VPL() : alloc(8) {}
|
VPL() : alloc(8) {}
|
||||||
|
@ -424,6 +426,7 @@ public:
|
||||||
sprintf(ptr, "MemPart: %08x - %08x size: %08x", address, address + sz, sz);
|
sprintf(ptr, "MemPart: %08x - %08x size: %08x", address, address + sz, sz);
|
||||||
}
|
}
|
||||||
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_UID; }
|
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_UID; }
|
||||||
|
static int GetStaticIDType() { return PPSSPP_KERNEL_TMID_PMB; }
|
||||||
int GetIDType() const { return PPSSPP_KERNEL_TMID_PMB; }
|
int GetIDType() const { return PPSSPP_KERNEL_TMID_PMB; }
|
||||||
|
|
||||||
PartitionMemoryBlock(BlockAllocator *_alloc, const char *_name, u32 size, MemblockType type, u32 alignment)
|
PartitionMemoryBlock(BlockAllocator *_alloc, const char *_name, u32 size, MemblockType type, u32 alignment)
|
||||||
|
@ -1331,6 +1334,7 @@ struct TLS : public KernelObject
|
||||||
const char *GetName() {return ntls.name;}
|
const char *GetName() {return ntls.name;}
|
||||||
const char *GetTypeName() {return "TLS";}
|
const char *GetTypeName() {return "TLS";}
|
||||||
static u32 GetMissingErrorCode() { return PSP_ERROR_UNKNOWN_TLS_ID; }
|
static u32 GetMissingErrorCode() { return PSP_ERROR_UNKNOWN_TLS_ID; }
|
||||||
|
static int GetStaticIDType() { return SCE_KERNEL_TMID_Tls; }
|
||||||
int GetIDType() const { return SCE_KERNEL_TMID_Tls; }
|
int GetIDType() const { return SCE_KERNEL_TMID_Tls; }
|
||||||
|
|
||||||
TLS() : next(0) {}
|
TLS() : next(0) {}
|
||||||
|
|
|
@ -179,6 +179,7 @@ public:
|
||||||
nm.entry_addr);
|
nm.entry_addr);
|
||||||
}
|
}
|
||||||
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_MODULE; }
|
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_MODULE; }
|
||||||
|
static int GetStaticIDType() { return PPSSPP_KERNEL_TMID_Module; }
|
||||||
int GetIDType() const { return PPSSPP_KERNEL_TMID_Module; }
|
int GetIDType() const { return PPSSPP_KERNEL_TMID_Module; }
|
||||||
|
|
||||||
virtual void DoState(PointerWrap &p)
|
virtual void DoState(PointerWrap &p)
|
||||||
|
@ -1349,7 +1350,7 @@ u32 sceKernelGetModuleIdByAddress(u32 moduleAddr)
|
||||||
state.addr = moduleAddr;
|
state.addr = moduleAddr;
|
||||||
state.result = SCE_KERNEL_ERROR_UNKNOWN_MODULE;
|
state.result = SCE_KERNEL_ERROR_UNKNOWN_MODULE;
|
||||||
|
|
||||||
kernelObjects.Iterate(&__GetModuleIdByAddressIterator, &state, PPSSPP_KERNEL_TMID_Module);
|
kernelObjects.Iterate(&__GetModuleIdByAddressIterator, &state);
|
||||||
if (state.result == SCE_KERNEL_ERROR_UNKNOWN_MODULE)
|
if (state.result == SCE_KERNEL_ERROR_UNKNOWN_MODULE)
|
||||||
ERROR_LOG(HLE, "sceKernelGetModuleIdByAddress(%08x): module not found", moduleAddr)
|
ERROR_LOG(HLE, "sceKernelGetModuleIdByAddress(%08x): module not found", moduleAddr)
|
||||||
else
|
else
|
||||||
|
|
|
@ -55,6 +55,7 @@ struct MsgPipe : public KernelObject
|
||||||
const char *GetName() {return nmp.name;}
|
const char *GetName() {return nmp.name;}
|
||||||
const char *GetTypeName() {return "MsgPipe";}
|
const char *GetTypeName() {return "MsgPipe";}
|
||||||
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_MPPID; }
|
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_MPPID; }
|
||||||
|
static int GetStaticIDType() { return SCE_KERNEL_TMID_Mpipe; }
|
||||||
int GetIDType() const { return SCE_KERNEL_TMID_Mpipe; }
|
int GetIDType() const { return SCE_KERNEL_TMID_Mpipe; }
|
||||||
|
|
||||||
MsgPipe() : buffer(NULL) {}
|
MsgPipe() : buffer(NULL) {}
|
||||||
|
|
|
@ -64,6 +64,7 @@ struct Mutex : public KernelObject
|
||||||
const char *GetName() {return nm.name;}
|
const char *GetName() {return nm.name;}
|
||||||
const char *GetTypeName() {return "Mutex";}
|
const char *GetTypeName() {return "Mutex";}
|
||||||
static u32 GetMissingErrorCode() { return PSP_MUTEX_ERROR_NO_SUCH_MUTEX; }
|
static u32 GetMissingErrorCode() { return PSP_MUTEX_ERROR_NO_SUCH_MUTEX; }
|
||||||
|
static int GetStaticIDType() { return SCE_KERNEL_TMID_Mutex; }
|
||||||
int GetIDType() const { return SCE_KERNEL_TMID_Mutex; }
|
int GetIDType() const { return SCE_KERNEL_TMID_Mutex; }
|
||||||
|
|
||||||
virtual void DoState(PointerWrap &p)
|
virtual void DoState(PointerWrap &p)
|
||||||
|
@ -125,6 +126,7 @@ struct LwMutex : public KernelObject
|
||||||
const char *GetName() {return nm.name;}
|
const char *GetName() {return nm.name;}
|
||||||
const char *GetTypeName() {return "LwMutex";}
|
const char *GetTypeName() {return "LwMutex";}
|
||||||
static u32 GetMissingErrorCode() { return PSP_LWMUTEX_ERROR_NO_SUCH_LWMUTEX; }
|
static u32 GetMissingErrorCode() { return PSP_LWMUTEX_ERROR_NO_SUCH_LWMUTEX; }
|
||||||
|
static int GetStaticIDType() { return SCE_KERNEL_TMID_LwMutex; }
|
||||||
int GetIDType() const { return SCE_KERNEL_TMID_LwMutex; }
|
int GetIDType() const { return SCE_KERNEL_TMID_LwMutex; }
|
||||||
|
|
||||||
virtual void DoState(PointerWrap &p)
|
virtual void DoState(PointerWrap &p)
|
||||||
|
|
|
@ -57,6 +57,7 @@ struct Semaphore : public KernelObject
|
||||||
const char *GetTypeName() {return "Semaphore";}
|
const char *GetTypeName() {return "Semaphore";}
|
||||||
|
|
||||||
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_SEMID; }
|
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_SEMID; }
|
||||||
|
static int GetStaticIDType() { return SCE_KERNEL_TMID_Semaphore; }
|
||||||
int GetIDType() const { return SCE_KERNEL_TMID_Semaphore; }
|
int GetIDType() const { return SCE_KERNEL_TMID_Semaphore; }
|
||||||
|
|
||||||
virtual void DoState(PointerWrap &p)
|
virtual void DoState(PointerWrap &p)
|
||||||
|
|
|
@ -82,6 +82,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_CBID; }
|
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_CBID; }
|
||||||
|
static int GetStaticIDType() { return SCE_KERNEL_TMID_Callback; }
|
||||||
int GetIDType() const { return SCE_KERNEL_TMID_Callback; }
|
int GetIDType() const { return SCE_KERNEL_TMID_Callback; }
|
||||||
|
|
||||||
virtual void DoState(PointerWrap &p)
|
virtual void DoState(PointerWrap &p)
|
||||||
|
@ -295,7 +296,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_THID; }
|
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_THID; }
|
||||||
|
static int GetStaticIDType() { return SCE_KERNEL_TMID_Thread; }
|
||||||
int GetIDType() const { return SCE_KERNEL_TMID_Thread; }
|
int GetIDType() const { return SCE_KERNEL_TMID_Thread; }
|
||||||
|
|
||||||
bool AllocateStack(u32 &stackSize)
|
bool AllocateStack(u32 &stackSize)
|
||||||
|
|
|
@ -42,6 +42,7 @@ struct VTimer : public KernelObject {
|
||||||
const char *GetName() {return nvt.name;}
|
const char *GetName() {return nvt.name;}
|
||||||
const char *GetTypeName() {return "VTimer";}
|
const char *GetTypeName() {return "VTimer";}
|
||||||
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_VTID; }
|
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_VTID; }
|
||||||
|
static int GetStaticIDType() { return SCE_KERNEL_TMID_VTimer; }
|
||||||
int GetIDType() const { return SCE_KERNEL_TMID_VTimer; }
|
int GetIDType() const { return SCE_KERNEL_TMID_VTimer; }
|
||||||
|
|
||||||
virtual void DoState(PointerWrap &p) {
|
virtual void DoState(PointerWrap &p) {
|
||||||
|
|
|
@ -327,10 +327,11 @@ void __MpegShutdown() {
|
||||||
u32 sceMpegInit() {
|
u32 sceMpegInit() {
|
||||||
if (isMpegInit) {
|
if (isMpegInit) {
|
||||||
WARN_LOG(HLE, "sceMpegInit(): already initialized");
|
WARN_LOG(HLE, "sceMpegInit(): already initialized");
|
||||||
return ERROR_MPEG_ALREADY_INIT;
|
// TODO: Need to properly hook module load/unload for this to work right.
|
||||||
|
//return ERROR_MPEG_ALREADY_INIT;
|
||||||
|
} else {
|
||||||
|
INFO_LOG(HLE, "sceMpegInit()");
|
||||||
}
|
}
|
||||||
|
|
||||||
INFO_LOG(HLE, "sceMpegInit()");
|
|
||||||
isMpegInit = true;
|
isMpegInit = true;
|
||||||
return hleDelayResult(0, "mpeg init", 750);
|
return hleDelayResult(0, "mpeg init", 750);
|
||||||
}
|
}
|
||||||
|
@ -1009,10 +1010,11 @@ u32 sceMpegFinish()
|
||||||
if (!isMpegInit)
|
if (!isMpegInit)
|
||||||
{
|
{
|
||||||
WARN_LOG(HLE, "sceMpegFinish(...): not initialized");
|
WARN_LOG(HLE, "sceMpegFinish(...): not initialized");
|
||||||
return ERROR_MPEG_NOT_YET_INIT;
|
// TODO: Need to properly hook module load/unload for this to work right.
|
||||||
|
//return ERROR_MPEG_NOT_YET_INIT;
|
||||||
|
} else {
|
||||||
|
INFO_LOG(HLE, "sceMpegFinish(...)");
|
||||||
}
|
}
|
||||||
|
|
||||||
INFO_LOG(HLE, "sceMpegFinish(...)");
|
|
||||||
isMpegInit = false;
|
isMpegInit = false;
|
||||||
//__MpegFinish();
|
//__MpegFinish();
|
||||||
return hleDelayResult(0, "mpeg finish", 250);
|
return hleDelayResult(0, "mpeg finish", 250);
|
||||||
|
|
|
@ -24,9 +24,16 @@
|
||||||
#include "sceUtility.h"
|
#include "sceUtility.h"
|
||||||
|
|
||||||
static bool netInited;
|
static bool netInited;
|
||||||
|
static bool netInetInited;
|
||||||
static bool netAdhocInited;
|
static bool netAdhocInited;
|
||||||
|
static bool netApctlInited;
|
||||||
|
|
||||||
static u32 adhocctlHandlerCount;
|
static u32 adhocctlHandlerCount;
|
||||||
|
static u32 apctlHandlerCount;
|
||||||
|
|
||||||
|
// TODO: Determine how many handlers we can actually have
|
||||||
|
const u32 MAX_ADHOCCTL_HANDLERS = 32;
|
||||||
|
const u32 MAX_APCTL_HANDLERS = 32;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ERROR_NET_BUFFER_TOO_SMALL = 0x80400706,
|
ERROR_NET_BUFFER_TOO_SMALL = 0x80400706,
|
||||||
|
@ -78,18 +85,26 @@ struct SceNetMallocStat {
|
||||||
|
|
||||||
static struct SceNetMallocStat netMallocStat;
|
static struct SceNetMallocStat netMallocStat;
|
||||||
|
|
||||||
struct AdhocctlHandler
|
struct AdhocctlHandler {
|
||||||
{
|
|
||||||
u32 entryPoint;
|
u32 entryPoint;
|
||||||
u32 argument;
|
u32 argument;
|
||||||
u32 id;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<AdhocctlHandler> adhocctlHandlers;
|
static std::map<int, AdhocctlHandler> adhocctlHandlers;
|
||||||
|
|
||||||
|
struct ApctlHandler {
|
||||||
|
u32 entryPoint;
|
||||||
|
u32 argument;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::map<int, ApctlHandler> apctlHandlers;
|
||||||
|
|
||||||
void __NetInit() {
|
void __NetInit() {
|
||||||
netInited = false;
|
netInited = false;
|
||||||
netAdhocInited = false;
|
netAdhocInited = false;
|
||||||
|
netApctlInited = false;
|
||||||
|
netInetInited = false;
|
||||||
|
memset(&netMallocStat, 0, sizeof(netMallocStat));
|
||||||
}
|
}
|
||||||
|
|
||||||
void __NetShutdown() {
|
void __NetShutdown() {
|
||||||
|
@ -98,21 +113,40 @@ void __NetShutdown() {
|
||||||
|
|
||||||
void __UpdateAdhocctlHandlers(int flag, int error) {
|
void __UpdateAdhocctlHandlers(int flag, int error) {
|
||||||
u32 args[3] = { 0, 0, 0 };
|
u32 args[3] = { 0, 0, 0 };
|
||||||
for(std::vector<AdhocctlHandler>::iterator it = adhocctlHandlers.begin(); it < adhocctlHandlers.end(); it++) {
|
args[0] = flag;
|
||||||
args[0] = flag;
|
args[1] = error;
|
||||||
args[1] = error;
|
|
||||||
args[2] = it->argument;
|
|
||||||
|
|
||||||
__KernelDirectMipsCall(it->entryPoint, NULL, args, 3, true);
|
for(std::map<int, AdhocctlHandler>::iterator it = adhocctlHandlers.begin(); it != adhocctlHandlers.end(); ++it) {
|
||||||
|
args[2] = it->second.argument;
|
||||||
|
|
||||||
|
__KernelDirectMipsCall(it->second.entryPoint, NULL, args, 3, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __UpdateApctlHandlers(int oldState, int newState, int flag, int error) {
|
||||||
|
u32 args[5] = { 0, 0, 0, 0, 0 };
|
||||||
|
args[0] = oldState;
|
||||||
|
args[1] = newState;
|
||||||
|
args[2] = flag;
|
||||||
|
args[3] = error;
|
||||||
|
|
||||||
|
for(std::map<int, ApctlHandler>::iterator it = apctlHandlers.begin(); it != apctlHandlers.end(); ++it) {
|
||||||
|
args[4] = it->second.argument;
|
||||||
|
|
||||||
|
__KernelDirectMipsCall(it->second.entryPoint, NULL, args, 5, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This feels like a dubious proposition, mostly...
|
// This feels like a dubious proposition, mostly...
|
||||||
void __NetDoState(PointerWrap &p) {
|
void __NetDoState(PointerWrap &p) {
|
||||||
p.Do(netInited);
|
p.Do(netInited);
|
||||||
|
p.Do(netInetInited);
|
||||||
p.Do(netAdhocInited);
|
p.Do(netAdhocInited);
|
||||||
|
p.Do(netApctlInited);
|
||||||
p.Do(adhocctlHandlers);
|
p.Do(adhocctlHandlers);
|
||||||
p.Do(adhocctlHandlerCount);
|
p.Do(adhocctlHandlerCount);
|
||||||
|
p.Do(apctlHandlers);
|
||||||
|
p.Do(apctlHandlerCount);
|
||||||
p.Do(netMallocStat);
|
p.Do(netMallocStat);
|
||||||
p.DoMarker("net");
|
p.DoMarker("net");
|
||||||
}
|
}
|
||||||
|
@ -121,12 +155,11 @@ void __NetDoState(PointerWrap &p) {
|
||||||
void sceNetInit() {
|
void sceNetInit() {
|
||||||
ERROR_LOG(HLE,"UNIMPL sceNetInit(poolsize=%d, calloutpri=%i, calloutstack=%d, netintrpri=%i, netintrstack=%d)", PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
|
ERROR_LOG(HLE,"UNIMPL sceNetInit(poolsize=%d, calloutpri=%i, calloutstack=%d, netintrpri=%i, netintrstack=%d)", PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
|
||||||
netInited = true;
|
netInited = true;
|
||||||
memset(&netMallocStat, 0, sizeof(netMallocStat));
|
|
||||||
netMallocStat.maximum = PARAM(0);
|
netMallocStat.maximum = PARAM(0);
|
||||||
netMallocStat.free = PARAM(0);
|
netMallocStat.free = PARAM(0);
|
||||||
netMallocStat.pool = 0;
|
netMallocStat.pool = 0;
|
||||||
|
|
||||||
RETURN(0); //ERROR <- The Dax: Why is it an error when it returns 0 on success?
|
RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 sceNetTerm() {
|
u32 sceNetTerm() {
|
||||||
|
@ -172,29 +205,35 @@ u32 sceWlanGetSwitchState() {
|
||||||
// TODO: Should we allow the same handler to be added more than once?
|
// TODO: Should we allow the same handler to be added more than once?
|
||||||
u32 sceNetAdhocctlAddHandler(u32 handlerPtr, u32 handlerArg) {
|
u32 sceNetAdhocctlAddHandler(u32 handlerPtr, u32 handlerArg) {
|
||||||
bool foundHandler = false;
|
bool foundHandler = false;
|
||||||
|
u32 retval = adhocctlHandlerCount;
|
||||||
struct AdhocctlHandler handler;
|
struct AdhocctlHandler handler;
|
||||||
memset(&handler, 0, sizeof(handler));
|
memset(&handler, 0, sizeof(handler));
|
||||||
|
|
||||||
handler.entryPoint = handlerPtr;
|
handler.entryPoint = handlerPtr;
|
||||||
handler.argument = handlerArg;
|
handler.argument = handlerArg;
|
||||||
handler.id = -1;
|
|
||||||
|
|
||||||
for(std::vector<AdhocctlHandler>::iterator it = adhocctlHandlers.begin(); it < adhocctlHandlers.end(); it++) {
|
for(std::map<int, AdhocctlHandler>::iterator it = adhocctlHandlers.begin(); it != adhocctlHandlers.end(); it++) {
|
||||||
if(it->entryPoint == handlerPtr) {
|
if(it->second.entryPoint == handlerPtr) {
|
||||||
foundHandler = true;
|
foundHandler = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!foundHandler && Memory::IsValidAddress(handlerPtr)) {
|
if(!foundHandler && Memory::IsValidAddress(handlerPtr)) {
|
||||||
handler.id = adhocctlHandlerCount > 0? ++adhocctlHandlerCount : 0;
|
if(adhocctlHandlerCount >= MAX_ADHOCCTL_HANDLERS) {
|
||||||
adhocctlHandlers.push_back(handler);
|
ERROR_LOG(HLE, "UNTESTED UNTESTED sceNetAdhocctlAddHandler(%x, %x): Too many handlers", handlerPtr, handlerArg);
|
||||||
WARN_LOG(HLE, "UNTESTED sceNetAdhocctlAddHandler(%x, %x): added handler %d", handlerPtr, handlerArg, handler.id);
|
retval = ERROR_NET_ADHOCCTL_TOO_MANY_HANDLERS;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
adhocctlHandlers[adhocctlHandlerCount++] = handler;
|
||||||
|
WARN_LOG(HLE, "UNTESTED sceNetAdhocctlAddHandler(%x, %x): added handler %d", handlerPtr, handlerArg, adhocctlHandlerCount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ERROR_LOG(HLE, "UNTESTED sceNetAdhocctlAddHandler(%x, %x): Same handler already exists", handlerPtr, handlerArg);
|
ERROR_LOG(HLE, "UNTESTED sceNetAdhocctlAddHandler(%x, %x): Same handler already exists", handlerPtr, handlerArg);
|
||||||
|
|
||||||
|
|
||||||
return handler.id;
|
// The id to return is the number of handlers currently registered
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 sceNetAdhocctlDisconnect() {
|
u32 sceNetAdhocctlDisconnect() {
|
||||||
|
@ -205,9 +244,14 @@ u32 sceNetAdhocctlDisconnect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 sceNetAdhocctlDelHandler(u32 handlerID) {
|
u32 sceNetAdhocctlDelHandler(u32 handlerID) {
|
||||||
WARN_LOG(HLE, "UNTESTED sceNetAdhocctlDelHandler(%x)", handlerID);
|
|
||||||
adhocctlHandlers.erase(adhocctlHandlers.begin() + handlerID);
|
if(adhocctlHandlers.find(handlerID) != adhocctlHandlers.end()) {
|
||||||
adhocctlHandlerCount = adhocctlHandlerCount > 0? --adhocctlHandlerCount : adhocctlHandlerCount;
|
adhocctlHandlers.erase(handlerID);
|
||||||
|
adhocctlHandlerCount = adhocctlHandlerCount > 0? --adhocctlHandlerCount : 0;
|
||||||
|
WARN_LOG(HLE, "UNTESTED sceNetAdhocctlDelHandler(%d): deleted handler %d", handlerID, handlerID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ERROR_LOG(HLE, "UNTESTED sceNetAdhocctlDelHandler(%d): asked to delete invalid handler %d", handlerID, handlerID);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -261,7 +305,7 @@ int sceNetAdhocPdpCreate(const char *mac, u32 port, int bufferSize, u32 unknown)
|
||||||
|
|
||||||
// TODO: Should we really write the struct if we're disconnected?
|
// TODO: Should we really write the struct if we're disconnected?
|
||||||
int sceNetAdhocctlGetParameter(u32 paramAddr) {
|
int sceNetAdhocctlGetParameter(u32 paramAddr) {
|
||||||
ERROR_LOG(HLE, "UNTESTED %x=sceNetAdhocctlGetParameter(%x)", 0, paramAddr);
|
WARN_LOG(HLE, "UNTESTED sceNetAdhocctlGetParameter(%x)", paramAddr);
|
||||||
struct SceNetAdhocctlParams params;
|
struct SceNetAdhocctlParams params;
|
||||||
params.channel = 0;
|
params.channel = 0;
|
||||||
for(int i = 0; i < 6; i++)
|
for(int i = 0; i < 6; i++)
|
||||||
|
@ -318,7 +362,7 @@ int sceNetAdhocctlConnect(u32 ptrToGroupName) {
|
||||||
|
|
||||||
// Write static data since we don't actually manage any memory for sceNet* yet.
|
// Write static data since we don't actually manage any memory for sceNet* yet.
|
||||||
int sceNetGetMallocStat(u32 statPtr) {
|
int sceNetGetMallocStat(u32 statPtr) {
|
||||||
ERROR_LOG(HLE, "UNTESTED sceNetGetMallocStat(%x)", statPtr);
|
WARN_LOG(HLE, "UNTESTED sceNetGetMallocStat(%x)", statPtr);
|
||||||
if(Memory::IsValidAddress(statPtr))
|
if(Memory::IsValidAddress(statPtr))
|
||||||
Memory::WriteStruct(statPtr, &netMallocStat);
|
Memory::WriteStruct(statPtr, &netMallocStat);
|
||||||
else
|
else
|
||||||
|
@ -332,6 +376,88 @@ int sceNetAdhocMatchingInit(u32 memsize) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sceNetInetInit() {
|
||||||
|
ERROR_LOG(HLE, "UNIMPL sceNetInetInit()");
|
||||||
|
if (netInetInited)
|
||||||
|
return ERROR_NET_ADHOC_ALREADY_INITIALIZED; // TODO: What's the proper error for netInet already being inited?
|
||||||
|
netInetInited = true;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sceNetInetTerm() {
|
||||||
|
ERROR_LOG(HLE, "UNIMPL sceNetInetTerm()");
|
||||||
|
netInetInited = false;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sceNetApctlInit() {
|
||||||
|
ERROR_LOG(HLE, "UNIMPL sceNetApctlInit()");
|
||||||
|
if (netAdhocInited)
|
||||||
|
return ERROR_NET_ADHOC_ALREADY_INITIALIZED; // TODO: What's the proper error for apctl already being inited?
|
||||||
|
netApctlInited = true;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sceNetApctlTerm() {
|
||||||
|
ERROR_LOG(HLE, "UNIMPL sceNeApctlTerm()");
|
||||||
|
netInetInited = false;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: How many handlers can the PSP actually have for Apctl?
|
||||||
|
// TODO: Should we allow the same handler to be added more than once?
|
||||||
|
u32 sceNetApctlAddHandler(u32 handlerPtr, u32 handlerArg) {
|
||||||
|
bool foundHandler = false;
|
||||||
|
u32 retval = apctlHandlerCount;
|
||||||
|
struct ApctlHandler handler;
|
||||||
|
memset(&handler, 0, sizeof(handler));
|
||||||
|
|
||||||
|
handler.entryPoint = handlerPtr;
|
||||||
|
handler.argument = handlerArg;
|
||||||
|
|
||||||
|
for(std::map<int, ApctlHandler>::iterator it = apctlHandlers.begin(); it != apctlHandlers.end(); it++) {
|
||||||
|
if(it->second.entryPoint == handlerPtr) {
|
||||||
|
foundHandler = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!foundHandler && Memory::IsValidAddress(handlerPtr)) {
|
||||||
|
if(apctlHandlerCount >= MAX_APCTL_HANDLERS) {
|
||||||
|
ERROR_LOG(HLE, "UNTESTED sceNetApctlAddHandler(%x, %x): Too many handlers", handlerPtr, handlerArg);
|
||||||
|
retval = ERROR_NET_ADHOCCTL_TOO_MANY_HANDLERS; // TODO: What's the proper error code for Apctl's TOO_MANY_HANDLERS?
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
apctlHandlers[apctlHandlerCount++] = handler;
|
||||||
|
WARN_LOG(HLE, "UNTESTED sceNetApctlAddHandler(%x, %x): added handler %d", handlerPtr, handlerArg, apctlHandlerCount);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ERROR_LOG(HLE, "UNTESTED sceNetApctlAddHandler(%x, %x): Same handler already exists", handlerPtr, handlerArg);
|
||||||
|
|
||||||
|
|
||||||
|
// The id to return is the number of handlers currently registered
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sceNetApctlDelHandler(u32 handlerID) {
|
||||||
|
|
||||||
|
if(apctlHandlers.find(handlerID) != apctlHandlers.end()) {
|
||||||
|
apctlHandlers.erase(handlerID);
|
||||||
|
apctlHandlerCount = apctlHandlerCount > 0? --apctlHandlerCount : 0;
|
||||||
|
WARN_LOG(HLE, "UNTESTED sceNetapctlDelHandler(%d): deleted handler %d", handlerID, handlerID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ERROR_LOG(HLE, "UNTESTED sceNetapctlDelHandler(%d): asked to delete invalid handler %d", handlerID, handlerID);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const HLEFunction sceNet[] = {
|
const HLEFunction sceNet[] = {
|
||||||
{0x39AF39A6, sceNetInit, "sceNetInit"},
|
{0x39AF39A6, sceNetInit, "sceNetInit"},
|
||||||
{0x281928A9, WrapU_V<sceNetTerm>, "sceNetTerm"},
|
{0x281928A9, WrapU_V<sceNetTerm>, "sceNetTerm"},
|
||||||
|
@ -431,7 +557,7 @@ const HLEFunction sceNetResolver[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const HLEFunction sceNetInet[] = {
|
const HLEFunction sceNetInet[] = {
|
||||||
{0x17943399, 0, "sceNetInetInit"},
|
{0x17943399, WrapI_V<sceNetInetInit>, "sceNetInetInit"},
|
||||||
{0x2fe71fe7, 0, "sceNetInetSetsockopt"},
|
{0x2fe71fe7, 0, "sceNetInetSetsockopt"},
|
||||||
{0x410b34aa, 0, "sceNetInetConnect"},
|
{0x410b34aa, 0, "sceNetInetConnect"},
|
||||||
{0x5be8d595, 0, "sceNetInetSelect"},
|
{0x5be8d595, 0, "sceNetInetSelect"},
|
||||||
|
@ -450,7 +576,7 @@ const HLEFunction sceNetInet[] = {
|
||||||
{0xd10a1a7a, 0, "sceNetInetListen"},
|
{0xd10a1a7a, 0, "sceNetInetListen"},
|
||||||
{0xdb094e1b, 0, "sceNetInetAccept"},
|
{0xdb094e1b, 0, "sceNetInetAccept"},
|
||||||
{0x8ca3a97e, 0, "sceNetInetGetPspError"},
|
{0x8ca3a97e, 0, "sceNetInetGetPspError"},
|
||||||
{0xa9ed66b9, 0, "sceNetInetTerm"},
|
{0xa9ed66b9, WrapI_V<sceNetInetTerm>, "sceNetInetTerm"},
|
||||||
{0xE30B8C19, 0, "sceNetInetInetPton"},
|
{0xE30B8C19, 0, "sceNetInetInetPton"},
|
||||||
{0xE247B6D6, 0, "sceNetInetGetpeername"},
|
{0xE247B6D6, 0, "sceNetInetGetpeername"},
|
||||||
{0x162e6fd5, 0, "sceNetInetGetsockname"},
|
{0x162e6fd5, 0, "sceNetInetGetsockname"},
|
||||||
|
@ -468,10 +594,10 @@ const HLEFunction sceNetApctl[] = {
|
||||||
{0xCFB957C6, 0, "sceNetApctlConnect"},
|
{0xCFB957C6, 0, "sceNetApctlConnect"},
|
||||||
{0x24fe91a1, 0, "sceNetApctlDisconnect"},
|
{0x24fe91a1, 0, "sceNetApctlDisconnect"},
|
||||||
{0x5deac81b, 0, "sceNetApctlGetState"},
|
{0x5deac81b, 0, "sceNetApctlGetState"},
|
||||||
{0x8abadd51, 0, "sceNetApctlAddHandler"},
|
{0x8abadd51, WrapU_UU<sceNetApctlAddHandler>, "sceNetApctlAddHandler"},
|
||||||
{0xe2f91f9b, 0, "sceNetApctlInit"},
|
{0xe2f91f9b, WrapI_V<sceNetApctlInit>, "sceNetApctlInit"},
|
||||||
{0x5963991b, 0, "sceNetApctlDelHandler"},
|
{0x5963991b, WrapI_U<sceNetApctlDelHandler>, "sceNetApctlDelHandler"},
|
||||||
{0xb3edd0ec, 0, "sceNetApctlTerm"},
|
{0xb3edd0ec, WrapI_V<sceNetApctlTerm>, "sceNetApctlTerm"},
|
||||||
{0x2BEFDF23, 0, "sceNetApctlGetInfo"},
|
{0x2BEFDF23, 0, "sceNetApctlGetInfo"},
|
||||||
{0xa3e77e13, 0, "sceNetApctlScanSSID2"},
|
{0xa3e77e13, 0, "sceNetApctlScanSSID2"},
|
||||||
{0xf25a5006, 0, "sceNetApctlGetBSSDescIDList2"},
|
{0xf25a5006, 0, "sceNetApctlGetBSSDescIDList2"},
|
||||||
|
|
|
@ -231,8 +231,8 @@ Psmf::Psmf(u32 data) {
|
||||||
streamOffset = bswap32(Memory::Read_U32(data + 8));
|
streamOffset = bswap32(Memory::Read_U32(data + 8));
|
||||||
streamSize = bswap32(Memory::Read_U32(data + 12));
|
streamSize = bswap32(Memory::Read_U32(data + 12));
|
||||||
streamDataTotalSize = bswap32(Memory::Read_U32(data + 0x50));
|
streamDataTotalSize = bswap32(Memory::Read_U32(data + 0x50));
|
||||||
presentationStartTime = bswap32(Memory::Read_U32(data + PSMF_FIRST_TIMESTAMP_OFFSET));
|
presentationStartTime = getMpegTimeStamp(Memory::GetPointer(data + PSMF_FIRST_TIMESTAMP_OFFSET));
|
||||||
presentationEndTime = bswap32(Memory::Read_U32(data + PSMF_LAST_TIMESTAMP_OFFSET));
|
presentationEndTime = getMpegTimeStamp(Memory::GetPointer(data + PSMF_LAST_TIMESTAMP_OFFSET));
|
||||||
streamDataNextBlockSize = bswap32(Memory::Read_U32(data + 0x6A));
|
streamDataNextBlockSize = bswap32(Memory::Read_U32(data + 0x6A));
|
||||||
streamDataNextInnerBlockSize = bswap32(Memory::Read_U32(data + 0x7C));
|
streamDataNextInnerBlockSize = bswap32(Memory::Read_U32(data + 0x7C));
|
||||||
numStreams = bswap16(Memory::Read_U16(data + 0x80));
|
numStreams = bswap16(Memory::Read_U16(data + 0x80));
|
||||||
|
|
|
@ -72,6 +72,7 @@ void __UtilityDoState(PointerWrap &p)
|
||||||
msgDialog.DoState(p);
|
msgDialog.DoState(p);
|
||||||
oskDialog.DoState(p);
|
oskDialog.DoState(p);
|
||||||
netDialog.DoState(p);
|
netDialog.DoState(p);
|
||||||
|
screenshotDialog.DoState(p);
|
||||||
p.Do(currentlyLoadedModules);
|
p.Do(currentlyLoadedModules);
|
||||||
p.DoMarker("sceUtility");
|
p.DoMarker("sceUtility");
|
||||||
}
|
}
|
||||||
|
@ -82,6 +83,7 @@ void __UtilityShutdown()
|
||||||
msgDialog.Shutdown(true);
|
msgDialog.Shutdown(true);
|
||||||
oskDialog.Shutdown(true);
|
oskDialog.Shutdown(true);
|
||||||
netDialog.Shutdown(true);
|
netDialog.Shutdown(true);
|
||||||
|
screenshotDialog.Shutdown(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int __UtilityGetStatus()
|
int __UtilityGetStatus()
|
||||||
|
@ -459,7 +461,7 @@ u32 sceUtilityGetSystemParamInt(u32 id, u32 destaddr)
|
||||||
param = g_Config.iDateFormat;
|
param = g_Config.iDateFormat;
|
||||||
break;
|
break;
|
||||||
case PSP_SYSTEMPARAM_ID_INT_TIME_FORMAT:
|
case PSP_SYSTEMPARAM_ID_INT_TIME_FORMAT:
|
||||||
param = g_Config.itimeformat?PSP_SYSTEMPARAM_TIME_FORMAT_12HR:PSP_SYSTEMPARAM_TIME_FORMAT_24HR;
|
param = g_Config.iTimeFormat?PSP_SYSTEMPARAM_TIME_FORMAT_12HR:PSP_SYSTEMPARAM_TIME_FORMAT_24HR;
|
||||||
break;
|
break;
|
||||||
case PSP_SYSTEMPARAM_ID_INT_TIMEZONE:
|
case PSP_SYSTEMPARAM_ID_INT_TIMEZONE:
|
||||||
param = g_Config.iTimeZone;
|
param = g_Config.iTimeZone;
|
||||||
|
@ -471,7 +473,7 @@ u32 sceUtilityGetSystemParamInt(u32 id, u32 destaddr)
|
||||||
param = g_Config.ilanguage;
|
param = g_Config.ilanguage;
|
||||||
break;
|
break;
|
||||||
case PSP_SYSTEMPARAM_ID_INT_BUTTON_PREFERENCE:
|
case PSP_SYSTEMPARAM_ID_INT_BUTTON_PREFERENCE:
|
||||||
param = g_Config.bButtonPreference?PSP_SYSTEMPARAM_BUTTON_CROSS:PSP_SYSTEMPARAM_BUTTON_CIRCLE;
|
param = g_Config.iButtonPreference?PSP_SYSTEMPARAM_BUTTON_CROSS:PSP_SYSTEMPARAM_BUTTON_CIRCLE;
|
||||||
break;
|
break;
|
||||||
case PSP_SYSTEMPARAM_ID_INT_LOCK_PARENTAL_LEVEL:
|
case PSP_SYSTEMPARAM_ID_INT_LOCK_PARENTAL_LEVEL:
|
||||||
param = g_Config.iLockParentalLevel;
|
param = g_Config.iLockParentalLevel;
|
||||||
|
|
|
@ -369,14 +369,13 @@ void MediaEngine::updateSwsFormat(int videoPixelMode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MediaEngine::stepVideo(int videoPixelMode) {
|
bool MediaEngine::stepVideo(int videoPixelMode) {
|
||||||
|
// if video engine is broken, force to add timestamp
|
||||||
|
m_videopts += 3003;
|
||||||
|
#ifdef USE_FFMPEG
|
||||||
if (!m_pFormatCtx)
|
if (!m_pFormatCtx)
|
||||||
return false;
|
return false;
|
||||||
if (!m_pCodecCtx)
|
if (!m_pCodecCtx)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// if video engine is broken, force to add timestamp
|
|
||||||
m_videopts += 3003;
|
|
||||||
#ifdef USE_FFMPEG
|
|
||||||
updateSwsFormat(videoPixelMode);
|
updateSwsFormat(videoPixelMode);
|
||||||
// TODO: Technically we could set this to frameWidth instead of m_desWidth for better perf.
|
// TODO: Technically we could set this to frameWidth instead of m_desWidth for better perf.
|
||||||
// Update the linesize for the new format too. We started with the largest size, so it should fit.
|
// Update the linesize for the new format too. We started with the largest size, so it should fit.
|
||||||
|
@ -525,7 +524,7 @@ int MediaEngine::writeVideoImage(u8* buffer, int frameWidth, int videoPixelMode)
|
||||||
}
|
}
|
||||||
return videoImageSize;
|
return videoImageSize;
|
||||||
#endif // USE_FFMPEG
|
#endif // USE_FFMPEG
|
||||||
return true;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MediaEngine::writeVideoImageWithRange(u8* buffer, int frameWidth, int videoPixelMode,
|
int MediaEngine::writeVideoImageWithRange(u8* buffer, int frameWidth, int videoPixelMode,
|
||||||
|
@ -590,7 +589,7 @@ int MediaEngine::writeVideoImageWithRange(u8* buffer, int frameWidth, int videoP
|
||||||
}
|
}
|
||||||
return videoImageSize;
|
return videoImageSize;
|
||||||
#endif // USE_FFMPEG
|
#endif // USE_FFMPEG
|
||||||
return true;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isHeader(u8* audioStream, int offset)
|
static bool isHeader(u8* audioStream, int offset)
|
||||||
|
|
|
@ -211,7 +211,7 @@ namespace Reporting
|
||||||
postdata.Add("pixel_height", PSP_CoreParameter().pixelHeight);
|
postdata.Add("pixel_height", PSP_CoreParameter().pixelHeight);
|
||||||
postdata.Add("ticks", (const uint64_t)CoreTiming::GetTicks());
|
postdata.Add("ticks", (const uint64_t)CoreTiming::GetTicks());
|
||||||
|
|
||||||
if (g_Config.bShowFPSCounter)
|
if (g_Config.iShowFPSCounter)
|
||||||
{
|
{
|
||||||
float vps, fps;
|
float vps, fps;
|
||||||
__DisplayGetAveragedFPS(&vps, &fps);
|
__DisplayGetAveragedFPS(&vps, &fps);
|
||||||
|
|
|
@ -32,6 +32,7 @@ enum GlobalUIState {
|
||||||
UISTATE_MENU,
|
UISTATE_MENU,
|
||||||
UISTATE_PAUSEMENU,
|
UISTATE_PAUSEMENU,
|
||||||
UISTATE_INGAME,
|
UISTATE_INGAME,
|
||||||
|
UISTATE_EXIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -956,9 +956,8 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GE_CMD_TEXLEVEL:
|
case GE_CMD_TEXLEVEL:
|
||||||
if (data == 1)
|
// We support 000001, it means fixed at mip level 0. Don't report 0 as it's normal.
|
||||||
WARN_LOG_REPORT_ONCE(texLevel1, G3D, "Unsupported texture level bias settings: %06x", data)
|
if (data != 1 && data != 0)
|
||||||
else if (data != 0)
|
|
||||||
WARN_LOG_REPORT_ONCE(texLevel2, G3D, "Unsupported texture level bias settings: %06x", data);
|
WARN_LOG_REPORT_ONCE(texLevel2, G3D, "Unsupported texture level bias settings: %06x", data);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -350,16 +350,35 @@ void FramebufferManager::SetRenderFrameBuffer() {
|
||||||
int drawing_width, drawing_height;
|
int drawing_width, drawing_height;
|
||||||
GuessDrawingSize(drawing_width, drawing_height);
|
GuessDrawingSize(drawing_width, drawing_height);
|
||||||
|
|
||||||
// Find a matching framebuffer
|
int buffer_width = drawing_width;
|
||||||
|
int buffer_height = drawing_height;
|
||||||
|
|
||||||
|
// Find a matching framebuffer, same size or bigger
|
||||||
VirtualFramebuffer *vfb = 0;
|
VirtualFramebuffer *vfb = 0;
|
||||||
for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter) {
|
for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter) {
|
||||||
VirtualFramebuffer *v = *iter;
|
VirtualFramebuffer *v = *iter;
|
||||||
if (MaskedEqual(v->fb_address, fb_address) && v->width == drawing_width && v->height == drawing_height && v->format == fmt) {
|
if (MaskedEqual(v->fb_address, fb_address) && v->format == fmt) {
|
||||||
// Let's not be so picky for now. Let's say this is the one.
|
// Okay, let's check the sizes. If the new one is bigger than the old one, recreate.
|
||||||
vfb = v;
|
// If the opposite, just use it and hope that the game sets scissors accordingly.
|
||||||
// Update fb stride in case it changed
|
if (v->bufferWidth >= drawing_width && v->bufferHeight >= drawing_height) {
|
||||||
vfb->fb_stride = fb_stride;
|
// Let's not be so picky for now. Let's say this is the one.
|
||||||
break;
|
vfb = v;
|
||||||
|
// Update fb stride in case it changed
|
||||||
|
vfb->fb_stride = fb_stride;
|
||||||
|
// Just hack the width/height and we should be fine. also hack renderwidth/renderheight?
|
||||||
|
v->width = drawing_width;
|
||||||
|
v->height = drawing_height;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
INFO_LOG(HLE, "Embiggening framebuffer (%i, %i) -> (%i, %i)", (int)v->width, (int)v->height, drawing_width, drawing_height);
|
||||||
|
// drawing_width or drawing_height is bigger. Let's recreate with the max.
|
||||||
|
// To do this right we should copy the data over too, but meh.
|
||||||
|
buffer_width = std::max((int)v->width, drawing_width);
|
||||||
|
buffer_height = std::max((int)v->height, drawing_height);
|
||||||
|
delete v;
|
||||||
|
vfbs_.erase(iter);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,6 +398,8 @@ void FramebufferManager::SetRenderFrameBuffer() {
|
||||||
vfb->height = drawing_height;
|
vfb->height = drawing_height;
|
||||||
vfb->renderWidth = (u16)(drawing_width * renderWidthFactor);
|
vfb->renderWidth = (u16)(drawing_width * renderWidthFactor);
|
||||||
vfb->renderHeight = (u16)(drawing_height * renderHeightFactor);
|
vfb->renderHeight = (u16)(drawing_height * renderHeightFactor);
|
||||||
|
vfb->bufferWidth = buffer_width;
|
||||||
|
vfb->bufferHeight = buffer_height;
|
||||||
vfb->format = fmt;
|
vfb->format = fmt;
|
||||||
vfb->usageFlags = FB_USAGE_RENDERTARGET;
|
vfb->usageFlags = FB_USAGE_RENDERTARGET;
|
||||||
vfb->dirtyAfterDisplay = true;
|
vfb->dirtyAfterDisplay = true;
|
||||||
|
|
|
@ -54,10 +54,16 @@ struct VirtualFramebuffer {
|
||||||
int z_stride;
|
int z_stride;
|
||||||
|
|
||||||
// There's also a top left of the drawing region, but meh...
|
// There's also a top left of the drawing region, but meh...
|
||||||
|
|
||||||
|
// width/height: The detected size of the current framebuffer.
|
||||||
u16 width;
|
u16 width;
|
||||||
u16 height;
|
u16 height;
|
||||||
|
// renderWidth/renderHeight: The actual size we render at. May be scaled to render at higher resolutions.
|
||||||
u16 renderWidth;
|
u16 renderWidth;
|
||||||
u16 renderHeight;
|
u16 renderHeight;
|
||||||
|
// bufferWidth/bufferHeight: The actual (but non scaled) size of the buffer we render to. May only be bigger than width/height.
|
||||||
|
u16 bufferWidth;
|
||||||
|
u16 bufferHeight;
|
||||||
|
|
||||||
u16 usageFlags;
|
u16 usageFlags;
|
||||||
|
|
||||||
|
|
|
@ -390,7 +390,22 @@ void LinkedShader::updateUniforms() {
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
if (dirtyUniforms & (DIRTY_LIGHT0 << i)) {
|
if (dirtyUniforms & (DIRTY_LIGHT0 << i)) {
|
||||||
if (u_lightpos[i] != -1) glUniform3fv(u_lightpos[i], 1, gstate_c.lightpos[i]);
|
GELightType type = (GELightType)((gstate.ltype[i] >> 8) & 3);
|
||||||
|
if (type == GE_LIGHTTYPE_DIRECTIONAL) {
|
||||||
|
// Prenormalize
|
||||||
|
float x = gstate_c.lightpos[i][0];
|
||||||
|
float y = gstate_c.lightpos[i][1];
|
||||||
|
float z = gstate_c.lightpos[i][2];
|
||||||
|
float len = sqrtf(x*x+y*y+z*z);
|
||||||
|
if (len == 0.0f)
|
||||||
|
len = 1.0f;
|
||||||
|
else
|
||||||
|
len = 1.0f / len;
|
||||||
|
float vec[3] = { x / len, y / len, z / len };
|
||||||
|
if (u_lightpos[i] != -1) glUniform3fv(u_lightpos[i], 1, vec);
|
||||||
|
} else {
|
||||||
|
if (u_lightpos[i] != -1) glUniform3fv(u_lightpos[i], 1, gstate_c.lightpos[i]);
|
||||||
|
}
|
||||||
if (u_lightdir[i] != -1) glUniform3fv(u_lightdir[i], 1, gstate_c.lightdir[i]);
|
if (u_lightdir[i] != -1) glUniform3fv(u_lightdir[i], 1, gstate_c.lightdir[i]);
|
||||||
if (u_lightatt[i] != -1) glUniform3fv(u_lightatt[i], 1, gstate_c.lightatt[i]);
|
if (u_lightatt[i] != -1) glUniform3fv(u_lightatt[i], 1, gstate_c.lightatt[i]);
|
||||||
if (u_lightangle[i] != -1) glUniform1f(u_lightangle[i], gstate_c.lightangle[i]);
|
if (u_lightangle[i] != -1) glUniform1f(u_lightangle[i], gstate_c.lightangle[i]);
|
||||||
|
|
|
@ -265,8 +265,8 @@ void TransformDrawEngine::ApplyDrawState(int prim) {
|
||||||
if (g_Config.bBufferedRendering) {
|
if (g_Config.bBufferedRendering) {
|
||||||
renderX = 0;
|
renderX = 0;
|
||||||
renderY = 0;
|
renderY = 0;
|
||||||
renderWidth = framebufferManager_->GetRenderWidth();
|
renderWidth = framebufferManager_->GetRenderWidth();
|
||||||
renderHeight = framebufferManager_->GetRenderHeight();
|
renderHeight = framebufferManager_->GetRenderHeight();
|
||||||
renderWidthFactor = (float)renderWidth / framebufferManager_->GetTargetWidth();
|
renderWidthFactor = (float)renderWidth / framebufferManager_->GetTargetWidth();
|
||||||
renderHeightFactor = (float)renderHeight / framebufferManager_->GetTargetHeight();
|
renderHeightFactor = (float)renderHeight / framebufferManager_->GetTargetHeight();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -484,16 +484,6 @@ static const GLuint MagFiltGL[2] = {
|
||||||
GL_LINEAR
|
GL_LINEAR
|
||||||
};
|
};
|
||||||
|
|
||||||
// OpenGL ES 2.0 workaround. This SHOULD be available but is NOT in the headers in Android.
|
|
||||||
// Let's see if this hackery works.
|
|
||||||
#ifndef GL_TEXTURE_LOD_BIAS
|
|
||||||
#define GL_TEXTURE_LOD_BIAS 0x8501
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GL_TEXTURE_MAX_LOD
|
|
||||||
#define GL_TEXTURE_MAX_LOD 0x813B
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// This should not have to be done per texture! OpenGL is silly yo
|
// This should not have to be done per texture! OpenGL is silly yo
|
||||||
// TODO: Dirty-check this against the current texture.
|
// TODO: Dirty-check this against the current texture.
|
||||||
void TextureCache::UpdateSamplingParams(TexCacheEntry &entry, bool force) {
|
void TextureCache::UpdateSamplingParams(TexCacheEntry &entry, bool force) {
|
||||||
|
@ -502,6 +492,8 @@ void TextureCache::UpdateSamplingParams(TexCacheEntry &entry, bool force) {
|
||||||
bool sClamp = gstate.texwrap & 1;
|
bool sClamp = gstate.texwrap & 1;
|
||||||
bool tClamp = (gstate.texwrap>>8) & 1;
|
bool tClamp = (gstate.texwrap>>8) & 1;
|
||||||
|
|
||||||
|
bool noMip = (gstate.texlevel & 0xFFFFFF) == 0x000001; // Fix texlevel at 0
|
||||||
|
|
||||||
if (entry.maxLevel == 0) {
|
if (entry.maxLevel == 0) {
|
||||||
// Enforce no mip filtering, for safety.
|
// Enforce no mip filtering, for safety.
|
||||||
minFilt &= 1; // no mipmaps yet
|
minFilt &= 1; // no mipmaps yet
|
||||||
|
@ -509,7 +501,9 @@ void TextureCache::UpdateSamplingParams(TexCacheEntry &entry, bool force) {
|
||||||
// TODO: Is this a signed value? Which direction?
|
// TODO: Is this a signed value? Which direction?
|
||||||
float lodBias = 0.0; // -(float)((gstate.texlevel >> 16) & 0xFF) / 16.0f;
|
float lodBias = 0.0; // -(float)((gstate.texlevel >> 16) & 0xFF) / 16.0f;
|
||||||
if (force || entry.lodBias != lodBias) {
|
if (force || entry.lodBias != lodBias) {
|
||||||
|
#ifndef USING_GLES2
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, lodBias);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, lodBias);
|
||||||
|
#endif
|
||||||
entry.lodBias = lodBias;
|
entry.lodBias = lodBias;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -519,7 +513,7 @@ void TextureCache::UpdateSamplingParams(TexCacheEntry &entry, bool force) {
|
||||||
minFilt |= 1;
|
minFilt |= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_Config.bMipMap) {
|
if (!g_Config.bMipMap || noMip) {
|
||||||
magFilt &= 1;
|
magFilt &= 1;
|
||||||
minFilt &= 1;
|
minFilt &= 1;
|
||||||
}
|
}
|
||||||
|
@ -1117,8 +1111,8 @@ void TextureCache::SetTexture() {
|
||||||
LoadTextureLevel(*entry, i, replaceImages);
|
LoadTextureLevel(*entry, i, replaceImages);
|
||||||
}
|
}
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, maxLevel);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, maxLevel);
|
||||||
#endif
|
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (float)maxLevel);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (float)maxLevel);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
LoadTextureLevel(*entry, 0, replaceImages);
|
LoadTextureLevel(*entry, 0, replaceImages);
|
||||||
#ifndef USING_GLES2
|
#ifndef USING_GLES2
|
||||||
|
|
|
@ -429,9 +429,10 @@ void GenerateVertexShader(int prim, char *buffer, bool useHWTransform) {
|
||||||
GELightComputation comp = (GELightComputation)(gstate.ltype[i] & 3);
|
GELightComputation comp = (GELightComputation)(gstate.ltype[i] & 3);
|
||||||
GELightType type = (GELightType)((gstate.ltype[i] >> 8) & 3);
|
GELightType type = (GELightType)((gstate.ltype[i] >> 8) & 3);
|
||||||
|
|
||||||
if (type == GE_LIGHTTYPE_DIRECTIONAL)
|
if (type == GE_LIGHTTYPE_DIRECTIONAL) {
|
||||||
WRITE(p, " toLight = normalize(u_lightpos%i);\n", i);
|
// We prenormalize light positions for directional lights.
|
||||||
else {
|
WRITE(p, " toLight = u_lightpos%i;\n", i);
|
||||||
|
} else {
|
||||||
WRITE(p, " toLight = u_lightpos%i - worldpos;\n", i);
|
WRITE(p, " toLight = u_lightpos%i - worldpos;\n", i);
|
||||||
WRITE(p, " distance = length(toLight);\n");
|
WRITE(p, " distance = length(toLight);\n");
|
||||||
WRITE(p, " toLight /= distance;\n");
|
WRITE(p, " toLight /= distance;\n");
|
||||||
|
|
|
@ -337,11 +337,18 @@ void EmuScreen::render() {
|
||||||
ui_draw2d.SetFontScale(1.0f, 1.0f);
|
ui_draw2d.SetFontScale(1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_Config.bShowFPSCounter) {
|
if (g_Config.iShowFPSCounter) {
|
||||||
float vps, fps;
|
float vps, fps;
|
||||||
__DisplayGetFPS(&vps, &fps);
|
__DisplayGetFPS(&vps, &fps);
|
||||||
char fpsbuf[256];
|
char fpsbuf[256];
|
||||||
sprintf(fpsbuf, "VPS: %0.1f\nFPS: %0.1f", vps, fps);
|
switch (g_Config.iShowFPSCounter) {
|
||||||
|
case 1:
|
||||||
|
sprintf(fpsbuf, "VPS: %0.1f", vps); break;
|
||||||
|
case 2:
|
||||||
|
sprintf(fpsbuf, "FPS: %0.1f", fps); break;
|
||||||
|
case 3:
|
||||||
|
sprintf(fpsbuf, "VPS: %0.1f\nFPS: %0.1f", vps, fps); break;
|
||||||
|
}
|
||||||
ui_draw2d.DrawText(UBUNTU24, fpsbuf, dp_xres - 8, 12, 0xc0000000, ALIGN_TOPRIGHT);
|
ui_draw2d.DrawText(UBUNTU24, fpsbuf, dp_xres - 8, 12, 0xc0000000, ALIGN_TOPRIGHT);
|
||||||
ui_draw2d.DrawText(UBUNTU24, fpsbuf, dp_xres - 10, 10, 0xFF3fFF3f, ALIGN_TOPRIGHT);
|
ui_draw2d.DrawText(UBUNTU24, fpsbuf, dp_xres - 10, 10, 0xFF3fFF3f, ALIGN_TOPRIGHT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ TouchStick leftStick(&ui_atlas, I_STICKBG, I_STICK, 0);
|
||||||
|
|
||||||
void LayoutGamepad(int w, int h)
|
void LayoutGamepad(int w, int h)
|
||||||
{
|
{
|
||||||
float controlScale = g_Config.bLargeControls ? 1.6 : 1.15;
|
float controlScale = g_Config.bLargeControls ? g_Config.fButtonScale : 1.15;
|
||||||
|
|
||||||
const int button_spacing = 50 * controlScale;
|
const int button_spacing = 50 * controlScale;
|
||||||
const int arrow_spacing = 40 * controlScale;
|
const int arrow_spacing = 40 * controlScale;
|
||||||
|
|
|
@ -466,8 +466,6 @@ void PauseScreen::render() {
|
||||||
if (gpu)
|
if (gpu)
|
||||||
gpu->Resized();
|
gpu->Resized();
|
||||||
}
|
}
|
||||||
UICheckBox(GEN_ID, x, y += stride, ss->T("Show FPS"), ALIGN_TOPLEFT, &g_Config.bShowFPSCounter);
|
|
||||||
|
|
||||||
bool enableFrameSkip = g_Config.iFrameSkip != 0;
|
bool enableFrameSkip = g_Config.iFrameSkip != 0;
|
||||||
UICheckBox(GEN_ID, x, y += stride , gs->T("Frame Skipping"), ALIGN_TOPLEFT, &enableFrameSkip);
|
UICheckBox(GEN_ID, x, y += stride , gs->T("Frame Skipping"), ALIGN_TOPLEFT, &enableFrameSkip);
|
||||||
if (enableFrameSkip) {
|
if (enableFrameSkip) {
|
||||||
|
@ -490,16 +488,52 @@ void PauseScreen::render() {
|
||||||
} else
|
} else
|
||||||
g_Config.iFrameSkip = 0;
|
g_Config.iFrameSkip = 0;
|
||||||
|
|
||||||
// TODO: Add UI for more than one slot.
|
UICheckBox(GEN_ID, x, y += stride, gs->T("Linear Filtering"), ALIGN_TOPLEFT, &g_Config.bLinearFiltering);
|
||||||
HLinear hlinear2(x, y += 70, 20);
|
ui_draw2d.DrawText(UBUNTU24, gs->T("Save State :"), 30, y += 40, 0xFFFFFFFF, ALIGN_LEFT);
|
||||||
if (UIButton(GEN_ID, hlinear2, LARGE_BUTTON_WIDTH, 0, i->T("Save State"), ALIGN_LEFT)) {
|
HLinear hlinear4(x + 180 , y , 10);
|
||||||
|
if (UIButton(GEN_ID, hlinear4, 60, 0, "1", ALIGN_LEFT)) {
|
||||||
SaveState::SaveSlot(0, 0, 0);
|
SaveState::SaveSlot(0, 0, 0);
|
||||||
screenManager()->finishDialog(this, DR_CANCEL);
|
screenManager()->finishDialog(this, DR_CANCEL);
|
||||||
}
|
}
|
||||||
if (UIButton(GEN_ID, hlinear2, LARGE_BUTTON_WIDTH, 0, i->T("Load State"), ALIGN_LEFT)) {
|
if (UIButton(GEN_ID, hlinear4, 60, 0, "2", ALIGN_LEFT)) {
|
||||||
|
SaveState::SaveSlot(1, 0, 0);
|
||||||
|
screenManager()->finishDialog(this, DR_CANCEL);
|
||||||
|
}
|
||||||
|
if (UIButton(GEN_ID, hlinear4, 60, 0, "3", ALIGN_LEFT)) {
|
||||||
|
SaveState::SaveSlot(2, 0, 0);
|
||||||
|
screenManager()->finishDialog(this, DR_CANCEL);
|
||||||
|
}
|
||||||
|
if (UIButton(GEN_ID, hlinear4, 60, 0, "4", ALIGN_LEFT)) {
|
||||||
|
SaveState::SaveSlot(3, 0, 0);
|
||||||
|
screenManager()->finishDialog(this, DR_CANCEL);
|
||||||
|
}
|
||||||
|
if (UIButton(GEN_ID, hlinear4, 60, 0, "5", ALIGN_LEFT)) {
|
||||||
|
SaveState::SaveSlot(4, 0, 0);
|
||||||
|
screenManager()->finishDialog(this, DR_CANCEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_draw2d.DrawText(UBUNTU24, gs->T("Load State :"), 30, y += 60, 0xFFFFFFFF, ALIGN_LEFT);
|
||||||
|
HLinear hlinear3(x + 180 , y + 10 , 10);
|
||||||
|
if (UIButton(GEN_ID, hlinear3, 60, 0, "1", ALIGN_LEFT)) {
|
||||||
SaveState::LoadSlot(0, 0, 0);
|
SaveState::LoadSlot(0, 0, 0);
|
||||||
screenManager()->finishDialog(this, DR_CANCEL);
|
screenManager()->finishDialog(this, DR_CANCEL);
|
||||||
}
|
}
|
||||||
|
if (UIButton(GEN_ID, hlinear3, 60, 0, "2", ALIGN_LEFT)) {
|
||||||
|
SaveState::LoadSlot(1, 0, 0);
|
||||||
|
screenManager()->finishDialog(this, DR_CANCEL);
|
||||||
|
}
|
||||||
|
if (UIButton(GEN_ID, hlinear3, 60, 0, "3", ALIGN_LEFT)) {
|
||||||
|
SaveState::LoadSlot(2, 0, 0);
|
||||||
|
screenManager()->finishDialog(this, DR_CANCEL);
|
||||||
|
}
|
||||||
|
if (UIButton(GEN_ID, hlinear3, 60, 0, "4", ALIGN_LEFT)) {
|
||||||
|
SaveState::LoadSlot(3, 0, 0);
|
||||||
|
screenManager()->finishDialog(this, DR_CANCEL);
|
||||||
|
}
|
||||||
|
if (UIButton(GEN_ID, hlinear3, 60, 0, "5", ALIGN_LEFT)) {
|
||||||
|
SaveState::LoadSlot(4, 0, 0);
|
||||||
|
screenManager()->finishDialog(this, DR_CANCEL);
|
||||||
|
}
|
||||||
|
|
||||||
DrawWatermark();
|
DrawWatermark();
|
||||||
UIEnd();
|
UIEnd();
|
||||||
|
@ -666,27 +700,31 @@ void DeveloperScreen::render() {
|
||||||
screenManager()->finishDialog(this, DR_OK);
|
screenManager()->finishDialog(this, DR_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UIButton(GEN_ID, vlinear, w, 0, d->T("Load language ini"), ALIGN_LEFT)) {
|
if (UIButton(GEN_ID, vlinear, LARGE_BUTTON_WIDTH + 80, 0, d->T("Load language ini"), ALIGN_LEFT)) {
|
||||||
i18nrepo.LoadIni(g_Config.languageIni);
|
i18nrepo.LoadIni(g_Config.languageIni);
|
||||||
// After this, g and s are no longer valid. Need to reload them.
|
// After this, g and s are no longer valid. Need to reload them.
|
||||||
g = GetI18NCategory("General");
|
g = GetI18NCategory("General");
|
||||||
d = GetI18NCategory("Developer");
|
d = GetI18NCategory("Developer");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UIButton(GEN_ID, vlinear, w, 0, d->T("Save language ini"), ALIGN_LEFT)) {
|
if (UIButton(GEN_ID, vlinear, LARGE_BUTTON_WIDTH + 80, 0, d->T("Save language ini"), ALIGN_LEFT)) {
|
||||||
i18nrepo.SaveIni(g_Config.languageIni);
|
i18nrepo.SaveIni(g_Config.languageIni);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UIButton(GEN_ID, vlinear, w, 0, d->T("Run CPU tests"), ALIGN_LEFT)) {
|
if (UIButton(GEN_ID, vlinear, LARGE_BUTTON_WIDTH + 80, 0, d->T("Run CPU Tests"), ALIGN_LEFT)) {
|
||||||
// TODO: Run tests
|
// TODO: Run tests
|
||||||
RunTests();
|
RunTests();
|
||||||
// screenManager()->push(new EmuScreen())
|
// screenManager()->push(new EmuScreen())
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UIButton(GEN_ID, vlinear, w, 0, d->T("Dump frame to log"), ALIGN_LEFT)) {
|
if (UIButton(GEN_ID, vlinear, LARGE_BUTTON_WIDTH + 80, 0, d->T("Dump next frame"), ALIGN_LEFT)) {
|
||||||
gpu->DumpNextFrame();
|
gpu->DumpNextFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (UIButton(GEN_ID, vlinear, LARGE_BUTTON_WIDTH + 80, 0, d->T("Cleanup Recents"), ALIGN_LEFT)) {
|
||||||
|
g_Config.recentIsos.clear();
|
||||||
|
}
|
||||||
|
|
||||||
UIEnd();
|
UIEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -908,7 +946,35 @@ void GraphicsScreenP3::render() {
|
||||||
int y = 35;
|
int y = 35;
|
||||||
int stride = 40;
|
int stride = 40;
|
||||||
int columnw = 400;
|
int columnw = 400;
|
||||||
|
|
||||||
|
bool ShowCounter = g_Config.iShowFPSCounter > 0;
|
||||||
|
UICheckBox(GEN_ID, x, y += stride, gs->T("Show VPS/FPS"), ALIGN_TOPLEFT, &ShowCounter);
|
||||||
|
if (ShowCounter) {
|
||||||
|
if (g_Config.iShowFPSCounter <= 0)
|
||||||
|
g_Config.iShowFPSCounter = 1;
|
||||||
|
|
||||||
|
char counter[256];
|
||||||
|
std::string type;
|
||||||
|
|
||||||
|
switch (g_Config.iShowFPSCounter) {
|
||||||
|
case 1: type = "VPS";break;
|
||||||
|
case 2: type = "FPS";break;
|
||||||
|
case 3: type = "Both";break;
|
||||||
|
}
|
||||||
|
sprintf(counter, "%s %s", gs->T("Format :"), type.c_str());
|
||||||
|
ui_draw2d.DrawText(UBUNTU24, counter, x + 60, y += stride , 0xFFFFFFFF, ALIGN_LEFT);
|
||||||
|
HLinear hlinear1(x + 250, y, 20);
|
||||||
|
if (UIButton(GEN_ID, hlinear1, 80, 0, gs->T("VPS"), ALIGN_LEFT))
|
||||||
|
g_Config.iShowFPSCounter = 1;
|
||||||
|
if (UIButton(GEN_ID, hlinear1, 80, 0, gs->T("FPS"), ALIGN_LEFT))
|
||||||
|
g_Config.iShowFPSCounter = 2;
|
||||||
|
if (UIButton(GEN_ID, hlinear1, 90, 0, gs->T("Both"), ALIGN_LEFT))
|
||||||
|
g_Config.iShowFPSCounter = 3;
|
||||||
|
|
||||||
|
y += 20;
|
||||||
|
} else
|
||||||
|
g_Config.iShowFPSCounter = 0;
|
||||||
|
|
||||||
bool FpsLimit = g_Config.iFpsLimit != 0;
|
bool FpsLimit = g_Config.iFpsLimit != 0;
|
||||||
UICheckBox(GEN_ID, x, y += stride, gs->T("FPS Limit"), ALIGN_TOPLEFT, &FpsLimit);
|
UICheckBox(GEN_ID, x, y += stride, gs->T("FPS Limit"), ALIGN_TOPLEFT, &FpsLimit);
|
||||||
if (FpsLimit) {
|
if (FpsLimit) {
|
||||||
|
@ -976,7 +1042,7 @@ void LanguageScreen::render() {
|
||||||
I18NCategory *g = GetI18NCategory("General");
|
I18NCategory *g = GetI18NCategory("General");
|
||||||
I18NCategory *l = GetI18NCategory("Language");
|
I18NCategory *l = GetI18NCategory("Language");
|
||||||
|
|
||||||
bool small = dp_xres < 720;
|
bool small = dp_xres < 790;
|
||||||
|
|
||||||
if (!small) {
|
if (!small) {
|
||||||
ui_draw2d.SetFontScale(1.5f, 1.5f);
|
ui_draw2d.SetFontScale(1.5f, 1.5f);
|
||||||
|
@ -999,6 +1065,12 @@ void LanguageScreen::render() {
|
||||||
|
|
||||||
|
|
||||||
for (size_t i = 0; i < langs_.size(); i++) {
|
for (size_t i = 0; i < langs_.size(); i++) {
|
||||||
|
// Skip README
|
||||||
|
if (langs_[i].name.find("README") != std::string::npos) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string code;
|
std::string code;
|
||||||
size_t dot = langs_[i].name.find('.');
|
size_t dot = langs_[i].name.find('.');
|
||||||
if (dot != std::string::npos)
|
if (dot != std::string::npos)
|
||||||
|
@ -1022,6 +1094,7 @@ void LanguageScreen::render() {
|
||||||
langValuesMapping["zh_CN"] = std::make_pair("简体中文", PSP_SYSTEMPARAM_LANGUAGE_CHINESE_SIMPLIFIED);
|
langValuesMapping["zh_CN"] = std::make_pair("简体中文", PSP_SYSTEMPARAM_LANGUAGE_CHINESE_SIMPLIFIED);
|
||||||
|
|
||||||
//langValuesMapping["ar_AE"] = std::make_pair("العربية", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH);
|
//langValuesMapping["ar_AE"] = std::make_pair("العربية", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH);
|
||||||
|
langValuesMapping["az_AZ"] = std::make_pair("Azeri", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH);
|
||||||
langValuesMapping["ca_ES"] = std::make_pair("Català", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH);
|
langValuesMapping["ca_ES"] = std::make_pair("Català", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH);
|
||||||
langValuesMapping["gr_EL"] = std::make_pair("ελληνικά", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH);
|
langValuesMapping["gr_EL"] = std::make_pair("ελληνικά", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH);
|
||||||
langValuesMapping["he_IL"] = std::make_pair("עברית", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH);
|
langValuesMapping["he_IL"] = std::make_pair("עברית", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH);
|
||||||
|
@ -1035,7 +1108,7 @@ void LanguageScreen::render() {
|
||||||
|
|
||||||
if (!code.empty()) {
|
if (!code.empty()) {
|
||||||
if(langValuesMapping.find(code) == langValuesMapping.end()) {
|
if(langValuesMapping.find(code) == langValuesMapping.end()) {
|
||||||
//No title found, show locale code
|
// No title found, show locale code
|
||||||
buttonTitle = code;
|
buttonTitle = code;
|
||||||
} else {
|
} else {
|
||||||
buttonTitle = langValuesMapping[code].first;
|
buttonTitle = langValuesMapping[code].first;
|
||||||
|
@ -1102,18 +1175,84 @@ void SystemScreen::render() {
|
||||||
#endif
|
#endif
|
||||||
if (g_Config.bJit)
|
if (g_Config.bJit)
|
||||||
UICheckBox(GEN_ID, x, y += stride, s->T("Fast Memory", "Fast Memory (unstable)"), ALIGN_TOPLEFT, &g_Config.bFastMemory);
|
UICheckBox(GEN_ID, x, y += stride, s->T("Fast Memory", "Fast Memory (unstable)"), ALIGN_TOPLEFT, &g_Config.bFastMemory);
|
||||||
UICheckBox(GEN_ID, x, y += stride, s->T("Show FPS"), ALIGN_TOPLEFT, &g_Config.bShowFPSCounter);
|
|
||||||
UICheckBox(GEN_ID, x, y += stride, s->T("Encrypt Save"), ALIGN_TOPLEFT, &g_Config.bEncryptSave);
|
UICheckBox(GEN_ID, x, y += stride, s->T("Daylight Savings"), ALIGN_TOPLEFT, &g_Config.bDayLightSavings);
|
||||||
UICheckBox(GEN_ID, x, y += stride, s->T("Use Button X to Confirm"), ALIGN_TOPLEFT, &g_Config.bButtonPreference);
|
UICheckBox(GEN_ID, x, y += stride, s->T("Button Preference"), ALIGN_TOPLEFT, &g_Config.bButtonPreference);
|
||||||
bool tf = g_Config.itimeformat == 1;
|
if (g_Config.bButtonPreference) {
|
||||||
if (UICheckBox(GEN_ID, x, y += stride, s->T("12HR Time Format"), ALIGN_TOPLEFT, &tf)) {
|
char button[256];
|
||||||
g_Config.itimeformat = tf ? 1 : 0;
|
std::string type;
|
||||||
|
switch (g_Config.iButtonPreference) {
|
||||||
|
case 0: type = "O to Enter";break;
|
||||||
|
case 1: type = "X to Enter";break;
|
||||||
|
}
|
||||||
|
sprintf(button, "%s %s", s->T("Type :"), type.c_str());
|
||||||
|
ui_draw2d.DrawText(UBUNTU24, button, x + 60, y += stride , 0xFFFFFFFF, ALIGN_LEFT);
|
||||||
|
HLinear hlinear1(x + 280, y, 20);
|
||||||
|
if (UIButton(GEN_ID, hlinear1, 90, 0, s->T("Use O"), ALIGN_LEFT))
|
||||||
|
g_Config.iButtonPreference = 0;
|
||||||
|
if (UIButton(GEN_ID, hlinear1, 90, 0, s->T("Use X"), ALIGN_LEFT))
|
||||||
|
g_Config.iButtonPreference = 1;
|
||||||
|
y += 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
bool time = g_Config.iTimeFormat > 0 ;
|
||||||
|
UICheckBox(GEN_ID, x, y += stride, s->T("Time Format"), ALIGN_TOPLEFT, &time);
|
||||||
|
if (time) {
|
||||||
|
if (g_Config.iTimeFormat <= 0)
|
||||||
|
g_Config.iTimeFormat = 1;
|
||||||
|
|
||||||
|
char button[256];
|
||||||
|
std::string type;
|
||||||
|
switch (g_Config.iTimeFormat) {
|
||||||
|
case 1: type = "12HR";break;
|
||||||
|
case 2: type = "24HR";break;
|
||||||
|
}
|
||||||
|
sprintf(button, "%s %s", s->T("Format :"), type.c_str());
|
||||||
|
ui_draw2d.DrawText(UBUNTU24, button, x + 60, y += stride , 0xFFFFFFFF, ALIGN_LEFT);
|
||||||
|
HLinear hlinear1(x + 280, y, 20);
|
||||||
|
if (UIButton(GEN_ID, hlinear1, 80, 0, s->T("12HR"), ALIGN_LEFT))
|
||||||
|
g_Config.iTimeFormat = 1;
|
||||||
|
if (UIButton(GEN_ID, hlinear1, 80, 0, s->T("24HR"), ALIGN_LEFT))
|
||||||
|
g_Config.iTimeFormat = 2;
|
||||||
|
y += 10;
|
||||||
|
} else
|
||||||
|
g_Config.iTimeFormat = 0 ;
|
||||||
|
|
||||||
|
bool date = g_Config.iDateFormat > 0;
|
||||||
|
UICheckBox(GEN_ID, x, y += stride, s->T("Date Format"), ALIGN_TOPLEFT, &date);
|
||||||
|
if (date) {
|
||||||
|
if (g_Config.iDateFormat <= 0)
|
||||||
|
g_Config.iDateFormat = 1;
|
||||||
|
char button[256];
|
||||||
|
std::string type;
|
||||||
|
switch (g_Config.iDateFormat) {
|
||||||
|
case 1: type = "YYYYMMDD";break;
|
||||||
|
case 2: type = "MMDDYYYY";break;
|
||||||
|
case 3: type = "DDMMYYYY";break;
|
||||||
|
}
|
||||||
|
sprintf(button, "%s %s", s->T("Format :"), type.c_str());
|
||||||
|
ui_draw2d.DrawText(UBUNTU24, button, x + 60, y += stride , 0xFFFFFFFF, ALIGN_LEFT);
|
||||||
|
HLinear hlinear1(x + 350, y, 10);
|
||||||
|
if (UIButton(GEN_ID, hlinear1, 70, 0, s->T("YMD"), ALIGN_LEFT))
|
||||||
|
g_Config.iDateFormat = 1;
|
||||||
|
if (UIButton(GEN_ID, hlinear1, 70, 0, s->T("MDY"), ALIGN_LEFT))
|
||||||
|
g_Config.iDateFormat = 2;
|
||||||
|
if (UIButton(GEN_ID, hlinear1, 70, 0, s->T("DMY"), ALIGN_LEFT))
|
||||||
|
g_Config.iDateFormat = 3;
|
||||||
|
y += 10;
|
||||||
|
} else
|
||||||
|
g_Config.iDateFormat = 0;
|
||||||
|
*/
|
||||||
|
|
||||||
UICheckBox(GEN_ID, x, y += stride, s->T("Enable Cheats"), ALIGN_TOPLEFT, &g_Config.bEnableCheats);
|
UICheckBox(GEN_ID, x, y += stride, s->T("Enable Cheats"), ALIGN_TOPLEFT, &g_Config.bEnableCheats);
|
||||||
HLinear hlinear2(x, y += stride + 10, 20);
|
if (g_Config.bEnableCheats) {
|
||||||
if (UIButton(GEN_ID, hlinear2, LARGE_BUTTON_WIDTH + 50, 0, s->T("Reload Cheats"), ALIGN_TOPLEFT)) {
|
HLinear hlinear1(x + 60, y += stride + 10, 20);
|
||||||
g_Config.bReloadCheats = true;
|
if (UIButton(GEN_ID, hlinear1, LARGE_BUTTON_WIDTH + 50, 0, s->T("Reload Cheats"), ALIGN_TOPLEFT))
|
||||||
|
g_Config.bReloadCheats = true;
|
||||||
|
y += 10;
|
||||||
}
|
}
|
||||||
|
HLinear hlinear2(x, y += stride + 10, 20);
|
||||||
if (UIButton(GEN_ID, hlinear2, LARGE_BUTTON_WIDTH, 0, s->T("Language"), ALIGN_TOPLEFT)) {
|
if (UIButton(GEN_ID, hlinear2, LARGE_BUTTON_WIDTH, 0, s->T("Language"), ALIGN_TOPLEFT)) {
|
||||||
screenManager()->push(new LanguageScreen());
|
screenManager()->push(new LanguageScreen());
|
||||||
}
|
}
|
||||||
|
@ -1143,17 +1282,47 @@ void ControlsScreen::render() {
|
||||||
int columnw = 440;
|
int columnw = 440;
|
||||||
|
|
||||||
UICheckBox(GEN_ID, x, y += stride, c->T("OnScreen", "On-Screen Touch Controls"), ALIGN_TOPLEFT, &g_Config.bShowTouchControls);
|
UICheckBox(GEN_ID, x, y += stride, c->T("OnScreen", "On-Screen Touch Controls"), ALIGN_TOPLEFT, &g_Config.bShowTouchControls);
|
||||||
|
UICheckBox(GEN_ID, x, y += stride, c->T("Show Analog Stick"), ALIGN_TOPLEFT, &g_Config.bShowAnalogStick);
|
||||||
|
UICheckBox(GEN_ID, x, y += stride, c->T("Tilt", "Tilt to Analog (horizontal)"), ALIGN_TOPLEFT, &g_Config.bAccelerometerToAnalogHoriz);
|
||||||
if (g_Config.bShowTouchControls) {
|
if (g_Config.bShowTouchControls) {
|
||||||
UICheckBox(GEN_ID, x, y += stride, c->T("Large Controls"), ALIGN_TOPLEFT, &g_Config.bLargeControls);
|
UICheckBox(GEN_ID, x, y += stride, c->T("Buttons Scaling"), ALIGN_TOPLEFT, &g_Config.bLargeControls);
|
||||||
UICheckBox(GEN_ID, x, y += stride, c->T("Show Analog Stick"), ALIGN_TOPLEFT, &g_Config.bShowAnalogStick);
|
if (g_Config.bLargeControls) {
|
||||||
|
char scale[256];
|
||||||
|
sprintf(scale, "%s %0.2f", c->T("Scale :"), g_Config.fButtonScale);
|
||||||
|
ui_draw2d.DrawText(UBUNTU24, scale, x + 60, y += stride , 0xFFFFFFFF, ALIGN_LEFT);
|
||||||
|
HLinear hlinear1(x + 250, y, 20);
|
||||||
|
if (UIButton(GEN_ID, hlinear1, 80, 0, c->T("Auto"), ALIGN_LEFT))
|
||||||
|
g_Config.fButtonScale = 1.15;
|
||||||
|
if (UIButton(GEN_ID, hlinear1, 60, 0, c->T("-0.1"), ALIGN_LEFT))
|
||||||
|
if (g_Config.fButtonScale > 1.15)
|
||||||
|
g_Config.fButtonScale -= 0.1;
|
||||||
|
if (UIButton(GEN_ID, hlinear1, 60, 0, c->T("+0.1"), ALIGN_LEFT))
|
||||||
|
if (g_Config.fButtonScale < 2.05)
|
||||||
|
g_Config.fButtonScale += 0.1;
|
||||||
|
y += 20;
|
||||||
|
}
|
||||||
// This will be a slider in the new UI later
|
// This will be a slider in the new UI later
|
||||||
bool bTransparent = g_Config.iTouchButtonOpacity < 30;
|
bool bTransparent = g_Config.iTouchButtonOpacity < 65;
|
||||||
bool prev = bTransparent;
|
bool prev = bTransparent;
|
||||||
UICheckBox(GEN_ID, x, y += stride, c->T("Transparent Buttons"), ALIGN_TOPLEFT, &bTransparent);
|
UICheckBox(GEN_ID, x, y += stride, c->T("Buttons Opacity"), ALIGN_TOPLEFT, &bTransparent);
|
||||||
|
if (bTransparent) {
|
||||||
|
char opacity[256];
|
||||||
|
sprintf(opacity, "%s %d", c->T("Opacity :"), g_Config.iTouchButtonOpacity);
|
||||||
|
ui_draw2d.DrawText(UBUNTU24, opacity, x + 60, y += stride , 0xFFFFFFFF, ALIGN_LEFT);
|
||||||
|
HLinear hlinear1(x + 250, y, 20);
|
||||||
|
if (UIButton(GEN_ID, hlinear1, 80, 0, c->T("Auto"), ALIGN_LEFT))
|
||||||
|
g_Config.iTouchButtonOpacity = 15;
|
||||||
|
if (UIButton(GEN_ID, hlinear1, 40, 0, c->T("-5"), ALIGN_LEFT))
|
||||||
|
if (g_Config.iTouchButtonOpacity > 15)
|
||||||
|
g_Config.iTouchButtonOpacity -= 5;
|
||||||
|
if (UIButton(GEN_ID, hlinear1, 40, 0, c->T("+5"), ALIGN_LEFT))
|
||||||
|
if (g_Config.iTouchButtonOpacity < 65)
|
||||||
|
g_Config.iTouchButtonOpacity += 5;
|
||||||
|
y += 20;
|
||||||
|
}
|
||||||
if (bTransparent != prev)
|
if (bTransparent != prev)
|
||||||
g_Config.iTouchButtonOpacity = bTransparent ? 15 : 65;
|
g_Config.iTouchButtonOpacity = bTransparent ? 15 : 65;
|
||||||
}
|
}
|
||||||
UICheckBox(GEN_ID, x, y += stride, c->T("Tilt", "Tilt to Analog (horizontal)"), ALIGN_TOPLEFT, &g_Config.bAccelerometerToAnalogHoriz);
|
|
||||||
|
|
||||||
// Button to KeyMapping screen
|
// Button to KeyMapping screen
|
||||||
I18NCategory *keyI18N = GetI18NCategory("KeyMapping");
|
I18NCategory *keyI18N = GetI18NCategory("KeyMapping");
|
||||||
|
@ -1457,7 +1626,7 @@ static const char * credits[] = {
|
||||||
"PPSSPP is intended for educational purposes only.",
|
"PPSSPP is intended for educational purposes only.",
|
||||||
"",
|
"",
|
||||||
"Please make sure that you own the rights to any games",
|
"Please make sure that you own the rights to any games",
|
||||||
"you play by owning the UMD or buying the digital",
|
"you play by owning the UMD or by buying the digital",
|
||||||
"download from the PSN store on your real PSP.",
|
"download from the PSN store on your real PSP.",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -237,6 +237,15 @@ void NativeInit(int argc, const char *argv[],
|
||||||
g_Config.externalDirectory = external_directory;
|
g_Config.externalDirectory = external_directory;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
// On Android, create a PSP directory tree in the external_directory,
|
||||||
|
// to hopefully reduce confusion a bit.
|
||||||
|
ILOG("Creating %s", (g_Config.externalDirectory + "/PSP").c_str());
|
||||||
|
mkDir((g_Config.externalDirectory + "/PSP").c_str());
|
||||||
|
mkDir((g_Config.externalDirectory + "/PSP/SAVEDATA").c_str());
|
||||||
|
mkDir((g_Config.externalDirectory + "/PSP/GAME").c_str());
|
||||||
|
#endif
|
||||||
|
|
||||||
const char *fileToLog = 0;
|
const char *fileToLog = 0;
|
||||||
const char *stateToLoad = 0;
|
const char *stateToLoad = 0;
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ void PluginScreen::CreateViews() {
|
||||||
Margins textMargins(20,17);
|
Margins textMargins(20,17);
|
||||||
Margins buttonMargins(10,10);
|
Margins buttonMargins(10,10);
|
||||||
|
|
||||||
root_->Add(new TextView(UBUNTU24, "Atrac3+ Audio Decoding Support", ALIGN_HCENTER, 1.0f, new LinearLayoutParams(textMargins)));
|
root_->Add(new TextView(UBUNTU24, "Atrac3+ Audio Support", ALIGN_HCENTER, 1.5f, new LinearLayoutParams(textMargins)));
|
||||||
|
|
||||||
ViewGroup *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0));
|
ViewGroup *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0));
|
||||||
LinearLayout *scrollContents = new LinearLayout(ORIENT_VERTICAL);
|
LinearLayout *scrollContents = new LinearLayout(ORIENT_VERTICAL);
|
||||||
|
@ -66,11 +66,11 @@ void PluginScreen::CreateViews() {
|
||||||
|
|
||||||
const char *legalityNotice =
|
const char *legalityNotice =
|
||||||
p->T("Origins are dubious", "* Mai's Atrac3+ decoder is currently required\n"
|
p->T("Origins are dubious", "* Mai's Atrac3+ decoder is currently required\n"
|
||||||
"for audio in many games.\n"
|
"for background audio and voice in many games.\n"
|
||||||
"Please note that the origins of this code are dubious.\n"
|
"Please note that the origins of this code are dubious.\n"
|
||||||
"Choose More Information for more information.");
|
"Choose More Information for more information.");
|
||||||
|
|
||||||
scrollContents->Add(new TextView(0, legalityNotice, ALIGN_LEFT, 1.0f, new LinearLayoutParams(textMargins) ));
|
scrollContents->Add(new TextView(0, legalityNotice, ALIGN_LEFT, 0.65f, new LinearLayoutParams(textMargins) ));
|
||||||
|
|
||||||
progress_ = root_->Add(new ProgressBar());
|
progress_ = root_->Add(new ProgressBar());
|
||||||
progress_->SetVisibility(V_GONE);
|
progress_->SetVisibility(V_GONE);
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace DSound
|
||||||
pcmwf.wBitsPerSample = 16;
|
pcmwf.wBitsPerSample = 16;
|
||||||
|
|
||||||
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
|
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
|
||||||
dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_STICKYFOCUS; // //DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
|
dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS; // //DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
|
||||||
dsbdesc.dwBufferBytes = bufferSize = BUFSIZE; //FIX32(pcmwf.wf.nAvgBytesPerSec); //change to set buffer size
|
dsbdesc.dwBufferBytes = bufferSize = BUFSIZE; //FIX32(pcmwf.wf.nAvgBytesPerSec); //change to set buffer size
|
||||||
dsbdesc.lpwfxFormat = (WAVEFORMATEX *)&pcmwf;
|
dsbdesc.lpwfxFormat = (WAVEFORMATEX *)&pcmwf;
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "Core/HLE/sceCtrl.h"
|
#include "Core/HLE/sceCtrl.h"
|
||||||
#include "DinputDevice.h"
|
#include "DinputDevice.h"
|
||||||
#include "ControlMapping.h"
|
#include "ControlMapping.h"
|
||||||
|
@ -25,6 +27,11 @@
|
||||||
#include "Xinput.h"
|
#include "Xinput.h"
|
||||||
#pragma comment(lib,"dinput8.lib")
|
#pragma comment(lib,"dinput8.lib")
|
||||||
|
|
||||||
|
#ifdef min
|
||||||
|
#undef min
|
||||||
|
#undef max
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned int dinput_ctrl_map[] = {
|
unsigned int dinput_ctrl_map[] = {
|
||||||
11, PAD_BUTTON_MENU, // Open PauseScreen
|
11, PAD_BUTTON_MENU, // Open PauseScreen
|
||||||
10, PAD_BUTTON_BACK, // Toggle PauseScreen & Back Setting Page
|
10, PAD_BUTTON_BACK, // Toggle PauseScreen & Back Setting Page
|
||||||
|
@ -183,8 +190,15 @@ int DinputDevice::UpdateState(InputState &input_state)
|
||||||
|
|
||||||
if (analog)
|
if (analog)
|
||||||
{
|
{
|
||||||
input_state.pad_lstick_x += (float)js.lX / 10000.f;
|
float x = (float)js.lX / 10000.f;
|
||||||
input_state.pad_lstick_y += -((float)js.lY / 10000.f);
|
float y = -((float)js.lY / 10000.f);
|
||||||
|
|
||||||
|
// Expand and clamp. Hack to let us reach the corners on most pads.
|
||||||
|
x = std::min(1.0f, std::max(-1.0f, x * 1.2f));
|
||||||
|
y = std::min(1.0f, std::max(-1.0f, y * 1.2f));
|
||||||
|
|
||||||
|
input_state.pad_lstick_x += x;
|
||||||
|
input_state.pad_lstick_y += y;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u8 i = 0; i < sizeof(dinput_ctrl_map)/sizeof(dinput_ctrl_map[0]); i += 2)
|
for (u8 i = 0; i < sizeof(dinput_ctrl_map)/sizeof(dinput_ctrl_map[0]); i += 2)
|
||||||
|
|
|
@ -67,6 +67,7 @@ void EmuThread_Start()
|
||||||
|
|
||||||
void EmuThread_Stop()
|
void EmuThread_Stop()
|
||||||
{
|
{
|
||||||
|
globalUIState = UISTATE_EXIT;
|
||||||
// DSound_UpdateSound();
|
// DSound_UpdateSound();
|
||||||
Core_Stop();
|
Core_Stop();
|
||||||
Core_WaitInactive(800);
|
Core_WaitInactive(800);
|
||||||
|
@ -137,7 +138,14 @@ unsigned int WINAPI TheThread(void *)
|
||||||
|
|
||||||
Core_EnableStepping(FALSE);
|
Core_EnableStepping(FALSE);
|
||||||
|
|
||||||
Core_Run();
|
while (globalUIState != UISTATE_EXIT)
|
||||||
|
{
|
||||||
|
Core_Run();
|
||||||
|
|
||||||
|
// We're here again, so the game quit. Restart Core_Run() which controls the UI.
|
||||||
|
// This way they can load a new game.
|
||||||
|
Core_UpdateState(CORE_RUNNING);
|
||||||
|
}
|
||||||
|
|
||||||
shutdown:
|
shutdown:
|
||||||
_InterlockedExchange(&emuThreadReady, THREAD_SHUTDOWN);
|
_InterlockedExchange(&emuThreadReady, THREAD_SHUTDOWN);
|
||||||
|
|
|
@ -726,7 +726,7 @@ namespace MainWindow
|
||||||
g_Config.bVertexCache = !g_Config.bVertexCache;
|
g_Config.bVertexCache = !g_Config.bVertexCache;
|
||||||
break;
|
break;
|
||||||
case ID_OPTIONS_SHOWFPS:
|
case ID_OPTIONS_SHOWFPS:
|
||||||
g_Config.bShowFPSCounter = !g_Config.bShowFPSCounter;
|
g_Config.iShowFPSCounter = !g_Config.iShowFPSCounter;
|
||||||
break;
|
break;
|
||||||
case ID_OPTIONS_DISPLAYRAWFRAMEBUFFER:
|
case ID_OPTIONS_DISPLAYRAWFRAMEBUFFER:
|
||||||
g_Config.bDisplayFramebuffer = !g_Config.bDisplayFramebuffer;
|
g_Config.bDisplayFramebuffer = !g_Config.bDisplayFramebuffer;
|
||||||
|
@ -898,7 +898,7 @@ namespace MainWindow
|
||||||
CHECKITEM(ID_EMULATION_RUNONLOAD, g_Config.bAutoRun);
|
CHECKITEM(ID_EMULATION_RUNONLOAD, g_Config.bAutoRun);
|
||||||
CHECKITEM(ID_OPTIONS_USEVBO, g_Config.bUseVBO);
|
CHECKITEM(ID_OPTIONS_USEVBO, g_Config.bUseVBO);
|
||||||
CHECKITEM(ID_OPTIONS_VERTEXCACHE, g_Config.bVertexCache);
|
CHECKITEM(ID_OPTIONS_VERTEXCACHE, g_Config.bVertexCache);
|
||||||
CHECKITEM(ID_OPTIONS_SHOWFPS, g_Config.bShowFPSCounter);
|
CHECKITEM(ID_OPTIONS_SHOWFPS, g_Config.iShowFPSCounter);
|
||||||
CHECKITEM(ID_OPTIONS_FRAMESKIP, g_Config.iFrameSkip != 0);
|
CHECKITEM(ID_OPTIONS_FRAMESKIP, g_Config.iFrameSkip != 0);
|
||||||
CHECKITEM(ID_OPTIONS_MIPMAP, g_Config.bMipMap);
|
CHECKITEM(ID_OPTIONS_MIPMAP, g_Config.bMipMap);
|
||||||
CHECKITEM(ID_OPTIONS_VSYNC, g_Config.iVSyncInterval != 0);
|
CHECKITEM(ID_OPTIONS_VSYNC, g_Config.iVSyncInterval != 0);
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:icon="@drawable/ic_launcher"
|
android:icon="@drawable/ic_launcher"
|
||||||
android:label="@string/app_name">
|
android:label="@string/app_name"
|
||||||
|
android:allowBackup="true">
|
||||||
<activity
|
<activity
|
||||||
android:name=".PpssppActivity"
|
android:name=".PpssppActivity"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
|
2
ffmpeg
2
ffmpeg
|
@ -1 +1 @@
|
||||||
Subproject commit 969f062d319ab9e3d341c6e661eedd51eefa50a2
|
Subproject commit e8ef410aac458a35064e67582fb80103c29e6474
|
|
@ -200,12 +200,12 @@ int main(int argc, const char* argv[])
|
||||||
g_Config.bVertexCache = true;
|
g_Config.bVertexCache = true;
|
||||||
g_Config.bTrueColor = true;
|
g_Config.bTrueColor = true;
|
||||||
g_Config.ilanguage = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH;
|
g_Config.ilanguage = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH;
|
||||||
g_Config.itimeformat = PSP_SYSTEMPARAM_TIME_FORMAT_24HR;
|
g_Config.iTimeFormat = PSP_SYSTEMPARAM_TIME_FORMAT_24HR;
|
||||||
g_Config.bEncryptSave = true;
|
g_Config.bEncryptSave = true;
|
||||||
g_Config.sNickName = "shadow";
|
g_Config.sNickName = "shadow";
|
||||||
g_Config.iTimeZone = 60;
|
g_Config.iTimeZone = 60;
|
||||||
g_Config.iDateFormat = PSP_SYSTEMPARAM_DATE_FORMAT_DDMMYYYY;
|
g_Config.iDateFormat = PSP_SYSTEMPARAM_DATE_FORMAT_DDMMYYYY;
|
||||||
g_Config.bButtonPreference = true;
|
g_Config.iButtonPreference = PSP_SYSTEMPARAM_BUTTON_CROSS;
|
||||||
g_Config.iLockParentalLevel = 9;
|
g_Config.iLockParentalLevel = 9;
|
||||||
|
|
||||||
#if defined(ANDROID)
|
#if defined(ANDROID)
|
||||||
|
|
2
lang
2
lang
|
@ -1 +1 @@
|
||||||
Subproject commit cf710f2017db93c4019ce53a03764edf3136fa84
|
Subproject commit 81dc0b9141e7d1445efc7b152b88ab16ff75c737
|
2
native
2
native
|
@ -1 +1 @@
|
||||||
Subproject commit 4c2f26ff35b9833752d956a97265261f1e149e58
|
Subproject commit 0a26fae856aecdaa426d92fa5dde101b19487796
|
Loading…
Add table
Reference in a new issue