Merge latest master changes

This commit is contained in:
Rodolfo Bogado
2015-11-07 19:07:47 -03:00
parent 3374eb731c
commit 0cd773fbfe
118 changed files with 37764 additions and 34641 deletions

View File

@@ -541,6 +541,11 @@ if(ENABLE_EVDEV)
endif()
endif()
if(UNIX)
message("Using named pipes as controller inputs")
add_definitions(-DUSE_PIPES=1)
endif()
########################################
# Setup include directories (and make sure they are preferred over the Externals)
#

View File

@@ -6,7 +6,9 @@ find_library(MINIUPNPC_LIBRARY miniupnpc)
if(MINIUPNPC_INCLUDE_DIR)
file(STRINGS "${MINIUPNPC_INCLUDE_DIR}/miniupnpc.h" MINIUPNPC_API_VERSION_STR REGEX "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+[0-9]+")
string(REGEX REPLACE "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+([0-9]+)" "\\1" MINIUPNPC_API_VERSION ${MINIUPNPC_API_VERSION_STR})
if(MINIUPNPC_API_VERSION_STR)
string(REGEX REPLACE "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+([0-9]+)" "\\1" MINIUPNPC_API_VERSION ${MINIUPNPC_API_VERSION_STR})
endif()
endif()
include(FindPackageHandleStandardArgs)

View File

@@ -2,6 +2,7 @@
[Core]
# Values set here will override the main Dolphin settings.
FastDiscSpeed = True
[EmuState]
# The Emulation State. 1 is worst, 5 is best, 0 is not set.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include <algorithm>
#include <cstring>
#include <vector>
#include "Common/Arm64Emitter.h"
@@ -312,6 +313,12 @@ const u8* ARM64XEmitter::AlignCodePage()
return m_code;
}
void ARM64XEmitter::Write32(u32 value)
{
std::memcpy(m_code, &value, sizeof(u32));
m_code += sizeof(u32);
}
void ARM64XEmitter::FlushIcache()
{
FlushIcacheSection(m_lastCacheFlushEnd, m_code);
@@ -815,32 +822,32 @@ void ARM64XEmitter::EncodeLoadStoreUnscaled(u32 size, u32 op, ARM64Reg Rt, ARM64
Write32((size << 30) | (0b111 << 27) | (op << 22) | ((imm & 0x1FF) << 12) | (Rn << 5) | Rt);
}
static inline bool IsInRangeImm19(s64 distance)
static constexpr bool IsInRangeImm19(s64 distance)
{
return (distance >= -0x40000 && distance <= 0x3FFFF);
}
static inline bool IsInRangeImm14(s64 distance)
static constexpr bool IsInRangeImm14(s64 distance)
{
return (distance >= -0x2000 && distance <= 0x1FFF);
}
static inline bool IsInRangeImm26(s64 distance)
static constexpr bool IsInRangeImm26(s64 distance)
{
return (distance >= -0x2000000 && distance <= 0x1FFFFFF);
}
static inline u32 MaskImm19(s64 distance)
static constexpr u32 MaskImm19(s64 distance)
{
return distance & 0x7FFFF;
}
static inline u32 MaskImm14(s64 distance)
static constexpr u32 MaskImm14(s64 distance)
{
return distance & 0x3FFF;
}
static inline u32 MaskImm26(s64 distance)
static constexpr u32 MaskImm26(s64 distance)
{
return distance & 0x3FFFFFF;
}

View File

@@ -81,19 +81,19 @@ enum ARM64Reg
INVALID_REG = 0xFFFFFFFF
};
inline bool Is64Bit(ARM64Reg reg) { return (reg & 0x20) != 0; }
inline bool IsSingle(ARM64Reg reg) { return (reg & 0xC0) == 0x40; }
inline bool IsDouble(ARM64Reg reg) { return (reg & 0xC0) == 0x80; }
inline bool IsScalar(ARM64Reg reg) { return IsSingle(reg) || IsDouble(reg); }
inline bool IsQuad(ARM64Reg reg) { return (reg & 0xC0) == 0xC0; }
inline bool IsVector(ARM64Reg reg) { return (reg & 0xC0) != 0; }
inline bool IsGPR(ARM64Reg reg) { return (int)reg < 0x40; }
constexpr bool Is64Bit(ARM64Reg reg) { return (reg & 0x20) != 0; }
constexpr bool IsSingle(ARM64Reg reg) { return (reg & 0xC0) == 0x40; }
constexpr bool IsDouble(ARM64Reg reg) { return (reg & 0xC0) == 0x80; }
constexpr bool IsScalar(ARM64Reg reg) { return IsSingle(reg) || IsDouble(reg); }
constexpr bool IsQuad(ARM64Reg reg) { return (reg & 0xC0) == 0xC0; }
constexpr bool IsVector(ARM64Reg reg) { return (reg & 0xC0) != 0; }
constexpr bool IsGPR(ARM64Reg reg) { return static_cast<int>(reg) < 0x40; }
inline ARM64Reg DecodeReg(ARM64Reg reg) { return (ARM64Reg)(reg & 0x1F); }
inline ARM64Reg EncodeRegTo64(ARM64Reg reg) { return (ARM64Reg)(reg | 0x20); }
inline ARM64Reg EncodeRegToSingle(ARM64Reg reg) { return (ARM64Reg)(DecodeReg(reg) + S0); }
inline ARM64Reg EncodeRegToDouble(ARM64Reg reg) { return (ARM64Reg)((reg & ~0xC0) | 0x80); }
inline ARM64Reg EncodeRegToQuad(ARM64Reg reg) { return (ARM64Reg)(reg | 0xC0); }
constexpr ARM64Reg DecodeReg(ARM64Reg reg) { return static_cast<ARM64Reg>(reg & 0x1F); }
constexpr ARM64Reg EncodeRegTo64(ARM64Reg reg) { return static_cast<ARM64Reg>(reg | 0x20); }
constexpr ARM64Reg EncodeRegToSingle(ARM64Reg reg) { return static_cast<ARM64Reg>(DecodeReg(reg) + S0); }
constexpr ARM64Reg EncodeRegToDouble(ARM64Reg reg) { return static_cast<ARM64Reg>((reg & ~0xC0) | 0x80); }
constexpr ARM64Reg EncodeRegToQuad(ARM64Reg reg) { return static_cast<ARM64Reg>(reg | 0xC0); }
// For AND/TST/ORR/EOR etc
bool IsImmLogical(uint64_t value, unsigned int width, unsigned int *n, unsigned int *imm_s, unsigned int *imm_r);
@@ -359,11 +359,7 @@ private:
void EncodeLoadStoreUnscaled(u32 size, u32 op, ARM64Reg Rt, ARM64Reg Rn, s32 imm);
protected:
inline void Write32(u32 value)
{
*(u32*)m_code = value;
m_code += 4;
}
void Write32(u32 value);
public:
ARM64XEmitter()

View File

@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 Scott Mansell
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the owner nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<!--
This is a re-implementation of the abstract bitfield class' algrothm (in BitField.h)
for Visual Studio to use for pretty-printing during debugging.
-->
<Type Name="BitField&lt;*,*,*&gt;">
<DisplayString Condition="$T2 == 1"><![CDATA[{(storage & (1 << $T1)) != 0}]]></DisplayString>
<DisplayString><![CDATA[{(storage >> $T1) & ((1 << $T2) - 1)}]]></DisplayString>
<Expand>
<Item Name="Offset">$T1</Item>
<Item Name="Size">$T2</Item>
</Expand>
</Type>
<!--Specialised versions for signed types-->
<Type Name="BitField&lt;*,*,__int64&gt;">
<!-- This is what I have do to get a sign extension in this crappy natvis "language"
Basically, we check the top bit, if it's one, we add the remaining
bits to the smallest (most negative) number. -->
<DisplayString Condition="(storage &amp; (1 &lt;&lt; ($T1 + $T2))) != 0">
<![CDATA[{(-1 * (1 << ($T2-1))) + ((storage >> $T1) & ((1 << ($T2-1)) - 1))}]]>
</DisplayString>
<DisplayString><![CDATA[{(storage >> $T1) & ((1 << ($T2-1)) - 1)}]]></DisplayString>
<Expand>
<Item Name="Offset">$T1</Item>
<Item Name="Size">$T2</Item>
</Expand>
</Type>
<!-- Oh, and I can't do a generic match for all signed types, so these are identical to the __int64 case above
Would be nice if std::numeric_limits<$T3>::is_signed or std::is_signed<$T3>::value worked -->
<Type Name="BitField&lt;*,*,__int32&gt;">
<DisplayString Condition="(storage &amp; (1 &lt;&lt; ($T1 + $T2))) != 0">
<![CDATA[{(-1 * (1 << ($T2-1))) + ((storage >> $T1) & ((1 << ($T2-1)) - 1))}]]>
</DisplayString>
<DisplayString><![CDATA[{(storage >> $T1) & ((1 << ($T2-1)) - 1)}]]></DisplayString>
<Expand>
<Item Name="Offset">$T1</Item>
<Item Name="Size">$T2</Item>
</Expand>
</Type>
<Type Name="BitField&lt;*,*,__int16&gt;">
<DisplayString Condition="(storage &amp; (1 &lt;&lt; ($T1 + $T2))) != 0">
<![CDATA[{(-1 * (1 << ($T2-1))) + ((storage >> $T1) & ((1 << ($T2-1)) - 1))}]]>
</DisplayString>
<DisplayString><![CDATA[{(storage >> $T1) & ((1 << ($T2-1)) - 1)}]]></DisplayString>
<Expand>
<Item Name="Offset">$T1</Item>
<Item Name="Size">$T2</Item>
</Expand>
</Type>
<Type Name="BitField&lt;*,*,__int8&gt;">
<DisplayString Condition="(storage &amp; (1 &lt;&lt; ($T1 + $T2))) != 0">
<![CDATA[{(-1 * (1 << ($T2-1))) + ((storage >> $T1) & ((1 << ($T2-1)) - 1))}]]>
</DisplayString>
<DisplayString><![CDATA[{(storage >> $T1) & ((1 << ($T2-1)) - 1)}]]></DisplayString>
<Expand>
<Item Name="Offset">$T1</Item>
<Item Name="Size">$T2</Item>
</Expand>
</Type>
</AutoVisualizer>

View File

@@ -192,7 +192,10 @@
<Project>{41279555-f94f-4ebc-99de-af863c10c5c4}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Natvis Include="BitField.natvis" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@@ -190,6 +190,8 @@
<ClInclude Include="GL\GLInterfaceBase.h">
<Filter>GL\GLInterface</Filter>
</ClInclude>
<ClInclude Include="Assert.h" />
<ClInclude Include="NonCopyable.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="BreakPoints.cpp" />
@@ -255,4 +257,7 @@
<ItemGroup>
<Text Include="CMakeLists.txt" />
</ItemGroup>
</Project>
<ItemGroup>
<Natvis Include="BitField.natvis" />
</ItemGroup>
</Project>

View File

@@ -77,6 +77,7 @@
#define WII_WC24CONF_DIR "shared2" DIR_SEP "wc24"
#define THEMES_DIR "Themes"
#define ANAGLYPH_DIR "Anaglyph"
#define PIPES_DIR "Pipes"
// Filenames
// Files in the directory returned by GetUserPath(D_CONFIG_IDX)

View File

@@ -791,6 +791,7 @@ static void RebuildUserDirectories(unsigned int dir_index)
s_user_paths[D_LOGS_IDX] = s_user_paths[D_USER_IDX] + LOGS_DIR DIR_SEP;
s_user_paths[D_MAILLOGS_IDX] = s_user_paths[D_LOGS_IDX] + MAIL_LOGS_DIR DIR_SEP;
s_user_paths[D_THEMES_IDX] = s_user_paths[D_USER_IDX] + THEMES_DIR DIR_SEP;
s_user_paths[D_PIPES_IDX] = s_user_paths[D_USER_IDX] + PIPES_DIR DIR_SEP;
s_user_paths[F_DOLPHINCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + DOLPHIN_CONFIG;
s_user_paths[F_DEBUGGERCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + DEBUGGER_CONFIG;
s_user_paths[F_LOGGERCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + LOGGER_CONFIG;

View File

@@ -43,6 +43,7 @@ enum {
D_LOGS_IDX,
D_MAILLOGS_IDX,
D_THEMES_IDX,
D_PIPES_IDX,
F_DOLPHINCONFIG_IDX,
F_DEBUGGERCONFIG_IDX,
F_LOGGERCONFIG_IDX,

View File

@@ -4,7 +4,4 @@
#include "Common/GL/GLExtensions/gl_common.h"
typedef void (GLAPIENTRY * PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
extern PFNGLCOPYIMAGESUBDATAPROC glCopyImageSubData;

View File

@@ -4,8 +4,5 @@
#include "Common/GL/GLExtensions/gl_common.h"
typedef void (*PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
typedef void (*PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
extern PFNGLTEXSTORAGE2DMULTISAMPLEPROC glTexStorage2DMultisample;
extern PFNGLTEXSTORAGE3DMULTISAMPLEPROC glTexStorage3DMultisample;

View File

@@ -2,6 +2,9 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <array>
#include <cstdlib>
#include "Common/GL/GLInterface/EGL.h"
#include "Common/Logging/Log.h"

View File

@@ -225,7 +225,6 @@ std::string Timer::GetTimeFormatted()
}
// Returns a timestamp with decimals for precise time comparisons
// ----------------
double Timer::GetDoubleTime()
{
#ifdef _WIN32
@@ -245,7 +244,7 @@ double Timer::GetDoubleTime()
// sure that we are detecting actual actions, perhaps 60 seconds is
// enough really, but I leave a year of seconds anyway, in case the
// user's clock is incorrect or something like that.
TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60);
TmpSeconds = TmpSeconds - DOUBLE_TIME_OFFSET;
// Make a smaller integer that fits in the double
u32 Seconds = (u32)TmpSeconds;
@@ -261,4 +260,16 @@ double Timer::GetDoubleTime()
return TmpTime;
}
// Formats a timestamp from GetDoubleTime() into a date and time string
std::string Timer::GetDateTimeFormatted(double time)
{
// revert adjustments from GetDoubleTime() to get a normal Unix timestamp again
time_t seconds = (time_t)time + DOUBLE_TIME_OFFSET;
tm* localTime = localtime(&seconds);
char tmp[32] = {};
strftime(tmp, sizeof(tmp), "%x %X", localTime);
return tmp;
}
} // Namespace Common

View File

@@ -26,15 +26,22 @@ public:
static void RestoreResolution();
static u64 GetTimeSinceJan1970();
static u64 GetLocalTimeSinceJan1970();
// Returns a timestamp with decimals for precise time comparisons
static double GetDoubleTime();
static std::string GetTimeFormatted();
// Formats a timestamp from GetDoubleTime() into a date and time string
static std::string GetDateTimeFormatted(double time);
std::string GetTimeElapsedFormatted() const;
u64 GetTimeElapsed();
static u32 GetTimeMs();
static u64 GetTimeUs();
// Arbitrarily chosen value (38 years) that is subtracted in GetDoubleTime()
// to increase sub-second precision of the resulting double timestamp
static const int DOUBLE_TIME_OFFSET = (38 * 365 * 24 * 60 * 60);
private:
u64 m_LastTime;
u64 m_StartTime;

View File

@@ -15,6 +15,8 @@ struct PatchInfo {
} static const s_patches[] = {
// 10.0.10240.16384 (th1.150709-1700)
{ L"ucrtbase.dll", 0xF61ED, 0x6AE7B, 5 },
// 10.0.10240.16390 (th1_st1.150714-1601)
{ L"ucrtbase.dll", 0xF5ED9, 0x6AE7B, 5 },
// 10.0.10137.0 (th1.150602-2238)
{ L"ucrtbase.dll", 0xF8B5E, 0x63ED6, 2 },
// 10.0.10150.0 (th1.150616-1659)

View File

@@ -56,7 +56,10 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader)
// Write necessary values
// Here we write values to memory that the apploader does not take care of. Game info goes
// to 0x80000000 according to YAGCD 4.2.
DVDInterface::DVDRead(/*offset*/0x00000000, /*address*/0x00000000, 0x20, false); // write disc info
// It's possible to boot DOL and ELF files without a disc inserted
if (DVDInterface::VolumeIsValid())
DVDInterface::DVDRead(/*offset*/0x00000000, /*address*/0x00000000, 0x20, false); // write disc info
PowerPC::HostWrite_U32(0x0D15EA5E, 0x80000020); // Booted from bootrom. 0xE5207C22 = booted from jtag
PowerPC::HostWrite_U32(Memory::REALRAM_SIZE, 0x80000028); // Physical Memory Size (24MB on retail)
@@ -81,6 +84,9 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader)
HLE::Patch(0x81300000, "OSReport"); // HLE OSReport for Apploader
if (!DVDInterface::VolumeIsValid())
return false;
// Load Apploader to Memory - The apploader is hardcoded to begin at 0x2440 on the disc,
// but the size can differ between discs. Compare with YAGCD chap 13.
const DiscIO::IVolume& volume = DVDInterface::GetVolume();

View File

@@ -10,6 +10,12 @@
using namespace Gen;
// Ordered in order of prefered use.
// Not all of these are actually available
const std::array<X64Reg, 15> DSPJitRegCache::m_allocation_order = {{
R8, R9, R10, R11, R12, R13, R14, R15, RSI, RDI, RBX, RCX, RDX, RAX, RBP
}};
static void* GetRegisterPointer(size_t reg)
{
switch (reg)
@@ -943,17 +949,11 @@ void DSPJitRegCache::WriteReg(int dreg, OpArg arg)
PutReg(dreg, true);
}
//ordered in order of prefered use
//not all of these are actually available
static X64Reg alloc_order[] = {
R8,R9,R10,R11,R12,R13,R14,R15,RSI,RDI,RBX,RCX,RDX,RAX,RBP
};
X64Reg DSPJitRegCache::SpillXReg()
{
int max_use_ctr_diff = 0;
X64Reg least_recent_use_reg = INVALID_REG;
for (X64Reg reg : alloc_order)
for (X64Reg reg : m_allocation_order)
{
if (xregs[reg].guest_reg <= DSP_REG_MAX_MEM_BACKED &&
!regs[xregs[reg].guest_reg].used)
@@ -974,7 +974,7 @@ X64Reg DSPJitRegCache::SpillXReg()
}
//just choose one.
for (X64Reg reg : alloc_order)
for (X64Reg reg : m_allocation_order)
{
if (xregs[reg].guest_reg <= DSP_REG_MAX_MEM_BACKED &&
!regs[xregs[reg].guest_reg].used)
@@ -1007,13 +1007,14 @@ void DSPJitRegCache::SpillXReg(X64Reg reg)
X64Reg DSPJitRegCache::FindFreeXReg()
{
for (X64Reg x : alloc_order)
for (X64Reg x : m_allocation_order)
{
if (xregs[x].guest_reg == DSP_REG_NONE)
{
return x;
}
}
return INVALID_REG;
}

View File

@@ -32,56 +32,6 @@ enum DSPJitSignExtend
class DSPJitRegCache
{
private:
struct X64CachedReg
{
size_t guest_reg; //including DSPJitRegSpecial
bool pushed;
};
struct DynamicReg
{
Gen::OpArg loc;
void *mem;
size_t size;
bool dirty;
bool used;
int last_use_ctr;
int parentReg;
int shift;//current shift if parentReg == DSP_REG_NONE
//otherwise the shift this part can be found at
Gen::X64Reg host_reg;
/* TODO:
+ drop sameReg
+ add parentReg
+ add shift:
- if parentReg != DSP_REG_NONE, this is the shift where this
register is found in the parentReg
- if parentReg == DSP_REG_NONE, this is the current shift _state_
*/
};
std::array<DynamicReg, 37> regs;
std::array<X64CachedReg, 16> xregs;
DSPEmitter &emitter;
bool temporary;
bool merged;
int use_ctr;
private:
// Find a free host reg
Gen::X64Reg FindFreeXReg();
Gen::X64Reg SpillXReg();
Gen::X64Reg FindSpillFreeXReg();
void SpillXReg(Gen::X64Reg reg);
void MovToHostReg(size_t reg, Gen::X64Reg host_reg, bool load);
void MovToHostReg(size_t reg, bool load);
void RotateHostReg(size_t reg, int shift, bool emit);
void MovToMemory(size_t reg);
void FlushMemBackedRegs();
public:
DSPJitRegCache(DSPEmitter &_emitter);
@@ -176,4 +126,56 @@ public:
void GetXReg(Gen::X64Reg reg);
// Unreserve the given host reg
void PutXReg(Gen::X64Reg reg);
private:
struct X64CachedReg
{
size_t guest_reg; // Including DSPJitRegSpecial
bool pushed;
};
struct DynamicReg
{
Gen::OpArg loc;
void *mem;
size_t size;
bool dirty;
bool used;
int last_use_ctr;
int parentReg;
int shift; // Current shift if parentReg == DSP_REG_NONE
// otherwise the shift this part can be found at
Gen::X64Reg host_reg;
// TODO:
// + drop sameReg
// + add parentReg
// + add shift:
// - if parentReg != DSP_REG_NONE, this is the shift where this
// register is found in the parentReg
// - if parentReg == DSP_REG_NONE, this is the current shift _state_
};
// Find a free host reg
Gen::X64Reg FindFreeXReg();
Gen::X64Reg SpillXReg();
Gen::X64Reg FindSpillFreeXReg();
void SpillXReg(Gen::X64Reg reg);
void MovToHostReg(size_t reg, Gen::X64Reg host_reg, bool load);
void MovToHostReg(size_t reg, bool load);
void RotateHostReg(size_t reg, int shift, bool emit);
void MovToMemory(size_t reg);
void FlushMemBackedRegs();
static const std::array<Gen::X64Reg, 15> m_allocation_order;
std::array<DynamicReg, 37> regs;
std::array<X64CachedReg, 16> xregs;
DSPEmitter& emitter;
bool temporary;
bool merged;
int use_ctr;
};

View File

@@ -2,6 +2,8 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <algorithm>
#include "Common/Assert.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
@@ -109,15 +111,10 @@ void LoadCPReg(u32 subCmd, u32 value, CPMemory& cpMem)
u32 CalculateVertexSize(int vatIndex, const CPMemory& cpMem)
{
u32 vertexSize = 0;
int sizes[21];
CalculateVertexElementSizes(sizes, vatIndex, cpMem);
for (auto& size : sizes)
vertexSize += size;
return vertexSize;
return std::accumulate(std::begin(sizes), std::end(sizes), 0U);
}
void CalculateVertexElementSizes(int sizes[], int vatIndex, const CPMemory& cpMem)

View File

@@ -30,7 +30,7 @@ FifoDataFile::~FifoDataFile()
bool FifoDataFile::HasBrokenEFBCopies() const
{
return version < 2;
return m_Version < 2;
}
void FifoDataFile::SetIsWii(bool isWii)
@@ -150,6 +150,7 @@ FifoDataFile* FifoDataFile::Load(const std::string &filename, bool flagsOnly)
FifoDataFile* dataFile = new FifoDataFile;
dataFile->m_Flags = header.flags;
dataFile->m_Version = header.file_version;
if (flagsOnly)
{

View File

@@ -94,7 +94,7 @@ private:
u32 m_XFRegs[XF_REGS_SIZE];
u32 m_Flags;
u32 version;
u32 m_Version;
std::vector<FifoFrameInfo> m_Frames;
};

View File

@@ -2,6 +2,8 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <cmath>
#include "Common/ChunkFile.h"
#include "Common/CommonTypes.h"
#include "Common/MathUtil.h"

View File

@@ -19,6 +19,9 @@ const std::string hotkey_labels[] =
_trans("Stop"),
_trans("Reset"),
_trans("Frame Advance"),
_trans("Frame Advance Decrease Speed"),
_trans("Frame Advance Increase Speed"),
_trans("Frame Advance Reset Speed"),
_trans("Start Recording"),
_trans("Play Recording"),

View File

@@ -17,6 +17,9 @@ enum Hotkey
HK_STOP,
HK_RESET,
HK_FRAME_ADVANCE,
HK_FRAME_ADVANCE_DECREASE_SPEED,
HK_FRAME_ADVANCE_INCREASE_SPEED,
HK_FRAME_ADVANCE_RESET_SPEED,
HK_START_RECORDING,
HK_PLAY_RECORDING,

View File

@@ -65,8 +65,6 @@ typedef std::map<u32, std::shared_ptr<IWII_IPC_HLE_Device>> TDeviceMap;
static TDeviceMap g_DeviceMap;
// STATE_TO_SAVE
typedef std::map<u32, std::string> TFileNameMap;
#define IPC_MAX_FDS 0x18
#define ES_MAX_COUNT 2
static std::shared_ptr<IWII_IPC_HLE_Device> g_FdMap[IPC_MAX_FDS];

View File

@@ -17,6 +17,7 @@
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/CoreTiming.h"
#include "Core/Host.h"
#include "Core/Movie.h"
#include "Core/State.h"
#include "Core/HW/CPU.h"
@@ -67,7 +68,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
static std::thread g_save_thread;
// Don't forget to increase this after doing changes on the savestate system
static const u32 STATE_VERSION = 49; // Last changed in PR 3108
static const u32 STATE_VERSION = 50; // Last changed in PR 3108
// Maps savestate versions to Dolphin versions.
// Versions after 42 don't need to be added to this list,
@@ -118,7 +119,8 @@ void EnableCompression(bool compression)
g_use_compression = compression;
}
static std::string DoState(PointerWrap& p)
// Returns true if state version matches current Dolphin state version, false otherwise.
static bool DoStateVersion(PointerWrap& p, std::string* version_created_by)
{
u32 version = STATE_VERSION;
{
@@ -128,15 +130,15 @@ static std::string DoState(PointerWrap& p)
version = cookie - COOKIE_BASE;
}
std::string version_created_by = scm_rev_str;
*version_created_by = scm_rev_str;
if (version > 42)
p.Do(version_created_by);
p.Do(*version_created_by);
else
version_created_by.clear();
version_created_by->clear();
if (version != STATE_VERSION)
{
if (version_created_by.empty() && s_old_versions.count(version))
if (version_created_by->empty() && s_old_versions.count(version))
{
// The savestate is from an old version that doesn't
// save the Dolphin version number to savestates, but
@@ -147,9 +149,21 @@ static std::string DoState(PointerWrap& p)
std::string oldest_version = version_range.first;
std::string newest_version = version_range.second;
version_created_by = "Dolphin " + oldest_version + " - " + newest_version;
*version_created_by = "Dolphin " + oldest_version + " - " + newest_version;
}
return false;
}
p.DoMarker("Version");
return true;
}
static std::string DoState(PointerWrap& p)
{
std::string version_created_by;
if (!DoStateVersion(p, &version_created_by))
{
// because the version doesn't match, fail.
// this will trigger an OSD message like "Can't load state from other revisions"
// we could use the version numbers to maintain some level of backward compatibility, but currently don't.
@@ -157,8 +171,6 @@ static std::string DoState(PointerWrap& p)
return version_created_by;
}
p.DoMarker("Version");
// Begin with video backend, so that it gets a chance to clear its caches and writeback modified things to RAM
g_video_backend->DoState(p);
p.DoMarker("video_backend");
@@ -373,6 +385,7 @@ static void CompressAndDumpState(CompressAndDumpState_args save_args)
}
Core::DisplayMessage(StringFromFormat("Saved State to %s", filename.c_str()), 2000);
Host_UpdateMainFrame();
}
void SaveAs(const std::string& filename, bool wait)
@@ -435,6 +448,19 @@ bool ReadHeader(const std::string& filename, StateHeader& header)
return true;
}
std::string GetInfoStringOfSlot(int slot)
{
std::string filename = MakeStateFilename(slot);
if (!File::Exists(filename))
return "Empty";
State::StateHeader header;
if (!ReadHeader(filename, header))
return "Unknown";
return Common::Timer::GetDateTimeFormatted(header.time);
}
static void LoadFileStateData(const std::string& filename, std::vector<u8>& ret_data)
{
Flush();

View File

@@ -33,6 +33,10 @@ void EnableCompression(bool compression);
bool ReadHeader(const std::string& filename, StateHeader& header);
// Returns a string containing information of the savestate in the given slot
// which can be presented to the user for identification purposes
std::string GetInfoStringOfSlot(int slot);
// These don't happen instantly - they get scheduled as events.
// ...But only if we're not in the main CPU thread.
// If we're in the main CPU thread then they run immediately instead

View File

@@ -74,11 +74,10 @@ static SPartitionGroup PartitionGroup[4];
void MarkAsUsed(u64 _Offset, u64 _Size);
void MarkAsUsedE(u64 _PartitionDataOffset, u64 _Offset, u64 _Size);
void ReadFromVolume(u64 _Offset, u64 _Length, u32& _Buffer, bool _Decrypt);
void ReadFromVolume(u64 _Offset, u64 _Length, u64& _Buffer, bool _Decrypt);
void ReadFromVolume(u64 _Offset, u32& _Buffer, bool _Decrypt);
void ReadFromVolume(u64 _Offset, u64& _Buffer, bool _Decrypt);
bool ParseDisc();
bool ParsePartitionData(SPartition& _rPartition);
u32 GetDOLSize(u64 _DOLOffset);
bool SetupScrub(const std::string& filename, int block_size)
@@ -96,6 +95,9 @@ bool SetupScrub(const std::string& filename, int block_size)
m_BlocksPerCluster = CLUSTER_SIZE / m_BlockSize;
m_Disc = CreateVolumeFromFilename(filename);
if (!m_Disc)
return false;
m_FileSize = m_Disc->GetSize();
u32 numClusters = (u32)(m_FileSize / CLUSTER_SIZE);
@@ -190,14 +192,14 @@ void MarkAsUsedE(u64 _PartitionDataOffset, u64 _Offset, u64 _Size)
}
// Helper functions for reading the BE volume
void ReadFromVolume(u64 _Offset, u64 _Length, u32& _Buffer, bool _Decrypt)
void ReadFromVolume(u64 _Offset, u32& _Buffer, bool _Decrypt)
{
m_Disc->Read(_Offset, _Length, (u8*)&_Buffer, _Decrypt);
m_Disc->Read(_Offset, sizeof(u32), (u8*)&_Buffer, _Decrypt);
_Buffer = Common::swap32(_Buffer);
}
void ReadFromVolume(u64 _Offset, u64 _Length, u64& _Buffer, bool _Decrypt)
void ReadFromVolume(u64 _Offset, u64& _Buffer, bool _Decrypt)
{
m_Disc->Read(_Offset, _Length, (u8*)&_Buffer, _Decrypt);
m_Disc->Read(_Offset, sizeof(u32), (u8*)&_Buffer, _Decrypt);
_Buffer = Common::swap32((u32)_Buffer);
_Buffer <<= 2;
}
@@ -209,8 +211,8 @@ bool ParseDisc()
for (int x = 0; x < 4; x++)
{
ReadFromVolume(0x40000 + (x * 8) + 0, 4, PartitionGroup[x].numPartitions, false);
ReadFromVolume(0x40000 + (x * 8) + 4, 4, PartitionGroup[x].PartitionsOffset, false);
ReadFromVolume(0x40000 + (x * 8) + 0, PartitionGroup[x].numPartitions, false);
ReadFromVolume(0x40000 + (x * 8) + 4, PartitionGroup[x].PartitionsOffset, false);
// Read all partitions
for (u32 i = 0; i < PartitionGroup[x].numPartitions; i++)
@@ -220,16 +222,16 @@ bool ParseDisc()
Partition.GroupNumber = x;
Partition.Number = i;
ReadFromVolume(PartitionGroup[x].PartitionsOffset + (i * 8) + 0, 4, Partition.Offset, false);
ReadFromVolume(PartitionGroup[x].PartitionsOffset + (i * 8) + 4, 4, Partition.Type, false);
ReadFromVolume(PartitionGroup[x].PartitionsOffset + (i * 8) + 0, Partition.Offset, false);
ReadFromVolume(PartitionGroup[x].PartitionsOffset + (i * 8) + 4, Partition.Type, false);
ReadFromVolume(Partition.Offset + 0x2a4, 4, Partition.Header.TMDSize, false);
ReadFromVolume(Partition.Offset + 0x2a8, 4, Partition.Header.TMDOffset, false);
ReadFromVolume(Partition.Offset + 0x2ac, 4, Partition.Header.CertChainSize, false);
ReadFromVolume(Partition.Offset + 0x2b0, 4, Partition.Header.CertChainOffset, false);
ReadFromVolume(Partition.Offset + 0x2b4, 4, Partition.Header.H3Offset, false);
ReadFromVolume(Partition.Offset + 0x2b8, 4, Partition.Header.DataOffset, false);
ReadFromVolume(Partition.Offset + 0x2bc, 4, Partition.Header.DataSize, false);
ReadFromVolume(Partition.Offset + 0x2a4, Partition.Header.TMDSize, false);
ReadFromVolume(Partition.Offset + 0x2a8, Partition.Header.TMDOffset, false);
ReadFromVolume(Partition.Offset + 0x2ac, Partition.Header.CertChainSize, false);
ReadFromVolume(Partition.Offset + 0x2b0, Partition.Header.CertChainOffset, false);
ReadFromVolume(Partition.Offset + 0x2b4, Partition.Header.H3Offset, false);
ReadFromVolume(Partition.Offset + 0x2b8, Partition.Header.DataOffset, false);
ReadFromVolume(Partition.Offset + 0x2bc, Partition.Header.DataSize, false);
PartitionGroup[x].PartitionsVec.push_back(Partition);
}
@@ -283,8 +285,8 @@ bool ParsePartitionData(SPartition& _rPartition)
{
// Mark things as used which are not in the filesystem
// Header, Header Information, Apploader
ReadFromVolume(0x2440 + 0x14, 4, _rPartition.Header.ApploaderSize, true);
ReadFromVolume(0x2440 + 0x18, 4, _rPartition.Header.ApploaderTrailerSize, true);
ReadFromVolume(0x2440 + 0x14, _rPartition.Header.ApploaderSize, true);
ReadFromVolume(0x2440 + 0x18, _rPartition.Header.ApploaderTrailerSize, true);
MarkAsUsedE(_rPartition.Offset
+ _rPartition.Header.DataOffset
, 0
@@ -293,16 +295,16 @@ bool ParsePartitionData(SPartition& _rPartition)
+ _rPartition.Header.ApploaderTrailerSize);
// DOL
ReadFromVolume(0x420, 4, _rPartition.Header.DOLOffset, true);
_rPartition.Header.DOLSize = GetDOLSize(_rPartition.Header.DOLOffset);
ReadFromVolume(0x420, _rPartition.Header.DOLOffset, true);
_rPartition.Header.DOLSize = filesystem->GetBootDOLSize(_rPartition.Header.DOLOffset);
MarkAsUsedE(_rPartition.Offset
+ _rPartition.Header.DataOffset
, _rPartition.Header.DOLOffset
, _rPartition.Header.DOLSize);
// FST
ReadFromVolume(0x424, 4, _rPartition.Header.FSTOffset, true);
ReadFromVolume(0x428, 4, _rPartition.Header.FSTSize, true);
ReadFromVolume(0x424, _rPartition.Header.FSTOffset, true);
ReadFromVolume(0x428, _rPartition.Header.FSTSize, true);
MarkAsUsedE(_rPartition.Offset
+ _rPartition.Header.DataOffset
, _rPartition.Header.FSTOffset
@@ -327,31 +329,6 @@ bool ParsePartitionData(SPartition& _rPartition)
return ParsedOK;
}
u32 GetDOLSize(u64 _DOLOffset)
{
u32 offset = 0, size = 0, max = 0;
// Iterate through the 7 code segments
for (u8 i = 0; i < 7; i++)
{
ReadFromVolume(_DOLOffset + 0x00 + i * 4, 4, offset, true);
ReadFromVolume(_DOLOffset + 0x90 + i * 4, 4, size, true);
if (offset + size > max)
max = offset + size;
}
// Iterate through the 11 data segments
for (u8 i = 0; i < 11; i++)
{
ReadFromVolume(_DOLOffset + 0x1c + i * 4, 4, offset, true);
ReadFromVolume(_DOLOffset + 0xac + i * 4, 4, size, true);
if (offset + size > max)
max = offset + size;
}
return max;
}
} // namespace DiscScrubber
} // namespace DiscIO

View File

@@ -150,27 +150,32 @@ bool CFileSystemGCWii::ExportApploader(const std::string& _rExportFolder) const
u32 CFileSystemGCWii::GetBootDOLSize() const
{
u32 DolOffset = m_rVolume->Read32(0x420, m_Wii) << GetOffsetShift();
u32 DolSize = 0, offset = 0, size = 0;
return GetBootDOLSize((u64)m_rVolume->Read32(0x420, m_Wii) << GetOffsetShift());
}
u32 CFileSystemGCWii::GetBootDOLSize(u64 dol_offset) const
{
u32 dol_size = 0;
u32 offset = 0;
u32 size = 0;
// Iterate through the 7 code segments
for (u8 i = 0; i < 7; i++)
{
offset = m_rVolume->Read32(DolOffset + 0x00 + i * 4, m_Wii);
size = m_rVolume->Read32(DolOffset + 0x90 + i * 4, m_Wii);
if (offset + size > DolSize)
DolSize = offset + size;
offset = m_rVolume->Read32(dol_offset + 0x00 + i * 4, m_Wii);
size = m_rVolume->Read32(dol_offset + 0x90 + i * 4, m_Wii);
dol_size = std::max(offset + size, dol_size);
}
// Iterate through the 11 data segments
for (u8 i = 0; i < 11; i++)
{
offset = m_rVolume->Read32(DolOffset + 0x1c + i * 4, m_Wii);
size = m_rVolume->Read32(DolOffset + 0xac + i * 4, m_Wii);
if (offset + size > DolSize)
DolSize = offset + size;
offset = m_rVolume->Read32(dol_offset + 0x1c + i * 4, m_Wii);
size = m_rVolume->Read32(dol_offset + 0xac + i * 4, m_Wii);
dol_size = std::max(offset + size, dol_size);
}
return DolSize;
return dol_size;
}
bool CFileSystemGCWii::GetBootDOL(u8* &buffer, u32 DolSize) const

View File

@@ -32,6 +32,7 @@ public:
bool ExportDOL(const std::string& _rExportFolder) const override;
bool GetBootDOL(u8* &buffer, u32 DolSize) const override;
u32 GetBootDOLSize() const override;
u32 GetBootDOLSize(u64 dol_offset) const override;
private:
bool m_Initialized;

View File

@@ -52,6 +52,7 @@ public:
virtual const std::string GetFileName(u64 _Address) = 0;
virtual bool GetBootDOL(u8* &buffer, u32 DolSize) const = 0;
virtual u32 GetBootDOLSize() const = 0;
virtual u32 GetBootDOLSize(u64 dol_offset) const = 0;
virtual const IVolume *GetVolume() const { return m_rVolume; }
protected:

View File

@@ -37,7 +37,7 @@ void Resources::Init()
m_regions[DiscIO::IVolume::COUNTRY_RUSSIA].load(GIFN("Flag_Russia"));
m_regions[DiscIO::IVolume::COUNTRY_SPAIN].load(GIFN("Flag_Spain"));
m_regions[DiscIO::IVolume::COUNTRY_TAIWAN].load(GIFN("Flag_Taiwan"));
m_regions[DiscIO::IVolume::COUNTRY_WORLD].load(GIFN("Flag_Europe")); // Uses European flag as a placeholder
m_regions[DiscIO::IVolume::COUNTRY_WORLD].load(GIFN("Flag_International"));
m_regions[DiscIO::IVolume::COUNTRY_UNKNOWN].load(GIFN("Flag_Unknown"));
m_platforms.resize(4);

View File

@@ -337,7 +337,7 @@ void GFXDebuggerPanel::OnClearScreenButton(wxCommandEvent& event)
void GFXDebuggerPanel::OnClearTextureCacheButton(wxCommandEvent& event)
{
TextureCache::Invalidate();
TextureCacheBase::Invalidate();
}
void GFXDebuggerPanel::OnClearVertexShaderCacheButton(wxCommandEvent& event)

View File

@@ -595,7 +595,7 @@ void FifoPlayerDlg::OnFrameListSelectionChanged(wxCommandEvent& event)
{
size_t num_objects = player.GetAnalyzedFrameInfo(event.GetInt()).objectStarts.size();
for (size_t i = 0; i < num_objects; ++i)
m_objectsList->Append(wxString::Format("Object %u", (u32)i));
m_objectsList->Append(wxString::Format(_("Object %zu"), i));
}
// Update object list
@@ -858,7 +858,7 @@ void FifoPlayerDlg::UpdateAnalyzerGui()
for (size_t i = 0; i < num_frames; ++i)
{
m_framesList->Append(wxString::Format("Frame %u", (u32)i));
m_framesList->Append(wxString::Format(_("Frame %zu"), i));
}
wxCommandEvent ev = wxCommandEvent(wxEVT_LISTBOX);
@@ -872,7 +872,7 @@ wxString FifoPlayerDlg::CreateFileFrameCountLabel() const
FifoDataFile *file = FifoPlayer::GetInstance().GetFile();
if (file)
return CreateIntegerLabel(file->GetFrameCount(), _("Frame"));
return wxString::Format(_("%u frames"), file->GetFrameCount());
return _("No file loaded");
}
@@ -882,7 +882,7 @@ wxString FifoPlayerDlg::CreateCurrentFrameLabel() const
FifoDataFile *file = FifoPlayer::GetInstance().GetFile();
if (file)
return _("Frame ") + wxString::Format("%u", FifoPlayer::GetInstance().GetCurrentFrameNum());
return wxString::Format(_("Frame %u"), FifoPlayer::GetInstance().GetCurrentFrameNum());
return wxEmptyString;
}
@@ -892,7 +892,7 @@ wxString FifoPlayerDlg::CreateFileObjectCountLabel() const
FifoDataFile *file = FifoPlayer::GetInstance().GetFile();
if (file)
return CreateIntegerLabel(FifoPlayer::GetInstance().GetFrameObjectCount(), _("Object"));
return wxString::Format(_("%u objects"), FifoPlayer::GetInstance().GetFrameObjectCount());
return wxEmptyString;
}
@@ -907,7 +907,7 @@ wxString FifoPlayerDlg::CreateRecordingFifoSizeLabel() const
for (size_t i = 0; i < file->GetFrameCount(); ++i)
fifoBytes += file->GetFrame(i).fifoDataSize;
return CreateIntegerLabel(fifoBytes, _("FIFO Byte"));
return wxString::Format(_("%zu FIFO bytes"), fifoBytes);
}
return _("No recorded file");
@@ -927,7 +927,7 @@ wxString FifoPlayerDlg::CreateRecordingMemSizeLabel() const
memBytes += memUpdate.size;
}
return CreateIntegerLabel(memBytes, _("Memory Byte"));
return wxString::Format(_("%zu memory bytes"), memBytes);
}
return wxEmptyString;
@@ -938,23 +938,11 @@ wxString FifoPlayerDlg::CreateRecordingFrameCountLabel() const
FifoDataFile *file = FifoRecorder::GetInstance().GetRecordedFile();
if (file)
{
size_t numFrames = file->GetFrameCount();
return CreateIntegerLabel(numFrames, _("Frame"));
}
return wxString::Format(_("%u frames"), file->GetFrameCount());
return wxEmptyString;
}
wxString FifoPlayerDlg::CreateIntegerLabel(size_t size, const wxString& label) const
{
wxString postfix;
if (size != 1)
postfix = _("s");
return wxString::Format("%u ", (u32)size) + label + postfix;
}
bool FifoPlayerDlg::GetSaveButtonEnabled() const
{
return (FifoRecorder::GetInstance().GetRecordedFile() != nullptr);

View File

@@ -66,7 +66,6 @@ private:
wxString CreateRecordingFifoSizeLabel() const;
wxString CreateRecordingMemSizeLabel() const;
wxString CreateRecordingFrameCountLabel() const;
wxString CreateIntegerLabel(size_t size, const wxString& label) const;
bool GetSaveButtonEnabled() const;

View File

@@ -1291,7 +1291,6 @@ void CFrame::ParseHotkeys()
case HK_CHANGE_DISC:
case HK_REFRESH_LIST:
case HK_RESET:
case HK_FRAME_ADVANCE:
case HK_START_RECORDING:
case HK_PLAY_RECORDING:
case HK_EXPORT_RECORDING:
@@ -1333,6 +1332,8 @@ void CFrame::ParseHotkeys()
// Pause and Unpause
if (IsHotkey(HK_PLAY_PAUSE))
DoPause();
// Frame advance
HandleFrameSkipHotkeys();
// Stop
if (IsHotkey(HK_STOP))
DoStop();
@@ -1531,3 +1532,61 @@ void CFrame::ParseHotkeys()
if (IsHotkey(HK_UNDO_SAVE_STATE))
State::UndoSaveState();
}
void CFrame::HandleFrameSkipHotkeys()
{
static const int MAX_FRAME_SKIP_DELAY = 60;
static int frameStepCount = 0;
static const int FRAME_STEP_DELAY = 30;
static int holdFrameStepDelay = 1;
static int holdFrameStepDelayCount = 0;
static bool holdFrameStep = false;
if (IsHotkey(HK_FRAME_ADVANCE_DECREASE_SPEED))
{
++holdFrameStepDelay;
if (holdFrameStepDelay > MAX_FRAME_SKIP_DELAY)
holdFrameStepDelay = MAX_FRAME_SKIP_DELAY;
}
else if (IsHotkey(HK_FRAME_ADVANCE_INCREASE_SPEED))
{
--holdFrameStepDelay;
if (holdFrameStepDelay < 0)
holdFrameStepDelay = 0;
}
else if (IsHotkey(HK_FRAME_ADVANCE_RESET_SPEED))
{
holdFrameStepDelay = 1;
}
else if (IsHotkey(HK_FRAME_ADVANCE, true))
{
if (holdFrameStepDelayCount < holdFrameStepDelay && holdFrameStep)
++holdFrameStepDelayCount;
if ((frameStepCount == 0 || frameStepCount == FRAME_STEP_DELAY) && !holdFrameStep)
{
wxCommandEvent evt;
evt.SetId(IDM_FRAMESTEP);
CFrame::OnFrameStep(evt);
if (holdFrameStepDelay > 0 && frameStepCount == 0)
holdFrameStep = true;
}
if (frameStepCount < FRAME_STEP_DELAY)
++frameStepCount;
if (frameStepCount == FRAME_STEP_DELAY && holdFrameStep && holdFrameStepDelayCount >= holdFrameStepDelay)
{
holdFrameStep = false;
holdFrameStepDelayCount = 0;
}
}
else if (frameStepCount > 0)
{
// Reset values of frame advance to default
frameStepCount = 0;
holdFrameStep = false;
holdFrameStepDelayCount = 0;
}
}

