mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-02 22:29:21 +00:00
Merge branch 'master' of https://github.com/MarioPartyNetplay/Dolphin-MPN
This commit is contained in:
commit
512e9e3fbc
27 changed files with 488 additions and 307 deletions
24
CMake/DolphinInjectVersionInfo.cmake
Normal file
24
CMake/DolphinInjectVersionInfo.cmake
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
function(dolphin_inject_version_info target)
|
||||||
|
set(INFO_PLIST_PATH "$<TARGET_BUNDLE_DIR:${target}>/Contents/Info.plist")
|
||||||
|
add_custom_command(TARGET ${target}
|
||||||
|
POST_BUILD
|
||||||
|
|
||||||
|
COMMAND /usr/libexec/PlistBuddy -c
|
||||||
|
"Delete :CFBundleShortVersionString"
|
||||||
|
"${INFO_PLIST_PATH}"
|
||||||
|
|| true
|
||||||
|
|
||||||
|
COMMAND /usr/libexec/PlistBuddy -c
|
||||||
|
"Delete :CFBundleLongVersionString"
|
||||||
|
"${INFO_PLIST_PATH}"
|
||||||
|
|| true
|
||||||
|
|
||||||
|
COMMAND /usr/libexec/PlistBuddy -c
|
||||||
|
"Delete :CFBundleVersion"
|
||||||
|
"${INFO_PLIST_PATH}"
|
||||||
|
|| true
|
||||||
|
|
||||||
|
COMMAND /usr/libexec/PlistBuddy -c
|
||||||
|
"Merge '${CMAKE_BINARY_DIR}/Source/Core/VersionInfo.plist'"
|
||||||
|
"${INFO_PLIST_PATH}")
|
||||||
|
endfunction()
|
|
@ -65,6 +65,5 @@ endfunction()
|
||||||
configure_source_file("Source/Core/Common/scmrev.h")
|
configure_source_file("Source/Core/Common/scmrev.h")
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
configure_source_file("Source/Core/DolphinQt/Info.plist")
|
configure_source_file("Source/Core/VersionInfo.plist")
|
||||||
configure_source_file("Source/Core/MacUpdater/Info.plist")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -783,14 +783,9 @@ if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/Source/Core/Common/scmrev.h)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Source/Core/DolphinQt)
|
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Source/Core)
|
||||||
if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/Source/Core/DolphinQt/Info.plist)
|
if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/Source/Core/VersionInfo.plist)
|
||||||
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/Source/Core/DolphinQt/Info.plist)
|
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/Source/Core/VersionInfo.plist)
|
||||||
endif()
|
|
||||||
|
|
||||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Source/Core/MacUpdater)
|
|
||||||
if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/Source/Core/MacUpdater/Info.plist)
|
|
||||||
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/Source/Core/MacUpdater/Info.plist)
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -239,9 +239,9 @@ C20C5B48 00000001
|
||||||
3A000000 00000000
|
3A000000 00000000
|
||||||
C20C2708 00000001
|
C20C2708 00000001
|
||||||
38600000 00000000
|
38600000 00000000
|
||||||
C20A9E08 00000004
|
C20A9E08 00000005
|
||||||
3C60817F 6063FFFC
|
3C60817F 6063FFFC
|
||||||
80830000 2C040001
|
A0830000 2C040001
|
||||||
41820008 1FDE0003
|
41820008 1FDE0003
|
||||||
3C800000 90830000
|
3C800000 90830000
|
||||||
60000000 00000000
|
60000000 00000000
|
||||||
|
@ -949,7 +949,7 @@ B09C002E 3B7B0002
|
||||||
83810010 83A10014
|
83810010 83A10014
|
||||||
83C10018 83E1001C
|
83C10018 83E1001C
|
||||||
38210010 00000000
|
38210010 00000000
|
||||||
C204BF38 00000008
|
C20A85F8 00000008
|
||||||
3FA08024 63BDD5F8
|
3FA08024 63BDD5F8
|
||||||
3C600001 60630025
|
3C600001 60630025
|
||||||
A8AD8BA8 2C050000
|
A8AD8BA8 2C050000
|
||||||
|
|
|
@ -1462,25 +1462,28 @@ $Minigame Deletion - Cash Flow [Tabitha]
|
||||||
002305A4 000000FF
|
002305A4 000000FF
|
||||||
00230CD4 000000FF
|
00230CD4 000000FF
|
||||||
|
|
||||||
$Minigame Deletion - Cashapult ➜ Jump The Gun [Tabitha]
|
$Minigame Deletion - Cashapult [Tabitha]
|
||||||
00231316 000000FF
|
00231316 000000FF
|
||||||
|
|
||||||
$Minigame Deletion - Money Belts ➜ Throw Me a Bone [Tabitha]
|
$Minigame Deletion - Money Belts [Tabitha]
|
||||||
00230966 000000FF
|
00230966 000000FF
|
||||||
|
|
||||||
$Minigame Deletion - Pitifall ➜ Cog Jog [Tabitha]
|
$Minigame Deletion - Pitifall [Tabitha]
|
||||||
00231962 000000FF
|
00231962 000000FF
|
||||||
|
|
||||||
$Minigame Deletion - Trap Ease Artist ➜ What Goes Up... [Tabitha]
|
$Minigame Deletion - Pop Star [Tabitha]
|
||||||
|
00230CCA 000000FF
|
||||||
|
|
||||||
|
$Minigame Deletion - Trap Ease Artist [Tabitha]
|
||||||
0023086E 000000FF
|
0023086E 000000FF
|
||||||
|
|
||||||
$Minigame Deletion - Trick or Tree ➜ Boo'd Off the Stage [Tabitha]
|
$Minigame Deletion - Trick or Tree [Tabitha]
|
||||||
00231CC6 000000FF
|
00231CC6 000000FF
|
||||||
|
|
||||||
$Minigame Deletion - Tricky Tires ➜ Cannonball Fun [Tabitha]
|
$Minigame Deletion - Tricky Tires [Tabitha]
|
||||||
00230396 000000FF
|
00230396 000000FF
|
||||||
|
|
||||||
$Minigame Deletion - Wrasslin' Rapids ➜ Hyper Sniper [Tabitha]
|
$Minigame Deletion - Wrasslin' Rapids [Tabitha]
|
||||||
00231DBE 000000FF
|
00231DBE 000000FF
|
||||||
|
|
||||||
$Orbs - Disable ALL Orbs [gamemasterplc]
|
$Orbs - Disable ALL Orbs [gamemasterplc]
|
||||||
|
|
|
@ -1459,28 +1459,28 @@ $Minigame - Vine Country - DK is Faster [gamemasterplc]
|
||||||
044E5EE4 3803FFFE
|
044E5EE4 3803FFFE
|
||||||
E2000001 80008000
|
E2000001 80008000
|
||||||
|
|
||||||
$Minigame Deletion - Bridge Work ➜ Mad Props
|
$Minigame Deletion - Bridge Works [Tabitha]
|
||||||
0025B722 000000FF
|
0025B722 000000FF
|
||||||
|
|
||||||
$Minigame Deletion - Cointagious ➜ Take Me Ohm
|
$Minigame Deletion - Cointagious [Tabitha]
|
||||||
00259FE2 000000FF
|
00259FE2 000000FF
|
||||||
|
|
||||||
$Minigame Deletion - Fish & Cheeps ➜ Weight for It
|
$Minigame Deletion - Fish & Cheeps [Tabitha]
|
||||||
0025BB02 000000FF
|
0025BB02 000000FF
|
||||||
|
|
||||||
$Minigame Deletion - Flashfright ➜ Think Tank
|
$Minigame Deletion - Flashfright [Tabitha]
|
||||||
0025AA0E 000000FF
|
0025AA0E 000000FF
|
||||||
|
|
||||||
$Minigame Deletion - Gimme a Sign ➜ Royal Rumpus
|
$Minigame Deletion - Gimme a Sign [Tabitha]
|
||||||
0025B6A6 000000FF
|
0025B6A6 000000FF
|
||||||
|
|
||||||
$Minigame Deletion - Light Speed ➜ Camp Ukiki
|
$Minigame Deletion - Light Speed [Tabitha]
|
||||||
0025BA0A 000000FF
|
0025BA0A 000000FF
|
||||||
|
|
||||||
$Minigame Deletion - Spin Doctor ➜ Hip Hop Drop
|
$Minigame Deletion - Spin Doctor [Tabitha]
|
||||||
0025B79E 000000FF
|
0025B79E 000000FF
|
||||||
|
|
||||||
$Minigame Deletion - Warp Pipe Dreams ➜ Apes of Wrath
|
$Minigame Deletion - Warp Pipe Dreams [Tabitha]
|
||||||
0025B3BE 000000FF
|
0025B3BE 000000FF
|
||||||
|
|
||||||
$Music - Disables Music [Ralf]
|
$Music - Disables Music [Ralf]
|
||||||
|
|
|
@ -209,6 +209,9 @@ $QOL - Increased Text Display [Tabitha]
|
||||||
$QOL - Invert IR Stick for GameCube Mod [gamemasterplc]
|
$QOL - Invert IR Stick for GameCube Mod [gamemasterplc]
|
||||||
04106A24 83DE6404
|
04106A24 83DE6404
|
||||||
04106A28 60000000
|
04106A28 60000000
|
||||||
|
04106AA4 C0428004
|
||||||
|
04106A74 C04282F0
|
||||||
|
|
||||||
|
|
||||||
$QOL - Remove Explanations [Rain]
|
$QOL - Remove Explanations [Rain]
|
||||||
82200001 80228760
|
82200001 80228760
|
||||||
|
|
|
@ -64,7 +64,7 @@ const Info<bool> GFX_CACHE_HIRES_TEXTURES{{System::GFX, "Settings", "CacheHiresT
|
||||||
const Info<bool> GFX_DUMP_EFB_TARGET{{System::GFX, "Settings", "DumpEFBTarget"}, false};
|
const Info<bool> GFX_DUMP_EFB_TARGET{{System::GFX, "Settings", "DumpEFBTarget"}, false};
|
||||||
const Info<bool> GFX_DUMP_XFB_TARGET{{System::GFX, "Settings", "DumpXFBTarget"}, false};
|
const Info<bool> GFX_DUMP_XFB_TARGET{{System::GFX, "Settings", "DumpXFBTarget"}, false};
|
||||||
const Info<bool> GFX_DUMP_FRAMES_AS_IMAGES{{System::GFX, "Settings", "DumpFramesAsImages"}, false};
|
const Info<bool> GFX_DUMP_FRAMES_AS_IMAGES{{System::GFX, "Settings", "DumpFramesAsImages"}, false};
|
||||||
const Info<bool> GFX_USE_FFV1{{System::GFX, "Settings", "UseFFV1"}, false};
|
const Info<bool> GFX_USE_LOSSLESS{{System::GFX, "Settings", "UseLossless"}, false};
|
||||||
const Info<std::string> GFX_DUMP_FORMAT{{System::GFX, "Settings", "DumpFormat"}, "avi"};
|
const Info<std::string> GFX_DUMP_FORMAT{{System::GFX, "Settings", "DumpFormat"}, "avi"};
|
||||||
const Info<std::string> GFX_DUMP_CODEC{{System::GFX, "Settings", "DumpCodec"}, ""};
|
const Info<std::string> GFX_DUMP_CODEC{{System::GFX, "Settings", "DumpCodec"}, ""};
|
||||||
const Info<std::string> GFX_DUMP_PIXEL_FORMAT{{System::GFX, "Settings", "DumpPixelFormat"}, ""};
|
const Info<std::string> GFX_DUMP_PIXEL_FORMAT{{System::GFX, "Settings", "DumpPixelFormat"}, ""};
|
||||||
|
|
|
@ -63,7 +63,7 @@ extern const Info<bool> GFX_CACHE_HIRES_TEXTURES;
|
||||||
extern const Info<bool> GFX_DUMP_EFB_TARGET;
|
extern const Info<bool> GFX_DUMP_EFB_TARGET;
|
||||||
extern const Info<bool> GFX_DUMP_XFB_TARGET;
|
extern const Info<bool> GFX_DUMP_XFB_TARGET;
|
||||||
extern const Info<bool> GFX_DUMP_FRAMES_AS_IMAGES;
|
extern const Info<bool> GFX_DUMP_FRAMES_AS_IMAGES;
|
||||||
extern const Info<bool> GFX_USE_FFV1;
|
extern const Info<bool> GFX_USE_LOSSLESS;
|
||||||
extern const Info<std::string> GFX_DUMP_FORMAT;
|
extern const Info<std::string> GFX_DUMP_FORMAT;
|
||||||
extern const Info<std::string> GFX_DUMP_CODEC;
|
extern const Info<std::string> GFX_DUMP_CODEC;
|
||||||
extern const Info<std::string> GFX_DUMP_PIXEL_FORMAT;
|
extern const Info<std::string> GFX_DUMP_PIXEL_FORMAT;
|
||||||
|
|
|
@ -41,6 +41,7 @@ static void LoadFromDTM(Config::Layer* config_layer, Movie::DTMHeader* dtm)
|
||||||
else
|
else
|
||||||
config_layer->Set(Config::MAIN_GC_LANGUAGE, static_cast<int>(dtm->language));
|
config_layer->Set(Config::MAIN_GC_LANGUAGE, static_cast<int>(dtm->language));
|
||||||
config_layer->Set(Config::SYSCONF_WIDESCREEN, dtm->bWidescreen);
|
config_layer->Set(Config::SYSCONF_WIDESCREEN, dtm->bWidescreen);
|
||||||
|
config_layer->Set(Config::SYSCONF_COUNTRY, dtm->countryCode);
|
||||||
|
|
||||||
config_layer->Set(Config::GFX_HACK_EFB_ACCESS_ENABLE, dtm->bEFBAccessEnable);
|
config_layer->Set(Config::GFX_HACK_EFB_ACCESS_ENABLE, dtm->bEFBAccessEnable);
|
||||||
config_layer->Set(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM, dtm->bSkipEFBCopyToRam);
|
config_layer->Set(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM, dtm->bSkipEFBCopyToRam);
|
||||||
|
@ -69,6 +70,7 @@ void SaveToDTM(Movie::DTMHeader* dtm)
|
||||||
else
|
else
|
||||||
dtm->language = Config::Get(Config::MAIN_GC_LANGUAGE);
|
dtm->language = Config::Get(Config::MAIN_GC_LANGUAGE);
|
||||||
dtm->bWidescreen = Config::Get(Config::SYSCONF_WIDESCREEN);
|
dtm->bWidescreen = Config::Get(Config::SYSCONF_WIDESCREEN);
|
||||||
|
dtm->countryCode = Config::Get(Config::SYSCONF_COUNTRY);
|
||||||
|
|
||||||
dtm->bEFBAccessEnable = Config::Get(Config::GFX_HACK_EFB_ACCESS_ENABLE);
|
dtm->bEFBAccessEnable = Config::Get(Config::GFX_HACK_EFB_ACCESS_ENABLE);
|
||||||
dtm->bSkipEFBCopyToRam = Config::Get(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM);
|
dtm->bSkipEFBCopyToRam = Config::Get(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM);
|
||||||
|
|
|
@ -132,7 +132,8 @@ struct DTMHeader
|
||||||
bool bUseFMA;
|
bool bUseFMA;
|
||||||
u8 GBAControllers; // GBA Controllers plugged in (the bits are ports 1-4)
|
u8 GBAControllers; // GBA Controllers plugged in (the bits are ports 1-4)
|
||||||
bool bWidescreen; // true indicates SYSCONF aspect ratio is 16:9, false for 4:3
|
bool bWidescreen; // true indicates SYSCONF aspect ratio is 16:9, false for 4:3
|
||||||
std::array<u8, 6> reserved; // Padding for any new config options
|
u8 countryCode; // SYSCONF country code
|
||||||
|
std::array<u8, 5> reserved; // Padding for any new config options
|
||||||
std::array<char, 40> discChange; // Name of iso file to switch to, for two disc games.
|
std::array<char, 40> discChange; // Name of iso file to switch to, for two disc games.
|
||||||
std::array<u8, 20> revision; // Git hash
|
std::array<u8, 20> revision; // Git hash
|
||||||
u32 DSPiromHash;
|
u32 DSPiromHash;
|
||||||
|
|
|
@ -355,8 +355,13 @@ protected:
|
||||||
Arm64Gen::ARM64Reg exit_address_after_return_reg = Arm64Gen::ARM64Reg::INVALID_REG);
|
Arm64Gen::ARM64Reg exit_address_after_return_reg = Arm64Gen::ARM64Reg::INVALID_REG);
|
||||||
void WriteBLRExit(Arm64Gen::ARM64Reg dest);
|
void WriteBLRExit(Arm64Gen::ARM64Reg dest);
|
||||||
|
|
||||||
Arm64Gen::FixupBranch JumpIfCRFieldBit(int field, int bit, bool jump_if_set);
|
void GetCRFieldBit(int field, int bit, Arm64Gen::ARM64Reg out);
|
||||||
|
void SetCRFieldBit(int field, int bit, Arm64Gen::ARM64Reg in, bool negate = false);
|
||||||
|
void ClearCRFieldBit(int field, int bit);
|
||||||
|
void SetCRFieldBit(int field, int bit);
|
||||||
void FixGTBeforeSettingCRFieldBit(Arm64Gen::ARM64Reg reg);
|
void FixGTBeforeSettingCRFieldBit(Arm64Gen::ARM64Reg reg);
|
||||||
|
Arm64Gen::FixupBranch JumpIfCRFieldBit(int field, int bit, bool jump_if_set);
|
||||||
|
|
||||||
void UpdateFPExceptionSummary(Arm64Gen::ARM64Reg fpscr);
|
void UpdateFPExceptionSummary(Arm64Gen::ARM64Reg fpscr);
|
||||||
void UpdateRoundingMode();
|
void UpdateRoundingMode();
|
||||||
|
|
||||||
|
|
|
@ -1128,47 +1128,85 @@ void JitArm64::addzex(UGeckoInstruction inst)
|
||||||
|
|
||||||
int a = inst.RA, d = inst.RD;
|
int a = inst.RA, d = inst.RD;
|
||||||
|
|
||||||
switch (js.carryFlag)
|
if (gpr.IsImm(a) && (gpr.GetImm(a) == 0 || HasConstantCarry()))
|
||||||
{
|
{
|
||||||
case CarryFlag::InPPCState:
|
const u32 imm = gpr.GetImm(a);
|
||||||
{
|
const bool is_all_ones = imm == 0xFFFFFFFF;
|
||||||
const bool allocate_reg = d == a;
|
|
||||||
gpr.BindToRegister(d, allocate_reg);
|
|
||||||
|
|
||||||
|
switch (js.carryFlag)
|
||||||
{
|
{
|
||||||
auto WA = allocate_reg ? gpr.GetScopedReg() : Arm64GPRCache::ScopedARM64Reg(gpr.R(d));
|
case CarryFlag::InPPCState:
|
||||||
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
|
|
||||||
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), WA);
|
|
||||||
}
|
|
||||||
|
|
||||||
ComputeCarry();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CarryFlag::InHostCarry:
|
|
||||||
{
|
|
||||||
gpr.BindToRegister(d, d == a);
|
|
||||||
CARRY_IF_NEEDED(ADC, ADCS, gpr.R(d), gpr.R(a), ARM64Reg::WZR);
|
|
||||||
ComputeCarry();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CarryFlag::ConstantTrue:
|
|
||||||
{
|
|
||||||
gpr.BindToRegister(d, d == a);
|
|
||||||
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), 1);
|
|
||||||
ComputeCarry();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CarryFlag::ConstantFalse:
|
|
||||||
{
|
|
||||||
if (d != a)
|
|
||||||
{
|
{
|
||||||
gpr.BindToRegister(d, false);
|
gpr.BindToRegister(d, false);
|
||||||
MOV(gpr.R(d), gpr.R(a));
|
LDRB(IndexType::Unsigned, gpr.R(d), PPC_REG, PPCSTATE_OFF(xer_ca));
|
||||||
|
ComputeCarry(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CarryFlag::InHostCarry:
|
||||||
|
{
|
||||||
|
gpr.BindToRegister(d, false);
|
||||||
|
CSET(gpr.R(d), CCFlags::CC_CS);
|
||||||
|
ComputeCarry(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CarryFlag::ConstantTrue:
|
||||||
|
{
|
||||||
|
gpr.SetImmediate(d, imm + 1);
|
||||||
|
ComputeCarry(is_all_ones);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CarryFlag::ConstantFalse:
|
||||||
|
{
|
||||||
|
gpr.SetImmediate(d, imm);
|
||||||
|
ComputeCarry(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ComputeCarry(false);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (js.carryFlag)
|
||||||
|
{
|
||||||
|
case CarryFlag::InPPCState:
|
||||||
|
{
|
||||||
|
const bool allocate_reg = d == a;
|
||||||
|
gpr.BindToRegister(d, allocate_reg);
|
||||||
|
|
||||||
|
{
|
||||||
|
auto WA = allocate_reg ? gpr.GetScopedReg() : Arm64GPRCache::ScopedARM64Reg(gpr.R(d));
|
||||||
|
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
|
||||||
|
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), WA);
|
||||||
|
}
|
||||||
|
|
||||||
|
ComputeCarry();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CarryFlag::InHostCarry:
|
||||||
|
{
|
||||||
|
gpr.BindToRegister(d, d == a);
|
||||||
|
CARRY_IF_NEEDED(ADC, ADCS, gpr.R(d), gpr.R(a), ARM64Reg::WZR);
|
||||||
|
ComputeCarry();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CarryFlag::ConstantTrue:
|
||||||
|
{
|
||||||
|
gpr.BindToRegister(d, d == a);
|
||||||
|
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), 1);
|
||||||
|
ComputeCarry();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CarryFlag::ConstantFalse:
|
||||||
|
{
|
||||||
|
if (d != a)
|
||||||
|
{
|
||||||
|
gpr.BindToRegister(d, false);
|
||||||
|
MOV(gpr.R(d), gpr.R(a));
|
||||||
|
}
|
||||||
|
|
||||||
|
ComputeCarry(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
|
@ -1216,40 +1254,62 @@ void JitArm64::subfex(UGeckoInstruction inst)
|
||||||
|
|
||||||
if (gpr.IsImm(a) && (mex || gpr.IsImm(b)))
|
if (gpr.IsImm(a) && (mex || gpr.IsImm(b)))
|
||||||
{
|
{
|
||||||
u32 i = gpr.GetImm(a), j = mex ? -1 : gpr.GetImm(b);
|
const u32 i = gpr.GetImm(a);
|
||||||
|
const u32 j = mex ? -1 : gpr.GetImm(b);
|
||||||
gpr.BindToRegister(d, false);
|
const u32 imm = ~i + j;
|
||||||
|
const bool is_zero = imm == 0;
|
||||||
|
const bool is_all_ones = imm == 0xFFFFFFFF;
|
||||||
|
|
||||||
switch (js.carryFlag)
|
switch (js.carryFlag)
|
||||||
{
|
{
|
||||||
case CarryFlag::InPPCState:
|
case CarryFlag::InPPCState:
|
||||||
{
|
{
|
||||||
auto WA = gpr.GetScopedReg();
|
gpr.BindToRegister(d, false);
|
||||||
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
|
ARM64Reg RD = gpr.R(d);
|
||||||
ADDI2R(gpr.R(d), WA, ~i + j, gpr.R(d));
|
if (is_zero)
|
||||||
|
{
|
||||||
|
LDRB(IndexType::Unsigned, RD, PPC_REG, PPCSTATE_OFF(xer_ca));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto WA = gpr.GetScopedReg();
|
||||||
|
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
|
||||||
|
ADDI2R(RD, WA, imm, RD);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CarryFlag::InHostCarry:
|
case CarryFlag::InHostCarry:
|
||||||
{
|
{
|
||||||
auto WA = gpr.GetScopedReg();
|
gpr.BindToRegister(d, false);
|
||||||
MOVI2R(WA, ~i + j);
|
ARM64Reg RD = gpr.R(d);
|
||||||
ADC(gpr.R(d), WA, ARM64Reg::WZR);
|
if (is_all_ones)
|
||||||
|
{
|
||||||
|
// RD = -1 + carry = carry ? 0 : -1
|
||||||
|
// CSETM sets the destination to -1 if the condition is true, 0
|
||||||
|
// otherwise. Hence, the condition must be carry clear.
|
||||||
|
CSETM(RD, CC_CC);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MOVI2R(RD, imm);
|
||||||
|
ADC(RD, RD, ARM64Reg::WZR);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CarryFlag::ConstantTrue:
|
case CarryFlag::ConstantTrue:
|
||||||
{
|
{
|
||||||
gpr.SetImmediate(d, ~i + j + 1);
|
gpr.SetImmediate(d, imm + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CarryFlag::ConstantFalse:
|
case CarryFlag::ConstantFalse:
|
||||||
{
|
{
|
||||||
gpr.SetImmediate(d, ~i + j);
|
gpr.SetImmediate(d, imm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool must_have_carry = Interpreter::Helper_Carry(~i, j);
|
const bool must_have_carry = Interpreter::Helper_Carry(~i, j);
|
||||||
const bool might_have_carry = (~i + j) == 0xFFFFFFFF;
|
const bool might_have_carry = is_all_ones;
|
||||||
|
|
||||||
if (must_have_carry)
|
if (must_have_carry)
|
||||||
{
|
{
|
||||||
|
@ -1337,39 +1397,49 @@ void JitArm64::subfzex(UGeckoInstruction inst)
|
||||||
|
|
||||||
int a = inst.RA, d = inst.RD;
|
int a = inst.RA, d = inst.RD;
|
||||||
|
|
||||||
gpr.BindToRegister(d, d == a);
|
if (gpr.IsImm(a) && HasConstantCarry())
|
||||||
|
{
|
||||||
|
const u32 imm = ~gpr.GetImm(a);
|
||||||
|
const u32 carry = js.carryFlag == CarryFlag::ConstantTrue;
|
||||||
|
gpr.SetImmediate(d, imm + carry);
|
||||||
|
ComputeCarry(Interpreter::Helper_Carry(imm, carry));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gpr.BindToRegister(d, d == a);
|
||||||
|
|
||||||
switch (js.carryFlag)
|
switch (js.carryFlag)
|
||||||
{
|
|
||||||
case CarryFlag::InPPCState:
|
|
||||||
{
|
|
||||||
{
|
{
|
||||||
auto WA = gpr.GetScopedReg();
|
case CarryFlag::InPPCState:
|
||||||
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
|
{
|
||||||
MVN(gpr.R(d), gpr.R(a));
|
{
|
||||||
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(d), WA);
|
auto WA = gpr.GetScopedReg();
|
||||||
|
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
|
||||||
|
MVN(gpr.R(d), gpr.R(a));
|
||||||
|
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(d), WA);
|
||||||
|
}
|
||||||
|
ComputeCarry();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CarryFlag::InHostCarry:
|
||||||
|
{
|
||||||
|
CARRY_IF_NEEDED(SBC, SBCS, gpr.R(d), ARM64Reg::WZR, gpr.R(a));
|
||||||
|
ComputeCarry();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CarryFlag::ConstantTrue:
|
||||||
|
{
|
||||||
|
CARRY_IF_NEEDED(NEG, NEGS, gpr.R(d), gpr.R(a));
|
||||||
|
ComputeCarry();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CarryFlag::ConstantFalse:
|
||||||
|
{
|
||||||
|
MVN(gpr.R(d), gpr.R(a));
|
||||||
|
ComputeCarry(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ComputeCarry();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CarryFlag::InHostCarry:
|
|
||||||
{
|
|
||||||
CARRY_IF_NEEDED(SBC, SBCS, gpr.R(d), ARM64Reg::WZR, gpr.R(a));
|
|
||||||
ComputeCarry();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CarryFlag::ConstantTrue:
|
|
||||||
{
|
|
||||||
CARRY_IF_NEEDED(NEG, NEGS, gpr.R(d), gpr.R(a));
|
|
||||||
ComputeCarry();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CarryFlag::ConstantFalse:
|
|
||||||
{
|
|
||||||
MVN(gpr.R(d), gpr.R(a));
|
|
||||||
ComputeCarry(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
|
@ -1436,40 +1506,66 @@ void JitArm64::addex(UGeckoInstruction inst)
|
||||||
|
|
||||||
if (gpr.IsImm(a) && (mex || gpr.IsImm(b)))
|
if (gpr.IsImm(a) && (mex || gpr.IsImm(b)))
|
||||||
{
|
{
|
||||||
u32 i = gpr.GetImm(a), j = mex ? -1 : gpr.GetImm(b);
|
const u32 i = gpr.GetImm(a), j = mex ? -1 : gpr.GetImm(b);
|
||||||
|
const u32 imm = i + j;
|
||||||
gpr.BindToRegister(d, false);
|
const bool is_zero = imm == 0;
|
||||||
|
const bool is_all_ones = imm == 0xFFFFFFFF;
|
||||||
|
|
||||||
switch (js.carryFlag)
|
switch (js.carryFlag)
|
||||||
{
|
{
|
||||||
case CarryFlag::InPPCState:
|
case CarryFlag::InPPCState:
|
||||||
{
|
{
|
||||||
auto WA = gpr.GetScopedReg();
|
gpr.BindToRegister(d, false);
|
||||||
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
|
ARM64Reg RD = gpr.R(d);
|
||||||
ADDI2R(gpr.R(d), WA, i + j, gpr.R(d));
|
if (is_zero)
|
||||||
|
{
|
||||||
|
LDRB(IndexType::Unsigned, RD, PPC_REG, PPCSTATE_OFF(xer_ca));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto WA = gpr.GetScopedReg();
|
||||||
|
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
|
||||||
|
ADDI2R(RD, WA, imm, RD);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CarryFlag::InHostCarry:
|
case CarryFlag::InHostCarry:
|
||||||
{
|
{
|
||||||
|
gpr.BindToRegister(d, false);
|
||||||
ARM64Reg RD = gpr.R(d);
|
ARM64Reg RD = gpr.R(d);
|
||||||
MOVI2R(RD, i + j);
|
if (is_zero)
|
||||||
ADC(RD, RD, ARM64Reg::WZR);
|
{
|
||||||
|
// RD = 0 + carry = carry ? 1 : 0
|
||||||
|
CSET(RD, CC_CS);
|
||||||
|
}
|
||||||
|
else if (is_all_ones)
|
||||||
|
{
|
||||||
|
// RD = -1 + carry = carry ? 0 : -1
|
||||||
|
// Note that CSETM sets the destination to -1 if the condition is true,
|
||||||
|
// and 0 otherwise. Hence, the condition must be carry clear.
|
||||||
|
CSETM(RD, CC_CC);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MOVI2R(RD, imm);
|
||||||
|
ADC(RD, RD, ARM64Reg::WZR);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CarryFlag::ConstantTrue:
|
case CarryFlag::ConstantTrue:
|
||||||
{
|
{
|
||||||
gpr.SetImmediate(d, i + j + 1);
|
gpr.SetImmediate(d, imm + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CarryFlag::ConstantFalse:
|
case CarryFlag::ConstantFalse:
|
||||||
{
|
{
|
||||||
gpr.SetImmediate(d, i + j);
|
gpr.SetImmediate(d, imm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool must_have_carry = Interpreter::Helper_Carry(i, j);
|
const bool must_have_carry = Interpreter::Helper_Carry(i, j);
|
||||||
const bool might_have_carry = (i + j) == 0xFFFFFFFF;
|
const bool might_have_carry = is_all_ones;
|
||||||
|
|
||||||
if (must_have_carry)
|
if (must_have_carry)
|
||||||
{
|
{
|
||||||
|
|
|
@ -817,9 +817,8 @@ void JitArm64::dcbx(UGeckoInstruction inst)
|
||||||
STR(IndexType::Unsigned, loop_counter, PPC_REG, PPCSTATE_OFF_SPR(SPR_CTR));
|
STR(IndexType::Unsigned, loop_counter, PPC_REG, PPCSTATE_OFF_SPR(SPR_CTR));
|
||||||
|
|
||||||
// downcount -= (WA * reg_cycle_count)
|
// downcount -= (WA * reg_cycle_count)
|
||||||
MUL(WB, WA, reg_cycle_count);
|
MSUB(reg_downcount, WA, reg_cycle_count, reg_downcount);
|
||||||
// ^ Note that this cannot overflow because it's limited by (downcount/cycle_count).
|
// ^ Note that this cannot overflow because it's limited by (downcount/cycle_count).
|
||||||
SUB(reg_downcount, reg_downcount, WB);
|
|
||||||
STR(IndexType::Unsigned, reg_downcount, PPC_REG, PPCSTATE_OFF(downcount));
|
STR(IndexType::Unsigned, reg_downcount, PPC_REG, PPCSTATE_OFF(downcount));
|
||||||
|
|
||||||
SetJumpTarget(downcount_is_zero_or_negative);
|
SetJumpTarget(downcount_is_zero_or_negative);
|
||||||
|
|
|
@ -20,6 +20,144 @@
|
||||||
|
|
||||||
using namespace Arm64Gen;
|
using namespace Arm64Gen;
|
||||||
|
|
||||||
|
void JitArm64::GetCRFieldBit(int field, int bit, ARM64Reg out)
|
||||||
|
{
|
||||||
|
ARM64Reg CR = gpr.CR(field);
|
||||||
|
ARM64Reg WCR = EncodeRegTo32(CR);
|
||||||
|
|
||||||
|
switch (bit)
|
||||||
|
{
|
||||||
|
case PowerPC::CR_SO_BIT: // check bit 59 set
|
||||||
|
UBFX(out, CR, PowerPC::CR_EMU_SO_BIT, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PowerPC::CR_EQ_BIT: // check bits 31-0 == 0
|
||||||
|
CMP(WCR, ARM64Reg::WZR);
|
||||||
|
CSET(out, CC_EQ);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PowerPC::CR_GT_BIT: // check val > 0
|
||||||
|
CMP(CR, ARM64Reg::ZR);
|
||||||
|
CSET(out, CC_GT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PowerPC::CR_LT_BIT: // check bit 62 set
|
||||||
|
UBFX(out, CR, PowerPC::CR_EMU_LT_BIT, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ASSERT_MSG(DYNA_REC, false, "Invalid CR bit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JitArm64::SetCRFieldBit(int field, int bit, ARM64Reg in, bool negate)
|
||||||
|
{
|
||||||
|
gpr.BindCRToRegister(field, true);
|
||||||
|
ARM64Reg CR = gpr.CR(field);
|
||||||
|
|
||||||
|
if (bit != PowerPC::CR_GT_BIT)
|
||||||
|
FixGTBeforeSettingCRFieldBit(CR);
|
||||||
|
|
||||||
|
switch (bit)
|
||||||
|
{
|
||||||
|
case PowerPC::CR_SO_BIT: // set bit 59 to input
|
||||||
|
BFI(CR, in, PowerPC::CR_EMU_SO_BIT, 1);
|
||||||
|
if (negate)
|
||||||
|
EOR(CR, CR, LogicalImm(1ULL << PowerPC::CR_EMU_SO_BIT, GPRSize::B64));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PowerPC::CR_EQ_BIT: // clear low 32 bits, set bit 0 to !input
|
||||||
|
AND(CR, CR, LogicalImm(0xFFFF'FFFF'0000'0000, GPRSize::B64));
|
||||||
|
ORR(CR, CR, in);
|
||||||
|
if (!negate)
|
||||||
|
EOR(CR, CR, LogicalImm(1ULL << 0, GPRSize::B64));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PowerPC::CR_GT_BIT: // set bit 63 to !input
|
||||||
|
BFI(CR, in, 63, 1);
|
||||||
|
if (!negate)
|
||||||
|
EOR(CR, CR, LogicalImm(1ULL << 63, GPRSize::B64));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PowerPC::CR_LT_BIT: // set bit 62 to input
|
||||||
|
BFI(CR, in, PowerPC::CR_EMU_LT_BIT, 1);
|
||||||
|
if (negate)
|
||||||
|
EOR(CR, CR, LogicalImm(1ULL << PowerPC::CR_EMU_LT_BIT, GPRSize::B64));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ORR(CR, CR, LogicalImm(1ULL << 32, GPRSize::B64));
|
||||||
|
}
|
||||||
|
|
||||||
|
void JitArm64::ClearCRFieldBit(int field, int bit)
|
||||||
|
{
|
||||||
|
gpr.BindCRToRegister(field, true);
|
||||||
|
ARM64Reg XA = gpr.CR(field);
|
||||||
|
|
||||||
|
switch (bit)
|
||||||
|
{
|
||||||
|
case PowerPC::CR_SO_BIT:
|
||||||
|
AND(XA, XA, LogicalImm(~(u64(1) << PowerPC::CR_EMU_SO_BIT), GPRSize::B64));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PowerPC::CR_EQ_BIT:
|
||||||
|
FixGTBeforeSettingCRFieldBit(XA);
|
||||||
|
ORR(XA, XA, LogicalImm(1, GPRSize::B64));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PowerPC::CR_GT_BIT:
|
||||||
|
ORR(XA, XA, LogicalImm(u64(1) << 63, GPRSize::B64));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PowerPC::CR_LT_BIT:
|
||||||
|
AND(XA, XA, LogicalImm(~(u64(1) << PowerPC::CR_EMU_LT_BIT), GPRSize::B64));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JitArm64::SetCRFieldBit(int field, int bit)
|
||||||
|
{
|
||||||
|
gpr.BindCRToRegister(field, true);
|
||||||
|
ARM64Reg XA = gpr.CR(field);
|
||||||
|
|
||||||
|
if (bit != PowerPC::CR_GT_BIT)
|
||||||
|
FixGTBeforeSettingCRFieldBit(XA);
|
||||||
|
|
||||||
|
switch (bit)
|
||||||
|
{
|
||||||
|
case PowerPC::CR_SO_BIT:
|
||||||
|
ORR(XA, XA, LogicalImm(u64(1) << PowerPC::CR_EMU_SO_BIT, GPRSize::B64));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PowerPC::CR_EQ_BIT:
|
||||||
|
AND(XA, XA, LogicalImm(0xFFFF'FFFF'0000'0000, GPRSize::B64));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PowerPC::CR_GT_BIT:
|
||||||
|
AND(XA, XA, LogicalImm(~(u64(1) << 63), GPRSize::B64));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PowerPC::CR_LT_BIT:
|
||||||
|
ORR(XA, XA, LogicalImm(u64(1) << PowerPC::CR_EMU_LT_BIT, GPRSize::B64));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ORR(XA, XA, LogicalImm(u64(1) << 32, GPRSize::B64));
|
||||||
|
}
|
||||||
|
|
||||||
|
void JitArm64::FixGTBeforeSettingCRFieldBit(ARM64Reg reg)
|
||||||
|
{
|
||||||
|
// GT is considered unset if the internal representation is <= 0, or in other words,
|
||||||
|
// if the internal representation either has bit 63 set or has all bits set to zero.
|
||||||
|
// If all bits are zero and we set some bit that's unrelated to GT, we need to set bit 63 so GT
|
||||||
|
// doesn't accidentally become considered set. Gross but necessary; this can break actual games.
|
||||||
|
auto WA = gpr.GetScopedReg();
|
||||||
|
ARM64Reg XA = EncodeRegTo64(WA);
|
||||||
|
ORR(XA, reg, LogicalImm(1ULL << 63, GPRSize::B64));
|
||||||
|
CMP(reg, ARM64Reg::ZR);
|
||||||
|
CSEL(reg, reg, XA, CC_NEQ);
|
||||||
|
}
|
||||||
|
|
||||||
FixupBranch JitArm64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set)
|
FixupBranch JitArm64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set)
|
||||||
{
|
{
|
||||||
ARM64Reg XA = gpr.CR(field);
|
ARM64Reg XA = gpr.CR(field);
|
||||||
|
@ -42,19 +180,6 @@ FixupBranch JitArm64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::FixGTBeforeSettingCRFieldBit(Arm64Gen::ARM64Reg reg)
|
|
||||||
{
|
|
||||||
// GT is considered unset if the internal representation is <= 0, or in other words,
|
|
||||||
// if the internal representation either has bit 63 set or has all bits set to zero.
|
|
||||||
// If all bits are zero and we set some bit that's unrelated to GT, we need to set bit 63 so GT
|
|
||||||
// doesn't accidentally become considered set. Gross but necessary; this can break actual games.
|
|
||||||
auto WA = gpr.GetScopedReg();
|
|
||||||
ARM64Reg XA = EncodeRegTo64(WA);
|
|
||||||
ORR(XA, reg, LogicalImm(1ULL << 63, GPRSize::B64));
|
|
||||||
CMP(reg, ARM64Reg::ZR);
|
|
||||||
CSEL(reg, reg, XA, CC_NEQ);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JitArm64::UpdateFPExceptionSummary(ARM64Reg fpscr)
|
void JitArm64::UpdateFPExceptionSummary(ARM64Reg fpscr)
|
||||||
{
|
{
|
||||||
auto WA = gpr.GetScopedReg();
|
auto WA = gpr.GetScopedReg();
|
||||||
|
@ -468,72 +593,47 @@ void JitArm64::crXXX(UGeckoInstruction inst)
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITSystemRegistersOff);
|
JITDISABLE(bJITSystemRegistersOff);
|
||||||
|
|
||||||
// Special case: crclr
|
if (inst.CRBA == inst.CRBB)
|
||||||
if (inst.CRBA == inst.CRBB && inst.CRBA == inst.CRBD && inst.SUBOP10 == 193)
|
|
||||||
{
|
{
|
||||||
// Clear CR field bit
|
switch (inst.SUBOP10)
|
||||||
int field = inst.CRBD >> 2;
|
|
||||||
int bit = 3 - (inst.CRBD & 3);
|
|
||||||
|
|
||||||
gpr.BindCRToRegister(field, true);
|
|
||||||
ARM64Reg XA = gpr.CR(field);
|
|
||||||
switch (bit)
|
|
||||||
{
|
{
|
||||||
case PowerPC::CR_SO_BIT:
|
// crclr
|
||||||
AND(XA, XA, LogicalImm(~(u64(1) << PowerPC::CR_EMU_SO_BIT), GPRSize::B64));
|
case 129: // crandc: A && ~B => 0
|
||||||
break;
|
case 193: // crxor: A ^ B => 0
|
||||||
|
{
|
||||||
case PowerPC::CR_EQ_BIT:
|
ClearCRFieldBit(inst.CRBD >> 2, 3 - (inst.CRBD & 3));
|
||||||
FixGTBeforeSettingCRFieldBit(XA);
|
return;
|
||||||
ORR(XA, XA, LogicalImm(1, GPRSize::B64));
|
}
|
||||||
break;
|
// crset
|
||||||
|
case 289: // creqv: ~(A ^ B) => 1
|
||||||
case PowerPC::CR_GT_BIT:
|
case 417: // crorc: A || ~B => 1
|
||||||
ORR(XA, XA, LogicalImm(u64(1) << 63, GPRSize::B64));
|
{
|
||||||
break;
|
SetCRFieldBit(inst.CRBD >> 2, 3 - (inst.CRBD & 3));
|
||||||
|
return;
|
||||||
case PowerPC::CR_LT_BIT:
|
}
|
||||||
AND(XA, XA, LogicalImm(~(u64(1) << PowerPC::CR_EMU_LT_BIT), GPRSize::B64));
|
case 257: // crand: A && B => A
|
||||||
break;
|
case 449: // cror: A || B => A
|
||||||
|
{
|
||||||
|
auto WA = gpr.GetScopedReg();
|
||||||
|
ARM64Reg XA = EncodeRegTo64(WA);
|
||||||
|
GetCRFieldBit(inst.CRBA >> 2, 3 - (inst.CRBA & 3), XA);
|
||||||
|
SetCRFieldBit(inst.CRBD >> 2, 3 - (inst.CRBD & 3), XA, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 33: // crnor: ~(A || B) => ~A
|
||||||
|
case 225: // crnand: ~(A && B) => ~A
|
||||||
|
{
|
||||||
|
auto WA = gpr.GetScopedReg();
|
||||||
|
ARM64Reg XA = EncodeRegTo64(WA);
|
||||||
|
GetCRFieldBit(inst.CRBA >> 2, 3 - (inst.CRBA & 3), XA);
|
||||||
|
SetCRFieldBit(inst.CRBD >> 2, 3 - (inst.CRBD & 3), XA, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case: crset
|
// crnor or crnand
|
||||||
if (inst.CRBA == inst.CRBB && inst.CRBA == inst.CRBD && inst.SUBOP10 == 289)
|
const bool negate_result = inst.SUBOP10 == 33 || inst.SUBOP10 == 225;
|
||||||
{
|
|
||||||
// SetCRFieldBit
|
|
||||||
int field = inst.CRBD >> 2;
|
|
||||||
int bit = 3 - (inst.CRBD & 3);
|
|
||||||
|
|
||||||
gpr.BindCRToRegister(field, true);
|
|
||||||
ARM64Reg XA = gpr.CR(field);
|
|
||||||
|
|
||||||
if (bit != PowerPC::CR_GT_BIT)
|
|
||||||
FixGTBeforeSettingCRFieldBit(XA);
|
|
||||||
|
|
||||||
switch (bit)
|
|
||||||
{
|
|
||||||
case PowerPC::CR_SO_BIT:
|
|
||||||
ORR(XA, XA, LogicalImm(u64(1) << PowerPC::CR_EMU_SO_BIT, GPRSize::B64));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PowerPC::CR_EQ_BIT:
|
|
||||||
AND(XA, XA, LogicalImm(0xFFFF'FFFF'0000'0000, GPRSize::B64));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PowerPC::CR_GT_BIT:
|
|
||||||
AND(XA, XA, LogicalImm(~(u64(1) << 63), GPRSize::B64));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PowerPC::CR_LT_BIT:
|
|
||||||
ORR(XA, XA, LogicalImm(u64(1) << PowerPC::CR_EMU_LT_BIT, GPRSize::B64));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ORR(XA, XA, LogicalImm(u64(1) << 32, GPRSize::B64));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto WA = gpr.GetScopedReg();
|
auto WA = gpr.GetScopedReg();
|
||||||
ARM64Reg XA = EncodeRegTo64(WA);
|
ARM64Reg XA = EncodeRegTo64(WA);
|
||||||
|
@ -541,106 +641,42 @@ void JitArm64::crXXX(UGeckoInstruction inst)
|
||||||
auto WB = gpr.GetScopedReg();
|
auto WB = gpr.GetScopedReg();
|
||||||
ARM64Reg XB = EncodeRegTo64(WB);
|
ARM64Reg XB = EncodeRegTo64(WB);
|
||||||
|
|
||||||
// creqv or crnand or crnor
|
GetCRFieldBit(inst.CRBA >> 2, 3 - (inst.CRBA & 3), XA);
|
||||||
bool negateA = inst.SUBOP10 == 289 || inst.SUBOP10 == 225 || inst.SUBOP10 == 33;
|
GetCRFieldBit(inst.CRBB >> 2, 3 - (inst.CRBB & 3), XB);
|
||||||
// crandc or crorc or crnand or crnor
|
|
||||||
bool negateB =
|
|
||||||
inst.SUBOP10 == 129 || inst.SUBOP10 == 417 || inst.SUBOP10 == 225 || inst.SUBOP10 == 33;
|
|
||||||
|
|
||||||
// GetCRFieldBit
|
|
||||||
for (int i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
int field = i ? inst.CRBB >> 2 : inst.CRBA >> 2;
|
|
||||||
int bit = i ? 3 - (inst.CRBB & 3) : 3 - (inst.CRBA & 3);
|
|
||||||
ARM64Reg out = i ? XB : XA;
|
|
||||||
bool negate = i ? negateB : negateA;
|
|
||||||
|
|
||||||
ARM64Reg XC = gpr.CR(field);
|
|
||||||
ARM64Reg WC = EncodeRegTo32(XC);
|
|
||||||
switch (bit)
|
|
||||||
{
|
|
||||||
case PowerPC::CR_SO_BIT: // check bit 59 set
|
|
||||||
UBFX(out, XC, PowerPC::CR_EMU_SO_BIT, 1);
|
|
||||||
if (negate)
|
|
||||||
EOR(out, out, LogicalImm(1, GPRSize::B64));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PowerPC::CR_EQ_BIT: // check bits 31-0 == 0
|
|
||||||
CMP(WC, ARM64Reg::WZR);
|
|
||||||
CSET(out, negate ? CC_NEQ : CC_EQ);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PowerPC::CR_GT_BIT: // check val > 0
|
|
||||||
CMP(XC, ARM64Reg::ZR);
|
|
||||||
CSET(out, negate ? CC_LE : CC_GT);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PowerPC::CR_LT_BIT: // check bit 62 set
|
|
||||||
UBFX(out, XC, PowerPC::CR_EMU_LT_BIT, 1);
|
|
||||||
if (negate)
|
|
||||||
EOR(out, out, LogicalImm(1, GPRSize::B64));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ASSERT_MSG(DYNA_REC, false, "Invalid CR bit");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute combined bit
|
// Compute combined bit
|
||||||
switch (inst.SUBOP10)
|
switch (inst.SUBOP10)
|
||||||
{
|
{
|
||||||
case 33: // crnor: ~(A || B) == (~A && ~B)
|
case 225: // crnand: ~(A && B)
|
||||||
case 129: // crandc: A && ~B
|
|
||||||
case 257: // crand: A && B
|
case 257: // crand: A && B
|
||||||
AND(XA, XA, XB);
|
AND(XA, XA, XB);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 129: // crandc: A && ~B
|
||||||
|
BIC(XA, XA, XB);
|
||||||
|
break;
|
||||||
|
|
||||||
case 193: // crxor: A ^ B
|
case 193: // crxor: A ^ B
|
||||||
case 289: // creqv: ~(A ^ B) = ~A ^ B
|
|
||||||
EOR(XA, XA, XB);
|
EOR(XA, XA, XB);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 225: // crnand: ~(A && B) == (~A || ~B)
|
case 289: // creqv: ~(A ^ B) = A ^ ~B
|
||||||
case 417: // crorc: A || ~B
|
EON(XA, XA, XB);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 33: // crnor: ~(A || B)
|
||||||
case 449: // cror: A || B
|
case 449: // cror: A || B
|
||||||
ORR(XA, XA, XB);
|
ORR(XA, XA, XB);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 417: // crorc: A || ~B
|
||||||
|
ORN(XA, XA, XB);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store result bit in CRBD
|
// Store result bit in CRBD
|
||||||
int field = inst.CRBD >> 2;
|
SetCRFieldBit(inst.CRBD >> 2, 3 - (inst.CRBD & 3), XA, negate_result);
|
||||||
int bit = 3 - (inst.CRBD & 3);
|
|
||||||
|
|
||||||
gpr.BindCRToRegister(field, true);
|
|
||||||
ARM64Reg CR = gpr.CR(field);
|
|
||||||
|
|
||||||
if (bit != PowerPC::CR_GT_BIT)
|
|
||||||
FixGTBeforeSettingCRFieldBit(CR);
|
|
||||||
|
|
||||||
switch (bit)
|
|
||||||
{
|
|
||||||
case PowerPC::CR_SO_BIT: // set bit 59 to input
|
|
||||||
BFI(CR, XA, PowerPC::CR_EMU_SO_BIT, 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PowerPC::CR_EQ_BIT: // clear low 32 bits, set bit 0 to !input
|
|
||||||
AND(CR, CR, LogicalImm(0xFFFF'FFFF'0000'0000, GPRSize::B64));
|
|
||||||
EOR(XA, XA, LogicalImm(1, GPRSize::B64));
|
|
||||||
ORR(CR, CR, XA);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PowerPC::CR_GT_BIT: // set bit 63 to !input
|
|
||||||
EOR(XA, XA, LogicalImm(1, GPRSize::B64));
|
|
||||||
BFI(CR, XA, 63, 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PowerPC::CR_LT_BIT: // set bit 62 to input
|
|
||||||
BFI(CR, XA, PowerPC::CR_EMU_LT_BIT, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ORR(CR, CR, LogicalImm(1ULL << 32, GPRSize::B64));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::mfcr(UGeckoInstruction inst)
|
void JitArm64::mfcr(UGeckoInstruction inst)
|
||||||
|
|
|
@ -110,7 +110,7 @@ JitBase::~JitBase()
|
||||||
CPUThreadConfigCallback::RemoveConfigChangedCallback(m_registered_config_callback_id);
|
CPUThreadConfigCallback::RemoveConfigChangedCallback(m_registered_config_callback_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JitBase::DoesConfigNeedRefresh()
|
bool JitBase::DoesConfigNeedRefresh() const
|
||||||
{
|
{
|
||||||
return std::ranges::any_of(JIT_SETTINGS, [this](const auto& pair) {
|
return std::ranges::any_of(JIT_SETTINGS, [this](const auto& pair) {
|
||||||
return this->*pair.first != Config::Get(*pair.second);
|
return this->*pair.first != Config::Get(*pair.second);
|
||||||
|
@ -276,7 +276,7 @@ bool JitBase::CanMergeNextInstructions(int count) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JitBase::ShouldHandleFPExceptionForInstruction(const PPCAnalyst::CodeOp* op)
|
bool JitBase::ShouldHandleFPExceptionForInstruction(const PPCAnalyst::CodeOp* op) const
|
||||||
{
|
{
|
||||||
if (jo.fp_exceptions)
|
if (jo.fp_exceptions)
|
||||||
return (op->opinfo->flags & FL_FLOAT_EXCEPTION) != 0;
|
return (op->opinfo->flags & FL_FLOAT_EXCEPTION) != 0;
|
||||||
|
|
|
@ -167,7 +167,7 @@ protected:
|
||||||
|
|
||||||
static const std::array<std::pair<bool JitBase::*, const Config::Info<bool>*>, 23> JIT_SETTINGS;
|
static const std::array<std::pair<bool JitBase::*, const Config::Info<bool>*>, 23> JIT_SETTINGS;
|
||||||
|
|
||||||
bool DoesConfigNeedRefresh();
|
bool DoesConfigNeedRefresh() const;
|
||||||
void RefreshConfig();
|
void RefreshConfig();
|
||||||
|
|
||||||
void InitFastmemArena();
|
void InitFastmemArena();
|
||||||
|
@ -178,8 +178,16 @@ protected:
|
||||||
void CleanUpAfterStackFault();
|
void CleanUpAfterStackFault();
|
||||||
|
|
||||||
bool CanMergeNextInstructions(int count) const;
|
bool CanMergeNextInstructions(int count) const;
|
||||||
|
bool HasConstantCarry() const
|
||||||
|
{
|
||||||
|
#ifdef _M_ARM_64
|
||||||
|
return js.carryFlag == CarryFlag::ConstantTrue || js.carryFlag == CarryFlag::ConstantFalse;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool ShouldHandleFPExceptionForInstruction(const PPCAnalyst::CodeOp* op);
|
bool ShouldHandleFPExceptionForInstruction(const PPCAnalyst::CodeOp* op) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit JitBase(Core::System& system);
|
explicit JitBase(Core::System& system);
|
||||||
|
|
|
@ -580,12 +580,11 @@ endif()
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
include(BundleUtilities)
|
include(BundleUtilities)
|
||||||
set(BUNDLE_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DolphinQt.app)
|
|
||||||
|
|
||||||
# Ask for an application bundle.
|
# Ask for an application bundle.
|
||||||
set_target_properties(dolphin-mpn PROPERTIES
|
set_target_properties(dolphin-mpn PROPERTIES
|
||||||
MACOSX_BUNDLE true
|
MACOSX_BUNDLE true
|
||||||
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_BINARY_DIR}/Info.plist"
|
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in"
|
||||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
|
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
|
||||||
OUTPUT_NAME DolphinQt
|
OUTPUT_NAME DolphinQt
|
||||||
)
|
)
|
||||||
|
@ -622,6 +621,9 @@ if(APPLE)
|
||||||
source_group("Resources" FILES "${CMAKE_SOURCE_DIR}/Data/${res}")
|
source_group("Resources" FILES "${CMAKE_SOURCE_DIR}/Data/${res}")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
include(DolphinInjectVersionInfo)
|
||||||
|
dolphin_inject_version_info(dolphin-emu)
|
||||||
|
|
||||||
# Copy MoltenVK into the bundle
|
# Copy MoltenVK into the bundle
|
||||||
if(ENABLE_VULKAN)
|
if(ENABLE_VULKAN)
|
||||||
if(USE_BUNDLED_MOLTENVK)
|
if(USE_BUNDLED_MOLTENVK)
|
||||||
|
@ -656,7 +658,7 @@ if(APPLE)
|
||||||
COMMAND "${CMAKE_SOURCE_DIR}/Tools/mac-codesign.sh"
|
COMMAND "${CMAKE_SOURCE_DIR}/Tools/mac-codesign.sh"
|
||||||
"-e" "${CMAKE_CURRENT_SOURCE_DIR}/DolphinEmu$<$<CONFIG:Debug>:Debug>.entitlements"
|
"-e" "${CMAKE_CURRENT_SOURCE_DIR}/DolphinEmu$<$<CONFIG:Debug>:Debug>.entitlements"
|
||||||
"${MACOS_CODE_SIGNING_IDENTITY}"
|
"${MACOS_CODE_SIGNING_IDENTITY}"
|
||||||
"${BUNDLE_PATH}"
|
"$<TARGET_BUNDLE_DIR:dolphin-emu>"
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
|
|
|
@ -185,11 +185,13 @@ void AdvancedWidget::CreateWidgets()
|
||||||
dump_layout->addWidget(m_frame_dumps_resolution_type, 0, 1);
|
dump_layout->addWidget(m_frame_dumps_resolution_type, 0, 1);
|
||||||
|
|
||||||
#if defined(HAVE_FFMPEG)
|
#if defined(HAVE_FFMPEG)
|
||||||
m_dump_use_ffv1 =
|
m_dump_use_lossless =
|
||||||
new ConfigBool(tr("Use Lossless Codec (FFV1)"), Config::GFX_USE_FFV1, m_game_layer);
|
new ConfigBool(tr("Use Lossless Codec (Ut Video)"), Config::GFX_USE_LOSSLESS, m_game_layer);
|
||||||
|
|
||||||
m_dump_bitrate = new ConfigInteger(0, 1000000, Config::GFX_BITRATE_KBPS, m_game_layer, 1000);
|
m_dump_bitrate = new ConfigInteger(0, 1000000, Config::GFX_BITRATE_KBPS, m_game_layer, 1000);
|
||||||
m_dump_bitrate->setEnabled(!m_dump_use_ffv1->isChecked());
|
m_dump_bitrate->setEnabled(!m_dump_use_lossless->isChecked());
|
||||||
dump_layout->addWidget(m_dump_use_ffv1, 1, 0);
|
|
||||||
|
dump_layout->addWidget(m_dump_use_lossless, 1, 0);
|
||||||
dump_layout->addWidget(new QLabel(tr("Bitrate (kbps):")), 2, 0);
|
dump_layout->addWidget(new QLabel(tr("Bitrate (kbps):")), 2, 0);
|
||||||
dump_layout->addWidget(m_dump_bitrate, 2, 1);
|
dump_layout->addWidget(m_dump_bitrate, 2, 1);
|
||||||
#endif
|
#endif
|
||||||
|
@ -261,9 +263,8 @@ void AdvancedWidget::ConnectWidgets()
|
||||||
});
|
});
|
||||||
connect(m_enable_graphics_mods, &QCheckBox::toggled, this,
|
connect(m_enable_graphics_mods, &QCheckBox::toggled, this,
|
||||||
[this](bool checked) { emit Settings::Instance().EnableGfxModsChanged(checked); });
|
[this](bool checked) { emit Settings::Instance().EnableGfxModsChanged(checked); });
|
||||||
|
|
||||||
#if defined(HAVE_FFMPEG)
|
#if defined(HAVE_FFMPEG)
|
||||||
connect(m_dump_use_ffv1, &QCheckBox::toggled, this,
|
connect(m_dump_use_lossless, &QCheckBox::toggled, this,
|
||||||
[this](bool checked) { m_dump_bitrate->setEnabled(!checked); });
|
[this](bool checked) { m_dump_bitrate->setEnabled(!checked); });
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -391,8 +392,9 @@ void AdvancedWidget::AddDescriptions()
|
||||||
"possible input for external editing software.<br><br><dolphin_emphasis>If unsure, leave "
|
"possible input for external editing software.<br><br><dolphin_emphasis>If unsure, leave "
|
||||||
"this at \"Aspect Ratio Corrected Internal Resolution\".</dolphin_emphasis>");
|
"this at \"Aspect Ratio Corrected Internal Resolution\".</dolphin_emphasis>");
|
||||||
#if defined(HAVE_FFMPEG)
|
#if defined(HAVE_FFMPEG)
|
||||||
static const char TR_USE_FFV1_DESCRIPTION[] =
|
static const char TR_USE_LOSSLESS_DESCRIPTION[] =
|
||||||
QT_TR_NOOP("Encodes frame dumps using the FFV1 codec.<br><br><dolphin_emphasis>If "
|
QT_TR_NOOP("Encodes frame dumps using the Ut Video codec. If this option is unchecked, a "
|
||||||
|
"lossy Xvid codec will be used.<br><br><dolphin_emphasis>If "
|
||||||
"unsure, leave this unchecked.</dolphin_emphasis>");
|
"unsure, leave this unchecked.</dolphin_emphasis>");
|
||||||
#endif
|
#endif
|
||||||
static const char TR_PNG_COMPRESSION_LEVEL_DESCRIPTION[] =
|
static const char TR_PNG_COMPRESSION_LEVEL_DESCRIPTION[] =
|
||||||
|
@ -483,7 +485,7 @@ void AdvancedWidget::AddDescriptions()
|
||||||
m_enable_graphics_mods->SetDescription(tr(TR_LOAD_GRAPHICS_MODS_DESCRIPTION));
|
m_enable_graphics_mods->SetDescription(tr(TR_LOAD_GRAPHICS_MODS_DESCRIPTION));
|
||||||
m_frame_dumps_resolution_type->SetDescription(tr(TR_FRAME_DUMPS_RESOLUTION_TYPE_DESCRIPTION));
|
m_frame_dumps_resolution_type->SetDescription(tr(TR_FRAME_DUMPS_RESOLUTION_TYPE_DESCRIPTION));
|
||||||
#ifdef HAVE_FFMPEG
|
#ifdef HAVE_FFMPEG
|
||||||
m_dump_use_ffv1->SetDescription(tr(TR_USE_FFV1_DESCRIPTION));
|
m_dump_use_lossless->SetDescription(tr(TR_USE_LOSSLESS_DESCRIPTION));
|
||||||
#endif
|
#endif
|
||||||
m_png_compression_level->SetDescription(tr(TR_PNG_COMPRESSION_LEVEL_DESCRIPTION));
|
m_png_compression_level->SetDescription(tr(TR_PNG_COMPRESSION_LEVEL_DESCRIPTION));
|
||||||
m_enable_cropping->SetDescription(tr(TR_CROPPING_DESCRIPTION));
|
m_enable_cropping->SetDescription(tr(TR_CROPPING_DESCRIPTION));
|
||||||
|
|
|
@ -60,7 +60,7 @@ private:
|
||||||
ConfigBool* m_dump_base_textures;
|
ConfigBool* m_dump_base_textures;
|
||||||
|
|
||||||
// Frame dumping
|
// Frame dumping
|
||||||
ConfigBool* m_dump_use_ffv1;
|
ConfigBool* m_dump_use_lossless;
|
||||||
ConfigChoice* m_frame_dumps_resolution_type;
|
ConfigChoice* m_frame_dumps_resolution_type;
|
||||||
ConfigInteger* m_dump_bitrate;
|
ConfigInteger* m_dump_bitrate;
|
||||||
ConfigInteger* m_png_compression_level;
|
ConfigInteger* m_png_compression_level;
|
||||||
|
|
|
@ -39,12 +39,6 @@
|
||||||
<string>English</string>
|
<string>English</string>
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>${DOLPHIN_WC_DESCRIBE}</string>
|
|
||||||
<key>CFBundleLongVersionString</key>
|
|
||||||
<string>${DOLPHIN_WC_REVISION}</string>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>${DOLPHIN_VERSION_MAJOR}.${DOLPHIN_VERSION_MINOR}</string>
|
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>Licensed under GPL version 2 or later (GPLv2+)</string>
|
<string>Licensed under GPL version 2 or later (GPLv2+)</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
|
|
|
@ -16,7 +16,7 @@ add_dependencies(MacUpdater dolphin_scmrev)
|
||||||
|
|
||||||
set_target_properties(MacUpdater PROPERTIES
|
set_target_properties(MacUpdater PROPERTIES
|
||||||
MACOSX_BUNDLE true
|
MACOSX_BUNDLE true
|
||||||
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_BINARY_DIR}/Info.plist"
|
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in"
|
||||||
OUTPUT_NAME "Dolphin Updater")
|
OUTPUT_NAME "Dolphin Updater")
|
||||||
|
|
||||||
target_compile_options(MacUpdater PRIVATE -x objective-c++)
|
target_compile_options(MacUpdater PRIVATE -x objective-c++)
|
||||||
|
@ -53,6 +53,9 @@ foreach(sb ${STORYBOARDS})
|
||||||
COMMENT "Compiling Storyboard ${sb}...")
|
COMMENT "Compiling Storyboard ${sb}...")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
include(DolphinInjectVersionInfo)
|
||||||
|
dolphin_inject_version_info(MacUpdater)
|
||||||
|
|
||||||
if(NOT SKIP_POSTPROCESS_BUNDLE)
|
if(NOT SKIP_POSTPROCESS_BUNDLE)
|
||||||
# Update library references to make the bundle portable
|
# Update library references to make the bundle portable
|
||||||
include(DolphinPostprocessBundle)
|
include(DolphinPostprocessBundle)
|
||||||
|
|
|
@ -16,10 +16,6 @@
|
||||||
<string>Dolphin Updater</string>
|
<string>Dolphin Updater</string>
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>${DOLPHIN_WC_DESCRIBE}</string>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>${DOLPHIN_VERSION_MAJOR}.${DOLPHIN_VERSION_MINOR}</string>
|
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
<string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
|
<string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
|
|
13
Source/Core/VersionInfo.plist.in
Normal file
13
Source/Core/VersionInfo.plist.in
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<!-- This plist file is merged with the application's Info.plist to set its version info. -->
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>${DOLPHIN_WC_DESCRIBE}</string>
|
||||||
|
<key>CFBundleLongVersionString</key>
|
||||||
|
<string>${DOLPHIN_WC_REVISION}</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>${DOLPHIN_VERSION_MAJOR}.${DOLPHIN_VERSION_MINOR}</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -217,7 +217,7 @@ bool FFMpegFrameDump::CreateVideoFile()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& codec_name = g_Config.bUseFFV1 ? "ffv1" : g_Config.sDumpCodec;
|
const std::string& codec_name = g_Config.bUseLossless ? "utvideo" : g_Config.sDumpCodec;
|
||||||
|
|
||||||
AVCodecID codec_id = output_format->video_codec;
|
AVCodecID codec_id = output_format->video_codec;
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ void VideoConfig::Refresh()
|
||||||
bDumpEFBTarget = Config::Get(Config::GFX_DUMP_EFB_TARGET);
|
bDumpEFBTarget = Config::Get(Config::GFX_DUMP_EFB_TARGET);
|
||||||
bDumpXFBTarget = Config::Get(Config::GFX_DUMP_XFB_TARGET);
|
bDumpXFBTarget = Config::Get(Config::GFX_DUMP_XFB_TARGET);
|
||||||
bDumpFramesAsImages = Config::Get(Config::GFX_DUMP_FRAMES_AS_IMAGES);
|
bDumpFramesAsImages = Config::Get(Config::GFX_DUMP_FRAMES_AS_IMAGES);
|
||||||
bUseFFV1 = Config::Get(Config::GFX_USE_FFV1);
|
bUseLossless = Config::Get(Config::GFX_USE_LOSSLESS);
|
||||||
sDumpFormat = Config::Get(Config::GFX_DUMP_FORMAT);
|
sDumpFormat = Config::Get(Config::GFX_DUMP_FORMAT);
|
||||||
sDumpCodec = Config::Get(Config::GFX_DUMP_CODEC);
|
sDumpCodec = Config::Get(Config::GFX_DUMP_CODEC);
|
||||||
sDumpPixelFormat = Config::Get(Config::GFX_DUMP_PIXEL_FORMAT);
|
sDumpPixelFormat = Config::Get(Config::GFX_DUMP_PIXEL_FORMAT);
|
||||||
|
|
|
@ -194,7 +194,7 @@ struct VideoConfig final
|
||||||
bool bDumpEFBTarget = false;
|
bool bDumpEFBTarget = false;
|
||||||
bool bDumpXFBTarget = false;
|
bool bDumpXFBTarget = false;
|
||||||
bool bDumpFramesAsImages = false;
|
bool bDumpFramesAsImages = false;
|
||||||
bool bUseFFV1 = false;
|
bool bUseLossless = false;
|
||||||
std::string sDumpCodec;
|
std::string sDumpCodec;
|
||||||
std::string sDumpPixelFormat;
|
std::string sDumpPixelFormat;
|
||||||
std::string sDumpEncoder;
|
std::string sDumpEncoder;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue