Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 88156cff05 | |||
| 1b7065d8b4 | |||
| 909f36017b | |||
| 631df2d903 | |||
| 789045e1b2 | |||
| 19551fb864 | |||
| 449e28f9a6 | |||
| 45db281360 | |||
| cb38303531 | |||
| 1310052bd7 | |||
| 9d786b6440 | |||
| 9734e39530 | |||
| ed4318b949 | |||
| 21a240547e | |||
| cfd83be9a1 | |||
| 620c263582 | |||
| 559bfa3112 | |||
| dff7aa5ed6 | |||
| 8d826b4f62 | |||
| f77140336d | |||
| 29cb2ddd87 | |||
| 88af328437 | |||
| 318abc4ece | |||
| d4ba991dd3 | |||
| 9ea17949ef | |||
| fc74ce36c6 | |||
| d42a27937d |
-31
@@ -1,31 +0,0 @@
|
||||
# Ignore image thumbnail files created by windows
|
||||
Thumbs.db
|
||||
# Ignore Finder view option files created by OS X
|
||||
.DS_Store
|
||||
# Ignore autogenerated source files
|
||||
Source/Core/Common/scmrev.h
|
||||
# Ignore files output by build
|
||||
/[Bb]uild*/
|
||||
/[Bb]inary/
|
||||
/obj/
|
||||
# Android cmake builds to here then copies to Source/Android.
|
||||
/libs/
|
||||
# Ignore various files created by visual studio/msbuild
|
||||
*.ipch
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.suo
|
||||
*.vcxproj.user
|
||||
*.obj
|
||||
*.tlog
|
||||
# Ignore build info file created by QtCreator
|
||||
CMakeLists.txt.user
|
||||
# Ignore files created by posix people
|
||||
*~
|
||||
# Ignore transifex configuration directory
|
||||
.tx
|
||||
# Ignore kdevelop files/dirs
|
||||
*.kdev4
|
||||
# Ignore IDEA/Clion files/dirs
|
||||
/.idea/
|
||||
*xcuserdata*
|
||||
@@ -1,7 +0,0 @@
|
||||
[submodule "Externals/Qt"]
|
||||
path = Externals/Qt
|
||||
url = https://github.com/dolphin-emu/ext-win-qt.git
|
||||
branch = master
|
||||
[submodule "dolphin"]
|
||||
path = dolphin
|
||||
url = https://github.com/dolphin-emu/dolphin.git
|
||||
@@ -1,54 +0,0 @@
|
||||
# This file exists to enable "git shortlog -s" to group by person.
|
||||
Andrew de los Reyes <adlr@gmail.com> <adlr@chromium.org>
|
||||
Augustin Cavalier <waddlesplash@gmail.com> <ajcsweb@gmail.com>
|
||||
Benjamin Przybocki <buddybenj@gmail.com>
|
||||
Dolphin Bots <noreply@dolphin-emu.org> <dolphin-emu-bot@users.noreply.github.com>
|
||||
Dolphin Bots <noreply@dolphin-emu.org> <contact+i18n@dolphin-emu.org>
|
||||
Dolphin Bots <noreply@dolphin-emu.org> <buildbot@ubuntu.ubuntu.dolphin-emu.org>
|
||||
Grant Paul <git@grantpaul.com> <chpwn@chpwn.com>
|
||||
Henrik Rydgård <hrydgard@gmail.com>
|
||||
Jack Frost <bhaal@0x1337.org> <j4ck.fr0st@gmail.com>
|
||||
James Dunne <james.jdunne@gmail.com>
|
||||
John Chadwick <johnwchadwick@gmail.com> <johnwchadwick>
|
||||
John Peterson <john.s.peterson@live.com>
|
||||
John Peterson <john.s.peterson@live.com> <jpeterson57@gmail.com>
|
||||
Jordan Cristiano <jordan.cristi@gmail.com> <jordan.cristi AT [Google mail]>
|
||||
Jordan Cristiano <jordan.cristi@gmail.com> <jordan.cristi [AT] gmail.com>
|
||||
Jordan Woyak <jordan.woyak@gmail.com> <jordan@bill-laptop.lan>
|
||||
Jordan Woyak <jordan.woyak@gmail.com> <Billiard26@gmail.com>
|
||||
Jules Blok <jules.blok@gmail.com> Armada <jules.blok@gmail.com>
|
||||
Lioncash <mathew1800@gmail.com>
|
||||
Lioncash <mathew1800@gmail.com> Lioncash <nope>
|
||||
Lioncash <mathew1800@gmail.com> <mathew1900@hotmail.com>
|
||||
Maarten ter Huurne <maarten@treewalker.org> <mth@lexx-9122.trinair2002>
|
||||
Marcos Vitali <marcosvitali@gmail.com>
|
||||
Markus Wick <markus+github@selfnet.de> <wickmarkus@web.de>
|
||||
Matthew Parlane <parlane@gmail.com>
|
||||
Matthew Parlane <parlane@gmail.com> <matthew@phantuntu.(none)>
|
||||
Oussama Danba <Shadoxfix@gmail.com>
|
||||
Pascal Jouy <pascal.jouy@hotmail.fr>
|
||||
Pierre <pierre@pirsoft.de>
|
||||
Pierre Bourdon <delroth@gmail.com> <delroth@lse.epita.fr>
|
||||
Rodolfo Bogado <rodolfoosvaldobogado@gmail.com>
|
||||
Rog <rdragoon@optonline.net>
|
||||
RolandMunsil <roland@munsil.com> <RolandMunsil@users.noreply.github.com>
|
||||
Runo <i.am.runo@hotmail.com>
|
||||
Ryan Houdek <sonicadvance1@gmail.com>
|
||||
Ryan Houdek <sonicadvance1@gmail.com> <Sonicadvance1@gmail.com>
|
||||
Ryan Houdek <sonicadvance1@gmail.com> <ryan.houdek@codethink.co.uk>
|
||||
Ryan Houdek <sonicadvance1@gmail.com> <sonicadvance1@Ryan-Desktop.(none)>
|
||||
Sacha <xsacha@gmail.com>
|
||||
Sean Maas <seanmaas27@gmail.com>
|
||||
Shawn Hoffman <godisgovernment@gmail.com>
|
||||
Steven V. <Stevoisiak@gmail.com>
|
||||
Steven V. <Stevoisiak@gmail.com> <S.Vascellaro@gmail.com>
|
||||
Tony Wasserka <neobrainx@gmail.com> <NeoBrainX@googlemail.com>
|
||||
Tony Wasserka <neobrainx@gmail.com> <NeoBrainX@gmail.com>
|
||||
TotalNerd <xtrafear@gmail.com>
|
||||
booto <remornicus@gmail.com> <booto+dolphin@justanothercoder.com>
|
||||
i418c <starfield94@aol.com> <i418c@users.noreply.github.com>
|
||||
luisr142004 <luisr142004@gmail.com> <luisr142004@yahoo.com>
|
||||
magumagu <magumagu9@gmail.com>
|
||||
masken <masken3@gmail.com> <masken@emulation64.com>
|
||||
nitsuja <nitsuja-@hotmail.com>
|
||||
skidau <skidau@gmail.com>
|
||||
@@ -1,193 +0,0 @@
|
||||
// Copyright 2009 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "AudioCommon/AudioCommon.h"
|
||||
#include "AudioCommon/Mixer.h"
|
||||
#include "AudioCommon/NullSoundStream.h"
|
||||
#include "OpenEmuAudioStream.h"
|
||||
#include "Common/Common.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
|
||||
// This shouldn't be a global, at least not here.
|
||||
extern std::unique_ptr<SoundStream> g_sound_stream;
|
||||
std::unique_ptr<SoundStream> g_sound_stream;
|
||||
|
||||
static bool s_audio_dump_start = false;
|
||||
static bool s_sound_stream_running = false;
|
||||
|
||||
namespace AudioCommon
|
||||
{
|
||||
static const int AUDIO_VOLUME_MIN = 0;
|
||||
static const int AUDIO_VOLUME_MAX = 100;
|
||||
|
||||
void InitSoundStream(Core::System& system)
|
||||
{
|
||||
g_sound_stream = std::make_unique<OpenEmuAudioStream>();
|
||||
|
||||
if (!g_sound_stream->Init())
|
||||
{
|
||||
WARN_LOG_FMT(AUDIO, "Could not initialize backend");
|
||||
g_sound_stream = std::make_unique<NullSound>();
|
||||
}
|
||||
|
||||
UpdateSoundStream(system);
|
||||
SetSoundStreamRunning(system, true);
|
||||
}
|
||||
|
||||
void PostInitSoundStream(Core::System& system)
|
||||
{
|
||||
// This needs to be called after AudioInterface::Init and SerialInterface::Init (for GBA devices)
|
||||
// where input sample rates are set
|
||||
UpdateSoundStream(system);
|
||||
SetSoundStreamRunning(system, true);
|
||||
|
||||
if (Config::Get(Config::MAIN_DUMP_AUDIO) && !s_audio_dump_start)
|
||||
StartAudioDump(system);
|
||||
}
|
||||
|
||||
void ShutdownSoundStream(Core::System& system)
|
||||
{
|
||||
INFO_LOG_FMT(AUDIO, "Shutting down sound stream");
|
||||
|
||||
if (Config::Get(Config::MAIN_DUMP_AUDIO) && s_audio_dump_start)
|
||||
StopAudioDump(system);
|
||||
|
||||
SetSoundStreamRunning(system, false);
|
||||
g_sound_stream.reset();
|
||||
|
||||
INFO_LOG_FMT(AUDIO, "Done shutting down sound stream");
|
||||
}
|
||||
|
||||
std::string GetDefaultSoundBackend()
|
||||
{
|
||||
std::string backend = "oeaudio";
|
||||
return backend;
|
||||
}
|
||||
|
||||
std::vector<std::string> GetSoundBackends()
|
||||
{
|
||||
std::vector<std::string> backends;
|
||||
backends.push_back("oeaudio");
|
||||
return backends;
|
||||
}
|
||||
|
||||
DPL2Quality GetDefaultDPL2Quality()
|
||||
{
|
||||
return DPL2Quality::High;
|
||||
}
|
||||
|
||||
bool SupportsDPL2Decoder(const std::string& backend)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SupportsLatencyControl(const std::string& backend)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SupportsVolumeChanges(const std::string& backend)
|
||||
{
|
||||
// FIXME: this one should ask the backend whether it supports it.
|
||||
// but getting the backend from string etc. is probably
|
||||
// too much just to enable/disable a stupid slider...
|
||||
return false;
|
||||
}
|
||||
|
||||
void UpdateSoundStream(Core::System& system)
|
||||
{
|
||||
if (g_sound_stream)
|
||||
{
|
||||
int volume = Config::Get(Config::MAIN_AUDIO_MUTED) ? 0 : Config::Get(Config::MAIN_AUDIO_VOLUME);
|
||||
g_sound_stream->SetVolume(volume);
|
||||
}
|
||||
}
|
||||
|
||||
void SetSoundStreamRunning(Core::System& system, bool running)
|
||||
{
|
||||
if (!g_sound_stream)
|
||||
return;
|
||||
|
||||
if (s_sound_stream_running == running)
|
||||
return;
|
||||
s_sound_stream_running = running;
|
||||
|
||||
if (g_sound_stream->SetRunning(running))
|
||||
return;
|
||||
if (running)
|
||||
ERROR_LOG_FMT(AUDIO, "Error starting stream.");
|
||||
else
|
||||
ERROR_LOG_FMT(AUDIO, "Error stopping stream.");
|
||||
}
|
||||
|
||||
void SendAIBuffer(Core::System& system, const short* samples, unsigned int num_samples)
|
||||
{
|
||||
if (!g_sound_stream)
|
||||
return;
|
||||
|
||||
if (Config::Get(Config::MAIN_DUMP_AUDIO) && !s_audio_dump_start)
|
||||
StartAudioDump(system);
|
||||
else if (!Config::Get(Config::MAIN_DUMP_AUDIO) && s_audio_dump_start)
|
||||
StopAudioDump(system);
|
||||
|
||||
Mixer* pMixer = g_sound_stream->GetMixer();
|
||||
|
||||
if (pMixer && samples)
|
||||
{
|
||||
pMixer->PushSamples(samples, num_samples);
|
||||
}
|
||||
}
|
||||
|
||||
void StartAudioDump(Core::System& system)
|
||||
{
|
||||
std::string audio_file_name_dtk = File::GetUserPath(D_DUMPAUDIO_IDX) + "dtkdump.wav";
|
||||
std::string audio_file_name_dsp = File::GetUserPath(D_DUMPAUDIO_IDX) + "dspdump.wav";
|
||||
File::CreateFullPath(audio_file_name_dtk);
|
||||
File::CreateFullPath(audio_file_name_dsp);
|
||||
g_sound_stream->GetMixer()->StartLogDTKAudio(audio_file_name_dtk);
|
||||
g_sound_stream->GetMixer()->StartLogDSPAudio(audio_file_name_dsp);
|
||||
s_audio_dump_start = true;
|
||||
}
|
||||
|
||||
void StopAudioDump(Core::System& system)
|
||||
{
|
||||
if (!g_sound_stream)
|
||||
return;
|
||||
g_sound_stream->GetMixer()->StopLogDTKAudio();
|
||||
g_sound_stream->GetMixer()->StopLogDSPAudio();
|
||||
s_audio_dump_start = false;
|
||||
}
|
||||
|
||||
void IncreaseVolume(Core::System& system, unsigned short offset)
|
||||
{
|
||||
Config::SetBaseOrCurrent(Config::MAIN_AUDIO_MUTED, false);
|
||||
int currentVolume = Config::Get(Config::MAIN_AUDIO_VOLUME);
|
||||
currentVolume += offset;
|
||||
if (currentVolume > AUDIO_VOLUME_MAX)
|
||||
currentVolume = AUDIO_VOLUME_MAX;
|
||||
Config::SetBaseOrCurrent(Config::MAIN_AUDIO_VOLUME, currentVolume);
|
||||
UpdateSoundStream(system);
|
||||
}
|
||||
|
||||
void DecreaseVolume(Core::System& system, unsigned short offset)
|
||||
{
|
||||
Config::SetBaseOrCurrent(Config::MAIN_AUDIO_MUTED, false);
|
||||
int currentVolume = Config::Get(Config::MAIN_AUDIO_VOLUME);
|
||||
currentVolume -= offset;
|
||||
if (currentVolume < AUDIO_VOLUME_MIN)
|
||||
currentVolume = AUDIO_VOLUME_MIN;
|
||||
Config::SetBaseOrCurrent(Config::MAIN_AUDIO_VOLUME, currentVolume);
|
||||
UpdateSoundStream(system);
|
||||
}
|
||||
|
||||
void ToggleMuteVolume(Core::System& system)
|
||||
{
|
||||
bool isMuted = Config::Get(Config::MAIN_AUDIO_MUTED);
|
||||
Config::SetBaseOrCurrent(Config::MAIN_AUDIO_MUTED, !isMuted);
|
||||
UpdateSoundStream(system);
|
||||
}
|
||||
} // namespace AudioCommon
|
||||
@@ -1,55 +0,0 @@
|
||||
// Copyright (c) 2018, OpenEmu Team
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the OpenEmu Team nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY OpenEmu Team ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL OpenEmu Team BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Copyright 2008 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#ifndef OpenEmuAudioStream_hpp
|
||||
#define OpenEmuAudioStream_hpp
|
||||
|
||||
#include "AudioCommon/SoundStream.h"
|
||||
|
||||
/* the sample rate is hardcoded in the initializer of the SoundStream
|
||||
* base class */
|
||||
#define OE_SAMPLERATE 48000
|
||||
|
||||
/* max amount of bytes pullable at once
|
||||
* should be <= Mixer::MAX_SAMPLES * sizeof(short) * 2 (= 16384)
|
||||
* however we can't use Mixer::MAX_SAMPLES because it is private */
|
||||
#define OE_SIZESOUNDBUFFER (16384 / 2)
|
||||
|
||||
class OpenEmuAudioStream final : public SoundStream
|
||||
{
|
||||
public:
|
||||
bool Init() override { return true; }
|
||||
bool SetRunning(bool running) override;
|
||||
static bool isValid() { return true; }
|
||||
int readAudio(void *buffer, int len);
|
||||
~OpenEmuAudioStream() {};
|
||||
private:
|
||||
bool running;
|
||||
};
|
||||
|
||||
#endif /* OpenEmuAudioStream_hpp */
|
||||
@@ -1,48 +0,0 @@
|
||||
// Copyright (c) 2018, OpenEmu Team
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the OpenEmu Team nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY OpenEmu Team ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL OpenEmu Team BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Copyright 2008 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
#include "DolphinGameCore.h"
|
||||
#include "OpenEmuAudioStream.h"
|
||||
|
||||
|
||||
bool OpenEmuAudioStream::SetRunning(bool r)
|
||||
{
|
||||
running = r;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int OpenEmuAudioStream::readAudio(void *buffer, int len)
|
||||
{
|
||||
if (!running)
|
||||
return 0;
|
||||
Mixer *mix = m_mixer.get();
|
||||
int bytePerSample = 2 * sizeof(short);
|
||||
return mix->Mix((short *)buffer, len / bytePerSample) * bytePerSample;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
// Copyright (c) 2022, OpenEmu Team
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the OpenEmu Team nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY OpenEmu Team ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL OpenEmu Team BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifdef __x86_64__
|
||||
#include "../../dolphin/Source/Core/Common/x64CPUDetect.cpp"
|
||||
#elif defined(__arm64__)
|
||||
#include "../../dolphin/Source/Core/Common/ArmCPUDetect.cpp"
|
||||
#endif
|
||||
@@ -1,27 +0,0 @@
|
||||
// Copyright (c) 2022, OpenEmu Team
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the OpenEmu Team nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY OpenEmu Team ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL OpenEmu Team BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifdef __x86_64__
|
||||
#include "../../dolphin/Source/Core/Common/x64FPURoundMode.cpp"
|
||||
#endif
|
||||
@@ -1,959 +0,0 @@
|
||||
// Copyright 2008 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "Common/FileUtil.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <fcntl.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <limits.h>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <sys/stat.h>
|
||||
#include <system_error>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/Common.h"
|
||||
#include "Common/CommonFuncs.h"
|
||||
#include "Common/CommonPaths.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#ifdef __APPLE__
|
||||
#include "Common/DynamicLibrary.h"
|
||||
#endif
|
||||
#include "Common/IOFile.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#include <Shlwapi.h>
|
||||
#include <commdlg.h> // for GetSaveFileName
|
||||
#include <direct.h> // getcwd
|
||||
#include <io.h>
|
||||
#include <objbase.h> // guid stuff
|
||||
#include <shellapi.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <libgen.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef OpenEmu
|
||||
#include "DolphinGameCore.h"
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <CoreFoundation/CFBundle.h>
|
||||
#include <CoreFoundation/CFString.h>
|
||||
#include <CoreFoundation/CFURL.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID
|
||||
#include "jni/AndroidCommon/AndroidCommon.h"
|
||||
#endif
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace File
|
||||
{
|
||||
#ifdef ANDROID
|
||||
static std::string s_android_sys_directory;
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
static Common::DynamicLibrary s_security_framework;
|
||||
|
||||
using DolSecTranslocateIsTranslocatedURL = Boolean (*)(CFURLRef path, bool* isTranslocated,
|
||||
CFErrorRef* __nullable error);
|
||||
using DolSecTranslocateCreateOriginalPathForURL = CFURLRef
|
||||
__nullable (*)(CFURLRef translocatedPath, CFErrorRef* __nullable error);
|
||||
|
||||
static DolSecTranslocateIsTranslocatedURL s_is_translocated_url;
|
||||
static DolSecTranslocateCreateOriginalPathForURL s_create_orig_path;
|
||||
#endif
|
||||
|
||||
FileInfo::FileInfo(const std::string& path) : FileInfo(path.c_str())
|
||||
{
|
||||
}
|
||||
|
||||
FileInfo::FileInfo(const char* path)
|
||||
{
|
||||
#ifdef ANDROID
|
||||
if (IsPathAndroidContent(path))
|
||||
{
|
||||
const jlong result = GetAndroidContentSizeAndIsDirectory(path);
|
||||
m_status.type((result == -2) ? fs::file_type::directory : fs::file_type::regular);
|
||||
m_size = (result >= 0) ? result : 0;
|
||||
m_exists = result != -1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
const auto fs_path = StringToPath(path);
|
||||
std::error_code error;
|
||||
m_status = fs::status(fs_path, error);
|
||||
m_size = fs::file_size(fs_path, error);
|
||||
if (error)
|
||||
m_size = 0;
|
||||
m_exists = fs::exists(m_status);
|
||||
}
|
||||
}
|
||||
|
||||
bool FileInfo::Exists() const
|
||||
{
|
||||
return m_exists;
|
||||
}
|
||||
|
||||
bool FileInfo::IsDirectory() const
|
||||
{
|
||||
return fs::is_directory(m_status);
|
||||
}
|
||||
|
||||
bool FileInfo::IsFile() const
|
||||
{
|
||||
return Exists() ? !fs::is_directory(m_status) : false;
|
||||
}
|
||||
|
||||
u64 FileInfo::GetSize() const
|
||||
{
|
||||
if (!IsFile())
|
||||
return 0;
|
||||
return m_size;
|
||||
}
|
||||
|
||||
// Returns true if the path exists
|
||||
bool Exists(const std::string& path)
|
||||
{
|
||||
return FileInfo(path).Exists();
|
||||
}
|
||||
|
||||
// Returns true if the path exists and is a directory
|
||||
bool IsDirectory(const std::string& path)
|
||||
{
|
||||
return FileInfo(path).IsDirectory();
|
||||
}
|
||||
|
||||
// Returns true if the path exists and is a file
|
||||
bool IsFile(const std::string& path)
|
||||
{
|
||||
return FileInfo(path).IsFile();
|
||||
}
|
||||
|
||||
// Deletes a given filename, return true on success
|
||||
// Doesn't supports deleting a directory
|
||||
bool Delete(const std::string& filename, IfAbsentBehavior behavior)
|
||||
{
|
||||
DEBUG_LOG_FMT(COMMON, "{}: file {}", __func__, filename);
|
||||
|
||||
#ifdef ANDROID
|
||||
if (filename.starts_with("content://"))
|
||||
{
|
||||
const bool success = DeleteAndroidContent(filename);
|
||||
if (!success)
|
||||
WARN_LOG_FMT(COMMON, "{} failed on {}", __func__, filename);
|
||||
return success;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto native_path = StringToPath(filename);
|
||||
std::error_code error;
|
||||
auto status = fs::status(native_path, error);
|
||||
|
||||
// Return true because we care about the file not being there, not the actual delete.
|
||||
if (!fs::exists(status))
|
||||
{
|
||||
if (behavior == IfAbsentBehavior::ConsoleWarning)
|
||||
{
|
||||
WARN_LOG_FMT(COMMON, "{}: {} does not exist", __func__, filename);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// fs::remove can only delete an empty directory. Legacy dolphin behavior is just to bail.
|
||||
if (fs::is_directory(status))
|
||||
{
|
||||
WARN_LOG_FMT(COMMON, "{} failed: {} is a directory", __func__, filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!fs::remove(native_path, error))
|
||||
{
|
||||
WARN_LOG_FMT(COMMON, "{}: failed on {}: {}", __func__, filename, error.message());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateDir(const std::string& path)
|
||||
{
|
||||
DEBUG_LOG_FMT(COMMON, "{}: directory {}", __func__, path);
|
||||
|
||||
std::error_code error;
|
||||
auto native_path = StringToPath(path);
|
||||
bool success = fs::create_directory(native_path, error);
|
||||
// If the path was not created, check if it was a pre-existing directory
|
||||
std::error_code error_ignored;
|
||||
if (!success && fs::is_directory(native_path, error_ignored))
|
||||
success = true;
|
||||
if (!success)
|
||||
ERROR_LOG_FMT(COMMON, "{}: failed on {}: {}", __func__, path, error.message());
|
||||
return success;
|
||||
}
|
||||
|
||||
bool CreateDirs(std::string_view path)
|
||||
{
|
||||
DEBUG_LOG_FMT(COMMON, "{}: directory {}", __func__, path);
|
||||
|
||||
std::error_code error;
|
||||
auto native_path = StringToPath(path);
|
||||
bool success = fs::create_directories(native_path, error);
|
||||
// If the path was not created, check if it was a pre-existing directory
|
||||
std::error_code error_ignored;
|
||||
if (!success && fs::is_directory(native_path, error_ignored))
|
||||
success = true;
|
||||
if (!success)
|
||||
ERROR_LOG_FMT(COMMON, "{}: failed on {}: {}", __func__, path, error.message());
|
||||
return success;
|
||||
}
|
||||
|
||||
bool CreateFullPath(std::string_view fullPath)
|
||||
{
|
||||
DEBUG_LOG_FMT(COMMON, "{}: path {}", __func__, fullPath);
|
||||
|
||||
std::error_code error;
|
||||
auto native_path = StringToPath(fullPath).parent_path();
|
||||
bool success = fs::create_directories(native_path, error);
|
||||
// If the path was not created, check if it was a pre-existing directory
|
||||
std::error_code error_ignored;
|
||||
if (!success && fs::is_directory(native_path, error_ignored))
|
||||
success = true;
|
||||
if (!success)
|
||||
ERROR_LOG_FMT(COMMON, "{}: failed on {}: {}", __func__, fullPath, error.message());
|
||||
return success;
|
||||
}
|
||||
|
||||
// Deletes a directory filename, returns true on success
|
||||
bool DeleteDir(const std::string& filename, IfAbsentBehavior behavior)
|
||||
{
|
||||
DEBUG_LOG_FMT(COMMON, "{}: directory {}", __func__, filename);
|
||||
|
||||
auto native_path = StringToPath(filename);
|
||||
std::error_code error;
|
||||
auto status = fs::status(native_path, error);
|
||||
|
||||
// Return true because we care about the directory not being there, not the actual delete.
|
||||
if (!fs::exists(status))
|
||||
{
|
||||
if (behavior == IfAbsentBehavior::ConsoleWarning)
|
||||
{
|
||||
WARN_LOG_FMT(COMMON, "{}: {} does not exist", __func__, filename);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// check if a directory
|
||||
if (!fs::is_directory(status))
|
||||
{
|
||||
ERROR_LOG_FMT(COMMON, "{}: Not a directory {}", __func__, filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!fs::remove(native_path, error))
|
||||
{
|
||||
WARN_LOG_FMT(COMMON, "{}: failed on {}: {}", __func__, filename, error.message());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// renames file srcFilename to destFilename, returns true on success
|
||||
bool Rename(const std::string& srcFilename, const std::string& destFilename)
|
||||
{
|
||||
DEBUG_LOG_FMT(COMMON, "{}: {} --> {}", __func__, srcFilename, destFilename);
|
||||
std::error_code error;
|
||||
std::filesystem::rename(StringToPath(srcFilename), StringToPath(destFilename), error);
|
||||
if (error)
|
||||
{
|
||||
ERROR_LOG_FMT(COMMON, "{} failed: {} --> {}: {}", __func__, srcFilename, destFilename,
|
||||
error.message());
|
||||
}
|
||||
return !error;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
static void FSyncPath(const char* path)
|
||||
{
|
||||
int fd = open(path, O_RDONLY);
|
||||
if (fd != -1)
|
||||
{
|
||||
fsync(fd);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool RenameSync(const std::string& srcFilename, const std::string& destFilename)
|
||||
{
|
||||
if (!Rename(srcFilename, destFilename))
|
||||
return false;
|
||||
#ifdef _WIN32
|
||||
int fd = -1;
|
||||
// XXX is this really needed?
|
||||
errno_t err = _wsopen_s(&fd, UTF8ToWString(srcFilename).c_str(), _O_RDONLY, _SH_DENYNO,
|
||||
_S_IREAD | _S_IWRITE);
|
||||
if (!err && fd >= 0)
|
||||
{
|
||||
if (_commit(fd) != 0)
|
||||
ERROR_LOG_FMT(COMMON, "{} sync failed on {}: {}", __func__, srcFilename, err);
|
||||
close(fd);
|
||||
}
|
||||
#else
|
||||
char* path = strdup(srcFilename.c_str());
|
||||
FSyncPath(path);
|
||||
FSyncPath(dirname(path));
|
||||
free(path);
|
||||
path = strdup(destFilename.c_str());
|
||||
FSyncPath(dirname(path));
|
||||
free(path);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CopyRegularFile(std::string_view source_path, std::string_view destination_path)
|
||||
{
|
||||
DEBUG_LOG_FMT(COMMON, "{}: {} --> {}", __func__, source_path, destination_path);
|
||||
|
||||
auto src_path = StringToPath(source_path);
|
||||
auto dst_path = StringToPath(destination_path);
|
||||
std::error_code error;
|
||||
bool copied = fs::copy_file(src_path, dst_path, fs::copy_options::overwrite_existing, error);
|
||||
if (!copied)
|
||||
{
|
||||
ERROR_LOG_FMT(COMMON, "{}: failed {} --> {}: {}", __func__, source_path, destination_path,
|
||||
error.message());
|
||||
}
|
||||
return copied;
|
||||
}
|
||||
|
||||
// Returns the size of a file (or returns 0 if the path isn't a file that exists)
|
||||
u64 GetSize(const std::string& path)
|
||||
{
|
||||
return FileInfo(path).GetSize();
|
||||
}
|
||||
|
||||
// Overloaded GetSize, accepts FILE*
|
||||
u64 GetSize(FILE* f)
|
||||
{
|
||||
// can't use off_t here because it can be 32-bit
|
||||
const u64 pos = ftello(f);
|
||||
if (fseeko(f, 0, SEEK_END) != 0)
|
||||
{
|
||||
ERROR_LOG_FMT(COMMON, "GetSize: seek failed {}: {}", fmt::ptr(f), LastStrerrorString());
|
||||
return 0;
|
||||
}
|
||||
|
||||
const u64 size = ftello(f);
|
||||
if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0))
|
||||
{
|
||||
ERROR_LOG_FMT(COMMON, "GetSize: seek failed {}: {}", fmt::ptr(f), LastStrerrorString());
|
||||
return 0;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
// creates an empty file filename, returns true on success
|
||||
bool CreateEmptyFile(const std::string& filename)
|
||||
{
|
||||
DEBUG_LOG_FMT(COMMON, "CreateEmptyFile: {}", filename);
|
||||
|
||||
if (!File::IOFile(filename, "wb"))
|
||||
{
|
||||
ERROR_LOG_FMT(COMMON, "CreateEmptyFile: failed {}: {}", filename, LastStrerrorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
static FSTEntry ScanDirectoryTreeAndroidContent(std::string directory, bool recursive)
|
||||
{
|
||||
FSTEntry parent_entry;
|
||||
parent_entry.physicalName = directory;
|
||||
parent_entry.isDirectory = true;
|
||||
parent_entry.size = 0;
|
||||
|
||||
for (const auto& child_name : GetAndroidContentChildNames(directory))
|
||||
{
|
||||
const auto physical_name = directory + DIR_SEP + child_name;
|
||||
const FileInfo file_info(physical_name);
|
||||
FSTEntry entry;
|
||||
|
||||
entry.isDirectory = file_info.IsDirectory();
|
||||
if (entry.isDirectory)
|
||||
{
|
||||
if (recursive)
|
||||
entry = ScanDirectoryTreeAndroidContent(physical_name, true);
|
||||
else
|
||||
entry.size = 0;
|
||||
parent_entry.size += entry.size;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.size = file_info.GetSize();
|
||||
}
|
||||
entry.virtualName = child_name;
|
||||
entry.physicalName = physical_name;
|
||||
|
||||
++parent_entry.size;
|
||||
parent_entry.children.push_back(entry);
|
||||
}
|
||||
|
||||
return parent_entry;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Recursive or non-recursive list of files and directories under directory.
|
||||
FSTEntry ScanDirectoryTree(std::string directory, bool recursive)
|
||||
{
|
||||
DEBUG_LOG_FMT(COMMON, "{}: directory {}", __func__, directory);
|
||||
|
||||
#ifdef ANDROID
|
||||
if (IsPathAndroidContent(directory))
|
||||
return ScanDirectoryTreeAndroidContent(directory, recursive);
|
||||
#endif
|
||||
|
||||
auto path_to_physical_name = [](const fs::path& path) {
|
||||
#ifdef _WIN32
|
||||
// TODO Ideally this would not be needed - dolphin really should not have code directly mucking
|
||||
// about with directory separators (for host paths - emulated paths may require it) and instead
|
||||
// use fs::path to interact with them.
|
||||
auto wpath = path.wstring();
|
||||
std::replace(wpath.begin(), wpath.end(), L'\\', L'/');
|
||||
return WStringToUTF8(wpath);
|
||||
#else
|
||||
return PathToString(path);
|
||||
#endif
|
||||
};
|
||||
|
||||
auto dirent_to_fstent = [&](const fs::directory_entry& entry) {
|
||||
return FSTEntry{
|
||||
.isDirectory = entry.is_directory(),
|
||||
.size = entry.is_directory() ? 0 : entry.file_size(),
|
||||
.physicalName = path_to_physical_name(entry.path()),
|
||||
.virtualName = PathToString(entry.path().filename()),
|
||||
};
|
||||
};
|
||||
|
||||
auto calc_dir_size = [](FSTEntry* dir) {
|
||||
dir->size += dir->children.size();
|
||||
for (auto& child : dir->children)
|
||||
if (child.isDirectory)
|
||||
dir->size += child.size;
|
||||
};
|
||||
|
||||
const auto directory_path = StringToPath(directory);
|
||||
|
||||
FSTEntry parent_entry;
|
||||
parent_entry.physicalName = path_to_physical_name(directory_path);
|
||||
parent_entry.isDirectory = fs::is_directory(directory_path);
|
||||
parent_entry.size = 0;
|
||||
|
||||
std::error_code error;
|
||||
if (recursive)
|
||||
{
|
||||
int prev_depth = 0;
|
||||
std::stack<FSTEntry*> dir_fsts;
|
||||
dir_fsts.push(&parent_entry);
|
||||
for (auto it = fs::recursive_directory_iterator(directory_path, error);
|
||||
it != fs::recursive_directory_iterator(); it.increment(error))
|
||||
{
|
||||
const int cur_depth = it.depth();
|
||||
if (cur_depth > prev_depth)
|
||||
{
|
||||
dir_fsts.push(&dir_fsts.top()->children.back());
|
||||
}
|
||||
else if (cur_depth < prev_depth)
|
||||
{
|
||||
while (dir_fsts.size() - 1 != cur_depth)
|
||||
{
|
||||
calc_dir_size(dir_fsts.top());
|
||||
dir_fsts.pop();
|
||||
}
|
||||
}
|
||||
dir_fsts.top()->children.emplace_back(dirent_to_fstent(*it));
|
||||
prev_depth = cur_depth;
|
||||
}
|
||||
while (dir_fsts.size())
|
||||
{
|
||||
calc_dir_size(dir_fsts.top());
|
||||
dir_fsts.pop();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto it = fs::directory_iterator(directory_path, error); it != fs::directory_iterator();
|
||||
it.increment(error))
|
||||
{
|
||||
parent_entry.children.emplace_back(dirent_to_fstent(*it));
|
||||
}
|
||||
calc_dir_size(&parent_entry);
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
// NOTE Possibly partial file list still returned
|
||||
ERROR_LOG_FMT(COMMON, "{} error on {}: {}", __func__, directory, error.message());
|
||||
}
|
||||
|
||||
return parent_entry;
|
||||
}
|
||||
|
||||
// Deletes the given directory and anything under it. Returns true on success.
|
||||
bool DeleteDirRecursively(const std::string& directory)
|
||||
{
|
||||
DEBUG_LOG_FMT(COMMON, "{}: {}", __func__, directory);
|
||||
|
||||
std::error_code error;
|
||||
const std::uintmax_t num_removed = std::filesystem::remove_all(StringToPath(directory), error);
|
||||
const bool success = num_removed != 0 && !error;
|
||||
if (!success)
|
||||
ERROR_LOG_FMT(COMMON, "{}: {} failed {}", __func__, directory, error.message());
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Copy(std::string_view source_path, std::string_view dest_path, bool overwrite_existing)
|
||||
{
|
||||
DEBUG_LOG_FMT(COMMON, "{}: {} --> {} ({})", __func__, source_path, dest_path,
|
||||
overwrite_existing ? "overwrite" : "preserve");
|
||||
|
||||
auto src_path = StringToPath(source_path);
|
||||
auto dst_path = StringToPath(dest_path);
|
||||
std::error_code error;
|
||||
auto options = fs::copy_options::recursive;
|
||||
if (overwrite_existing)
|
||||
options |= fs::copy_options::overwrite_existing;
|
||||
fs::copy(src_path, dst_path, options, error);
|
||||
if (error)
|
||||
{
|
||||
std::error_code error_ignored;
|
||||
if (fs::equivalent(src_path, dst_path, error_ignored))
|
||||
return true;
|
||||
|
||||
ERROR_LOG_FMT(COMMON, "{}: failed {} --> {} ({}): {}", __func__, source_path, dest_path,
|
||||
overwrite_existing ? "overwrite" : "preserve", error.message());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool MoveWithOverwrite(const std::filesystem::path& src, const std::filesystem::path& dst,
|
||||
std::error_code& error)
|
||||
{
|
||||
fs::rename(src, dst, error);
|
||||
if (!error)
|
||||
return true;
|
||||
|
||||
// rename failed, try fallbacks
|
||||
|
||||
if (!fs::is_directory(src))
|
||||
{
|
||||
// src is not a directory (ie, probably a file), try to copy file + delete
|
||||
if (!fs::copy_file(src, dst, fs::copy_options::overwrite_existing, error))
|
||||
return false;
|
||||
if (!fs::remove(src, error))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// src is a directory, recurse into it and try to move all sub-elements one by one
|
||||
// this usually happens because the target is a non-empty directory
|
||||
for (fs::directory_iterator it(src, error); it != fs::directory_iterator(); it.increment(error))
|
||||
{
|
||||
if (error)
|
||||
return false;
|
||||
if (!MoveWithOverwrite(it->path(), dst / it->path().filename(), error))
|
||||
return false;
|
||||
}
|
||||
if (error)
|
||||
return false;
|
||||
|
||||
// all sub-elements moved, remove top directory
|
||||
if (!fs::remove(src, error))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MoveWithOverwrite(std::string_view source_path, std::string_view dest_path)
|
||||
{
|
||||
DEBUG_LOG_FMT(COMMON, "{}: {} --> {}", __func__, source_path, dest_path);
|
||||
auto src_path = StringToPath(source_path);
|
||||
auto dst_path = StringToPath(dest_path);
|
||||
std::error_code error;
|
||||
if (!MoveWithOverwrite(src_path, dst_path, error))
|
||||
{
|
||||
ERROR_LOG_FMT(COMMON, "{}: failed {} --> {}: {}", __func__, source_path, dest_path,
|
||||
error.message());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns the current directory
|
||||
std::string GetCurrentDir()
|
||||
{
|
||||
std::error_code error;
|
||||
auto directory = PathToString(fs::current_path(error));
|
||||
if (error)
|
||||
{
|
||||
ERROR_LOG_FMT(COMMON, "{} failed: {}", __func__, error.message());
|
||||
return {};
|
||||
}
|
||||
return directory;
|
||||
}
|
||||
|
||||
// Sets the current directory to the given directory
|
||||
bool SetCurrentDir(const std::string& directory)
|
||||
{
|
||||
std::error_code error;
|
||||
fs::current_path(StringToPath(directory), error);
|
||||
if (error)
|
||||
{
|
||||
ERROR_LOG_FMT(COMMON, "{} failed: {}", __func__, error.message());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string CreateTempDir()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
TCHAR temp[MAX_PATH];
|
||||
if (!GetTempPath(MAX_PATH, temp))
|
||||
return "";
|
||||
|
||||
GUID guid;
|
||||
if (FAILED(CoCreateGuid(&guid)))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
OLECHAR tguid[40]{};
|
||||
if (!StringFromGUID2(guid, tguid, _countof(tguid)))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
std::string dir = TStrToUTF8(temp) + "/" + TStrToUTF8(tguid);
|
||||
if (!CreateDir(dir))
|
||||
return "";
|
||||
dir = ReplaceAll(dir, "\\", DIR_SEP);
|
||||
return dir;
|
||||
#else
|
||||
const char* base = getenv("TMPDIR") ?: "/tmp";
|
||||
std::string path = std::string(base) + "/DolphinWii.XXXXXX";
|
||||
if (!mkdtemp(&path[0]))
|
||||
return "";
|
||||
return path;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string GetTempFilenameForAtomicWrite(std::string path)
|
||||
{
|
||||
std::error_code error;
|
||||
auto absolute_path = fs::absolute(StringToPath(path), error);
|
||||
if (!error)
|
||||
path = PathToString(absolute_path);
|
||||
return std::move(path) + ".xxx";
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
std::string GetBundleDirectory()
|
||||
{
|
||||
//OpenEmu
|
||||
GET_CURRENT_OR_RETURN("");
|
||||
|
||||
return [current getBundlePath];
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string GetExePath()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
auto exe_path = GetModuleName(nullptr);
|
||||
if (!exe_path)
|
||||
return {};
|
||||
std::error_code error;
|
||||
auto exe_path_absolute = fs::absolute(exe_path.value(), error);
|
||||
if (error)
|
||||
return {};
|
||||
return PathToString(exe_path_absolute);
|
||||
#elif defined(__APPLE__)
|
||||
return GetBundleDirectory();
|
||||
#else
|
||||
char dolphin_exe_path[PATH_MAX];
|
||||
ssize_t len = ::readlink("/proc/self/exe", dolphin_exe_path, sizeof(dolphin_exe_path));
|
||||
if (len == -1 || len == sizeof(dolphin_exe_path))
|
||||
{
|
||||
len = 0;
|
||||
}
|
||||
dolphin_exe_path[len] = '\0';
|
||||
return dolphin_exe_path;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string GetExeDirectory()
|
||||
{
|
||||
return PathToString(StringToPath(GetExePath()).parent_path());
|
||||
}
|
||||
|
||||
static std::string CreateSysDirectoryPath()
|
||||
{
|
||||
#if defined(_WIN32) || defined(LINUX_LOCAL_DEV)
|
||||
#define SYSDATA_DIR "Sys"
|
||||
#elif defined __APPLE__
|
||||
//openemu
|
||||
#define SYSDATA_DIR "Sys"
|
||||
#else
|
||||
#ifdef DATA_DIR
|
||||
#define SYSDATA_DIR DATA_DIR "sys"
|
||||
#else
|
||||
#define SYSDATA_DIR "sys"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
const std::string sys_directory = GetBundleDirectory() + DIR_SEP SYSDATA_DIR DIR_SEP;
|
||||
#elif defined(_WIN32) || defined(LINUX_LOCAL_DEV)
|
||||
const std::string sys_directory = GetExeDirectory() + DIR_SEP SYSDATA_DIR DIR_SEP;
|
||||
#elif defined ANDROID
|
||||
const std::string sys_directory = s_android_sys_directory + DIR_SEP;
|
||||
ASSERT_MSG(COMMON, !s_android_sys_directory.empty(), "Sys directory has not been set");
|
||||
#else
|
||||
const std::string sys_directory = SYSDATA_DIR DIR_SEP;
|
||||
#endif
|
||||
|
||||
INFO_LOG_FMT(COMMON, "CreateSysDirectoryPath: Setting to {}", sys_directory);
|
||||
return sys_directory;
|
||||
}
|
||||
|
||||
const std::string& GetSysDirectory()
|
||||
{
|
||||
static const std::string sys_directory = CreateSysDirectoryPath();
|
||||
return sys_directory;
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
void SetSysDirectory(const std::string& path)
|
||||
{
|
||||
INFO_LOG_FMT(COMMON, "Setting Sys directory to {}", path);
|
||||
ASSERT_MSG(COMMON, s_android_sys_directory.empty(), "Sys directory already set to {}",
|
||||
s_android_sys_directory);
|
||||
s_android_sys_directory = path;
|
||||
}
|
||||
#endif
|
||||
|
||||
static std::string s_user_paths[NUM_PATH_INDICES];
|
||||
static void RebuildUserDirectories(unsigned int dir_index)
|
||||
{
|
||||
switch (dir_index)
|
||||
{
|
||||
case D_USER_IDX:
|
||||
s_user_paths[D_GCUSER_IDX] = s_user_paths[D_USER_IDX] + GC_USER_DIR DIR_SEP;
|
||||
s_user_paths[D_WIIROOT_IDX] = s_user_paths[D_USER_IDX] + WII_USER_DIR DIR_SEP;
|
||||
s_user_paths[D_CONFIG_IDX] = s_user_paths[D_USER_IDX] + CONFIG_DIR DIR_SEP;
|
||||
s_user_paths[D_GAMESETTINGS_IDX] = s_user_paths[D_USER_IDX] + GAMESETTINGS_DIR DIR_SEP;
|
||||
s_user_paths[D_MAPS_IDX] = s_user_paths[D_USER_IDX] + MAPS_DIR DIR_SEP;
|
||||
s_user_paths[D_CACHE_IDX] = s_user_paths[D_USER_IDX] + CACHE_DIR DIR_SEP;
|
||||
s_user_paths[D_COVERCACHE_IDX] = s_user_paths[D_CACHE_IDX] + COVERCACHE_DIR DIR_SEP;
|
||||
s_user_paths[D_REDUMPCACHE_IDX] = s_user_paths[D_CACHE_IDX] + REDUMPCACHE_DIR DIR_SEP;
|
||||
s_user_paths[D_SHADERCACHE_IDX] = s_user_paths[D_CACHE_IDX] + SHADERCACHE_DIR DIR_SEP;
|
||||
s_user_paths[D_SHADERS_IDX] = s_user_paths[D_USER_IDX] + SHADERS_DIR DIR_SEP;
|
||||
s_user_paths[D_STATESAVES_IDX] = s_user_paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP;
|
||||
s_user_paths[D_SCREENSHOTS_IDX] = s_user_paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP;
|
||||
s_user_paths[D_LOAD_IDX] = s_user_paths[D_USER_IDX] + LOAD_DIR DIR_SEP;
|
||||
s_user_paths[D_HIRESTEXTURES_IDX] = s_user_paths[D_LOAD_IDX] + HIRES_TEXTURES_DIR DIR_SEP;
|
||||
s_user_paths[D_RIIVOLUTION_IDX] = s_user_paths[D_LOAD_IDX] + RIIVOLUTION_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMP_IDX] = s_user_paths[D_USER_IDX] + DUMP_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMPFRAMES_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMPOBJECTS_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_OBJECTS_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMPAUDIO_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMPTEXTURES_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMPDSP_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_DSP_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMPSSL_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_SSL_DIR DIR_SEP;
|
||||
s_user_paths[D_LOGS_IDX] = s_user_paths[D_USER_IDX] + LOGS_DIR DIR_SEP;
|
||||
s_user_paths[D_MAILLOGS_IDX] = s_user_paths[D_LOGS_IDX] + MAIL_LOGS_DIR DIR_SEP;
|
||||
s_user_paths[D_THEMES_IDX] = s_user_paths[D_USER_IDX] + THEMES_DIR DIR_SEP;
|
||||
s_user_paths[D_STYLES_IDX] = s_user_paths[D_USER_IDX] + STYLES_DIR DIR_SEP;
|
||||
s_user_paths[D_PIPES_IDX] = s_user_paths[D_USER_IDX] + PIPES_DIR DIR_SEP;
|
||||
s_user_paths[D_WFSROOT_IDX] = s_user_paths[D_USER_IDX] + WFSROOT_DIR DIR_SEP;
|
||||
s_user_paths[D_BACKUP_IDX] = s_user_paths[D_USER_IDX] + BACKUP_DIR DIR_SEP;
|
||||
s_user_paths[D_RESOURCEPACK_IDX] = s_user_paths[D_USER_IDX] + RESOURCEPACK_DIR DIR_SEP;
|
||||
s_user_paths[D_DYNAMICINPUT_IDX] = s_user_paths[D_LOAD_IDX] + DYNAMICINPUT_DIR DIR_SEP;
|
||||
s_user_paths[D_GRAPHICSMOD_IDX] = s_user_paths[D_LOAD_IDX] + GRAPHICSMOD_DIR DIR_SEP;
|
||||
s_user_paths[D_WIISDCARDSYNCFOLDER_IDX] = s_user_paths[D_LOAD_IDX] + WIISDSYNC_DIR DIR_SEP;
|
||||
s_user_paths[F_DOLPHINCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + DOLPHIN_CONFIG;
|
||||
s_user_paths[F_GCPADCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + GCPAD_CONFIG;
|
||||
s_user_paths[F_WIIPADCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + WIIPAD_CONFIG;
|
||||
s_user_paths[F_GCKEYBOARDCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + GCKEYBOARD_CONFIG;
|
||||
s_user_paths[F_GFXCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + GFX_CONFIG;
|
||||
s_user_paths[F_DEBUGGERCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + DEBUGGER_CONFIG;
|
||||
s_user_paths[F_LOGGERCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + LOGGER_CONFIG;
|
||||
s_user_paths[F_DUALSHOCKUDPCLIENTCONFIG_IDX] =
|
||||
s_user_paths[D_CONFIG_IDX] + DUALSHOCKUDPCLIENT_CONFIG;
|
||||
s_user_paths[F_FREELOOKCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + FREELOOK_CONFIG;
|
||||
s_user_paths[F_MAINLOG_IDX] = s_user_paths[D_LOGS_IDX] + MAIN_LOG;
|
||||
s_user_paths[F_MEM1DUMP_IDX] = s_user_paths[D_DUMP_IDX] + MEM1_DUMP;
|
||||
s_user_paths[F_MEM2DUMP_IDX] = s_user_paths[D_DUMP_IDX] + MEM2_DUMP;
|
||||
s_user_paths[F_ARAMDUMP_IDX] = s_user_paths[D_DUMP_IDX] + ARAM_DUMP;
|
||||
s_user_paths[F_FAKEVMEMDUMP_IDX] = s_user_paths[D_DUMP_IDX] + FAKEVMEM_DUMP;
|
||||
s_user_paths[F_GCSRAM_IDX] = s_user_paths[D_GCUSER_IDX] + GC_SRAM;
|
||||
s_user_paths[F_WIISDCARDIMAGE_IDX] = s_user_paths[D_LOAD_IDX] + WII_SD_CARD_IMAGE;
|
||||
|
||||
s_user_paths[D_MEMORYWATCHER_IDX] = s_user_paths[D_USER_IDX] + MEMORYWATCHER_DIR DIR_SEP;
|
||||
s_user_paths[F_MEMORYWATCHERLOCATIONS_IDX] =
|
||||
s_user_paths[D_MEMORYWATCHER_IDX] + MEMORYWATCHER_LOCATIONS;
|
||||
s_user_paths[F_MEMORYWATCHERSOCKET_IDX] =
|
||||
s_user_paths[D_MEMORYWATCHER_IDX] + MEMORYWATCHER_SOCKET;
|
||||
|
||||
s_user_paths[D_GBAUSER_IDX] = s_user_paths[D_USER_IDX] + GBA_USER_DIR DIR_SEP;
|
||||
s_user_paths[D_GBASAVES_IDX] = s_user_paths[D_GBAUSER_IDX] + GBASAVES_DIR DIR_SEP;
|
||||
s_user_paths[F_GBABIOS_IDX] = s_user_paths[D_GBAUSER_IDX] + GBA_BIOS;
|
||||
|
||||
// The shader cache has moved to the cache directory, so remove the old one.
|
||||
// TODO: remove that someday.
|
||||
File::DeleteDirRecursively(s_user_paths[D_USER_IDX] + SHADERCACHE_LEGACY_DIR DIR_SEP);
|
||||
break;
|
||||
|
||||
case D_CONFIG_IDX:
|
||||
s_user_paths[F_DOLPHINCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + DOLPHIN_CONFIG;
|
||||
s_user_paths[F_GCPADCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + GCPAD_CONFIG;
|
||||
s_user_paths[F_GCKEYBOARDCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + GCKEYBOARD_CONFIG;
|
||||
s_user_paths[F_WIIPADCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + WIIPAD_CONFIG;
|
||||
s_user_paths[F_GFXCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + GFX_CONFIG;
|
||||
s_user_paths[F_DEBUGGERCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + DEBUGGER_CONFIG;
|
||||
s_user_paths[F_LOGGERCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + LOGGER_CONFIG;
|
||||
s_user_paths[F_DUALSHOCKUDPCLIENTCONFIG_IDX] =
|
||||
s_user_paths[D_CONFIG_IDX] + DUALSHOCKUDPCLIENT_CONFIG;
|
||||
s_user_paths[F_FREELOOKCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + FREELOOK_CONFIG;
|
||||
break;
|
||||
|
||||
case D_CACHE_IDX:
|
||||
s_user_paths[D_COVERCACHE_IDX] = s_user_paths[D_CACHE_IDX] + COVERCACHE_DIR DIR_SEP;
|
||||
s_user_paths[D_REDUMPCACHE_IDX] = s_user_paths[D_CACHE_IDX] + REDUMPCACHE_DIR DIR_SEP;
|
||||
s_user_paths[D_SHADERCACHE_IDX] = s_user_paths[D_CACHE_IDX] + SHADERCACHE_DIR DIR_SEP;
|
||||
break;
|
||||
|
||||
case D_GCUSER_IDX:
|
||||
s_user_paths[F_GCSRAM_IDX] = s_user_paths[D_GCUSER_IDX] + GC_SRAM;
|
||||
break;
|
||||
|
||||
case D_DUMP_IDX:
|
||||
s_user_paths[D_DUMPFRAMES_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMPOBJECTS_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_OBJECTS_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMPAUDIO_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMPTEXTURES_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMPDSP_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_DSP_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMPSSL_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_SSL_DIR DIR_SEP;
|
||||
s_user_paths[F_MEM1DUMP_IDX] = s_user_paths[D_DUMP_IDX] + MEM1_DUMP;
|
||||
s_user_paths[F_MEM2DUMP_IDX] = s_user_paths[D_DUMP_IDX] + MEM2_DUMP;
|
||||
s_user_paths[F_ARAMDUMP_IDX] = s_user_paths[D_DUMP_IDX] + ARAM_DUMP;
|
||||
s_user_paths[F_FAKEVMEMDUMP_IDX] = s_user_paths[D_DUMP_IDX] + FAKEVMEM_DUMP;
|
||||
break;
|
||||
|
||||
case D_LOGS_IDX:
|
||||
s_user_paths[D_MAILLOGS_IDX] = s_user_paths[D_LOGS_IDX] + MAIL_LOGS_DIR DIR_SEP;
|
||||
s_user_paths[F_MAINLOG_IDX] = s_user_paths[D_LOGS_IDX] + MAIN_LOG;
|
||||
break;
|
||||
|
||||
case D_LOAD_IDX:
|
||||
s_user_paths[D_HIRESTEXTURES_IDX] = s_user_paths[D_LOAD_IDX] + HIRES_TEXTURES_DIR DIR_SEP;
|
||||
s_user_paths[D_RIIVOLUTION_IDX] = s_user_paths[D_LOAD_IDX] + RIIVOLUTION_DIR DIR_SEP;
|
||||
s_user_paths[D_DYNAMICINPUT_IDX] = s_user_paths[D_LOAD_IDX] + DYNAMICINPUT_DIR DIR_SEP;
|
||||
s_user_paths[D_GRAPHICSMOD_IDX] = s_user_paths[D_LOAD_IDX] + GRAPHICSMOD_DIR DIR_SEP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Gets a set user directory path
|
||||
// Don't call prior to setting the base user directory
|
||||
const std::string& GetUserPath(unsigned int dir_index)
|
||||
{
|
||||
return s_user_paths[dir_index];
|
||||
}
|
||||
|
||||
// Sets a user directory path
|
||||
// Rebuilds internal directory structure to compensate for the new directory
|
||||
void SetUserPath(unsigned int dir_index, std::string path)
|
||||
{
|
||||
if (path.empty())
|
||||
return;
|
||||
|
||||
#ifdef _WIN32
|
||||
// On Windows, replace all '\' with '/' since we assume the latter in various places in the
|
||||
// codebase.
|
||||
for (char& c : path)
|
||||
{
|
||||
if (c == '\\')
|
||||
c = '/';
|
||||
}
|
||||
#endif
|
||||
|
||||
// Directories should end with a separator, files should not.
|
||||
while (path.ends_with('/'))
|
||||
path.pop_back();
|
||||
if (path.empty())
|
||||
return;
|
||||
const bool is_directory = dir_index < FIRST_FILE_USER_PATH_IDX;
|
||||
if (is_directory)
|
||||
path.push_back('/');
|
||||
|
||||
s_user_paths[dir_index] = std::move(path);
|
||||
RebuildUserDirectories(dir_index);
|
||||
}
|
||||
|
||||
std::string GetThemeDir(const std::string& theme_name)
|
||||
{
|
||||
std::string dir = File::GetUserPath(D_THEMES_IDX) + theme_name + "/";
|
||||
if (Exists(dir))
|
||||
return dir;
|
||||
|
||||
// If the theme doesn't exist in the user dir, load from shared directory
|
||||
dir = GetSysDirectory() + THEMES_DIR "/" + theme_name + "/";
|
||||
if (Exists(dir))
|
||||
return dir;
|
||||
|
||||
// If the theme doesn't exist at all, load the default theme
|
||||
return GetSysDirectory() + THEMES_DIR "/" DEFAULT_THEME_DIR "/";
|
||||
}
|
||||
|
||||
bool WriteStringToFile(const std::string& filename, std::string_view str)
|
||||
{
|
||||
return File::IOFile(filename, "wb").WriteBytes(str.data(), str.size());
|
||||
}
|
||||
|
||||
bool ReadFileToString(const std::string& filename, std::string& str)
|
||||
{
|
||||
File::IOFile file(filename, "rb");
|
||||
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
str.resize(file.GetSize());
|
||||
return file.ReadArray(str.data(), str.size());
|
||||
}
|
||||
|
||||
} // namespace File
|
||||
@@ -1,102 +0,0 @@
|
||||
// Copyright 2016 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
|
||||
#include "Common/Config/Config.h"
|
||||
#include "Common/Config/Layer.h"
|
||||
|
||||
namespace Config
|
||||
{
|
||||
ConfigLayerLoader::ConfigLayerLoader(LayerType layer) : m_layer(layer)
|
||||
{
|
||||
}
|
||||
|
||||
ConfigLayerLoader::~ConfigLayerLoader() = default;
|
||||
|
||||
LayerType ConfigLayerLoader::GetLayer() const
|
||||
{
|
||||
return m_layer;
|
||||
}
|
||||
|
||||
Layer::Layer(LayerType type) : m_layer(type)
|
||||
{
|
||||
}
|
||||
|
||||
Layer::Layer(std::unique_ptr<ConfigLayerLoader> loader)
|
||||
: m_layer(loader->GetLayer()), m_loader(std::move(loader))
|
||||
{
|
||||
Load();
|
||||
}
|
||||
|
||||
Layer::~Layer()
|
||||
{
|
||||
Save();
|
||||
}
|
||||
|
||||
bool Layer::Exists(const Location& location) const
|
||||
{
|
||||
const auto iter = m_map.find(location);
|
||||
return iter != m_map.end() && iter->second.has_value();
|
||||
}
|
||||
|
||||
bool Layer::DeleteKey(const Location& location)
|
||||
{
|
||||
m_is_dirty = true;
|
||||
bool had_value = false;
|
||||
const auto iter = m_map.find(location);
|
||||
if (iter != m_map.end() && iter->second.has_value())
|
||||
{
|
||||
iter->second.reset();
|
||||
had_value = true;
|
||||
}
|
||||
|
||||
return had_value;
|
||||
}
|
||||
|
||||
void Layer::DeleteAllKeys()
|
||||
{
|
||||
m_is_dirty = true;
|
||||
for (auto& pair : m_map)
|
||||
{
|
||||
pair.second.reset();
|
||||
}
|
||||
}
|
||||
|
||||
Section Layer::GetSection(System system, const std::string& section)
|
||||
{
|
||||
return Section{m_map.lower_bound(Location{system, section, ""}),
|
||||
m_map.lower_bound(Location{system, section + '\001', ""})};
|
||||
}
|
||||
|
||||
ConstSection Layer::GetSection(System system, const std::string& section) const
|
||||
{
|
||||
return ConstSection{m_map.lower_bound(Location{system, section, ""}),
|
||||
m_map.lower_bound(Location{system, section + '\001', ""})};
|
||||
}
|
||||
|
||||
void Layer::Load()
|
||||
{
|
||||
if (m_loader)
|
||||
m_loader->Load(this);
|
||||
m_is_dirty = false;
|
||||
}
|
||||
|
||||
void Layer::Save()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LayerType Layer::GetLayer() const
|
||||
{
|
||||
return m_layer;
|
||||
}
|
||||
|
||||
const LayerMap& Layer::GetLayerMap() const
|
||||
{
|
||||
return m_map;
|
||||
}
|
||||
} // namespace Config
|
||||
@@ -1,7 +0,0 @@
|
||||
// TODO: get values from git repo
|
||||
#define SCM_REV_STR "OEDolphin"
|
||||
#define SCM_DESC_STR "OEDolphin"
|
||||
#define SCM_BRANCH_STR "master"
|
||||
#define SCM_IS_MASTER 1
|
||||
#define SCM_DISTRIBUTOR_STR "Duckey77"
|
||||
#define SCM_UPDATE_TRACK_STR "none"
|
||||
@@ -1,405 +0,0 @@
|
||||
// Copyright 2008 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "Core/ConfigManager.h"
|
||||
|
||||
#include <cinttypes>
|
||||
#include <climits>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <variant>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "AudioCommon/AudioCommon.h"
|
||||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/CommonPaths.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Config/Config.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/IniFile.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Common/NandPaths.h"
|
||||
#include "Common/StringUtil.h"
|
||||
#include "Common/scmrev.h"
|
||||
|
||||
#include "Core/Boot/Boot.h"
|
||||
#include "Core/CommonTitles.h"
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/Config/SYSCONFSettings.h"
|
||||
#include "Core/ConfigLoaders/GameConfigLoader.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/FifoPlayer/FifoDataFile.h"
|
||||
#include "Core/HLE/HLE.h"
|
||||
#include "Core/HW/DVD/DVDInterface.h"
|
||||
#include "Core/HW/EXI/EXI_Device.h"
|
||||
#include "Core/HW/SI/SI.h"
|
||||
#include "Core/HW/SI/SI_Device.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Core/IOS/ES/ES.h"
|
||||
#include "Core/IOS/ES/Formats.h"
|
||||
#include "Core/PatchEngine.h"
|
||||
#include "Core/PowerPC/PPCSymbolDB.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
#include "Core/TitleDatabase.h"
|
||||
#include "VideoCommon/HiresTextures.h"
|
||||
|
||||
#include "DiscIO/Enums.h"
|
||||
#include "DiscIO/Volume.h"
|
||||
#include "DiscIO/VolumeWad.h"
|
||||
|
||||
SConfig* SConfig::m_Instance;
|
||||
|
||||
SConfig::SConfig()
|
||||
{
|
||||
LoadDefaults();
|
||||
// Make sure we have log manager
|
||||
LoadSettings();
|
||||
}
|
||||
|
||||
void SConfig::Init()
|
||||
{
|
||||
m_Instance = new SConfig;
|
||||
}
|
||||
|
||||
void SConfig::Shutdown()
|
||||
{
|
||||
delete m_Instance;
|
||||
m_Instance = nullptr;
|
||||
}
|
||||
|
||||
SConfig::~SConfig()
|
||||
{
|
||||
SaveSettings();
|
||||
}
|
||||
|
||||
void SConfig::SaveSettings()
|
||||
{
|
||||
NOTICE_LOG_FMT(BOOT, "Saving settings to {}", File::GetUserPath(F_DOLPHINCONFIG_IDX));
|
||||
Config::Save();
|
||||
}
|
||||
|
||||
void SConfig::LoadSettings()
|
||||
{
|
||||
INFO_LOG_FMT(BOOT, "Loading Settings from {}", File::GetUserPath(F_DOLPHINCONFIG_IDX));
|
||||
Config::Load();
|
||||
}
|
||||
|
||||
void SConfig::ResetRunningGameMetadata()
|
||||
{
|
||||
SetRunningGameMetadata("00000000", "", 0, 0, DiscIO::Region::Unknown);
|
||||
}
|
||||
|
||||
void SConfig::SetRunningGameMetadata(const DiscIO::Volume& volume,
|
||||
const DiscIO::Partition& partition)
|
||||
{
|
||||
if (partition == volume.GetGamePartition())
|
||||
{
|
||||
SetRunningGameMetadata(volume.GetGameID(), volume.GetGameTDBID(),
|
||||
volume.GetTitleID().value_or(0), volume.GetRevision().value_or(0),
|
||||
volume.GetRegion());
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRunningGameMetadata(volume.GetGameID(partition), volume.GetGameTDBID(),
|
||||
volume.GetTitleID(partition).value_or(0),
|
||||
volume.GetRevision(partition).value_or(0), volume.GetRegion());
|
||||
}
|
||||
}
|
||||
|
||||
void SConfig::SetRunningGameMetadata(const IOS::ES::TMDReader& tmd, DiscIO::Platform platform)
|
||||
{
|
||||
const u64 tmd_title_id = tmd.GetTitleId();
|
||||
|
||||
// If we're launching a disc game, we want to read the revision from
|
||||
// the disc header instead of the TMD. They can differ.
|
||||
// (IOS HLE ES calls us with a TMDReader rather than a volume when launching
|
||||
// a disc game, because ES has no reason to be accessing the disc directly.)
|
||||
if (platform == DiscIO::Platform::WiiWAD ||
|
||||
!DVDInterface::UpdateRunningGameMetadata(tmd_title_id))
|
||||
{
|
||||
// If not launching a disc game, just read everything from the TMD.
|
||||
SetRunningGameMetadata(tmd.GetGameID(), tmd.GetGameTDBID(), tmd_title_id, tmd.GetTitleVersion(),
|
||||
tmd.GetRegion());
|
||||
}
|
||||
}
|
||||
|
||||
void SConfig::SetRunningGameMetadata(const std::string& game_id, const std::string& gametdb_id,
|
||||
u64 title_id, u16 revision, DiscIO::Region region)
|
||||
{
|
||||
const bool was_changed = m_game_id != game_id || m_gametdb_id != gametdb_id ||
|
||||
m_title_id != title_id || m_revision != revision;
|
||||
m_game_id = game_id;
|
||||
m_gametdb_id = gametdb_id;
|
||||
m_title_id = title_id;
|
||||
m_revision = revision;
|
||||
|
||||
if (game_id.length() == 6)
|
||||
{
|
||||
m_debugger_game_id = game_id;
|
||||
}
|
||||
else if (title_id != 0)
|
||||
{
|
||||
m_debugger_game_id =
|
||||
fmt::format("{:08X}_{:08X}", static_cast<u32>(title_id >> 32), static_cast<u32>(title_id));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_debugger_game_id.clear();
|
||||
}
|
||||
|
||||
if (!was_changed)
|
||||
return;
|
||||
|
||||
if (game_id == "00000000")
|
||||
{
|
||||
m_title_name.clear();
|
||||
m_title_description.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
const Core::TitleDatabase title_database;
|
||||
const DiscIO::Language language = GetLanguageAdjustedForRegion(bWii, region);
|
||||
m_title_name = title_database.GetTitleName(m_gametdb_id, language);
|
||||
m_title_description = title_database.Describe(m_gametdb_id, language);
|
||||
NOTICE_LOG_FMT(CORE, "Active title: {}", m_title_description);
|
||||
Host_TitleChanged();
|
||||
if (Core::IsRunning())
|
||||
{
|
||||
Core::UpdateTitle();
|
||||
}
|
||||
|
||||
Config::AddLayer(ConfigLoaders::GenerateGlobalGameConfigLoader(game_id, revision));
|
||||
Config::AddLayer(ConfigLoaders::GenerateLocalGameConfigLoader(game_id, revision));
|
||||
}
|
||||
|
||||
void SConfig::LoadDefaults()
|
||||
{
|
||||
bAutomaticStart = false;
|
||||
bBootToPause = false;
|
||||
|
||||
bWii = false;
|
||||
|
||||
ResetRunningGameMetadata();
|
||||
}
|
||||
|
||||
struct SetGameMetadata
|
||||
{
|
||||
SetGameMetadata(SConfig* config_, DiscIO::Region* region_) : config(config_), region(region_) {}
|
||||
bool operator()(const BootParameters::Disc& disc) const
|
||||
{
|
||||
*region = disc.volume->GetRegion();
|
||||
config->bWii = disc.volume->GetVolumeType() == DiscIO::Platform::WiiDisc;
|
||||
config->m_disc_booted_from_game_list = true;
|
||||
config->SetRunningGameMetadata(*disc.volume, disc.volume->GetGamePartition());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator()(const BootParameters::Executable& executable) const
|
||||
{
|
||||
if (!executable.reader->IsValid())
|
||||
return false;
|
||||
|
||||
*region = DiscIO::Region::Unknown;
|
||||
config->bWii = executable.reader->IsWii();
|
||||
|
||||
// Strip the .elf/.dol file extension and directories before the name
|
||||
SplitPath(executable.path, nullptr, &config->m_debugger_game_id, nullptr);
|
||||
|
||||
Host_TitleChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator()(const DiscIO::VolumeWAD& wad) const
|
||||
{
|
||||
if (!wad.GetTMD().IsValid())
|
||||
{
|
||||
PanicAlertFmtT("This WAD is not valid.");
|
||||
return false;
|
||||
}
|
||||
if (!IOS::ES::IsChannel(wad.GetTMD().GetTitleId()))
|
||||
{
|
||||
PanicAlertFmtT("This WAD is not bootable.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const IOS::ES::TMDReader& tmd = wad.GetTMD();
|
||||
*region = tmd.GetRegion();
|
||||
config->bWii = true;
|
||||
config->SetRunningGameMetadata(tmd, DiscIO::Platform::WiiWAD);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator()(const BootParameters::NANDTitle& nand_title) const
|
||||
{
|
||||
IOS::HLE::Kernel ios;
|
||||
const IOS::ES::TMDReader tmd = ios.GetES()->FindInstalledTMD(nand_title.id);
|
||||
if (!tmd.IsValid() || !IOS::ES::IsChannel(nand_title.id))
|
||||
{
|
||||
PanicAlertFmtT("This title cannot be booted.");
|
||||
return false;
|
||||
}
|
||||
|
||||
*region = tmd.GetRegion();
|
||||
config->bWii = true;
|
||||
config->SetRunningGameMetadata(tmd, DiscIO::Platform::WiiWAD);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator()(const BootParameters::IPL& ipl) const
|
||||
{
|
||||
*region = ipl.region;
|
||||
config->bWii = false;
|
||||
Host_TitleChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator()(const BootParameters::DFF& dff) const
|
||||
{
|
||||
std::unique_ptr<FifoDataFile> dff_file(FifoDataFile::Load(dff.dff_path, true));
|
||||
if (!dff_file)
|
||||
return false;
|
||||
|
||||
*region = DiscIO::Region::NTSC_U;
|
||||
config->bWii = dff_file->GetIsWii();
|
||||
Host_TitleChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
SConfig* config;
|
||||
DiscIO::Region* region;
|
||||
};
|
||||
|
||||
bool SConfig::SetPathsAndGameMetadata(const BootParameters& boot)
|
||||
{
|
||||
m_is_mios = false;
|
||||
m_disc_booted_from_game_list = false;
|
||||
if (!std::visit(SetGameMetadata(this, &m_region), boot.parameters))
|
||||
return false;
|
||||
|
||||
if (m_region == DiscIO::Region::Unknown)
|
||||
m_region = Config::Get(Config::MAIN_FALLBACK_REGION);
|
||||
|
||||
// Set up paths
|
||||
const std::string region_dir = Config::GetDirectoryForRegion(Config::ToGameCubeRegion(m_region));
|
||||
m_strSRAM = File::GetUserPath(F_GCSRAM_IDX);
|
||||
m_strBootROM = Config::GetBootROMPath(region_dir);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DiscIO::Language SConfig::GetCurrentLanguage(bool wii) const
|
||||
{
|
||||
DiscIO::Language language;
|
||||
if (wii)
|
||||
language = static_cast<DiscIO::Language>(Config::Get(Config::SYSCONF_LANGUAGE));
|
||||
else
|
||||
language = DiscIO::FromGameCubeLanguage(Config::Get(Config::MAIN_GC_LANGUAGE));
|
||||
|
||||
// Get rid of invalid values (probably doesn't matter, but might as well do it)
|
||||
if (language > DiscIO::Language::Unknown || language < DiscIO::Language::Japanese)
|
||||
language = DiscIO::Language::Unknown;
|
||||
return language;
|
||||
}
|
||||
|
||||
DiscIO::Language SConfig::GetLanguageAdjustedForRegion(bool wii, DiscIO::Region region) const
|
||||
{
|
||||
const DiscIO::Language language = GetCurrentLanguage(wii);
|
||||
|
||||
if (!wii && region == DiscIO::Region::NTSC_K)
|
||||
region = DiscIO::Region::NTSC_J; // NTSC-K only exists on Wii, so use a fallback
|
||||
|
||||
if (!wii && region == DiscIO::Region::NTSC_J && language == DiscIO::Language::English)
|
||||
return DiscIO::Language::Japanese; // English and Japanese both use the value 0 in GC SRAM
|
||||
|
||||
if (!Config::Get(Config::MAIN_OVERRIDE_REGION_SETTINGS))
|
||||
{
|
||||
if (region == DiscIO::Region::NTSC_J)
|
||||
return DiscIO::Language::Japanese;
|
||||
|
||||
if (region == DiscIO::Region::NTSC_U && language != DiscIO::Language::English &&
|
||||
(!wii || (language != DiscIO::Language::French && language != DiscIO::Language::Spanish)))
|
||||
{
|
||||
return DiscIO::Language::English;
|
||||
}
|
||||
|
||||
if (region == DiscIO::Region::PAL &&
|
||||
(language < DiscIO::Language::English || language > DiscIO::Language::Dutch))
|
||||
{
|
||||
return DiscIO::Language::English;
|
||||
}
|
||||
|
||||
if (region == DiscIO::Region::NTSC_K)
|
||||
return DiscIO::Language::Korean;
|
||||
}
|
||||
|
||||
return language;
|
||||
}
|
||||
|
||||
IniFile SConfig::LoadDefaultGameIni() const
|
||||
{
|
||||
return LoadDefaultGameIni(GetGameID(), m_revision);
|
||||
}
|
||||
|
||||
IniFile SConfig::LoadLocalGameIni() const
|
||||
{
|
||||
return LoadLocalGameIni(GetGameID(), m_revision);
|
||||
}
|
||||
|
||||
IniFile SConfig::LoadGameIni() const
|
||||
{
|
||||
return LoadGameIni(GetGameID(), m_revision);
|
||||
}
|
||||
|
||||
IniFile SConfig::LoadDefaultGameIni(const std::string& id, std::optional<u16> revision)
|
||||
{
|
||||
IniFile game_ini;
|
||||
for (const std::string& filename : ConfigLoaders::GetGameIniFilenames(id, revision))
|
||||
game_ini.Load(File::GetSysDirectory() + GAMESETTINGS_DIR DIR_SEP + filename, true);
|
||||
return game_ini;
|
||||
}
|
||||
|
||||
IniFile SConfig::LoadLocalGameIni(const std::string& id, std::optional<u16> revision)
|
||||
{
|
||||
IniFile game_ini;
|
||||
for (const std::string& filename : ConfigLoaders::GetGameIniFilenames(id, revision))
|
||||
game_ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + filename, true);
|
||||
return game_ini;
|
||||
}
|
||||
|
||||
IniFile SConfig::LoadGameIni(const std::string& id, std::optional<u16> revision)
|
||||
{
|
||||
IniFile game_ini;
|
||||
for (const std::string& filename : ConfigLoaders::GetGameIniFilenames(id, revision))
|
||||
game_ini.Load(File::GetSysDirectory() + GAMESETTINGS_DIR DIR_SEP + filename, true);
|
||||
for (const std::string& filename : ConfigLoaders::GetGameIniFilenames(id, revision))
|
||||
game_ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + filename, true);
|
||||
return game_ini;
|
||||
}
|
||||
|
||||
void SConfig::OnNewTitleLoad(const Core::CPUThreadGuard &guard)
|
||||
{
|
||||
if (!Core::IsRunning())
|
||||
return;
|
||||
|
||||
if (!g_symbolDB.IsEmpty())
|
||||
{
|
||||
g_symbolDB.Clear();
|
||||
Host_NotifyMapLoaded();
|
||||
}
|
||||
CBoot::LoadMapFromFilename(guard);
|
||||
HLE::Reload(Core::System::GetInstance());
|
||||
PatchEngine::Reload();
|
||||
HiresTexture::Update();
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "Core/Config/GraphicsSettings.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Common/Config/Config.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
namespace Config
|
||||
{
|
||||
// Configuration Information
|
||||
|
||||
// Graphics.Hardware
|
||||
|
||||
const Info<bool> GFX_VSYNC{{System::GFX, "Hardware", "VSync"}, false};
|
||||
const Info<int> GFX_ADAPTER{{System::GFX, "Hardware", "Adapter"}, 0};
|
||||
|
||||
// Graphics.Settings
|
||||
|
||||
const Info<bool> GFX_WIDESCREEN_HACK{{System::GFX, "Settings", "wideScreenHack"}, false};
|
||||
//OpenEmu change apect to stretch
|
||||
const Info<AspectMode> GFX_ASPECT_RATIO{{System::GFX, "Settings", "AspectRatio"}, AspectMode::Stretch};
|
||||
const Info<AspectMode> GFX_SUGGESTED_ASPECT_RATIO{{System::GFX, "Settings", "SuggestedAspectRatio"},
|
||||
AspectMode::Auto};
|
||||
const Info<bool> GFX_CROP{{System::GFX, "Settings", "Crop"}, false};
|
||||
const Info<int> GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES{
|
||||
{System::GFX, "Settings", "SafeTextureCacheColorSamples"}, 128};
|
||||
const Info<bool> GFX_SHOW_FPS{{System::GFX, "Settings", "ShowFPS"}, false};
|
||||
const Info<bool> GFX_SHOW_NETPLAY_PING{{System::GFX, "Settings", "ShowNetPlayPing"}, false};
|
||||
const Info<bool> GFX_SHOW_NETPLAY_MESSAGES{{System::GFX, "Settings", "ShowNetPlayMessages"}, false};
|
||||
const Info<bool> GFX_LOG_RENDER_TIME_TO_FILE{{System::GFX, "Settings", "LogRenderTimeToFile"},
|
||||
false};
|
||||
const Info<bool> GFX_OVERLAY_STATS{{System::GFX, "Settings", "OverlayStats"}, false};
|
||||
const Info<bool> GFX_OVERLAY_PROJ_STATS{{System::GFX, "Settings", "OverlayProjStats"}, false};
|
||||
const Info<bool> GFX_DUMP_TEXTURES{{System::GFX, "Settings", "DumpTextures"}, false};
|
||||
const Info<bool> GFX_DUMP_MIP_TEXTURES{{System::GFX, "Settings", "DumpMipTextures"}, true};
|
||||
const Info<bool> GFX_DUMP_BASE_TEXTURES{{System::GFX, "Settings", "DumpBaseTextures"}, true};
|
||||
const Info<bool> GFX_HIRES_TEXTURES{{System::GFX, "Settings", "HiresTextures"}, false};
|
||||
const Info<bool> GFX_CACHE_HIRES_TEXTURES{{System::GFX, "Settings", "CacheHiresTextures"}, 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_FRAMES_AS_IMAGES{{System::GFX, "Settings", "DumpFramesAsImages"}, false};
|
||||
const Info<bool> GFX_USE_FFV1{{System::GFX, "Settings", "UseFFV1"}, false};
|
||||
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_ENCODER{{System::GFX, "Settings", "DumpEncoder"}, ""};
|
||||
const Info<std::string> GFX_DUMP_PATH{{System::GFX, "Settings", "DumpPath"}, ""};
|
||||
const Info<int> GFX_BITRATE_KBPS{{System::GFX, "Settings", "BitrateKbps"}, 25000};
|
||||
const Info<bool> GFX_INTERNAL_RESOLUTION_FRAME_DUMPS{
|
||||
{System::GFX, "Settings", "InternalResolutionFrameDumps"}, false};
|
||||
const Info<bool> GFX_ENABLE_GPU_TEXTURE_DECODING{
|
||||
{System::GFX, "Settings", "EnableGPUTextureDecoding"}, false};
|
||||
const Info<bool> GFX_ENABLE_PIXEL_LIGHTING{{System::GFX, "Settings", "EnablePixelLighting"}, false};
|
||||
const Info<bool> GFX_FAST_DEPTH_CALC{{System::GFX, "Settings", "FastDepthCalc"}, true};
|
||||
const Info<u32> GFX_MSAA{{System::GFX, "Settings", "MSAA"}, 1};
|
||||
const Info<bool> GFX_SSAA{{System::GFX, "Settings", "SSAA"}, false};
|
||||
const Info<int> GFX_EFB_SCALE{{System::GFX, "Settings", "InternalResolution"}, 1};
|
||||
const Info<int> GFX_MAX_EFB_SCALE{{System::GFX, "Settings", "MaxInternalResolution"}, 8};
|
||||
const Info<bool> GFX_TEXFMT_OVERLAY_ENABLE{{System::GFX, "Settings", "TexFmtOverlayEnable"}, false};
|
||||
const Info<bool> GFX_TEXFMT_OVERLAY_CENTER{{System::GFX, "Settings", "TexFmtOverlayCenter"}, false};
|
||||
const Info<bool> GFX_ENABLE_WIREFRAME{{System::GFX, "Settings", "WireFrame"}, false};
|
||||
const Info<bool> GFX_DISABLE_FOG{{System::GFX, "Settings", "DisableFog"}, false};
|
||||
const Info<bool> GFX_BORDERLESS_FULLSCREEN{{System::GFX, "Settings", "BorderlessFullscreen"},
|
||||
false};
|
||||
const Info<bool> GFX_ENABLE_VALIDATION_LAYER{{System::GFX, "Settings", "EnableValidationLayer"},
|
||||
false};
|
||||
|
||||
#if defined(ANDROID)
|
||||
const Info<bool> GFX_BACKEND_MULTITHREADING{{System::GFX, "Settings", "BackendMultithreading"},
|
||||
false};
|
||||
const Info<int> GFX_COMMAND_BUFFER_EXECUTE_INTERVAL{
|
||||
{System::GFX, "Settings", "CommandBufferExecuteInterval"}, 0};
|
||||
#else
|
||||
const Info<bool> GFX_BACKEND_MULTITHREADING{{System::GFX, "Settings", "BackendMultithreading"},
|
||||
true};
|
||||
const Info<int> GFX_COMMAND_BUFFER_EXECUTE_INTERVAL{
|
||||
{System::GFX, "Settings", "CommandBufferExecuteInterval"}, 100};
|
||||
#endif
|
||||
|
||||
//////OpenEmu change ShaderCache True, WaitForShaders false, Compiler and Precompiler thread -1
|
||||
const Info<bool> GFX_SHADER_CACHE{{System::GFX, "Settings", "ShaderCache"}, true};
|
||||
const Info<bool> GFX_WAIT_FOR_SHADERS_BEFORE_STARTING{
|
||||
{System::GFX, "Settings", "WaitForShadersBeforeStarting"}, false};
|
||||
const Info<ShaderCompilationMode> GFX_SHADER_COMPILATION_MODE{
|
||||
{System::GFX, "Settings", "ShaderCompilationMode"}, ShaderCompilationMode::Synchronous};
|
||||
const Info<int> GFX_SHADER_COMPILER_THREADS{{System::GFX, "Settings", "ShaderCompilerThreads"}, -1};
|
||||
const Info<int> GFX_SHADER_PRECOMPILER_THREADS{
|
||||
{System::GFX, "Settings", "ShaderPrecompilerThreads"}, -1};
|
||||
const Info<bool> GFX_SAVE_TEXTURE_CACHE_TO_STATE{
|
||||
{System::GFX, "Settings", "SaveTextureCacheToState"}, true};
|
||||
|
||||
const Info<bool> GFX_SW_ZCOMPLOC{{System::GFX, "Settings", "SWZComploc"}, true};
|
||||
const Info<bool> GFX_SW_ZFREEZE{{System::GFX, "Settings", "SWZFreeze"}, true};
|
||||
const Info<bool> GFX_SW_DUMP_OBJECTS{{System::GFX, "Settings", "SWDumpObjects"}, false};
|
||||
const Info<bool> GFX_SW_DUMP_TEV_STAGES{{System::GFX, "Settings", "SWDumpTevStages"}, false};
|
||||
const Info<bool> GFX_SW_DUMP_TEV_TEX_FETCHES{{System::GFX, "Settings", "SWDumpTevTexFetches"},
|
||||
false};
|
||||
const Info<int> GFX_SW_DRAW_START{{System::GFX, "Settings", "SWDrawStart"}, 0};
|
||||
const Info<int> GFX_SW_DRAW_END{{System::GFX, "Settings", "SWDrawEnd"}, 100000};
|
||||
|
||||
const Info<bool> GFX_PREFER_GLES{{System::GFX, "Settings", "PreferGLES"}, false};
|
||||
|
||||
// Graphics.Enhancements
|
||||
|
||||
const Info<bool> GFX_ENHANCE_FORCE_FILTERING{{System::GFX, "Enhancements", "ForceFiltering"},
|
||||
false};
|
||||
const Info<int> GFX_ENHANCE_MAX_ANISOTROPY{{System::GFX, "Enhancements", "MaxAnisotropy"}, 0};
|
||||
const Info<std::string> GFX_ENHANCE_POST_SHADER{
|
||||
{System::GFX, "Enhancements", "PostProcessingShader"}, ""};
|
||||
const Info<bool> GFX_ENHANCE_FORCE_TRUE_COLOR{{System::GFX, "Enhancements", "ForceTrueColor"},
|
||||
true};
|
||||
const Info<bool> GFX_ENHANCE_DISABLE_COPY_FILTER{{System::GFX, "Enhancements", "DisableCopyFilter"},
|
||||
true};
|
||||
const Info<bool> GFX_ENHANCE_ARBITRARY_MIPMAP_DETECTION{
|
||||
{System::GFX, "Enhancements", "ArbitraryMipmapDetection"}, true};
|
||||
const Info<float> GFX_ENHANCE_ARBITRARY_MIPMAP_DETECTION_THRESHOLD{
|
||||
{System::GFX, "Enhancements", "ArbitraryMipmapDetectionThreshold"}, 14.0f};
|
||||
|
||||
// Graphics.Stereoscopy
|
||||
|
||||
const Info<StereoMode> GFX_STEREO_MODE{{System::GFX, "Stereoscopy", "StereoMode"}, StereoMode::Off};
|
||||
const Info<int> GFX_STEREO_DEPTH{{System::GFX, "Stereoscopy", "StereoDepth"}, 20};
|
||||
const Info<int> GFX_STEREO_CONVERGENCE_PERCENTAGE{
|
||||
{System::GFX, "Stereoscopy", "StereoConvergencePercentage"}, 100};
|
||||
const Info<bool> GFX_STEREO_SWAP_EYES{{System::GFX, "Stereoscopy", "StereoSwapEyes"}, false};
|
||||
const Info<int> GFX_STEREO_CONVERGENCE{{System::GFX, "Stereoscopy", "StereoConvergence"}, 20};
|
||||
const Info<bool> GFX_STEREO_EFB_MONO_DEPTH{{System::GFX, "Stereoscopy", "StereoEFBMonoDepth"},
|
||||
false};
|
||||
const Info<int> GFX_STEREO_DEPTH_PERCENTAGE{{System::GFX, "Stereoscopy", "StereoDepthPercentage"},
|
||||
100};
|
||||
|
||||
// Graphics.Hacks
|
||||
|
||||
const Info<bool> GFX_HACK_EFB_ACCESS_ENABLE{{System::GFX, "Hacks", "EFBAccessEnable"}, true};
|
||||
const Info<bool> GFX_HACK_EFB_DEFER_INVALIDATION{
|
||||
{System::GFX, "Hacks", "EFBAccessDeferInvalidation"}, false};
|
||||
const Info<int> GFX_HACK_EFB_ACCESS_TILE_SIZE{{System::GFX, "Hacks", "EFBAccessTileSize"}, 64};
|
||||
const Info<bool> GFX_HACK_BBOX_ENABLE{{System::GFX, "Hacks", "BBoxEnable"}, false};
|
||||
const Info<bool> GFX_HACK_FORCE_PROGRESSIVE{{System::GFX, "Hacks", "ForceProgressive"}, true};
|
||||
const Info<bool> GFX_HACK_SKIP_EFB_COPY_TO_RAM{{System::GFX, "Hacks", "EFBToTextureEnable"}, true};
|
||||
const Info<bool> GFX_HACK_SKIP_XFB_COPY_TO_RAM{{System::GFX, "Hacks", "XFBToTextureEnable"}, true};
|
||||
const Info<bool> GFX_HACK_DISABLE_COPY_TO_VRAM{{System::GFX, "Hacks", "DisableCopyToVRAM"}, false};
|
||||
const Info<bool> GFX_HACK_DEFER_EFB_COPIES{{System::GFX, "Hacks", "DeferEFBCopies"}, true};
|
||||
const Info<bool> GFX_HACK_IMMEDIATE_XFB{{System::GFX, "Hacks", "ImmediateXFBEnable"}, false};
|
||||
const Info<bool> GFX_HACK_SKIP_DUPLICATE_XFBS{{System::GFX, "Hacks", "SkipDuplicateXFBs"}, true};
|
||||
const Info<bool> GFX_HACK_COPY_EFB_SCALED{{System::GFX, "Hacks", "EFBScaledCopy"}, true};
|
||||
const Info<bool> GFX_HACK_EFB_EMULATE_FORMAT_CHANGES{
|
||||
{System::GFX, "Hacks", "EFBEmulateFormatChanges"}, false};
|
||||
const Info<bool> GFX_HACK_VERTEX_ROUDING{{System::GFX, "Hacks", "VertexRounding"}, false};
|
||||
|
||||
// Graphics.GameSpecific
|
||||
|
||||
const Info<bool> GFX_PERF_QUERIES_ENABLE{{System::GFX, "GameSpecific", "PerfQueriesEnable"}, false};
|
||||
} // namespace Config
|
||||
@@ -1,59 +0,0 @@
|
||||
// Copyright (c) 2022, OpenEmu Team
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the OpenEmu Team nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY OpenEmu Team ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL OpenEmu Team BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifdef __x86_64__
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/Jit64/Jit.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/Jit64/Jit_Branch.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/Jit64/Jit_FloatingPoint.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/Jit64/Jit_LoadStoreFloating.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/Jit64/Jit_LoadStorePaired.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/Jit64/Jit_Paired.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/Jit64Common/BlockCache.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/Jit64Common/ConstantPool.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/Jit64Common/FarCodeCache.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/Jit64Common/TrampolineCache.cpp"
|
||||
#elif defined(__arm64__)
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/JitArm64/Jit_Util.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/JitArm64/Jit.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/JitArm64/JitArm64_Branch.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStorePaired.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/JitArm64/JitArm64_Paired.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/JitArm64/JitArm64Cache.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp"
|
||||
#include "../../dolphin/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp"
|
||||
#endif
|
||||
@@ -1,341 +0,0 @@
|
||||
// Copyright 2010 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||
|
||||
//OpenEmu undefine the OSX settings
|
||||
#ifdef CIFACE_USE_OSX
|
||||
#undef CIFACE_USE_OSX
|
||||
#endif
|
||||
|
||||
//OpenEmu include OE input header
|
||||
#include "OpenEmuInput.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Core/HW/WiimoteReal/WiimoteReal.h"
|
||||
|
||||
#ifdef CIFACE_USE_WIN32
|
||||
#include "InputCommon/ControllerInterface/Win32/Win32.h"
|
||||
#endif
|
||||
#ifdef CIFACE_USE_XLIB
|
||||
#include "InputCommon/ControllerInterface/Xlib/XInput2.h"
|
||||
#endif
|
||||
#ifdef CIFACE_USE_OSX
|
||||
#include "InputCommon/ControllerInterface/OSX/OSX.h"
|
||||
#include "InputCommon/ControllerInterface/Quartz/Quartz.h"
|
||||
#endif
|
||||
#ifdef CIFACE_USE_SDL
|
||||
#include "InputCommon/ControllerInterface/SDL/SDL.h"
|
||||
#endif
|
||||
#ifdef CIFACE_USE_ANDROID
|
||||
#include "InputCommon/ControllerInterface/Android/Android.h"
|
||||
#endif
|
||||
#ifdef CIFACE_USE_EVDEV
|
||||
#include "InputCommon/ControllerInterface/evdev/evdev.h"
|
||||
#endif
|
||||
#ifdef CIFACE_USE_PIPES
|
||||
#include "InputCommon/ControllerInterface/Pipes/Pipes.h"
|
||||
#endif
|
||||
#ifdef CIFACE_USE_DUALSHOCKUDPCLIENT
|
||||
#include "InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPClient.h"
|
||||
#endif
|
||||
|
||||
ControllerInterface g_controller_interface;
|
||||
static bool m_is_populating_devices = false;
|
||||
|
||||
void ControllerInterface::Initialize(const WindowSystemInfo& wsi)
|
||||
{
|
||||
if (m_is_init)
|
||||
return;
|
||||
|
||||
m_wsi = wsi;
|
||||
|
||||
// Allow backends to add devices as soon as they are initialized.
|
||||
m_is_init = true;
|
||||
|
||||
m_is_populating_devices = true;
|
||||
|
||||
#ifdef CIFACE_USE_WIN32
|
||||
ciface::Win32::Init(wsi.render_window);
|
||||
#endif
|
||||
#ifdef CIFACE_USE_XLIB
|
||||
// nothing needed
|
||||
#endif
|
||||
#ifdef CIFACE_USE_OSX
|
||||
if (m_wsi.type == WindowSystemType::MacOS)
|
||||
ciface::OSX::Init(wsi.render_window);
|
||||
// nothing needed for Quartz
|
||||
#endif
|
||||
#ifdef CIFACE_USE_SDL
|
||||
ciface::SDL::Init();
|
||||
#endif
|
||||
#ifdef CIFACE_USE_ANDROID
|
||||
// nothing needed
|
||||
#endif
|
||||
#ifdef CIFACE_USE_EVDEV
|
||||
ciface::evdev::Init();
|
||||
#endif
|
||||
#ifdef CIFACE_USE_PIPES
|
||||
// nothing needed
|
||||
#endif
|
||||
#ifdef CIFACE_USE_DUALSHOCKUDPCLIENT
|
||||
m_input_backends.emplace_back(ciface::DualShockUDPClient::CreateInputBackend(this));
|
||||
#endif
|
||||
|
||||
//OpenEmu initalize OpenEmu Input
|
||||
Input::Openemu_Input_Init();
|
||||
|
||||
RefreshDevices();
|
||||
|
||||
//OpenEmu set populating devices to false
|
||||
m_is_populating_devices = false;
|
||||
}
|
||||
|
||||
static thread_local ciface::InputChannel tls_input_channel = ciface::InputChannel::Host;
|
||||
|
||||
void ControllerInterface::SetCurrentInputChannel(ciface::InputChannel input_channel)
|
||||
{
|
||||
tls_input_channel = input_channel;
|
||||
}
|
||||
|
||||
ciface::InputChannel ControllerInterface::GetCurrentInputChannel()
|
||||
{
|
||||
return tls_input_channel;
|
||||
}
|
||||
|
||||
void ControllerInterface::PlatformPopulateDevices(std::function<void()> callback)
|
||||
{
|
||||
if (!m_is_init)
|
||||
return;
|
||||
|
||||
std::lock_guard lk_population(m_devices_population_mutex);
|
||||
|
||||
m_populating_devices_counter.fetch_add(1);
|
||||
|
||||
callback();
|
||||
|
||||
if (m_populating_devices_counter.fetch_sub(1) == 1)
|
||||
InvokeDevicesChangedCallbacks();
|
||||
}
|
||||
|
||||
void ControllerInterface::ChangeWindow(void* hwnd, WindowChangeReason reason)
|
||||
{
|
||||
if (!m_is_init)
|
||||
return;
|
||||
|
||||
// This shouldn't use render_surface so no need to update it.
|
||||
m_wsi.render_window = hwnd;
|
||||
RefreshDevices();
|
||||
}
|
||||
|
||||
void ControllerInterface::RefreshDevices(RefreshReason reason)
|
||||
{
|
||||
if (!m_is_init)
|
||||
return;
|
||||
|
||||
//OpenEmu comment out this section so we can maintain our controller input
|
||||
// {
|
||||
// std::lock_guard lk(m_devices_mutex);
|
||||
// m_devices.clear();
|
||||
// }
|
||||
|
||||
m_is_populating_devices = true;
|
||||
|
||||
// Make sure shared_ptr<Device> objects are released before repopulating.
|
||||
InvokeDevicesChangedCallbacks();
|
||||
|
||||
#ifdef CIFACE_USE_WIN32
|
||||
ciface::Win32::PopulateDevices(m_wsi.render_window);
|
||||
#endif
|
||||
#ifdef CIFACE_USE_XLIB
|
||||
if (m_wsi.type == WindowSystemType::X11)
|
||||
ciface::XInput2::PopulateDevices(m_wsi.render_window);
|
||||
#endif
|
||||
#ifdef CIFACE_USE_OSX
|
||||
if (m_wsi.type == WindowSystemType::MacOS)
|
||||
{
|
||||
ciface::OSX::PopulateDevices(m_wsi.render_window);
|
||||
ciface::Quartz::PopulateDevices(m_wsi.render_window);
|
||||
}
|
||||
#endif
|
||||
#ifdef CIFACE_USE_SDL
|
||||
ciface::SDL::PopulateDevices();
|
||||
#endif
|
||||
#ifdef CIFACE_USE_ANDROID
|
||||
ciface::Android::PopulateDevices();
|
||||
#endif
|
||||
#ifdef CIFACE_USE_EVDEV
|
||||
ciface::evdev::PopulateDevices();
|
||||
#endif
|
||||
#ifdef CIFACE_USE_PIPES
|
||||
ciface::Pipes::PopulateDevices();
|
||||
#endif
|
||||
|
||||
WiimoteReal::ProcessWiimotePool();
|
||||
|
||||
m_is_populating_devices = false;
|
||||
InvokeDevicesChangedCallbacks();
|
||||
}
|
||||
|
||||
// Remove all devices and call library cleanup functions
|
||||
void ControllerInterface::Shutdown()
|
||||
{
|
||||
if (!m_is_init)
|
||||
return;
|
||||
|
||||
// Prevent additional devices from being added during shutdown.
|
||||
m_is_init = false;
|
||||
|
||||
{
|
||||
std::lock_guard lk(m_devices_mutex);
|
||||
|
||||
for (const auto& d : m_devices)
|
||||
{
|
||||
// Set outputs to ZERO before destroying device
|
||||
for (ciface::Core::Device::Output* o : d->Outputs())
|
||||
o->SetState(0);
|
||||
}
|
||||
|
||||
m_devices.clear();
|
||||
}
|
||||
|
||||
// This will update control references so shared_ptr<Device>s are freed up
|
||||
// BEFORE we shutdown the backends.
|
||||
InvokeDevicesChangedCallbacks();
|
||||
|
||||
#ifdef CIFACE_USE_WIN32
|
||||
ciface::Win32::DeInit();
|
||||
#endif
|
||||
#ifdef CIFACE_USE_XLIB
|
||||
// nothing needed
|
||||
#endif
|
||||
#ifdef CIFACE_USE_OSX
|
||||
ciface::OSX::DeInit();
|
||||
ciface::Quartz::DeInit();
|
||||
#endif
|
||||
#ifdef CIFACE_USE_SDL
|
||||
ciface::SDL::DeInit();
|
||||
#endif
|
||||
#ifdef CIFACE_USE_ANDROID
|
||||
// nothing needed
|
||||
#endif
|
||||
#ifdef CIFACE_USE_EVDEV
|
||||
ciface::evdev::Shutdown();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ControllerInterface::AddDevice(std::shared_ptr<ciface::Core::Device> device)
|
||||
{
|
||||
// If we are shutdown (or in process of shutting down) ignore this request:
|
||||
if (!m_is_init)
|
||||
return false;
|
||||
|
||||
{
|
||||
std::lock_guard lk(m_devices_mutex);
|
||||
|
||||
const auto is_id_in_use = [&device, this](int id) {
|
||||
return std::any_of(m_devices.begin(), m_devices.end(), [&device, &id](const auto& d) {
|
||||
return d->GetSource() == device->GetSource() && d->GetName() == device->GetName() &&
|
||||
d->GetId() == id;
|
||||
});
|
||||
};
|
||||
|
||||
const auto preferred_id = device->GetPreferredId();
|
||||
if (preferred_id.has_value() && !is_id_in_use(*preferred_id))
|
||||
{
|
||||
// Use the device's preferred ID if available.
|
||||
device->SetId(*preferred_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find the first available ID to use.
|
||||
int id = 0;
|
||||
while (is_id_in_use(id))
|
||||
++id;
|
||||
|
||||
device->SetId(id);
|
||||
}
|
||||
|
||||
NOTICE_LOG_FMT(CONTROLLERINTERFACE, "Added device: {}", device->GetQualifiedName());
|
||||
m_devices.emplace_back(std::move(device));
|
||||
}
|
||||
|
||||
if (!m_is_populating_devices)
|
||||
InvokeDevicesChangedCallbacks();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ControllerInterface::RemoveDevice(std::function<bool(const ciface::Core::Device*)> callback, bool force_devices_release)
|
||||
{
|
||||
{
|
||||
std::lock_guard lk(m_devices_mutex);
|
||||
auto it = std::remove_if(m_devices.begin(), m_devices.end(), [&callback](const auto& dev) {
|
||||
if (callback(dev.get()))
|
||||
{
|
||||
NOTICE_LOG_FMT(SERIALINTERFACE, "Removed device: {}", dev->GetQualifiedName());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
m_devices.erase(it, m_devices.end());
|
||||
}
|
||||
|
||||
if (!m_is_populating_devices)
|
||||
InvokeDevicesChangedCallbacks();
|
||||
}
|
||||
|
||||
// Update input for all devices if lock can be acquired without waiting.
|
||||
void ControllerInterface::UpdateInput()
|
||||
{
|
||||
// Don't block the UI or CPU thread (to avoid a short but noticeable frame drop)
|
||||
if (m_devices_mutex.try_lock())
|
||||
{
|
||||
std::lock_guard lk(m_devices_mutex, std::adopt_lock);
|
||||
for (const auto& d : m_devices)
|
||||
d->UpdateInput();
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerInterface::SetAspectRatioAdjustment(float value)
|
||||
{
|
||||
m_aspect_ratio_adjustment = value;
|
||||
}
|
||||
|
||||
Common::Vec2 ControllerInterface::GetWindowInputScale() const
|
||||
{
|
||||
const auto ar = m_aspect_ratio_adjustment.load();
|
||||
|
||||
if (ar > 1)
|
||||
return {1.f, ar};
|
||||
else
|
||||
return {1 / ar, 1.f};
|
||||
}
|
||||
|
||||
// Register a callback to be called when a device is added or removed (as from the input backends'
|
||||
// hotplug thread), or when devices are refreshed
|
||||
// Returns a handle for later removing the callback.
|
||||
ControllerInterface::HotplugCallbackHandle
|
||||
ControllerInterface::RegisterDevicesChangedCallback(std::function<void()> callback)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(m_callbacks_mutex);
|
||||
m_devices_changed_callbacks.emplace_back(std::move(callback));
|
||||
return std::prev(m_devices_changed_callbacks.end());
|
||||
}
|
||||
|
||||
// Unregister a device callback.
|
||||
void ControllerInterface::UnregisterDevicesChangedCallback(const HotplugCallbackHandle& handle)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(m_callbacks_mutex);
|
||||
m_devices_changed_callbacks.erase(handle);
|
||||
}
|
||||
|
||||
// Invoke all callbacks that were registered
|
||||
void ControllerInterface::InvokeDevicesChangedCallbacks() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(m_callbacks_mutex);
|
||||
for (const auto& callback : m_devices_changed_callbacks)
|
||||
callback();
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
// Copyright 2010 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/IniFile.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Common/StringUtil.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/HW/Wiimote.h"
|
||||
#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h"
|
||||
#include "InputCommon/ControllerEmu/ControllerEmu.h"
|
||||
#include "InputCommon/ControllerEmu/Setting/NumericSetting.h"
|
||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||
#include "InputCommon/InputConfig.h"
|
||||
#include "InputCommon/InputProfile.h"
|
||||
|
||||
InputConfig::InputConfig(const std::string& ini_name, const std::string& gui_name,
|
||||
const std::string& profile_name)
|
||||
: m_ini_name(ini_name), m_gui_name(gui_name), m_profile_name(profile_name)
|
||||
{
|
||||
}
|
||||
|
||||
InputConfig::~InputConfig() = default;
|
||||
|
||||
bool InputConfig::LoadConfig(InputClass type)
|
||||
{
|
||||
//OpenEmu Stub
|
||||
return false;
|
||||
}
|
||||
|
||||
void InputConfig::SaveConfig()
|
||||
{
|
||||
std::string ini_filename = File::GetUserPath(D_CONFIG_IDX) + m_ini_name + ".ini";
|
||||
|
||||
IniFile inifile;
|
||||
inifile.Load(ini_filename);
|
||||
|
||||
for (auto& controller : m_controllers)
|
||||
controller->SaveConfig(inifile.GetOrCreateSection(controller->GetName()));
|
||||
|
||||
inifile.Save(ini_filename);
|
||||
}
|
||||
|
||||
ControllerEmu::EmulatedController* InputConfig::GetController(int index) const
|
||||
{
|
||||
return m_controllers.at(index).get();
|
||||
}
|
||||
|
||||
void InputConfig::ClearControllers()
|
||||
{
|
||||
m_controllers.clear();
|
||||
}
|
||||
|
||||
bool InputConfig::ControllersNeedToBeCreated() const
|
||||
{
|
||||
return m_controllers.empty();
|
||||
}
|
||||
|
||||
int InputConfig::GetControllerCount() const
|
||||
{
|
||||
return static_cast<int>(m_controllers.size());
|
||||
}
|
||||
|
||||
void InputConfig::RegisterHotplugCallback()
|
||||
{
|
||||
// Update control references on all controllers
|
||||
// as configured devices may have been added or removed.
|
||||
m_hotplug_callback_handle = g_controller_interface.RegisterDevicesChangedCallback([this] {
|
||||
for (auto& controller : m_controllers)
|
||||
controller->UpdateReferences(g_controller_interface);
|
||||
});
|
||||
}
|
||||
|
||||
void InputConfig::UnregisterHotplugCallback()
|
||||
{
|
||||
g_controller_interface.UnregisterDevicesChangedCallback(m_hotplug_callback_handle);
|
||||
}
|
||||
|
||||
bool InputConfig::IsControllerControlledByGamepadDevice(int index) const
|
||||
{
|
||||
if (static_cast<size_t>(index) >= m_controllers.size())
|
||||
return false;
|
||||
|
||||
const auto& controller = m_controllers.at(index).get()->GetDefaultDevice();
|
||||
|
||||
// Filter out anything which obviously not a gamepad
|
||||
return !((controller.source == "Quartz") // OSX Quartz Keyboard/Mouse
|
||||
|| (controller.source == "XInput2") // Linux and BSD Keyboard/Mouse
|
||||
|| (controller.source == "Android" &&
|
||||
controller.name == "Touchscreen") // Android Touchscreen
|
||||
|| (controller.source == "DInput" &&
|
||||
controller.name == "Keyboard Mouse")); // Windows Keyboard/Mouse
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
typedef struct
|
||||
{
|
||||
int openemuButton;
|
||||
int value;
|
||||
} keymap;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
keymap gc_pad_keymap[22] = {
|
||||
{OEGCButtonUp, 0},
|
||||
{OEGCButtonDown, 0},
|
||||
{OEGCButtonLeft, 0},
|
||||
{OEGCButtonRight, 0},
|
||||
{OEGCAnalogUp, 0},
|
||||
{OEGCAnalogDown, 0},
|
||||
{OEGCAnalogLeft, 0},
|
||||
{OEGCAnalogRight, 0},
|
||||
{OEGCAnalogCUp, 0},
|
||||
{OEGCAnalogCDown, 0},
|
||||
{OEGCAnalogCLeft, 0},
|
||||
{OEGCAnalogCRight, 0},
|
||||
{OEGCButtonA, 0},
|
||||
{OEGCButtonB, 0},
|
||||
{OEGCButtonX, 0},
|
||||
{OEGCButtonY, 0},
|
||||
{OEGCButtonL, 0},
|
||||
{OEGCButtonR, 0},
|
||||
{OEGCButtonZ, 0},
|
||||
{OEGCButtonStart, 0},
|
||||
{OEGCDigitalL, 0},
|
||||
{OEGCDigitalR, 0},
|
||||
};
|
||||
} gc_pad;
|
||||
|
||||
|
||||
void setGameCubeButton(int pad_num, int button , int value);
|
||||
void setGameCubeAxis(int pad_num, int button , float value);
|
||||
void init_Callback();
|
||||
|
||||
static gc_pad GameCubePads[4];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
keymap wiimote_keymap[54] = {
|
||||
{OEWiiMoteButtonLeft, 0},
|
||||
{OEWiiMoteButtonRight, 0},
|
||||
{OEWiiMoteButtonDown, 0},
|
||||
{OEWiiMoteButtonUp, 0},
|
||||
{OEWiiMoteButtonA, 0},
|
||||
{OEWiiMoteButtonB, 0},
|
||||
{OEWiiMoteButton1, 0},
|
||||
{OEWiiMoteButton2, 0},
|
||||
{OEWiiMoteButtonPlus, 0},
|
||||
{OEWiiMoteButtonMinus, 0},
|
||||
{OEWiiMoteButtonHome, 0},
|
||||
{OEWiiMoteTiltForward, 0},
|
||||
{OEWiiMoteTiltBackward, 0},
|
||||
{OEWiiMoteTiltLeft, 0},
|
||||
{OEWiiMoteTiltRight, 0},
|
||||
{OEWiiMoteShake, 0},
|
||||
{OEWiiMoteSwingUp, 0},
|
||||
{OEWiiMoteSwingDown, 0},
|
||||
{OEWiiMoteSwingLeft, 0},
|
||||
{OEWiiMoteSwingRight, 0},
|
||||
{OEWiiMoteSwingForward, 0},
|
||||
{OEWiiMoteSwingBackward, 0},
|
||||
{OEWiiNunchukAnalogUp, 0},
|
||||
{OEWiiNunchukAnalogDown, 0},
|
||||
{OEWiiNunchukAnalogLeft, 0},
|
||||
{OEWiiNunchukAnalogRight, 0},
|
||||
{OEWiiNunchukButtonC, 0},
|
||||
{OEWiiNunchukButtonZ, 0},
|
||||
{OEWiiNunchukShake, 0},
|
||||
{OEWiiClassicButtonUp, 0},
|
||||
{OEWiiClassicButtonDown, 0},
|
||||
{OEWiiClassicButtonLeft, 0},
|
||||
{OEWiiClassicButtonRight, 0},
|
||||
{OEWiiClassicAnalogLUp, 0},
|
||||
{OEWiiClassicAnalogLDown, 0},
|
||||
{OEWiiClassicAnalogLLeft, 0},
|
||||
{OEWiiClassicAnalogLRight, 0},
|
||||
{OEWiiClassicAnalogRUp, 0},
|
||||
{OEWiiClassicAnalogRDown, 0},
|
||||
{OEWiiClassicAnalogRLeft, 0},
|
||||
{OEWiiClassicAnalogRRight, 0},
|
||||
{OEWiiClassicButtonA, 0},
|
||||
{OEWiiClassicButtonB, 0},
|
||||
{OEWiiClassicButtonX, 0},
|
||||
{OEWiiClassicButtonY, 0},
|
||||
{OEWiiClassicButtonL, 0},
|
||||
{OEWiiClassicButtonR, 0},
|
||||
{OEWiiClassicButtonZl, 0},
|
||||
{OEWiiClassicButtonZr, 0},
|
||||
{OEWiiClassicButtonStart, 0},
|
||||
{OEWiiClassicButtonSelect, 0},
|
||||
{OEWiiClassicButtonHome, 0},
|
||||
{OEWiimoteSideways, 0},
|
||||
{OEWiimoteUpright, 0},
|
||||
};
|
||||
|
||||
OEWiiConType wiimoteType;
|
||||
ControlState dx, dy;
|
||||
} wii_remote;
|
||||
|
||||
void setWiiButton(int pad_num, int button , int value);
|
||||
void setWiiAxis(int pad_num, int button , float value);
|
||||
|
||||
static wii_remote WiiRemotes[4];
|
||||
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
#include "DolphinGameCore.h"
|
||||
#include "DolHost.h"
|
||||
#include "OpenEmuInput.h"
|
||||
#include "OpenEmuController.h"
|
||||
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Common/Config/Config.h"
|
||||
#include "Core/Config/MainSettings.h"
|
||||
|
||||
void input_poll_f()
|
||||
{
|
||||
//This is called every chance the Dolphin Emulator has to poll input from the frontend
|
||||
// OpenEmu handles this, so it could be used to perfom a task per per input polling
|
||||
return;
|
||||
};
|
||||
|
||||
int16_t input_state_f(unsigned port, unsigned device, unsigned index, unsigned button)
|
||||
{
|
||||
if (SConfig::GetInstance().bWii && !Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_ENABLED))
|
||||
{
|
||||
//This is where we must translate the OpenEmu frontend keys presses stored in the keymap to bitmasks for Dolphin.
|
||||
return WiiRemotes[port].wiimote_keymap[button].value;
|
||||
} else {
|
||||
return GameCubePads[port].gc_pad_keymap[button].value;
|
||||
}
|
||||
};
|
||||
|
||||
void init_Callback() {
|
||||
//Dolphin Polling Callback
|
||||
Input::openemu_set_input_poll(input_poll_f);
|
||||
|
||||
//Controller input Callbacks
|
||||
Input::openemu_set_input_state(input_state_f);
|
||||
}
|
||||
|
||||
void setGameCubeButton(int pad_num, int button , int value) {
|
||||
GameCubePads[pad_num].gc_pad_keymap[button].value = value;
|
||||
}
|
||||
|
||||
void setGameCubeAxis(int pad_num, int button , float value)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case OEGCAnalogUp:
|
||||
case OEGCAnalogLeft:
|
||||
case OEGCAnalogCUp:
|
||||
case OEGCAnalogCLeft:
|
||||
value *= -0x8000;
|
||||
break;
|
||||
default:
|
||||
value *= 0x7FFF;
|
||||
break;
|
||||
}
|
||||
GameCubePads[pad_num].gc_pad_keymap[button].value = value;
|
||||
}
|
||||
|
||||
void setWiiButton(int pad_num, int button , int value) {
|
||||
WiiRemotes[pad_num].wiimote_keymap[button].value = value;
|
||||
}
|
||||
|
||||
void setWiiAxis(int pad_num, int button , float value)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
|
||||
case OEWiiMoteTiltLeft:
|
||||
case OEWiiMoteTiltForward:
|
||||
value *= -180;
|
||||
break;
|
||||
case OEWiiMoteTiltRight:
|
||||
case OEWiiMoteTiltBackward:
|
||||
value *= 180;
|
||||
break;
|
||||
|
||||
case OEWiiNunchukAnalogUp:
|
||||
case OEWiiNunchukAnalogLeft:
|
||||
case OEWiiClassicAnalogLUp:
|
||||
case OEWiiClassicAnalogLLeft:
|
||||
case OEWiiClassicAnalogRUp:
|
||||
case OEWiiClassicAnalogRLeft:
|
||||
value *= -0x8000;
|
||||
break;
|
||||
default:
|
||||
value *= 0x7FFF;
|
||||
break;
|
||||
}
|
||||
WiiRemotes[pad_num].wiimote_keymap[button].value = value;
|
||||
}
|
||||
@@ -1,545 +0,0 @@
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
|
||||
#include "Common/Common.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/IniFile.h"
|
||||
#include "Common/Config/Config.h"
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/Config/WiimoteSettings.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/HW/GCKeyboard.h"
|
||||
#include "Core/HW/GCPad.h"
|
||||
#include "Core/HW/GCPadEmu.h"
|
||||
#include "Core/HW/Wiimote.h"
|
||||
#include "Core/HW/WiimoteEmu/Extension/Classic.h"
|
||||
#include "Core/HW/WiimoteEmu/Extension/Nunchuk.h"
|
||||
#include "Core/HW/WiimoteEmu/WiimoteEmu.h"
|
||||
#include "Core/HW/WiimoteReal/WiimoteReal.h"
|
||||
#include "Core/Host.h"
|
||||
#include "OpenEmuInput.h"
|
||||
|
||||
#include "InputCommon/ControlReference/ControlReference.h"
|
||||
#include "InputCommon/ControlReference/ExpressionParser.h"
|
||||
#include "InputCommon/ControllerEmu/Control/Control.h"
|
||||
#include "InputCommon/ControllerEmu/ControlGroup/Attachments.h"
|
||||
#include "InputCommon/ControllerEmu/Setting/NumericSetting.h"
|
||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||
#include "InputCommon/GCAdapter.h"
|
||||
#include "InputCommon/GCPadStatus.h"
|
||||
#include "InputCommon/InputConfig.h"
|
||||
|
||||
#include "DolHost.h"
|
||||
|
||||
static Input::openemu_input_state_t input_cb;
|
||||
static Input::openemu_input_poll_t poll_cb;
|
||||
static const std::string source = "OpenEmu";
|
||||
static unsigned input_types[4];
|
||||
static bool init_wiimotes = false;
|
||||
|
||||
static std::string GetDeviceName(unsigned device)
|
||||
{
|
||||
switch (device)
|
||||
{
|
||||
case OEDolDevJoy:
|
||||
return "Joypad";
|
||||
case OEDolDevAnalog:
|
||||
return "Analog";
|
||||
case OEDolDevPointer:
|
||||
return "Pointer";
|
||||
case OEDolDevLightGun:
|
||||
return "LightGun";
|
||||
case OEDolDevKeyboard:
|
||||
return "Keyboard";
|
||||
case OEDolDevMouse:
|
||||
return "Mouse";
|
||||
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
static std::string GetQualifiedName(unsigned port, unsigned device)
|
||||
{
|
||||
return ciface::Core::DeviceQualifier(source, port, GetDeviceName(device)).ToString();
|
||||
}
|
||||
|
||||
|
||||
class OEDevice : public ciface::Core::Device
|
||||
{
|
||||
private:
|
||||
class Button : public ciface::Core::Device::Input
|
||||
{
|
||||
public:
|
||||
Button(unsigned port, unsigned device, unsigned index, unsigned id, const char* name)
|
||||
: m_port(port), m_device(device), m_index(index), m_id(id), m_name(name)
|
||||
{
|
||||
}
|
||||
std::string GetName() const override { return m_name; }
|
||||
ControlState GetState() const override {
|
||||
return input_cb(m_port, m_device, m_index, m_id);
|
||||
}
|
||||
|
||||
private:
|
||||
const unsigned m_port;
|
||||
const unsigned m_device;
|
||||
const unsigned m_index;
|
||||
const unsigned m_id;
|
||||
const char* m_name;
|
||||
};
|
||||
|
||||
class Axis : public ciface::Core::Device::Input
|
||||
{
|
||||
public:
|
||||
Axis(unsigned port, unsigned device, unsigned index, unsigned id, s16 range, const char* name)
|
||||
: m_port(port), m_device(device), m_index(index), m_id(id), m_range(range), m_name(name)
|
||||
{
|
||||
}
|
||||
std::string GetName() const override { return m_name; }
|
||||
ControlState GetState() const override
|
||||
{
|
||||
return std::max(0.0, input_cb(m_port, m_device, m_index, m_id) / m_range);
|
||||
}
|
||||
|
||||
private:
|
||||
const unsigned m_port;
|
||||
const unsigned m_device;
|
||||
const unsigned m_index;
|
||||
const unsigned m_id;
|
||||
const ControlState m_range;
|
||||
const char* m_name;
|
||||
};
|
||||
|
||||
class Motor : public ciface::Core::Device::Output
|
||||
{
|
||||
public:
|
||||
Motor(u8 port) : m_port(port) {}
|
||||
std::string GetName() const override { return "Rumble"; }
|
||||
void SetState(ControlState state) override
|
||||
{
|
||||
uint16_t str = std::min(std::max(0.0, state), 1.0) * 0xFFFF;
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
const u8 m_port;
|
||||
};
|
||||
|
||||
void AddButton(unsigned id, const char* name, unsigned index = 0)
|
||||
{
|
||||
AddInput(new Button(m_port, m_device, index, id, name));
|
||||
}
|
||||
void AddAxis(unsigned id, s16 range, const char* name, unsigned index = 0)
|
||||
{
|
||||
AddInput(new Axis(m_port, m_device, index, id, range, name));
|
||||
}
|
||||
void AddMotor() { AddOutput(new Motor(m_port)); }
|
||||
|
||||
public:
|
||||
OEDevice(unsigned device, unsigned port);
|
||||
void UpdateInput() override
|
||||
{
|
||||
poll_cb();
|
||||
}
|
||||
std::string GetName() const override { return GetDeviceName(m_device); }
|
||||
std::string GetSource() const override { return source; }
|
||||
unsigned GetPort() const { return m_port; }
|
||||
|
||||
private:
|
||||
unsigned m_device;
|
||||
unsigned m_port;
|
||||
};
|
||||
|
||||
OEDevice::OEDevice(unsigned device, unsigned p) : m_device(device), m_port(p)
|
||||
{
|
||||
switch (device)
|
||||
{
|
||||
case OEDolDevJoy:
|
||||
//GC
|
||||
AddButton(OEGCButtonB, "B");
|
||||
AddButton(OEGCButtonY, "Y");
|
||||
AddButton(OEGCButtonStart, "Start");
|
||||
AddButton(OEGCButtonUp, "Up");
|
||||
AddButton(OEGCButtonDown, "Down");
|
||||
AddButton(OEGCButtonLeft, "Left");
|
||||
AddButton(OEGCButtonRight, "Right");
|
||||
AddButton(OEGCButtonA, "A");
|
||||
AddButton(OEGCButtonX, "X");
|
||||
AddButton(OEGCDigitalL, "L");
|
||||
AddButton(OEGCDigitalR, "R");
|
||||
AddButton(OEGCButtonZ, "Z");
|
||||
//Wiimote
|
||||
AddButton(OEWiiMoteButtonUp, "Up");
|
||||
AddButton(OEWiiMoteButtonDown, "Down");
|
||||
AddButton(OEWiiMoteButtonLeft, "Left");
|
||||
AddButton(OEWiiMoteButtonRight, "Right");
|
||||
AddButton(OEWiiMoteButtonA, "A");
|
||||
AddButton(OEWiiMoteButtonB, "B");
|
||||
AddButton(OEWiiMoteButton1, "1");
|
||||
AddButton(OEWiiMoteButton2, "2");
|
||||
AddButton(OEWiiMoteButtonPlus, "+");
|
||||
AddButton(OEWiiMoteButtonMinus, "-");
|
||||
AddButton(OEWiiMoteButtonHome, "Home");
|
||||
AddButton(OEWiiMoteShake, "wmShake");
|
||||
//Special Buttons
|
||||
AddButton(OEWiimoteSideways, "Sideways");
|
||||
AddButton(OEWiimoteUpright, "Upright");
|
||||
//Nunchuk
|
||||
AddButton(OEWiiNunchukButtonC, "C");
|
||||
AddButton(OEWiiNunchukButtonZ, "Z");
|
||||
AddButton(OEWiiNunchukShake, "ncShake");
|
||||
//Classic
|
||||
AddButton(OEWiiClassicButtonUp, "Up");
|
||||
AddButton(OEWiiClassicButtonDown, "Down");
|
||||
AddButton(OEWiiClassicButtonLeft, "Left");
|
||||
AddButton(OEWiiClassicButtonRight, "Right");
|
||||
AddButton(OEWiiClassicButtonA, "A");
|
||||
AddButton(OEWiiClassicButtonB, "B");
|
||||
AddButton(OEWiiClassicButtonX, "X");
|
||||
AddButton(OEWiiClassicButtonY, "Y");
|
||||
AddButton(OEWiiClassicButtonL, "L");
|
||||
AddButton(OEWiiClassicButtonR, "R");
|
||||
AddButton(OEWiiClassicButtonZl, "Zl");
|
||||
AddButton(OEWiiClassicButtonZr, "Zr");
|
||||
AddButton(OEWiiClassicButtonStart, "Start");
|
||||
AddButton(OEWiiClassicButtonSelect, "Select");
|
||||
AddButton(OEWiiClassicButtonHome, "Home");
|
||||
return;
|
||||
|
||||
case OEDolDevAnalog:
|
||||
AddAxis(OEGCAnalogLeft, -0x8000, "X0-", 0);
|
||||
AddAxis(OEGCAnalogRight, 0x7FFF, "X0+", 0);
|
||||
AddAxis(OEGCAnalogUp, -0x8000, "Y0-", 0);
|
||||
AddAxis(OEGCAnalogDown, 0x7FFF, "Y0+", 0 );
|
||||
AddAxis(OEGCAnalogCLeft, -0x8000, "X1-", 1);
|
||||
AddAxis(OEGCAnalogCRight, 0x7FFF, "X1+", 1);
|
||||
AddAxis(OEGCAnalogCUp, -0x8000, "Y1-", 1);
|
||||
AddAxis(OEGCAnalogCDown, 0x7FFF, "Y1+", 1);
|
||||
AddAxis(OEGCButtonL, 0x7FFF, "LTrigger0+");
|
||||
AddAxis(OEGCButtonR, 0x7FFF, "RTrigger1+");
|
||||
//Wiimote
|
||||
AddAxis(OEWiiMoteTiltForward, -180, "TiltY0-", 2);
|
||||
AddAxis(OEWiiMoteTiltBackward, 180, "TiltY0+", 2 );
|
||||
AddAxis(OEWiiMoteTiltLeft, -180, "TiltX0-", 2);
|
||||
AddAxis(OEWiiMoteTiltRight, 180, "TiltX0+", 2);
|
||||
AddAxis(OEWiiMoteSwingUp,-0x8000, "SwingY0-", 3);
|
||||
AddAxis(OEWiiMoteSwingDown,0x7FFF, "SwingY0+", 3);
|
||||
AddAxis(OEWiiMoteSwingLeft,-0x8000, "SwingX0-", 3);
|
||||
AddAxis(OEWiiMoteSwingRight,0x7FFF, "SwingX0+", 3);
|
||||
AddAxis(OEWiiMoteSwingForward, -0x8000, "SwingZ0-", 3);
|
||||
AddAxis(OEWiiMoteSwingBackward,0x7FFF, "SwingZ0+", 3);
|
||||
//Nunchuk
|
||||
AddAxis(OEWiiNunchukAnalogUp, -0x8000, "ncY0-", 4);
|
||||
AddAxis(OEWiiNunchukAnalogDown,0x7FFF, "ncY0+", 4);
|
||||
AddAxis(OEWiiNunchukAnalogLeft,-0x8000, "ncX0-", 4);
|
||||
AddAxis(OEWiiNunchukAnalogRight,0x7FFF, "ncX0+", 4);
|
||||
//Classic
|
||||
AddAxis(OEWiiClassicAnalogLUp, -0x8000, "ccY0-", 5);
|
||||
AddAxis(OEWiiClassicAnalogLDown,0x7FFF, "ccY0+", 5);
|
||||
AddAxis(OEWiiClassicAnalogLLeft,-0x8000, "ccX0-", 5);
|
||||
AddAxis(OEWiiClassicAnalogLRight,0x7FFF, "ccX0+", 5);
|
||||
AddAxis(OEWiiClassicAnalogRUp,-0x8000, "ccY1-", 6);
|
||||
AddAxis(OEWiiClassicAnalogRDown,0x7FFF, "ccY1+", 6);
|
||||
AddAxis(OEWiiClassicAnalogRLeft,-0x8000, "ccX1-", 6);
|
||||
AddAxis(OEWiiClassicAnalogRRight,0x7FFF, "ccX1+", 6);
|
||||
AddAxis(OEWiiClassicButtonL, 0x7FFF, "ccLTrigger0+");
|
||||
AddAxis(OEWiiClassicButtonR, 0x7FFF, "ccRTrigger1+");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void AddDevicesForPort(unsigned port)
|
||||
{
|
||||
g_controller_interface.AddDevice(std::make_shared<OEDevice>(OEDolDevJoy, port));
|
||||
g_controller_interface.AddDevice(std::make_shared<OEDevice>(OEDolDevAnalog, port));
|
||||
g_controller_interface.AddDevice(std::make_shared<OEDevice>(OEDolDevPointer, port));
|
||||
}
|
||||
|
||||
static void RemoveDevicesForPort(unsigned port)
|
||||
{
|
||||
g_controller_interface.RemoveDevice([&port](const auto& device) {
|
||||
return device->GetSource() == source
|
||||
&& (device->GetName() == GetDeviceName(OEDolDevAnalog)
|
||||
|| device->GetName() == GetDeviceName(OEDolDevJoy)
|
||||
|| device->GetName() == GetDeviceName(OEDolDevPointer))
|
||||
&& dynamic_cast<const OEDevice *>(device)->GetPort() == port;
|
||||
});
|
||||
}
|
||||
|
||||
void Input::Openemu_Input_Init()
|
||||
{
|
||||
|
||||
g_controller_interface.Initialize(DolHost::GetInstance()->GetWSI());
|
||||
|
||||
g_controller_interface.AddDevice(std::make_shared<OEDevice>(OEDolDevKeyboard, 0));
|
||||
|
||||
Pad::Initialize();
|
||||
Keyboard::Initialize();
|
||||
|
||||
if (SConfig::GetInstance().bWii && !Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_ENABLED))
|
||||
{
|
||||
init_wiimotes = true;
|
||||
Wiimote::Initialize(Wiimote::InitializeMode::DO_NOT_WAIT_FOR_WIIMOTES);
|
||||
}
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
{
|
||||
Wiimote::ResetAllWiimotes();
|
||||
Wiimote::Shutdown();
|
||||
init_wiimotes = false;
|
||||
Keyboard::Shutdown();
|
||||
Pad::Shutdown();
|
||||
g_controller_interface.Shutdown();
|
||||
}
|
||||
|
||||
void OpenEmu_Input_Update()
|
||||
{
|
||||
}
|
||||
|
||||
void Input::ResetControllers()
|
||||
{
|
||||
for (int port = 0; port < 4; port++)
|
||||
Input::openemu_set_controller_port_device(port, input_types[port]);
|
||||
}
|
||||
|
||||
void Input::openemu_set_input_state(Input::openemu_input_state_t cb)
|
||||
{
|
||||
input_cb = cb;
|
||||
}
|
||||
|
||||
void Input::openemu_set_input_poll(Input::openemu_input_poll_t cb)
|
||||
{
|
||||
poll_cb = cb;
|
||||
}
|
||||
|
||||
void Input::openemu_set_controller_port_device(unsigned port, unsigned device)
|
||||
{
|
||||
if (port > 4)
|
||||
return;
|
||||
|
||||
input_types[port] = device;
|
||||
|
||||
std::string devJoypad = GetQualifiedName(port, OEDolDevJoy);
|
||||
std::string devAnalog = GetQualifiedName(port, OEDolDevAnalog);
|
||||
std::string devMouse = GetQualifiedName(port, OEDolDevMouse);
|
||||
std::string devPointer = GetQualifiedName(port, OEDolDevPointer);
|
||||
|
||||
RemoveDevicesForPort(port);
|
||||
if ((device & 0xff) != OEDolDevNone)
|
||||
AddDevicesForPort(port);
|
||||
|
||||
|
||||
GCPad* gcPad = (GCPad*)Pad::GetConfig()->GetController(port);
|
||||
// load an empty inifile section, clears everything
|
||||
IniFile::Section sec;
|
||||
gcPad->LoadConfig(&sec);
|
||||
gcPad->SetDefaultDevice(devJoypad);
|
||||
|
||||
ControllerEmu::ControlGroup* gcButtons = gcPad->GetGroup(PadGroup::Buttons);
|
||||
ControllerEmu::ControlGroup* gcMainStick = gcPad->GetGroup(PadGroup::MainStick);
|
||||
ControllerEmu::ControlGroup* gcCStick = gcPad->GetGroup(PadGroup::CStick);
|
||||
ControllerEmu::ControlGroup* gcDPad = gcPad->GetGroup(PadGroup::DPad);
|
||||
ControllerEmu::ControlGroup* gcTriggers = gcPad->GetGroup(PadGroup::Triggers);
|
||||
ControllerEmu::ControlGroup* gcRumble = gcPad->GetGroup(PadGroup::Rumble);
|
||||
#if 0
|
||||
ControllerEmu::ControlGroup* gcMic = gcPad->GetGroup(PadGroup::Mic);
|
||||
ControllerEmu::ControlGroup* gcOptions = gcPad->GetGroup(PadGroup::Options);
|
||||
#endif
|
||||
|
||||
gcButtons->SetControlExpression(0, "A"); // A
|
||||
gcButtons->SetControlExpression(1, "B"); // B
|
||||
gcButtons->SetControlExpression(2, "X"); // X
|
||||
gcButtons->SetControlExpression(3, "Y"); // Y
|
||||
gcButtons->SetControlExpression(4, "Z"); // Z
|
||||
gcButtons->SetControlExpression(5, "Start"); // Start
|
||||
gcMainStick->SetControlExpression(0, "`" + devAnalog + ":Y0-`"); // Up
|
||||
gcMainStick->SetControlExpression(1, "`" + devAnalog + ":Y0+`"); // Down
|
||||
gcMainStick->SetControlExpression(2, "`" + devAnalog + ":X0-`"); // Left
|
||||
gcMainStick->SetControlExpression(3, "`" + devAnalog + ":X0+`"); // Right
|
||||
gcCStick->SetControlExpression(0, "`" + devAnalog + ":Y1-`"); // Up
|
||||
gcCStick->SetControlExpression(1, "`" + devAnalog + ":Y1+`"); // Down
|
||||
gcCStick->SetControlExpression(2, "`" + devAnalog + ":X1-`"); // Left
|
||||
gcCStick->SetControlExpression(3, "`" + devAnalog + ":X1+`"); // Right
|
||||
gcDPad->SetControlExpression(0, "Up"); // Up
|
||||
gcDPad->SetControlExpression(1, "Down"); // Down
|
||||
gcDPad->SetControlExpression(2, "Left"); // Left
|
||||
gcDPad->SetControlExpression(3, "Right"); // Right
|
||||
gcTriggers->SetControlExpression(0, "L"); // L-trigger
|
||||
gcTriggers->SetControlExpression(1, "R"); // R-trigger
|
||||
gcTriggers->SetControlExpression(2, "`" + devAnalog + ":LTrigger0+`"); // L-trigger Analog
|
||||
gcTriggers->SetControlExpression(3, "`" + devAnalog + ":RTrigger1+`"); // R-trigger Analog
|
||||
gcRumble->SetControlExpression(0, "Rumble");
|
||||
|
||||
gcPad->UpdateReferences(g_controller_interface);
|
||||
Pad::GetConfig()->SaveConfig();
|
||||
|
||||
if (SConfig::GetInstance().bWii && !Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_ENABLED))
|
||||
{
|
||||
WiimoteEmu::Wiimote* wm = (WiimoteEmu::Wiimote*)Wiimote::GetConfig()->GetController(port);
|
||||
// load an empty inifile section, clears everything
|
||||
IniFile::Section sec;
|
||||
wm->LoadConfig(&sec);
|
||||
wm->SetDefaultDevice(devJoypad);
|
||||
|
||||
using namespace WiimoteEmu;
|
||||
if (device == OEWiimoteCC || device == OEWiimoteCC_Pro)
|
||||
{
|
||||
ControllerEmu::ControlGroup* ccButtons = wm->GetClassicGroup(ClassicGroup::Buttons);
|
||||
ControllerEmu::ControlGroup* ccTriggers = wm->GetClassicGroup(ClassicGroup::Triggers);
|
||||
ControllerEmu::ControlGroup* ccDpad = wm->GetClassicGroup(ClassicGroup::DPad);
|
||||
ControllerEmu::ControlGroup* ccLeftStick = wm->GetClassicGroup(ClassicGroup::LeftStick);
|
||||
ControllerEmu::ControlGroup* ccRightStick = wm->GetClassicGroup(ClassicGroup::RightStick);
|
||||
|
||||
ccButtons->SetControlExpression(0, "A"); // A
|
||||
ccButtons->SetControlExpression(1, "B"); // B
|
||||
ccButtons->SetControlExpression(2, "X"); // X
|
||||
ccButtons->SetControlExpression(3, "Y"); // Y
|
||||
ccButtons->SetControlExpression(4, "Zl"); // ZL
|
||||
ccButtons->SetControlExpression(5, "Zr"); // ZR
|
||||
ccButtons->SetControlExpression(6, "-"); // -
|
||||
ccButtons->SetControlExpression(7, "+"); // +
|
||||
ccButtons->SetControlExpression(8, "Home"); // Home
|
||||
ccTriggers->SetControlExpression(0, "L"); // L-trigger
|
||||
ccTriggers->SetControlExpression(1, "R"); // R-trigger
|
||||
ccTriggers->SetControlExpression(2, "`" + devAnalog + "ccLTrigger0+`"); // L-trigger Analog
|
||||
ccTriggers->SetControlExpression(3, "`" + devAnalog + "ccRTrigger1+`"); // R-trigger Analog
|
||||
ccDpad->SetControlExpression(0, "Up"); // Up
|
||||
ccDpad->SetControlExpression(1, "Down"); // Down
|
||||
ccDpad->SetControlExpression(2, "Left"); // Left
|
||||
ccDpad->SetControlExpression(3, "Right"); // Right
|
||||
ccLeftStick->SetControlExpression(0, "`" + devAnalog + ":ccY0-`"); // Up
|
||||
ccLeftStick->SetControlExpression(1, "`" + devAnalog + ":ccY0+`"); // Down
|
||||
ccLeftStick->SetControlExpression(2, "`" + devAnalog + ":ccX0-`"); // Left
|
||||
ccLeftStick->SetControlExpression(3, "`" + devAnalog + ":ccX0+`"); // Right
|
||||
ccRightStick->SetControlExpression(0, "`" + devAnalog + ":ccY1-`"); // Up
|
||||
ccRightStick->SetControlExpression(1, "`" + devAnalog + ":ccY1+`"); // Down
|
||||
ccRightStick->SetControlExpression(2, "`" + devAnalog + ":ccX1-`"); // Left
|
||||
ccRightStick->SetControlExpression(3, "`" + devAnalog + ":ccX1+`"); // Right
|
||||
}
|
||||
else //if (device != OEWiiMoteReal)
|
||||
{
|
||||
ControllerEmu::ControlGroup* wmButtons = wm->GetWiimoteGroup(WiimoteGroup::Buttons);
|
||||
ControllerEmu::ControlGroup* wmDPad = wm->GetWiimoteGroup(WiimoteGroup::DPad);
|
||||
ControllerEmu::ControlGroup* wmIR = wm->GetWiimoteGroup(WiimoteGroup::Point);
|
||||
ControllerEmu::ControlGroup* wmShake = wm->GetWiimoteGroup(WiimoteGroup::Shake);
|
||||
ControllerEmu::ControlGroup* wmTilt = wm->GetWiimoteGroup(WiimoteGroup::Tilt);
|
||||
ControllerEmu::ControlGroup* wmHotkeys = wm->GetWiimoteGroup(WiimoteGroup::Hotkeys);
|
||||
#if 0
|
||||
ControllerEmu::ControlGroup* wmSwing = wm->GetWiimoteGroup(WiimoteGroup::Swing);
|
||||
|
||||
#endif
|
||||
|
||||
wmButtons->SetControlExpression(0, "A | `" + devMouse + ":Left`"); // A
|
||||
wmButtons->SetControlExpression(1, "B | `" + devMouse + ":Right`"); // B
|
||||
|
||||
if (device == OEWiimoteNC)
|
||||
{
|
||||
ControllerEmu::ControlGroup* ncButtons = wm->GetNunchukGroup(NunchukGroup::Buttons);
|
||||
ControllerEmu::ControlGroup* ncStick = wm->GetNunchukGroup(NunchukGroup::Stick);
|
||||
ControllerEmu::ControlGroup* ncShake = wm->GetNunchukGroup(NunchukGroup::Shake);
|
||||
#if 0
|
||||
ControllerEmu::ControlGroup* ncTilt = wm->GetNunchukGroup(NunchukGroup::Tilt);
|
||||
ControllerEmu::ControlGroup* ncSwing = wm->GetNunchukGroup(NunchukGroup::Swing);
|
||||
#endif
|
||||
|
||||
ncButtons->SetControlExpression(0, "C"); // C
|
||||
ncButtons->SetControlExpression(1, "Z"); // Z
|
||||
ncStick->SetControlExpression(0, "`" + devAnalog + ":ccY0-`"); // Up
|
||||
ncStick->SetControlExpression(1, "`" + devAnalog + ":ccY0+`"); // Down
|
||||
ncStick->SetControlExpression(2, "`" + devAnalog + ":ccX0-`"); // Left
|
||||
ncStick->SetControlExpression(3, "`" + devAnalog + ":ccX0+`"); // Right
|
||||
ncShake->SetControlExpression(0, "ncShake"); // X
|
||||
ncShake->SetControlExpression(1, "ncShake"); // Y
|
||||
ncShake->SetControlExpression(2, "ncShake"); // Z
|
||||
|
||||
wmButtons->SetControlExpression(2, "1"); // 1
|
||||
wmButtons->SetControlExpression(3, "2"); // 2
|
||||
wmButtons->SetControlExpression(4, "-"); // -
|
||||
wmButtons->SetControlExpression(5, "+"); // +
|
||||
}
|
||||
else
|
||||
{
|
||||
wmButtons->SetControlExpression(2, "1"); // 1
|
||||
wmButtons->SetControlExpression(3, "2"); // 2
|
||||
wmButtons->SetControlExpression(4, "-"); // -
|
||||
wmButtons->SetControlExpression(5, "+"); // +
|
||||
}
|
||||
|
||||
wmButtons->SetControlExpression(6, "Home"); // Home
|
||||
wmDPad->SetControlExpression(0, "Up"); // Up
|
||||
wmDPad->SetControlExpression(1, "Down"); // Down
|
||||
wmDPad->SetControlExpression(2, "Left"); // Left
|
||||
wmDPad->SetControlExpression(3, "Right"); // Right
|
||||
wmIR->SetControlExpression(0, "`" + devPointer + ":Y0-`"); // Up
|
||||
wmIR->SetControlExpression(1, "`" + devPointer + ":Y0+`"); // Down
|
||||
wmIR->SetControlExpression(2, "`" + devPointer + ":X0-`"); // Left
|
||||
wmIR->SetControlExpression(3, "`" + devPointer + ":X0+`"); // Right
|
||||
wmShake->SetControlExpression(0, "wmShake"); // X
|
||||
wmShake->SetControlExpression(1, "wmShake"); // Y
|
||||
wmShake->SetControlExpression(2, "wmShake"); // Z
|
||||
wmTilt->SetControlExpression(0, "`" + devAnalog + ":TiltY0-`"); // Forward
|
||||
wmTilt->SetControlExpression(1, "`" + devAnalog + ":TiltY0+`"); // Backward
|
||||
wmTilt->SetControlExpression(2, "`" + devAnalog + ":TiltX0-`"); // Left
|
||||
wmTilt->SetControlExpression(3, "`" + devAnalog + ":TiltX0+`"); // Right
|
||||
|
||||
#if 0
|
||||
wmHotkeys->SetControlExpression(0, "Sideways"); // Sideways Toggle
|
||||
wmHotkeys->SetControlExpression(1, "Upright"); // Upright Toggle
|
||||
wmHotkeys->SetControlExpression(2, "Sideways"); // Sideways Hold
|
||||
wmHotkeys->SetControlExpression(3, "Upright"); // Upright Hold
|
||||
#endif
|
||||
}
|
||||
|
||||
ControllerEmu::ControlGroup* wmRumble = wm->GetWiimoteGroup(WiimoteGroup::Rumble);
|
||||
ControllerEmu::ControlGroup* wmOptions = wm->GetWiimoteGroup(WiimoteGroup::Options);
|
||||
ControllerEmu::Attachments* wmExtension =
|
||||
(ControllerEmu::Attachments*)wm->GetWiimoteGroup(WiimoteGroup::Attachments);
|
||||
|
||||
static_cast<ControllerEmu::NumericSetting<double>*>(wmOptions->numeric_settings[0].get())
|
||||
->SetValue(0); // Speaker Pan [-100, 100]
|
||||
static_cast<ControllerEmu::NumericSetting<double>*>(wmOptions->numeric_settings[1].get())
|
||||
->SetValue(95); // Battery [0, 100]
|
||||
static_cast<ControllerEmu::NumericSetting<bool>*>(wmOptions->numeric_settings[2].get())
|
||||
->SetValue(false); // Upright Wiimote
|
||||
static_cast<ControllerEmu::NumericSetting<bool>*>(wmOptions->numeric_settings[3].get())
|
||||
->SetValue(false); // Sideways Wiimote
|
||||
wmRumble->SetControlExpression(0, "Rumble");
|
||||
switch (device)
|
||||
{
|
||||
case OEWiimote:
|
||||
wmExtension->SetSelectedAttachment(ExtensionNumber::NONE);
|
||||
Config::SetCurrent(Config::GetInfoForWiimoteSource(port), WiimoteSource::Emulated);
|
||||
break;
|
||||
|
||||
case OEWiimoteSW:
|
||||
wmExtension->SetSelectedAttachment(ExtensionNumber::NONE);
|
||||
static_cast<ControllerEmu::NumericSetting<bool>*>(wmOptions->numeric_settings[2].get())
|
||||
->SetValue(true); // Sideways Wiimote
|
||||
Config::SetCurrent(Config::GetInfoForWiimoteSource(port), WiimoteSource::Emulated);
|
||||
break;
|
||||
|
||||
case OEWiimoteNC:
|
||||
wmExtension->SetSelectedAttachment(ExtensionNumber::NUNCHUK);
|
||||
Config::SetCurrent(Config::GetInfoForWiimoteSource(port), WiimoteSource::Emulated);
|
||||
break;
|
||||
|
||||
case OEWiimoteCC:
|
||||
case OEWiimoteCC_Pro:
|
||||
wmExtension->SetSelectedAttachment(ExtensionNumber::CLASSIC);
|
||||
Config::SetCurrent(Config::GetInfoForWiimoteSource(port), WiimoteSource::Emulated);
|
||||
break;
|
||||
|
||||
case OEWiiMoteReal:
|
||||
//desc = Libretro::Input::descEmpty;
|
||||
Config::SetCurrent(Config::GetInfoForWiimoteSource(port), WiimoteSource::Real);
|
||||
|
||||
default:
|
||||
//desc = Libretro::Input::descGC;
|
||||
Config::SetCurrent(Config::GetInfoForWiimoteSource(port), WiimoteSource::None);
|
||||
break;
|
||||
}
|
||||
wm->UpdateReferences(g_controller_interface);
|
||||
::Wiimote::GetConfig()->SaveConfig();
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
//Dolphins Internal Controll expression Reference
|
||||
|
||||
//Wiimote
|
||||
//m_buttons->SetControlExpression(0, "A");
|
||||
//m_buttons->SetControlExpression(1, "B");
|
||||
//m_buttons->SetControlExpression(2, "`1`");
|
||||
//m_buttons->SetControlExpression(3, "`2`");
|
||||
//m_buttons->SetControlExpression(4, "-");
|
||||
//m_buttons->SetControlExpression(5, "+");
|
||||
//m_buttons->SetControlExpression(6, "Home");
|
||||
//m_dpad->SetControlExpression(0, "UP");
|
||||
//m_dpad->SetControlExpression(1, "DOWN");
|
||||
//m_dpad->SetControlExpression(2, "LEFT");
|
||||
//m_dpad->SetControlExpression(3, "RIGHT");
|
||||
//m_ir->SetControlExpression(0, "Cursor Y-");
|
||||
//m_ir->SetControlExpression(1, "Cursor Y+");
|
||||
//m_ir->SetControlExpression(2, "Cursor X-");
|
||||
//m_ir->SetControlExpression(3, "Cursor X+");
|
||||
//Tilt:
|
||||
//m_imu_gyroscope->SetControlExpression(0, "Tilt Backward");
|
||||
//m_imu_gyroscope->SetControlExpression(1, "Tilt Forward");
|
||||
//m_imu_gyroscope->SetControlExpression(2, "Tilt Left");
|
||||
//m_imu_gyroscope->SetControlExpression(3, "Tilt Right");
|
||||
//m_imu_gyroscope->SetControlExpression(3, "Tilt Modifier");
|
||||
//Swing:
|
||||
//m_imu_accelerometer->SetControlExpression(0, "Accel Up");
|
||||
//m_imu_accelerometer->SetControlExpression(1, "Accel Down");
|
||||
//m_imu_accelerometer->SetControlExpression(2, "Accel Left");
|
||||
//m_imu_accelerometer->SetControlExpression(3, "Accel Right");
|
||||
//m_imu_accelerometer->SetControlExpression(4, "Accel Forward");
|
||||
//m_imu_accelerometer->SetControlExpression(5, "Accel Backward");
|
||||
//Gyro:
|
||||
//m_imu_gyroscope->SetControlExpression(0, "Gyro Pitch Up");
|
||||
//m_imu_gyroscope->SetControlExpression(1, "Gyro Pitch Down");
|
||||
//m_imu_gyroscope->SetControlExpression(2, "Gyro Roll Left");
|
||||
//m_imu_gyroscope->SetControlExpression(3, "Gyro Roll Right");
|
||||
//m_imu_gyroscope->SetControlExpression(4, "Gyro Yaw Left");
|
||||
//m_imu_gyroscope->SetControlExpression(5, "Gyro Yaw Right");
|
||||
|
||||
typedef enum _OEDolDev
|
||||
{
|
||||
OEDolDevNone,
|
||||
OEDolDevJoy,
|
||||
OEDolDevMouse,
|
||||
OEDolDevKeyboard,
|
||||
OEDolDevLightGun,
|
||||
OEDolDevAnalog,
|
||||
OEDolDevPointer
|
||||
} OEDolDevs;
|
||||
|
||||
typedef enum _OEGCDigital
|
||||
{
|
||||
OEGCDigitalL = 21,
|
||||
OEGCDigitalR
|
||||
} OEGCDigital;
|
||||
|
||||
typedef enum _OEWiiConType
|
||||
{
|
||||
OEWiimote = 1,
|
||||
OEWiimoteSW,
|
||||
OEWiimoteNC,
|
||||
OEWiimoteCC,
|
||||
OEWiimoteCC_Pro,
|
||||
OEWiiMoteReal
|
||||
} OEWiiConType;
|
||||
|
||||
namespace Input
|
||||
{
|
||||
typedef int16_t (*openemu_input_state_t)(unsigned port, unsigned device, unsigned index, unsigned id);
|
||||
typedef void (*openemu_input_poll_t)();
|
||||
|
||||
void openemu_set_controller_port_device(unsigned port, unsigned device);
|
||||
void openemu_set_input_state(openemu_input_state_t);
|
||||
void openemu_set_input_poll(openemu_input_poll_t);
|
||||
|
||||
void Openemu_Input_Init();
|
||||
void OpenEmu_Input_Update();
|
||||
void ResetControllers();
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
// Copyright 2012 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
#include "DolphinGameCore.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include <OpenGL/gl3.h>
|
||||
|
||||
#include "Common/GL/GLInterface/AGL.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
|
||||
static bool UpdateCachedDimensions(NSView* view, u32* width, u32* height)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool AttachContextToView(NSOpenGLContext* context, NSView* view, u32* width, u32* height)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
GLContextAGL::~GLContextAGL()
|
||||
{
|
||||
}
|
||||
|
||||
bool GLContextAGL::IsHeadless() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void GLContextAGL::Swap()
|
||||
{
|
||||
[_current.renderDelegate didRenderFrameOnAlternateThread];
|
||||
}
|
||||
|
||||
// Create rendering window.
|
||||
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
|
||||
bool GLContextAGL::Initialize(const WindowSystemInfo& wsi, bool stereo, bool core)
|
||||
{
|
||||
MakeCurrent();
|
||||
// Control window size and picture scaling
|
||||
if(SConfig::GetInstance().bWii) {
|
||||
m_backbuffer_width = 854;
|
||||
m_backbuffer_height = 480;
|
||||
} else {
|
||||
m_backbuffer_width = 640;
|
||||
m_backbuffer_height = 480;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
std::unique_ptr<GLContext> GLContextAGL::CreateSharedContext()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool GLContextAGL::MakeCurrent()
|
||||
{
|
||||
[_current.renderDelegate willRenderFrameOnAlternateThread];
|
||||
|
||||
// Set the background color of the context to black
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
Swap();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GLContextAGL::ClearCurrent()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLContextAGL::Update()
|
||||
{
|
||||
if(SConfig::GetInstance().bWii) {
|
||||
m_backbuffer_width = 854;
|
||||
m_backbuffer_height = 480;
|
||||
} else {
|
||||
m_backbuffer_width = 640;
|
||||
m_backbuffer_height = 480;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void GLContextAGL::SwapInterval(int interval)
|
||||
{
|
||||
}
|
||||
@@ -1,524 +0,0 @@
|
||||
// Copyright 2022 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "VideoBackends/Metal/MTLGfx.h"
|
||||
|
||||
#include "VideoBackends/Metal/MTLBoundingBox.h"
|
||||
#include "VideoBackends/Metal/MTLObjectCache.h"
|
||||
#include "VideoBackends/Metal/MTLPipeline.h"
|
||||
#include "VideoBackends/Metal/MTLStateTracker.h"
|
||||
#include "VideoBackends/Metal/MTLTexture.h"
|
||||
#include "VideoBackends/Metal/MTLUtil.h"
|
||||
#include "VideoBackends/Metal/MTLVertexFormat.h"
|
||||
#include "VideoBackends/Metal/MTLVertexManager.h"
|
||||
|
||||
#include "VideoCommon/FramebufferManager.h"
|
||||
#include "VideoCommon/Present.h"
|
||||
#include "VideoCommon/VideoBackendBase.h"
|
||||
|
||||
#import "DolphinGameCore.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
Metal::Gfx::Gfx(MRCOwned<CAMetalLayer*> layer) : m_layer(std::move(layer))
|
||||
{
|
||||
UpdateActiveConfig();
|
||||
[m_layer setDisplaySyncEnabled:g_ActiveConfig.bVSyncActive];
|
||||
|
||||
SetupSurface();
|
||||
g_state_tracker->FlushEncoders();
|
||||
}
|
||||
|
||||
Metal::Gfx::~Gfx() = default;
|
||||
|
||||
bool Metal::Gfx::IsHeadless() const
|
||||
{
|
||||
return m_layer == nullptr;
|
||||
}
|
||||
|
||||
// MARK: Texture Creation
|
||||
|
||||
std::unique_ptr<AbstractTexture> Metal::Gfx::CreateTexture(const TextureConfig& config,
|
||||
std::string_view name)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
MRCOwned<MTLTextureDescriptor*> desc = MRCTransfer([MTLTextureDescriptor new]);
|
||||
[desc setTextureType:config.samples > 1 ? MTLTextureType2DMultisampleArray :
|
||||
MTLTextureType2DArray];
|
||||
[desc setPixelFormat:Util::FromAbstract(config.format)];
|
||||
[desc setWidth:config.width];
|
||||
[desc setHeight:config.height];
|
||||
[desc setMipmapLevelCount:config.levels];
|
||||
[desc setArrayLength:config.layers];
|
||||
[desc setSampleCount:config.samples];
|
||||
[desc setStorageMode:MTLStorageModePrivate];
|
||||
MTLTextureUsage usage = MTLTextureUsageShaderRead;
|
||||
if (config.IsRenderTarget())
|
||||
usage |= MTLTextureUsageRenderTarget;
|
||||
if (config.IsComputeImage())
|
||||
usage |= MTLTextureUsageShaderWrite;
|
||||
[desc setUsage:usage];
|
||||
id<MTLTexture> texture = [g_device newTextureWithDescriptor:desc];
|
||||
if (!texture)
|
||||
return nullptr;
|
||||
|
||||
if (name.empty())
|
||||
[texture setLabel:[NSString stringWithFormat:@"Texture %d", m_texture_counter++]];
|
||||
else
|
||||
[texture setLabel:MRCTransfer([[NSString alloc] initWithBytes:name.data()
|
||||
length:name.size()
|
||||
encoding:NSUTF8StringEncoding])];
|
||||
return std::make_unique<Texture>(MRCTransfer(texture), config);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<AbstractStagingTexture>
|
||||
Metal::Gfx::CreateStagingTexture(StagingTextureType type, const TextureConfig& config)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
const size_t stride = config.GetStride();
|
||||
const size_t buffer_size = stride * static_cast<size_t>(config.height);
|
||||
|
||||
MTLResourceOptions options = MTLStorageModeShared;
|
||||
if (type == StagingTextureType::Upload)
|
||||
options |= MTLResourceCPUCacheModeWriteCombined;
|
||||
|
||||
id<MTLBuffer> buffer = [g_device newBufferWithLength:buffer_size options:options];
|
||||
if (!buffer)
|
||||
return nullptr;
|
||||
[buffer
|
||||
setLabel:[NSString stringWithFormat:@"Staging Texture %d", m_staging_texture_counter++]];
|
||||
return std::make_unique<StagingTexture>(MRCTransfer(buffer), type, config);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<AbstractFramebuffer>
|
||||
Metal::Gfx::CreateFramebuffer(AbstractTexture* color_attachment, AbstractTexture* depth_attachment)
|
||||
{
|
||||
AbstractTexture* const either_attachment = color_attachment ? color_attachment : depth_attachment;
|
||||
return std::make_unique<Framebuffer>(
|
||||
color_attachment, depth_attachment, either_attachment->GetWidth(),
|
||||
either_attachment->GetHeight(), either_attachment->GetLayers(),
|
||||
either_attachment->GetSamples());
|
||||
}
|
||||
|
||||
// MARK: Pipeline Creation
|
||||
|
||||
std::unique_ptr<AbstractShader> Metal::Gfx::CreateShaderFromSource(ShaderStage stage,
|
||||
std::string_view source,
|
||||
std::string_view name)
|
||||
{
|
||||
std::optional<std::string> msl = Util::TranslateShaderToMSL(stage, source);
|
||||
if (!msl.has_value())
|
||||
{
|
||||
PanicAlertFmt("Failed to convert shader {} to MSL", name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return CreateShaderFromMSL(stage, std::move(*msl), source, name);
|
||||
}
|
||||
|
||||
std::unique_ptr<AbstractShader> Metal::Gfx::CreateShaderFromBinary(ShaderStage stage,
|
||||
const void* data, size_t length,
|
||||
std::string_view name)
|
||||
{
|
||||
return CreateShaderFromMSL(stage, std::string(static_cast<const char*>(data), length), {}, name);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
||||
static const char* StageFilename(ShaderStage stage)
|
||||
{
|
||||
switch (stage)
|
||||
{
|
||||
case ShaderStage::Vertex: return "vs";
|
||||
case ShaderStage::Geometry: return "gs";
|
||||
case ShaderStage::Pixel: return "ps";
|
||||
case ShaderStage::Compute: return "cs";
|
||||
}
|
||||
}
|
||||
|
||||
static NSString* GenericShaderName(ShaderStage stage)
|
||||
{
|
||||
switch (stage)
|
||||
{
|
||||
case ShaderStage::Vertex: return @"Vertex shader %d";
|
||||
case ShaderStage::Geometry: return @"Geometry shader %d";
|
||||
case ShaderStage::Pixel: return @"Pixel shader %d";
|
||||
case ShaderStage::Compute: return @"Compute shader %d";
|
||||
}
|
||||
}
|
||||
|
||||
// clang-format on
|
||||
|
||||
std::unique_ptr<AbstractShader> Metal::Gfx::CreateShaderFromMSL(ShaderStage stage, std::string msl,
|
||||
std::string_view glsl,
|
||||
std::string_view name)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
NSError* err = nullptr;
|
||||
auto DumpBadShader = [&](std::string_view msg) {
|
||||
static int counter = 0;
|
||||
std::string filename = VideoBackendBase::BadShaderFilename(StageFilename(stage), counter++);
|
||||
std::ofstream stream(filename);
|
||||
if (stream.good())
|
||||
{
|
||||
stream << msl << std::endl;
|
||||
stream << "/*" << std::endl;
|
||||
stream << msg << std::endl;
|
||||
stream << "Error:" << std::endl;
|
||||
stream << [[err localizedDescription] UTF8String] << std::endl;
|
||||
if (!glsl.empty())
|
||||
{
|
||||
stream << "Original GLSL:" << std::endl;
|
||||
stream << glsl << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
stream << "Shader was created with cached MSL so no GLSL is available." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
stream << std::endl;
|
||||
stream << "Dolphin Version: " << Common::GetScmRevStr() << std::endl;
|
||||
stream << "Video Backend: " << g_video_backend->GetDisplayName() << std::endl;
|
||||
stream << "*/" << std::endl;
|
||||
stream.close();
|
||||
|
||||
PanicAlertFmt("{} (written to {})\n", msg, filename);
|
||||
};
|
||||
|
||||
auto lib = MRCTransfer([g_device newLibraryWithSource:[NSString stringWithUTF8String:msl.data()]
|
||||
options:nil
|
||||
error:&err]);
|
||||
if (err)
|
||||
{
|
||||
DumpBadShader(fmt::format("Failed to compile {}", name));
|
||||
return nullptr;
|
||||
}
|
||||
auto fn = MRCTransfer([lib newFunctionWithName:@"main0"]);
|
||||
if (!fn)
|
||||
{
|
||||
DumpBadShader(fmt::format("Shader {} is missing its main0 function", name));
|
||||
return nullptr;
|
||||
}
|
||||
if (!name.empty())
|
||||
[fn setLabel:MRCTransfer([[NSString alloc] initWithBytes:name.data()
|
||||
length:name.size()
|
||||
encoding:NSUTF8StringEncoding])];
|
||||
else
|
||||
[fn setLabel:[NSString stringWithFormat:GenericShaderName(stage),
|
||||
m_shader_counter[static_cast<u32>(stage)]++]];
|
||||
[lib setLabel:[fn label]];
|
||||
if (stage == ShaderStage::Compute)
|
||||
{
|
||||
MTLComputePipelineReflection* reflection = nullptr;
|
||||
auto desc = [MTLComputePipelineDescriptor new];
|
||||
[desc setComputeFunction:fn];
|
||||
[desc setLabel:[fn label]];
|
||||
MRCOwned<id<MTLComputePipelineState>> pipeline =
|
||||
MRCTransfer([g_device newComputePipelineStateWithDescriptor:desc
|
||||
options:MTLPipelineOptionArgumentInfo
|
||||
reflection:&reflection
|
||||
error:&err]);
|
||||
if (err)
|
||||
{
|
||||
DumpBadShader(fmt::format("Failed to compile compute pipeline {}", name));
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_unique<ComputePipeline>(stage, reflection, std::move(msl), std::move(fn),
|
||||
std::move(pipeline));
|
||||
}
|
||||
return std::make_unique<Shader>(stage, std::move(msl), std::move(fn));
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<NativeVertexFormat>
|
||||
Metal::Gfx::CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
return std::make_unique<VertexFormat>(vtx_decl);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<AbstractPipeline> Metal::Gfx::CreatePipeline(const AbstractPipelineConfig& config,
|
||||
const void* cache_data,
|
||||
size_t cache_data_length)
|
||||
{
|
||||
return g_object_cache->CreatePipeline(config);
|
||||
}
|
||||
|
||||
void Metal::Gfx::Flush()
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
g_state_tracker->FlushEncoders();
|
||||
}
|
||||
}
|
||||
|
||||
void Metal::Gfx::WaitForGPUIdle()
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
g_state_tracker->FlushEncoders();
|
||||
g_state_tracker->WaitForFlushedEncoders();
|
||||
}
|
||||
}
|
||||
|
||||
void Metal::Gfx::OnConfigChanged(u32 bits)
|
||||
{
|
||||
AbstractGfx::OnConfigChanged(bits);
|
||||
|
||||
if (bits & CONFIG_CHANGE_BIT_VSYNC)
|
||||
[m_layer setDisplaySyncEnabled:g_ActiveConfig.bVSyncActive];
|
||||
|
||||
if (bits & CONFIG_CHANGE_BIT_ANISOTROPY)
|
||||
{
|
||||
g_object_cache->ReloadSamplers();
|
||||
g_state_tracker->ReloadSamplers();
|
||||
}
|
||||
}
|
||||
|
||||
void Metal::Gfx::ClearRegion(const MathUtil::Rectangle<int>& target_rc, bool color_enable,
|
||||
bool alpha_enable, bool z_enable, u32 color, u32 z)
|
||||
{
|
||||
u32 framebuffer_width = m_current_framebuffer->GetWidth();
|
||||
u32 framebuffer_height = m_current_framebuffer->GetHeight();
|
||||
// All Metal render passes are fullscreen, so we can only run a fast clear if the target is too
|
||||
if (target_rc == MathUtil::Rectangle<int>(0, 0, framebuffer_width, framebuffer_height))
|
||||
{
|
||||
// Determine whether the EFB has an alpha channel. If it doesn't, we can clear the alpha
|
||||
// channel to 0xFF. This hopefully allows us to use the fast path in most cases.
|
||||
if (bpmem.zcontrol.pixel_format == PixelFormat::RGB565_Z16 ||
|
||||
bpmem.zcontrol.pixel_format == PixelFormat::RGB8_Z24 ||
|
||||
bpmem.zcontrol.pixel_format == PixelFormat::Z24)
|
||||
{
|
||||
// Force alpha writes, and clear the alpha channel. This is different from the other backends,
|
||||
// where the existing values of the alpha channel are preserved.
|
||||
alpha_enable = true;
|
||||
color &= 0x00FFFFFF;
|
||||
}
|
||||
|
||||
bool c_ok = (color_enable && alpha_enable) ||
|
||||
g_state_tracker->GetCurrentFramebuffer()->GetColorFormat() ==
|
||||
AbstractTextureFormat::Undefined;
|
||||
bool z_ok = z_enable || g_state_tracker->GetCurrentFramebuffer()->GetDepthFormat() ==
|
||||
AbstractTextureFormat::Undefined;
|
||||
if (c_ok && z_ok)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
// clang-format off
|
||||
MTLClearColor clear_color = MTLClearColorMake(
|
||||
static_cast<double>((color >> 16) & 0xFF) / 255.0,
|
||||
static_cast<double>((color >> 8) & 0xFF) / 255.0,
|
||||
static_cast<double>((color >> 0) & 0xFF) / 255.0,
|
||||
static_cast<double>((color >> 24) & 0xFF) / 255.0);
|
||||
// clang-format on
|
||||
float z_normalized = static_cast<float>(z & 0xFFFFFF) / 16777216.0f;
|
||||
if (!g_Config.backend_info.bSupportsReversedDepthRange)
|
||||
z_normalized = 1.f - z_normalized;
|
||||
g_state_tracker->BeginClearRenderPass(clear_color, z_normalized);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_state_tracker->EnableEncoderLabel(false);
|
||||
AbstractGfx::ClearRegion(target_rc, color_enable, alpha_enable, z_enable, color, z);
|
||||
g_state_tracker->EnableEncoderLabel(true);
|
||||
}
|
||||
|
||||
void Metal::Gfx::SetPipeline(const AbstractPipeline* pipeline)
|
||||
{
|
||||
g_state_tracker->SetPipeline(static_cast<const Pipeline*>(pipeline));
|
||||
}
|
||||
|
||||
void Metal::Gfx::SetFramebuffer(AbstractFramebuffer* framebuffer)
|
||||
{
|
||||
// Shouldn't be bound as a texture.
|
||||
if (AbstractTexture* color = framebuffer->GetColorAttachment())
|
||||
g_state_tracker->UnbindTexture(static_cast<Texture*>(color)->GetMTLTexture());
|
||||
if (AbstractTexture* depth = framebuffer->GetDepthAttachment())
|
||||
g_state_tracker->UnbindTexture(static_cast<Texture*>(depth)->GetMTLTexture());
|
||||
|
||||
m_current_framebuffer = framebuffer;
|
||||
g_state_tracker->SetCurrentFramebuffer(static_cast<Framebuffer*>(framebuffer));
|
||||
}
|
||||
|
||||
void Metal::Gfx::SetAndDiscardFramebuffer(AbstractFramebuffer* framebuffer)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
SetFramebuffer(framebuffer);
|
||||
g_state_tracker->BeginRenderPass(MTLLoadActionDontCare);
|
||||
}
|
||||
}
|
||||
|
||||
void Metal::Gfx::SetAndClearFramebuffer(AbstractFramebuffer* framebuffer,
|
||||
const ClearColor& color_value, float depth_value)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
SetFramebuffer(framebuffer);
|
||||
MTLClearColor color =
|
||||
MTLClearColorMake(color_value[0], color_value[1], color_value[2], color_value[3]);
|
||||
g_state_tracker->BeginClearRenderPass(color, depth_value);
|
||||
}
|
||||
}
|
||||
|
||||
void Metal::Gfx::SetScissorRect(const MathUtil::Rectangle<int>& rc)
|
||||
{
|
||||
g_state_tracker->SetScissor(rc);
|
||||
}
|
||||
|
||||
void Metal::Gfx::SetTexture(u32 index, const AbstractTexture* texture)
|
||||
{
|
||||
g_state_tracker->SetTexture(
|
||||
index, texture ? static_cast<const Texture*>(texture)->GetMTLTexture() : nullptr);
|
||||
}
|
||||
|
||||
void Metal::Gfx::SetSamplerState(u32 index, const SamplerState& state)
|
||||
{
|
||||
g_state_tracker->SetSampler(index, state);
|
||||
}
|
||||
|
||||
void Metal::Gfx::SetComputeImageTexture(AbstractTexture* texture, bool read, bool write)
|
||||
{
|
||||
g_state_tracker->SetComputeTexture(static_cast<const Texture*>(texture));
|
||||
}
|
||||
|
||||
void Metal::Gfx::UnbindTexture(const AbstractTexture* texture)
|
||||
{
|
||||
g_state_tracker->UnbindTexture(static_cast<const Texture*>(texture)->GetMTLTexture());
|
||||
}
|
||||
|
||||
void Metal::Gfx::SetViewport(float x, float y, float width, float height, float near_depth,
|
||||
float far_depth)
|
||||
{
|
||||
g_state_tracker->SetViewport(x, y, width, height, near_depth, far_depth);
|
||||
}
|
||||
|
||||
void Metal::Gfx::Draw(u32 base_vertex, u32 num_vertices)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
g_state_tracker->Draw(base_vertex, num_vertices);
|
||||
}
|
||||
}
|
||||
|
||||
void Metal::Gfx::DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
g_state_tracker->DrawIndexed(base_index, num_indices, base_vertex);
|
||||
}
|
||||
}
|
||||
|
||||
void Metal::Gfx::DispatchComputeShader(const AbstractShader* shader, //
|
||||
u32 groupsize_x, u32 groupsize_y, u32 groupsize_z,
|
||||
u32 groups_x, u32 groups_y, u32 groups_z)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
g_state_tracker->SetPipeline(static_cast<const ComputePipeline*>(shader));
|
||||
g_state_tracker->DispatchComputeShader(groupsize_x, groupsize_y, groupsize_z, //
|
||||
groups_x, groups_y, groups_z);
|
||||
}
|
||||
}
|
||||
|
||||
void Metal::Gfx::BindBackbuffer(const ClearColor& clear_color)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
CheckForSurfaceChange();
|
||||
CheckForSurfaceResize();
|
||||
m_drawable = MRCRetain([m_layer nextDrawable]);
|
||||
m_bb_texture->SetMTLTexture(MRCRetain([m_drawable texture]));
|
||||
SetAndClearFramebuffer(m_backbuffer.get(), clear_color);
|
||||
}
|
||||
}
|
||||
|
||||
void Metal::Gfx::PresentBackbuffer()
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
g_state_tracker->EndRenderPass();
|
||||
if (m_drawable)
|
||||
{
|
||||
//OpenEmu Blit to GameCoore Texture for Rendering
|
||||
id<MTLBlitCommandEncoder> blitCommandEncoder = [g_state_tracker->GetRenderCmdBuf() blitCommandEncoder];
|
||||
|
||||
if (@available(macOS 10.15, *)) {
|
||||
[blitCommandEncoder copyFromTexture:[m_drawable texture] toTexture:id<MTLTexture>([_current metalTexture])];
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
// TODO: Add pre 10.15 metal blit
|
||||
}
|
||||
|
||||
[blitCommandEncoder endEncoding];
|
||||
|
||||
// PresentDrawable refuses to allow Dolphin to present faster than the display's refresh rate
|
||||
// when windowed (or fullscreen with vsync enabled, but that's more understandable).
|
||||
// On the other hand, it helps Xcode's GPU captures start and stop on frame boundaries
|
||||
// which is convenient. Put it here as a default-off config, which we can override in Xcode.
|
||||
// It also seems to improve frame pacing, so enable it by default with vsync
|
||||
if (g_ActiveConfig.iUsePresentDrawable == TriState::On ||
|
||||
(g_ActiveConfig.iUsePresentDrawable == TriState::Auto && g_ActiveConfig.bVSyncActive))
|
||||
[g_state_tracker->GetRenderCmdBuf() presentDrawable:m_drawable];
|
||||
else
|
||||
[g_state_tracker->GetRenderCmdBuf()
|
||||
addScheduledHandler:[drawable = std::move(m_drawable)](id) { [drawable present]; }];
|
||||
m_bb_texture->SetMTLTexture(nullptr);
|
||||
m_drawable = nullptr;
|
||||
}
|
||||
g_state_tracker->FlushEncoders();
|
||||
}
|
||||
}
|
||||
|
||||
void Metal::Gfx::CheckForSurfaceChange()
|
||||
{
|
||||
if (!g_presenter->SurfaceChangedTestAndClear())
|
||||
return;
|
||||
m_layer = MRCRetain(static_cast<CAMetalLayer*>(g_presenter->GetNewSurfaceHandle()));
|
||||
SetupSurface();
|
||||
}
|
||||
|
||||
void Metal::Gfx::CheckForSurfaceResize()
|
||||
{
|
||||
if (!g_presenter->SurfaceResizedTestAndClear())
|
||||
return;
|
||||
SetupSurface();
|
||||
}
|
||||
|
||||
void Metal::Gfx::SetupSurface()
|
||||
{
|
||||
auto info = GetSurfaceInfo();
|
||||
|
||||
[m_layer setDrawableSize:{static_cast<double>(info.width), static_cast<double>(info.height)}];
|
||||
|
||||
TextureConfig cfg(info.width, info.height, 1, 1, 1, info.format,
|
||||
AbstractTextureFlag_RenderTarget);
|
||||
m_bb_texture = std::make_unique<Texture>(nullptr, cfg);
|
||||
m_backbuffer = std::make_unique<Framebuffer>(m_bb_texture.get(), nullptr, //
|
||||
info.width, info.height, 1, 1);
|
||||
|
||||
if (g_presenter)
|
||||
g_presenter->SetBackbuffer(info);
|
||||
}
|
||||
|
||||
SurfaceInfo Metal::Gfx::GetSurfaceInfo() const
|
||||
{
|
||||
if (!m_layer) // Headless
|
||||
return {};
|
||||
|
||||
CGSize size = [m_layer bounds].size;
|
||||
const float scale = [m_layer contentsScale];
|
||||
|
||||
return {static_cast<u32>(size.width * scale), static_cast<u32>(size.height * scale), scale,
|
||||
Util::ToAbstract([m_layer pixelFormat])};
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
// Copyright 2022 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "VideoBackends/Metal/VideoBackend.h"
|
||||
|
||||
// This must be included before we use any TARGET_OS_* macros.
|
||||
#include <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
#include <AppKit/AppKit.h>
|
||||
#endif
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
|
||||
#include "Common/Common.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
|
||||
#include "VideoBackends/Metal/MTLBoundingBox.h"
|
||||
#include "VideoBackends/Metal/MTLGfx.h"
|
||||
#include "VideoBackends/Metal/MTLObjectCache.h"
|
||||
#include "VideoBackends/Metal/MTLPerfQuery.h"
|
||||
#include "VideoBackends/Metal/MTLStateTracker.h"
|
||||
#include "VideoBackends/Metal/MTLUtil.h"
|
||||
#include "VideoBackends/Metal/MTLVertexManager.h"
|
||||
|
||||
#include "VideoCommon/AbstractGfx.h"
|
||||
#include "VideoCommon/FramebufferManager.h"
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
#import "DolphinGameCore.h"
|
||||
|
||||
std::string Metal::VideoBackend::GetName() const
|
||||
{
|
||||
return NAME;
|
||||
}
|
||||
|
||||
std::string Metal::VideoBackend::GetDisplayName() const
|
||||
{
|
||||
// i18n: Apple's Metal graphics API (https://developer.apple.com/metal/)
|
||||
return _trans("Metal");
|
||||
}
|
||||
|
||||
std::optional<std::string> Metal::VideoBackend::GetWarningMessage() const
|
||||
{
|
||||
// if (Util::GetAdapterList().empty())
|
||||
// {
|
||||
// return _trans("No Metal-compatible GPUs were found. "
|
||||
// "Use the OpenGL backend or upgrade your computer/GPU");
|
||||
// }
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
static bool WindowSystemTypeSupportsMetal(WindowSystemType type)
|
||||
{
|
||||
// switch (type)
|
||||
// {
|
||||
// case WindowSystemType::MacOS:
|
||||
// case WindowSystemType::Headless:
|
||||
return true;
|
||||
// default:
|
||||
// return false;
|
||||
// }
|
||||
}
|
||||
|
||||
bool Metal::VideoBackend::Initialize(const WindowSystemInfo& wsi)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
const bool surface_ok = wsi.type == WindowSystemType::Headless || wsi.render_surface;
|
||||
if (!WindowSystemTypeSupportsMetal(wsi.type) || !surface_ok)
|
||||
{
|
||||
PanicAlertFmt("Bad WindowSystemInfo for Metal renderer.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Util::PopulateBackendInfo(&g_Config);
|
||||
std::vector<MRCOwned<id<MTLDevice>>> adapters;
|
||||
adapters.push_back(MRCTransfer([_current metalDevice]));
|
||||
Util::PopulateBackendInfoAdapters(&g_Config, adapters);
|
||||
if (!adapters.empty())
|
||||
{
|
||||
// Use the selected adapter, or the first to fill features.
|
||||
size_t index = static_cast<size_t>(g_Config.iAdapter);
|
||||
if (index >= adapters.size())
|
||||
index = 0;
|
||||
Util::PopulateBackendInfoFeatures(&g_Config, adapters[index]);
|
||||
}
|
||||
|
||||
// Since we haven't called InitializeShared yet, iAdapter may be out of range,
|
||||
// so we have to check it ourselves.
|
||||
size_t selected_adapter_index = static_cast<size_t>(g_Config.iAdapter);
|
||||
if (selected_adapter_index >= adapters.size())
|
||||
{
|
||||
WARN_LOG_FMT(VIDEO, "Metal adapter index out of range, selecting default adapter.");
|
||||
selected_adapter_index = 0;
|
||||
}
|
||||
MRCOwned<id<MTLDevice>> adapter = MRCOwned<id<MTLDevice>>(MRCRetain([_current metalDevice]));
|
||||
Util::PopulateBackendInfoFeatures(&g_Config, adapter);
|
||||
|
||||
UpdateActiveConfig();
|
||||
|
||||
MRCOwned<CAMetalLayer*> layer = MRCRetain(static_cast<CAMetalLayer*>(wsi.render_surface));
|
||||
//MRCOwned<CAMetalLayer*> layer = MRCRetain([CAMetalLayer layer]);
|
||||
layer.Get().framebufferOnly=NO;
|
||||
[layer setDevice:adapter];
|
||||
|
||||
if (Util::ToAbstract([layer pixelFormat]) == AbstractTextureFormat::Undefined)
|
||||
[layer setPixelFormat:MTLPixelFormatBGRA8Unorm];
|
||||
|
||||
ObjectCache::Initialize(std::move(adapter));
|
||||
g_state_tracker = std::make_unique<StateTracker>();
|
||||
|
||||
return InitializeShared(
|
||||
std::make_unique<Metal::Gfx>(std::move(layer)), std::make_unique<Metal::VertexManager>(),
|
||||
std::make_unique<Metal::PerfQuery>(), std::make_unique<Metal::BoundingBox>());
|
||||
}
|
||||
}
|
||||
|
||||
void Metal::VideoBackend::Shutdown()
|
||||
{
|
||||
ShutdownShared();
|
||||
|
||||
g_state_tracker.reset();
|
||||
ObjectCache::Shutdown();
|
||||
}
|
||||
|
||||
void Metal::VideoBackend::InitBackendInfo()
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
Util::PopulateBackendInfo(&g_Config);
|
||||
std::vector<MRCOwned<id<MTLDevice>>> adapters;
|
||||
adapters.push_back(MRCTransfer([_current metalDevice]));
|
||||
Util::PopulateBackendInfoAdapters(&g_Config, adapters);
|
||||
if (!adapters.empty())
|
||||
{
|
||||
// Use the selected adapter, or the first to fill features.
|
||||
size_t index = static_cast<size_t>(g_Config.iAdapter);
|
||||
if (index >= adapters.size())
|
||||
index = 0;
|
||||
Util::PopulateBackendInfoFeatures(&g_Config, adapters[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Metal::VideoBackend::PrepareWindow(WindowSystemInfo& wsi)
|
||||
{
|
||||
//#if TARGET_OS_OSX
|
||||
// if (wsi.type != WindowSystemType::MacOS)
|
||||
// return;
|
||||
// NSView* view = static_cast<NSView*>(wsi.render_surface);
|
||||
CAMetalLayer* layer = [CAMetalLayer layer];
|
||||
// [view setWantsLayer:YES];
|
||||
// [view setLayer:layer];
|
||||
wsi.render_surface = layer;
|
||||
//#endif
|
||||
}
|
||||
@@ -1,731 +0,0 @@
|
||||
// Copyright 2023 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "VideoBackends/OGL/OGLGfx.h"
|
||||
|
||||
#include "Common/GL/GLContext.h"
|
||||
#include "Common/GL/GLExtensions/GLExtensions.h"
|
||||
#include "Common/Logging/LogManager.h"
|
||||
|
||||
#include "Core/Config/GraphicsSettings.h"
|
||||
|
||||
#include "VideoBackends/OGL/OGLConfig.h"
|
||||
#include "VideoBackends/OGL/OGLPipeline.h"
|
||||
#include "VideoBackends/OGL/OGLShader.h"
|
||||
#include "VideoBackends/OGL/OGLTexture.h"
|
||||
#include "VideoBackends/OGL/ProgramShaderCache.h"
|
||||
#include "VideoBackends/OGL/SamplerCache.h"
|
||||
|
||||
#include "VideoCommon/AsyncShaderCompiler.h"
|
||||
#include "VideoCommon/DriverDetails.h"
|
||||
#include "VideoCommon/OnScreenDisplay.h"
|
||||
#include "VideoCommon/Present.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace OGL
|
||||
{
|
||||
VideoConfig g_ogl_config;
|
||||
|
||||
static void APIENTRY ErrorCallback(GLenum source, GLenum type, GLuint id, GLenum severity,
|
||||
GLsizei length, const char* message, const void* userParam)
|
||||
{
|
||||
const char* s_source;
|
||||
const char* s_type;
|
||||
|
||||
// Performance - DualCore driver performance warning:
|
||||
// DualCore application thread syncing with server thread
|
||||
if (id == 0x200b0)
|
||||
return;
|
||||
|
||||
switch (source)
|
||||
{
|
||||
case GL_DEBUG_SOURCE_API_ARB:
|
||||
s_source = "API";
|
||||
break;
|
||||
case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
|
||||
s_source = "Window System";
|
||||
break;
|
||||
case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
|
||||
s_source = "Shader Compiler";
|
||||
break;
|
||||
case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
|
||||
s_source = "Third Party";
|
||||
break;
|
||||
case GL_DEBUG_SOURCE_APPLICATION_ARB:
|
||||
s_source = "Application";
|
||||
break;
|
||||
case GL_DEBUG_SOURCE_OTHER_ARB:
|
||||
s_source = "Other";
|
||||
break;
|
||||
default:
|
||||
s_source = "Unknown";
|
||||
break;
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case GL_DEBUG_TYPE_ERROR_ARB:
|
||||
s_type = "Error";
|
||||
break;
|
||||
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
|
||||
s_type = "Deprecated";
|
||||
break;
|
||||
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
|
||||
s_type = "Undefined";
|
||||
break;
|
||||
case GL_DEBUG_TYPE_PORTABILITY_ARB:
|
||||
s_type = "Portability";
|
||||
break;
|
||||
case GL_DEBUG_TYPE_PERFORMANCE_ARB:
|
||||
s_type = "Performance";
|
||||
break;
|
||||
case GL_DEBUG_TYPE_OTHER_ARB:
|
||||
s_type = "Other";
|
||||
break;
|
||||
default:
|
||||
s_type = "Unknown";
|
||||
break;
|
||||
}
|
||||
switch (severity)
|
||||
{
|
||||
case GL_DEBUG_SEVERITY_HIGH_ARB:
|
||||
ERROR_LOG_FMT(HOST_GPU, "id: {:x}, source: {}, type: {} - {}", id, s_source, s_type, message);
|
||||
break;
|
||||
case GL_DEBUG_SEVERITY_MEDIUM_ARB:
|
||||
WARN_LOG_FMT(HOST_GPU, "id: {:x}, source: {}, type: {} - {}", id, s_source, s_type, message);
|
||||
break;
|
||||
case GL_DEBUG_SEVERITY_LOW_ARB:
|
||||
DEBUG_LOG_FMT(HOST_GPU, "id: {:x}, source: {}, type: {} - {}", id, s_source, s_type, message);
|
||||
break;
|
||||
case GL_DEBUG_SEVERITY_NOTIFICATION:
|
||||
DEBUG_LOG_FMT(HOST_GPU, "id: {:x}, source: {}, type: {} - {}", id, s_source, s_type, message);
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG_FMT(HOST_GPU, "id: {:x}, source: {}, type: {} - {}", id, s_source, s_type, message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Two small Fallbacks to avoid GL_ARB_ES2_compatibility
|
||||
static void APIENTRY DepthRangef(GLfloat neardepth, GLfloat fardepth)
|
||||
{
|
||||
glDepthRange(neardepth, fardepth);
|
||||
}
|
||||
static void APIENTRY ClearDepthf(GLfloat depthval)
|
||||
{
|
||||
glClearDepth(depthval);
|
||||
}
|
||||
|
||||
OGLGfx::OGLGfx(std::unique_ptr<GLContext> main_gl_context, float backbuffer_scale)
|
||||
: m_main_gl_context(std::move(main_gl_context)),
|
||||
m_current_rasterization_state(RenderState::GetInvalidRasterizationState()),
|
||||
m_current_depth_state(RenderState::GetInvalidDepthState()),
|
||||
m_current_blend_state(RenderState::GetInvalidBlendingState()),
|
||||
m_backbuffer_scale(backbuffer_scale)
|
||||
{
|
||||
// Create the window framebuffer.
|
||||
if (!m_main_gl_context->IsHeadless())
|
||||
{
|
||||
m_system_framebuffer = std::make_unique<OGLFramebuffer>(
|
||||
nullptr, nullptr, AbstractTextureFormat::RGBA8, AbstractTextureFormat::Undefined,
|
||||
std::max(m_main_gl_context->GetBackBufferWidth(), 1u),
|
||||
std::max(m_main_gl_context->GetBackBufferHeight(), 1u), 1, 1, g_Config.iRenderFBO);
|
||||
m_current_framebuffer = m_system_framebuffer.get();
|
||||
}
|
||||
|
||||
if (!m_main_gl_context->IsGLES())
|
||||
{
|
||||
// OpenGL 3 doesn't provide GLES like float functions for depth.
|
||||
// They are in core in OpenGL 4.1, so almost every driver should support them.
|
||||
// But for the oldest ones, we provide fallbacks to the old double functions.
|
||||
if (!GLExtensions::Supports("GL_ARB_ES2_compatibility"))
|
||||
{
|
||||
glDepthRangef = DepthRangef;
|
||||
glClearDepthf = ClearDepthf;
|
||||
}
|
||||
}
|
||||
|
||||
if (!PopulateConfig(m_main_gl_context.get()))
|
||||
{
|
||||
// Not all needed extensions are supported, so we have to stop here.
|
||||
// Else some of the next calls might crash.
|
||||
return;
|
||||
}
|
||||
InitDriverInfo();
|
||||
|
||||
// Setup Debug logging
|
||||
if (g_ogl_config.bSupportsDebug)
|
||||
{
|
||||
if (GLExtensions::Supports("GL_KHR_debug"))
|
||||
{
|
||||
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, true);
|
||||
glDebugMessageCallback(ErrorCallback, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, true);
|
||||
glDebugMessageCallbackARB(ErrorCallback, nullptr);
|
||||
}
|
||||
if (Common::Log::LogManager::GetInstance()->IsEnabled(Common::Log::LogType::HOST_GPU,
|
||||
Common::Log::LogLevel::LERROR))
|
||||
{
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_DEBUG_OUTPUT);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle VSync on/off
|
||||
if (!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_VSYNC))
|
||||
m_main_gl_context->SwapInterval(g_ActiveConfig.bVSyncActive);
|
||||
|
||||
if (g_ActiveConfig.backend_info.bSupportsClipControl)
|
||||
glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
|
||||
|
||||
if (g_ActiveConfig.backend_info.bSupportsDepthClamp)
|
||||
{
|
||||
glEnable(GL_CLIP_DISTANCE0);
|
||||
glEnable(GL_CLIP_DISTANCE1);
|
||||
glEnable(GL_DEPTH_CLAMP);
|
||||
}
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment
|
||||
|
||||
glGenFramebuffers(1, &m_shared_read_framebuffer);
|
||||
glGenFramebuffers(1, &m_shared_draw_framebuffer);
|
||||
|
||||
if (g_ActiveConfig.backend_info.bSupportsPrimitiveRestart)
|
||||
GLUtil::EnablePrimitiveRestart(m_main_gl_context.get());
|
||||
|
||||
UpdateActiveConfig();
|
||||
}
|
||||
|
||||
OGLGfx::~OGLGfx()
|
||||
{
|
||||
glDeleteFramebuffers(1, &m_shared_draw_framebuffer);
|
||||
glDeleteFramebuffers(1, &m_shared_read_framebuffer);
|
||||
}
|
||||
|
||||
bool OGLGfx::IsHeadless() const
|
||||
{
|
||||
return m_main_gl_context->IsHeadless();
|
||||
}
|
||||
|
||||
std::unique_ptr<AbstractTexture> OGLGfx::CreateTexture(const TextureConfig& config,
|
||||
std::string_view name)
|
||||
{
|
||||
return std::make_unique<OGLTexture>(config, name);
|
||||
}
|
||||
|
||||
std::unique_ptr<AbstractStagingTexture> OGLGfx::CreateStagingTexture(StagingTextureType type,
|
||||
const TextureConfig& config)
|
||||
{
|
||||
return OGLStagingTexture::Create(type, config);
|
||||
}
|
||||
|
||||
std::unique_ptr<AbstractFramebuffer> OGLGfx::CreateFramebuffer(AbstractTexture* color_attachment,
|
||||
AbstractTexture* depth_attachment)
|
||||
{
|
||||
return OGLFramebuffer::Create(static_cast<OGLTexture*>(color_attachment),
|
||||
static_cast<OGLTexture*>(depth_attachment));
|
||||
}
|
||||
|
||||
std::unique_ptr<AbstractShader>
|
||||
OGLGfx::CreateShaderFromSource(ShaderStage stage, std::string_view source, std::string_view name)
|
||||
{
|
||||
return OGLShader::CreateFromSource(stage, source, name);
|
||||
}
|
||||
|
||||
std::unique_ptr<AbstractShader>
|
||||
OGLGfx::CreateShaderFromBinary(ShaderStage stage, const void* data, size_t length,
|
||||
[[maybe_unused]] std::string_view name)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<AbstractPipeline> OGLGfx::CreatePipeline(const AbstractPipelineConfig& config,
|
||||
const void* cache_data,
|
||||
size_t cache_data_length)
|
||||
{
|
||||
return OGLPipeline::Create(config, cache_data, cache_data_length);
|
||||
}
|
||||
|
||||
void OGLGfx::SetScissorRect(const MathUtil::Rectangle<int>& rc)
|
||||
{
|
||||
glScissor(rc.left, rc.top, rc.GetWidth(), rc.GetHeight());
|
||||
}
|
||||
|
||||
void OGLGfx::SetViewport(float x, float y, float width, float height, float near_depth,
|
||||
float far_depth)
|
||||
{
|
||||
if (g_ogl_config.bSupportViewportFloat)
|
||||
{
|
||||
glViewportIndexedf(0, x, y, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto iceilf = [](float f) { return static_cast<GLint>(std::ceil(f)); };
|
||||
glViewport(iceilf(x), iceilf(y), iceilf(width), iceilf(height));
|
||||
}
|
||||
|
||||
glDepthRangef(near_depth, far_depth);
|
||||
}
|
||||
|
||||
void OGLGfx::Draw(u32 base_vertex, u32 num_vertices)
|
||||
{
|
||||
glDrawArrays(static_cast<const OGLPipeline*>(m_current_pipeline)->GetGLPrimitive(), base_vertex,
|
||||
num_vertices);
|
||||
}
|
||||
|
||||
void OGLGfx::DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex)
|
||||
{
|
||||
if (g_ogl_config.bSupportsGLBaseVertex)
|
||||
{
|
||||
glDrawElementsBaseVertex(static_cast<const OGLPipeline*>(m_current_pipeline)->GetGLPrimitive(),
|
||||
num_indices, GL_UNSIGNED_SHORT,
|
||||
static_cast<u16*>(nullptr) + base_index, base_vertex);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDrawElements(static_cast<const OGLPipeline*>(m_current_pipeline)->GetGLPrimitive(),
|
||||
num_indices, GL_UNSIGNED_SHORT, static_cast<u16*>(nullptr) + base_index);
|
||||
}
|
||||
}
|
||||
|
||||
void OGLGfx::DispatchComputeShader(const AbstractShader* shader, u32 groupsize_x, u32 groupsize_y,
|
||||
u32 groupsize_z, u32 groups_x, u32 groups_y, u32 groups_z)
|
||||
{
|
||||
glUseProgram(static_cast<const OGLShader*>(shader)->GetGLComputeProgramID());
|
||||
glDispatchCompute(groups_x, groups_y, groups_z);
|
||||
|
||||
// We messed up the program binding, so restore it.
|
||||
ProgramShaderCache::InvalidateLastProgram();
|
||||
if (m_current_pipeline)
|
||||
static_cast<const OGLPipeline*>(m_current_pipeline)->GetProgram()->shader.Bind();
|
||||
|
||||
// Barrier to texture can be used for reads.
|
||||
if (m_bound_image_texture)
|
||||
glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
|
||||
}
|
||||
|
||||
void OGLGfx::SelectLeftBuffer()
|
||||
{
|
||||
glDrawBuffer(GL_BACK_LEFT);
|
||||
}
|
||||
|
||||
void OGLGfx::SelectRightBuffer()
|
||||
{
|
||||
glDrawBuffer(GL_BACK_RIGHT);
|
||||
}
|
||||
|
||||
void OGLGfx::SelectMainBuffer()
|
||||
{
|
||||
glDrawBuffer(GL_BACK);
|
||||
}
|
||||
|
||||
void OGLGfx::SetFramebuffer(AbstractFramebuffer* framebuffer)
|
||||
{
|
||||
if (m_current_framebuffer == framebuffer)
|
||||
return;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, static_cast<OGLFramebuffer*>(framebuffer)->GetFBO());
|
||||
m_current_framebuffer = framebuffer;
|
||||
}
|
||||
|
||||
void OGLGfx::SetAndDiscardFramebuffer(AbstractFramebuffer* framebuffer)
|
||||
{
|
||||
// EXT_discard_framebuffer could be used here to save bandwidth on tilers.
|
||||
SetFramebuffer(framebuffer);
|
||||
}
|
||||
|
||||
void OGLGfx::SetAndClearFramebuffer(AbstractFramebuffer* framebuffer, const ClearColor& color_value,
|
||||
float depth_value)
|
||||
{
|
||||
SetFramebuffer(framebuffer);
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
GLbitfield clear_mask = 0;
|
||||
if (framebuffer->HasColorBuffer())
|
||||
{
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glClearColor(color_value[0], color_value[1], color_value[2], color_value[3]);
|
||||
clear_mask |= GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
if (framebuffer->HasDepthBuffer())
|
||||
{
|
||||
glDepthMask(GL_TRUE);
|
||||
glClearDepthf(depth_value);
|
||||
clear_mask |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
glClear(clear_mask);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
// Restore color/depth mask.
|
||||
if (framebuffer->HasColorBuffer())
|
||||
{
|
||||
glColorMask(m_current_blend_state.colorupdate, m_current_blend_state.colorupdate,
|
||||
m_current_blend_state.colorupdate, m_current_blend_state.alphaupdate);
|
||||
}
|
||||
if (framebuffer->HasDepthBuffer())
|
||||
glDepthMask(m_current_depth_state.updateenable);
|
||||
}
|
||||
|
||||
void OGLGfx::ClearRegion(const MathUtil::Rectangle<int>& target_rc, bool colorEnable,
|
||||
bool alphaEnable, bool zEnable, u32 color, u32 z)
|
||||
{
|
||||
u32 clear_mask = 0;
|
||||
if (colorEnable || alphaEnable)
|
||||
{
|
||||
glColorMask(colorEnable, colorEnable, colorEnable, alphaEnable);
|
||||
glClearColor(float((color >> 16) & 0xFF) / 255.0f, float((color >> 8) & 0xFF) / 255.0f,
|
||||
float((color >> 0) & 0xFF) / 255.0f, float((color >> 24) & 0xFF) / 255.0f);
|
||||
clear_mask = GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
if (zEnable)
|
||||
{
|
||||
glDepthMask(zEnable ? GL_TRUE : GL_FALSE);
|
||||
glClearDepthf(float(z & 0xFFFFFF) / 16777216.0f);
|
||||
clear_mask |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
|
||||
// Update rect for clearing the picture
|
||||
// glColorMask/glDepthMask/glScissor affect glClear (glViewport does not)
|
||||
g_gfx->SetScissorRect(target_rc);
|
||||
|
||||
glClear(clear_mask);
|
||||
|
||||
// Restore color/depth mask.
|
||||
if (colorEnable || alphaEnable)
|
||||
{
|
||||
glColorMask(m_current_blend_state.colorupdate, m_current_blend_state.colorupdate,
|
||||
m_current_blend_state.colorupdate, m_current_blend_state.alphaupdate);
|
||||
}
|
||||
if (zEnable)
|
||||
glDepthMask(m_current_depth_state.updateenable);
|
||||
}
|
||||
|
||||
void OGLGfx::BindBackbuffer(const ClearColor& clear_color)
|
||||
{
|
||||
CheckForSurfaceChange();
|
||||
CheckForSurfaceResize();
|
||||
SetAndClearFramebuffer(m_system_framebuffer.get(), clear_color);
|
||||
}
|
||||
|
||||
void OGLGfx::PresentBackbuffer()
|
||||
{
|
||||
if (g_ogl_config.bSupportsDebug)
|
||||
{
|
||||
if (Common::Log::LogManager::GetInstance()->IsEnabled(Common::Log::LogType::HOST_GPU,
|
||||
Common::Log::LogLevel::LERROR))
|
||||
{
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_DEBUG_OUTPUT);
|
||||
}
|
||||
}
|
||||
|
||||
// Swap the back and front buffers, presenting the image.
|
||||
m_main_gl_context->Swap();
|
||||
}
|
||||
|
||||
void OGLGfx::OnConfigChanged(u32 bits)
|
||||
{
|
||||
AbstractGfx::OnConfigChanged(bits);
|
||||
|
||||
if (bits & CONFIG_CHANGE_BIT_VSYNC && !DriverDetails::HasBug(DriverDetails::BUG_BROKEN_VSYNC))
|
||||
m_main_gl_context->SwapInterval(g_ActiveConfig.bVSyncActive);
|
||||
|
||||
if (bits & CONFIG_CHANGE_BIT_ANISOTROPY)
|
||||
g_sampler_cache->Clear();
|
||||
}
|
||||
|
||||
void OGLGfx::Flush()
|
||||
{
|
||||
// ensure all commands are sent to the GPU.
|
||||
// Otherwise the driver could batch several frames together.
|
||||
glFlush();
|
||||
}
|
||||
|
||||
void OGLGfx::WaitForGPUIdle()
|
||||
{
|
||||
glFinish();
|
||||
}
|
||||
|
||||
void OGLGfx::CheckForSurfaceChange()
|
||||
{
|
||||
if (!g_presenter->SurfaceChangedTestAndClear())
|
||||
return;
|
||||
|
||||
m_main_gl_context->UpdateSurface(g_presenter->GetNewSurfaceHandle());
|
||||
|
||||
u32 width = m_main_gl_context->GetBackBufferWidth();
|
||||
u32 height = m_main_gl_context->GetBackBufferHeight();
|
||||
|
||||
// With a surface change, the window likely has new dimensions.
|
||||
g_presenter->SetBackbuffer(width, height);
|
||||
m_system_framebuffer->UpdateDimensions(width, height);
|
||||
}
|
||||
|
||||
void OGLGfx::CheckForSurfaceResize()
|
||||
{
|
||||
if (!g_presenter->SurfaceResizedTestAndClear())
|
||||
return;
|
||||
|
||||
m_main_gl_context->Update();
|
||||
u32 width = m_main_gl_context->GetBackBufferWidth();
|
||||
u32 height = m_main_gl_context->GetBackBufferHeight();
|
||||
g_presenter->SetBackbuffer(width, height);
|
||||
m_system_framebuffer->UpdateDimensions(width, height);
|
||||
}
|
||||
|
||||
void OGLGfx::BeginUtilityDrawing()
|
||||
{
|
||||
AbstractGfx::BeginUtilityDrawing();
|
||||
if (g_ActiveConfig.backend_info.bSupportsDepthClamp)
|
||||
{
|
||||
glDisable(GL_CLIP_DISTANCE0);
|
||||
glDisable(GL_CLIP_DISTANCE1);
|
||||
}
|
||||
}
|
||||
|
||||
void OGLGfx::EndUtilityDrawing()
|
||||
{
|
||||
AbstractGfx::EndUtilityDrawing();
|
||||
if (g_ActiveConfig.backend_info.bSupportsDepthClamp)
|
||||
{
|
||||
glEnable(GL_CLIP_DISTANCE0);
|
||||
glEnable(GL_CLIP_DISTANCE1);
|
||||
}
|
||||
}
|
||||
|
||||
void OGLGfx::ApplyRasterizationState(const RasterizationState state)
|
||||
{
|
||||
if (m_current_rasterization_state == state)
|
||||
return;
|
||||
|
||||
// none, ccw, cw, ccw
|
||||
if (state.cullmode != CullMode::None)
|
||||
{
|
||||
// TODO: GX_CULL_ALL not supported, yet!
|
||||
glEnable(GL_CULL_FACE);
|
||||
glFrontFace(state.cullmode == CullMode::Front ? GL_CCW : GL_CW);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
m_current_rasterization_state = state;
|
||||
}
|
||||
|
||||
void OGLGfx::ApplyDepthState(const DepthState state)
|
||||
{
|
||||
if (m_current_depth_state == state)
|
||||
return;
|
||||
|
||||
const GLenum glCmpFuncs[8] = {GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL,
|
||||
GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, GL_ALWAYS};
|
||||
|
||||
if (state.testenable)
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(state.updateenable ? GL_TRUE : GL_FALSE);
|
||||
glDepthFunc(glCmpFuncs[u32(state.func.Value())]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if the test is disabled write is disabled too
|
||||
// TODO: When PE performance metrics are being emulated via occlusion queries, we should
|
||||
// (probably?) enable depth test with depth function ALWAYS here
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
}
|
||||
|
||||
m_current_depth_state = state;
|
||||
}
|
||||
|
||||
void OGLGfx::ApplyBlendingState(const BlendingState state)
|
||||
{
|
||||
if (m_current_blend_state == state)
|
||||
return;
|
||||
|
||||
bool useDualSource = state.usedualsrc;
|
||||
|
||||
const GLenum src_factors[8] = {GL_ZERO,
|
||||
GL_ONE,
|
||||
GL_DST_COLOR,
|
||||
GL_ONE_MINUS_DST_COLOR,
|
||||
useDualSource ? GL_SRC1_ALPHA : (GLenum)GL_SRC_ALPHA,
|
||||
useDualSource ? GL_ONE_MINUS_SRC1_ALPHA :
|
||||
(GLenum)GL_ONE_MINUS_SRC_ALPHA,
|
||||
GL_DST_ALPHA,
|
||||
GL_ONE_MINUS_DST_ALPHA};
|
||||
const GLenum dst_factors[8] = {GL_ZERO,
|
||||
GL_ONE,
|
||||
GL_SRC_COLOR,
|
||||
GL_ONE_MINUS_SRC_COLOR,
|
||||
useDualSource ? GL_SRC1_ALPHA : (GLenum)GL_SRC_ALPHA,
|
||||
useDualSource ? GL_ONE_MINUS_SRC1_ALPHA :
|
||||
(GLenum)GL_ONE_MINUS_SRC_ALPHA,
|
||||
GL_DST_ALPHA,
|
||||
GL_ONE_MINUS_DST_ALPHA};
|
||||
|
||||
if (state.blendenable)
|
||||
glEnable(GL_BLEND);
|
||||
else
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
// Always call glBlendEquationSeparate and glBlendFuncSeparate, even when
|
||||
// GL_BLEND is disabled, as a workaround for some bugs (possibly graphics
|
||||
// driver issues?). See https://bugs.dolphin-emu.org/issues/10120 : "Sonic
|
||||
// Adventure 2 Battle: graphics crash when loading first Dark level"
|
||||
GLenum equation = state.subtract ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD;
|
||||
GLenum equationAlpha = state.subtractAlpha ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD;
|
||||
glBlendEquationSeparate(equation, equationAlpha);
|
||||
glBlendFuncSeparate(src_factors[u32(state.srcfactor.Value())],
|
||||
dst_factors[u32(state.dstfactor.Value())],
|
||||
src_factors[u32(state.srcfactoralpha.Value())],
|
||||
dst_factors[u32(state.dstfactoralpha.Value())]);
|
||||
|
||||
const GLenum logic_op_codes[16] = {
|
||||
GL_CLEAR, GL_AND, GL_AND_REVERSE, GL_COPY, GL_AND_INVERTED, GL_NOOP,
|
||||
GL_XOR, GL_OR, GL_NOR, GL_EQUIV, GL_INVERT, GL_OR_REVERSE,
|
||||
GL_COPY_INVERTED, GL_OR_INVERTED, GL_NAND, GL_SET};
|
||||
|
||||
// Logic ops aren't available in GLES3
|
||||
if (!IsGLES())
|
||||
{
|
||||
if (state.logicopenable)
|
||||
{
|
||||
glEnable(GL_COLOR_LOGIC_OP);
|
||||
glLogicOp(logic_op_codes[u32(state.logicmode.Value())]);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
}
|
||||
}
|
||||
|
||||
glColorMask(state.colorupdate, state.colorupdate, state.colorupdate, state.alphaupdate);
|
||||
m_current_blend_state = state;
|
||||
}
|
||||
|
||||
void OGLGfx::SetPipeline(const AbstractPipeline* pipeline)
|
||||
{
|
||||
if (m_current_pipeline == pipeline)
|
||||
return;
|
||||
|
||||
if (pipeline)
|
||||
{
|
||||
ApplyRasterizationState(static_cast<const OGLPipeline*>(pipeline)->GetRasterizationState());
|
||||
ApplyDepthState(static_cast<const OGLPipeline*>(pipeline)->GetDepthState());
|
||||
ApplyBlendingState(static_cast<const OGLPipeline*>(pipeline)->GetBlendingState());
|
||||
ProgramShaderCache::BindVertexFormat(
|
||||
static_cast<const OGLPipeline*>(pipeline)->GetVertexFormat());
|
||||
static_cast<const OGLPipeline*>(pipeline)->GetProgram()->shader.Bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
ProgramShaderCache::InvalidateLastProgram();
|
||||
glUseProgram(0);
|
||||
}
|
||||
m_current_pipeline = pipeline;
|
||||
}
|
||||
|
||||
void OGLGfx::SetTexture(u32 index, const AbstractTexture* texture)
|
||||
{
|
||||
const OGLTexture* gl_texture = static_cast<const OGLTexture*>(texture);
|
||||
if (m_bound_textures[index] == gl_texture)
|
||||
return;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + index);
|
||||
if (gl_texture)
|
||||
glBindTexture(gl_texture->GetGLTarget(), gl_texture->GetGLTextureId());
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
|
||||
m_bound_textures[index] = gl_texture;
|
||||
}
|
||||
|
||||
void OGLGfx::SetSamplerState(u32 index, const SamplerState& state)
|
||||
{
|
||||
g_sampler_cache->SetSamplerState(index, state);
|
||||
}
|
||||
|
||||
void OGLGfx::SetComputeImageTexture(AbstractTexture* texture, bool read, bool write)
|
||||
{
|
||||
if (m_bound_image_texture == texture)
|
||||
return;
|
||||
|
||||
if (texture)
|
||||
{
|
||||
const GLenum access = read ? (write ? GL_READ_WRITE : GL_READ_ONLY) : GL_WRITE_ONLY;
|
||||
glBindImageTexture(0, static_cast<OGLTexture*>(texture)->GetGLTextureId(), 0, GL_TRUE, 0,
|
||||
access, static_cast<OGLTexture*>(texture)->GetGLFormatForImageTexture());
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindImageTexture(0, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
|
||||
}
|
||||
|
||||
m_bound_image_texture = texture;
|
||||
}
|
||||
|
||||
void OGLGfx::UnbindTexture(const AbstractTexture* texture)
|
||||
{
|
||||
for (size_t i = 0; i < m_bound_textures.size(); i++)
|
||||
{
|
||||
if (m_bound_textures[i] != texture)
|
||||
continue;
|
||||
|
||||
glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + i));
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
|
||||
m_bound_textures[i] = nullptr;
|
||||
}
|
||||
|
||||
if (m_bound_image_texture == texture)
|
||||
{
|
||||
glBindImageTexture(0, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
|
||||
m_bound_image_texture = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoCommon::AsyncShaderCompiler> OGLGfx::CreateAsyncShaderCompiler()
|
||||
{
|
||||
return std::make_unique<SharedContextAsyncShaderCompiler>();
|
||||
}
|
||||
|
||||
bool OGLGfx::IsGLES() const
|
||||
{
|
||||
return m_main_gl_context->IsGLES();
|
||||
}
|
||||
|
||||
void OGLGfx::BindSharedReadFramebuffer()
|
||||
{
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_shared_read_framebuffer);
|
||||
}
|
||||
|
||||
void OGLGfx::BindSharedDrawFramebuffer()
|
||||
{
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_shared_draw_framebuffer);
|
||||
}
|
||||
|
||||
void OGLGfx::RestoreFramebufferBinding()
|
||||
{
|
||||
glBindFramebuffer(
|
||||
GL_FRAMEBUFFER,
|
||||
m_current_framebuffer ? static_cast<OGLFramebuffer*>(m_current_framebuffer)->GetFBO() : 0);
|
||||
}
|
||||
|
||||
SurfaceInfo OGLGfx::GetSurfaceInfo() const
|
||||
{
|
||||
return {std::max(m_main_gl_context->GetBackBufferWidth(), 1u),
|
||||
std::max(m_main_gl_context->GetBackBufferHeight(), 1u), m_backbuffer_scale,
|
||||
AbstractTextureFormat::RGBA8};
|
||||
}
|
||||
|
||||
} // namespace OGL
|
||||
@@ -1,27 +0,0 @@
|
||||
// Copyright (c) 2022, OpenEmu Team
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the OpenEmu Team nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY OpenEmu Team ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL OpenEmu Team BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifdef __x86_64__
|
||||
#include "../../dolphin/Source/Core/VideoCommon/TextureDecoder_x64.cpp"
|
||||
#endif
|
||||
@@ -1,29 +0,0 @@
|
||||
// Copyright (c) 2022, OpenEmu Team
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the OpenEmu Team nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY OpenEmu Team ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL OpenEmu Team BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifdef __x86_64__
|
||||
#include "../../dolphin/Source/Core/VideoCommon/VertexLoaderX64.cpp"
|
||||
#elif defined(__arm64__)
|
||||
#include "../../dolphin/Source/Core/VideoCommon/VertexLoaderARM64.cpp"
|
||||
#endif
|
||||
@@ -1,338 +0,0 @@
|
||||
//// Copyright 2008 Dolphin Emulator Project
|
||||
//// Licensed under GPLv2+
|
||||
// Copyright 2008 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// IMPORTANT: UI etc should modify g_Config. Graphics code should read g_ActiveConfig.
|
||||
// The reason for this is to get rid of race conditions etc when the configuration
|
||||
// changes in the middle of a frame. This is done by copying g_Config to g_ActiveConfig
|
||||
// at the start of every frame. Noone should ever change members of g_ActiveConfig
|
||||
// directly.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "VideoCommon/GraphicsModSystem/Config/GraphicsModGroup.h"
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
|
||||
enum class APIType;
|
||||
|
||||
// Log in two categories, and save three other options in the same byte
|
||||
#define CONF_LOG 1
|
||||
#define CONF_PRIMLOG 2
|
||||
#define CONF_SAVETARGETS 8
|
||||
#define CONF_SAVESHADERS 16
|
||||
|
||||
constexpr int EFB_SCALE_AUTO_INTEGRAL = 0;
|
||||
|
||||
enum class AspectMode : int
|
||||
{
|
||||
Auto,
|
||||
AnalogWide,
|
||||
Analog,
|
||||
Stretch,
|
||||
};
|
||||
|
||||
enum class StereoMode : int
|
||||
{
|
||||
Off,
|
||||
SBS,
|
||||
TAB,
|
||||
Anaglyph,
|
||||
QuadBuffer,
|
||||
Passive
|
||||
};
|
||||
|
||||
enum class ShaderCompilationMode : int
|
||||
{
|
||||
Synchronous,
|
||||
SynchronousUberShaders,
|
||||
AsynchronousUberShaders,
|
||||
AsynchronousSkipRendering
|
||||
};
|
||||
|
||||
enum class TextureFilteringMode : int
|
||||
{
|
||||
Default,
|
||||
Nearest,
|
||||
Linear,
|
||||
};
|
||||
|
||||
enum class TriState : int
|
||||
{
|
||||
Off,
|
||||
On,
|
||||
Auto
|
||||
};
|
||||
|
||||
// Bitmask containing information about which configuration has changed for the backend.
|
||||
enum ConfigChangeBits : u32
|
||||
{
|
||||
CONFIG_CHANGE_BIT_HOST_CONFIG = (1 << 0),
|
||||
CONFIG_CHANGE_BIT_MULTISAMPLES = (1 << 1),
|
||||
CONFIG_CHANGE_BIT_STEREO_MODE = (1 << 2),
|
||||
CONFIG_CHANGE_BIT_TARGET_SIZE = (1 << 3),
|
||||
CONFIG_CHANGE_BIT_ANISOTROPY = (1 << 4),
|
||||
CONFIG_CHANGE_BIT_FORCE_TEXTURE_FILTERING = (1 << 5),
|
||||
CONFIG_CHANGE_BIT_VSYNC = (1 << 6),
|
||||
CONFIG_CHANGE_BIT_BBOX = (1 << 7),
|
||||
CONFIG_CHANGE_BIT_ASPECT_RATIO = (1 << 8),
|
||||
CONFIG_CHANGE_BIT_POST_PROCESSING_SHADER = (1 << 9),
|
||||
};
|
||||
|
||||
// NEVER inherit from this class.
|
||||
struct VideoConfig final
|
||||
{
|
||||
VideoConfig() = default;
|
||||
void Refresh();
|
||||
void VerifyValidity();
|
||||
|
||||
// General
|
||||
bool bVSync = false;
|
||||
bool bVSyncActive = false;
|
||||
bool bWidescreenHack = false;
|
||||
AspectMode aspect_mode{};
|
||||
AspectMode suggested_aspect_mode{};
|
||||
bool bCrop = false; // Aspect ratio controls.
|
||||
bool bShaderCache = false;
|
||||
|
||||
// Enhancements
|
||||
u32 iMultisamples = 0;
|
||||
bool bSSAA = false;
|
||||
int iEFBScale = 0;
|
||||
TextureFilteringMode texture_filtering_mode = TextureFilteringMode::Default;
|
||||
int iMaxAnisotropy = 0;
|
||||
std::string sPostProcessingShader;
|
||||
bool bForceTrueColor = false;
|
||||
bool bDisableCopyFilter = false;
|
||||
bool bArbitraryMipmapDetection = false;
|
||||
float fArbitraryMipmapDetectionThreshold = 0;
|
||||
|
||||
// Information
|
||||
bool bShowFPS = false;
|
||||
bool bShowFTimes = false;
|
||||
bool bShowVPS = false;
|
||||
bool bShowVTimes = false;
|
||||
bool bShowGraphs = false;
|
||||
bool bShowSpeed = false;
|
||||
bool bShowSpeedColors = false;
|
||||
int iPerfSampleUSec = 0;
|
||||
bool bShowNetPlayPing = false;
|
||||
bool bShowNetPlayMessages = false;
|
||||
bool bOverlayStats = false;
|
||||
bool bOverlayProjStats = false;
|
||||
bool bOverlayScissorStats = false;
|
||||
bool bTexFmtOverlayEnable = false;
|
||||
bool bTexFmtOverlayCenter = false;
|
||||
bool bLogRenderTimeToFile = false;
|
||||
|
||||
// Render
|
||||
bool bWireFrame;
|
||||
bool bDisableFog;
|
||||
|
||||
// OpenEmu render buffer
|
||||
int iRenderFBO = 0;
|
||||
|
||||
// Utility
|
||||
bool bDumpTextures = false;
|
||||
bool bDumpMipmapTextures = false;
|
||||
bool bDumpBaseTextures = false;
|
||||
bool bHiresTextures = false;
|
||||
bool bCacheHiresTextures = false;
|
||||
bool bDumpEFBTarget = false;
|
||||
bool bDumpXFBTarget = false;
|
||||
bool bDumpFramesAsImages = false;
|
||||
bool bUseFFV1 = false;
|
||||
std::string sDumpCodec;
|
||||
std::string sDumpPixelFormat;
|
||||
std::string sDumpEncoder;
|
||||
std::string sDumpFormat;
|
||||
std::string sDumpPath;
|
||||
bool bInternalResolutionFrameDumps = false;
|
||||
bool bBorderlessFullscreen = false;
|
||||
bool bEnableGPUTextureDecoding = false;
|
||||
bool bPreferVSForLinePointExpansion = false;
|
||||
int iBitrateKbps = 0;
|
||||
bool bGraphicMods = false;
|
||||
std::optional<GraphicsModGroupConfig> graphics_mod_config;
|
||||
|
||||
// Hacks
|
||||
bool bEFBAccessEnable = false;
|
||||
bool bEFBAccessDeferInvalidation = false;
|
||||
bool bPerfQueriesEnable = false;
|
||||
bool bBBoxEnable = false;
|
||||
bool bForceProgressive = false;
|
||||
bool bCPUCull = false;
|
||||
|
||||
bool bEFBEmulateFormatChanges = false;
|
||||
bool bSkipEFBCopyToRam = false;
|
||||
bool bSkipXFBCopyToRam = false;
|
||||
bool bDisableCopyToVRAM = false;
|
||||
bool bDeferEFBCopies = false;
|
||||
bool bImmediateXFB = false;
|
||||
bool bSkipPresentingDuplicateXFBs = false;
|
||||
bool bCopyEFBScaled = false;
|
||||
int iSafeTextureCache_ColorSamples = 0;
|
||||
float fAspectRatioHackW = 1; // Initial value needed for the first frame
|
||||
float fAspectRatioHackH = 1;
|
||||
bool bEnablePixelLighting = false;
|
||||
bool bFastDepthCalc = false;
|
||||
bool bVertexRounding = false;
|
||||
bool bVISkip = false;
|
||||
int iEFBAccessTileSize = 0;
|
||||
int iSaveTargetId = 0; // TODO: Should be dropped
|
||||
u32 iMissingColorValue = 0;
|
||||
bool bFastTextureSampling = false;
|
||||
#ifdef __APPLE__
|
||||
bool bNoMipmapping = false; // Used by macOS fifoci to work around an M1 bug
|
||||
#endif
|
||||
|
||||
// Stereoscopy
|
||||
StereoMode stereo_mode{};
|
||||
int iStereoDepth = 0;
|
||||
int iStereoConvergence = 0;
|
||||
int iStereoConvergencePercentage = 0;
|
||||
bool bStereoSwapEyes = false;
|
||||
bool bStereoEFBMonoDepth = false;
|
||||
int iStereoDepthPercentage = 0;
|
||||
|
||||
// D3D only config, mostly to be merged into the above
|
||||
int iAdapter = 0;
|
||||
|
||||
// Metal only config
|
||||
TriState iManuallyUploadBuffers = TriState::Auto;
|
||||
TriState iUsePresentDrawable = TriState::Auto;
|
||||
|
||||
// Enable API validation layers, currently only supported with Vulkan.
|
||||
bool bEnableValidationLayer = false;
|
||||
|
||||
// Multithreaded submission, currently only supported with Vulkan.
|
||||
bool bBackendMultithreading = true;
|
||||
|
||||
// Early command buffer execution interval in number of draws.
|
||||
// Currently only supported with Vulkan.
|
||||
int iCommandBufferExecuteInterval = 0;
|
||||
|
||||
// Shader compilation settings.
|
||||
bool bWaitForShadersBeforeStarting = false;
|
||||
ShaderCompilationMode iShaderCompilationMode{};
|
||||
|
||||
// Number of shader compiler threads.
|
||||
// 0 disables background compilation.
|
||||
// -1 uses an automatic number based on the CPU threads.
|
||||
int iShaderCompilerThreads = 0;
|
||||
int iShaderPrecompilerThreads = 0;
|
||||
|
||||
// Static config per API
|
||||
// TODO: Move this out of VideoConfig
|
||||
struct
|
||||
{
|
||||
APIType api_type = APIType::Nothing;
|
||||
std::string DisplayName;
|
||||
|
||||
std::vector<std::string> Adapters; // for D3D
|
||||
std::vector<u32> AAModes;
|
||||
|
||||
// TODO: merge AdapterName and Adapters array
|
||||
std::string AdapterName; // for OpenGL
|
||||
|
||||
u32 MaxTextureSize = 16384;
|
||||
bool bUsesLowerLeftOrigin = false;
|
||||
bool bUsesExplictQuadBuffering = false;
|
||||
|
||||
bool bSupportsExclusiveFullscreen = false;
|
||||
bool bSupportsDualSourceBlend = false;
|
||||
bool bSupportsPrimitiveRestart = false;
|
||||
bool bSupportsGeometryShaders = false;
|
||||
bool bSupportsComputeShaders = false;
|
||||
bool bSupports3DVision = false;
|
||||
bool bSupportsEarlyZ = false; // needed by PixelShaderGen, so must stay in VideoCommon
|
||||
bool bSupportsBindingLayout = false; // Needed by ShaderGen, so must stay in VideoCommon
|
||||
bool bSupportsBBox = false;
|
||||
bool bSupportsGSInstancing = false; // Needed by GeometryShaderGen, so must stay in VideoCommon
|
||||
bool bSupportsPostProcessing = false;
|
||||
bool bSupportsPaletteConversion = false;
|
||||
bool bSupportsClipControl = false; // Needed by VertexShaderGen, so must stay in VideoCommon
|
||||
bool bSupportsSSAA = false;
|
||||
bool bSupportsFragmentStoresAndAtomics = false; // a.k.a. OpenGL SSBOs a.k.a. Direct3D UAVs
|
||||
bool bSupportsDepthClamp = false; // Needed by VertexShaderGen, so must stay in VideoCommon
|
||||
bool bSupportsReversedDepthRange = false;
|
||||
bool bSupportsLogicOp = false;
|
||||
bool bSupportsMultithreading = false;
|
||||
bool bSupportsGPUTextureDecoding = false;
|
||||
bool bSupportsST3CTextures = false;
|
||||
bool bSupportsCopyToVram = false;
|
||||
bool bSupportsBitfield = false; // Needed by UberShaders, so must stay in VideoCommon
|
||||
// Needed by UberShaders, so must stay in VideoCommon
|
||||
bool bSupportsDynamicSamplerIndexing = false;
|
||||
bool bSupportsBPTCTextures = false;
|
||||
bool bSupportsFramebufferFetch = false; // Used as an alternative to dual-source blend on GLES
|
||||
bool bSupportsBackgroundCompiling = false;
|
||||
bool bSupportsLargePoints = false;
|
||||
bool bSupportsPartialDepthCopies = false;
|
||||
bool bSupportsDepthReadback = false;
|
||||
bool bSupportsShaderBinaries = false;
|
||||
bool bSupportsPipelineCacheData = false;
|
||||
bool bSupportsCoarseDerivatives = false;
|
||||
bool bSupportsTextureQueryLevels = false;
|
||||
bool bSupportsLodBiasInSampler = false;
|
||||
bool bSupportsSettingObjectNames = false;
|
||||
bool bSupportsPartialMultisampleResolve = false;
|
||||
bool bSupportsDynamicVertexLoader = false;
|
||||
bool bSupportsVSLinePointExpand = false;
|
||||
bool bSupportsGLLayerInFS = true;
|
||||
} backend_info;
|
||||
|
||||
// Utility
|
||||
bool UseVSForLinePointExpand() const
|
||||
{
|
||||
if (!backend_info.bSupportsVSLinePointExpand)
|
||||
return false;
|
||||
if (!backend_info.bSupportsGeometryShaders)
|
||||
return true;
|
||||
return bPreferVSForLinePointExpansion;
|
||||
}
|
||||
bool MultisamplingEnabled() const { return iMultisamples > 1; }
|
||||
bool ExclusiveFullscreenEnabled() const
|
||||
{
|
||||
return backend_info.bSupportsExclusiveFullscreen && !bBorderlessFullscreen;
|
||||
}
|
||||
bool UseGPUTextureDecoding() const
|
||||
{
|
||||
return backend_info.bSupportsGPUTextureDecoding && bEnableGPUTextureDecoding;
|
||||
}
|
||||
bool UseVertexRounding() const { return bVertexRounding && iEFBScale != 1; }
|
||||
bool ManualTextureSamplingWithCustomTextureSizes() const
|
||||
{
|
||||
// If manual texture sampling is disabled, we don't need to do anything.
|
||||
if (bFastTextureSampling)
|
||||
return false;
|
||||
// Hi-res textures break the wrapping logic used by manual texture sampling, as a texture's
|
||||
// size won't match the size the game sets.
|
||||
if (bHiresTextures)
|
||||
return true;
|
||||
// Hi-res EFB copies (but not native-resolution EFB copies at higher internal resolutions)
|
||||
// also result in different texture sizes that need special handling.
|
||||
if (iEFBScale != 1 && bCopyEFBScaled)
|
||||
return true;
|
||||
// Stereoscopic 3D changes the number of layers some textures have (EFB copies have 2 layers,
|
||||
// while game textures still have 1), meaning bounds checks need to be added.
|
||||
if (stereo_mode != StereoMode::Off)
|
||||
return true;
|
||||
// Otherwise, manual texture sampling can use the sizes games specify directly.
|
||||
return false;
|
||||
}
|
||||
bool UsingUberShaders() const;
|
||||
u32 GetShaderCompilerThreads() const;
|
||||
u32 GetShaderPrecompilerThreads() const;
|
||||
};
|
||||
|
||||
extern VideoConfig g_Config;
|
||||
extern VideoConfig g_ActiveConfig;
|
||||
|
||||
// Called every frame.
|
||||
void UpdateActiveConfig();
|
||||
@@ -1,86 +0,0 @@
|
||||
/* Default visibility */
|
||||
#define DEFAULT_VISIBILITY __attribute__((visibility("hidden")))
|
||||
|
||||
/* Start with debug message logging enabled */
|
||||
#undef ENABLE_DEBUG_LOGGING
|
||||
|
||||
/* Message logging */
|
||||
#undef ENABLE_LOGGING
|
||||
|
||||
/* Define to 1 if you have the <asm/types.h> header file. */
|
||||
/* #undef HAVE_ASM_TYPES_H */
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
|
||||
/* Define to 1 if you have the `udev' library (-ludev). */
|
||||
/* #undef HAVE_LIBUDEV */
|
||||
|
||||
/* Define to 1 if you have the <linux/filter.h> header file. */
|
||||
/* #undef HAVE_LINUX_FILTER_H */
|
||||
|
||||
/* Define to 1 if you have the <linux/netlink.h> header file. */
|
||||
/* #undef HAVE_LINUX_NETLINK_H */
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
#define HAVE_POLL_H 1
|
||||
|
||||
/* Define to 1 if you have the <signal.h> header file. */
|
||||
#define HAVE_SIGNAL_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `struct timespec'. */
|
||||
/* #undef HAVE_STRUCT_TIMESPEC */
|
||||
|
||||
/* syslog() function available */
|
||||
#define HAVE_SYSLOG_FUNC 1
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#define HAVE_SYSLOG_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Darwin backend */
|
||||
#define OS_DARWIN 1
|
||||
|
||||
/* Linux backend */
|
||||
/* #undef OS_LINUX */
|
||||
|
||||
/* NetBSD backend */
|
||||
/* #undef OS_NETBSD */
|
||||
|
||||
/* OpenBSD backend */
|
||||
/* #undef OS_OPENBSD */
|
||||
|
||||
/* Windows backend */
|
||||
/* #undef OS_WINDOWS */
|
||||
|
||||
/* type of second poll() argument */
|
||||
#define POLL_NFDS_TYPE unsigned int
|
||||
|
||||
/* Use POSIX Threads */
|
||||
#define THREADS_POSIX
|
||||
|
||||
/* timerfd headers available */
|
||||
/* #undef USBI_TIMERFD_AVAILABLE */
|
||||
|
||||
/* Enable output to system log */
|
||||
#define USE_SYSTEM_LOGGING_FACILITY 1
|
||||
|
||||
/* Use udev for device enumeration/hotplug */
|
||||
/* #undef USE_UDEV */
|
||||
|
||||
/* Use GNU extensions */
|
||||
#define _GNU_SOURCE
|
||||
|
||||
/* Oldest Windows version supported */
|
||||
#define WINVER 0x0501
|
||||
@@ -1,505 +0,0 @@
|
||||
/* Define if building universal (internal helper macro) */
|
||||
/* #undef AC_APPLE_UNIVERSAL_BUILD */
|
||||
|
||||
/* How many MiB of RAM to assume if the real amount cannot be determined. */
|
||||
#define ASSUME_RAM 128
|
||||
|
||||
/* Define to 1 if translation of program messages to the user's native
|
||||
language is requested. */
|
||||
/* #undef #define ENABLE_NLS 1 */
|
||||
|
||||
/* Define to 1 if bswap_16 is available. */
|
||||
#define HAVE_BSWAP_16 1
|
||||
|
||||
/* Define to 1 if bswap_32 is available. */
|
||||
#define HAVE_BSWAP_32 1
|
||||
|
||||
/* Define to 1 if bswap_64 is available. */
|
||||
#define HAVE_BSWAP_64 1
|
||||
|
||||
/* Define to 1 if you have the <byteswap.h> header file. */
|
||||
/* #undef HAVE_BYTESWAP_H 1 */
|
||||
|
||||
/* Define to 1 if Capsicum is available. */
|
||||
/* #undef HAVE_CAPSICUM */
|
||||
|
||||
/* Define to 1 if the system has the type `CC_SHA256_CTX'. */
|
||||
/* #undef HAVE_CC_SHA256_CTX */
|
||||
|
||||
/* Define to 1 if you have the `CC_SHA256_Init' function. */
|
||||
/* #undef HAVE_CC_SHA256_INIT */
|
||||
|
||||
/* Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the
|
||||
CoreFoundation framework. */
|
||||
/* #undef HAVE_CFLOCALECOPYCURRENT */
|
||||
|
||||
/* Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in
|
||||
the CoreFoundation framework. */
|
||||
/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */
|
||||
|
||||
/* Define to 1 if crc32 integrity check is enabled. */
|
||||
#define HAVE_CHECK_CRC32 1
|
||||
|
||||
/* Define to 1 if crc64 integrity check is enabled. */
|
||||
#define HAVE_CHECK_CRC64 1
|
||||
|
||||
/* Define to 1 if sha256 integrity check is enabled. */
|
||||
#define HAVE_CHECK_SHA256 1
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#define HAVE_CLOCK_GETTIME 1
|
||||
|
||||
/* Define to 1 if you have the <CommonCrypto/CommonDigest.h> header file. */
|
||||
/* #undef HAVE_COMMONCRYPTO_COMMONDIGEST_H */
|
||||
|
||||
/* Define if the GNU dcgettext() function is already present or preinstalled.
|
||||
*/
|
||||
#define HAVE_DCGETTEXT 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `CLOCK_MONOTONIC', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_CLOCK_MONOTONIC 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `program_invocation_name', and
|
||||
to 0 if you don't. */
|
||||
/* undef HAVE_DECL_PROGRAM_INVOCATION_NAME 1 */
|
||||
|
||||
/* Define to 1 if any of HAVE_DECODER_foo have been defined. */
|
||||
#define HAVE_DECODERS 1
|
||||
|
||||
/* Define to 1 if arm decoder is enabled. */
|
||||
// #define HAVE_DECODER_ARM 1
|
||||
|
||||
/* Define to 1 if armthumb decoder is enabled. */
|
||||
// #define HAVE_DECODER_ARMTHUMB 1
|
||||
|
||||
/* Define to 1 if delta decoder is enabled. */
|
||||
#define HAVE_DECODER_DELTA 1
|
||||
|
||||
/* Define to 1 if ia64 decoder is enabled. */
|
||||
// #define HAVE_DECODER_IA64 1
|
||||
|
||||
/* Define to 1 if lzma1 decoder is enabled. */
|
||||
#define HAVE_DECODER_LZMA1 1
|
||||
|
||||
/* Define to 1 if lzma2 decoder is enabled. */
|
||||
#define HAVE_DECODER_LZMA2 1
|
||||
|
||||
/* Define to 1 if powerpc decoder is enabled. */
|
||||
// #define HAVE_DECODER_POWERPC 1
|
||||
|
||||
/* Define to 1 if sparc decoder is enabled. */
|
||||
// #define HAVE_DECODER_SPARC 1
|
||||
|
||||
/* Define to 1 if x86 decoder is enabled. */
|
||||
// #define HAVE_DECODER_X86 1
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if any of HAVE_ENCODER_foo have been defined. */
|
||||
#define HAVE_ENCODERS 1
|
||||
|
||||
/* Define to 1 if arm encoder is enabled. */
|
||||
// #define HAVE_ENCODER_ARM 1
|
||||
|
||||
/* Define to 1 if armthumb encoder is enabled. */
|
||||
// #define HAVE_ENCODER_ARMTHUMB 1
|
||||
|
||||
/* Define to 1 if delta encoder is enabled. */
|
||||
#define HAVE_ENCODER_DELTA 1
|
||||
|
||||
/* Define to 1 if ia64 encoder is enabled. */
|
||||
// #define HAVE_ENCODER_IA64 1
|
||||
|
||||
/* Define to 1 if lzma1 encoder is enabled. */
|
||||
#define HAVE_ENCODER_LZMA1 1
|
||||
|
||||
/* Define to 1 if lzma2 encoder is enabled. */
|
||||
#define HAVE_ENCODER_LZMA2 1
|
||||
|
||||
/* Define to 1 if powerpc encoder is enabled. */
|
||||
// #define HAVE_ENCODER_POWERPC 1
|
||||
|
||||
/* Define to 1 if sparc encoder is enabled. */
|
||||
// #define HAVE_ENCODER_SPARC 1
|
||||
|
||||
/* Define to 1 if x86 encoder is enabled. */
|
||||
// #define HAVE_ENCODER_X86 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the `futimens' function. */
|
||||
#define HAVE_FUTIMENS 1
|
||||
|
||||
/* Define to 1 if you have the `futimes' function. */
|
||||
/* #undef HAVE_FUTIMES */
|
||||
|
||||
/* Define to 1 if you have the `futimesat' function. */
|
||||
/* #undef HAVE_FUTIMESAT */
|
||||
|
||||
/* Define to 1 if you have the <getopt.h> header file. */
|
||||
#define HAVE_GETOPT_H 1
|
||||
|
||||
/* Define to 1 if you have the `getopt_long' function. */
|
||||
#define HAVE_GETOPT_LONG 1
|
||||
|
||||
/* Define if the GNU gettext() function is already present or preinstalled. */
|
||||
/* #undef HAVE_GETTEXT 1 */
|
||||
|
||||
/* Define if you have the iconv() function and it works. */
|
||||
/* #undef HAVE_ICONV */
|
||||
|
||||
#ifdef _M_X86
|
||||
/* Define to 1 if you have the <immintrin.h> header file. */
|
||||
#define HAVE_IMMINTRIN_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define to 1 if mbrtowc and mbstate_t are properly declared. */
|
||||
#define HAVE_MBRTOWC 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 to enable bt2 match finder. */
|
||||
#define HAVE_MF_BT2 1
|
||||
|
||||
/* Define to 1 to enable bt3 match finder. */
|
||||
#define HAVE_MF_BT3 1
|
||||
|
||||
/* Define to 1 to enable bt4 match finder. */
|
||||
#define HAVE_MF_BT4 1
|
||||
|
||||
/* Define to 1 to enable hc3 match finder. */
|
||||
#define HAVE_MF_HC3 1
|
||||
|
||||
/* Define to 1 to enable hc4 match finder. */
|
||||
#define HAVE_MF_HC4 1
|
||||
|
||||
/* Define to 1 if getopt.h declares extern int optreset. */
|
||||
/* #undef HAVE_OPTRESET */
|
||||
|
||||
/* Define to 1 if you have the `posix_fadvise' function. */
|
||||
#define HAVE_POSIX_FADVISE 1
|
||||
|
||||
/* Define to 1 if you have the `pthread_condattr_setclock' function. */
|
||||
//#define HAVE_PTHREAD_CONDATTR_SETCLOCK 1
|
||||
|
||||
/* Have PTHREAD_PRIO_INHERIT. */
|
||||
#define HAVE_PTHREAD_PRIO_INHERIT 1
|
||||
|
||||
/* Define to 1 if you have the `SHA256Init' function. */
|
||||
/* #undef HAVE_SHA256INIT */
|
||||
|
||||
/* Define to 1 if the system has the type `SHA256_CTX'. */
|
||||
/* #undef HAVE_SHA256_CTX */
|
||||
|
||||
/* Define to 1 if you have the <sha256.h> header file. */
|
||||
/* #undef HAVE_SHA256_H */
|
||||
|
||||
/* Define to 1 if you have the `SHA256_Init' function. */
|
||||
/* #undef HAVE_SHA256_INIT */
|
||||
|
||||
/* Define to 1 if the system has the type `SHA2_CTX'. */
|
||||
/* #undef HAVE_SHA2_CTX */
|
||||
|
||||
/* Define to 1 if you have the <sha2.h> header file. */
|
||||
/* #undef HAVE_SHA2_H */
|
||||
|
||||
/* Define to 1 if optimizing for size. */
|
||||
/* #undef HAVE_SMALL */
|
||||
|
||||
/* Define to 1 if stdbool.h conforms to C99. */
|
||||
#define HAVE_STDBOOL_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
/* #undef HAVE_STRINGS_H 1 */
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if `st_atimensec' is a member of `struct stat'. */
|
||||
/* #undef HAVE_STRUCT_STAT_ST_ATIMENSEC */
|
||||
|
||||
/* Define to 1 if `st_atimespec.tv_nsec' is a member of `struct stat'. */
|
||||
/* #undef HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC */
|
||||
|
||||
/* Define to 1 if `st_atim.st__tim.tv_nsec' is a member of `struct stat'. */
|
||||
/* #undef HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC */
|
||||
|
||||
/* Define to 1 if `st_atim.tv_nsec' is a member of `struct stat'. */
|
||||
#define HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC 1
|
||||
|
||||
/* Define to 1 if `st_uatime' is a member of `struct stat'. */
|
||||
/* #undef HAVE_STRUCT_STAT_ST_UATIME */
|
||||
|
||||
/* Define to 1 if you have the <sys/byteorder.h> header file. */
|
||||
/* #undef HAVE_SYS_BYTEORDER_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/capsicum.h> header file. */
|
||||
/* #undef HAVE_SYS_CAPSICUM_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/endian.h> header file. */
|
||||
/* #undef HAVE_SYS_ENDIAN_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
/* #undef HAVE_SYS_TIME_H 1 */
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `uintptr_t'. */
|
||||
#define HAVE_UINTPTR_T 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `utime' function. */
|
||||
/* #undef HAVE_UTIME */
|
||||
|
||||
/* Define to 1 if you have the `utimes' function. */
|
||||
/* #undef HAVE_UTIMES */
|
||||
|
||||
/* Define to 1 or 0, depending whether the compiler supports simple visibility
|
||||
declarations. */
|
||||
#define HAVE_VISIBILITY 0
|
||||
|
||||
/* Define to 1 if you have the `wcwidth' function. */
|
||||
#define HAVE_WCWIDTH 1
|
||||
|
||||
/* Define to 1 if the system has the type `_Bool'. */
|
||||
#define HAVE__BOOL 1
|
||||
|
||||
/* Define to 1 if you have the `_futime' function. */
|
||||
/* #undef HAVE__FUTIME */
|
||||
|
||||
/* Define to 1 if _mm_movemask_epi8 is available. */
|
||||
#define HAVE__MM_MOVEMASK_EPI8 1
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
#ifndef _WIN32
|
||||
/* Define to 1 when using POSIX threads (pthreads). */
|
||||
#define MYTHREAD_POSIX 1
|
||||
#else
|
||||
/* Define to 1 when using Windows Vista compatible threads. This uses features
|
||||
that are not available on Windows XP. */
|
||||
#define MYTHREAD_VISTA
|
||||
#endif
|
||||
|
||||
/* Define to 1 when using Windows 95 (and thus XP) compatible threads. This
|
||||
avoids use of features that were added in Windows Vista. */
|
||||
/* #undef MYTHREAD_WIN95 */
|
||||
|
||||
/* Define to 1 to disable debugging code. */
|
||||
#define NDEBUG 1
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "xz"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "lasse.collin@tukaani.org"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "XZ Utils"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "XZ Utils 5.2.4"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "xz"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL "https://tukaani.org/xz/"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "5.2.4"
|
||||
|
||||
/* Define to necessary symbol if this constant uses a non-standard name on
|
||||
your system. */
|
||||
/* #undef PTHREAD_CREATE_JOINABLE */
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#define SIZEOF_SIZE_T 8
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if the number of available CPU cores can be detected with
|
||||
cpuset(2). */
|
||||
/* #undef TUKLIB_CPUCORES_CPUSET */
|
||||
|
||||
/* Define to 1 if the number of available CPU cores can be detected with
|
||||
pstat_getdynamic(). */
|
||||
/* #undef TUKLIB_CPUCORES_PSTAT_GETDYNAMIC */
|
||||
|
||||
/* Define to 1 if the number of available CPU cores can be detected with
|
||||
sched_getaffinity() */
|
||||
/* #undef TUKLIB_CPUCORES_SCHED_GETAFFINITY */
|
||||
|
||||
/* Define to 1 if the number of available CPU cores can be detected with
|
||||
sysconf(_SC_NPROCESSORS_ONLN) or sysconf(_SC_NPROC_ONLN). */
|
||||
/* #undef TUKLIB_CPUCORES_SYSCONF */
|
||||
|
||||
/* Define to 1 if the number of available CPU cores can be detected with
|
||||
sysctl(). */
|
||||
/* #undef TUKLIB_CPUCORES_SYSCTL */
|
||||
|
||||
#ifdef _M_X86
|
||||
/* Define to 1 if the system supports fast unaligned access to 16-bit and
|
||||
32-bit integers. */
|
||||
#define TUKLIB_FAST_UNALIGNED_ACCESS 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if the amount of physical memory can be detected with
|
||||
_system_configuration.physmem. */
|
||||
/* #undef TUKLIB_PHYSMEM_AIX */
|
||||
|
||||
/* Define to 1 if the amount of physical memory can be detected with
|
||||
getinvent_r(). */
|
||||
/* #undef TUKLIB_PHYSMEM_GETINVENT_R */
|
||||
|
||||
/* Define to 1 if the amount of physical memory can be detected with
|
||||
getsysinfo(). */
|
||||
/* #undef TUKLIB_PHYSMEM_GETSYSINFO */
|
||||
|
||||
/* Define to 1 if the amount of physical memory can be detected with
|
||||
pstat_getstatic(). */
|
||||
/* #undef TUKLIB_PHYSMEM_PSTAT_GETSTATIC */
|
||||
|
||||
/* Define to 1 if the amount of physical memory can be detected with
|
||||
sysconf(_SC_PAGESIZE) and sysconf(_SC_PHYS_PAGES). */
|
||||
#define TUKLIB_PHYSMEM_SYSCONF 1
|
||||
|
||||
/* Define to 1 if the amount of physical memory can be detected with sysctl().
|
||||
*/
|
||||
/* #undef TUKLIB_PHYSMEM_SYSCTL */
|
||||
|
||||
/* Define to 1 if the amount of physical memory can be detected with Linux
|
||||
sysinfo(). */
|
||||
/* #undef TUKLIB_PHYSMEM_SYSINFO */
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# define _ALL_SOURCE 1
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# define _POSIX_PTHREAD_SEMANTICS 1
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# define _TANDEM_SOURCE 1
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# define __EXTENSIONS__ 1
|
||||
#endif
|
||||
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "5.2.4"
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
# if defined __BIG_ENDIAN__
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#else
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
/* # undef WORDS_BIGENDIAN */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
/* #undef _FILE_OFFSET_BITS */
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* #undef _LARGE_FILES */
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
/* #undef _MINIX */
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
/* #undef _POSIX_1_SOURCE */
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
/* #undef _POSIX_SOURCE */
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
/* #undef _UINT32_T */
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
/* #undef _UINT64_T */
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
/* #undef _UINT8_T */
|
||||
|
||||
/* Define to rpl_ if the getopt replacement functions and variables should be
|
||||
used. */
|
||||
/* #undef __GETOPT_PREFIX */
|
||||
|
||||
/* Define to the type of a signed integer type of width exactly 32 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
/* #undef int32_t */
|
||||
|
||||
/* Define to the type of a signed integer type of width exactly 64 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
/* #undef int64_t */
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 16 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
/* #undef uint16_t */
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 32 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
/* #undef uint32_t */
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 64 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
/* #undef uint64_t */
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 8 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
/* #undef uint8_t */
|
||||
|
||||
/* Define to the type of an unsigned integer type wide enough to hold a
|
||||
pointer, if such a type exists, and if the system does not define it. */
|
||||
/* #undef uintptr_t */
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,182 @@
|
||||
[Default]
|
||||
IRLeft = 266
|
||||
IRTop = 215
|
||||
IRWidth = 486
|
||||
IRHeight = 490
|
||||
[RSPE] # Wii Sports (NTSC)
|
||||
IRLeft = 266
|
||||
IRTop = 215
|
||||
IRWidth = 486
|
||||
IRHeight = 490
|
||||
[RSPP] # Wii Sports (PAL)
|
||||
IRLeft = 266
|
||||
IRTop = 215
|
||||
IRWidth = 486
|
||||
IRHeight = 490
|
||||
[RMGE] # Mario Galaxy (NTSC)
|
||||
IRLeft = 255
|
||||
IRTop = 278
|
||||
IRWidth = 452
|
||||
IRHeight = 456
|
||||
[RMGP] # Mario Galaxy (PAL)
|
||||
IRLeft = 255
|
||||
IRTop = 278
|
||||
IRWidth = 452
|
||||
IRHeight = 456
|
||||
[RMCE] # Mario Kart Wii (NTSC)
|
||||
IRLeft = 253
|
||||
IRTop = 272
|
||||
IRWidth = 454
|
||||
IRHeight = 455
|
||||
[RMCP] # Mario Kart Wii (PAL)
|
||||
IRLeft = 254
|
||||
IRTop = 278
|
||||
IRWidth = 451
|
||||
IRHeight = 448
|
||||
[R7PE] # Punch Out (NTSC)
|
||||
IRLeft = 265
|
||||
IRTop = 289
|
||||
IRWidth = 408
|
||||
IRHeight = 416
|
||||
[R7PP] # Punch Out (PAL)
|
||||
IRLeft = 265
|
||||
IRTop = 289
|
||||
IRWidth = 408
|
||||
IRHeight = 416
|
||||
[RZDE] # Zelda - Twilight Princess (NTSC)
|
||||
IRLeft = 233
|
||||
IRTop = 181
|
||||
IRWidth = 559
|
||||
IRHeight = 409
|
||||
[RZDP] # Zelda - Twilight Princess (PAL)
|
||||
IRLeft = 233
|
||||
IRTop = 181
|
||||
IRWidth = 559
|
||||
IRHeight = 409
|
||||
[RM8E] # Mario Part 8 (NTSC)
|
||||
IRLeft = 277
|
||||
IRTop = 273
|
||||
IRWidth = 460
|
||||
IRHeight = 394
|
||||
[RM8P] # Mario Part 8 (PAL)
|
||||
IRLeft = 277
|
||||
IRTop = 273
|
||||
IRWidth = 460
|
||||
IRHeight = 394
|
||||
[R8PE] # Super Paper Mario (NTSC)
|
||||
IRLeft = 399
|
||||
IRTop = 373
|
||||
IRWidth = 227
|
||||
IRHeight = 228
|
||||
[R8PP] # Super Paper Mario (PAL)
|
||||
IRLeft = 399
|
||||
IRTop = 373
|
||||
IRWidth = 227
|
||||
IRHeight = 228
|
||||
[R4QP] # Mario Strikers (NTSC)
|
||||
IRLeft = 200
|
||||
IRTop = 54
|
||||
IRWidth = 615
|
||||
IRHeight = 657
|
||||
[R4QP] # Mario Strikers (PAL)
|
||||
IRLeft = 200
|
||||
IRTop = 54
|
||||
IRWidth = 615
|
||||
IRHeight = 657
|
||||
[RBUE] # Resident Evil - The Umbrella Chronicles (NTSC)
|
||||
IRLeft = 335
|
||||
IRTop = 351
|
||||
IRWidth = 357
|
||||
IRHeight = 273
|
||||
[RBUP] # Resident Evil - The Umbrella Chronicles (PAL)
|
||||
IRLeft = 335
|
||||
IRTop = 351
|
||||
IRWidth = 357
|
||||
IRHeight = 273
|
||||
[RB4E] # Resident Evil 4 (NTSC)
|
||||
IRLeft = 286
|
||||
IRTop = 256
|
||||
IRWidth = 450
|
||||
IRHeight = 455
|
||||
[RB4P] # Resident Evil 4 (PAL)
|
||||
IRLeft = 286
|
||||
IRTop = 256
|
||||
IRWidth = 450
|
||||
IRHeight = 455
|
||||
[R3IJ] # Metroid Prime - Wii De Asobu (JAP)
|
||||
IRLeft = 228
|
||||
IRTop = 112
|
||||
IRWidth = 486
|
||||
IRHeight = 577
|
||||
[RM3E] # Metroid Prime 3 (NTSC)
|
||||
IRLeft = 258
|
||||
IRTop = 84
|
||||
IRWidth = 489
|
||||
IRHeight = 613
|
||||
[RM3P] # Metroid Prime 3 (PAL)
|
||||
IRLeft = 258
|
||||
IRTop = 84
|
||||
IRWidth = 489
|
||||
IRHeight = 613
|
||||
[RSUP] # Sports Party (NTSC)
|
||||
IRLeft = 391
|
||||
IRTop = 377
|
||||
IRWidth = 241
|
||||
IRHeight = 225
|
||||
[RSUP] # Sports Party (PAL)
|
||||
IRLeft = 391
|
||||
IRTop = 377
|
||||
IRWidth = 241
|
||||
IRHeight = 225
|
||||
[RDZE] # Disaster - Day of Crisis (NTSC)
|
||||
IRLeft = 253
|
||||
IRTop = 276
|
||||
IRWidth = 453
|
||||
IRHeight = 421
|
||||
[RDZP] # Disaster - Day of Crisis (PAL)
|
||||
IRLeft = 253
|
||||
IRTop = 276
|
||||
IRWidth = 453
|
||||
IRHeight = 421
|
||||
[R4QE] # Mario Strikers (NTSC)
|
||||
IRLeft = 266
|
||||
IRTop = 215
|
||||
IRWidth = 486
|
||||
IRHeight = 490
|
||||
[R4QP] # Mario Strikers (PAL)
|
||||
IRLeft = 266
|
||||
IRTop = 215
|
||||
IRWidth = 486
|
||||
IRHeight = 490
|
||||
[RPBE] # Pokemon Battle Revolution (NTSC)
|
||||
IRLeft = 287
|
||||
IRTop = 261
|
||||
IRWidth = 451
|
||||
IRHeight = 449
|
||||
[RPBP] # Pokemon Battle Revolution (PAL)
|
||||
IRLeft = 287
|
||||
IRTop = 261
|
||||
IRWidth = 451
|
||||
IRHeight = 449
|
||||
[R2GJ] # Fragile: Sayonara Tsuki no Haikyo (JAP)
|
||||
IRLeft = 254
|
||||
IRTop = 280
|
||||
IRWidth = 451
|
||||
IRHeight = 453
|
||||
[RFNE] # Wii Fit (NTSC)
|
||||
[RFNP] # Wii Fit (PAL)
|
||||
[RSBE] # Super Smash Bros. Brawl (NTSC)
|
||||
[RSBP] # Super Smash Bros. Brawl (PAL)
|
||||
[R3TE] # Top Spin 3 (NTSC)
|
||||
[RSBP] # Top Spin 3 (PAL)
|
||||
[RLBE] # Lego Batman (NTSC)
|
||||
[RLBP] # Lego Batman (PAL)
|
||||
##########################################################################
|
||||
# These games don't use the IR Pointer at any time
|
||||
##########################################################################
|
||||
[RSRE] # Sonic and the Secret Rings (NTSC)
|
||||
[RSRP] # Sonic and the Secret Rings (PAL)
|
||||
[RWLE] # Wario Land - Shake It (NTSC)
|
||||
[RWLP] # Wario Land - Shake It (PAL)
|
||||
[RTNE] # Tenchu: Shadow Assassins (NTSC)
|
||||
[RTNE] # Tenchu: Shadow Assassins (PAL)
|
||||
Executable → Regular
@@ -0,0 +1,15 @@
|
||||
# D43E01 - ZELDA OCARINA MULTI PACK
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 5
|
||||
EmulationIssues = Minor video glitches when pausing
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
@@ -0,0 +1,14 @@
|
||||
# D43J01 - ZELDA OCARINA MULTI PACK
|
||||
[Core]
|
||||
#Values set here will override the main dolphin settings.
|
||||
[EmuState]
|
||||
#The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues =
|
||||
[OnLoad]
|
||||
#Add memory patches to be loaded once on boot here.
|
||||
[OnFrame]
|
||||
+$loophack
|
||||
0x806866E4:word:0x60000000
|
||||
[ActionReplay]
|
||||
[Video]
|
||||
@@ -0,0 +1,10 @@
|
||||
# D43P01 - The Legend of Zelda: Ocarina of Time
|
||||
[EmuState]
|
||||
#The Emulation State.
|
||||
EmulationStateId = 1
|
||||
Issues="Dolphin doesn't support soft reset"
|
||||
EmulationIssues =
|
||||
[OnFrame]#Add memory patches here.
|
||||
[ActionReplay]
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
@@ -0,0 +1,10 @@
|
||||
# D43U01 - ZELDA OCARINA MULTI PACK
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
[Gecko]
|
||||
@@ -0,0 +1,9 @@
|
||||
# DTLX01 - ACTION REPLAY
|
||||
[Core]
|
||||
TLBHack = 1
|
||||
#Values set here will override the main dolphin settings.
|
||||
[EmuState]
|
||||
#The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 0
|
||||
[OnFrame]
|
||||
[ActionReplay]
|
||||
@@ -0,0 +1,6 @@
|
||||
# DVDXDV - Unknown
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,9 @@
|
||||
# FABP01 - Zelda: Link to Past
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationIssues =
|
||||
EmulationStateId = 4
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
@@ -0,0 +1,7 @@
|
||||
# FBYE01 - Super Mario Bros. 2
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 3
|
||||
EmulationIssues = Can't see graphics
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,7 @@
|
||||
# G2BE5G - Black & Bruised
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues = No sound/bad sound
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,6 @@
|
||||
# G2BP7D - Black & Bruised
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,7 @@
|
||||
# G2CE52 - TC2 US
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack=1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 3
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,20 @@
|
||||
# G2FE78 - Tak 2: The Staff of Dreams
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
$Master Code
|
||||
C43213D8 0000FF01
|
||||
$Infinite Health
|
||||
04112828 48232224
|
||||
04344A4C D017021C
|
||||
04344A50 C1B7021C
|
||||
04344A54 4BDCDDDC
|
||||
$Max JuJu Elements
|
||||
00000000 843C58B8
|
||||
4479C000 00030003
|
||||
$Have All Cards/All Cards Mixable
|
||||
00000000 8439A5E0
|
||||
00000001 001E000A
|
||||
@@ -0,0 +1,6 @@
|
||||
# G2GJB2 - MOBILE SUIT GUNDAM GUNDAMvs.ZGUNDAM
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 5
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,158 @@
|
||||
# G2ME01 - Metroid Prime 2 Echoes
|
||||
[EmuState]
|
||||
#The Emulation State.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues =
|
||||
[Speedhacks]
|
||||
0x803758bc=400
|
||||
[OnFrame]
|
||||
[ActionReplay]
|
||||
$(M)
|
||||
C4354E70 0000FF01
|
||||
C436F000 0000FF02
|
||||
4D30294C 4E800020
|
||||
C530294C 0000FF03
|
||||
0441FD80 00000000
|
||||
C6004010 000000FF
|
||||
$This Code Must Be On!
|
||||
043BC410 906D0000
|
||||
043BC414 88030004
|
||||
043BC418 4BC5C1F4
|
||||
04018608 483A3E08
|
||||
$Infinite Health
|
||||
4241FD80 000A44BB
|
||||
4241FD80 000B6000
|
||||
$Max Energy Tanks
|
||||
4241FD80 012B000E
|
||||
4241FD80 012D000E
|
||||
$Maximum Missiles
|
||||
4241FD80 013900FA
|
||||
$Infinite Missiles
|
||||
4241FD80 013700FA
|
||||
$Have Charge Beam
|
||||
4241FD80 00310001
|
||||
4241FD80 00330001
|
||||
$Have Dark Beam
|
||||
4241FD80 0037000F
|
||||
4241FD80 0039000F
|
||||
$Have Light Beam
|
||||
4241FD80 003D000F
|
||||
4241FD80 003F000F
|
||||
$Have Annihilator
|
||||
4241FD80 0043000F
|
||||
4241FD80 0045000F
|
||||
$Have Super Missile
|
||||
4241FD80 00470001
|
||||
4241FD80 00490001
|
||||
$Have Darkburst
|
||||
4241FD80 004D0001
|
||||
4241FD80 004F0001
|
||||
$Have Sunburst
|
||||
4241FD80 00530001
|
||||
4241FD80 00550001
|
||||
$Have Sonic Boom
|
||||
4241FD80 00590001
|
||||
4241FD80 005B0001
|
||||
$Have Combat Visor
|
||||
4241FD80 005F0001
|
||||
4241FD80 00610001
|
||||
$Have Scan Visor
|
||||
4241FD80 00650001
|
||||
4241FD80 00670001
|
||||
$Have Dark Visor
|
||||
4241FD80 006B0001
|
||||
4241FD80 006D0001
|
||||
$Have Echo Visor
|
||||
4241FD80 00710001
|
||||
4241FD80 00730001
|
||||
$Have Varia Suit
|
||||
4241FD80 00770001
|
||||
4241FD80 00790001
|
||||
$Have Dark Suit
|
||||
4241FD80 007D0001
|
||||
4241FD80 007F0001
|
||||
$Have Light Suit
|
||||
4241FD80 00830001
|
||||
4241FD80 00850001
|
||||
$Have Space Jump Boots
|
||||
4241FD80 00BF0001
|
||||
4241FD80 00C10001
|
||||
$Have Grapple Beam
|
||||
4241FD80 00B90001
|
||||
4241FD80 00BB0001
|
||||
$Have Gravity Boost
|
||||
4241FD80 00C50001
|
||||
4241FD80 00C70001
|
||||
$Have Screw Attack
|
||||
4241FD80 00D10001
|
||||
4241FD80 00D30001
|
||||
$Have Seeker Missile
|
||||
4241FD80 00CB0001
|
||||
4241FD80 00CD0001
|
||||
$Have Morph Ball Power Bomb
|
||||
4241FD80 01310001
|
||||
4241FD80 01330001
|
||||
$Have Beam Ammo Expansion
|
||||
4241FD80 013D000F
|
||||
4241FD80 013F000F
|
||||
$Have Sky Temple Key 1
|
||||
4241FD80 00DD0001
|
||||
4241FD80 00DF0001
|
||||
$Have Sky Temple Key 2
|
||||
4241FD80 00E30001
|
||||
4241FD80 00E50001
|
||||
$Have Sky Temple Key 3
|
||||
4241FD80 00E90001
|
||||
4241FD80 00EB0001
|
||||
$Have Agon Temple Key 1
|
||||
4241FD80 00EF0001
|
||||
4241FD80 00F10001
|
||||
$Have Agon Temple Key 2
|
||||
4241FD80 00F50001
|
||||
4241FD80 00F70001
|
||||
$Have Agon Temple Key 3
|
||||
4241FD80 00FB0001
|
||||
4241FD80 00FD0001
|
||||
$Have Torvus Temple Key 1
|
||||
4241FD80 01010001
|
||||
4241FD80 01030001
|
||||
$Have Torvus Temple Key 2
|
||||
4241FD80 01070001
|
||||
4241FD80 01090001
|
||||
$Have Torvus Temple Key 3
|
||||
4241FD80 010D0001
|
||||
4241FD80 010F0001
|
||||
$Have Ing Hive Temple Key 1
|
||||
4241FD80 01130001
|
||||
4241FD80 01150001
|
||||
$Have Ing Hive Temple Key 2
|
||||
4241FD80 01190001
|
||||
4241FD80 011B0001
|
||||
$Have Ing Hive Temple Key 3
|
||||
4241FD80 011F0001
|
||||
$One Hit Kill
|
||||
0403DB68 4BFC539C
|
||||
04002F04 FFC00090
|
||||
04002F08 7C1BE050
|
||||
04002F0C 2C000010
|
||||
04002F10 41820008
|
||||
04002F14 EFDEF028
|
||||
04002F18 4803AC54
|
||||
$Full Logbook
|
||||
0421166C 4BDF18CC
|
||||
04002F38 3BE000FF
|
||||
04002F3C 9BE50004
|
||||
04002F40 88050004
|
||||
04002F44 4820E72C
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
[Video_Hacks]
|
||||
EFBCopyEnable = True
|
||||
EFBCopyRAMEnable = True
|
||||
EFBCopyVirtualEnable = True
|
||||
@@ -0,0 +1,157 @@
|
||||
# G2MP01 - Metroid Prime 2 Echoes
|
||||
[EmuState]
|
||||
#The Emulation State.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues =
|
||||
[Speedhacks]
|
||||
#Patch OSYieldThread to take more time - MP2's idle loop is really stupid.
|
||||
0x80375c68=400
|
||||
[OnFrame]
|
||||
[ActionReplay]
|
||||
$(M)
|
||||
C43552C8 0000FF01
|
||||
C436F41C 0000FF02
|
||||
0D30294C 4E800020
|
||||
C530294C 0000FF03
|
||||
$Infinite Health
|
||||
423DDE0C 000A44BB
|
||||
423DDE0C 000B6000
|
||||
$Max Energy Tanks
|
||||
423DDE0C 012B000E
|
||||
423DDE0C 012D000E
|
||||
$Maximum Missiles
|
||||
423DDE0C 013900FA
|
||||
$Infinite Missiles
|
||||
423DDE0C 013700FA
|
||||
$Moon Jump (Hold B)
|
||||
3A705F24 00000200
|
||||
423DDDFC 00D84101
|
||||
$Have Charge Beam
|
||||
423DDE0C 00310001
|
||||
423DDE0C 00330001
|
||||
$Have Dark Beam
|
||||
423DDE0C 00370001
|
||||
423DDE0C 00390001
|
||||
$Have Light Beam
|
||||
423DDE0C 003D0001
|
||||
423DDE0C 003F0001
|
||||
$Have Annihilator
|
||||
423DDE0C 00430001
|
||||
423DDE0C 00450001
|
||||
$Have Super Missile
|
||||
423DDE0C 00470001
|
||||
423DDE0C 00490001
|
||||
$Have Darkburst
|
||||
423DDE0C 004D0001
|
||||
423DDE0C 004F0001
|
||||
$Have Sunburst
|
||||
423DDE0C 00530001
|
||||
423DDE0C 00550001
|
||||
$Have Sonic Boom
|
||||
423DDE0C 00590001
|
||||
423DDE0C 005B0001
|
||||
$Have Combat Visor
|
||||
423DDE0C 005F0001
|
||||
423DDE0C 00610001
|
||||
$Have Scan Visor
|
||||
423DDE0C 00650001
|
||||
423DDE0C 00670001
|
||||
$Have Dark Visor
|
||||
423DDE0C 006B0001
|
||||
423DDE0C 006D0001
|
||||
$Have Echo Visor
|
||||
423DDE0C 00710001
|
||||
423DDE0C 00730001
|
||||
$Have Varia Suit
|
||||
423DDE0C 00770001
|
||||
423DDE0C 00790001
|
||||
$Have Dark Suit
|
||||
423DDE0C 007D0001
|
||||
423DDE0C 007F0001
|
||||
$Have Light Suit
|
||||
423DDE0C 00830001
|
||||
423DDE0C 00850001
|
||||
$Have Space Jump Boots
|
||||
423DDE0C 00BF0001
|
||||
423DDE0C 00C10001
|
||||
$Have Grapple Beam
|
||||
423DDE0C 00B90001
|
||||
423DDE0C 00BB0001
|
||||
$Have Gravity Boost
|
||||
423DDE0C 00C50001
|
||||
423DDE0C 00C70001
|
||||
$Have Screw Attack
|
||||
423DDE0C 00D10001
|
||||
423DDE0C 00D30001
|
||||
$Have Seeker Missile
|
||||
423DDE0C 00CB0001
|
||||
423DDE0C 00CD0001
|
||||
$Have Morph Ball Power Bomb
|
||||
423DDE0C 01310001
|
||||
423DDE0C 01330001
|
||||
$Have Beam Ammo Expansion
|
||||
423DDE0C 013D000F
|
||||
423DDE0C 013F000F
|
||||
$Have Sky Temple Key 1
|
||||
423DDE0C 00DD0001
|
||||
423DDE0C 00DF0001
|
||||
$Have Sky Temple Key 2
|
||||
423DDE0C 00E30001
|
||||
423DDE0C 00E50001
|
||||
$Have Sky Temple Key 3
|
||||
423DDE0C 00E90001
|
||||
423DDE0C 00EB0001
|
||||
$Have Agon Temple Key 1
|
||||
423DDE0C 00EF0001
|
||||
423DDE0C 00F10001
|
||||
$Have Agon Temple Key 2
|
||||
423DDE0C 00F50001
|
||||
423DDE0C 00F70001
|
||||
$Have Agon Temple Key 3
|
||||
423DDE0C 00FB0001
|
||||
423DDE0C 00FD0001
|
||||
$Have Torvus Temple Key 1
|
||||
423DDE0C 01010001
|
||||
423DDE0C 01030001
|
||||
$Have Torvus Temple Key 2
|
||||
423DDE0C 01070001
|
||||
423DDE0C 01090001
|
||||
$Have Torvus Temple Key 3
|
||||
423DDE0C 010D0001
|
||||
423DDE0C 010F0001
|
||||
$Have Ing Hive Temple Key 1
|
||||
423DDE0C 01130001
|
||||
423DDE0C 01150001
|
||||
$Have Ing Hive Temple Key 2
|
||||
423DDE0C 01190001
|
||||
423DDE0C 011B0001
|
||||
$Have Ing Hive Temple Key 3
|
||||
423DDE0C 011F0001
|
||||
423DDE0C 01210001
|
||||
$One Hit Kill
|
||||
0403DCB8 4BFC524C
|
||||
04002F04 FFC00090
|
||||
04002F08 7C1BE050
|
||||
04002F0C 2C000010
|
||||
04002F10 41820008
|
||||
04002F14 EFDEF028
|
||||
04002F18 4803ADA4
|
||||
$Full Logbook
|
||||
04211974 4BDF15C4
|
||||
04002F38 3BE000FF
|
||||
04002F3C 9BE50004
|
||||
04002F40 88050004
|
||||
04002F44 4820EA34
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
[Video_Hacks]
|
||||
EFBCopyEnable = True
|
||||
EFBCopyRAMEnable = True
|
||||
EFBCopyVirtualEnable = True
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# G2OE41 - PoP:WW
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
@@ -0,0 +1,11 @@
|
||||
# G2OP41 - PoP:WW
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
[Gecko]
|
||||
@@ -0,0 +1,7 @@
|
||||
# G2TE52 - Tony Hawk's Underground 2
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack=1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 1
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,18 @@
|
||||
# G2VE08 - Viewtiful Joe 2
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues = Needs xfb real for videos to show up.
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
[Video_Settings]
|
||||
UseXFB = True
|
||||
UseRealXFB = True
|
||||
@@ -0,0 +1,18 @@
|
||||
# G2VP08 - Viewtiful Joe 2
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues = Needs xfb real for videos to show up.
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
[Video_Settings]
|
||||
UseXFB = True
|
||||
UseRealXFB = True
|
||||
@@ -0,0 +1,15 @@
|
||||
# G2XE8P - SONIC GEMS COLLECTION
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues = Everything playable with minor glitches, except Sonic the Fighters.
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
@@ -0,0 +1,15 @@
|
||||
# G2XP8P - SONIC GEMS COLLECTION
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues = Everything playable with minor glitches, except Sonic the Fighters.
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
@@ -0,0 +1,16 @@
|
||||
# G3AD69 - The Lord of the Rings, The Third Age
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 0
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
@@ -0,0 +1,17 @@
|
||||
# G3AE69 - The Lord of the Rings, The Third Age
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 0
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# G3AF69 - The Lord of the Rings, The Third Age
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 0
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
@@ -0,0 +1,16 @@
|
||||
# G3AE69 - The Lord of the Rings, The Third Age
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 0
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
@@ -0,0 +1,6 @@
|
||||
# G3DE6L - Carmen Sandiego
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,10 @@
|
||||
# G3EE51 - Extreme G3
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 1
|
||||
EmulationIssues = Black screen. Use an older rev for the game to work like r4727 (r6521 tested)
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
[Gecko]
|
||||
@@ -0,0 +1,21 @@
|
||||
# G3FE69 - TimeSplitters Future Perfect
|
||||
[EmuState]
|
||||
#The Emulation State.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues = Needs mmu to run, and it runs very slow because of it (r6436)
|
||||
[OnFrame]
|
||||
[ActionReplay]
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
[Core]
|
||||
MMU = 1
|
||||
VBeam = 1
|
||||
BlockMerging = 1
|
||||
[Video_Hacks]
|
||||
DlistCachingEnable = False
|
||||
@@ -0,0 +1,21 @@
|
||||
# G3FF69 - TimeSplitters Future Perfect
|
||||
[EmuState]
|
||||
#The Emulation State.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues = Needs mmu to run, and it runs very slow because of it (r6436)
|
||||
[OnFrame]
|
||||
[ActionReplay]
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
[Core]
|
||||
MMU = 1
|
||||
VBeam = 1
|
||||
BlockMerging = 1
|
||||
[Video_Hacks]
|
||||
DlistCachingEnable = False
|
||||
@@ -0,0 +1,21 @@
|
||||
# G3FP69 - TimeSplitters Future Perfect
|
||||
[EmuState]
|
||||
#The Emulation State.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues = Needs mmu to run, and it runs very slow because of it (r6436)
|
||||
[OnFrame]
|
||||
[ActionReplay]
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
[Core]
|
||||
MMU = 1
|
||||
VBeam = 1
|
||||
BlockMerging = 1
|
||||
[Video_Hacks]
|
||||
DlistCachingEnable = False
|
||||
@@ -0,0 +1,7 @@
|
||||
# G3JEAF - CuriousGeorge
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationIssues = Stuck at memcard check
|
||||
EmulationStateId = 1
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,6 @@
|
||||
# G3NJDA - NARUTO3
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,7 @@
|
||||
# G3QEA4 - TMNT3
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack=1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 5
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,10 @@
|
||||
# G3SE41 - BUST A MOVE 3000
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 5
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# G3VE69 - NBA STREET V3
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 0
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,16 @@
|
||||
# G3XE52 - X-Men: The Official Game
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
MMU = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
@@ -0,0 +1,11 @@
|
||||
# G3XP52 - X-Men: The Official Game
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
MMU = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
[Gecko]
|
||||
@@ -0,0 +1,21 @@
|
||||
# G4AEE9 - HARVEST MOON - Magical Melody -
|
||||
[EmuState]
|
||||
EmulationStateId = 4
|
||||
# !!!WARNING!!!
|
||||
# Time Does NOT flow with current Release.
|
||||
# !!!WARNING!!!
|
||||
EmulationIssues =
|
||||
[OnFrame]#Add memory patches here.
|
||||
[Video_Enhancements]
|
||||
PostProcessingShader =
|
||||
[Video_Hacks]
|
||||
DlistCachingEnable = False
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[ActionReplay]
|
||||
[Gecko]
|
||||
@@ -0,0 +1,9 @@
|
||||
# G4BE08 - resident evil 4 game disc 1
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
@@ -0,0 +1,9 @@
|
||||
# G4BP08 - resident evil 4 game disc 1
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
@@ -0,0 +1,9 @@
|
||||
# G4CE54 - Charlie and The Chocolate Factory
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack=1
|
||||
UseDualCore = 0
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
Issues="Don't try DC because high LOAD CPU!!! and with Optimize Quantizers crash"
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,11 @@
|
||||
# G4FD69 - FIFA 07
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
MMU = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues = Sound issues need LLE plugin and videos are messed up. Slow due to MMU(r6932)
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
[Gecko]
|
||||
@@ -0,0 +1,12 @@
|
||||
# G4FE69 - FIFA 07
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
MMU = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 3
|
||||
EmulationIssues = Sound issues need LLE plugin and videos are messed up. Slow due to MMU(r6932)
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
[Gecko]
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# G4FF69 - FIFA 07
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
MMU = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues = Sound issues need LLE plugin and videos are messed up. Slow due to MMU(r6932)
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
[Gecko]
|
||||
@@ -0,0 +1,11 @@
|
||||
# G4FE69 - FIFA 07
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
MMU = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues = Sound issues need LLE plugin and videos are messed up. Slow due to MMU(r6932)
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
[Gecko]
|
||||
@@ -0,0 +1,67 @@
|
||||
# G4GEE9 - Harvest Moon: Another Wonderful Life - NTSC
|
||||
|
||||
[EmuState]
|
||||
# The Emulation State as of r1062; screen text hidden behind background; essentially non-playable. # Even when text was visible, the font was corrupted so the text was unreadable
|
||||
EmulationStateId = 2
|
||||
|
||||
[OnFrame]
|
||||
#Add memory patches here.
|
||||
|
||||
[ActionReplay]
|
||||
#Add decrypted action replay cheats here.
|
||||
|
||||
$(M)
|
||||
06C2E568 88000000
|
||||
C41D3578 0000FF01
|
||||
|
||||
$Infinite Money
|
||||
06C2E569 08000000
|
||||
050943A8 0098967F
|
||||
|
||||
$Infinite Fodder In Barn
|
||||
06C2E56A 08000000
|
||||
030A3EDC 000003E7
|
||||
|
||||
$Chickens Always Have Feed
|
||||
06C2E56B 08000000
|
||||
03094E46 00005D8A
|
||||
|
||||
$All Tools In Shed
|
||||
04055934 38000091
|
||||
04055938 98030008
|
||||
|
||||
$All Barn Animals Have Food
|
||||
06C2E56D 08000000
|
||||
01094D8F 00000004
|
||||
01094D93 00000003
|
||||
01094DA7 00000004
|
||||
01094DAB 00000003
|
||||
01094DBF 00000004
|
||||
01094DC3 00000003
|
||||
01094DD7 00000004
|
||||
01094DDB 00000003
|
||||
01094DEF 00000004
|
||||
01094DF3 00000003
|
||||
01094E07 00000004
|
||||
01094E0B 00000003
|
||||
01094E1F 00000004
|
||||
01094E23 00000003
|
||||
01094E37 00000004
|
||||
01094E3B 00000003
|
||||
|
||||
$Increase Time Speed (D Pad Up)
|
||||
06C2E56E 08000000
|
||||
4A3434E6 00000008
|
||||
1A01245A 00006000
|
||||
8201245A 00000001
|
||||
|
||||
$Decrease Time Speed (D Pad Down)
|
||||
06C2E56F 08000000
|
||||
4A3434E6 00000004
|
||||
2201245A 00000000
|
||||
8201245A 0000FFFF
|
||||
|
||||
$Reset Time Speed (D Pad Right)
|
||||
06C2E570 08000000
|
||||
0A3434E6 00000002
|
||||
04012458 38080014
|
||||
@@ -0,0 +1,17 @@
|
||||
# G4ME69 - The Sims: Bustin Out GameCube
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# G4MP69 - The Sims: Bustin Out GameCube
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
@@ -0,0 +1,14 @@
|
||||
# G4NJDA - NARUTO Gekitou Ninja Taisen! 4
|
||||
[Core]
|
||||
#Values set here will override the main dolphin settings.
|
||||
[EmuState]
|
||||
#The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
[OnFrame]
|
||||
Master Code
|
||||
0FC07078 A8000000
|
||||
C4175B8C 0000FF00
|
||||
[ActionReplay]
|
||||
Everything unlocked
|
||||
042232F0 00FFFFFF
|
||||
002232FC 00002FFF
|
||||
@@ -0,0 +1,34 @@
|
||||
# G4QE01 - Mario Soccer
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 5
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
$Master Code
|
||||
C425B280 0000FF01
|
||||
$Press D-Pad Up - Team 1 Wins
|
||||
4A32C348 00000008
|
||||
40371238 00003F32
|
||||
4037123C 00003F00
|
||||
$Press D-Pad Down - Team 2 Wins
|
||||
4A32C348 00000004
|
||||
40371238 00003F00
|
||||
4037123C 00003F32
|
||||
$Press D-Pad Left To End Match
|
||||
0A32C348 00000001
|
||||
42371238 FFBC4416
|
||||
$Press D-Pad Right For More Time
|
||||
0A32C348 00000002
|
||||
42371238 FFBC0000
|
||||
$Have All Milestone Trophies
|
||||
03535D50 0000012C
|
||||
03535D52 00000064
|
||||
03535D54 0000012C
|
||||
03535D56 000003E8
|
||||
03535D4E 00000064
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
[Gecko]
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# G4QP01 - Mario Smash Football
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState]
|
||||
#The Emulation State.
|
||||
EmulationStateId = 5
|
||||
EmulationIssues = Needs TLB Hack
|
||||
[OnFrame]
|
||||
[ActionReplay]
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
[Core]
|
||||
TLBHack = 1
|
||||
@@ -0,0 +1,16 @@
|
||||
# G4SE01 - The Legend of Zelda: Four Swords FOR NINTENDO GAMECUBE
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
# G4SP01 - The Legend of Zelda: Four Swords FOR NINTENDO GAMECUBE
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay]
|
||||
$(M)
|
||||
0658E214 98000000
|
||||
C404F588 0002FF00
|
||||
$Infinite Health
|
||||
0658E215 18000000
|
||||
04247EDC 80030BF8
|
||||
04247EE0 90030BFC
|
||||
04247EE4 4800000C
|
||||
$Max Health
|
||||
0658E216 18000000
|
||||
0425AB40 38000020
|
||||
$Max/Infinite Force Gems
|
||||
0658E217 18000000
|
||||
0423C730 3860270F
|
||||
$All Adventure Mode Levels Unlocked
|
||||
0658E218 18000000
|
||||
0452A2C8 FFFFFFFF
|
||||
0452A390 FFFFFFFF
|
||||
0452A548 FFFFFFFF
|
||||
$Items Always Level 2
|
||||
0658E22C 18000000
|
||||
04247BB4 38600002
|
||||
$Super Jump
|
||||
0658E219 18000000
|
||||
0455D684 415CCCCD
|
||||
$Infinite Force Fairies
|
||||
0658E21A 18000000
|
||||
00545660 00000063
|
||||
0052A390 00000063
|
||||
$Infinite Air
|
||||
0658E21B 18000000
|
||||
04248F40 38030000
|
||||
04289A44 38030000
|
||||
$Massive Links
|
||||
0658E21C 18000000
|
||||
0426B82C C02200DC
|
||||
0426B834 C06200DC
|
||||
0426B844 C00200DC
|
||||
$Mini Links
|
||||
0658E21D 18000000
|
||||
0426B82C C0220108
|
||||
0426B834 C0620108
|
||||
0426B844 C0020108
|
||||
$More Time On Huge Death Bombs(Press Z)
|
||||
0658E21E 18000000
|
||||
0434A148 3803FFFF
|
||||
0A52EA28 00000010
|
||||
0434A148 38000300
|
||||
$Item Codes
|
||||
0658E21F 15008000
|
||||
$Pegasus Boots(D-Pad Left)
|
||||
0658E220 14710FC0
|
||||
0A54BD94 00000001
|
||||
04247D04 38600001
|
||||
$Lantern(D-Pad Right)
|
||||
0658E221 14710FC0
|
||||
0A54BD94 00000002
|
||||
04247D04 38600002
|
||||
$Boomerang(D-Pad Up)
|
||||
0658E222 14710FC0
|
||||
0A54BD94 00000008
|
||||
04247D04 38600003
|
||||
$Bow & Arrows(D-Pad Down)
|
||||
0658E223 14710FC0
|
||||
0A54BD94 00000004
|
||||
04247D04 38600004
|
||||
$Magic Hammer(L+D-Pad Left)
|
||||
0658E224 14710FC0
|
||||
0A54BD94 00000041
|
||||
04247D04 38600005
|
||||
$Fire Rod(L+D-Pad Right)
|
||||
0658E225 14710FC0
|
||||
0A54BD94 00000042
|
||||
04247D04 38600006
|
||||
$Roc's Feather(L+D-Pad)
|
||||
0658E226 14710FC0
|
||||
0A54BD94 00000048
|
||||
04247D04 38600007
|
||||
$Bombs(L+D-Pad)
|
||||
0658E227 14710FC0
|
||||
0A54BD94 00000044
|
||||
04247D04 38600008
|
||||
$Shovel(R Button)
|
||||
0658E228 14710FC0
|
||||
0A54BD94 00000020
|
||||
04247D04 38600009
|
||||
$Slingshot(Z BUtton)
|
||||
0658E229 14710FC0
|
||||
0A54BD94 00000010
|
||||
04247D04 3860000A
|
||||
$Have Blue Bracelet
|
||||
0658E22A 14710FC0
|
||||
0A54BD94 60000000
|
||||
$Have Power Bracelet
|
||||
0658E22B 14710FC0
|
||||
0A54BD94 60000000
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
[Gecko]
|
||||
@@ -0,0 +1,8 @@
|
||||
# G4ZE69 - The Sims 2 GameCube
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack=1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 2
|
||||
Issues="Go to menu and select options, then hangs"
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,8 @@
|
||||
# G63E41 - RainbowSix3
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationIssues =
|
||||
EmulationStateId = 1
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,8 @@
|
||||
# G63P41 - RainbowSix3
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack=1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
Issues="Needs Projection Hack R844 and Copy EFB to GL texture"
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,7 @@
|
||||
# G6FE69 - 2006 FIFA World Cup
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 3
|
||||
EmulationIssues = Sound missing in menus game can crash randomly
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,7 @@
|
||||
# G6NE69 - NBA LIVE 06
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,7 @@
|
||||
# G6NP69 - NBA LIVE 06
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,7 @@
|
||||
# G6QE08 - Megaman Collection
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 4
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
@@ -0,0 +1,17 @@
|
||||
# G6TE5G - Teen Titans
|
||||
[Core] Values set here will override the main dolphin settings.
|
||||
TLBHack = 1
|
||||
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||
EmulationStateId = 2
|
||||
EmulationIssues =
|
||||
[OnFrame] Add memory patches to be applied every frame here.
|
||||
[ActionReplay] Add action replay cheats here.
|
||||
[Video]
|
||||
ProjectionHack = 0
|
||||
PH_SZNear = 0
|
||||
PH_SZFar = 0
|
||||
PH_ExtraParam = 0
|
||||
PH_ZNear =
|
||||
PH_ZFar =
|
||||
[Gecko]
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user