View File

@@ -211,6 +211,7 @@ private:
wxAuiNotebook * GetNotebookFromId(u32 NBId);
int GetNotebookCount();
wxAuiNotebook *CreateEmptyNotebook();
void HandleFrameSkipHotkeys();
// Perspectives
void AddRemoveBlankPage();

View File

@@ -462,8 +462,8 @@ wxString CFrame::GetMenuLabel(int Id)
case HK_LOAD_STATE_SLOT_8:
case HK_LOAD_STATE_SLOT_9:
case HK_LOAD_STATE_SLOT_10:
Label = wxString::Format(_("Slot %i"),
Id - HK_LOAD_STATE_SLOT_1 + 1);
Label = wxString::Format(_("Slot %i - %s"),
Id - HK_LOAD_STATE_SLOT_1 + 1, State::GetInfoStringOfSlot(Id - HK_LOAD_STATE_SLOT_1 + 1).c_str());
break;
case HK_SAVE_STATE_SLOT_1:
@@ -476,8 +476,8 @@ wxString CFrame::GetMenuLabel(int Id)
case HK_SAVE_STATE_SLOT_8:
case HK_SAVE_STATE_SLOT_9:
case HK_SAVE_STATE_SLOT_10:
Label = wxString::Format(_("Slot %i"),
Id - HK_SAVE_STATE_SLOT_1 + 1);
Label = wxString::Format(_("Slot %i - %s"),
Id - HK_SAVE_STATE_SLOT_1 + 1, State::GetInfoStringOfSlot(Id - HK_SAVE_STATE_SLOT_1 + 1).c_str());
break;
case HK_SAVE_STATE_FILE:
Label = _("Save State...");
@@ -522,7 +522,8 @@ wxString CFrame::GetMenuLabel(int Id)
case HK_SELECT_STATE_SLOT_8:
case HK_SELECT_STATE_SLOT_9:
case HK_SELECT_STATE_SLOT_10:
Label = wxString::Format(_("Select Slot %i"), Id - HK_SELECT_STATE_SLOT_1 + 1);
Label = wxString::Format(_("Select Slot %i - %s"),
Id - HK_SELECT_STATE_SLOT_1 + 1, State::GetInfoStringOfSlot(Id - HK_SELECT_STATE_SLOT_1 + 1).c_str());
break;
@@ -1680,7 +1681,7 @@ void CFrame::OnFrameSkip(wxCommandEvent& event)
void CFrame::OnSelectSlot(wxCommandEvent& event)
{
g_saveSlot = event.GetId() - IDM_SELECT_SLOT_1 + 1;
Core::DisplayMessage(StringFromFormat("Selected slot %d", g_saveSlot), 1000);
Core::DisplayMessage(StringFromFormat("Selected slot %d - %s", g_saveSlot, State::GetInfoStringOfSlot(g_saveSlot).c_str()), 2500);
}
void CFrame::OnLoadCurrentSlot(wxCommandEvent& event)

