diff --git a/CMakeLists.txt b/CMakeLists.txt
index ea88a762d6..34bec74416 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,8 +3,9 @@
#
cmake_minimum_required(VERSION 2.6)
-option(USE_GLES "Enables GLES And EGL, disables OGL" OFF)
+option(ANDROID "Enables a build for Android" OFF)
option(USE_EGL "Enables EGL OpenGL Interface" OFF)
+option(USE_GLES "Enables GLES And EGL, disables OGL" OFF)
option(DISABLE_WX "Disable wxWidgets (use CLI interface)" OFF)
option(FASTLOG "Enable all logs" OFF)
@@ -271,7 +272,6 @@ if(USE_EGL)
endif()
add_definitions(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE)
-option(ANDROID "Enables a build for Android" OFF)
if(ANDROID)
message("Building for Android")
add_definitions(-DANDROID)
@@ -394,7 +394,6 @@ if(NOT ANDROID)
set(PORTAUDIO_FOUND FALSE)
endif(PORTAUDIO)
- option(OPROFILING "Enable profiling" OFF)
if(OPROFILING)
check_lib(OPROFILE opagent opagent.h)
check_lib(BFD bfd bfd.h)
diff --git a/Data/User/GameConfig/GAFE01.ini b/Data/User/GameConfig/GAFE01.ini
index dcef253178..73e01b1138 100644
--- a/Data/User/GameConfig/GAFE01.ini
+++ b/Data/User/GameConfig/GAFE01.ini
@@ -319,4 +319,4 @@ PH_ZFar =
[Video_Settings]
SafeTextureCacheColorSamples = 512
[Core]
-FastDiscSpeed = 1
+
diff --git a/Data/User/GameConfig/GAFJ01.ini b/Data/User/GameConfig/GAFJ01.ini
index b6e93ab361..5e3a64f473 100644
--- a/Data/User/GameConfig/GAFJ01.ini
+++ b/Data/User/GameConfig/GAFJ01.ini
@@ -16,4 +16,4 @@ PH_ZFar =
[Video_Settings]
SafeTextureCacheColorSamples = 512
[Core]
-FastDiscSpeed = 1
+
diff --git a/Data/User/GameConfig/GAFP01.ini b/Data/User/GameConfig/GAFP01.ini
index 7930f58e5f..d3ba2f99fc 100644
--- a/Data/User/GameConfig/GAFP01.ini
+++ b/Data/User/GameConfig/GAFP01.ini
@@ -16,4 +16,4 @@ PH_ZFar =
[Video_Settings]
SafeTextureCacheColorSamples = 512
[Core]
-FastDiscSpeed = 1
+
diff --git a/Data/User/GameConfig/GAFU01.ini b/Data/User/GameConfig/GAFU01.ini
index 273357ddc1..990f09d3cb 100644
--- a/Data/User/GameConfig/GAFU01.ini
+++ b/Data/User/GameConfig/GAFU01.ini
@@ -16,4 +16,4 @@ PH_ZFar =
[Video_Settings]
SafeTextureCacheColorSamples = 512
[Core]
-FastDiscSpeed = 1
+
diff --git a/Data/User/GameConfig/GFZE01.ini b/Data/User/GameConfig/GFZE01.ini
index 32b1e195c0..d6ffdecdf1 100644
--- a/Data/User/GameConfig/GFZE01.ini
+++ b/Data/User/GameConfig/GFZE01.ini
@@ -2,10 +2,10 @@
[Core] Values set here will override the main dolphin settings.
EnableFPRF = True
TLBHack = 1
-CPUThread = 0
+SyncGPU = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4
-EmulationIssues = Dual core is very unstable/doesn't even boot with most video plugins. Efb to ram is needed for proper shadows.
+EmulationIssues = Needs Synchronize GPU thread for stability.
[OnFrame] Add memory patches to be applied every frame here.
[Video]
ProjectionHack = 1
diff --git a/Data/User/GameConfig/GFZJ01.ini b/Data/User/GameConfig/GFZJ01.ini
new file mode 100644
index 0000000000..fe25191e22
--- /dev/null
+++ b/Data/User/GameConfig/GFZJ01.ini
@@ -0,0 +1,26 @@
+# GFZJ01 - F-ZERO GX
+[Core] Values set here will override the main dolphin settings.
+EnableFPRF = True
+TLBHack = 1
+SyncGPU = 1
+[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
+EmulationStateId = 4
+EmulationIssues = Needs Synchronize GPU thread for stability.
+[OnFrame] Add memory patches to be applied every frame here.
+[Video]
+ProjectionHack = 1
+PH_SZNear = 1
+PH_SZFar = 1
+PH_ExtraParam = 0
+PH_ZNear = 20
+PH_ZFar = 1.7555555
+[ActionReplay]
+$Make Save Copyable
+0C031514 909C0028
+04031518 48BFFBE8
+04C31100 38000004
+04C31104 981C0034
+04C31108 38000000
+04C3110C 4B400410
+[Gecko]
+
diff --git a/Data/User/GameConfig/GFZP01.ini b/Data/User/GameConfig/GFZP01.ini
index 0586d53d3f..dbae5b6711 100644
--- a/Data/User/GameConfig/GFZP01.ini
+++ b/Data/User/GameConfig/GFZP01.ini
@@ -2,10 +2,10 @@
[Core] Values set here will override the main dolphin settings.
EnableFPRF = True
TLBHack = 1
-CPUThread = 0
+SyncGPU = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4
-EmulationIssues = Dual core is very unstable/doesn't even boot with most video plugins. Efb to ram is needed for proper shadows.
+EmulationIssues = Needs Synchronize GPU thread for stability.
[OnFrame] Add memory patches to be applied every frame here.
[Video]
ProjectionHack = 1
diff --git a/Data/User/GameConfig/GJXE51.ini b/Data/User/GameConfig/GJXE51.ini
index aa031144dd..d503dffbef 100644
--- a/Data/User/GameConfig/GJXE51.ini
+++ b/Data/User/GameConfig/GJXE51.ini
@@ -15,4 +15,4 @@ EmulationIssues = Slow,needs mmu and lle audio plugin for proper audio(r7411).
[Video_Settings]
[Core]
MMU = 1
-FastDiscSpeed = 1
+
diff --git a/Data/User/GameConfig/GNOE78.ini b/Data/User/GameConfig/GNOE78.ini
index ca4bbf12fa..cd43ce75ab 100644
--- a/Data/User/GameConfig/GNOE78.ini
+++ b/Data/User/GameConfig/GNOE78.ini
@@ -1,7 +1,6 @@
# GNOE78 - Nicktoons Unite!
[Core] Values set here will override the main dolphin settings.
TLBHack = 1
-FastDiscSpeed = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4
EmulationIssues =
diff --git a/Data/User/GameConfig/GOSE41.ini b/Data/User/GameConfig/GOSE41.ini
index adc124119f..4a9637bf1a 100644
--- a/Data/User/GameConfig/GOSE41.ini
+++ b/Data/User/GameConfig/GOSE41.ini
@@ -1,7 +1,6 @@
# GOSE41 - Open Season
[Core] Values set here will override the main dolphin settings.
MMU = 1
-FastDiscSpeed = 1
BlockMerging = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4
diff --git a/Data/User/GameConfig/GOSP41.ini b/Data/User/GameConfig/GOSP41.ini
index cb12055384..9ce80bf3d3 100644
--- a/Data/User/GameConfig/GOSP41.ini
+++ b/Data/User/GameConfig/GOSP41.ini
@@ -1,7 +1,6 @@
# GOSP41 - Open Season
[Core] Values set here will override the main dolphin settings.
MMU = 1
-FastDiscSpeed = 1
BlockMerging = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4
diff --git a/Data/User/GameConfig/GOSX41.ini b/Data/User/GameConfig/GOSX41.ini
index 8790cdfd8c..c28b0dbebc 100644
--- a/Data/User/GameConfig/GOSX41.ini
+++ b/Data/User/GameConfig/GOSX41.ini
@@ -1,7 +1,6 @@
# GOSX41 - Open Season
[Core] Values set here will override the main dolphin settings.
MMU = 1
-FastDiscSpeed = 1
BlockMerging = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4
diff --git a/Data/User/GameConfig/GWAE8P.ini b/Data/User/GameConfig/GWAE8P.ini
index b7e3138a49..3163bd601a 100644
--- a/Data/User/GameConfig/GWAE8P.ini
+++ b/Data/User/GameConfig/GWAE8P.ini
@@ -1,6 +1,5 @@
# GWAE8P - Spartan: Total Warrior
[Core] Values set here will override the main dolphin settings.
-FastDiscSpeed = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 0
EmulationIssues =
diff --git a/Data/User/GameConfig/GWAF8P.ini b/Data/User/GameConfig/GWAF8P.ini
index 56be20b81e..53c4baf506 100644
--- a/Data/User/GameConfig/GWAF8P.ini
+++ b/Data/User/GameConfig/GWAF8P.ini
@@ -1,6 +1,5 @@
# GWAF8P - Spartan: Total Warrior
[Core] Values set here will override the main dolphin settings.
-FastDiscSpeed = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 0
EmulationIssues =
diff --git a/Data/User/GameConfig/GWAP8P.ini b/Data/User/GameConfig/GWAP8P.ini
index af91c968bc..5a1bcd81b1 100644
--- a/Data/User/GameConfig/GWAP8P.ini
+++ b/Data/User/GameConfig/GWAP8P.ini
@@ -1,6 +1,5 @@
# GWAP8P - Spartan : Total Warrior (TM)
[Core] Values set here will override the main dolphin settings.
-FastDiscSpeed = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 0
EmulationIssues =
diff --git a/Data/User/GameConfig/RRBE41.ini b/Data/User/GameConfig/RRBE41.ini
index ec6dc890e8..b16ea65aee 100644
--- a/Data/User/GameConfig/RRBE41.ini
+++ b/Data/User/GameConfig/RRBE41.ini
@@ -1,9 +1,9 @@
# RRBE41 - Rayman Raving Rabbids
[Core] Values set here will override the main dolphin settings.
-CPUThread = 0
+SyncGPU = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4
-EmulationIssues = Dual core is unstable.Use direct3d11 for less glitches. Slow.(r7687)
+EmulationIssues = Needs Synchronise GPU thread for stability. Use direct3d11 for less glitches.
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.
[Video]
@@ -14,4 +14,4 @@ PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko]
-[Wii]
\ No newline at end of file
+[Wii]
diff --git a/Data/User/GameConfig/RRBJ41.ini b/Data/User/GameConfig/RRBJ41.ini
index 498d8aca84..64e91abdf4 100644
--- a/Data/User/GameConfig/RRBJ41.ini
+++ b/Data/User/GameConfig/RRBJ41.ini
@@ -1,9 +1,9 @@
# RRBJ41 - Rayman Raving Rabbids
[Core] Values set here will override the main dolphin settings.
-CPUThread = 0
+SyncGPU = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4
-EmulationIssues = Dual core is unstable.Use direct3d11 for less glitches. Slow.(r7687)
+EmulationIssues = Needs Synchronise GPU thread for stability. Use direct3d11 for less glitches.
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.
[Video]
diff --git a/Data/User/GameConfig/RRBP41.ini b/Data/User/GameConfig/RRBP41.ini
index ae27d7f6db..5305264dc4 100644
--- a/Data/User/GameConfig/RRBP41.ini
+++ b/Data/User/GameConfig/RRBP41.ini
@@ -1,9 +1,9 @@
# RRBP41 - Rayman Raving Rabbids
[Core] Values set here will override the main dolphin settings.
-CPUThread = 0
+SyncGPU = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4
-EmulationIssues = Dual core is unstable.Use direct3d11 for less glitches. Slow.(r7687)
+EmulationIssues = Needs Synchronise GPU thread for stability. Use direct3d11 for less glitches.
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.
[Video]
diff --git a/Externals/soundtouch/SoundTouch.vcxproj b/Externals/soundtouch/SoundTouch.vcxproj
index 8f5c475687..763b00a58a 100644
--- a/Externals/soundtouch/SoundTouch.vcxproj
+++ b/Externals/soundtouch/SoundTouch.vcxproj
@@ -174,7 +174,7 @@
Default
- Win32\SoundTouch.lib
+ Win32\SoundTouchD.lib
true
diff --git a/Source/Core/Common/Src/ArmCPUDetect.cpp b/Source/Core/Common/Src/ArmCPUDetect.cpp
index 8b5cbf9b79..04be3ac90c 100644
--- a/Source/Core/Common/Src/ArmCPUDetect.cpp
+++ b/Source/Core/Common/Src/ArmCPUDetect.cpp
@@ -122,6 +122,12 @@ void CPUInfo::Detect()
bVFPv4 = CheckCPUFeature("vfpv4");
bIDIVa = CheckCPUFeature("idiva");
bIDIVt = CheckCPUFeature("idivt");
+
+ // On some buggy kernels(Qualcomm) they show that they support VFPv4 but not IDIVa
+ // All VFPv4 CPUs will support IDIVa
+ if (bVFPv4)
+ bIDIVa = bIDIVt = true;
+
// These two are ARMv8 specific.
bFP = CheckCPUFeature("fp");
bASIMD = CheckCPUFeature("asimd");
diff --git a/Source/Core/Common/Src/ArmEmitter.cpp b/Source/Core/Common/Src/ArmEmitter.cpp
index c6fd34f55c..10c72cf39f 100644
--- a/Source/Core/Common/Src/ArmEmitter.cpp
+++ b/Source/Core/Common/Src/ArmEmitter.cpp
@@ -176,7 +176,7 @@ void ARMXEmitter::MOVI2R(ARMReg reg, u32 val, bool optimize)
} else {
// Use literal pool for ARMv6.
AddNewLit(val);
- LDRLIT(reg, 0, 0); // To be backpatched later
+ LDR(reg, _PC); // To be backpatched later
}
}
}
@@ -608,39 +608,6 @@ void ARMXEmitter::MRS (ARMReg dest)
{
Write32(condition | (16 << 20) | (15 << 16) | (dest << 12));
}
-
-void ARMXEmitter::WriteStoreOp(u32 op, ARMReg src, ARMReg dest, s16 op2)
-{
- // Qualcomm chipsets get /really/ angry if you don't use index, even if the offset is zero.
- // bool Index = op2 != 0 ? true : false;
- bool Index = true;
- bool Add = op2 >= 0 ? true : false;
- u32 imm = abs(op2);
- Write32(condition | (op << 20) | (Index << 24) | (Add << 23) | (src << 16) | (dest << 12) | imm);
-}
-void ARMXEmitter::STR (ARMReg result, ARMReg base, s16 op) { WriteStoreOp(0x40, base, result, op);}
-void ARMXEmitter::STRH (ARMReg result, ARMReg base, Operand2 op)
-{
- u8 Imm = op.Imm8();
- Write32(condition | (0x04 << 20) | (base << 16) | (result << 12) | ((Imm >> 4) << 8) | (0xB << 4) | (Imm & 0x0F));
-}
-void ARMXEmitter::STRB (ARMReg result, ARMReg base, s16 op) { WriteStoreOp(0x44, base, result, op);}
-void ARMXEmitter::STR (ARMReg result, ARMReg base, Operand2 op2, bool Index, bool Add)
-{
- Write32(condition | (0x60 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (result << 12) | op2.IMMSR());
-}
-void ARMXEmitter::STR (ARMReg result, ARMReg base, ARMReg offset, bool Index, bool Add)
-{
- Write32(condition | (0x60 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (result << 12) | offset);
-}
-void ARMXEmitter::STRH (ARMReg result, ARMReg base, ARMReg offset, bool Index, bool Add)
-{
- Write32(condition | (0x00 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (result << 12) | (0xB << 4) | offset);
-}
-void ARMXEmitter::STRB (ARMReg result, ARMReg base, ARMReg offset, bool Index, bool Add)
-{
- Write32(condition | (0x64 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (result << 12) | offset);
-}
void ARMXEmitter::LDREX(ARMReg dest, ARMReg base)
{
Write32(condition | (25 << 20) | (base << 16) | (dest << 12) | 0xF9F);
@@ -659,49 +626,113 @@ void ARMXEmitter::SVC(Operand2 op)
Write32(condition | (0x0F << 24) | op.Imm24());
}
-void ARMXEmitter::LDR (ARMReg dest, ARMReg src, s16 op) { WriteStoreOp(0x41, src, dest, op);}
-void ARMXEmitter::LDRH(ARMReg dest, ARMReg src, Operand2 op)
+// IMM, REG, IMMSREG, RSR
+// -1 for invalid if the instruction doesn't support that
+const s32 LoadStoreOps[][4] = { {0x40, 0x60, 0x60, -1}, // STR
+ {0x41, 0x61, 0x61, -1}, // LDR
+ {0x44, 0x64, 0x64, -1}, // STRB
+ {0x45, 0x65, 0x65, -1}, // LDRB
+ // Special encodings
+ { 0x4, 0x0, -1, -1}, // STRH
+ { 0x5, 0x1, -1, -1}, // LDRH
+ { 0x5, 0x1, -1, -1}, // LDRSB
+ { 0x5, 0x1, -1, -1}, // LDRSH
+ };
+const char *LoadStoreNames[] = { "STR",
+ "LDR",
+ "STRB",
+ "LDRB",
+ "STRH",
+ "LDRH",
+ "LDRSB",
+ "LDRSH",
+ };
+
+void ARMXEmitter::WriteStoreOp(u32 Op, ARMReg Rt, ARMReg Rn, Operand2 Rm, bool RegAdd)
{
- u8 Imm = op.Imm8();
- Write32(condition | (0x05 << 20) | (src << 16) | (dest << 12) | ((Imm >> 4) << 8) | (0xB << 4) | (Imm & 0x0F));
-}
-void ARMXEmitter::LDRSH(ARMReg dest, ARMReg src, Operand2 op)
-{
- u8 Imm = op.Imm8();
- Write32(condition | (0x05 << 20) | (src << 16) | (dest << 12) | ((Imm >> 4) << 8) | (0xF << 4) | (Imm & 0x0F));
-}
-void ARMXEmitter::LDRB(ARMReg dest, ARMReg src, s16 op) { WriteStoreOp(0x45, src, dest, op);}
-void ARMXEmitter::LDRSB(ARMReg dest, ARMReg src, Operand2 op)
-{
- u8 Imm = op.Imm8();
- Write32(condition | (0x05 << 20) | (src << 16) | (dest << 12) | ((Imm >> 4) << 8) | (0xD << 4) | (Imm & 0x0F));
+ s32 op = LoadStoreOps[Op][Rm.GetType()]; // Type always decided by last operand
+ u32 Data;
+
+ // Qualcomm chipsets get /really/ angry if you don't use index, even if the offset is zero.
+ // Some of these encodings require Index at all times anyway. Doesn't really matter.
+ // bool Index = op2 != 0 ? true : false;
+ bool Index = true;
+ bool Add = false;
+
+ // Special Encoding
+ bool SpecialOp = false;
+ bool Half = false;
+ bool SignedLoad = false;
+
+ if (op == -1)
+ _assert_msg_(DYNA_REC, false, "%s does not support %d", LoadStoreNames[Op], Rm.GetType());
+
+ switch (Op)
+ {
+ case 4: // STRH
+ SpecialOp = true;
+ Half = true;
+ SignedLoad = false;
+ break;
+ case 5: // LDRH
+ SpecialOp = true;
+ Half = true;
+ SignedLoad = false;
+ break;
+ case 6: // LDRSB
+ SpecialOp = true;
+ Half = false;
+ SignedLoad = true;
+ break;
+ case 7: // LDRSH
+ SpecialOp = true;
+ Half = true;
+ SignedLoad = true;
+ break;
+ }
+ switch (Rm.GetType())
+ {
+ case TYPE_IMM:
+ {
+ s32 Temp = (s32)Rm.Value;
+ Data = abs(Temp);
+ // The offset is encoded differently on this one.
+ if (SpecialOp)
+ Data = (Data & 0xF0 << 4) | (Data & 0xF);
+ if (Temp >= 0) Add = true;
+ }
+ break;
+ case TYPE_REG:
+ case TYPE_IMMSREG:
+ if (!SpecialOp)
+ {
+ Data = Rm.GetData();
+ Add = RegAdd;
+ break;
+ }
+ default:
+ // RSR not supported for any of these
+ // We already have the warning above
+ BKPT(0x2);
+ return;
+ break;
+ }
+ if (SpecialOp)
+ {
+ // Add SpecialOp things
+ Data = (0x5 << 4) | (SignedLoad << 6) | (Half << 5) | Data;
+ }
+ Write32(condition | (op << 20) | (Index << 24) | (Add << 23) | (Rn << 16) | (Rt << 12) | Data);
}
-void ARMXEmitter::LDR (ARMReg dest, ARMReg base, Operand2 op2, bool Index, bool Add)
-{
- Write32(condition | (0x61 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (dest << 12) | op2.IMMSR());
-}
-void ARMXEmitter::LDR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add)
-{
- Write32(condition | (0x61 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (dest << 12) | offset);
-}
-void ARMXEmitter::LDRH (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add)
-{
- Write32(condition | (0x01 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (dest << 12) | (0xB << 4) | offset);
-}
-void ARMXEmitter::LDRSH(ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add)
-{
- Write32(condition | (0x01 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (dest << 12) | (0xF << 4) | offset);
-}
-void ARMXEmitter::LDRB (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add)
-{
- Write32(condition | (0x65 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (dest << 12) | offset);
-}
-void ARMXEmitter::LDRSB(ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add)
-{
- Write32(condition | (0x01 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (dest << 12) | (0xD << 4) | offset);
-}
-void ARMXEmitter::LDRLIT (ARMReg dest, u32 offset, bool Add) { Write32(condition | 0x05 << 24 | Add << 23 | 0x1F << 16 | dest << 12 | offset);}
+void ARMXEmitter::LDR (ARMReg dest, ARMReg base, Operand2 op2, bool RegAdd) { WriteStoreOp(1, dest, base, op2, RegAdd);}
+void ARMXEmitter::LDRB(ARMReg dest, ARMReg base, Operand2 op2, bool RegAdd) { WriteStoreOp(3, dest, base, op2, RegAdd);}
+void ARMXEmitter::LDRH(ARMReg dest, ARMReg base, Operand2 op2, bool RegAdd) { WriteStoreOp(5, dest, base, op2, RegAdd);}
+void ARMXEmitter::LDRSB(ARMReg dest, ARMReg base, Operand2 op2, bool RegAdd) { WriteStoreOp(6, dest, base, op2, RegAdd);}
+void ARMXEmitter::LDRSH(ARMReg dest, ARMReg base, Operand2 op2, bool RegAdd) { WriteStoreOp(7, dest, base, op2, RegAdd);}
+void ARMXEmitter::STR (ARMReg result, ARMReg base, Operand2 op2, bool RegAdd) { WriteStoreOp(0, result, base, op2, RegAdd);}
+void ARMXEmitter::STRH (ARMReg result, ARMReg base, Operand2 op2, bool RegAdd) { WriteStoreOp(4, result, base, op2, RegAdd);}
+void ARMXEmitter::STRB (ARMReg result, ARMReg base, Operand2 op2, bool RegAdd) { WriteStoreOp(2, result, base, op2, RegAdd);}
void ARMXEmitter::WriteRegStoreOp(u32 op, ARMReg dest, bool WriteBack, u16 RegList)
{
@@ -787,6 +818,100 @@ void ARMXEmitter::VSUB(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
}
// VFP Specific
+struct VFPEnc
+{
+ u16 opc1;
+ u16 opc2;
+};
+// Double/single, Neon
+const VFPEnc VFPOps[][2] = {
+ {{0xE0, 0xA0}, {0x20, 0xD1}}, // VMLA
+ {{0xE0, 0xA4}, {0x22, 0xD1}}, // VMLS
+ {{0xE3, 0xA0}, {0x20, 0xD0}}, // VADD
+ {{0xE3, 0xA4}, {0x22, 0xD0}}, // VSUB
+ {{0xE2, 0xA0}, {0x30, 0xD1}}, // VMUL
+ {{0xEB, 0xAC}, {0x3B, 0x30}}, // VABS
+ {{0xE8, 0xA0}, { -1, -1}}, // VDIV
+ {{0xEB, 0xA4}, { -1, -1}}, // VNEG
+ {{0xEB, 0xAC}, { -1, -1}}, // VSQRT
+ {{0xED, 0xA2}, { -1, -1}}, // VCMP
+ {{0xED, 0xAA}, { -1, -1}}, // VCMPE
+ {{ -1, -1}, {0x3B, 0x70}}, // VABSi
+ };
+const char *VFPOps[] = {
+ "VMLA",
+ "VMLS",
+ "VADD",
+ "VSUB",
+ "VMUL",
+ "VABS",
+ "VDIV",
+ "VNEG",
+ "VSQRT",
+ "VCMP",
+ "VCMPE",
+ "VABSi",
+};
+
+u32 ARMXEmitter::EncodeVd(ARMReg Vd)
+{
+ bool quad_reg = Vd >= Q0;
+ bool double_reg = Vd >= D0;
+
+ ARMReg Reg = SubBase(Vd);
+
+ if (quad_reg)
+ ((Reg & 0x10) << 18) | ((Reg & 0xF) << 12);
+ else
+ if (double_reg)
+ return ((Reg & 0x10) << 18) | ((Reg & 0xF) << 16);
+ else
+ return ((Reg & 0x1) << 22) | ((Reg & 0x1E) << 11);
+}
+u32 ARMXEmitter::EncodeVn(ARMReg Vn)
+{
+ bool quad_reg = Vn >= Q0;
+ bool double_reg = Vn >= D0;
+
+ ARMReg Reg = SubBase(Vn);
+ if (quad_reg)
+ ((Reg & 0xF) << 16) | ((Reg & 0x10) << 3);
+ else
+ if (double_reg)
+ return ((Reg & 0xF) << 16) | ((Reg & 0x10) << 3);
+ else
+ return ((Reg & 0x1E) << 15) | ((Reg & 0x1) << 7);
+}
+u32 ARMXEmitter::EncodeVm(ARMReg Vm)
+{
+ bool quad_reg = Vm >= Q0;
+ bool double_reg = Vm >= D0;
+
+ ARMReg Reg = SubBase(Vm);
+
+ if (quad_reg)
+ ((Reg & 0x10) << 2) | (Reg & 0xF);
+ else
+ if (double_reg)
+ return ((Reg & 0x10) << 2) | (Reg & 0xF);
+ else
+ return ((Reg & 0x1) << 5) | (Reg >> 1);
+}
+void ARMXEmitter::WriteVFPDataOp(u32 Op, ARMReg Vd, ARMReg Vn, ARMReg Vm)
+{
+ bool quad_reg = Vd >= Q0;
+ bool double_reg = Vd >= D0;
+
+ VFPEnc enc = VFPOps[Op][quad_reg];
+ if (enc.opc1 == (u16)-1 && enc.opc1 == (u16)-1)
+ _assert_msg_(DYNA_REC, false, "%s does not support %s", VFPOps[Op], quad_reg ? "NEON" : "VFP");
+ u32 VdEnc = EncodeVd(Vd);
+ u32 VnEnc = EncodeVn(Vn);
+ u32 VmEnc = EncodeVm(Vm);
+ u32 cond = quad_reg ? (0xF << 28) : condition;
+
+ Write32(cond | enc.opc1 | VnEnc | VdEnc | enc.opc2 | VmEnc);
+}
void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, s16 offset)
{
diff --git a/Source/Core/Common/Src/ArmEmitter.h b/Source/Core/Common/Src/ArmEmitter.h
index 20d867fa39..0749d42c96 100644
--- a/Source/Core/Common/Src/ArmEmitter.h
+++ b/Source/Core/Common/Src/ArmEmitter.h
@@ -352,7 +352,7 @@ private:
u32 condition;
std::vector currentLitPool;
- void WriteStoreOp(u32 op, ARMReg src, ARMReg dest, s16 op2);
+ void WriteStoreOp(u32 Op, ARMReg Rt, ARMReg Rn, Operand2 op2, bool RegAdd);
void WriteRegStoreOp(u32 op, ARMReg dest, bool WriteBack, u16 RegList);
void WriteShiftedDataOp(u32 op, bool SetFlags, ARMReg dest, ARMReg src, ARMReg op2);
void WriteShiftedDataOp(u32 op, bool SetFlags, ARMReg dest, ARMReg src, Operand2 op2);
@@ -495,28 +495,14 @@ public:
void MRS (ARMReg dest);
// Memory load/store operations
- void LDR (ARMReg dest, ARMReg src, s16 op2 = 0);
- void LDRH (ARMReg dest, ARMReg src, Operand2 op2 = 0);
- void LDRSH(ARMReg dest, ARMReg src, Operand2 op2 = 0);
- void LDRB (ARMReg dest, ARMReg src, s16 op2 = 0);
- void LDRSB(ARMReg dest, ARMReg src, Operand2 op2 = 0);
- // Offset adds to the base register in LDR
- void LDR (ARMReg dest, ARMReg base, Operand2 op2, bool Index, bool Add);
- void LDR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add);
- void LDRH (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add);
- void LDRSH(ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add);
- void LDRB (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add);
- void LDRSB(ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add);
- void LDRLIT(ARMReg dest, u32 offset, bool Add);
-
- void STR (ARMReg result, ARMReg base, s16 op2 = 0);
- void STRH (ARMReg result, ARMReg base, Operand2 op2 = 0);
- void STRB (ARMReg result, ARMReg base, s16 op2 = 0);
- // Offset adds on to the destination register in STR
- void STR (ARMReg result, ARMReg base, Operand2 op2, bool Index, bool Add);
- void STR (ARMReg result, ARMReg base, ARMReg offset, bool Index, bool Add);
- void STRH (ARMReg result, ARMReg base, ARMReg offset, bool Index, bool Add);
- void STRB (ARMReg result, ARMReg base, ARMReg offset, bool Index, bool Add);
+ void LDR (ARMReg dest, ARMReg base, Operand2 op2 = 0, bool RegAdd = true);
+ void LDRB (ARMReg dest, ARMReg base, Operand2 op2 = 0, bool RegAdd = true);
+ void LDRH (ARMReg dest, ARMReg base, Operand2 op2 = 0, bool RegAdd = true);
+ void LDRSB(ARMReg dest, ARMReg base, Operand2 op2 = 0, bool RegAdd = true);
+ void LDRSH(ARMReg dest, ARMReg base, Operand2 op2 = 0, bool RegAdd = true);
+ void STR (ARMReg result, ARMReg base, Operand2 op2 = 0, bool RegAdd = true);
+ void STRB (ARMReg result, ARMReg base, Operand2 op2 = 0, bool RegAdd = true);
+ void STRH (ARMReg result, ARMReg base, Operand2 op2 = 0, bool RegAdd = true);
void STMFD(ARMReg dest, bool WriteBack, const int Regnum, ...);
void LDMFD(ARMReg dest, bool WriteBack, const int Regnum, ...);
diff --git a/Source/Core/Core/Src/HW/WII_IPC.cpp b/Source/Core/Core/Src/HW/WII_IPC.cpp
index 3651eef8ab..3d269d0fcd 100644
--- a/Source/Core/Core/Src/HW/WII_IPC.cpp
+++ b/Source/Core/Core/Src/HW/WII_IPC.cpp
@@ -28,6 +28,7 @@
#include "../IPC_HLE/WII_IPC_HLE.h"
#include "WII_IPC.h"
+#include "CoreTiming.h"
// This is the intercommunication between ARM and PPC. Currently only PPC actually uses it, because of the IOS HLE
@@ -104,6 +105,8 @@ static u32 arm_irq_masks;
static u32 sensorbar_power; // do we need to care about this?
+int updateInterrupts;
+
void DoState(PointerWrap &p)
{
p.Do(ppc_msg);
@@ -130,6 +133,8 @@ void Init()
sensorbar_power = 0;
ppc_irq_masks |= INT_CAUSE_IPC_BROADWAY;
+
+ updateInterrupts = CoreTiming::RegisterEvent("IPCInterrupt", UpdateInterrupts);
}
void Reset()
@@ -222,10 +227,10 @@ void Write32(const u32 _Value, const u32 _Address)
}
WII_IPC_HLE_Interface::Update();
- UpdateInterrupts();
+ CoreTiming::ScheduleEvent_Threadsafe(0, updateInterrupts, 0);
}
-void UpdateInterrupts()
+void UpdateInterrupts(u64 userdata, int cyclesLate)
{
if ((ctrl.Y1 & ctrl.IY1) || (ctrl.Y2 & ctrl.IY2))
{
@@ -247,7 +252,7 @@ void GenerateAck(u32 _Address)
ctrl.Y2 = 1;
INFO_LOG(WII_IPC, "GenerateAck: %08x | %08x [R:%i A:%i E:%i]",
ppc_msg,_Address, ctrl.Y1, ctrl.Y2, ctrl.X1);
- UpdateInterrupts();
+ CoreTiming::ScheduleEvent_Threadsafe(0, updateInterrupts, 0);
}
void GenerateReply(u32 _Address)
diff --git a/Source/Core/Core/Src/HW/WII_IPC.h b/Source/Core/Core/Src/HW/WII_IPC.h
index cb79a4f700..3d4e416c42 100644
--- a/Source/Core/Core/Src/HW/WII_IPC.h
+++ b/Source/Core/Core/Src/HW/WII_IPC.h
@@ -52,7 +52,7 @@ void DoState(PointerWrap &p);
void Read32(u32& _rReturnValue, const u32 _Address);
void Write32(const u32 _Value, const u32 _Address);
-void UpdateInterrupts();
+void UpdateInterrupts(u64 userdata = 0, int cyclesLate = 0);
void GenerateAck(u32 _Address);
void GenerateReply(u32 _Address);
diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp
index 28263baa32..aa999c9a39 100644
--- a/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp
+++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp
@@ -72,7 +72,7 @@ void JitArmAsmRoutineManager::Generate()
MOVI2R(R14, (u32)jit->GetBlockCache()->GetICache());
// Confirmed That this loads the base iCache Location correctly 08-04-12
- LDR(R12, R14, R12, true, true); // R12 contains iCache[PC & JIT_ICACHE_MASK] here
+ LDR(R12, R14, R12); // R12 contains iCache[PC & JIT_ICACHE_MASK] here
// R12 Confirmed this is the correct iCache Location loaded.
TST(R12, 0xFC); // Test to see if it is a JIT block.
@@ -82,7 +82,7 @@ void JitArmAsmRoutineManager::Generate()
// LDR R14 right here to get CodePointers()[0] pointer.
REV(R12, R12); // Reversing this gives us our JITblock.
LSL(R12, R12, 2); // Multiply by four because address locations are u32 in size
- LDR(R14, R14, R12, true, true); // Load the block address in to R14
+ LDR(R14, R14, R12); // Load the block address in to R14
B(R14);
diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp
index 4b1fc820a9..e72b5db13d 100644
--- a/Source/Core/DolphinWX/Src/FrameTools.cpp
+++ b/Source/Core/DolphinWX/Src/FrameTools.cpp
@@ -74,6 +74,20 @@ Core::GetWindowHandle().
#include // wxWidgets
+#ifdef _WIN32
+#ifndef SM_YVIRTUALSCREEN
+#define SM_YVIRTUALSCREEN 77
+#endif
+#ifndef SM_XVIRTUALSCREEN
+#define SM_XVIRTUALSCREEN 76
+#endif
+#ifndef SM_CXVIRTUALSCREEN
+#define SM_CXVIRTUALSCREEN 78
+#endif
+#ifndef SM_CYVIRTUALSCREEN
+#define SM_CYVIRTUALSCREEN 79
+#endif
+#endif
// Resources
extern "C" {
@@ -861,14 +875,23 @@ void CFrame::StartGame(const std::string& filename)
position = wxDefaultPosition;
#endif
+ wxSize size(SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowWidth,
+ SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowHeight);
+#ifdef _WIN32
+ // Out of desktop check
+ int height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
+ int width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
+ int leftPos = GetSystemMetrics(SM_XVIRTUALSCREEN);
+ int topPos = GetSystemMetrics(SM_YVIRTUALSCREEN);
+ if ((leftPos + width) < (position.x + size.GetWidth()) || leftPos > position.x || (topPos + height) < (position.y + size.GetHeight()) || topPos > position.y)
+ position.x = position.y = wxDefaultCoord;
+#endif
m_RenderFrame = new CRenderFrame((wxFrame*)this, wxID_ANY, _("Dolphin"), position);
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bKeepWindowOnTop)
m_RenderFrame->SetWindowStyle(m_RenderFrame->GetWindowStyle() | wxSTAY_ON_TOP);
else
m_RenderFrame->SetWindowStyle(m_RenderFrame->GetWindowStyle() & ~wxSTAY_ON_TOP);
- wxSize size(SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowWidth,
- SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowHeight);
m_RenderFrame->SetClientSize(size.GetWidth(), size.GetHeight());
m_RenderFrame->Bind(wxEVT_CLOSE_WINDOW, &CFrame::OnRenderParentClose, this);
m_RenderFrame->Bind(wxEVT_ACTIVATE, &CFrame::OnActive, this);
diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp
index 0721f9ad4d..f765a7a8e0 100644
--- a/Source/Core/DolphinWX/Src/ISOProperties.cpp
+++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp
@@ -316,7 +316,7 @@ void CISOProperties::CreateGUIControls(bool IsWad)
DCBZOFF->SetToolTip(_("Bypass the clearing of the data cache by the DCBZ instruction. Usually leave this option disabled."));
VBeam = new wxCheckBox(m_GameConfig, ID_VBEAM, _("Accurate VBeam emulation"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
VBeam->SetToolTip(_("If the FPS is erratic, this option may help. (ON = Compatible, OFF = Fast)"));
- SyncGPU = new wxCheckBox(m_GameConfig, ID_SYNCGPU, _("Sychronise GPU thread"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
+ SyncGPU = new wxCheckBox(m_GameConfig, ID_SYNCGPU, _("Synchronise GPU thread"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
SyncGPU->SetToolTip(_("Synchonises the GPU and CPU threads to help prevent random freezes in Dual Core mode. (ON = Compatible, OFF = Fast)"));
FastDiscSpeed = new wxCheckBox(m_GameConfig, ID_DISCSPEED, _("Speed up Disc Transfer Rate"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
FastDiscSpeed->SetToolTip(_("Enable fast disc access. Needed for a few games. (ON = Fast, OFF = Compatible)"));
@@ -659,8 +659,8 @@ void CISOProperties::OnExtractFile(wxCommandEvent& WXUNUSED (event))
if (DiscIO::IsVolumeWiiDisc(OpenISO))
{
- int partitionNum = wxAtoi(File.SubString(10, 11));
- File.Remove(0, 12); // Remove "Partition x/"
+ int partitionNum = wxAtoi(File.Mid(File.find_first_of("/"), 1));
+ File.Remove(0, File.find_first_of("/") +1); // Remove "Partition x/"
WiiDisc.at(partitionNum).FileSystem->ExportFile(WxStrToStr(File).c_str(), WxStrToStr(Path).c_str());
}
else
@@ -794,8 +794,8 @@ void CISOProperties::OnExtractDir(wxCommandEvent& event)
if (DiscIO::IsVolumeWiiDisc(OpenISO))
{
- int partitionNum = wxAtoi(Directory.SubString(10, 11));
- Directory.Remove(0, 12); // Remove "Partition x/"
+ int partitionNum = wxAtoi(Directory.Mid(Directory.find_first_of("/"), 1));
+ Directory.Remove(0, Directory.find_first_of("/") +1); // Remove "Partition x/"
ExportDir(WxStrToStr(Directory).c_str(), WxStrToStr(Path).c_str(), partitionNum);
}
else
@@ -860,7 +860,7 @@ void CISOProperties::CheckPartitionIntegrity(wxCommandEvent& event)
return;
// Get the partition number from the item text ("Partition N")
- int PartitionNum = wxAtoi(PartitionName.SubString(10, 11));
+ int PartitionNum = wxAtoi(PartitionName.Mid(PartitionName.find_first_of("0123456789"), 1));
const WiiPartition& Partition = WiiDisc[PartitionNum];
wxProgressDialog* dialog = new wxProgressDialog(
diff --git a/Source/Core/DolphinWX/Src/Main.cpp b/Source/Core/DolphinWX/Src/Main.cpp
index d3fb3856ff..b42a299088 100644
--- a/Source/Core/DolphinWX/Src/Main.cpp
+++ b/Source/Core/DolphinWX/Src/Main.cpp
@@ -48,6 +48,20 @@
#ifdef _WIN32
#include
+
+#ifndef SM_YVIRTUALSCREEN
+#define SM_YVIRTUALSCREEN 77
+#endif
+#ifndef SM_XVIRTUALSCREEN
+#define SM_XVIRTUALSCREEN 76
+#endif
+#ifndef SM_CXVIRTUALSCREEN
+#define SM_CXVIRTUALSCREEN 78
+#endif
+#ifndef SM_CYVIRTUALSCREEN
+#define SM_CYVIRTUALSCREEN 79
+#endif
+
#endif
#ifdef __APPLE__
@@ -166,6 +180,11 @@ bool DolphinApp::OnInit()
"Low level (LLE) or high level (HLE) audio",
wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL
},
+ {
+ wxCMD_LINE_OPTION, "m", "movie",
+ "Play a movie file",
+ wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL
+ },
{
wxCMD_LINE_NONE, NULL, NULL, NULL, wxCMD_LINE_VAL_NONE, 0
}
@@ -186,6 +205,7 @@ bool DolphinApp::OnInit()
&videoBackendName);
selectAudioEmulation = parser.Found(wxT("audio_emulation"),
&audioEmulationName);
+ playMovie = parser.Found(wxT("movie"), &movieFile);
#endif // wxUSE_CMDLINE_PARSER
#if defined _DEBUG && defined _WIN32
@@ -303,10 +323,11 @@ bool DolphinApp::OnInit()
// do not allow windows to be created off the desktop.
#ifdef _WIN32
// Out of desktop check
- HWND hDesktop = GetDesktopWindow();
- RECT rc;
- GetWindowRect(hDesktop, &rc);
- if (rc.right < x + w || rc.bottom < y + h)
+ int height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
+ int width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
+ int leftPos = GetSystemMetrics(SM_XVIRTUALSCREEN);
+ int topPos = GetSystemMetrics(SM_YVIRTUALSCREEN);
+ if ((leftPos + width) < (x + w) || leftPos > x || (topPos + height) < (y + h) || topPos > y)
x = y = wxDefaultCoord;
#elif defined __APPLE__
if (y < 1)
@@ -346,8 +367,21 @@ void DolphinApp::AfterInit(wxTimerEvent& WXUNUSED(event))
if (!BatchMode)
main_frame->UpdateGameList();
+ if (playMovie && movieFile != wxEmptyString)
+ {
+ if (Movie::PlayInput(movieFile.char_str()))
+ {
+ if (LoadFile && FileToLoad != wxEmptyString)
+ {
+ main_frame->BootGame(WxStrToStr(FileToLoad));
+ }
+ else
+ main_frame->BootGame(std::string(""));
+ }
+ }
+
// First check if we have an exec command line.
- if (LoadFile && FileToLoad != wxEmptyString)
+ else if (LoadFile && FileToLoad != wxEmptyString)
{
main_frame->BootGame(WxStrToStr(FileToLoad));
}
@@ -357,17 +391,7 @@ void DolphinApp::AfterInit(wxTimerEvent& WXUNUSED(event))
{
if (main_frame->g_pCodeWindow->AutomaticStart())
{
- if(!SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDefaultGCM.empty()
- && File::Exists(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDefaultGCM))
- {
- main_frame->BootGame(SConfig::GetInstance().m_LocalCoreStartupParameter.
- m_strDefaultGCM);
- }
- else if(!SConfig::GetInstance().m_LastFilename.empty()
- && File::Exists(SConfig::GetInstance().m_LastFilename))
- {
- main_frame->BootGame(SConfig::GetInstance().m_LastFilename);
- }
+ main_frame->BootGame("");
}
}
}
diff --git a/Source/Core/DolphinWX/Src/Main.h b/Source/Core/DolphinWX/Src/Main.h
index 0fb99fcfd4..d043a6c24e 100644
--- a/Source/Core/DolphinWX/Src/Main.h
+++ b/Source/Core/DolphinWX/Src/Main.h
@@ -40,7 +40,9 @@ private:
wxTimer *m_afterinit;
bool BatchMode;
bool LoadFile;
+ bool playMovie;
wxString FileToLoad;
+ wxString movieFile;
wxLocale *m_locale;
void AfterInit(wxTimerEvent& WXUNUSED(event));
diff --git a/Source/Core/VideoCommon/Src/BPMemory.h b/Source/Core/VideoCommon/Src/BPMemory.h
index 0ee00f911e..4a97f04960 100644
--- a/Source/Core/VideoCommon/Src/BPMemory.h
+++ b/Source/Core/VideoCommon/Src/BPMemory.h
@@ -93,7 +93,7 @@
#define BPMEM_TEV_ALPHA_ENV 0xC1 // 0xC1 + (2 * 16)
#define BPMEM_TEV_REGISTER_L 0xE0 // 0xE0 + (2 * 4)
#define BPMEM_TEV_REGISTER_H 0xE1 // 0xE1 + (2 * 4)
-#define BPMEM_FOGRANGE 0xE8
+#define BPMEM_FOGRANGE 0xE8 // 0xE8 + 6
#define BPMEM_FOGPARAM0 0xEE
#define BPMEM_FOGBMAGNITUDE 0xEF
#define BPMEM_FOGBEXPONENT 0xF0
@@ -988,7 +988,7 @@ struct BPMemory
FourTexUnits tex[2]; //80-bf
TevStageCombiner combiners[16]; //0xC0-0xDF
TevReg tevregs[4]; //0xE0
- FogRangeParams fogRange;
+ FogRangeParams fogRange; // 0xE8
FogParams fog; //0xEE,0xEF,0xF0,0xF1,0xF2
AlphaTest alpha_test; //0xF3
ZTex1 ztex1; //0xf4,0xf5
diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp
index 93decf7ce3..7c2eb6fb9e 100644
--- a/Source/Core/VideoCommon/Src/Fifo.cpp
+++ b/Source/Core/VideoCommon/Src/Fifo.cpp
@@ -235,11 +235,11 @@ void RunGpu()
{
u8 *uData = Memory::GetPointer(fifo.CPReadPointer);
- FPURoundMode::SaveSIMDState();
- FPURoundMode::LoadDefaultSIMDState();
- ReadDataFromFifo(uData, 32);
- u32 count = OpcodeDecoder_Run(g_bSkipCurrentFrame);
- FPURoundMode::LoadSIMDState();
+ FPURoundMode::SaveSIMDState();
+ FPURoundMode::LoadDefaultSIMDState();
+ ReadDataFromFifo(uData, 32);
+ u32 count = OpcodeDecoder_Run(g_bSkipCurrentFrame);
+ FPURoundMode::LoadSIMDState();
//DEBUG_LOG(COMMANDPROCESSOR, "Fifo wraps to base");
diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp
index 7d7fcf1135..d9c09c441b 100644
--- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp
+++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp
@@ -276,7 +276,7 @@ void ValidatePixelShaderIDs(API_TYPE api, PIXELSHADERUIDSAFE old_id, const std::
static void WriteStage(char *&p, int n, API_TYPE ApiType);
static void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType);
// static void WriteAlphaCompare(char *&p, int num, int comp);
-static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool depthTextureEnable);
+static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth);
static void WriteFog(char *&p);
static const char *tevKSelTableC[] = // KCSEL
@@ -511,8 +511,8 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
BuildSwapModeTable(); // Needed for WriteStage
int numStages = bpmem.genMode.numtevstages + 1;
int numTexgen = bpmem.genMode.numtexgens;
-
- bool depthTextureEnable = bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable;
+
+ bool per_pixel_depth = bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable;
char *p = text;
WRITE(p, "//Pixel Shader for TEV stages\n");
@@ -602,7 +602,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND)
WRITE(p, "out float4 ocol1;\n");
- if (depthTextureEnable)
+ if (per_pixel_depth)
WRITE(p, "#define depth gl_FragDepth\n");
WRITE(p, "float4 rawpos = gl_FragCoord;\n");
@@ -658,14 +658,14 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
{
WRITE(p, " out float4 ocol0 : COLOR0,%s%s\n in float4 rawpos : %s,\n",
dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : COLOR1," : "",
- depthTextureEnable ? "\n out float depth : DEPTH," : "",
+ per_pixel_depth ? "\n out float depth : DEPTH," : "",
ApiType & API_D3D9_SM20 ? "POSITION" : "VPOS");
}
else
{
WRITE(p, " out float4 ocol0 : SV_Target0,%s%s\n in float4 rawpos : SV_Position,\n",
dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : SV_Target1," : "",
- depthTextureEnable ? "\n out float depth : SV_Depth," : "");
+ per_pixel_depth ? "\n out float depth : SV_Depth," : "");
}
WRITE(p, " in float4 colors_0 : COLOR0,\n");
@@ -808,7 +808,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
AlphaTest::TEST_RESULT Pretest = bpmem.alpha_test.TestResult();
if (Pretest == AlphaTest::UNDETERMINED)
- WriteAlphaTest(p, ApiType, dstAlphaMode, depthTextureEnable);
+ WriteAlphaTest(p, ApiType, dstAlphaMode, per_pixel_depth);
// the screen space depth value = far z + (clip z / clip w) * z range
@@ -817,9 +817,10 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
else
// dx9 doesn't support 4 component position, so we have to calculate it again
WRITE(p, "float zCoord = " I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * " I_ZBIAS"[1].y;\n");
-
- // Note: depth textures are disabled if early depth test is enabled
- if (depthTextureEnable)
+
+ // depth texture can safely be ignored if the result won't be written to the depth buffer (early_ztest) and isn't used for fog either
+ bool skip_ztexture = !per_pixel_depth && !bpmem.fog.c_proj_fsel.fsel;
+ if (bpmem.ztex2.op != ZTEXTURE_DISABLE && !skip_ztexture)
{
// use the texture input of the last texture stage (textemp), hopefully this has been read and is in correct format...
WRITE(p, "zCoord = dot(" I_ZBIAS"[0].xyzw, textemp.xyzw) + " I_ZBIAS"[1].w %s;\n",
@@ -829,8 +830,10 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
WRITE(p, "zCoord = zCoord * (16777215.0f/16777216.0f);\n");
WRITE(p, "zCoord = frac(zCoord);\n");
WRITE(p, "zCoord = zCoord * (16777216.0f/16777215.0f);\n");
-
- WRITE(p, "depth = zCoord;\n");
+
+ // Note: depth texture out put is only written to depth buffer if late depth test is used
+ if (per_pixel_depth)
+ WRITE(p, "depth = zCoord;\n");
}
if (dstAlphaMode == DSTALPHA_ALPHA_PASS)
@@ -1242,7 +1245,7 @@ static const char *tevAlphaFunclogicTable[] =
" == " // xnor
};
-static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool depthTextureEnable)
+static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth)
{
static const char *alphaRef[2] =
{
@@ -1266,7 +1269,7 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode
WRITE(p, "\t\tocol0 = float4(0.0f, 0.0f, 0.0f, 0.0f);\n");
if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND)
WRITE(p, "\t\tocol1 = float4(0.0f, 0.0f, 0.0f, 0.0f);\n");
- if(depthTextureEnable)
+ if(per_pixel_depth)
WRITE(p, "depth = 1.f;\n");
// HAXX: zcomploc (aka early_ztest) is a way to control whether depth test is done before
diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp
index f744f41ee1..1d048e14fd 100644
--- a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp
+++ b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp
@@ -415,6 +415,7 @@ void PixelShaderManager::SetZTextureBias(u32 bias)
void PixelShaderManager::SetViewportChanged()
{
s_bDepthRangeChanged = true;
+ s_bFogRangeAdjustChanged = true; // TODO: Shouldn't be necessary with an accurate fog range adjust implementation
}
void PixelShaderManager::SetIndTexScaleChanged(u8 stagemask)
diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.h b/Source/Core/VideoCommon/Src/VertexManagerBase.h
index 2690ffc03e..f44676cb32 100644
--- a/Source/Core/VideoCommon/Src/VertexManagerBase.h
+++ b/Source/Core/VideoCommon/Src/VertexManagerBase.h
@@ -2,6 +2,7 @@
#ifndef _VERTEXMANAGERBASE_H
#define _VERTEXMANAGERBASE_H
+#include "Common.h"
#include
class NativeVertexFormat;
@@ -10,17 +11,16 @@ class PointerWrap;
class VertexManager
{
private:
- // What are the actual values?
- static const u32 SMALLEST_POSSIBLE_VERTEX = 1;
- static const u32 LARGEST_POSSIBLE_VERTEX = 188;
+ static const u32 SMALLEST_POSSIBLE_VERTEX = sizeof(float)*3; // 3 pos
+ static const u32 LARGEST_POSSIBLE_VERTEX = sizeof(float)*45 + sizeof(u32)*2; // 3 pos, 3*3 normal, 2*u32 color, 8*4 tex, 1 posMat
static const u32 MAX_PRIMITIVES_PER_COMMAND = (u16)-1;
public:
- static const u32 MAXVBUFFERSIZE = MAX_PRIMITIVES_PER_COMMAND * LARGEST_POSSIBLE_VERTEX;
+ static const u32 MAXVBUFFERSIZE = ROUND_UP_POW2 (MAX_PRIMITIVES_PER_COMMAND * LARGEST_POSSIBLE_VERTEX);
// We may convert triangle-fans to triangle-lists, almost 3x as many indices.
- static const u32 MAXIBUFFERSIZE = MAX_PRIMITIVES_PER_COMMAND * 3;
+ static const u32 MAXIBUFFERSIZE = ROUND_UP_POW2 (MAX_PRIMITIVES_PER_COMMAND * 3);
VertexManager();
// needs to be virtual for DX11's dtor
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp
index aa6ddf3b11..3751ba9fa1 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp
+++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp
@@ -39,9 +39,9 @@ namespace DX11
{
// TODO: Find sensible values for these two
-const UINT IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16 * sizeof(u16);
-const UINT VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16;
-const UINT MAX_VBUFFER_COUNT = 2;
+const UINT IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * sizeof(u16) * 8;
+const UINT VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE;
+const UINT MAXVBUFFER_COUNT = 2;
void VertexManager::CreateDeviceObjects()
{
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp
index 6d9586e8cf..7b44a1a591 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp
@@ -42,9 +42,9 @@ extern NativeVertexFormat *g_nativeVertexFmt;
namespace DX9
{
//This are the initially requeted size for the buffers expresed in elements
-const u32 IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16;
-const u32 VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16;
-const u32 MAX_VBUFFER_COUNT = 2;
+const u32 IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * sizeof(u16) * 8;
+const u32 VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE;
+const u32 MAXVBUFFER_COUNT = 2;
inline void DumpBadShaders()
{
diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/EfbInterface.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/EfbInterface.cpp
index 8fdc0425a4..77d87988c8 100644
--- a/Source/Plugins/Plugin_VideoSoftware/Src/EfbInterface.cpp
+++ b/Source/Plugins/Plugin_VideoSoftware/Src/EfbInterface.cpp
@@ -461,10 +461,11 @@ namespace EfbInterface
SetPixelAlphaOnly(offset, color[ALP_C]);
}
- void SetDepth(u16 x, u16 y, u32 depth)
- {
- SetPixelDepth(GetDepthOffset(x, y), depth);
- }
+ void SetDepth(u16 x, u16 y, u32 depth)
+ {
+ if (bpmem.zmode.updateenable)
+ SetPixelDepth(GetDepthOffset(x, y), depth);
+ }
void GetColor(u16 x, u16 y, u8 *color)
{