Merge pull request #3 from hrydgard/master

Update Readme.md
This commit is contained in:
Panderner authored and GitHub committed 2021-01-12 14:31:47 +08:00
commit a44c6c3516
74 files changed
+393 -172

No files matched your search

+5 -4
View File
@@ -121,22 +121,22 @@ jobs:
extra: android
cc: clang
cxx: clang++
args: cd android && ./ab.sh -j2 APP_ABI=arm64-v8a
args: cd android && ./ab.sh -j2 APP_ABI=arm64-v8a UNITTEST=1 HEADLESS=1
- os: ubuntu-latest
extra: android
cc: clang
cxx: clang++
args: cd android && ./ab.sh -j2 APP_ABI=armeabi-v7a
args: cd android && ./ab.sh -j2 APP_ABI=armeabi-v7a UNITTEST=1 HEADLESS=1
- os: ubuntu-latest
extra: android
cc: clang
cxx: clang++
args: cd android && ./ab.sh -j2 APP_ABI=x86
args: cd android && ./ab.sh -j2 APP_ABI=x86 UNITTEST=1 HEADLESS=1
- os: ubuntu-latest
extra: android
cc: clang
cxx: clang++
args: cd android && ./ab.sh -j2 APP_ABI=x86_64
args: cd android && ./ab.sh -j2 APP_ABI=x86_64 UNITTEST=1 HEADLESS=1
- os: ubuntu-latest
extra: android
cc: clang
@@ -215,6 +215,7 @@ jobs:
cp -r build*/PPSSPPSDL.app ppsspp/
elif [ -e build*/PPSSPPSDL ]; then
cp build*/PPSSPPSDL ppsspp/
cp -r assets ppsspp/assets
fi
if [ -e build*/$BUILD_CONFIGURATION/PPSSPPHeadless ]; then
cp build*/$BUILD_CONFIGURATION/PPSSPPHeadless ppsspp/
+5
View File
@@ -4,13 +4,18 @@
#include "Common/StringUtils.h"
#ifndef _WIN32
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <unistd.h>
#define closesocket close
#else
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
#include <io.h>
-13
View File
@@ -7,19 +7,6 @@
#include "Common/Net/Resolve.h"
#ifdef _WIN32
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#endif
#include "Common/Buffer.h"
namespace net {
+1 -1
View File
@@ -126,7 +126,7 @@ std::string UriDecode(const std::string & sSrc)
const unsigned char * const SRC_END = pSrc + SRC_LEN;
const unsigned char * const SRC_LAST_DEC = SRC_END - 2; // last decodable '%'
char * const pStart = new char[SRC_LEN];
char * const pStart = new char[SRC_LEN]; // Output will be shorter.
char * pEnd = pStart;
while (pSrc < SRC_LAST_DEC)
+1
View File
@@ -59,6 +59,7 @@ enum SystemProperty {
// Need hacky solutions to get at this.
SYSPROP_HAS_ADDITIONAL_STORAGE,
SYSPROP_ADDITIONAL_STORAGE_DIRS,
SYSPROP_TEMP_DIRS,
SYSPROP_HAS_FILE_BROWSER,
SYSPROP_HAS_FOLDER_BROWSER,
+3
View File
@@ -527,6 +527,9 @@ public:
paddingW_ = w;
paddingH_ = h;
}
void SetImageID(ImageID imageID) {
imageID_ = imageID;
}
// Needed an extra small button...
void SetScale(float f) {
+6 -6
View File
@@ -149,11 +149,11 @@ int PSPMsgDialog::Init(unsigned int paramAddr) {
void PSPMsgDialog::FormatErrorCode(uint32_t code) {
auto di = GetI18NCategory("Dialog");
auto err = GetI18NCategory("Dialog");
switch (code) {
case SCE_UTILITY_SAVEDATA_ERROR_LOAD_DATA_BROKEN:
snprintf(msgText, 512, "%s (%08x)", di->T("MsgErrorSavedataDataBroken", "Save data was corrupt."), code);
snprintf(msgText, 512, "%s (%08x)", err->T("MsgErrorSavedataDataBroken", "Save data was corrupt."), code);
break;
case SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_MS:
@@ -161,23 +161,23 @@ void PSPMsgDialog::FormatErrorCode(uint32_t code) {
case SCE_UTILITY_SAVEDATA_ERROR_SAVE_NO_MS:
case SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_MS:
case SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_MS:
snprintf(msgText, 512, "%s (%08x)", di->T("MsgErrorSavedataNoMS", "Memory stick not inserted."), code);
snprintf(msgText, 512, "%s (%08x)", err->T("MsgErrorSavedataNoMS", "Memory stick not inserted."), code);
break;
case SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA:
case SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA:
case SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA:
case SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_DATA:
snprintf(msgText, 512, "%s (%08x)", di->T("MsgErrorSavedataNoData", "Warning: no save data was found."), code);
snprintf(msgText, 512, "%s (%08x)", err->T("MsgErrorSavedataNoData", "Warning: no save data was found."), code);
break;
case SCE_UTILITY_SAVEDATA_ERROR_RW_MEMSTICK_FULL:
case SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_NOSPACE:
snprintf(msgText, 512, "%s (%08x)", di->T("MsgErrorSavedataMSFull", "Memory stick full. Check your storage space."), code);
snprintf(msgText, 512, "%s (%08x)", err->T("MsgErrorSavedataMSFull", "Memory stick full. Check your storage space."), code);
break;
default:
snprintf(msgText, 512, "%s %08x", di->T("MsgErrorCode", "Error code:"), code);
snprintf(msgText, 512, "%s %08x", err->T("MsgErrorCode", "Error code:"), code);
}
}
+1 -1
View File
@@ -347,7 +347,7 @@ int PSPNetconfDialog::Update(int animSpeed) {
if (g_Config.iWlanAdhocChannel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC)
channel = "Automatic";
DisplayMessage(di->T("ConnectingPleaseWait", "Connecting.\nPlease wait..."), di->T("Channel") + std::string(" ") + di->T(channel));
DisplayMessage(di->T("ConnectingPleaseWait", "Connecting.\nPlease wait..."), di->T("Channel:") + std::string(" ") + di->T(channel));
// Only Join mode is showing Cancel button on KHBBS and the button will fade out before the dialog is fading out, probably because it's already connected thus can't be canceled anymore
if (request.netAction == NETCONF_JOIN_ADHOC)
+15 -9
View File
@@ -1203,18 +1203,24 @@ void notifyAdhocctlHandlers(u32 flag, u32 error) {
// Note: Must not lock peerlock within this function to prevent race-condition with other thread whos owning peerlock and trying to lock context->eventlock owned by this thread
void notifyMatchingHandler(SceNetAdhocMatchingContext * context, ThreadMessage * msg, void * opt, u32_le &bufAddr, u32_le &bufLen, u32_le * args) {
// Don't share buffer address space with other mipscall in the queue since mipscalls aren't immediately executed
MatchingArgs argsNew;
MatchingArgs argsNew = { 0 };
u32_le dataBufLen = msg->optlen + 8; //max(bufLen, msg->optlen + 8);
u32_le dataBufAddr = userMemory.Alloc(dataBufLen); // We will free this memory after returning from mipscall
uint8_t * dataPtr = Memory::GetPointer(dataBufAddr);
memcpy(dataPtr, &msg->mac, sizeof(msg->mac));
if (msg->optlen > 0)
memcpy(dataPtr + 8, opt, msg->optlen);
argsNew.data[0] = context->id;
argsNew.data[1] = msg->opcode;
argsNew.data[2] = dataBufAddr;
argsNew.data[3] = msg->optlen;
argsNew.data[4] = dataBufAddr + 8; // OptData Addr
if (dataPtr) {
memcpy(dataPtr, &msg->mac, sizeof(msg->mac));
if (msg->optlen > 0)
memcpy(dataPtr + 8, opt, msg->optlen);
argsNew.data[1] = msg->opcode;
argsNew.data[2] = dataBufAddr;
argsNew.data[3] = msg->optlen;
argsNew.data[4] = dataBufAddr + 8; // OptData Addr
}
else {
argsNew.data[1] = PSP_ADHOC_MATCHING_EVENT_ERROR; // not sure where to put the error code for EVENT_ERROR tho
}
argsNew.data[0] = context->id;
argsNew.data[5] = context->handler.entryPoint; //not part of callback argument, just borrowing a space to store callback address so i don't need to search the context first later
// ScheduleEvent_Threadsafe_Immediate seems to get mixed up with interrupt (returning from mipscall inside an interrupt) and getting invalid address before returning from interrupt
+3 -2
View File
@@ -103,6 +103,7 @@ u32_le matchingThreadCode[3];
int matchingEventThread(int matchingId);
int matchingInputThread(int matchingId);
void sendBulkDataPacket(SceNetAdhocMatchingContext* context, SceNetEtherAddr* mac, int datalen, void* data);
int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEtherAddr* addr, u16_le* port);
int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout, int nonblock);
int FlushPtpSocket(int socketId);
@@ -5279,7 +5280,7 @@ int sceNetAdhocMatchingSendData(int matchingId, const char *mac, int dataLen, u3
peer->sending = 1;
// Send Data to Peer
sendBulkData(context, peer, dataLen, data);
sendBulkDataPacket(context, &peer->mac, dataLen, data);
// Return Success
return 0;
@@ -5518,7 +5519,7 @@ void __NetMatchingCallbacks() //(int matchingId)
after->SetData(args[0], args[1], args[2]);
hleEnqueueCall(args[5], 5, args, after);
matchingEvents.pop_front();
delayus = (adhocMatchingEventDelay + adhocExtraDelay); // Added an extra delay to prevent I/O Timing method from causing disconnection
delayus = adhocMatchingEventDelay; // Add extra delay to prevent I/O Timing method from causing disconnection, but delaying too long may cause matchingEvents to pile up
}
// Must be delayed long enough whenever there is a pending callback. Should it be 10-100ms for Matching Events? or Not Less than the delays on sceNetAdhocMatching HLE?
+1 -1
View File
@@ -44,7 +44,7 @@ using namespace MIPSAnalyst;
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
// Currently known non working ones should have DISABLE.
// #define CONDITIONAL_DISABLE { Comp_Generic(op); return; }
// #define CONDITIONAL_DISABLE(flag) { Comp_Generic(op); return; }
#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; }
#define DISABLE { Comp_Generic(op); return; }
+1 -1
View File
@@ -43,7 +43,7 @@
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
// Currently known non working ones should have DISABLE.
// #define CONDITIONAL_DISABLE { Comp_Generic(op); return; }
// #define CONDITIONAL_DISABLE(flag) { Comp_Generic(op); return; }
#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; }
#define DISABLE { Comp_Generic(op); return; }
+1 -1
View File
@@ -41,7 +41,7 @@
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
// Currently known non working ones should have DISABLE.
// #define CONDITIONAL_DISABLE { Comp_Generic(op); return; }
// #define CONDITIONAL_DISABLE(flag) { Comp_Generic(op); return; }
#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; }
#define DISABLE { Comp_Generic(op); return; }
+1 -1
View File
@@ -37,7 +37,7 @@
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
// Currently known non working ones should have DISABLE.
// #define CONDITIONAL_DISABLE { Comp_Generic(op); return; }
// #define CONDITIONAL_DISABLE(flag) { Comp_Generic(op); return; }
#define CONDITIONAL_DISABLE(flag) if (opts.disableFlags & (uint32_t)JitDisable::flag) { Comp_Generic(op); return; }
#define DISABLE { Comp_Generic(op); return; }
#define INVALIDOP { Comp_Generic(op); return; }
+1 -1
View File
@@ -48,7 +48,7 @@
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
// Currently known non working ones should have DISABLE.
// #define CONDITIONAL_DISABLE { Comp_Generic(op); return; }
// #define CONDITIONAL_DISABLE(flag) { Comp_Generic(op); return; }
#define CONDITIONAL_DISABLE(flag) if (opts.disableFlags & (uint32_t)JitDisable::flag) { Comp_Generic(op); return; }
#define DISABLE { Comp_Generic(op); return; }
#define INVALIDOP { Comp_Generic(op); return; }
+1 -1
View File
@@ -38,7 +38,7 @@
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
// Currently known non working ones should have DISABLE.
// #define CONDITIONAL_DISABLE { Comp_Generic(op); return; }
// #define CONDITIONAL_DISABLE(flag) { Comp_Generic(op); return; }
#define CONDITIONAL_DISABLE(flag) if (opts.disableFlags & (uint32_t)JitDisable::flag) { Comp_Generic(op); return; }
#define DISABLE { Comp_Generic(op); return; }
#define INVALIDOP { Comp_Generic(op); return; }
+2 -2
View File
@@ -36,7 +36,7 @@
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
// Currently known non working ones should have DISABLE.
// #define CONDITIONAL_DISABLE { Comp_Generic(op); return; }
// #define CONDITIONAL_DISABLE(flag) { Comp_Generic(op); return; }
#define CONDITIONAL_DISABLE(flag) if (opts.disableFlags & (uint32_t)JitDisable::flag) { Comp_Generic(op); return; }
#define DISABLE { Comp_Generic(op); return; }
#define INVALIDOP { Comp_Generic(op); return; }
@@ -993,7 +993,7 @@ namespace MIPSComp {
ir.Write(IROp::AndConst, IRTEMP_0, rt, ir.AddConstant(mask));
ir.Write(IROp::SetCtrlVFPUReg, imm - 128, IRTEMP_0);
} else {
ir.Write(IROp::SetCtrlVFPU, imm - 128, rt);
ir.Write(IROp::SetCtrlVFPUReg, imm - 128, rt);
}
}
+2 -2
View File
@@ -114,11 +114,11 @@ static const IRMeta irMeta[] = {
{ IROp::FpCondToReg, "FpCondToReg", "G" },
{ IROp::VfpuCtrlToReg, "VfpuCtrlToReg", "GI" },
{ IROp::SetCtrlVFPU, "SetCtrlVFPU", "TC" },
{ IROp::SetCtrlVFPUReg, "SetCtrlVFPUReg", "TC" },
{ IROp::SetCtrlVFPUReg, "SetCtrlVFPUReg", "TG" },
{ IROp::SetCtrlVFPUFReg, "SetCtrlVFPUFReg", "TF" },
{ IROp::FCmovVfpuCC, "FCmovVfpuCC", "FFI" },
{ IROp::FCmpVfpuBit, "FCmpVfpuBit", "IFF" },
{ IROp::FCmpVfpuAggregate, "FCmpVfpuAggregate", "" },
{ IROp::FCmpVfpuAggregate, "FCmpVfpuAggregate", "I" },
{ IROp::Vec4Init, "Vec4Init", "Vv" },
{ IROp::Vec4Shuffle, "Vec4Shuffle", "VVs" },
{ IROp::Vec4Mov, "Vec4Mov", "VV" },
+20
View File
@@ -8,6 +8,10 @@
#include "Core/MIPS/IR/IRPassSimplify.h"
#include "Core/MIPS/IR/IRRegCache.h"
// #define CONDITIONAL_DISABLE { for (IRInst inst : in.GetInstructions()) { out.Write(inst); } return false; }
#define CONDITIONAL_DISABLE
#define DISABLE { for (IRInst inst : in.GetInstructions()) { out.Write(inst); } return false; }
u32 Evaluate(u32 a, u32 b, IROp op) {
switch (op) {
case IROp::Add: case IROp::AddConst: return a + b;
@@ -101,8 +105,11 @@ bool IRApplyPasses(const IRPassFunc *passes, size_t c, const IRWriter &in, IRWri
}
bool OptimizeFPMoves(const IRWriter &in, IRWriter &out, const IROptions &opts) {
CONDITIONAL_DISABLE;
bool logBlocks = false;
IRInst prev{ IROp::Nop };
for (int i = 0; i < (int)in.GetInstructions().size(); i++) {
IRInst inst = in.GetInstructions()[i];
switch (inst.op) {
@@ -151,6 +158,8 @@ bool OptimizeFPMoves(const IRWriter &in, IRWriter &out, const IROptions &opts) {
// Might be useful later on x86.
bool ThreeOpToTwoOp(const IRWriter &in, IRWriter &out, const IROptions &opts) {
CONDITIONAL_DISABLE;
bool logBlocks = false;
for (int i = 0; i < (int)in.GetInstructions().size(); i++) {
IRInst inst = in.GetInstructions()[i];
@@ -201,6 +210,8 @@ bool ThreeOpToTwoOp(const IRWriter &in, IRWriter &out, const IROptions &opts) {
}
bool RemoveLoadStoreLeftRight(const IRWriter &in, IRWriter &out, const IROptions &opts) {
CONDITIONAL_DISABLE;
bool logBlocks = false;
for (int i = 0, n = (int)in.GetInstructions().size(); i < n; ++i) {
const IRInst &inst = in.GetInstructions()[i];
@@ -366,6 +377,7 @@ bool RemoveLoadStoreLeftRight(const IRWriter &in, IRWriter &out, const IROptions
}
bool PropagateConstants(const IRWriter &in, IRWriter &out, const IROptions &opts) {
CONDITIONAL_DISABLE;
IRRegCache gpr(&out);
bool logBlocks = false;
@@ -784,6 +796,7 @@ bool IRMutatesDestGPR(const IRInst &inst, int reg) {
}
bool PurgeTemps(const IRWriter &in, IRWriter &out, const IROptions &opts) {
CONDITIONAL_DISABLE;
std::vector<IRInst> insts;
insts.reserve(in.GetInstructions().size());
@@ -822,6 +835,8 @@ bool PurgeTemps(const IRWriter &in, IRWriter &out, const IROptions &opts) {
insts[check.index] = IRReplaceDestGPR(insts[check.index], check.reg, inst.dest);
lastWrittenTo[inst.dest] = check.index;
check.reg = inst.dest;
// Update the read by exit flag to match the new reg.
check.readByExit = inst.dest < IRTEMP_0 || inst.dest > IRTEMP_LR_SHIFT;
// And swap the args for this mov, since we changed the other dest. We'll optimize this out later.
std::swap(inst.dest, inst.src1);
} else {
@@ -903,6 +918,7 @@ bool PurgeTemps(const IRWriter &in, IRWriter &out, const IROptions &opts) {
}
bool ReduceLoads(const IRWriter &in, IRWriter &out, const IROptions &opts) {
CONDITIONAL_DISABLE;
// This tells us to skip an AND op that has been optimized out.
// Maybe we could skip multiple, but that'd slow things down and is pretty uncommon.
int nextSkip = -1;
@@ -1039,6 +1055,8 @@ static std::vector<IRInst> ReorderLoadStoreOps(std::vector<IRInst> &ops) {
}
bool ReorderLoadStore(const IRWriter &in, IRWriter &out, const IROptions &opts) {
CONDITIONAL_DISABLE;
bool logBlocks = false;
enum class RegState : u8 {
@@ -1234,6 +1252,8 @@ bool ReorderLoadStore(const IRWriter &in, IRWriter &out, const IROptions &opts)
}
bool MergeLoadStore(const IRWriter &in, IRWriter &out, const IROptions &opts) {
CONDITIONAL_DISABLE;
bool logBlocks = false;
auto opsCompatible = [&](const IRInst &a, const IRInst &b, int dist) {
+1 -1
View File
@@ -41,7 +41,7 @@
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
// Currently known non working ones should have DISABLE.
// #define CONDITIONAL_DISABLE { Comp_Generic(op); return; }
// #define CONDITIONAL_DISABLE(flag) { Comp_Generic(op); return; }
#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; }
#define DISABLE { Comp_Generic(op); return; }
+1 -1
View File
@@ -41,7 +41,7 @@
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
// Currently known non working ones should have DISABLE.
// #define CONDITIONAL_DISABLE { Comp_Generic(op); return; }
// #define CONDITIONAL_DISABLE(flag) { Comp_Generic(op); return; }
#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; }
#define DISABLE { Comp_Generic(op); return; }
+1 -1
View File
@@ -493,7 +493,7 @@ void PSP_Shutdown() {
// Make sure things know right away that PSP memory, etc. is going away.
pspIsQuitting = true;
if (coreState == CORE_RUNNING)
Core_UpdateState(CORE_POWERDOWN);
Core_Stop();
#ifndef MOBILE_DEVICE
if (g_Config.bFuncHashMap) {
+3
View File
@@ -28,6 +28,9 @@
#else
#include "ext/libzip/zip.h"
#endif
#ifdef _WIN32
#include "Common/CommonWindows.h"
#endif
#include "Common/Data/Encoding/Utf8.h"
#include "Common/Data/Format/IniFile.h"
#include "Common/Log.h"
+2 -2
View File
@@ -61,7 +61,7 @@ std::string VertexShaderDesc(const VShaderID &id) {
return desc.str();
}
void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform, bool useHWTessellation) {
void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat) {
bool isModeThrough = (vertType & GE_VTYPE_THROUGH) != 0;
bool doTexture = gstate.isTextureMapEnabled() && !gstate.isModeClear();
bool doShadeMapping = doTexture && (gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP);
@@ -112,7 +112,7 @@ void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform,
id.SetBits(VS_BIT_BONES, 3, TranslateNumBones(vertTypeGetNumBoneWeights(vertType)) - 1);
// 2 bits. We should probably send in the weight scalefactor as a uniform instead,
// or simply preconvert all weights to floats.
id.SetBits(VS_BIT_WEIGHT_FMTSCALE, 2, (vertType & GE_VTYPE_WEIGHT_MASK) >> GE_VTYPE_WEIGHT_SHIFT);
id.SetBits(VS_BIT_WEIGHT_FMTSCALE, 2, weightsAsFloat ? 0 : (vertType & GE_VTYPE_WEIGHT_MASK) >> GE_VTYPE_WEIGHT_SHIFT);
}
if (gstate.isLightingEnabled()) {
+1 -1
View File
@@ -225,7 +225,7 @@ class Bugs;
}
void ComputeVertexShaderID(VShaderID *id, uint32_t vertexType, bool useHWTransform, bool useHWTessellation);
void ComputeVertexShaderID(VShaderID *id, uint32_t vertexType, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat);
// Generates a compact string that describes the shader. Useful in a list to get an overview
// of the current flora of shaders.
std::string VertexShaderDesc(const VShaderID &id);
+3 -3
View File
@@ -822,9 +822,9 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
// Uncomment this to screw up bone shaders to check the vertex shader software fallback
// WRITE(p, "THIS SHOULD ERROR! #error");
if (numBoneWeights == 1 && ShaderLanguageIsOpenGL(compat.shaderLanguage))
WRITE(p, " %s skinMatrix = w1 * u_bone0", boneMatrix);
WRITE(p, " %s skinMatrix = mul(w1, u_bone0)", boneMatrix);
else
WRITE(p, " %s skinMatrix = w1.x * u_bone0", boneMatrix);
WRITE(p, " %s skinMatrix = mul(w1.x, u_bone0)", boneMatrix);
for (int i = 1; i < numBoneWeights; i++) {
const char *weightAttr = boneWeightAttr[i];
// workaround for "cant do .x of scalar" issue.
@@ -832,7 +832,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
if (numBoneWeights == 1 && i == 0) weightAttr = "w1";
if (numBoneWeights == 5 && i == 4) weightAttr = "w2";
}
WRITE(p, " + %s * u_bone%i", weightAttr, i);
WRITE(p, " + mul(%s, u_bone%i)", weightAttr, i);
}
WRITE(p, ";\n");
+2 -2
View File
@@ -523,7 +523,7 @@ rotateVBO:
D3D11VertexShader *vshader;
D3D11FragmentShader *fshader;
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, useHWTransform, useHWTessellation_);
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, useHWTransform, useHWTessellation_, decOptions_.expandAllWeightsToFloat);
ID3D11InputLayout *inputLayout = SetupDecFmtForDraw(vshader, dec_->GetDecVtxFmt(), dec_->VertexType());
context_->PSSetShader(fshader->GetShader(), nullptr, 0);
context_->VSSetShader(vshader->GetShader(), nullptr, 0);
@@ -609,7 +609,7 @@ rotateVBO:
D3D11VertexShader *vshader;
D3D11FragmentShader *fshader;
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, false, false);
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, false, false, decOptions_.expandAllWeightsToFloat);
context_->PSSetShader(fshader->GetShader(), nullptr, 0);
context_->VSSetShader(vshader->GetShader(), nullptr, 0);
shaderManager_->UpdateUniforms(framebufferManager_->UseBufferedRendering());
+2 -2
View File
@@ -177,13 +177,13 @@ void ShaderManagerD3D11::BindUniforms() {
context_->PSSetConstantBuffers(0, 1, ps_cbs);
}
void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, bool useHWTransform, bool useHWTessellation) {
void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat) {
VShaderID VSID;
FShaderID FSID;
if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) {
gstate_c.Clean(DIRTY_VERTEXSHADER_STATE);
ComputeVertexShaderID(&VSID, vertType, useHWTransform, useHWTessellation);
ComputeVertexShaderID(&VSID, vertType, useHWTransform, useHWTessellation, weightsAsFloat);
} else {
VSID = lastVSID_;
}
+1 -1
View File
@@ -85,7 +85,7 @@ public:
ShaderManagerD3D11(Draw::DrawContext *draw, ID3D11Device *device, ID3D11DeviceContext *context, D3D_FEATURE_LEVEL featureLevel);
~ShaderManagerD3D11();
void GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, bool useHWTransform, bool useHWTessellation);
void GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat);
void ClearShaders();
void DirtyLastShader() override;
+3 -3
View File
@@ -324,7 +324,7 @@ void DrawEngineDX9::DoFlush() {
GEPrimitiveType prim = prevPrim_;
ApplyDrawState(prim);
VSShader *vshader = shaderManager_->ApplyShader(CanUseHardwareTransform(prim), useHWTessellation_, lastVType_);
VSShader *vshader = shaderManager_->ApplyShader(CanUseHardwareTransform(prim), useHWTessellation_, lastVType_, decOptions_.expandAllWeightsToFloat);
if (vshader->UseHWTransform()) {
LPDIRECT3DVERTEXBUFFER9 vb_ = NULL;
@@ -505,7 +505,7 @@ rotateVBO:
}
ApplyDrawStateLate();
vshader = shaderManager_->ApplyShader(CanUseHardwareTransform(prim), useHWTessellation_, lastVType_);
vshader = shaderManager_->ApplyShader(CanUseHardwareTransform(prim), useHWTessellation_, lastVType_, decOptions_.expandAllWeightsToFloat);
IDirect3DVertexDeclaration9 *pHardwareVertexDecl = SetupDecFmtForDraw(vshader, dec_->GetDecVtxFmt(), dec_->VertexType());
if (pHardwareVertexDecl) {
@@ -568,7 +568,7 @@ rotateVBO:
framebufferManager_->SetSafeSize(result.safeWidth, result.safeHeight);
ApplyDrawStateLate();
vshader = shaderManager_->ApplyShader(false, false, lastVType_);
vshader = shaderManager_->ApplyShader(false, false, lastVType_, decOptions_.expandAllWeightsToFloat);
if (result.action == SW_DRAW_PRIMITIVES) {
if (result.setStencil) {
+3 -3
View File
@@ -541,7 +541,7 @@ void ShaderManagerDX9::DirtyLastShader() { // disables vertex arrays
lastPShader_ = nullptr;
}
VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellation, u32 vertType) {
VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellation, u32 vertType, bool weightsAsFloat) {
// Always use software for flat shading to fix the provoking index.
bool tess = gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE;
useHWTransform = useHWTransform && (tess || gstate.getShadeMode() != GE_SHADE_FLAT);
@@ -549,7 +549,7 @@ VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellat
VShaderID VSID;
if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) {
gstate_c.Clean(DIRTY_VERTEXSHADER_STATE);
ComputeVertexShaderID(&VSID, vertType, useHWTransform, useHWTessellation);
ComputeVertexShaderID(&VSID, vertType, useHWTransform, useHWTessellation, weightsAsFloat);
} else {
VSID = lastVSID_;
}
@@ -598,7 +598,7 @@ VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellat
}
delete vs;
ComputeVertexShaderID(&VSID, vertType, false, false);
ComputeVertexShaderID(&VSID, vertType, false, false, weightsAsFloat);
// TODO: Look for existing shader with the appropriate ID, use that instead of generating a new one - however, need to make sure
// that that shader ID is not used when computing the linked shader ID below, because then IDs won't match
+1 -1
View File
@@ -80,7 +80,7 @@ public:
~ShaderManagerDX9();
void ClearCache(bool deleteThem); // TODO: deleteThem currently not respected
VSShader *ApplyShader(bool useHWTransform, bool useHWTessellation, u32 vertType);
VSShader *ApplyShader(bool useHWTransform, bool useHWTessellation, u32 vertType, bool weightsAsFloat);
void DirtyShader();
void DirtyLastShader() override;
+1 -1
View File
@@ -333,7 +333,7 @@ void DrawEngineGLES::DoFlush() {
GEPrimitiveType prim = prevPrim_;
VShaderID vsid;
Shader *vshader = shaderManager_->ApplyVertexShader(CanUseHardwareTransform(prim), useHWTessellation_, lastVType_, &vsid);
Shader *vshader = shaderManager_->ApplyVertexShader(CanUseHardwareTransform(prim), useHWTessellation_, lastVType_, decOptions_.expandAllWeightsToFloat, &vsid);
GLRBuffer *vertexBuffer = nullptr;
GLRBuffer *indexBuffer = nullptr;
+3 -3
View File
@@ -656,10 +656,10 @@ Shader *ShaderManagerGLES::CompileVertexShader(VShaderID VSID) {
return new Shader(render_, codeBuffer_, desc, GL_VERTEX_SHADER, useHWTransform, attrMask, uniformMask);
}
Shader *ShaderManagerGLES::ApplyVertexShader(bool useHWTransform, bool useHWTessellation, u32 vertType, VShaderID *VSID) {
Shader *ShaderManagerGLES::ApplyVertexShader(bool useHWTransform, bool useHWTessellation, u32 vertType, bool weightsAsFloat, VShaderID *VSID) {
if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) {
gstate_c.Clean(DIRTY_VERTEXSHADER_STATE);
ComputeVertexShaderID(VSID, vertType, useHWTransform, useHWTessellation);
ComputeVertexShaderID(VSID, vertType, useHWTransform, useHWTessellation, weightsAsFloat);
} else {
*VSID = lastVSID_;
}
@@ -690,7 +690,7 @@ Shader *ShaderManagerGLES::ApplyVertexShader(bool useHWTransform, bool useHWTess
// Can still work with software transform.
VShaderID vsidTemp;
ComputeVertexShaderID(&vsidTemp, vertType, false, false);
ComputeVertexShaderID(&vsidTemp, vertType, false, false, weightsAsFloat);
vs = CompileVertexShader(vsidTemp);
}
+1 -1
View File
@@ -146,7 +146,7 @@ public:
// This is the old ApplyShader split into two parts, because of annoying information dependencies.
// If you call ApplyVertexShader, you MUST call ApplyFragmentShader soon afterwards.
Shader *ApplyVertexShader(bool useHWTransform, bool useHWTessellation, u32 vertType, VShaderID *VSID);
Shader *ApplyVertexShader(bool useHWTransform, bool useHWTessellation, u32 vertType, bool weightsAsFloat, VShaderID *VSID);
LinkedShader *ApplyFragmentShader(VShaderID VSID, Shader *vs, u32 vertType, bool useBufferedRendering);
void DeviceLost();
+2 -2
View File
@@ -818,7 +818,7 @@ void DrawEngineVulkan::DoFlush() {
ConvertStateToVulkanKey(*framebufferManager_, shaderManager_, prim, pipelineKey_, dynState_);
}
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, true, useHWTessellation_); // usehwtransform
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, true, useHWTessellation_, decOptions_.expandAllWeightsToFloat); // usehwtransform
_dbg_assert_msg_(vshader->UseHWTransform(), "Bad vshader");
Draw::NativeObject object = framebufferManager_->UseBufferedRendering() ? Draw::NativeObject::FRAMEBUFFER_RENDERPASS : Draw::NativeObject::BACKBUFFER_RENDERPASS;
@@ -939,7 +939,7 @@ void DrawEngineVulkan::DoFlush() {
sampler = nullSampler_;
}
if (!lastPipeline_ || gstate_c.IsDirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE) || prim != lastPrim_) {
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, false, false); // usehwtransform
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, false, false, decOptions_.expandAllWeightsToFloat); // usehwtransform
_dbg_assert_msg_(!vshader->UseHWTransform(), "Bad vshader");
if (prim != lastPrim_ || gstate_c.IsDirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE)) {
ConvertStateToVulkanKey(*framebufferManager_, shaderManager_, prim, pipelineKey_, dynState_);
+2 -2
View File
@@ -228,11 +228,11 @@ uint64_t ShaderManagerVulkan::UpdateUniforms(bool useBufferedRendering) {
return dirty;
}
void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, bool useHWTransform, bool useHWTessellation) {
void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat) {
VShaderID VSID;
if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) {
gstate_c.Clean(DIRTY_VERTEXSHADER_STATE);
ComputeVertexShaderID(&VSID, vertType, useHWTransform, useHWTessellation);
ComputeVertexShaderID(&VSID, vertType, useHWTransform, useHWTessellation, weightsAsFloat);
} else {
VSID = lastVSID_;
}
+1 -1
View File
@@ -88,7 +88,7 @@ public:
void DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw);
void GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, bool useHWTransform, bool useHWTessellation);
void GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat);
void ClearShaders();
void DirtyShader();
void DirtyLastShader() override;
+11 -1
View File
@@ -150,9 +150,19 @@ std::string System_GetProperty(SystemProperty prop) {
}
std::vector<std::string> System_GetPropertyStringVec(SystemProperty prop) {
std::vector<std::string> result;
switch (prop) {
case SYSPROP_TEMP_DIRS:
if (getenv("TMPDIR") && strlen(getenv("TMPDIR")) != 0)
result.push_back(getenv("TMPDIR"));
if (getenv("TMP") && strlen(getenv("TMP")) != 0)
result.push_back(getenv("TMP"));
if (getenv("TEMP") && strlen(getenv("TEMP")) != 0)
result.push_back(getenv("TEMP"));
return result;
default:
return std::vector<std::string>();
return result;
}
}
+12 -1
View File
@@ -326,9 +326,20 @@ std::string System_GetProperty(SystemProperty prop) {
}
std::vector<std::string> System_GetPropertyStringVec(SystemProperty prop) {
std::vector<std::string> result;
switch (prop) {
case SYSPROP_TEMP_DIRS:
if (getenv("TMPDIR") && strlen(getenv("TMPDIR")) != 0)
result.push_back(getenv("TMPDIR"));
if (getenv("TMP") && strlen(getenv("TMP")) != 0)
result.push_back(getenv("TMP"));
if (getenv("TEMP") && strlen(getenv("TEMP")) != 0)
result.push_back(getenv("TEMP"));
return result;
default:
return std::vector<std::string>();
return result;
}
}
+2
View File
@@ -420,6 +420,8 @@ void EmuScreen::sendMessage(const char *message, const char *value) {
PSP_Shutdown();
bootPending_ = true;
gamePath_ = value;
// Don't leave it on CORE_POWERDOWN, we'll sometimes aggressively bail.
Core_UpdateState(CORE_POWERUP);
}
} else if (!strcmp(message, "config_loaded")) {
// In case we need to position touch controls differently.
+1 -1
View File
@@ -766,7 +766,7 @@ void GameSettingsScreen::CreateViews() {
networkingSettingsScroll->Add(networkingSettings);
tabHolder->AddTab(ms->T("Networking"), networkingSettingsScroll);
networkingSettings->Add(new ItemHeader(n->T("Networking")));
networkingSettings->Add(new ItemHeader(ms->T("Networking")));
networkingSettings->Add(new Choice(n->T("Adhoc Multiplayer forum")))->OnClick.Handle(this, &GameSettingsScreen::OnAdhocGuides);
+63 -49
View File
@@ -15,8 +15,9 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <cmath>
#include <algorithm>
#include <cmath>
#include <sstream>
#include "ppsspp_config.h"
@@ -33,6 +34,7 @@
#include "Common/Data/Encoding/Utf8.h"
#include "Common/File/PathBrowser.h"
#include "Common/Math/curves.h"
#include "Common/Net/URL.h"
#include "Common/File/FileUtil.h"
#include "Common/TimeUtil.h"
#include "Common/StringUtils.h"
@@ -63,13 +65,6 @@
#include "Core/HLE/sceDisplay.h"
#include "Core/HLE/sceUmd.h"
#ifdef _WIN32
// Unfortunate, for undef DrawText...
#include "Common/CommonWindows.h"
#endif
#include <sstream>
bool MainScreen::showHomebrewTab = false;
bool LaunchFile(ScreenManager *screenManager, std::string path) {
@@ -96,8 +91,13 @@ bool LaunchFile(ScreenManager *screenManager, std::string path) {
static bool IsTempPath(const std::string &str) {
std::string item = str;
#ifdef _WIN32
// Normalize slashes.
item = ReplaceAll(str, "/", "\\");
#endif
const auto testPath = [&](std::string temp) {
std::vector<std::string> tempPaths = System_GetPropertyStringVec(SYSPROP_TEMP_DIRS);
for (auto temp : tempPaths) {
#ifdef _WIN32
temp = ReplaceAll(temp, "/", "\\");
if (!temp.empty() && temp[temp.size() - 1] != '\\')
@@ -106,37 +106,9 @@ static bool IsTempPath(const std::string &str) {
if (!temp.empty() && temp[temp.size() - 1] != '/')
temp += "/";
#endif
return startsWith(item, temp);
};
const auto testCPath = [&](const char *temp) {
if (temp && temp[0])
return testPath(temp);
return false;
};
#ifdef _WIN32
// Normalize slashes.
item = ReplaceAll(str, "/", "\\");
std::wstring tempPath(MAX_PATH, '\0');
size_t sz = GetTempPath((DWORD)tempPath.size(), &tempPath[0]);
if (sz >= tempPath.size()) {
tempPath.resize(sz);
sz = GetTempPath((DWORD)tempPath.size(), &tempPath[0]);
if (startsWith(item, temp))
return true;
}
// Need to resize off the null terminator either way.
tempPath.resize(sz);
if (testPath(ConvertWStringToUTF8(tempPath)))
return true;
#endif
if (testCPath(getenv("TMPDIR")))
return true;
if (testCPath(getenv("TMP")))
return true;
if (testCPath(getenv("TEMP")))
return true;
return false;
}
@@ -1091,17 +1063,18 @@ void MainScreen::CreateViews() {
char versionString[256];
sprintf(versionString, "%s", PPSSPP_GIT_VERSION);
rightColumnItems->SetSpacing(0.0f);
LinearLayout *logos = new LinearLayout(ORIENT_HORIZONTAL);
AnchorLayout *logos = new AnchorLayout(new AnchorLayoutParams(FILL_PARENT, 60.0f, false));
if (System_GetPropertyBool(SYSPROP_APP_GOLD)) {
logos->Add(new ImageView(ImageID("I_ICONGOLD"), IS_DEFAULT, new AnchorLayoutParams(64, 64, 10, 10, NONE, NONE, false)));
logos->Add(new ImageView(ImageID("I_ICONGOLD"), IS_DEFAULT, new AnchorLayoutParams(64, 64, 0, 0, NONE, NONE, false)));
} else {
logos->Add(new ImageView(ImageID("I_ICON"), IS_DEFAULT, new AnchorLayoutParams(64, 64, 10, 10, NONE, NONE, false)));
logos->Add(new ImageView(ImageID("I_ICON"), IS_DEFAULT, new AnchorLayoutParams(64, 64, 0, 0, NONE, NONE, false)));
}
logos->Add(new ImageView(ImageID("I_LOGO"), IS_DEFAULT, new LinearLayoutParams(Margins(-12, 0, 0, 0))));
logos->Add(new ImageView(ImageID("I_LOGO"), IS_DEFAULT, new AnchorLayoutParams(180, 64, 64, -5.0f, NONE, NONE, false)));
#if defined(USING_WIN_UI) || defined(USING_QT_UI) || PPSSPP_PLATFORM(UWP)
#if !defined(MOBILE_DEVICE)
if (!g_Config.bFullScreen) {
logos->Add(new ImageView(ImageID("I_FULLSCREEN"), IS_DEFAULT, new AnchorLayoutParams(64, 64, NONE, 0, 0, NONE, false)));
fullscreenButton_ = logos->Add(new Button(ImageID(g_Config.bFullScreen ? "I_RESTORE" : "I_FULLSCREEN"), new AnchorLayoutParams(48, 48, NONE, 0, 0, NONE, false)));
fullscreenButton_->OnClick.Handle(this, &MainScreen::OnFullScreenToggle);
}
#endif
@@ -1109,9 +1082,10 @@ void MainScreen::CreateViews() {
TextView *ver = rightColumnItems->Add(new TextView(versionString, new LinearLayoutParams(Margins(70, -6, 0, 0))));
ver->SetSmall(true);
ver->SetClip(false);
#if defined(USING_WIN_UI) || defined(USING_QT_UI) || PPSSPP_PLATFORM(UWP)
rightColumnItems->Add(new Choice(mm->T("Load","Load...")))->OnClick.Handle(this, &MainScreen::OnLoadFile);
#endif
if (System_GetPropertyBool(SYSPROP_HAS_FILE_BROWSER)) {
rightColumnItems->Add(new Choice(mm->T("Load", "Load...")))->OnClick.Handle(this, &MainScreen::OnLoadFile);
}
rightColumnItems->Add(new Choice(mm->T("Game Settings", "Settings")))->OnClick.Handle(this, &MainScreen::OnGameSettings);
rightColumnItems->Add(new Choice(mm->T("Credits")))->OnClick.Handle(this, &MainScreen::OnCredits);
rightColumnItems->Add(new Choice(mm->T("www.ppsspp.org")))->OnClick.Handle(this, &MainScreen::OnPPSSPPOrg);
@@ -1210,9 +1184,38 @@ void MainScreen::sendMessage(const char *message, const char *value) {
LaunchFile(screenManager(), std::string(value));
}
if (!strcmp(message, "browse_folderSelect")) {
std::string filename;
#if PPSSPP_PLATFORM(ANDROID)
// Hacky way to get a normal path from a Android Storage Framework path.
// Is not gonna work forever, but ship-hack for 1.11.
std::string url = value;
const char *prefix = "content://com.android.externalstorage.documents/tree/";
const char *primaryPrefix = "/storage/primary/";
if (startsWith(url, prefix)) {
url = UriDecode(url.substr(strlen(prefix)));
size_t colonPos = url.find(":");
if (colonPos != std::string::npos) {
url[colonPos] = '/';
}
url = "/storage/" + url;
if (startsWith(url, primaryPrefix)) {
url = g_Config.memStickDirectory + url.substr(strlen(primaryPrefix));
}
INFO_LOG(SYSTEM, "Translated '%s' into '%s'", value, url.c_str());
} else {
// It's not gonna work.
// TODO: Show an error message?
INFO_LOG(SYSTEM, "Failed to parse content string: '%s'", value);
return;
}
filename = url;
#else
filename = value;
#endif
INFO_LOG(SYSTEM, "Got folder: '%s'", filename.c_str());
int tab = tabHolder_->GetCurrentTab();
if (tab >= 0 && tab < (int)gameBrowsers_.size()) {
gameBrowsers_[tab]->SetPath(value);
gameBrowsers_[tab]->SetPath(filename);
}
}
}
@@ -1245,6 +1248,17 @@ UI::EventReturn MainScreen::OnLoadFile(UI::EventParams &e) {
return UI::EVENT_DONE;
}
UI::EventReturn MainScreen::OnFullScreenToggle(UI::EventParams &e) {
if (fullscreenButton_) {
fullscreenButton_->SetImageID(ImageID(!g_Config.bFullScreen ? "I_RESTORE" : "I_FULLSCREEN"));
}
#if !defined(MOBILE_DEVICE)
g_Config.bFullScreen = !g_Config.bFullScreen;
System_SendMessage("toggle_fullscreen", "");
#endif
return UI::EVENT_DONE;
}
void MainScreen::DrawBackground(UIContext &dc) {
UIScreenWithBackground::DrawBackground(dc);
if (highlightedGamePath_.empty() && prevHighlightedGamePath_.empty()) {
+2
View File
@@ -125,9 +125,11 @@ protected:
UI::EventReturn OnDownloadUpgrade(UI::EventParams &e);
UI::EventReturn OnDismissUpgrade(UI::EventParams &e);
UI::EventReturn OnAllowStorage(UI::EventParams &e);
UI::EventReturn OnFullScreenToggle(UI::EventParams &e);
UI::LinearLayout *upgradeBar_ = nullptr;
UI::TabHolder *tabHolder_ = nullptr;
UI::Button *fullscreenButton_ = nullptr;
std::string restoreFocusGamePath_;
std::vector<GameBrowser *> gameBrowsers_;
+30 -3
View File
@@ -357,9 +357,31 @@ std::string System_GetProperty(SystemProperty prop) {
}
std::vector<std::string> System_GetPropertyStringVec(SystemProperty prop) {
std::vector<std::string> result;
switch (prop) {
case SYSPROP_TEMP_DIRS:
{
std::wstring tempPath(MAX_PATH, '\0');
size_t sz = GetTempPath((DWORD)tempPath.size(), &tempPath[0]);
if (sz >= tempPath.size()) {
tempPath.resize(sz);
sz = GetTempPath((DWORD)tempPath.size(), &tempPath[0]);
}
// Need to resize off the null terminator either way.
tempPath.resize(sz);
result.push_back(ConvertWStringToUTF8(tempPath));
if (getenv("TMPDIR") && strlen(getenv("TMPDIR")) != 0)
result.push_back(getenv("TMPDIR"));
if (getenv("TMP") && strlen(getenv("TMP")) != 0)
result.push_back(getenv("TMP"));
if (getenv("TEMP") && strlen(getenv("TEMP")) != 0)
result.push_back(getenv("TEMP"));
return result;
}
default:
return std::vector<std::string>();
return result;
}
}
@@ -447,11 +469,16 @@ void System_SendMessage(const char *command, const char *parameter) {
});
} else if (!strcmp(command, "toggle_fullscreen")) {
auto view = Windows::UI::ViewManagement::ApplicationView::GetForCurrentView();
bool flag = !view->IsFullScreenMode;
if (strcmp(parameter, "0") == 0) {
view->ExitFullScreenMode();
flag = false;
} else if (strcmp(parameter, "1") == 0){
flag = true;
}
else if (strcmp(parameter, "1") == 0){
if (flag) {
view->TryEnterFullScreenMode();
} else {
view->ExitFullScreenMode();
}
}
}
+6
View File
@@ -132,6 +132,7 @@ namespace MainWindow
static bool inFullscreenResize = false;
static bool inResizeMove = false;
static bool hasFocus = true;
static bool g_isFullscreen = false;
// gross hack
bool noFocusPause = false; // TOGGLE_PAUSE state to override pause on lost focus
@@ -355,6 +356,7 @@ namespace MainWindow
::SetMenu(hWnd, goingFullscreen ? NULL : menu);
g_Config.bFullScreen = goingFullscreen;
g_isFullscreen = goingFullscreen;
g_IgnoreWM_SIZE = false;
@@ -1029,4 +1031,8 @@ namespace MainWindow
PostMessage(hwndMain, WM_USER_TOGGLE_FULLSCREEN, fullscreen, 0);
}
bool IsFullscreen() {
return g_isFullscreen;
}
} // namespace
+1
View File
@@ -76,6 +76,7 @@ namespace MainWindow
void ToggleFullscreen(HWND hWnd, bool goingFullscreen);
void Minimize();
void SendToggleFullscreen(bool fullscreen); // To be used off-thread
bool IsFullscreen();
void ToggleDebugConsoleVisibility();
void SetInternalResolution(int res = -1);
void SetWindowSize(int zoom);
+24 -2
View File
@@ -217,9 +217,31 @@ std::string System_GetProperty(SystemProperty prop) {
}
std::vector<std::string> System_GetPropertyStringVec(SystemProperty prop) {
std::vector<std::string> result;
switch (prop) {
case SYSPROP_TEMP_DIRS:
{
std::wstring tempPath(MAX_PATH, '\0');
size_t sz = GetTempPath((DWORD)tempPath.size(), &tempPath[0]);
if (sz >= tempPath.size()) {
tempPath.resize(sz);
sz = GetTempPath((DWORD)tempPath.size(), &tempPath[0]);
}
// Need to resize off the null terminator either way.
tempPath.resize(sz);
result.push_back(ConvertWStringToUTF8(tempPath));
if (getenv("TMPDIR") && strlen(getenv("TMPDIR")) != 0)
result.push_back(getenv("TMPDIR"));
if (getenv("TMP") && strlen(getenv("TMP")) != 0)
result.push_back(getenv("TMP"));
if (getenv("TEMP") && strlen(getenv("TEMP")) != 0)
result.push_back(getenv("TEMP"));
return result;
}
default:
return std::vector<std::string>();
return result;
}
}
@@ -330,7 +352,7 @@ void System_SendMessage(const char *command, const char *parameter) {
} else if (!strcmp(command, "bgImage_browse")) {
MainWindow::BrowseBackground();
} else if (!strcmp(command, "toggle_fullscreen")) {
bool flag = !g_Config.bFullScreen;
bool flag = !MainWindow::IsFullscreen();
if (strcmp(parameter, "0") == 0) {
flag = false;
} else if (strcmp(parameter, "1") == 0) {
+7 -12
View File
@@ -17,6 +17,7 @@ ARCH_FILES := \
$(SRC)/Common/x64Emitter.cpp \
$(SRC)/Common/x64Analyzer.cpp \
$(SRC)/Common/CPUDetect.cpp \
$(SRC)/Common/Math/fast/fast_matrix_sse.c \
$(SRC)/Common/Thunk.cpp \
$(SRC)/Core/MIPS/x86/CompALU.cpp \
$(SRC)/Core/MIPS/x86/CompBranch.cpp \
@@ -39,6 +40,7 @@ ARCH_FILES := \
$(SRC)/Common/x64Emitter.cpp \
$(SRC)/Common/x64Analyzer.cpp \
$(SRC)/Common/CPUDetect.cpp \
$(SRC)/Common/Math/fast/fast_matrix_sse.c \
$(SRC)/Common/Thunk.cpp \
$(SRC)/Core/MIPS/x86/CompALU.cpp \
$(SRC)/Core/MIPS/x86/CompBranch.cpp \
@@ -62,6 +64,7 @@ ARCH_FILES := \
$(SRC)/Common/ArmEmitter.cpp \
$(SRC)/Common/ArmCPUDetect.cpp \
$(SRC)/Common/ColorConvNEON.cpp.neon \
$(SRC)/Common/Math/fast/fast_matrix_neon.S.neon \
$(SRC)/Core/MIPS/ARM/ArmCompALU.cpp \
$(SRC)/Core/MIPS/ARM/ArmCompBranch.cpp \
$(SRC)/Core/MIPS/ARM/ArmCompFPU.cpp \
@@ -76,6 +79,9 @@ ARCH_FILES := \
$(SRC)/Core/MIPS/ARM/ArmRegCacheFPU.cpp \
$(SRC)/GPU/Common/VertexDecoderArm.cpp \
$(SRC)/ext/disarm.cpp \
$(SRC)/ext/libpng17/arm/arm_init.c \
$(SRC)/ext/libpng17/arm/filter_neon_intrinsics.c \
$(SRC)/ext/libpng17/arm/filter_neon.S.neon \
ArmEmitterTest.cpp
endif
@@ -620,18 +626,6 @@ LOCAL_SRC_FILES := \
ifeq ($(findstring armeabi-v7a,$(TARGET_ARCH_ABI)),armeabi-v7a)
LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
$(SRC)/Common/Math/fast/fast_matrix_neon.S.neon \
$(SRC)/ext/libpng17/arm/arm_init.c \
$(SRC)/ext/libpng17/arm/filter_neon_intrinsics.c \
$(SRC)/ext/libpng17/arm/filter_neon.S.neon
else ifeq ($(TARGET_ARCH_ABI),x86)
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
$(SRC)/Common/Math/fast/fast_matrix_sse.c
else ifeq ($(TARGET_ARCH_ABI),x86_64)
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
$(SRC)/Common/Math/fast/fast_matrix_sse.c
endif
ifneq ($(SKIPAPP),1)
@@ -684,6 +678,7 @@ ifeq ($(UNITTEST),1)
LOCAL_MODULE := ppsspp_unittest
LOCAL_SRC_FILES := \
$(SRC)/unittest/JitHarness.cpp \
$(SRC)/unittest/TestShaderGenerators.cpp \
$(SRC)/unittest/TestVertexJit.cpp \
$(TESTARMEMITTER_FILE) \
$(SRC)/unittest/UnitTest.cpp
+7
View File
@@ -372,6 +372,8 @@ std::vector<std::string> System_GetPropertyStringVec(SystemProperty prop) {
switch (prop) {
case SYSPROP_ADDITIONAL_STORAGE_DIRS:
return g_additionalStorageDirs;
case SYSPROP_TEMP_DIRS:
default:
return std::vector<std::string>();
}
@@ -429,6 +431,11 @@ bool System_GetPropertyBool(SystemProperty prop) {
return true;
case SYSPROP_HAS_IMAGE_BROWSER:
return true;
case SYSPROP_HAS_FILE_BROWSER:
return false; // We kind of have but needs more work.
case SYSPROP_HAS_FOLDER_BROWSER:
// Uses OPEN_DOCUMENT_TREE to let you select a folder.
return androidVersion >= 21;
case SYSPROP_APP_GOLD:
#ifdef GOLD
return true;
@@ -25,6 +25,7 @@ import android.os.Bundle;
import android.os.Environment;
import android.os.PowerManager;
import android.os.Vibrator;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.InputType;
import android.util.Log;
@@ -99,7 +100,10 @@ public abstract class NativeActivity extends Activity {
// This is to avoid losing the game/menu state etc when we are just
// switched-away from or rotated etc.
private boolean shuttingDown;
private static final int RESULT_LOAD_IMAGE = 1;
private static final int RESULT_BROWSE_FILE = 2;
private static final int RESULT_OPEN_DOCUMENT_TREE = 3;
// Allow for multiple connected gamepads but just consider them the same for now.
// Actually this is not entirely true, see the code.
@@ -257,14 +261,27 @@ public abstract class NativeActivity extends Activity {
String removableStoragePath;
list = new ArrayList<String>();
File fileList[] = new File("/storage/").listFiles();
for (File file : fileList) {
if (!file.getAbsolutePath().equalsIgnoreCase(Environment.getExternalStorageDirectory().getAbsolutePath()) && file.isDirectory() && file.canRead()) {
list.add(file.getAbsolutePath());
if (fileList != null) {
for (File file : fileList) {
if (!file.getAbsolutePath().equalsIgnoreCase(Environment.getExternalStorageDirectory().getAbsolutePath()) && file.isDirectory() && file.canRead()) {
list.add(file.getAbsolutePath());
}
}
}
}
// TODO: On older devices, try System.getenv(“EXTERNAL_SDCARD_STORAGE”)
if (list == null) {
String[] varNames = { "EXTERNAL_SDCARD_STORAGE", "SECONDARY_STORAGE" };
for (String var : varNames) {
Log.i(TAG, "getSdCardPaths: Checking env " + var);
String secStore = System.getenv("SECONDARY_STORAGE");
if (secStore != null && secStore.length() > 0) {
list = new ArrayList<String>();
list.add(secStore);
break;
}
}
}
if (list == null) {
return new ArrayList<String>();
@@ -273,9 +290,6 @@ public abstract class NativeActivity extends Activity {
}
}
/**
* returns a list of all available sd cards paths, or null if not found.
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
private static ArrayList<String> getSdCardPaths19(final Context context)
{
@@ -300,8 +314,12 @@ public abstract class NativeActivity extends Activity {
if (file == null)
continue;
final String storageState = Environment.getStorageState(file);
if (Environment.MEDIA_MOUNTED.equals(storageState))
result.add(getRootOfInnerSdCardFolder(externalCacheDirs[i]));
if (Environment.MEDIA_MOUNTED.equals(storageState)) {
String root = getRootOfInnerSdCardFolder(externalCacheDirs[i]);
if (root != null) {
result.add(root);
}
}
}
if (result.isEmpty())
return null;
@@ -314,6 +332,9 @@ public abstract class NativeActivity extends Activity {
if (file == null)
return null;
final long totalSpace = file.getTotalSpace();
if (totalSpace <= 0) {
return null;
}
while (true) {
final File parentFile = file.getParentFile();
if (parentFile == null || !parentFile.canRead()) {
@@ -384,19 +405,25 @@ public abstract class NativeActivity extends Activity {
Log.i(TAG, "Ext storage: " + extStorageState + " " + extStorageDir);
ArrayList<String> sdCards = getSdCardPaths(this);
String additionalStorageDirs = "";
try {
ArrayList<String> sdCards = getSdCardPaths(this);
// String.join doesn't exist on old devices (???).
StringBuilder s = new StringBuilder();
for (int i = 0; i < sdCards.size(); i++) {
String sdCard = sdCards.get(i);
Log.i(TAG, "SD card: " + sdCard);
s.append(sdCard);
if (i != sdCards.size() - 1) {
s.append(":");
// String.join doesn't exist on old devices (???).
StringBuilder s = new StringBuilder();
for (int i = 0; i < sdCards.size(); i++) {
String sdCard = sdCards.get(i);
Log.i(TAG, "SD card: " + sdCard);
s.append(sdCard);
if (i != sdCards.size() - 1) {
s.append(":");
}
}
additionalStorageDirs = s.toString();
}
catch (Exception e) {
Log.e(TAG, "Failed to get SD storage dirs: " + e.toString());
}
String additionalStorageDirs = s.toString();
Log.i(TAG, "End of storage paths");
@@ -1098,7 +1125,10 @@ public abstract class NativeActivity extends Activity {
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
if (resultCode != RESULT_OK || data == null) {
return;
}
if (requestCode == RESULT_LOAD_IMAGE) {
Uri selectedImage = data.getData();
if (selectedImage != null) {
String[] filePathColumn = {MediaStore.Images.Media.DATA};
@@ -1109,6 +1139,20 @@ public abstract class NativeActivity extends Activity {
cursor.close();
NativeApp.sendMessage("bgImage_updated", picturePath);
}
} else if (requestCode == RESULT_BROWSE_FILE) {
Uri selectedFile = data.getData();
if (selectedFile != null) {
// NativeApp.sendMessage("br");
Log.i(TAG, "Browse file finished:" + selectedFile.toString());
}
} else if (requestCode == RESULT_OPEN_DOCUMENT_TREE) {
Uri selectedFile = data.getData();
if (selectedFile != null) {
// Convert URI to normal path. (This might not be possible in Android 12+)
String path = selectedFile.toString();
Log.i(TAG, "Browse folder finished: " + path);
NativeApp.sendMessage("browse_folderSelect", path);
}
}
}
@@ -1240,6 +1284,30 @@ public abstract class NativeActivity extends Activity {
Log.e(TAG, e.toString());
return false;
}
} else if (command.equals("browse_file")) {
try {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("application/octet-stream");
//intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri);
startActivityForResult(intent, RESULT_BROWSE_FILE);
} catch (Exception e) {
Log.e(TAG, e.toString());
return false;
}
} else if (command.equals("browse_folder")) {
try {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); // not yet used properly
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true); // Only allow local folders.
startActivityForResult(intent, RESULT_OPEN_DOCUMENT_TREE);
return true;
} catch (Exception e) {
Log.e(TAG, e.toString());
return false;
}
} else if (command.equals("sharejpeg")) {
try {
Intent share = new Intent(Intent.ACTION_SEND);
+12
View File
@@ -804,6 +804,18 @@ ULUS10132 = true
# Homebrew Kurok (we don't normally add homebrew here but it has a distinctive GameID)
KURO00767 = true
# Scooby-Doo! Who's Watching Who?
ULUS10168 = true
ULES00571 = true
# Tron Evolution
ULUS10548 = true
ULES01494 = true
ULES01495 = true
# Atari Classics Evolved
ULUS10325 = true
[JitInvalidationHack]
# This is an absolutely awful hack that somehow prevents issues when clearing the JIT,
# if the game has copied code with EmuHack opcodes or something. Hopefully will be able
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+6 -2
View File
@@ -2,10 +2,11 @@
// See headless.txt.
// To build on non-windows systems, just run CMake in the SDL directory, it will build both a normal ppsspp and the headless version.
#include "ppsspp_config.h"
#include <cstdio>
#include <cstdlib>
#include <limits>
#if defined(ANDROID)
#if PPSSPP_PLATFORM(ANDROID)
#include <jni.h>
#endif
@@ -38,7 +39,7 @@
#include "SDLHeadlessHost.h"
#endif
#if defined(ANDROID)
#if PPSSPP_PLATFORM(ANDROID)
JNIEnv *getEnv() {
return nullptr;
}
@@ -46,6 +47,9 @@ JNIEnv *getEnv() {
jclass findClass(const char *name) {
return nullptr;
}
bool audioRecording_Available() { return false; }
bool audioRecording_State() { return false; }
#endif
class PrintfLogger : public LogListener {
+1
View File
@@ -66,6 +66,7 @@ std::string System_GetProperty(SystemProperty prop) {
std::vector<std::string> System_GetPropertyStringVec(SystemProperty prop) {
switch (prop) {
case SYSPROP_TEMP_DIRS:
default:
return std::vector<std::string>();
}
+9
View File
@@ -1,3 +1,4 @@
#include "ppsspp_config.h"
#include <algorithm>
#include "Common/StringUtils.h"
@@ -13,11 +14,13 @@
#include "GPU/Common/VertexShaderGenerator.h"
#include "GPU/Common/ReinterpretFramebuffer.h"
#if PPSSPP_PLATFORM(WINDOWS)
#include "GPU/D3D11/D3D11Util.h"
#include "GPU/D3D11/D3D11Loader.h"
#include "GPU/D3D9/D3DCompilerLoader.h"
#include "GPU/D3D9/D3D9ShaderCompiler.h"
#endif
bool GenerateFShader(FShaderID id, char *buffer, ShaderLanguage lang, Draw::Bugs bugs, std::string *errorString) {
uint64_t uniformMask;
@@ -89,6 +92,7 @@ bool GenerateVShader(VShaderID id, char *buffer, ShaderLanguage lang, Draw::Bugs
bool TestCompileShader(const char *buffer, ShaderLanguage lang, bool vertex, std::string *errorMessage) {
std::vector<uint32_t> spirv;
switch (lang) {
#if PPSSPP_PLATFORM(WINDOWS)
case ShaderLanguage::HLSL_D3D11:
{
auto output = CompileShaderToBytecodeD3D11(buffer, strlen(buffer), vertex ? "vs_4_0" : "ps_4_0", 0);
@@ -104,6 +108,7 @@ bool TestCompileShader(const char *buffer, ShaderLanguage lang, bool vertex, std
return false;
}
}
#endif
case ShaderLanguage::GLSL_VULKAN:
return GLSLtoSPV(vertex ? VK_SHADER_STAGE_VERTEX_BIT : VK_SHADER_STAGE_FRAGMENT_BIT, buffer, GLSLVariant::VULKAN, spirv, errorMessage);
@@ -352,9 +357,13 @@ bool TestFragmentShaders() {
}
bool TestShaderGenerators() {
#if PPSSPP_PLATFORM(WINDOWS)
LoadD3D11();
init_glslang();
LoadD3DCompilerDynamic();
#else
init_glslang();
#endif
if (!TestFragmentShaders()) {
return false;
+6 -3
View File
@@ -27,17 +27,17 @@
// To use, set command line parameter to one or more of the tests below, or "all".
// Search for "availableTests".
#include "ppsspp_config.h"
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <string>
#include <sstream>
#if defined(ANDROID)
#if PPSSPP_PLATFORM(ANDROID)
#include <jni.h>
#endif
#include "ppsspp_config.h"
#include "Common/System/NativeApp.h"
#include "Common/System/System.h"
#include "Common/Input/InputState.h"
@@ -72,7 +72,7 @@ bool System_GetPropertyBool(SystemProperty prop) {
return false;
}
#if defined(ANDROID)
#if PPSSPP_PLATFORM(ANDROID)
JNIEnv *getEnv() {
return nullptr;
}
@@ -80,6 +80,9 @@ JNIEnv *getEnv() {
jclass findClass(const char *name) {
return nullptr;
}
bool audioRecording_Available() { return false; }
bool audioRecording_State() { return false; }
#endif
#ifndef M_PI_2