Merge branch 'master' into TemporaryHackishBranch

# Conflicts:
#	Core/Util/AudioFormat.cpp
# bad path was disabled so let's just sync
#	UI/CwCheatScreen.cpp
# just because I keep parse function to use multiply cheat.db files
This commit is contained in:
LunaMoo committed 2017-11-30 23:17:57 +01:00
commit aa7b2430a0
47 files changed
+258 -177

No files matched your search

+4 -2
View File
@@ -733,9 +733,11 @@ void ARM64XEmitter::EncodeLoadStoreIndexedInst(u32 op, ARM64Reg Rt, ARM64Reg Rn,
else if (size == 16)
shift = 1;
_assert_msg_(DYNA_REC, ((imm >> shift) << shift) == imm, "%s(INDEX_UNSIGNED): offset must be aligned %d", __FUNCTION__, imm);
if (shift) {
_assert_msg_(DYNA_REC, ((imm >> shift) << shift) == imm, "%s(INDEX_UNSIGNED): offset must be aligned %d", __FUNCTION__, imm);
imm >>= shift;
}
imm >>= shift;
_assert_msg_(DYNA_REC, imm >= 0, "%s(INDEX_UNSIGNED): offset must be positive %d", __FUNCTION__, imm);
_assert_msg_(DYNA_REC, !(imm & ~0xFFF), "%s(INDEX_UNSIGNED): offset too large %d", __FUNCTION__, imm);
+21
View File
@@ -134,6 +134,27 @@ size_t VulkanPushBuffer::GetTotalSize() const {
return sum;
}
void VulkanPushBuffer::Map() {
assert(!writePtr_);
VkResult res = vkMapMemory(device_, buffers_[buf_].deviceMemory, 0, size_, 0, (void **)(&writePtr_));
assert(writePtr_);
assert(VK_SUCCESS == res);
}
void VulkanPushBuffer::Unmap() {
assert(writePtr_);
/*
// Should not need this since we use coherent memory.
VkMappedMemoryRange range = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE };
range.offset = 0;
range.size = offset_;
range.memory = buffers_[buf_].deviceMemory;
vkFlushMappedMemoryRanges(device_, 1, &range);
*/
vkUnmapMemory(device_, buffers_[buf_].deviceMemory);
writePtr_ = nullptr;
}
VulkanDeviceAllocator::VulkanDeviceAllocator(VulkanContext *vulkan, size_t minSlabSize, size_t maxSlabSize)
: vulkan_(vulkan), lastSlab_(0), minSlabSize_(minSlabSize), maxSlabSize_(maxSlabSize), memoryTypeIndex_(UNDEFINED_MEMORY_TYPE), destroyed_(false) {
assert((minSlabSize_ & (SLAB_GRAIN_SIZE - 1)) == 0);
+2 -19
View File
@@ -46,26 +46,9 @@ public:
Unmap();
}
void Map() {
assert(!writePtr_);
VkResult res = vkMapMemory(device_, buffers_[buf_].deviceMemory, 0, size_, 0, (void **)(&writePtr_));
assert(writePtr_);
assert(VK_SUCCESS == res);
}
void Map();
void Unmap() {
assert(writePtr_);
/*
// Should not need this since we use coherent memory.
VkMappedMemoryRange range = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE };
range.offset = 0;
range.size = offset_;
range.memory = buffers_[buf_].deviceMemory;
vkFlushMappedMemoryRanges(device_, 1, &range);
*/
vkUnmapMemory(device_, buffers_[buf_].deviceMemory);
writePtr_ = nullptr;
}
void Unmap();
// When using the returned memory, make sure to bind the returned vkbuf.
// This will later allow for handling overflow correctly.
+21 -2
View File
@@ -87,7 +87,12 @@ bool CheatFileParser::Parse() {
getline(file_, line, '\n');
line = TrimString(line);
if (line.length() > 2 && line[0] == '_') {
// Minimum length is set to 5 just to match GetCodesList() function
// which discards anything shorter when called anyway.
// It's decided from shortest possible _ lines name of the game "_G N+"
// and a minimum of 1 displayable character in cheat name string "_C0 1"
// which both equal to 5 characters.
if (line.length() >= 5 && line[0] == '_') {
ParseLine(line);
} else if (line.length() >= 2 && line[0] == '/' && line[1] == '/') {
// Comment, ignore.
@@ -340,7 +345,21 @@ std::vector<std::string> CWCheatEngine::GetCodesList() {
std::string line;
getline(list, line, '\n');
if (line.length() > 3 && (line.substr(0, 1) == "_" || line.substr(0, 2) == "//")) {
bool validCheatLine = false;
// This function is called by cheat menu(UI) which doesn't support empty names
// minimum 1 non space character is required starting from 5 position.
// It also goes through other "_" lines, but they all have to meet this requirement anyway
// so we don't have to specify any syntax checks here that are made by cheat engine.
if (line.length() >= 5 && line[0] == '_') {
for (int i = 4; i < line.length(); i++) {
if (line[i] != ' ') {
validCheatLine = true;
break;
}
}
}
// Any lines not passing this check are discarded when we save changes to the cheat ini file
if (validCheatLine || (line.length() >= 2 && line[0] == '/' && line[1] == '/') || (line.length() >= 1 && line[0] == '#')) {
codesList.push_back(TrimString(line));
}
}
+2 -2
View File
@@ -635,7 +635,7 @@ size_t hleFormatLogArgs(char *message, size_t sz, const char *argmask) {
// TODO: Double? Does it ever happen?
default:
_assert_msg_(HLE, false, "Invalid argmask character: %c", argmask[i]);
_dbg_assert_msg_(HLE, false, "Invalid argmask character: %c", argmask[i]);
APPEND_FMT(" -- invalid arg format: %c -- %08x", argmask[i], regval);
break;
}
@@ -673,7 +673,7 @@ void hleDoLogInternal(LogTypes::LOG_TYPE t, LogTypes::LOG_LEVELS level, u64 res,
// TODO: For now, floats are just shown as bits.
fmt = "%s%08x=%s(%s)%s";
} else {
_assert_msg_(HLE, false, "Invalid return format: %c", retmask);
_dbg_assert_msg_(HLE, false, "Invalid return format: %c", retmask);
fmt = "%s%08llx=%s(%s)%s";
}
-15
View File
@@ -106,21 +106,6 @@ void ArmJit::DoState(PointerWrap &p)
}
}
// This is here so the savestate matches between jit and non-jit.
void ArmJit::DoDummyState(PointerWrap &p)
{
auto s = p.Section("Jit", 1, 2);
if (!s)
return;
bool dummy = false;
p.Do(dummy);
if (s >= 2) {
dummy = true;
p.Do(dummy);
}
}
void ArmJit::FlushAll()
{
gpr.FlushAll();
-1
View File
@@ -39,7 +39,6 @@ public:
virtual ~ArmJit();
void DoState(PointerWrap &p) override;
void DoDummyState(PointerWrap &p) override;
const JitOptions &GetJitOptions() { return jo; }
-14
View File
@@ -98,20 +98,6 @@ void Arm64Jit::DoState(PointerWrap &p) {
}
}
// This is here so the savestate matches between jit and non-jit.
void Arm64Jit::DoDummyState(PointerWrap &p) {
auto s = p.Section("Jit", 1, 2);
if (!s)
return;
bool dummy = false;
p.Do(dummy);
if (s >= 2) {
dummy = true;
p.Do(dummy);
}
}
void Arm64Jit::FlushAll()
{
gpr.FlushAll();
-1
View File
@@ -39,7 +39,6 @@ public:
virtual ~Arm64Jit();
void DoState(PointerWrap &p) override;
void DoDummyState(PointerWrap &p) override;
const JitOptions &GetJitOptions() { return jo; }
-14
View File
@@ -50,20 +50,6 @@ void IRJit::DoState(PointerWrap &p) {
frontend_.DoState(p);
}
// This is here so the savestate matches between jit and non-jit.
void IRJit::DoDummyState(PointerWrap &p) {
auto s = p.Section("Jit", 1, 2);
if (!s)
return;
bool dummy = false;
p.Do(dummy);
if (s >= 2) {
dummy = true;
p.Do(dummy);
}
}
void IRJit::ClearCache() {
ILOG("IRJit: Clearing the cache!");
blocks_.Clear();
-1
View File
@@ -127,7 +127,6 @@ public:
virtual ~IRJit();
void DoState(PointerWrap &p) override;
void DoDummyState(PointerWrap &p) override;
const JitOptions &GetJitOptions() { return jo; }
+16
View File
@@ -21,6 +21,8 @@
#include "ext/udis86/udis86.h"
#include "Common/StringUtils.h"
#include "Common/ChunkFile.h"
#include "Core/Util/DisArm64.h"
#include "Core/Config.h"
@@ -46,6 +48,20 @@ namespace MIPSComp {
jit->Compile(currentMIPS->pc);
}
void DoDummyJitState(PointerWrap &p) {
// This is here so the savestate matches between jit and non-jit.
auto s = p.Section("Jit", 1, 2);
if (!s)
return;
bool dummy = false;
p.Do(dummy);
if (s >= 2) {
dummy = true;
p.Do(dummy);
}
}
JitInterface *CreateNativeJit(MIPSState *mips) {
#if PPSSPP_ARCH(ARM)
return new MIPSComp::ArmJit(mips);
+2 -1
View File
@@ -125,7 +125,6 @@ namespace MIPSComp {
virtual JitBlockCache *GetBlockCache() = 0;
virtual void InvalidateCacheAt(u32 em_address, int length = 4) = 0;
virtual void DoState(PointerWrap &p) = 0;
virtual void DoDummyState(PointerWrap &p) = 0;
virtual void RunLoopUntil(u64 globalticks) = 0;
virtual void Compile(u32 em_address) = 0;
virtual void ClearCache() = 0;
@@ -147,5 +146,7 @@ namespace MIPSComp {
extern JitInterface *jit;
void DoDummyJitState(PointerWrap &p);
JitInterface *CreateNativeJit(MIPSState *mips);
}
+1 -1
View File
@@ -262,7 +262,7 @@ void MIPSState::DoState(PointerWrap &p) {
if (MIPSComp::jit)
MIPSComp::jit->DoState(p);
else
MIPSComp::jit->DoDummyState(p);
MIPSComp::DoDummyJitState(p);
p.DoArray(r, sizeof(r) / sizeof(r[0]));
p.DoArray(f, sizeof(f) / sizeof(f[0]));
-15
View File
@@ -66,21 +66,6 @@ void MipsJit::DoState(PointerWrap &p)
}
}
// This is here so the savestate matches between jit and non-jit.
void MipsJit::DoDummyState(PointerWrap &p)
{
auto s = p.Section("Jit", 1, 2);
if (!s)
return;
bool dummy = false;
p.Do(dummy);
if (s >= 2) {
dummy = true;
p.Do(dummy);
}
}
void MipsJit::FlushAll()
{
//gpr.FlushAll();
-1
View File
@@ -38,7 +38,6 @@ public:
MipsJit(MIPSState *mips);
void DoState(PointerWrap &p) override;
void DoDummyState(PointerWrap &p) override;
// Compiled ops should ignore delay slots
// the compiler will take care of them by itself
-15
View File
@@ -142,21 +142,6 @@ void Jit::DoState(PointerWrap &p) {
CBreakPoints::SetSkipFirst(0);
}
// This is here so the savestate matches between jit and non-jit.
void Jit::DoDummyState(PointerWrap &p) {
auto s = p.Section("Jit", 1, 2);
if (!s)
return;
bool dummy = false;
p.Do(dummy);
if (s >= 2) {
dummy = true;
p.Do(dummy);
}
}
void Jit::GetStateAndFlushAll(RegCacheState &state) {
gpr.GetState(state.gpr);
fpr.GetState(state.fpr);
-1
View File
@@ -52,7 +52,6 @@ public:
const JitOptions &GetJitOptions() { return jo; }
void DoState(PointerWrap &p) override;
void DoDummyState(PointerWrap &p) override;
// Compiled ops should ignore delay slots
// the compiler will take care of them by itself
+32 -11
View File
@@ -26,7 +26,7 @@
void AdjustVolumeBlockStandard(s16 *out, s16 *in, size_t size, int leftVol, int rightVol) {
#ifdef _M_SSE
if (leftVol <= 0x7fff && rightVol <= 0x7fff) {
if (leftVol <= 0x7fff && -leftVol <= 0x8000 && rightVol <= 0x7fff && -rightVol <= 0x8000) {
__m128i volume = _mm_set_epi16(leftVol, rightVol, leftVol, rightVol, leftVol, rightVol, leftVol, rightVol);
while (size >= 16) {
__m128i indata1 = _mm_loadu_si128((__m128i *)in);
@@ -37,25 +37,46 @@ void AdjustVolumeBlockStandard(s16 *out, s16 *in, size_t size, int leftVol, int
out += 16;
size -= 16;
}
} else {
// We have to shift inside the loop to avoid the signed multiply issue.
leftVol >>= 1;
rightVol >>= 1;
__m128i volume = _mm_set_epi16(leftVol, rightVol, leftVol, rightVol, leftVol, rightVol, leftVol, rightVol);
}
#if 0
// This path wraps instead of clamps in _mm_slli_epi16. Needs fixing.
else {
// We have to shift inside the loop to avoid the signed 16-bit multiply issue.
int leftShift = 0;
int leftVol16 = leftVol;
while (leftVol16 > 0x7fff || -leftVol16 > 0x8000) {
++leftShift;
leftVol16 >>= 1;
}
int rightShift = 0;
int rightVol16 = rightVol;
while (rightVol16 > 0x7fff || -rightVol16 > 0x8000) {
++rightShift;
rightVol16 >>= 1;
}
__m128i volume = _mm_set_epi16(leftVol16, rightVol16, leftVol16, rightVol16, leftVol16, rightVol16, leftVol16, rightVol16);
while (size >= 16) {
__m128i indata1 = _mm_loadu_si128((__m128i *)in);
__m128i indata2 = _mm_loadu_si128((__m128i *)(in + 8));
_mm_storeu_si128((__m128i *)out, _mm_slli_epi16(_mm_mulhi_epi16(indata1, volume), 1));
_mm_storeu_si128((__m128i *)(out + 8), _mm_slli_epi16(_mm_mulhi_epi16(indata2, volume), 1));
_mm_storeu_si128((__m128i *)out, _mm_slli_epi16(_mm_mulhi_epi16(indata1, volume), leftShift));
_mm_storeu_si128((__m128i *)(out + 8), _mm_slli_epi16(_mm_mulhi_epi16(indata2, volume), rightShift));
in += 16;
out += 16;
size -= 16;
}
}
#endif
for (size_t i = 0; i < size; i += 2) {
out[i] = ApplySampleVolume(in[i], leftVol);
out[i + 1] = ApplySampleVolume(in[i + 1], rightVol);
#endif
if (leftVol <= 0x7fff && -leftVol <= 0x8000 && rightVol <= 0x7fff && -rightVol <= 0x8000) {
for (size_t i = 0; i < size; i += 2) {
out[i] = ApplySampleVolume(in[i], leftVol);
out[i + 1] = ApplySampleVolume(in[i + 1], rightVol);
}
} else {
for (size_t i = 0; i < size; i += 2) {
out[i] = ApplySampleVolume20Bit(in[i], leftVol);
out[i + 1] = ApplySampleVolume20Bit(in[i + 1], rightVol);
}
}
}
+6
View File
@@ -59,6 +59,12 @@ static inline s16 ApplySampleVolume(s16 sample, int vol) {
#endif
}
// We sacrifice a little volume precision to fit in 32 bits, for speed.
// Probably not worth it to make a special path for 64-bit CPUs.
static inline s16 ApplySampleVolume20Bit(s16 sample, int vol20) {
return clamp_s16((sample * (vol20 >> 4)) >> 12);
}
void SetupAudioFormats();
void AdjustVolumeBlockStandard(s16 *out, s16 *in, size_t size, int leftVol, int rightVol);
void ConvertS16ToF32(float *ou, const s16 *in, size_t size);
+10 -3
View File
@@ -55,9 +55,16 @@ void AdjustVolumeBlockNEON(s16 *out, s16 *in, size_t size, int leftVol, int righ
size -= 16;
}
for (size_t i = 0; i < size; i += 2) {
out[i] = ApplySampleVolume(in[i], leftVol);
out[i + 1] = ApplySampleVolume(in[i + 1], rightVol);
if (leftVol <= 0x7fff && -leftVol <= 0x8000 && rightVol <= 0x7fff && -rightVol <= 0x8000) {
for (size_t i = 0; i < size; i += 2) {
out[i] = ApplySampleVolume(in[i], leftVol);
out[i + 1] = ApplySampleVolume(in[i + 1], rightVol);
}
} else {
for (size_t i = 0; i < size; i += 2) {
out[i] = ApplySampleVolume20Bit(in[i], leftVol);
out[i + 1] = ApplySampleVolume20Bit(in[i + 1], rightVol);
}
}
}
+5 -2
View File
@@ -136,6 +136,8 @@ FramebufferManagerCommon::~FramebufferManagerCommon() {
DestroyFramebuf(vfb);
}
bvfbs_.clear();
SetNumExtraFBOs(0);
}
void FramebufferManagerCommon::Init() {
@@ -201,7 +203,7 @@ bool FramebufferManagerCommon::ShouldDownloadFramebuffer(const VirtualFramebuffe
void FramebufferManagerCommon::SetNumExtraFBOs(int num) {
for (size_t i = 0; i < extraFBOs_.size(); i++) {
extraFBOs_[i]->Release();
extraFBOs_[i]->ReleaseAssertLast();
}
extraFBOs_.clear();
for (int i = 0; i < num; i++) {
@@ -210,7 +212,8 @@ void FramebufferManagerCommon::SetNumExtraFBOs(int num) {
extraFBOs_.push_back(fbo);
}
currentRenderVfb_ = 0;
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
if (num != 0)
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
}
// Heuristics to figure out the size of FBO to create.
+6 -1
View File
@@ -698,7 +698,12 @@ void VertexDecoderJitCache::Jit_PosS16Through() {
}
void VertexDecoderJitCache::Jit_NormalS8() {
LDRH(INDEX_UNSIGNED, tempReg1, srcReg, dec_->nrmoff);
// nrmoff can be odd in case of byte-only vertices! odd unsigned offsets are not allowed for LDRH.
// Switching to LDRB.
// Only seen this in a crash log.
LDRB(INDEX_UNSIGNED, tempReg1, srcReg, dec_->nrmoff);
LDRB(INDEX_UNSIGNED, tempReg3, srcReg, dec_->nrmoff + 1);
ORR(tempReg1, tempReg1, tempReg3, ArithOption(tempReg3, ST_LSL, 8));
LDRB(INDEX_UNSIGNED, tempReg3, srcReg, dec_->nrmoff + 2);
ORR(tempReg1, tempReg1, tempReg3, ArithOption(tempReg3, ST_LSL, 16));
STR(INDEX_UNSIGNED, tempReg1, dstReg, dec_->decFmt.nrmoff);
+7 -3
View File
@@ -148,9 +148,13 @@ void ShaderManagerDX9::PSSetColorUniform3(int creg, u32 color) {
}
void ShaderManagerDX9::PSSetColorUniform3Alpha255(int creg, u32 color, u8 alpha) {
float f[4];
Uint8x3ToFloat4_AlphaUint8(f, color, alpha);
device_->SetPixelShaderConstantF(creg, f, 1);
const float col[4] = {
(float)((color & 0xFF)),
(float)((color & 0xFF00) >> 8),
(float)((color & 0xFF0000) >> 16),
(float)alpha,
};
device_->SetPixelShaderConstantF(creg, col, 1);
}
void ShaderManagerDX9::PSSetFloat(int creg, float value) {
-1
View File
@@ -250,7 +250,6 @@ FramebufferManagerGLES::~FramebufferManagerGLES() {
if (stencilUploadProgram_) {
glsl_destroy(stencilUploadProgram_);
}
SetNumExtraFBOs(0);
for (auto it = tempFBOs_.begin(), end = tempFBOs_.end(); it != end; ++it) {
it->second.fbo->Release();
+2 -1
View File
@@ -69,7 +69,8 @@ DepalShaderCacheVulkan::~DepalShaderCacheVulkan() {
void DepalShaderCacheVulkan::DeviceLost() {
Clear();
vulkan_->Delete().QueueDeleteShaderModule(vshader_);
if (vshader_)
vulkan_->Delete().QueueDeleteShaderModule(vshader_);
draw_ = nullptr;
vulkan_ = nullptr;
}
+5 -3
View File
@@ -247,9 +247,11 @@ void DrawEngineVulkan::DestroyDeviceObjects() {
delete nullTexture_;
nullTexture_ = nullptr;
}
vertexCache_->Destroy(vulkan_);
delete vertexCache_;
vertexCache_ = nullptr;
if (vertexCache_) {
vertexCache_->Destroy(vulkan_);
delete vertexCache_;
vertexCache_ = nullptr;
}
// Need to clear this to get rid of all remaining references to the dead buffers.
vai_.Iterate([](uint32_t hash, VertexArrayInfoVulkan *vai) {
delete vai;
+1 -2
View File
@@ -301,8 +301,7 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip
VulkanPipeline *PipelineManagerVulkan::GetOrCreatePipeline(VkPipelineLayout layout, VkRenderPass renderPass, const VulkanPipelineRasterStateKey &rasterKey, const DecVtxFormat *decFmt, VulkanVertexShader *vs, VulkanFragmentShader *fs, bool useHwTransform) {
VulkanPipelineKey key{};
if (!renderPass)
Crash();
_assert_msg_(G3D, renderPass, "Can't create a pipeline with a null renderpass");
key.raster = rasterKey;
key.renderPass = renderPass;
+17
View File
@@ -27,6 +27,23 @@ For the latest source code, see [our github page](https://github.com/hrydgard/pp
For build instructions and other development tutorials, see the [wiki](https://github.com/hrydgard/ppsspp/wiki).
What's new in 1.5.0
-------------------
* Full Vulkan support, also for Android now. Very fast on supported devices. (#10033, #10049)
* Smarter graphics state management, reduced CPU consumption on all backends (#9899)
* Android: Support for Arabic and other scripts we couldn't support before
* Fix Android widgets, screen scaling (#10145)
* Fixes to video dumping
* Geometry problems fixed in Medal of Honor
* Implement immediate draws, fixing Thrillville (#7459)
* Software rendering improvements, speed and accuracy
* Hardware tesselation of PSP Beziers and Splines (used by a few games)
* Partial sceUsbGps and sceUsbCam support (Android)
* Android "Sustained performance mode" to avoid thermal throttling (#9901)
* Linux controller mapping fixes (#9997)
* Assorted bugfixes and compatibility improvements
What's new in 1.4.2
-------------------
* Fixed longstanding bug causing games to crash on ARM64
+14 -12
View File
@@ -65,9 +65,9 @@ void CwCheatScreen::CreateCodeList() {
bEnableCheat.clear();
formattedList_.clear();
for (size_t i = 0; i < cheatList.size(); i++) {
if (cheatList[i].substr(0, 2) == "_C") {
if (cheatList[i][0] == '_' && cheatList[i][1] == 'C') {
formattedList_.push_back(cheatList[i].substr(4));
if (cheatList[i].substr(2, 1) == "0") {
if (cheatList[i][2] == '0') {
bEnableCheat.push_back(false);
} else {
bEnableCheat.push_back(true);
@@ -136,11 +136,11 @@ UI::EventReturn CwCheatScreen::OnEnableAll(UI::EventParams &params) {
enableAll = !enableAll;
File::OpenCPPFile(fs, activeCheatFile, std::ios::out);
for (int j = 0; j < (int)cheatList.size(); j++) {
if (cheatList[j].substr(0, 2) == "_C") {
if (cheatList[j].substr(2, 1) == "0" && enableAll) {
cheatList[j].replace(2, 1, "1");
} else if (cheatList[j].substr(2, 1) != "0" && !enableAll) {
cheatList[j].replace(2, 1, "0");
if (cheatList[j][0] == '_' && cheatList[j][1] == 'C') {
if (cheatList[j][2] == '0' && enableAll) {
cheatList[j][2] = '1';
} else if (cheatList[j][2] != '0' && !enableAll) {
cheatList[j][2] = '0';
}
}
}
@@ -181,6 +181,8 @@ UI::EventReturn CwCheatScreen::OnEditCheatFile(UI::EventParams &params) {
void CwCheatScreen::ParseCheatDB(std::string line, std::vector<std::string> title, std::vector<std::string> newList, std::string cheatFile) {
bool finished = false, skip = false;
std::string gameID = StringFromFormat("_S %s-%s", gameTitle.substr(0, 4).c_str(), gameTitle.substr(4).c_str());
std::fstream fs;
File::OpenCPPFile(fs, cheatFile, std::ios::in);
@@ -190,7 +192,7 @@ void CwCheatScreen::ParseCheatDB(std::string line, std::vector<std::string> titl
while (fs.good()) {
getline(fs, line); // get line from file
if (line == "_S " + gameTitle.substr(0, 4) + "-" + gameTitle.substr(4)) {
if (line == gameID) {
title.push_back(line);
getline(fs, line);
title.push_back(line);
@@ -198,7 +200,7 @@ void CwCheatScreen::ParseCheatDB(std::string line, std::vector<std::string> titl
if (finished == false) {
getline(fs, line);
}
if (line.substr(0, 2) == "_C") {
if (line[0] == '_' && line[1] == 'C') {
//Test if cheat already exists in cheatList
for (size_t j = 0; j < formattedList_.size(); j++) {
if (line.substr(4) == formattedList_[j]) {
@@ -212,14 +214,14 @@ void CwCheatScreen::ParseCheatDB(std::string line, std::vector<std::string> titl
do {
newList.push_back(line);
getline(fs, line);
} while (line.substr(0, 2) == "_L");
} while (line[0] == '_' && line[1] == 'L');
finished = true;
}
else {
continue;
}
loop:;
} while (line.substr(0, 2) != "_S");
} while (fs.good() && line[0] != '_' && line[1] != 'S');
finished = true;
}
if (finished == true)
@@ -234,7 +236,7 @@ void CwCheatScreen::ParseCheatDB(std::string line, std::vector<std::string> titl
File::OpenCPPFile(fs, activeCheatFile, std::ios::out | std::ios::app);
auto it = title.begin();
if (title2.substr(0, 2) != "_S" && it != title.end() && (++it) != title.end()) {
if (title2[0] != '_' && title2[1] != 'S' && it != title.end() && (++it) != title.end()) {
fs << title[0] << "\n" << title[1];
}
+6
View File
@@ -534,6 +534,7 @@ void CreditsScreen::CreateViews() {
}
root_->Add(new Button(cr->T("PPSSPP Forums"), new AnchorLayoutParams(260, 64, 10, NONE, NONE, 84, false)))->OnClick.Handle(this, &CreditsScreen::OnForums);
root_->Add(new Button("www.ppsspp.org", new AnchorLayoutParams(260, 64, 10, NONE, NONE, 158, false)))->OnClick.Handle(this, &CreditsScreen::OnPPSSPPOrg);
root_->Add(new Button(cr->T("Privacy Policy"), new AnchorLayoutParams(260, 64, 10, NONE, NONE, 232, false)))->OnClick.Handle(this, &CreditsScreen::OnPrivacy);
#ifdef __ANDROID__
root_->Add(new Button(cr->T("Share PPSSPP"), new AnchorLayoutParams(260, 64, NONE, NONE, 10, 84, false)))->OnClick.Handle(this, &CreditsScreen::OnShare);
root_->Add(new Button(cr->T("Twitter @PPSSPP_emu"), new AnchorLayoutParams(260, 64, NONE, NONE, 10, 154, false)))->OnClick.Handle(this, &CreditsScreen::OnTwitter);
@@ -568,6 +569,11 @@ UI::EventReturn CreditsScreen::OnPPSSPPOrg(UI::EventParams &e) {
return UI::EVENT_DONE;
}
UI::EventReturn CreditsScreen::OnPrivacy(UI::EventParams &e) {
LaunchBrowser("https://www.ppsspp.org/privacy.html");
return UI::EVENT_DONE;
}
UI::EventReturn CreditsScreen::OnForums(UI::EventParams &e) {
LaunchBrowser("https://forums.ppsspp.org");
return UI::EVENT_DONE;
+1 -1
View File
@@ -142,8 +142,8 @@ private:
UI::EventReturn OnSupport(UI::EventParams &e);
UI::EventReturn OnPPSSPPOrg(UI::EventParams &e);
UI::EventReturn OnPrivacy(UI::EventParams &e);
UI::EventReturn OnForums(UI::EventParams &e);
UI::EventReturn OnChineseForum(UI::EventParams &e);
UI::EventReturn OnShare(UI::EventParams &e);
UI::EventReturn OnTwitter(UI::EventParams &e);
+4 -1
View File
@@ -613,12 +613,14 @@ static void UIThemeInit() {
void RenderOverlays(UIContext *dc, void *userdata);
void NativeInitGraphics(GraphicsContext *graphicsContext) {
bool NativeInitGraphics(GraphicsContext *graphicsContext) {
ILOG("NativeInitGraphics");
_assert_msg_(G3D, graphicsContext, "No graphics context!");
using namespace Draw;
Core_SetGraphicsContext(graphicsContext);
g_draw = graphicsContext->GetDrawContext();
_assert_msg_(G3D, g_draw, "No draw context available!");
ui_draw2d.SetAtlas(&ui_atlas);
ui_draw2d_front.SetAtlas(&ui_atlas);
@@ -694,6 +696,7 @@ void NativeInitGraphics(GraphicsContext *graphicsContext) {
g_graphicsInited = true;
ILOG("NativeInitGraphics completed");
return true;
}
void NativeShutdownGraphics() {
+2 -2
View File
@@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.ppsspp.ppsspp"
android:installLocation="auto"
android:versionCode="14200000"
android:versionName="1.4.2.0">
android:versionCode="15000000"
android:versionName="1.5.0.0">
<!-- For the next release: Note that versionCode should be in the format xyzzrrrr -->
<uses-sdk
+2 -1
View File
@@ -1,5 +1,5 @@
plugins {
id 'com.gladed.androidgitversion' version '0.3.4'
id 'com.gladed.androidgitversion' version '0.4.3'
}
apply plugin: 'com.android.application'
@@ -7,6 +7,7 @@ androidGitVersion {
codeFormat = "MNPPBBBB"
format = "%tag%%-count%%-branch%%-dirty%"
prefix = "v" // Only tags beginning with v are considered.
untrackedIsDirty = false
}
android {
+3 -1
View File
@@ -742,6 +742,8 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env,
if (javaGL && !graphicsContext) {
graphicsContext = new AndroidJavaEGLGraphicsContext();
} else if (!graphicsContext) {
_assert_msg_(G3D, false, "No graphics context in displayInit?");
}
if (renderer_inited) {
@@ -750,7 +752,6 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env,
NativeShutdownGraphics();
NativeDeviceRestore();
NativeInitGraphics(graphicsContext);
ILOG("Restored.");
} else {
ILOG("NativeApp.displayInit() first time");
@@ -1139,6 +1140,7 @@ retry:
}
delete graphicsContext;
graphicsContext = nullptr;
return false;
}
@@ -20,17 +20,18 @@ class LocationHelper implements LocationListener {
void startLocationUpdates() {
Log.d(TAG, "startLocationUpdates");
if (!mLocationEnable) {
boolean isGPSEnabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
boolean isNetworkEnabled = mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
try {
isGPSEnabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this);
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, this);
mLocationEnable = true;
} catch (SecurityException e) {
Log.e(TAG, "Cannot start location updates: " + e.toString());
}
if(!isGPSEnabled && !isNetworkEnabled) {
if (!isGPSEnabled && !isNetworkEnabled) {
Log.i(TAG, "No location provider found");
// TODO: notify user
}
+1 -1
View File
@@ -49,7 +49,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
// Runs after NativeInit() at some point. May (and probably should) call OpenGL.
// Should not initialize anything screen-size-dependent - do that in NativeResized.
void NativeInitGraphics(GraphicsContext *graphicsContext);
bool NativeInitGraphics(GraphicsContext *graphicsContext);
// Signals that you need to forget all buffered OpenGL resources,
// like textures, vbo etc.
+17 -10
View File
@@ -467,7 +467,8 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
vkCmdEndRenderPass(cmd);
// Transition the framebuffer if requested.
if (fb && step.render.finalColorLayout != VK_IMAGE_LAYOUT_UNDEFINED) {
// Don't need to transition it if VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.
if (fb && step.render.finalColorLayout != VK_IMAGE_LAYOUT_UNDEFINED && step.render.finalColorLayout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
VkImageMemoryBarrier barrier{};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.oldLayout = fb->color.layout;
@@ -490,6 +491,9 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
break;
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
break;
default:
Crash();
}
@@ -517,8 +521,8 @@ void VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKRStep &step
// Now, if the image needs transitioning, let's transition.
// The backbuffer does not, that's handled by VulkanContext.
if (step.render.framebuffer->color.layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
VkAccessFlags srcAccessMask;
VkPipelineStageFlags srcStage;
VkAccessFlags srcAccessMask = 0;
VkPipelineStageFlags srcStage = 0;
switch (fb->color.layout) {
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
@@ -533,7 +537,7 @@ void VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKRStep &step
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
break;
default:
Crash();
_dbg_assert_msg_(G3D, false, "PerformBindRT: Unexpected color layout %d", (int)fb->color.layout);
break;
}
@@ -545,8 +549,8 @@ void VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKRStep &step
fb->color.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
}
if (fb->depth.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
VkAccessFlags srcAccessMask;
VkPipelineStageFlags srcStage;
VkAccessFlags srcAccessMask = 0;
VkPipelineStageFlags srcStage = 0;
switch (fb->depth.layout) {
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
@@ -562,7 +566,7 @@ void VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKRStep &step
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
break;
default:
Crash();
_dbg_assert_msg_(G3D, false, "PerformBindRT: Unexpected depth layout %d", (int)fb->color.layout);
break;
}
@@ -791,7 +795,8 @@ void VulkanQueueRunner::SetupTransitionToTransferSrc(VKRImage &img, VkImageMemor
stage |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
break;
default:
Crash();
_dbg_assert_msg_(G3D, false, "Transition from this layout to transfer src not supported (%d)", (int)img.layout);
break;
}
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
@@ -826,7 +831,8 @@ void VulkanQueueRunner::SetupTransitionToTransferDst(VKRImage &img, VkImageMemor
stage |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
break;
default:
Crash();
_dbg_assert_msg_(G3D, false, "Transition from this layout to transfer dst not supported (%d)", (int)img.layout);
break;
}
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
@@ -869,7 +875,8 @@ void VulkanQueueRunner::PerformReadback(const VKRStep &step, VkCommandBuffer cmd
srcImage = &step.readback.src->depth;
}
else {
assert(false);
_dbg_assert_msg_(G3D, false, "No image aspect to readback?");
return;
}
VkImageMemoryBarrier barrier{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
@@ -690,6 +690,12 @@ VkImageView VulkanRenderManager::BindFramebufferAsTexture(VKRFramebuffer *fb, in
}
}
if (!curRenderStep_->preTransitions.empty() &&
curRenderStep_->preTransitions.back().fb == fb &&
curRenderStep_->preTransitions.back().targetLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
// We're done.
return fb->color.imageView;
}
curRenderStep_->preTransitions.push_back({ fb, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL });
return fb->color.imageView;
}
+14 -7
View File
@@ -51,13 +51,20 @@ public:
}
~VKRFramebuffer() {
vulkan_->Delete().QueueDeleteImage(color.image);
vulkan_->Delete().QueueDeleteImage(depth.image);
vulkan_->Delete().QueueDeleteImageView(color.imageView);
vulkan_->Delete().QueueDeleteImageView(depth.imageView);
vulkan_->Delete().QueueDeleteDeviceMemory(color.memory);
vulkan_->Delete().QueueDeleteDeviceMemory(depth.memory);
vulkan_->Delete().QueueDeleteFramebuffer(framebuf);
if (color.image)
vulkan_->Delete().QueueDeleteImage(color.image);
if (depth.image)
vulkan_->Delete().QueueDeleteImage(depth.image);
if (color.imageView)
vulkan_->Delete().QueueDeleteImageView(color.imageView);
if (depth.imageView)
vulkan_->Delete().QueueDeleteImageView(depth.imageView);
if (color.memory)
vulkan_->Delete().QueueDeleteDeviceMemory(color.memory);
if (depth.memory)
vulkan_->Delete().QueueDeleteDeviceMemory(depth.memory);
if (framebuf)
vulkan_->Delete().QueueDeleteFramebuffer(framebuf);
}
int numShadows = 1; // TODO: Support this.
+16
View File
@@ -4,6 +4,7 @@
#include "base/logging.h"
#include "thin3d/thin3d.h"
#include "Common/Log.h"
#include "Common/ColorConv.h"
namespace Draw {
@@ -75,11 +76,26 @@ bool RefCountedObject::Release() {
}
}
else {
_dbg_assert_msg_(G3D, false, "Refcount (%d) invalid for object %p - corrupt?", refcount_, this);
}
return false;
}
bool RefCountedObject::ReleaseAssertLast() {
_dbg_assert_msg_(G3D, refcount_ == 1, "RefCountedObject: Expected to be the last reference, but isn't!");
if (refcount_ > 0 && refcount_ < 10000) {
refcount_--;
if (refcount_ == 0) {
delete this;
return true;
}
} else {
ELOG("Refcount (%d) invalid for object %p - corrupt?", refcount_, this);
}
return false;
}
// ================================== PIXEL/FRAGMENT SHADERS
// The Vulkan ones can be re-used with modern GL later if desired, as they're just GLSL.
+1
View File
@@ -346,6 +346,7 @@ public:
void AddRef() { refcount_++; }
bool Release();
bool ReleaseAssertLast();
private:
int refcount_;
-1
View File
@@ -1298,7 +1298,6 @@ uint32_t VKContext::GetDataFormatSupport(DataFormat fmt) const {
// use this frame's init command buffer.
class VKFramebuffer : public Framebuffer {
public:
// Inherits ownership so no AddRef.
VKFramebuffer(VKRFramebuffer *fb) : buf_(fb) {}
~VKFramebuffer() {
buf_->vulkan_->Delete().QueueCallback([](void *fb) {
+1 -1
View File
@@ -264,7 +264,7 @@ private:
const char *category_;
ScreenManager *screenManager_;
std::string valueText_;
bool restoreFocus_;
bool restoreFocus_ = false;
std::set<int> hidden_;
};
+4 -2
View File
@@ -1314,8 +1314,10 @@ EventReturn ListView::OnItemCallback(int num, EventParams &e) {
View *focused = GetFocusedView();
OnChoice.Trigger(ev);
CreateAllItems();
if (focused)
SetFocusedView(e.v);
// TODO: At this point, focused may no longer exist, depending on what OnChoice.Trigger does.
// Disable the refocus feature for now.
// if (focused)
// SetFocusedView(e.v);
return EVENT_DONE;
}