View File

@@ -1080,6 +1080,9 @@ void CGameListCtrl::CompressSelection(bool _compress)
if (!iso->IsCompressed() && _compress)
{
if (iso->GetPlatform() == DiscIO::IVolume::WII_DISC && !WiiCompressWarning())
return;
std::string FileName, FileExt;
SplitPath(iso->GetFileName(), nullptr, &FileName, &FileExt);
m_currentFilename = FileName;
@@ -1093,7 +1096,7 @@ void CGameListCtrl::CompressSelection(bool _compress)
if (File::Exists(OutputFileName) &&
wxMessageBox(
wxString::Format(_("The file %s already exists.\nDo you wish to replace it?"),
StrToWxStr(OutputFileName)),
StrToWxStr(OutputFileName)),
_("Confirm File Overwrite"),
wxYES_NO) == wxNO)
continue;
@@ -1121,7 +1124,7 @@ void CGameListCtrl::CompressSelection(bool _compress)
if (File::Exists(OutputFileName) &&
wxMessageBox(
wxString::Format(_("The file %s already exists.\nDo you wish to replace it?"),
StrToWxStr(OutputFileName)),
StrToWxStr(OutputFileName)),
_("Confirm File Overwrite"),
wxYES_NO) == wxNO)
continue;
@@ -1178,6 +1181,9 @@ void CGameListCtrl::OnCompressISO(wxCommandEvent& WXUNUSED (event))
}
else
{
if (iso->GetPlatform() == DiscIO::IVolume::WII_DISC && !WiiCompressWarning())
return;
path = wxFileSelector(
_("Save compressed GCM/ISO"),
StrToWxStr(FilePath),
@@ -1292,3 +1298,10 @@ void CGameListCtrl::UnselectAll()
SetItemState(i, 0, wxLIST_STATE_SELECTED);
}
}
bool CGameListCtrl::WiiCompressWarning()
{
return wxMessageBox(
_("Compressing a Wii disc image will irreversibly change the compressed copy by removing padding data. Your disc image will still work. Continue?"),
_("Warning"),
wxYES_NO) == wxYES;
}

