mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-12 17:19:28 +01:00
74 files changed
+393
-172
No files matched your search
@@ -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/
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -527,6 +527,9 @@ public:
|
||||
paddingW_ = w;
|
||||
paddingH_ = h;
|
||||
}
|
||||
void SetImageID(ImageID imageID) {
|
||||
imageID_ = imageID;
|
||||
}
|
||||
|
||||
// Needed an extra small button...
|
||||
void SetScale(float f) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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" },
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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_;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -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_;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -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()) {
|
||||
|
||||
@@ -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
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
@@ -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 {
|
||||
|
||||
@@ -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>();
|
||||
}
|
||||
|
||||
+1
-1
Submodule pspautotests updated: 7e4a1e7509...879e7959eb.
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user