View File

@@ -107,4 +107,5 @@ private:
static size_t m_numberItem;
static bool CompressCB(const std::string& text, float percent, void* arg);
static bool MultiCompressCB(const std::string& text, float percent, void* arg);
static bool WiiCompressWarning();
};

View File

@@ -108,7 +108,7 @@ bool DolphinApp::Initialize(int& c, wxChar **v)
bool DolphinApp::OnInit()
{
if (!wxApp::OnInit() || DolphinEmulatorDotComTextFileExists())
if (!wxApp::OnInit())
return false;
Bind(wxEVT_QUERY_END_SESSION, &DolphinApp::OnEndSession, this);
@@ -269,23 +269,6 @@ void DolphinApp::MacOpenFile(const wxString& fileName)
}
#endif
bool DolphinApp::DolphinEmulatorDotComTextFileExists()
{
if (!File::Exists("www.dolphin-emulator.com.txt"))
return false;
File::Delete("www.dolphin-emulator.com.txt");
wxMessageDialog dlg(nullptr, _(
"This version of Dolphin was downloaded from a website stealing money from developers of the emulator. Please "
"download Dolphin from the official website instead: https://dolphin-emu.org/"),
_("Unofficial version detected"), wxOK | wxICON_WARNING);
dlg.ShowModal();
wxLaunchDefaultBrowser("https://dolphin-emu.org/?ref=badver");
return true;
}
void DolphinApp::AfterInit()
{
if (!m_batch_mode)

View File

@@ -33,7 +33,6 @@ private:
void OnEndSession(wxCloseEvent& event);
void InitLanguageSupport();
void AfterInit();
static bool DolphinEmulatorDotComTextFileExists();
bool m_batch_mode = false;
bool m_confirm_stop = false;

View File

@@ -129,7 +129,6 @@ static wxString log_fps_to_file_desc = _("Log the number of frames rendered per
static wxString show_input_display_desc = _("Display the inputs read by the emulator.\n\nIf unsure, leave this unchecked.");
static wxString show_stats_desc = _("Show various statistics.\n\nIf unsure, leave this unchecked.");
static wxString texfmt_desc = _("Modify textures to show the format they're encoded in. Needs an emulation reset in most cases.\n\nIf unsure, leave this unchecked.");
static wxString efb_copy_regions_desc = _("[BROKEN]\nHighlight regions the EFB was copied from.\n\nIf unsure, leave this unchecked.");
static wxString xfb_desc = _("Disable any XFB emulation.\nSpeeds up emulation a lot but causes heavy glitches in many games which rely on them (especially homebrew applications).\n\nIf unsure, leave this checked.");
static wxString xfb_virtual_desc = _("Emulate XFBs using GPU texture objects.\nFixes many games which don't work without XFB emulation while not being as slow as real XFB emulation. However, it may still fail for a lot of other games (especially homebrew applications).\n\nIf unsure, leave this checked.");
static wxString xfb_real_desc = _("Emulate XFBs accurately.\nSlows down emulation a lot and prohibits high-resolution rendering but is necessary to emulate a number of games properly.\n\nIf unsure, check virtual XFB emulation instead.");
@@ -680,7 +679,6 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con
wxGridSizer* const szr_debug = new wxGridSizer(2, 5, 5);
szr_debug->Add(CreateCheckBox(page_advanced, _("Enable Wireframe"), (wireframe_desc), vconfig.bWireFrame));
szr_debug->Add(CreateCheckBox(page_advanced, _("Show EFB Copy Regions"), (efb_copy_regions_desc), vconfig.bShowEFBCopyRegions));
szr_debug->Add(CreateCheckBox(page_advanced, _("Show Statistics"), (show_stats_desc), vconfig.bOverlayStats));
szr_debug->Add(CreateCheckBox(page_advanced, _("Texture Format Overlay"), (texfmt_desc), vconfig.bTexFmtOverlayEnable));

View File

@@ -42,6 +42,10 @@ if(LIBEVDEV_FOUND AND LIBUDEV_FOUND)
set(LIBS ${LIBS} ${LIBEVDEV_LIBRARY} ${LIBUDEV_LIBRARY})
endif()
if(UNIX)
set(SRCS ${SRCS} ControllerInterface/Pipes/Pipes.cpp)
endif()
if(SDL_FOUND OR SDL2_FOUND)
set(SRCS ${SRCS} ControllerInterface/SDL/SDL.cpp)
if (SDL2_FOUND)

View File

@@ -29,6 +29,9 @@
#ifdef CIFACE_USE_EVDEV
#include "InputCommon/ControllerInterface/evdev/evdev.h"
#endif
#ifdef CIFACE_USE_PIPES
#include "InputCommon/ControllerInterface/Pipes/Pipes.h"
#endif
using namespace ciface::ExpressionParser;
@@ -75,6 +78,9 @@ void ControllerInterface::Initialize(void* const hwnd)
#ifdef CIFACE_USE_EVDEV
ciface::evdev::Init(m_devices);
#endif
#ifdef CIFACE_USE_PIPES
ciface::Pipes::Init(m_devices);
#endif
m_is_init = true;
}

View File

@@ -38,6 +38,9 @@
#if defined(HAVE_LIBEVDEV) && defined(HAVE_LIBUDEV)
#define CIFACE_USE_EVDEV
#endif
#if defined(USE_PIPES)
#define CIFACE_USE_PIPES
#endif
//
// ControllerInterface

View File

@@ -0,0 +1,178 @@
// Copyright 2015 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <array>
#include <cstdlib>
#include <fcntl.h>
#include <iostream>
#include <map>
#include <string>
#include <unistd.h>
#include <vector>
#include <sys/stat.h>
#include "Common/FileUtil.h"
#include "Common/MathUtil.h"
#include "Common/StringUtil.h"
#include "InputCommon/ControllerInterface/Pipes/Pipes.h"
namespace ciface
{
namespace Pipes
{
static const std::array<std::string, 12> s_button_tokens
{{
"A",
"B",
"X",
"Y",
"Z",
"START",
"L",
"R",
"D_UP",
"D_DOWN",
"D_LEFT",
"D_RIGHT"
}};
static const std::array<std::string, 2> s_shoulder_tokens
{{
"L",
"R"
}};
static const std::array<std::string, 2> s_axis_tokens
{{
"MAIN",
"C"
}};
void Init(std::vector<Core::Device*>& devices)
{
// Search the Pipes directory for files that we can open in read-only,
// non-blocking mode. The device name is the virtual name of the file.
File::FSTEntry fst;
int found = 0;
std::string dir_path = File::GetUserPath(D_PIPES_IDX);
if (!File::Exists(dir_path))
return;
fst = File::ScanDirectoryTree(dir_path, false);
if (!fst.isDirectory)
return;
for (unsigned int i = 0; i < fst.size; ++i)
{
const File::FSTEntry& child = fst.children[i];
if (child.isDirectory)
continue;
int fd = open(child.physicalName.c_str(), O_RDONLY | O_NONBLOCK);
if (fd < 0)
continue;
devices.push_back(new PipeDevice(fd, child.virtualName, found++));
}
}
PipeDevice::PipeDevice(int fd, const std::string& name, int id)
: m_fd(fd), m_name(name), m_id(id)
{
for (const auto& tok : s_button_tokens)
{
PipeInput* btn = new PipeInput("Button " + tok);
AddInput(btn);
m_buttons[tok] = btn;
}
for (const auto& tok : s_shoulder_tokens)
{
AddAxis(tok, 0.0);
}
for (const auto& tok : s_axis_tokens)
{
AddAxis(tok + " X", 0.5);
AddAxis(tok + " Y", 0.5);
}
}
PipeDevice::~PipeDevice()
{
close(m_fd);
}
void PipeDevice::UpdateInput()
{
// Read any pending characters off the pipe. If we hit a newline,
// then dequeue a command off the front of m_buf and parse it.
char buf[32];
ssize_t bytes_read = read(m_fd, buf, sizeof buf);
while (bytes_read > 0)
{
m_buf.append(buf, bytes_read);
bytes_read = read(m_fd, buf, sizeof buf);
}
std::size_t newline = m_buf.find("\n");
while (newline != std::string::npos)
{
std::string command = m_buf.substr(0, newline);
ParseCommand(command);
m_buf.erase(0, newline + 1);
newline = m_buf.find("\n");
}
}
void PipeDevice::AddAxis(const std::string& name, double value)
{
// Dolphin uses separate axes for left/right, which complicates things.
PipeInput* ax_hi = new PipeInput("Axis " + name + " +");
ax_hi->SetState(value);
PipeInput* ax_lo = new PipeInput("Axis " + name + " -");
ax_lo->SetState(value);
m_axes[name + " +"] = ax_hi;
m_axes[name + " -"] = ax_lo;
AddAnalogInputs(ax_lo, ax_hi);
}
void PipeDevice::SetAxis(const std::string& entry, double value)
{
value = MathUtil::Clamp(value, 0.0, 1.0);
double hi = std::max(0.0, value - 0.5) * 2.0;
double lo = (0.5 - std::min(0.5, value)) * 2.0;
auto search_hi = m_axes.find(entry + " +");
if (search_hi != m_axes.end())
search_hi->second->SetState(hi);
auto search_lo = m_axes.find(entry + " -");
if (search_lo != m_axes.end())
search_lo->second->SetState(lo);
}
void PipeDevice::ParseCommand(const std::string& command)
{
std::vector<std::string> tokens;
SplitString(command, ' ', tokens);
if (tokens.size() < 2 || tokens.size() > 4)
return;
if (tokens[0] == "PRESS" || tokens[0] == "RELEASE")
{
auto search = m_buttons.find(tokens[1]);
if (search != m_buttons.end())
search->second->SetState(tokens[0] == "PRESS" ? 1.0 : 0.0);
}
else if (tokens[0] == "SET")
{
if (tokens.size() == 3)
{
double value = strtod(tokens[2].c_str(), nullptr);
SetAxis(tokens[1], (value / 2.0) + 0.5);
}
else if (tokens.size() == 4)
{
double x = strtod(tokens[2].c_str(), nullptr);
double y = strtod(tokens[3].c_str(), nullptr);
SetAxis(tokens[1] + " X", x);
SetAxis(tokens[1] + " Y", y);
}
}
}
}
}

View File

@@ -0,0 +1,65 @@
// Copyright 2015 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <map>
#include <string>
#include <vector>
#include "InputCommon/ControllerInterface/Device.h"
namespace ciface
{
namespace Pipes
{
// To create a piped controller input, create a named pipe in the
// Pipes directory and write commands out to it. Commands are separated
// by a newline character, with spaces separating command tokens.
// Command syntax is as follows, where curly brackets are one-of and square
// brackets are inclusive numeric ranges. Cases are sensitive. Numeric inputs
// are clamped to [0, 1] and otherwise invalid commands are discarded.
// {PRESS, RELEASE} {A, B, X, Y, Z, START, L, R, D_UP, D_DOWN, D_LEFT, D_RIGHT}
// SET {L, R} [0, 1]
// SET {MAIN, C} [0, 1] [0, 1]
void Init(std::vector<Core::Device*>& devices);
class PipeDevice : public Core::Device
{
public:
PipeDevice(int fd, const std::string& name, int id);
~PipeDevice();
void UpdateInput() override;
std::string GetName() const override { return m_name; }
int GetId() const override { return m_id; }
std::string GetSource() const override { return "Pipe"; }
private:
class PipeInput : public Input
{
public:
PipeInput(const std::string& name) : m_name(name), m_state(0.0) {}
std::string GetName() const override { return m_name; }
ControlState GetState() const override { return m_state; }
void SetState(ControlState state) { m_state = state; }
private:
const std::string m_name;
ControlState m_state;
};
void AddAxis(const std::string& name, double value);
void ParseCommand(const std::string& command);
void SetAxis(const std::string& entry, double value);
const int m_fd;
const std::string m_name;
const int m_id;
std::string m_buf;
std::map<std::string, PipeInput*> m_buttons;
std::map<std::string, PipeInput*> m_axes;
};
}
}

View File

@@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <X11/XKBlib.h>

View File

@@ -943,7 +943,7 @@ void CSTextureEncoder::Encode(u8* dst, const TextureCache::TCacheEntryBase *text
HRESULT hr;
u32 numBlocksY = texture_entry->NumBlocksY();
u32 cacheLinesPerRow = texture_entry->CacheLinesPerRow();
u32 cacheLinesPerRow = texture_entry->BytesPerRow() / 32;
if ((texture_entry->format & 0xF) == 0x6 && texture_entry->format != GX_TF_RGBA8)
cacheLinesPerRow *= 2;
// Reset API
@@ -1020,7 +1020,7 @@ void CSTextureEncoder::Encode(u8* dst, const TextureCache::TCacheEntryBase *text
if (hr == S_OK)
{
u8* src = (u8*)map.pData;
u32 readStride = std::min(texture_entry->CacheLinesPerRow() * 32, map.RowPitch);
u32 readStride = std::min(texture_entry->BytesPerRow(), map.RowPitch);
for (u32 y = 0; y < numBlocksY; ++y)
{
memcpy(dst, src, readStride);

View File

@@ -20,7 +20,7 @@ public:
void Init();
void Shutdown();
void Encode(u8* dst, const TextureCache::TCacheEntryBase *texture_entry,
void Encode(u8* dst, const TextureCacheBase::TCacheEntryBase *texture_entry,
PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect,
bool isIntensity, bool scaleByHalf) override;
private:

View File

@@ -1019,7 +1019,7 @@ void PSTextureEncoder::Encode(u8* dst, const TextureCache::TCacheEntryBase *text
HRESULT hr;
u32 numBlocksY = texture_entry->NumBlocksY();
u32 cacheLinesPerRow = texture_entry->CacheLinesPerRow();
u32 cacheLinesPerRow = texture_entry->BytesPerRow() / 32;
if ((texture_entry->format & 0xF) == 0x6 && texture_entry->format != GX_TF_RGBA8)
cacheLinesPerRow *= 2;
// Reset API
@@ -1117,7 +1117,7 @@ void PSTextureEncoder::Encode(u8* dst, const TextureCache::TCacheEntryBase *text
CHECK(SUCCEEDED(hr), "map staging buffer");
u8* src = (u8*)map.pData;
u32 readStride = std::min(texture_entry->CacheLinesPerRow() * 32, map.RowPitch);
u32 readStride = std::min(texture_entry->BytesPerRow(), map.RowPitch);
for (u32 y = 0; y < numBlocksY; ++y)
{
memcpy(dst, src, readStride);

View File

@@ -20,7 +20,7 @@ namespace DX11
void Init();
void Shutdown();
void Encode(u8* dst, const TextureCache::TCacheEntryBase *texture_entry,
void Encode(u8* dst, const TextureCacheBase::TCacheEntryBase *texture_entry,
PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect,
bool isIntensity, bool scaleByHalf) override;

View File

@@ -903,11 +903,11 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
OSD::DrawMessages();
D3D::EndFrame();
TextureCache::Cleanup(frameCount);
TextureCacheBase::Cleanup(frameCount);
// Enable configuration changes
UpdateActiveConfig();
TextureCache::OnConfigChanged(g_ActiveConfig);
TextureCacheBase::OnConfigChanged(g_ActiveConfig);
SetWindowSize(fbStride, fbHeight);

View File

@@ -10,7 +10,7 @@
namespace DX11
{
class TextureCache : public ::TextureCache
class TextureCache : public ::TextureCacheBase
{
public:
TextureCache();

View File

@@ -116,7 +116,7 @@ namespace DX11
virtual void Init() = 0;
virtual void Shutdown() = 0;
virtual void Encode(u8* dst, const TextureCache::TCacheEntryBase *texture_entry,
virtual void Encode(u8* dst, const TextureCacheBase::TCacheEntryBase *texture_entry,
PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect,
bool isIntensity, bool scaleByHalf) = 0;

View File

@@ -9,7 +9,7 @@
namespace DX11
{
class VertexManager : public ::VertexManager
class VertexManager : public ::VertexManagerBase
{
public:
VertexManager();
@@ -39,8 +39,8 @@ private:
u32 m_bufferCursor;
enum { MAX_BUFFER_COUNT = 2 };
// TODO: Find sensible values for these two
const u32 MAX_IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * sizeof(u16);
const u32 MAX_VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE;
const u32 MAX_IBUFFER_SIZE = VertexManagerBase::MAXIBUFFERSIZE * sizeof(u16);
const u32 MAX_VBUFFER_SIZE = VertexManagerBase::MAXVBUFFERSIZE;
const u32 MAX_BUFFER_SIZE = MAX_IBUFFER_SIZE + MAX_VBUFFER_SIZE;
D3D::BufferPtr m_buffers[MAX_BUFFER_COUNT];

View File

@@ -88,7 +88,7 @@ void TeardownDeviceObjects()
delete g_framebuffer_manager;
((PerfQuery*)g_perf_query)->DestroyDeviceObjects();
D3D::font.Shutdown();
TextureCache::Invalidate();
TextureCacheBase::Invalidate();
VertexLoaderManager::Shutdown();
VertexShaderCache::Shutdown();
PixelShaderCache::Shutdown();
@@ -840,12 +840,12 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
GFX_DEBUGGER_PAUSE_AT(NEXT_FRAME, true);
TextureCache::Cleanup(frameCount);
TextureCacheBase::Cleanup(frameCount);
// Flip/present backbuffer to frontbuffer here
D3D::Present();
// Enable configuration changes
UpdateActiveConfig();
TextureCache::OnConfigChanged(g_ActiveConfig);
TextureCacheBase::OnConfigChanged(g_ActiveConfig);
SetWindowSize(fbStride, fbHeight);

View File

@@ -15,7 +15,7 @@
namespace DX9
{
class TextureCache : public ::TextureCache
class TextureCache : public ::TextureCacheBase
{
public:
TextureCache();

View File

@@ -399,7 +399,7 @@ void EncodeToRamFromTexture(u8 *dest_ptr, const TextureCache::TCacheEntryBase *t
if ((texture_entry->format & 0x0f) == 6)
cacheBytes = 64;
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(texture_entry->format);
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, (expandedWidth / samples) * 4, expandedHeight, texture_entry->CacheLinesPerRow() * 32, readStride, bScaleByHalf > 0, 1.0f);
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, (expandedWidth / samples) * 4, expandedHeight, texture_entry->BytesPerRow(), readStride, bScaleByHalf > 0, 1.0f);
}
void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc, u8* destAddr, u32 dstwidth, u32 dstStride, u32 dstHeight, float Gamma)

View File

@@ -28,7 +28,7 @@ void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourc
void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE9 destTexture);
// returns size of the encoded data (in bytes)
void EncodeToRamFromTexture(u8 *dest_ptr, const TextureCache::TCacheEntryBase *texture_entry, u32 SourceW, u32 SourceH,
void EncodeToRamFromTexture(u8 *dest_ptr, const TextureCacheBase::TCacheEntryBase *texture_entry, u32 SourceW, u32 SourceH,
LPDIRECT3DTEXTURE9 source_texture, bool bFromZBuffer, bool bIsIntensityFmt, int bScaleByHalf, const EFBRectangle& source);

View File

@@ -27,8 +27,8 @@ extern NativeVertexFormat *g_nativeVertexFmt;
namespace DX9
{
// This are the initially requeted size for the buffers expresed in elements
const u32 MAX_IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * sizeof(u16) * 8;
const u32 MAX_VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE;
const u32 MAX_IBUFFER_SIZE = VertexManagerBase::MAXIBUFFERSIZE * sizeof(u16) * 8;
const u32 MAX_VBUFFER_SIZE = VertexManagerBase::MAXVBUFFERSIZE;
const u32 MAX_VBUFFER_COUNT = 2;
// Register count for line/point offset storage
const u32 LINE_PT_OFFSETS_PARAMS_LEN = C_VENVCONST_END - C_PLOFFSETPARAMS;

View File

@@ -14,7 +14,7 @@
namespace DX9
{
class VertexManager : public ::VertexManager
class VertexManager : public ::VertexManagerBase
{
public:
VertexManager();

View File

@@ -369,9 +369,6 @@ GLuint ProgramShaderCache::CompileSingleShader(GLuint type, const char* code, co
GLsizei length = 0;
glGetShaderiv(result, GL_INFO_LOG_LENGTH, &length);
if (DriverDetails::HasBug(DriverDetails::BUG_BROKENINFOLOG))
length = 1024;
if (compileStatus != GL_TRUE || (length > 1 && DEBUG_GLSL))
{
GLsizei charsWritten;

View File

@@ -753,128 +753,6 @@ void Renderer::Init()
glVertexAttribPointer(SHADER_COLOR0_ATTRIB, 3, GL_FLOAT, 0, sizeof(GLfloat)*5, (GLfloat*)nullptr+2);
}
// Create On-Screen-Messages
void Renderer::ShowEfbCopyRegions()
{
if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL && g_ActiveConfig.bShowEFBCopyRegions)
{
// Set Line Size
glLineWidth(3.0f);
// 2*Coords + 3*Color
GLsizeiptr length = stats.efb_regions.size() * sizeof(GLfloat) * (2 + 3) * 2 * 6;
glBindBuffer(GL_ARRAY_BUFFER, s_ShowEFBCopyRegions_VBO);
glBufferData(GL_ARRAY_BUFFER, length, nullptr, GL_STREAM_DRAW);
GLfloat *Vertices = (GLfloat*)glMapBufferRange(GL_ARRAY_BUFFER, 0, length, GL_MAP_WRITE_BIT);
// Draw EFB copy regions rectangles
int a = 0;
GLfloat color[3] = {0.0f, 1.0f, 1.0f};
for (const EFBRectangle& rect : stats.efb_regions)
{
GLfloat halfWidth = EFB_WIDTH / 2.0f;
GLfloat halfHeight = EFB_HEIGHT / 2.0f;
GLfloat x = (GLfloat) -1.0f + ((GLfloat)rect.left / halfWidth);
GLfloat y = (GLfloat) 1.0f - ((GLfloat)rect.top / halfHeight);
GLfloat x2 = (GLfloat) -1.0f + ((GLfloat)rect.right / halfWidth);
GLfloat y2 = (GLfloat) 1.0f - ((GLfloat)rect.bottom / halfHeight);
Vertices[a++] = x;
Vertices[a++] = y;
Vertices[a++] = color[0];
Vertices[a++] = color[1];
Vertices[a++] = color[2];
Vertices[a++] = x2;
Vertices[a++] = y;
Vertices[a++] = color[0];
Vertices[a++] = color[1];
Vertices[a++] = color[2];
Vertices[a++] = x2;
Vertices[a++] = y;
Vertices[a++] = color[0];
Vertices[a++] = color[1];
Vertices[a++] = color[2];
Vertices[a++] = x2;
Vertices[a++] = y2;
Vertices[a++] = color[0];
Vertices[a++] = color[1];
Vertices[a++] = color[2];
Vertices[a++] = x2;
Vertices[a++] = y2;
Vertices[a++] = color[0];
Vertices[a++] = color[1];
Vertices[a++] = color[2];
Vertices[a++] = x;
Vertices[a++] = y2;
Vertices[a++] = color[0];
Vertices[a++] = color[1];
Vertices[a++] = color[2];
Vertices[a++] = x;
Vertices[a++] = y2;
Vertices[a++] = color[0];
Vertices[a++] = color[1];
Vertices[a++] = color[2];
Vertices[a++] = x;
Vertices[a++] = y;
Vertices[a++] = color[0];
Vertices[a++] = color[1];
Vertices[a++] = color[2];
Vertices[a++] = x;
Vertices[a++] = y;
Vertices[a++] = color[0];
Vertices[a++] = color[1];
Vertices[a++] = color[2];
Vertices[a++] = x2;
Vertices[a++] = y2;
Vertices[a++] = color[0];
Vertices[a++] = color[1];
Vertices[a++] = color[2];
Vertices[a++] = x2;
Vertices[a++] = y;
Vertices[a++] = color[0];
Vertices[a++] = color[1];
Vertices[a++] = color[2];
Vertices[a++] = x;
Vertices[a++] = y2;
Vertices[a++] = color[0];
Vertices[a++] = color[1];
Vertices[a++] = color[2];
// TO DO: build something nicer here
GLfloat temp = color[0];
color[0] = color[1];
color[1] = color[2];
color[2] = temp;
}
glUnmapBuffer(GL_ARRAY_BUFFER);
s_ShowEFBCopyRegions.Bind();
glBindVertexArray(s_ShowEFBCopyRegions_VAO);
GLsizei count = static_cast<GLsizei>(stats.efb_regions.size() * 2*6);
glDrawArrays(GL_LINES, 0, count);
// Clear stored regions
stats.efb_regions.clear();
}
}
void Renderer::RenderText(const std::string& text, int left, int top, u32 color)
{
const int nBackbufferWidth = (int)GLInterface->GetBackBufferWidth();
@@ -1706,7 +1584,6 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
// Reset viewport for drawing text
glViewport(0, 0, GLInterface->GetBackBufferWidth(), GLInterface->GetBackBufferHeight());
ShowEfbCopyRegions();
DrawDebugText();
// Do our OSD callbacks

View File

@@ -86,8 +86,7 @@ public:
void ApplyState(bool bUseDstAlpha) override {}
void RestoreState() override {}
void RenderText(const std::string& text, int left, int top, u32 color) override;
void ShowEfbCopyRegions();
void RenderText(const std::string& text, int left, int top, u32 color) override;
void FlipImageData(u8 *data, int w, int h, int pixel_width = 3);
u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override;

View File

@@ -14,7 +14,7 @@
namespace OGL
{
class TextureCache : public ::TextureCache
class TextureCache : public ::TextureCacheBase
{
public:
TextureCache();
@@ -22,7 +22,7 @@ public:
static void SetStage();
private:
struct TCacheEntry : TCacheEntryBase
struct TCacheEntry : TextureCacheBase::TCacheEntryBase
{
GLuint texture;
GLuint nrm_texture;

View File

@@ -280,7 +280,7 @@ void EncodeToRamFromTexture(u8 *dest_ptr, const TextureCache::TCacheEntryBase *t
source.left, source.top, texture_entry->native_width, bScaleByHalf ? 2 : 1);
EncodeToRamUsingShader(source_texture,
dest_ptr, texture_entry->CacheLinesPerRow() * 32, texture_entry->NumBlocksY(),
dest_ptr, texture_entry->BytesPerRow(), texture_entry->NumBlocksY(),
texture_entry->memory_stride, bScaleByHalf > 0 && !bFromZBuffer);
}

View File

@@ -25,7 +25,7 @@ void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc,
void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTexture);
// returns size of the encoded data (in bytes)
void EncodeToRamFromTexture(u8 *dest_ptr, const TextureCache::TCacheEntryBase *texture_entry,
void EncodeToRamFromTexture(u8 *dest_ptr, const TextureCacheBase::TCacheEntryBase *texture_entry,
GLuint source_texture, bool bFromZBuffer, bool bIsIntensityFmt, int bScaleByHalf, const EFBRectangle& source);
}

View File

@@ -25,7 +25,7 @@ namespace OGL
// Handles the OpenGL details of drawing lots of vertices quickly.
// Other functionality is moving out.
class VertexManager : public ::VertexManager
class VertexManager : public ::VertexManagerBase
{
public:
VertexManager();

View File

@@ -27,7 +27,7 @@ namespace BPFunctions
void FlushPipeline()
{
VertexManager::Flush();
VertexManagerBase::Flush();
}
void SetGenerationMode()

View File

@@ -258,11 +258,8 @@ void BPWritten(const BPCmd& bp)
// Check if we are to copy from the EFB or draw to the XFB
if (PE_copy.copy_to_xfb == 0)
{
if (g_ActiveConfig.bShowEFBCopyRegions)
stats.efb_regions.push_back(srcRect);
// bpmem.zcontrol.pixel_format to PEControl::Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format)
TextureCache::CopyRenderTargetToTexture(destAddr, PE_copy.tp_realFormat(), destStride,
TextureCacheBase::CopyRenderTargetToTexture(destAddr, PE_copy.tp_realFormat(), destStride,
bpmem.zcontrol.pixel_format, srcRect,
!!PE_copy.intensity_fmt, !!PE_copy.half_scale);
}

Some files were not shown because too many files have changed in this diff Show More