summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorLPFaint99 <lpfaint99@gmail.com>2009-07-06 02:10:26 +0000
committerLPFaint99 <lpfaint99@gmail.com>2009-07-06 02:10:26 +0000
commita41c1b2d0a9fab51f8a75ccdb7dba0890f766820 (patch)
tree5cc47f2330d83ece993db6443e944c103235821b /Source
parent23f3e327e2f96843b0deebafddef12d195d73381 (diff)
add *.user, Win32, and x64 build dir to ignore list for DebuggerUICommon and Unit Tests
add *.aps to ignore list for DolphinWX dir add eol-style native to 120 or so files git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3689 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/AudioCommon/Src/AudioCommon.cpp176
-rw-r--r--Source/Core/AudioCommon/Src/AudioCommon.h80
-rw-r--r--Source/Core/AudioCommon/Src/AudioCommonConfig.cpp104
-rw-r--r--Source/Core/AudioCommon/Src/AudioCommonConfig.h100
-rw-r--r--Source/Core/AudioCommon/Src/OpenALStream.cpp340
-rw-r--r--Source/Core/AudioCommon/Src/OpenALStream.h148
-rw-r--r--Source/Core/AudioCommon/Src/aldlist.cpp682
-rw-r--r--Source/Core/AudioCommon/Src/aldlist.h102
-rw-r--r--Source/Core/Common/Src/SymbolDB.cpp118
-rw-r--r--Source/Core/Common/Src/SymbolDB.h244
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Usb_Kbd_apple.h48
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Usb_Kbd_linux.h50
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Usb_Kbd_win32.h382
-rw-r--r--Source/Core/DSPCore/Src/DSPAnalyzer.cpp266
-rw-r--r--Source/Core/DSPCore/Src/DSPAnalyzer.h98
-rw-r--r--Source/Core/DSPCore/Src/DSPBreakpoints.cpp38
-rw-r--r--Source/Core/DSPCore/Src/DSPBreakpoints.h126
-rw-r--r--Source/Core/DSPCore/Src/DSPCodeUtil.cpp470
-rw-r--r--Source/Core/DSPCore/Src/DSPCodeUtil.h86
-rw-r--r--Source/Core/DSPCore/Src/DSPCore.cpp512
-rw-r--r--Source/Core/DSPCore/Src/DSPCore.h480
-rw-r--r--Source/Core/DSPCore/Src/DSPHost.h70
-rw-r--r--Source/Core/DSPCore/Src/DSPIntCCUtil.cpp280
-rw-r--r--Source/Core/DSPCore/Src/DSPIntCCUtil.h78
-rw-r--r--Source/Core/DSPCore/Src/DSPInterpreter.h342
-rw-r--r--Source/Core/DSPCore/Src/DSPJit.cpp44
-rw-r--r--Source/Core/DSPCore/Src/DSPJit.h56
-rw-r--r--Source/Core/DSPCore/Src/DSPTables.cpp1166
-rw-r--r--Source/Core/DSPCore/Src/DSPTables.h336
-rw-r--r--Source/Core/DSPCore/Src/DspIntArithmetic.cpp1468
-rw-r--r--Source/Core/DSPCore/Src/DspIntBranch.cpp498
-rw-r--r--Source/Core/DSPCore/Src/DspIntLoadStore.cpp532
-rw-r--r--Source/Core/DSPCore/Src/DspIntMisc.cpp404
-rw-r--r--Source/Core/DSPCore/Src/DspIntMultiplier.cpp1004
-rw-r--r--Source/Core/DSPCore/Src/LabelMap.cpp170
-rw-r--r--Source/Core/DSPCore/Src/LabelMap.h110
-rw-r--r--Source/Core/DSPCore/Src/assemble.cpp2032
-rw-r--r--Source/Core/DSPCore/Src/assemble.h278
-rw-r--r--Source/Core/DebuggerUICommon/Src/DebuggerUIUtil.cpp46
-rw-r--r--Source/Core/DebuggerUICommon/Src/DebuggerUIUtil.h72
-rw-r--r--Source/Core/DiscIO/Src/NANDContentLoader.h200
-rw-r--r--Source/Core/DiscIO/Src/VolumeWad.h104
-rw-r--r--Source/Core/DiscIO/Src/WiiWad.cpp312
-rw-r--r--Source/Core/DiscIO/Src/WiiWad.h156
-rw-r--r--Source/Core/DolphinWX/Src/NetEvent.cpp576
-rw-r--r--Source/Core/DolphinWX/Src/NetFunctions.cpp1180
-rw-r--r--Source/Core/DolphinWX/Src/NetSockets.cpp1190
-rw-r--r--Source/Core/DolphinWX/Src/NetWindow.cpp1110
-rw-r--r--Source/Core/DolphinWX/Src/NetWindow.h634
-rw-r--r--Source/Core/DolphinWX/Src/Summarize.h252
-rw-r--r--Source/Core/DolphinWX/resources/Dolphin.xpm258
-rw-r--r--Source/Core/DolphinWX/resources/Flag_Europe.xpm166
-rw-r--r--Source/Core/DolphinWX/resources/Flag_France.xpm160
-rw-r--r--Source/Core/DolphinWX/resources/Flag_Japan.xpm204
-rw-r--r--Source/Core/DolphinWX/resources/Flag_Taiwan.xpm246
-rw-r--r--Source/Core/DolphinWX/resources/Flag_USA.xpm130
-rw-r--r--Source/Core/VideoCommon/Src/AVIDump.cpp358
-rw-r--r--Source/Core/VideoCommon/Src/BPFunctions.h118
-rw-r--r--Source/Core/VideoCommon/Src/BPStructs.cpp1220
-rw-r--r--Source/Core/VideoCommon/Src/BPStructs.h54
-rw-r--r--Source/Core/VideoCommon/Src/HiresTextures.cpp308
-rw-r--r--Source/DSPSpy/Config.h36
-rw-r--r--Source/DSPSpy/Stubs.cpp238
-rw-r--r--Source/DSPSpy/dsp_interface.cpp84
-rw-r--r--Source/DSPSpy/dsp_interface.h100
-rw-r--r--Source/DSPSpy/main_spy.cpp1130
-rw-r--r--Source/DSPSpy/real_dsp.cpp136
-rw-r--r--Source/DSPSpy/real_dsp.h62
-rw-r--r--Source/DSPTool/Src/main.cpp806
-rw-r--r--Source/Plugins/Plugin_DSP_HLE/Src/HLEMixer.cpp84
-rw-r--r--Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_ADPCM.cpp190
-rw-r--r--Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_ADPCM.h40
-rw-r--r--Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_Synth.cpp212
-rw-r--r--Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_Voice.cpp932
-rw-r--r--Source/Plugins/Plugin_DSP_LLE/Src/DSPDebugInterface.cpp358
-rw-r--r--Source/Plugins/Plugin_DSP_LLE/Src/DSPDebugInterface.h66
-rw-r--r--Source/Plugins/Plugin_DSP_LLE/Src/DSPHost.cpp230
-rw-r--r--Source/Plugins/Plugin_DSP_LLE/Src/DSPSymbols.cpp574
-rw-r--r--Source/Plugins/Plugin_DSP_LLE/Src/DSPSymbols.h108
-rw-r--r--Source/Plugins/Plugin_DSP_LLE/Src/Debugger/Debugger.cpp456
-rw-r--r--Source/Plugins/Plugin_DSP_LLE/Src/Debugger/Debugger.h252
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp670
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp424
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp902
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.h304
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/PostProcessing.cpp178
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/PostProcessing.h72
-rw-r--r--Source/Plugins/Plugin_nJoy_SDL/Src/GUI/Images/njoy.xpm8056
-rw-r--r--Source/Plugins/Plugin_nJoy_Testing/Src/GUI/Images/njoy.xpm8056
-rw-r--r--Source/TestSuite/FPU/source/dolphintest_fpu.cpp216
-rw-r--r--Source/TestSuite/PAD/source/dolphintest_pad.cpp66
-rw-r--r--Source/TestSuite/RTC/source/dolphintest_rtc.cpp142
-rw-r--r--Source/TestSuite/WRTC/source/dolphintest_wrtc.cpp142
-rw-r--r--Source/UnitTests/UnitTests.cpp284
94 files changed, 24089 insertions, 24089 deletions
diff --git a/Source/Core/AudioCommon/Src/AudioCommon.cpp b/Source/Core/AudioCommon/Src/AudioCommon.cpp
index 9e7100451a..8c7ca0a524 100644
--- a/Source/Core/AudioCommon/Src/AudioCommon.cpp
+++ b/Source/Core/AudioCommon/Src/AudioCommon.cpp
@@ -1,88 +1,88 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "AudioCommon.h"
-#include "Mixer.h"
-#include "DSoundStream.h"
-#include "AOSoundStream.h"
-#include "NullSoundStream.h"
-#include "OpenALStream.h"
-
-namespace AudioCommon
-{
- SoundStream *InitSoundStream(CMixer *mixer)
- {
- if (!mixer)
- mixer = new CMixer();
-
- std::string backend = ac_Config.sBackend;
- if (backend == BACKEND_DIRECTSOUND && DSound::isValid()) soundStream = new DSound(mixer, g_dspInitialize.hWnd);
- if (backend == BACKEND_AOSOUND && AOSound::isValid()) soundStream = new AOSound(mixer);
- if (backend == BACKEND_OPENAL && OpenALStream::isValid()) soundStream = new OpenALStream(mixer);
- if (backend == BACKEND_NULL && NullSound::isValid()) soundStream = new NullSound(mixer);
-
- if (soundStream != NULL) {
- ac_Config.Update();
- if (soundStream->Start()) {
- // Start the sound recording
- /*
- if (ac_Config.record) {
- soundStream->StartLogAudio(FULL_DUMP_DIR g_Config.recordFile);
- }
- */
-
- return soundStream;
- }
- PanicAlert("Could not initialize backend %s, falling back to NULL", backend.c_str());
- }
-
- PanicAlert("Sound backend %s is not valid, falling back to NULL", backend.c_str());
-
- delete soundStream;
- soundStream = new NullSound(mixer);
- soundStream->Start();
-
- return NULL;
- }
-
- void ShutdownSoundStream()
- {
- NOTICE_LOG(DSPHLE, "Shutting down sound stream");
-
- if (soundStream)
- {
- soundStream->Stop();
- soundStream->StopLogAudio();
- delete soundStream;
- soundStream = NULL;
- }
-
- INFO_LOG(DSPHLE, "Done shutting down sound stream");
- }
-
- std::vector<std::string> GetSoundBackends()
- {
- std::vector<std::string> backends;
-
- if (DSound::isValid()) backends.push_back(BACKEND_DIRECTSOUND);
- if (AOSound::isValid()) backends.push_back(BACKEND_AOSOUND);
- if (OpenALStream::isValid()) backends.push_back(BACKEND_OPENAL);
- if (NullSound::isValid()) backends.push_back(BACKEND_NULL);
-
- return backends;
- }
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "AudioCommon.h"
+#include "Mixer.h"
+#include "DSoundStream.h"
+#include "AOSoundStream.h"
+#include "NullSoundStream.h"
+#include "OpenALStream.h"
+
+namespace AudioCommon
+{
+ SoundStream *InitSoundStream(CMixer *mixer)
+ {
+ if (!mixer)
+ mixer = new CMixer();
+
+ std::string backend = ac_Config.sBackend;
+ if (backend == BACKEND_DIRECTSOUND && DSound::isValid()) soundStream = new DSound(mixer, g_dspInitialize.hWnd);
+ if (backend == BACKEND_AOSOUND && AOSound::isValid()) soundStream = new AOSound(mixer);
+ if (backend == BACKEND_OPENAL && OpenALStream::isValid()) soundStream = new OpenALStream(mixer);
+ if (backend == BACKEND_NULL && NullSound::isValid()) soundStream = new NullSound(mixer);
+
+ if (soundStream != NULL) {
+ ac_Config.Update();
+ if (soundStream->Start()) {
+ // Start the sound recording
+ /*
+ if (ac_Config.record) {
+ soundStream->StartLogAudio(FULL_DUMP_DIR g_Config.recordFile);
+ }
+ */
+
+ return soundStream;
+ }
+ PanicAlert("Could not initialize backend %s, falling back to NULL", backend.c_str());
+ }
+
+ PanicAlert("Sound backend %s is not valid, falling back to NULL", backend.c_str());
+
+ delete soundStream;
+ soundStream = new NullSound(mixer);
+ soundStream->Start();
+
+ return NULL;
+ }
+
+ void ShutdownSoundStream()
+ {
+ NOTICE_LOG(DSPHLE, "Shutting down sound stream");
+
+ if (soundStream)
+ {
+ soundStream->Stop();
+ soundStream->StopLogAudio();
+ delete soundStream;
+ soundStream = NULL;
+ }
+
+ INFO_LOG(DSPHLE, "Done shutting down sound stream");
+ }
+
+ std::vector<std::string> GetSoundBackends()
+ {
+ std::vector<std::string> backends;
+
+ if (DSound::isValid()) backends.push_back(BACKEND_DIRECTSOUND);
+ if (AOSound::isValid()) backends.push_back(BACKEND_AOSOUND);
+ if (OpenALStream::isValid()) backends.push_back(BACKEND_OPENAL);
+ if (NullSound::isValid()) backends.push_back(BACKEND_NULL);
+
+ return backends;
+ }
+}
diff --git a/Source/Core/AudioCommon/Src/AudioCommon.h b/Source/Core/AudioCommon/Src/AudioCommon.h
index ba0a1a7e87..2e61b3491f 100644
--- a/Source/Core/AudioCommon/Src/AudioCommon.h
+++ b/Source/Core/AudioCommon/Src/AudioCommon.h
@@ -1,40 +1,40 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _AUDIO_COMMON_H_
-#define _AUDIO_COMMON_H_
-
-#include "Common.h"
-#include "AudioCommonConfig.h"
-#include "../../../PluginSpecs/pluginspecs_dsp.h"
-#include "SoundStream.h"
-
-
-class CMixer;
-
-extern DSPInitialize g_dspInitialize;
-extern SoundStream *soundStream;
-extern AudioCommonConfig ac_Config;
-
-namespace AudioCommon
-{
- SoundStream *InitSoundStream(CMixer *mixer = NULL);
- void ShutdownSoundStream();
- std::vector<std::string> GetSoundBackends();
-}
-
-#endif // _AUDIO_COMMON_H_
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _AUDIO_COMMON_H_
+#define _AUDIO_COMMON_H_
+
+#include "Common.h"
+#include "AudioCommonConfig.h"
+#include "../../../PluginSpecs/pluginspecs_dsp.h"
+#include "SoundStream.h"
+
+
+class CMixer;
+
+extern DSPInitialize g_dspInitialize;
+extern SoundStream *soundStream;
+extern AudioCommonConfig ac_Config;
+
+namespace AudioCommon
+{
+ SoundStream *InitSoundStream(CMixer *mixer = NULL);
+ void ShutdownSoundStream();
+ std::vector<std::string> GetSoundBackends();
+}
+
+#endif // _AUDIO_COMMON_H_
diff --git a/Source/Core/AudioCommon/Src/AudioCommonConfig.cpp b/Source/Core/AudioCommon/Src/AudioCommonConfig.cpp
index fd58aa2c50..90ef0461a4 100644
--- a/Source/Core/AudioCommon/Src/AudioCommonConfig.cpp
+++ b/Source/Core/AudioCommon/Src/AudioCommonConfig.cpp
@@ -1,52 +1,52 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "AudioCommon.h"
-AudioCommonConfig ac_Config;
-
-// Load from given file
-void AudioCommonConfig::Load(IniFile &file) {
- file.Get("Config", "EnableDTKMusic", &m_EnableDTKMusic, true);
- file.Get("Config", "EnableThrottle", &m_EnableThrottle, true);
- file.Get("Config", "Volume", &m_Volume, 75);
-#ifdef _WIN32
- file.Get("Config", "Backend", &sBackend, "DSound");
-#elif defined(__APPLE__)
- std::string temp;
- file.Get("Config", "Backend", &temp, "AOSound");
- strncpy(sBackend, temp.c_str(), 128);
-#else
- file.Get("Config", "Backend", &sBackend, "AOSound");
-#endif
-}
-
-// Set the values for the file
-void AudioCommonConfig::Set(IniFile &file) {
- file.Set("Config", "EnableDTKMusic", m_EnableDTKMusic);
- file.Set("Config", "EnableThrottle", m_EnableThrottle);
- file.Set("Config", "Backend", sBackend);
- file.Set("Config", "Volume", m_Volume);
-}
-
-// Update according to the values (stream/mixer)
-void AudioCommonConfig::Update() {
- if (soundStream) {
- soundStream->GetMixer()->SetThrottle(m_EnableThrottle);
- soundStream->GetMixer()->SetDTKMusic(m_EnableDTKMusic);
- soundStream->SetVolume(m_Volume);
- }
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "AudioCommon.h"
+AudioCommonConfig ac_Config;
+
+// Load from given file
+void AudioCommonConfig::Load(IniFile &file) {
+ file.Get("Config", "EnableDTKMusic", &m_EnableDTKMusic, true);
+ file.Get("Config", "EnableThrottle", &m_EnableThrottle, true);
+ file.Get("Config", "Volume", &m_Volume, 75);
+#ifdef _WIN32
+ file.Get("Config", "Backend", &sBackend, "DSound");
+#elif defined(__APPLE__)
+ std::string temp;
+ file.Get("Config", "Backend", &temp, "AOSound");
+ strncpy(sBackend, temp.c_str(), 128);
+#else
+ file.Get("Config", "Backend", &sBackend, "AOSound");
+#endif
+}
+
+// Set the values for the file
+void AudioCommonConfig::Set(IniFile &file) {
+ file.Set("Config", "EnableDTKMusic", m_EnableDTKMusic);
+ file.Set("Config", "EnableThrottle", m_EnableThrottle);
+ file.Set("Config", "Backend", sBackend);
+ file.Set("Config", "Volume", m_Volume);
+}
+
+// Update according to the values (stream/mixer)
+void AudioCommonConfig::Update() {
+ if (soundStream) {
+ soundStream->GetMixer()->SetThrottle(m_EnableThrottle);
+ soundStream->GetMixer()->SetDTKMusic(m_EnableDTKMusic);
+ soundStream->SetVolume(m_Volume);
+ }
+}
diff --git a/Source/Core/AudioCommon/Src/AudioCommonConfig.h b/Source/Core/AudioCommon/Src/AudioCommonConfig.h
index 53507325f9..b43b0e5e81 100644
--- a/Source/Core/AudioCommon/Src/AudioCommonConfig.h
+++ b/Source/Core/AudioCommon/Src/AudioCommonConfig.h
@@ -1,50 +1,50 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _AUDIO_COMMON_CONFIG_H_
-#define _AUDIO_COMMON_CONFIG_H_
-
-#include <string>
-#include "IniFile.h"
-
-// Backend Types
-#define BACKEND_DIRECTSOUND "DSound"
-#define BACKEND_AOSOUND "AOSound"
-#define BACKEND_OPENAL "OpenAL"
-#define BACKEND_NULL "NullSound"
-struct AudioCommonConfig
-{
- bool m_EnableDTKMusic;
- bool m_EnableThrottle;
- int m_Volume;
-#ifdef __APPLE__
- char sBackend[128];
-#else
- std::string sBackend;
-#endif
-
- // Load from given file
- void Load(IniFile &file);
-
- // Set the values for the file
- void Set(IniFile &file);
-
- // Update according to the values (stream/mixer)
- void Update();
-};
-
-#endif //AUDIO_COMMON_CONFIG
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _AUDIO_COMMON_CONFIG_H_
+#define _AUDIO_COMMON_CONFIG_H_
+
+#include <string>
+#include "IniFile.h"
+
+// Backend Types
+#define BACKEND_DIRECTSOUND "DSound"
+#define BACKEND_AOSOUND "AOSound"
+#define BACKEND_OPENAL "OpenAL"
+#define BACKEND_NULL "NullSound"
+struct AudioCommonConfig
+{
+ bool m_EnableDTKMusic;
+ bool m_EnableThrottle;
+ int m_Volume;
+#ifdef __APPLE__
+ char sBackend[128];
+#else
+ std::string sBackend;
+#endif
+
+ // Load from given file
+ void Load(IniFile &file);
+
+ // Set the values for the file
+ void Set(IniFile &file);
+
+ // Update according to the values (stream/mixer)
+ void Update();
+};
+
+#endif //AUDIO_COMMON_CONFIG
diff --git a/Source/Core/AudioCommon/Src/OpenALStream.cpp b/Source/Core/AudioCommon/Src/OpenALStream.cpp
index 9787734d9e..749e6ae793 100644
--- a/Source/Core/AudioCommon/Src/OpenALStream.cpp
+++ b/Source/Core/AudioCommon/Src/OpenALStream.cpp
@@ -1,170 +1,170 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "aldlist.h"
-#include "OpenALStream.h"
-
-#if defined HAVE_OPENAL && HAVE_OPENAL
-
-#define AUDIO_NUMBUFFERS (4)
-//#define AUDIO_SERVICE_UPDATE_PERIOD (20)
-
-bool OpenALStream::Start()
-{
- ALDeviceList *pDeviceList = NULL;
- ALCcontext *pContext = NULL;
- ALCdevice *pDevice = NULL;
- bool bReturn = false;
-
- pDeviceList = new ALDeviceList();
- if ((pDeviceList) && (pDeviceList->GetNumDevices()))
- {
- pDevice = alcOpenDevice((const ALCchar *)pDeviceList->GetDeviceName(pDeviceList->GetDefaultDevice()));
- if (pDevice)
- {
- pContext = alcCreateContext(pDevice, NULL);
- if (pContext)
- {
- alcMakeContextCurrent(pContext);
- thread = new Common::Thread(OpenALStream::ThreadFunc, (void *)this);
- bReturn = true;
- }
- else
- {
- alcCloseDevice(pDevice);
- PanicAlert("OpenAL: can't create context for device %s", pDevice);
- }
- } else {
- PanicAlert("OpenAL: can't open device %s", pDevice);
- }
-
-
- delete pDeviceList;
- } else {
- PanicAlert("OpenAL: can't find sound devices");
- }
-
- return bReturn;
-}
-
-void OpenALStream::Stop()
-{
- ALCcontext *pContext;
- ALCdevice *pDevice;
-
- soundCriticalSection.Enter();
- threadData = 1;
- // kick the thread if it's waiting
- soundSyncEvent.Set();
- soundCriticalSection.Leave();
- delete thread;
-
- pContext = alcGetCurrentContext();
- pDevice = alcGetContextsDevice(pContext);
-
- alcMakeContextCurrent(NULL);
- alcDestroyContext(pContext);
- alcCloseDevice(pDevice);
-
- soundSyncEvent.Shutdown();
- thread = NULL;
-}
-
-void OpenALStream::Update()
-{
- //if (m_mixer->GetDataSize()) //here need debug
- {
- soundSyncEvent.Set();
- }
-}
-
-THREAD_RETURN OpenALStream::ThreadFunc(void* args)
-{
- (reinterpret_cast<OpenALStream *>(args))->SoundLoop();
- return 0;
-}
-
-void OpenALStream::SoundLoop()
-{
- ALuint uiBuffers[AUDIO_NUMBUFFERS] = {0};
- ALuint uiSource = 0;
- ALenum err;
- u32 ulFrequency = m_mixer->GetSampleRate();
- // Generate some AL Buffers for streaming
- alGenBuffers(AUDIO_NUMBUFFERS, (ALuint *)uiBuffers);
- // Generate a Source to playback the Buffers
- alGenSources(1, &uiSource);
-
- memset(realtimeBuffer, 0, OAL_BUFFER_SIZE * sizeof(short));
-//*
- for (int iLoop = 0; iLoop < AUDIO_NUMBUFFERS; iLoop++)
- {
- // pay load fake data
- alBufferData(uiBuffers[iLoop], AL_FORMAT_STEREO16, realtimeBuffer, 1024, ulFrequency);
- alSourceQueueBuffers(uiSource, 1, &uiBuffers[iLoop]);
- }
-//*/
- alSourcePlay(uiSource);
- err = alGetError();
-
- while (!threadData)
- {
- soundCriticalSection.Enter();
- int numBytesToRender = 32768; //ya, this is a hack, we need real data count
- /*int numBytesRender =*/ m_mixer->Mix(realtimeBuffer, numBytesToRender >> 2);
- soundCriticalSection.Leave();
-
- //if (numBytesRender) //here need debug
- {
- ALint iBuffersProcessed = 0;
- alGetSourcei(uiSource, AL_BUFFERS_PROCESSED, &iBuffersProcessed);
-
- if (iBuffersProcessed)
- {
- // Remove the Buffer from the Queue. (uiBuffer contains the Buffer ID for the unqueued Buffer)
- ALuint uiTempBuffer = 0;
- alSourceUnqueueBuffers(uiSource, 1, &uiTempBuffer);
-/*
- soundCriticalSection.Enter();
- int numBytesToRender = 32768; //ya, this is a hack, we need real data count
- m_mixer->Mix(realtimeBuffer, numBytesToRender >> 2);
- soundCriticalSection.Leave();
-
- unsigned long ulBytesWritten = 0;
-*/
- //if (numBytesRender)
- {
- alBufferData(uiTempBuffer, AL_FORMAT_STEREO16, realtimeBuffer, numBytesToRender, ulFrequency);
- }
- alSourceQueueBuffers(uiSource, 1, &uiTempBuffer);
- }
- }
-
- if (!threadData)
- soundSyncEvent.Wait();
- }
- alSourceStop(uiSource);
- alSourcei(uiSource, AL_BUFFER, 0);
-
- // Clean up buffers and sources
- alDeleteSources(1, &uiSource);
- alDeleteBuffers(AUDIO_NUMBUFFERS, (ALuint *)uiBuffers);
-
-}
-
-#endif //HAVE_OPENAL
-
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "aldlist.h"
+#include "OpenALStream.h"
+
+#if defined HAVE_OPENAL && HAVE_OPENAL
+
+#define AUDIO_NUMBUFFERS (4)
+//#define AUDIO_SERVICE_UPDATE_PERIOD (20)
+
+bool OpenALStream::Start()
+{
+ ALDeviceList *pDeviceList = NULL;
+ ALCcontext *pContext = NULL;
+ ALCdevice *pDevice = NULL;
+ bool bReturn = false;
+
+ pDeviceList = new ALDeviceList();
+ if ((pDeviceList) && (pDeviceList->GetNumDevices()))
+ {
+ pDevice = alcOpenDevice((const ALCchar *)pDeviceList->GetDeviceName(pDeviceList->GetDefaultDevice()));
+ if (pDevice)
+ {
+ pContext = alcCreateContext(pDevice, NULL);
+ if (pContext)
+ {
+ alcMakeContextCurrent(pContext);
+ thread = new Common::Thread(OpenALStream::ThreadFunc, (void *)this);
+ bReturn = true;
+ }
+ else
+ {
+ alcCloseDevice(pDevice);
+ PanicAlert("OpenAL: can't create context for device %s", pDevice);
+ }
+ } else {
+ PanicAlert("OpenAL: can't open device %s", pDevice);
+ }
+
+
+ delete pDeviceList;
+ } else {
+ PanicAlert("OpenAL: can't find sound devices");
+ }
+
+ return bReturn;
+}
+
+void OpenALStream::Stop()
+{
+ ALCcontext *pContext;
+ ALCdevice *pDevice;
+
+ soundCriticalSection.Enter();
+ threadData = 1;
+ // kick the thread if it's waiting
+ soundSyncEvent.Set();
+ soundCriticalSection.Leave();
+ delete thread;
+
+ pContext = alcGetCurrentContext();
+ pDevice = alcGetContextsDevice(pContext);
+
+ alcMakeContextCurrent(NULL);
+ alcDestroyContext(pContext);
+ alcCloseDevice(pDevice);
+
+ soundSyncEvent.Shutdown();
+ thread = NULL;
+}
+
+void OpenALStream::Update()
+{
+ //if (m_mixer->GetDataSize()) //here need debug
+ {
+ soundSyncEvent.Set();
+ }
+}
+
+THREAD_RETURN OpenALStream::ThreadFunc(void* args)
+{
+ (reinterpret_cast<OpenALStream *>(args))->SoundLoop();
+ return 0;
+}
+
+void OpenALStream::SoundLoop()
+{
+ ALuint uiBuffers[AUDIO_NUMBUFFERS] = {0};
+ ALuint uiSource = 0;
+ ALenum err;
+ u32 ulFrequency = m_mixer->GetSampleRate();
+ // Generate some AL Buffers for streaming
+ alGenBuffers(AUDIO_NUMBUFFERS, (ALuint *)uiBuffers);
+ // Generate a Source to playback the Buffers
+ alGenSources(1, &uiSource);
+
+ memset(realtimeBuffer, 0, OAL_BUFFER_SIZE * sizeof(short));
+//*
+ for (int iLoop = 0; iLoop < AUDIO_NUMBUFFERS; iLoop++)
+ {
+ // pay load fake data
+ alBufferData(uiBuffers[iLoop], AL_FORMAT_STEREO16, realtimeBuffer, 1024, ulFrequency);
+ alSourceQueueBuffers(uiSource, 1, &uiBuffers[iLoop]);
+ }
+//*/
+ alSourcePlay(uiSource);
+ err = alGetError();
+
+ while (!threadData)
+ {
+ soundCriticalSection.Enter();
+ int numBytesToRender = 32768; //ya, this is a hack, we need real data count
+ /*int numBytesRender =*/ m_mixer->Mix(realtimeBuffer, numBytesToRender >> 2);
+ soundCriticalSection.Leave();
+
+ //if (numBytesRender) //here need debug
+ {
+ ALint iBuffersProcessed = 0;
+ alGetSourcei(uiSource, AL_BUFFERS_PROCESSED, &iBuffersProcessed);
+
+ if (iBuffersProcessed)
+ {
+ // Remove the Buffer from the Queue. (uiBuffer contains the Buffer ID for the unqueued Buffer)
+ ALuint uiTempBuffer = 0;
+ alSourceUnqueueBuffers(uiSource, 1, &uiTempBuffer);
+/*
+ soundCriticalSection.Enter();
+ int numBytesToRender = 32768; //ya, this is a hack, we need real data count
+ m_mixer->Mix(realtimeBuffer, numBytesToRender >> 2);
+ soundCriticalSection.Leave();
+
+ unsigned long ulBytesWritten = 0;
+*/
+ //if (numBytesRender)
+ {
+ alBufferData(uiTempBuffer, AL_FORMAT_STEREO16, realtimeBuffer, numBytesToRender, ulFrequency);
+ }
+ alSourceQueueBuffers(uiSource, 1, &uiTempBuffer);
+ }
+ }
+
+ if (!threadData)
+ soundSyncEvent.Wait();
+ }
+ alSourceStop(uiSource);
+ alSourcei(uiSource, AL_BUFFER, 0);
+
+ // Clean up buffers and sources
+ alDeleteSources(1, &uiSource);
+ alDeleteBuffers(AUDIO_NUMBUFFERS, (ALuint *)uiBuffers);
+
+}
+
+#endif //HAVE_OPENAL
+
diff --git a/Source/Core/AudioCommon/Src/OpenALStream.h b/Source/Core/AudioCommon/Src/OpenALStream.h
index 4624807006..83f9dc1341 100644
--- a/Source/Core/AudioCommon/Src/OpenALStream.h
+++ b/Source/Core/AudioCommon/Src/OpenALStream.h
@@ -1,74 +1,74 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _OPENALSTREAM_H_
-#define _OPENALSTREAM_H_
-
-#include "Common.h"
-#include "SoundStream.h"
-#include "Thread.h"
-
-
-#if defined HAVE_OPENAL && HAVE_OPENAL
-#ifdef _WIN32
-#include "../../../../Externals/OpenAL/include/al.h"
-#include "../../../../Externals/OpenAL/include/alc.h"
-#elif defined(__APPLE__)
-#include "openal/al.h"
-#include "openal/alc.h"
-#else
-#include "AL/al.h"
-#include "AL/alc.h"
-#endif // WIN32
-// public use
-#define SFX_MAX_SOURCE 1
-#define OAL_BUFFER_SIZE 1024*1024
-#endif
-
-
-class OpenALStream: public SoundStream
-{
-#if defined HAVE_OPENAL && HAVE_OPENAL
-public:
- OpenALStream(CMixer *mixer, void *hWnd = NULL): SoundStream(mixer) {};
- virtual ~OpenALStream() {};
-
- virtual bool Start();
- virtual void SoundLoop();
- virtual void Stop();
- static bool isValid() { return true; }
- virtual bool usesMixer() const { return true; }
- virtual void Update();
-
- static THREAD_RETURN ThreadFunc(void* args);
-
-private:
- Common::Thread *thread;
- Common::CriticalSection soundCriticalSection;
- Common::Event soundSyncEvent;
-
- short realtimeBuffer[OAL_BUFFER_SIZE];
-#else
-public:
- OpenALStream(CMixer *mixer, void *hWnd = NULL): SoundStream(mixer) {}
-#endif // HAVE_OPENAL
-};
-
-
-
-
-#endif // OPENALSTREAM
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _OPENALSTREAM_H_
+#define _OPENALSTREAM_H_
+
+#include "Common.h"
+#include "SoundStream.h"
+#include "Thread.h"
+
+
+#if defined HAVE_OPENAL && HAVE_OPENAL
+#ifdef _WIN32
+#include "../../../../Externals/OpenAL/include/al.h"
+#include "../../../../Externals/OpenAL/include/alc.h"
+#elif defined(__APPLE__)
+#include "openal/al.h"
+#include "openal/alc.h"
+#else
+#include "AL/al.h"
+#include "AL/alc.h"
+#endif // WIN32
+// public use
+#define SFX_MAX_SOURCE 1
+#define OAL_BUFFER_SIZE 1024*1024
+#endif
+
+
+class OpenALStream: public SoundStream
+{
+#if defined HAVE_OPENAL && HAVE_OPENAL
+public:
+ OpenALStream(CMixer *mixer, void *hWnd = NULL): SoundStream(mixer) {};
+ virtual ~OpenALStream() {};
+
+ virtual bool Start();
+ virtual void SoundLoop();
+ virtual void Stop();
+ static bool isValid() { return true; }
+ virtual bool usesMixer() const { return true; }
+ virtual void Update();
+
+ static THREAD_RETURN ThreadFunc(void* args);
+
+private:
+ Common::Thread *thread;
+ Common::CriticalSection soundCriticalSection;
+ Common::Event soundSyncEvent;
+
+ short realtimeBuffer[OAL_BUFFER_SIZE];
+#else
+public:
+ OpenALStream(CMixer *mixer, void *hWnd = NULL): SoundStream(mixer) {}
+#endif // HAVE_OPENAL
+};
+
+
+
+
+#endif // OPENALSTREAM
diff --git a/Source/Core/AudioCommon/Src/aldlist.cpp b/Source/Core/AudioCommon/Src/aldlist.cpp
index 1992271680..34e9f778d9 100644
--- a/Source/Core/AudioCommon/Src/aldlist.cpp
+++ b/Source/Core/AudioCommon/Src/aldlist.cpp
@@ -1,341 +1,341 @@
-/*
- * Copyright (c) 2006, Creative Labs Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this list of conditions and
- * the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
- * and the following disclaimer in the documentation and/or other materials provided with the distribution.
- * * Neither the name of Creative Labs Inc. nor the names of its contributors may be used to endorse or
- * promote products derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "Common.h"
-#include "aldlist.h"
-#include "../../../../Externals/OpenAL/include/al.h"
-#include "../../../../Externals/OpenAL/include/alc.h"
-
-
-/*
- * Init call
- */
-ALDeviceList::ALDeviceList()
-{
- ALDEVICEINFO ALDeviceInfo;
- char *devices;
- s32 index;
- const char *defaultDeviceName = NULL;
- const char *actualDeviceName = NULL;
-
- // DeviceInfo vector stores, for each enumerated device, it's device name, selection status, spec version #, and extension support
- vDeviceInfo.empty();
- vDeviceInfo.reserve(10);
-
- defaultDeviceIndex = 0;
-
- // grab function pointers for 1.0-API functions, and if successful proceed to enumerate all devices
- //if (LoadOAL10Library(NULL, &ALFunction) == TRUE) {
- if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT"))
- {
- devices = (char *)alcGetString(NULL, ALC_DEVICE_SPECIFIER);
- defaultDeviceName = (char *)alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
- index = 0;
- // go through device list (each device terminated with a single NULL, list terminated with double NULL)
- while (devices != NULL && strlen(devices) > 0)
- {
- if (strcmp(defaultDeviceName, devices) == 0)
- {
- defaultDeviceIndex = index;
- }
- ALCdevice *device = alcOpenDevice(devices);
- if (device)
- {
- ALCcontext *context = alcCreateContext(device, NULL);
- if (context)
- {
- alcMakeContextCurrent(context);
- // if new actual device name isn't already in the list, then add it...
- actualDeviceName = alcGetString(device, ALC_DEVICE_SPECIFIER);
- bool bNewName = true;
- for (s32 i = 0; i < GetNumDevices(); i++)
- {
- if (strcmp(GetDeviceName(i), actualDeviceName) == 0)
- {
- bNewName = false;
- }
- }
- if ((bNewName) && (actualDeviceName != NULL) && (strlen(actualDeviceName) > 0))
- {
- ALDeviceInfo.bSelected = true;
- ALDeviceInfo.strDeviceName = actualDeviceName;
- alcGetIntegerv(device, ALC_MAJOR_VERSION, sizeof(s32), &ALDeviceInfo.iMajorVersion);
- alcGetIntegerv(device, ALC_MINOR_VERSION, sizeof(s32), &ALDeviceInfo.iMinorVersion);
-
- ALDeviceInfo.pvstrExtensions = new vector<string>;
-
- // Check for ALC Extensions
- if (alcIsExtensionPresent(device, "ALC_EXT_CAPTURE") == AL_TRUE)
- ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_CAPTURE");
- if (alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_TRUE)
- ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_EFX");
-
- // Check for AL Extensions
- if (alIsExtensionPresent("AL_EXT_OFFSET") == AL_TRUE)
- ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_OFFSET");
-
- if (alIsExtensionPresent("AL_EXT_LINEAR_DISTANCE") == AL_TRUE)
- ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_LINEAR_DISTANCE");
- if (alIsExtensionPresent("AL_EXT_EXPONENT_DISTANCE") == AL_TRUE)
- ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_EXPONENT_DISTANCE");
-
- if (alIsExtensionPresent("EAX2.0") == AL_TRUE)
- ALDeviceInfo.pvstrExtensions->push_back("EAX2.0");
- if (alIsExtensionPresent("EAX3.0") == AL_TRUE)
- ALDeviceInfo.pvstrExtensions->push_back("EAX3.0");
- if (alIsExtensionPresent("EAX4.0") == AL_TRUE)
- ALDeviceInfo.pvstrExtensions->push_back("EAX4.0");
- if (alIsExtensionPresent("EAX5.0") == AL_TRUE)
- ALDeviceInfo.pvstrExtensions->push_back("EAX5.0");
-
- if (alIsExtensionPresent("EAX-RAM") == AL_TRUE)
- ALDeviceInfo.pvstrExtensions->push_back("EAX-RAM");
-
- // Get Source Count
- ALDeviceInfo.uiSourceCount = GetMaxNumSources();
-
- vDeviceInfo.push_back(ALDeviceInfo);
- }
- alcMakeContextCurrent(NULL);
- alcDestroyContext(context);
- }
- alcCloseDevice(device);
- }
- devices += strlen(devices) + 1;
- index += 1;
- }
- }
- //}
-
- ResetFilters();
-}
-
-/*
- * Exit call
- */
-ALDeviceList::~ALDeviceList()
-{
- for (u32 i = 0; i < vDeviceInfo.size(); i++) {
- if (vDeviceInfo[i].pvstrExtensions) {
- vDeviceInfo[i].pvstrExtensions->empty();
- delete vDeviceInfo[i].pvstrExtensions;
- }
- }
-
- vDeviceInfo.empty();
-}
-
-/*
- * Returns the number of devices in the complete device list
- */
-s32 ALDeviceList::GetNumDevices()
-{
- return (s32)vDeviceInfo.size();
-}
-
-/*
- * Returns the device name at an index in the complete device list
- */
-char * ALDeviceList::GetDeviceName(s32 index)
-{
- if (index < GetNumDevices())
- return (char *)vDeviceInfo[index].strDeviceName.c_str();
- else
- return NULL;
-}
-
-/*
- * Returns the major and minor version numbers for a device at a specified index in the complete list
- */
-void ALDeviceList::GetDeviceVersion(s32 index, s32 *major, s32 *minor)
-{
- if (index < GetNumDevices()) {
- if (major)
- *major = vDeviceInfo[index].iMajorVersion;
- if (minor)
- *minor = vDeviceInfo[index].iMinorVersion;
- }
- return;
-}
-
-/*
- * Returns the maximum number of Sources that can be generate on the given device
- */
-u32 ALDeviceList::GetMaxNumSources(s32 index)
-{
- if (index < GetNumDevices())
- return vDeviceInfo[index].uiSourceCount;
- else
- return 0;
-}
-
-/*
- * Checks if the extension is supported on the given device
- */
-bool ALDeviceList::IsExtensionSupported(s32 index, char *szExtName)
-{
- bool bReturn = false;
-
- if (index < GetNumDevices()) {
- for (u32 i = 0; i < vDeviceInfo[index].pvstrExtensions->size(); i++) {
- if (!strcasecmp(vDeviceInfo[index].pvstrExtensions->at(i).c_str(), szExtName)) {
- bReturn = true;
- break;
- }
- }
- }
-
- return bReturn;
-}
-
-/*
- * returns the index of the default device in the complete device list
- */
-s32 ALDeviceList::GetDefaultDevice()
-{
- return defaultDeviceIndex;
-}
-
-/*
- * Deselects devices which don't have the specified minimum version
- */
-void ALDeviceList::FilterDevicesMinVer(s32 major, s32 minor)
-{
- s32 dMajor = 0, dMinor = 0;
- for (u32 i = 0; i < vDeviceInfo.size(); i++) {
- GetDeviceVersion(i, &dMajor, &dMinor);
- if ((dMajor < major) || ((dMajor == major) && (dMinor < minor))) {
- vDeviceInfo[i].bSelected = false;
- }
- }
-}
-
-/*
- * Deselects devices which don't have the specified maximum version
- */
-void ALDeviceList::FilterDevicesMaxVer(s32 major, s32 minor)
-{
- s32 dMajor = 0, dMinor = 0;
- for (u32 i = 0; i < vDeviceInfo.size(); i++) {
- GetDeviceVersion(i, &dMajor, &dMinor);
- if ((dMajor > major) || ((dMajor == major) && (dMinor > minor))) {
- vDeviceInfo[i].bSelected = false;
- }
- }
-}
-
-/*
- * Deselects device which don't support the given extension name
- */
-void ALDeviceList::FilterDevicesExtension(char *szExtName)
-{
- bool bFound;
-
- for (u32 i = 0; i < vDeviceInfo.size(); i++) {
- bFound = false;
- for (u32 j = 0; j < vDeviceInfo[i].pvstrExtensions->size(); j++) {
- if (!strcasecmp(vDeviceInfo[i].pvstrExtensions->at(j).c_str(), szExtName)) {
- bFound = true;
- break;
- }
- }
- if (!bFound)
- vDeviceInfo[i].bSelected = false;
- }
-}
-
-/*
- * Resets all filtering, such that all devices are in the list
- */
-void ALDeviceList::ResetFilters()
-{
- for (s32 i = 0; i < GetNumDevices(); i++) {
- vDeviceInfo[i].bSelected = true;
- }
- filterIndex = 0;
-}
-
-/*
- * Gets index of first filtered device
- */
-s32 ALDeviceList::GetFirstFilteredDevice()
-{
- s32 i;
-
- for (i = 0; i < GetNumDevices(); i++) {
- if (vDeviceInfo[i].bSelected == true) {
- break;
- }
- }
- filterIndex = i + 1;
- return i;
-}
-
-/*
- * Gets index of next filtered device
- */
-s32 ALDeviceList::GetNextFilteredDevice()
-{
- s32 i;
-
- for (i = filterIndex; i < GetNumDevices(); i++) {
- if (vDeviceInfo[i].bSelected == true) {
- break;
- }
- }
- filterIndex = i + 1;
- return i;
-}
-
-/*
- * Internal function to detemine max number of Sources that can be generated
- */
-u32 ALDeviceList::GetMaxNumSources()
-{
- ALuint uiSources[256];
- u32 iSourceCount = 0;
-
- // Clear AL Error Code
- alGetError();
-
- // Generate up to 256 Sources, checking for any errors
- for (iSourceCount = 0; iSourceCount < 256; iSourceCount++)
- {
- alGenSources(1, &uiSources[iSourceCount]);
- if (alGetError() != AL_NO_ERROR)
- break;
- }
-
- // Release the Sources
- alDeleteSources(iSourceCount, uiSources);
- if (alGetError() != AL_NO_ERROR)
- {
- for (u32 i = 0; i < 256; i++)
- {
- alDeleteSources(1, &uiSources[i]);
- }
- }
-
- return iSourceCount;
-}
+/*
+ * Copyright (c) 2006, Creative Labs Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of conditions and
+ * the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
+ * and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * * Neither the name of Creative Labs Inc. nor the names of its contributors may be used to endorse or
+ * promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "Common.h"
+#include "aldlist.h"
+#include "../../../../Externals/OpenAL/include/al.h"
+#include "../../../../Externals/OpenAL/include/alc.h"
+
+
+/*
+ * Init call
+ */
+ALDeviceList::ALDeviceList()
+{
+ ALDEVICEINFO ALDeviceInfo;
+ char *devices;
+ s32 index;
+ const char *defaultDeviceName = NULL;
+ const char *actualDeviceName = NULL;
+
+ // DeviceInfo vector stores, for each enumerated device, it's device name, selection status, spec version #, and extension support
+ vDeviceInfo.empty();
+ vDeviceInfo.reserve(10);
+
+ defaultDeviceIndex = 0;
+
+ // grab function pointers for 1.0-API functions, and if successful proceed to enumerate all devices
+ //if (LoadOAL10Library(NULL, &ALFunction) == TRUE) {
+ if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT"))
+ {
+ devices = (char *)alcGetString(NULL, ALC_DEVICE_SPECIFIER);
+ defaultDeviceName = (char *)alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
+ index = 0;
+ // go through device list (each device terminated with a single NULL, list terminated with double NULL)
+ while (devices != NULL && strlen(devices) > 0)
+ {
+ if (strcmp(defaultDeviceName, devices) == 0)
+ {
+ defaultDeviceIndex = index;
+ }
+ ALCdevice *device = alcOpenDevice(devices);
+ if (device)
+ {
+ ALCcontext *context = alcCreateContext(device, NULL);
+ if (context)
+ {
+ alcMakeContextCurrent(context);
+ // if new actual device name isn't already in the list, then add it...
+ actualDeviceName = alcGetString(device, ALC_DEVICE_SPECIFIER);
+ bool bNewName = true;
+ for (s32 i = 0; i < GetNumDevices(); i++)
+ {
+ if (strcmp(GetDeviceName(i), actualDeviceName) == 0)
+ {
+ bNewName = false;
+ }
+ }
+ if ((bNewName) && (actualDeviceName != NULL) && (strlen(actualDeviceName) > 0))
+ {
+ ALDeviceInfo.bSelected = true;
+ ALDeviceInfo.strDeviceName = actualDeviceName;
+ alcGetIntegerv(device, ALC_MAJOR_VERSION, sizeof(s32), &ALDeviceInfo.iMajorVersion);
+ alcGetIntegerv(device, ALC_MINOR_VERSION, sizeof(s32), &ALDeviceInfo.iMinorVersion);
+
+ ALDeviceInfo.pvstrExtensions = new vector<string>;
+
+ // Check for ALC Extensions
+ if (alcIsExtensionPresent(device, "ALC_EXT_CAPTURE") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_CAPTURE");
+ if (alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_EFX");
+
+ // Check for AL Extensions
+ if (alIsExtensionPresent("AL_EXT_OFFSET") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_OFFSET");
+
+ if (alIsExtensionPresent("AL_EXT_LINEAR_DISTANCE") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_LINEAR_DISTANCE");
+ if (alIsExtensionPresent("AL_EXT_EXPONENT_DISTANCE") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_EXPONENT_DISTANCE");
+
+ if (alIsExtensionPresent("EAX2.0") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("EAX2.0");
+ if (alIsExtensionPresent("EAX3.0") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("EAX3.0");
+ if (alIsExtensionPresent("EAX4.0") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("EAX4.0");
+ if (alIsExtensionPresent("EAX5.0") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("EAX5.0");
+
+ if (alIsExtensionPresent("EAX-RAM") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("EAX-RAM");
+
+ // Get Source Count
+ ALDeviceInfo.uiSourceCount = GetMaxNumSources();
+
+ vDeviceInfo.push_back(ALDeviceInfo);
+ }
+ alcMakeContextCurrent(NULL);
+ alcDestroyContext(context);
+ }
+ alcCloseDevice(device);
+ }
+ devices += strlen(devices) + 1;
+ index += 1;
+ }
+ }
+ //}
+
+ ResetFilters();
+}
+
+/*
+ * Exit call
+ */
+ALDeviceList::~ALDeviceList()
+{
+ for (u32 i = 0; i < vDeviceInfo.size(); i++) {
+ if (vDeviceInfo[i].pvstrExtensions) {
+ vDeviceInfo[i].pvstrExtensions->empty();
+ delete vDeviceInfo[i].pvstrExtensions;
+ }
+ }
+
+ vDeviceInfo.empty();
+}
+
+/*
+ * Returns the number of devices in the complete device list
+ */
+s32 ALDeviceList::GetNumDevices()
+{
+ return (s32)vDeviceInfo.size();
+}
+
+/*
+ * Returns the device name at an index in the complete device list
+ */
+char * ALDeviceList::GetDeviceName(s32 index)
+{
+ if (index < GetNumDevices())
+ return (char *)vDeviceInfo[index].strDeviceName.c_str();
+ else
+ return NULL;
+}
+
+/*
+ * Returns the major and minor version numbers for a device at a specified index in the complete list
+ */
+void ALDeviceList::GetDeviceVersion(s32 index, s32 *major, s32 *minor)
+{
+ if (index < GetNumDevices()) {
+ if (major)
+ *major = vDeviceInfo[index].iMajorVersion;
+ if (minor)
+ *minor = vDeviceInfo[index].iMinorVersion;
+ }
+ return;
+}
+
+/*
+ * Returns the maximum number of Sources that can be generate on the given device
+ */
+u32 ALDeviceList::GetMaxNumSources(s32 index)
+{
+ if (index < GetNumDevices())
+ return vDeviceInfo[index].uiSourceCount;
+ else
+ return 0;
+}
+
+/*
+ * Checks if the extension is supported on the given device
+ */
+bool ALDeviceList::IsExtensionSupported(s32 index, char *szExtName)
+{
+ bool bReturn = false;
+
+ if (index < GetNumDevices()) {
+ for (u32 i = 0; i < vDeviceInfo[index].pvstrExtensions->size(); i++) {
+ if (!strcasecmp(vDeviceInfo[index].pvstrExtensions->at(i).c_str(), szExtName)) {
+ bReturn = true;
+ break;
+ }
+ }
+ }
+
+ return bReturn;
+}
+
+/*
+ * returns the index of the default device in the complete device list
+ */
+s32 ALDeviceList::GetDefaultDevice()
+{
+ return defaultDeviceIndex;
+}
+
+/*
+ * Deselects devices which don't have the specified minimum version
+ */
+void ALDeviceList::FilterDevicesMinVer(s32 major, s32 minor)
+{
+ s32 dMajor = 0, dMinor = 0;
+ for (u32 i = 0; i < vDeviceInfo.size(); i++) {
+ GetDeviceVersion(i, &dMajor, &dMinor);
+ if ((dMajor < major) || ((dMajor == major) && (dMinor < minor))) {
+ vDeviceInfo[i].bSelected = false;
+ }
+ }
+}
+
+/*
+ * Deselects devices which don't have the specified maximum version
+ */
+void ALDeviceList::FilterDevicesMaxVer(s32 major, s32 minor)
+{
+ s32 dMajor = 0, dMinor = 0;
+ for (u32 i = 0; i < vDeviceInfo.size(); i++) {
+ GetDeviceVersion(i, &dMajor, &dMinor);
+ if ((dMajor > major) || ((dMajor == major) && (dMinor > minor))) {
+ vDeviceInfo[i].bSelected = false;
+ }
+ }
+}
+
+/*
+ * Deselects device which don't support the given extension name
+ */
+void ALDeviceList::FilterDevicesExtension(char *szExtName)
+{
+ bool bFound;
+
+ for (u32 i = 0; i < vDeviceInfo.size(); i++) {
+ bFound = false;
+ for (u32 j = 0; j < vDeviceInfo[i].pvstrExtensions->size(); j++) {
+ if (!strcasecmp(vDeviceInfo[i].pvstrExtensions->at(j).c_str(), szExtName)) {
+ bFound = true;
+ break;
+ }
+ }
+ if (!bFound)
+ vDeviceInfo[i].bSelected = false;
+ }
+}
+
+/*
+ * Resets all filtering, such that all devices are in the list
+ */
+void ALDeviceList::ResetFilters()
+{
+ for (s32 i = 0; i < GetNumDevices(); i++) {
+ vDeviceInfo[i].bSelected = true;
+ }
+ filterIndex = 0;
+}
+
+/*
+ * Gets index of first filtered device
+ */
+s32 ALDeviceList::GetFirstFilteredDevice()
+{
+ s32 i;
+
+ for (i = 0; i < GetNumDevices(); i++) {
+ if (vDeviceInfo[i].bSelected == true) {
+ break;
+ }
+ }
+ filterIndex = i + 1;
+ return i;
+}
+
+/*
+ * Gets index of next filtered device
+ */
+s32 ALDeviceList::GetNextFilteredDevice()
+{
+ s32 i;
+
+ for (i = filterIndex; i < GetNumDevices(); i++) {
+ if (vDeviceInfo[i].bSelected == true) {
+ break;
+ }
+ }
+ filterIndex = i + 1;
+ return i;
+}
+
+/*
+ * Internal function to detemine max number of Sources that can be generated
+ */
+u32 ALDeviceList::GetMaxNumSources()
+{
+ ALuint uiSources[256];
+ u32 iSourceCount = 0;
+
+ // Clear AL Error Code
+ alGetError();
+
+ // Generate up to 256 Sources, checking for any errors
+ for (iSourceCount = 0; iSourceCount < 256; iSourceCount++)
+ {
+ alGenSources(1, &uiSources[iSourceCount]);
+ if (alGetError() != AL_NO_ERROR)
+ break;
+ }
+
+ // Release the Sources
+ alDeleteSources(iSourceCount, uiSources);
+ if (alGetError() != AL_NO_ERROR)
+ {
+ for (u32 i = 0; i < 256; i++)
+ {
+ alDeleteSources(1, &uiSources[i]);
+ }
+ }
+
+ return iSourceCount;
+}
diff --git a/Source/Core/AudioCommon/Src/aldlist.h b/Source/Core/AudioCommon/Src/aldlist.h
index cea2fe41f6..645b759660 100644
--- a/Source/Core/AudioCommon/Src/aldlist.h
+++ b/Source/Core/AudioCommon/Src/aldlist.h
@@ -1,51 +1,51 @@
-#ifndef ALDEVICELIST_H
-#define ALDEVICELIST_H
-
-#include "CommonTypes.h"
-#ifdef _WIN32
-#pragma warning(disable: 4786) //disable warning "identifier was truncated to
- //'255' characters in the browser information"
-#endif
-#include <vector>
-#include <string>
-
-using namespace std;
-
-typedef struct
-{
- string strDeviceName;
- s32 iMajorVersion;
- s32 iMinorVersion;
- u32 uiSourceCount;
- vector<string> *pvstrExtensions;
- bool bSelected;
-} ALDEVICEINFO, *LPALDEVICEINFO;
-
-class ALDeviceList
-{
-private:
- vector<ALDEVICEINFO> vDeviceInfo;
- s32 defaultDeviceIndex;
- s32 filterIndex;
-
-public:
- ALDeviceList ();
- ~ALDeviceList ();
- s32 GetNumDevices();
- char *GetDeviceName(s32 index);
- void GetDeviceVersion(s32 index, s32 *major, s32 *minor);
- u32 GetMaxNumSources(s32 index);
- bool IsExtensionSupported(s32 index, char *szExtName);
- s32 GetDefaultDevice();
- void FilterDevicesMinVer(s32 major, s32 minor);
- void FilterDevicesMaxVer(s32 major, s32 minor);
- void FilterDevicesExtension(char *szExtName);
- void ResetFilters();
- s32 GetFirstFilteredDevice();
- s32 GetNextFilteredDevice();
-
-private:
- u32 GetMaxNumSources();
-};
-
-#endif // ALDEVICELIST_H
+#ifndef ALDEVICELIST_H
+#define ALDEVICELIST_H
+
+#include "CommonTypes.h"
+#ifdef _WIN32
+#pragma warning(disable: 4786) //disable warning "identifier was truncated to
+ //'255' characters in the browser information"
+#endif
+#include <vector>
+#include <string>
+
+using namespace std;
+
+typedef struct
+{
+ string strDeviceName;
+ s32 iMajorVersion;
+ s32 iMinorVersion;
+ u32 uiSourceCount;
+ vector<string> *pvstrExtensions;
+ bool bSelected;
+} ALDEVICEINFO, *LPALDEVICEINFO;
+
+class ALDeviceList
+{
+private:
+ vector<ALDEVICEINFO> vDeviceInfo;
+ s32 defaultDeviceIndex;
+ s32 filterIndex;
+
+public:
+ ALDeviceList ();
+ ~ALDeviceList ();
+ s32 GetNumDevices();
+ char *GetDeviceName(s32 index);
+ void GetDeviceVersion(s32 index, s32 *major, s32 *minor);
+ u32 GetMaxNumSources(s32 index);
+ bool IsExtensionSupported(s32 index, char *szExtName);
+ s32 GetDefaultDevice();
+ void FilterDevicesMinVer(s32 major, s32 minor);
+ void FilterDevicesMaxVer(s32 major, s32 minor);
+ void FilterDevicesExtension(char *szExtName);
+ void ResetFilters();
+ s32 GetFirstFilteredDevice();
+ s32 GetNextFilteredDevice();
+
+private:
+ u32 GetMaxNumSources();
+};
+
+#endif // ALDEVICELIST_H
diff --git a/Source/Core/Common/Src/SymbolDB.cpp b/Source/Core/Common/Src/SymbolDB.cpp
index 86161b6b9c..7752b484e2 100644
--- a/Source/Core/Common/Src/SymbolDB.cpp
+++ b/Source/Core/Common/Src/SymbolDB.cpp
@@ -1,59 +1,59 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "SymbolDB.h"
-
-
-void SymbolDB::List()
-{
- for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++)
- {
- DEBUG_LOG(HLE,"%s @ %08x: %i bytes (hash %08x) : %i calls", iter->second.name.c_str(), iter->second.address, iter->second.size, iter->second.hash,iter->second.numCalls);
- }
- INFO_LOG(HLE,"%i functions known in this program above.", functions.size());
-}
-
-void SymbolDB::Clear(const char *prefix)
-{
- // TODO: honor prefix
- functions.clear();
- checksumToFunction.clear();
-}
-
-void SymbolDB::Index()
-{
- int i = 0;
- for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++)
- {
- iter->second.index = i++;
- }
-}
-
-Symbol *SymbolDB::GetSymbolFromName(const char *name)
-{
- for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++)
- {
- if (!strcmp(iter->second.name.c_str(), name))
- return &iter->second;
- }
- return 0;
-}
-
-void SymbolDB::AddCompleteSymbol(const Symbol &symbol)
-{
- functions.insert(std::pair<u32, Symbol>(symbol.address, symbol));
-}
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "SymbolDB.h"
+
+
+void SymbolDB::List()
+{
+ for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++)
+ {
+ DEBUG_LOG(HLE,"%s @ %08x: %i bytes (hash %08x) : %i calls", iter->second.name.c_str(), iter->second.address, iter->second.size, iter->second.hash,iter->second.numCalls);
+ }
+ INFO_LOG(HLE,"%i functions known in this program above.", functions.size());
+}
+
+void SymbolDB::Clear(const char *prefix)
+{
+ // TODO: honor prefix
+ functions.clear();
+ checksumToFunction.clear();
+}
+
+void SymbolDB::Index()
+{
+ int i = 0;
+ for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++)
+ {
+ iter->second.index = i++;
+ }
+}
+
+Symbol *SymbolDB::GetSymbolFromName(const char *name)
+{
+ for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++)
+ {
+ if (!strcmp(iter->second.name.c_str(), name))
+ return &iter->second;
+ }
+ return 0;
+}
+
+void SymbolDB::AddCompleteSymbol(const Symbol &symbol)
+{
+ functions.insert(std::pair<u32, Symbol>(symbol.address, symbol));
+}
diff --git a/Source/Core/Common/Src/SymbolDB.h b/Source/Core/Common/Src/SymbolDB.h
index dc6ba56f23..41d22a0b44 100644
--- a/Source/Core/Common/Src/SymbolDB.h
+++ b/Source/Core/Common/Src/SymbolDB.h
@@ -1,122 +1,122 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-
-// This file contains a generic symbol map implementation. For CPU-specific
-// magic, derive and extend.
-
-#ifndef _SYMBOL_DB_H
-#define _SYMBOL_DB_H
-
-#include <string>
-#include <map>
-
-#include "Common.h"
-
-struct SCall
-{
- SCall(u32 a, u32 b) :
- function(a),
- callAddress(b)
- {}
- u32 function;
- u32 callAddress;
-};
-
-struct Symbol
-{
- enum {
- SYMBOL_FUNCTION = 0,
- SYMBOL_DATA = 1,
- };
-
- Symbol() :
- hash(0),
- address(0),
- flags(0),
- size(0),
- numCalls(0),
- type(SYMBOL_FUNCTION),
- analyzed(0)
- {}
-
- std::string name;
- std::vector<SCall> callers; //addresses of functions that call this function
- std::vector<SCall> calls; //addresses of functions that are called by this function
- u32 hash; //use for HLE function finding
- u32 address;
- u32 flags;
- int size;
- int numCalls;
- int type;
- int index; // only used for coloring the disasm view
- int analyzed;
-};
-
-enum
-{
- FFLAG_TIMERINSTRUCTIONS=(1<<0),
- FFLAG_LEAF=(1<<1),
- FFLAG_ONLYCALLSNICELEAFS=(1<<2),
- FFLAG_EVIL=(1<<3),
- FFLAG_RFI=(1<<4),
- FFLAG_STRAIGHT=(1<<5)
-};
-
-
-
-class SymbolDB
-{
-public:
- typedef std::map<u32, Symbol> XFuncMap;
- typedef std::map<u32, Symbol*> XFuncPtrMap;
-
-protected:
- XFuncMap functions;
- XFuncPtrMap checksumToFunction;
-
-public:
- SymbolDB() {}
- virtual ~SymbolDB() {}
- virtual Symbol *GetSymbolFromAddr(u32 addr) { return 0; }
- virtual Symbol *AddFunction(u32 startAddr) { return 0;}
-
- void AddCompleteSymbol(const Symbol &symbol);
-
- Symbol *GetSymbolFromName(const char *name);
- Symbol *GetSymbolFromHash(u32 hash) {
- XFuncPtrMap::iterator iter = checksumToFunction.find(hash);
- if (iter != checksumToFunction.end())
- return iter->second;
- else
- return 0;
- }
-
- const XFuncMap &Symbols() const {return functions;}
- XFuncMap &AccessSymbols() {return functions;}
-
- // deprecated
- XFuncMap::iterator GetIterator() { return functions.begin(); }
- XFuncMap::const_iterator GetConstIterator() { return functions.begin(); }
- XFuncMap::iterator End() { return functions.end(); }
-
- void Clear(const char *prefix = "");
- void List();
- void Index();
-};
-
-#endif
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+
+// This file contains a generic symbol map implementation. For CPU-specific
+// magic, derive and extend.
+
+#ifndef _SYMBOL_DB_H
+#define _SYMBOL_DB_H
+
+#include <string>
+#include <map>
+
+#include "Common.h"
+
+struct SCall
+{
+ SCall(u32 a, u32 b) :
+ function(a),
+ callAddress(b)
+ {}
+ u32 function;
+ u32 callAddress;
+};
+
+struct Symbol
+{
+ enum {
+ SYMBOL_FUNCTION = 0,
+ SYMBOL_DATA = 1,
+ };
+
+ Symbol() :
+ hash(0),
+ address(0),
+ flags(0),
+ size(0),
+ numCalls(0),
+ type(SYMBOL_FUNCTION),
+ analyzed(0)
+ {}
+
+ std::string name;
+ std::vector<SCall> callers; //addresses of functions that call this function
+ std::vector<SCall> calls; //addresses of functions that are called by this function
+ u32 hash; //use for HLE function finding
+ u32 address;
+ u32 flags;
+ int size;
+ int numCalls;
+ int type;
+ int index; // only used for coloring the disasm view
+ int analyzed;
+};
+
+enum
+{
+ FFLAG_TIMERINSTRUCTIONS=(1<<0),
+ FFLAG_LEAF=(1<<1),
+ FFLAG_ONLYCALLSNICELEAFS=(1<<2),
+ FFLAG_EVIL=(1<<3),
+ FFLAG_RFI=(1<<4),
+ FFLAG_STRAIGHT=(1<<5)
+};
+
+
+
+class SymbolDB
+{
+public:
+ typedef std::map<u32, Symbol> XFuncMap;
+ typedef std::map<u32, Symbol*> XFuncPtrMap;
+
+protected:
+ XFuncMap functions;
+ XFuncPtrMap checksumToFunction;
+
+public:
+ SymbolDB() {}
+ virtual ~SymbolDB() {}
+ virtual Symbol *GetSymbolFromAddr(u32 addr) { return 0; }
+ virtual Symbol *AddFunction(u32 startAddr) { return 0;}
+
+ void AddCompleteSymbol(const Symbol &symbol);
+
+ Symbol *GetSymbolFromName(const char *name);
+ Symbol *GetSymbolFromHash(u32 hash) {
+ XFuncPtrMap::iterator iter = checksumToFunction.find(hash);
+ if (iter != checksumToFunction.end())
+ return iter->second;
+ else
+ return 0;
+ }
+
+ const XFuncMap &Symbols() const {return functions;}
+ XFuncMap &AccessSymbols() {return functions;}
+
+ // deprecated
+ XFuncMap::iterator GetIterator() { return functions.begin(); }
+ XFuncMap::const_iterator GetConstIterator() { return functions.begin(); }
+ XFuncMap::iterator End() { return functions.end(); }
+
+ void Clear(const char *prefix = "");
+ void List();
+ void Index();
+};
+
+#endif
diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Usb_Kbd_apple.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Usb_Kbd_apple.h
index dd69c3f751..e6aeadca75 100644
--- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Usb_Kbd_apple.h
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Usb_Kbd_apple.h
@@ -1,24 +1,24 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-u8 CWII_IPC_HLE_Device_usb_kbd::m_KeyCodesQWERTY[256] = {
-//Add support for apple keycodes
-};
-
-u8 CWII_IPC_HLE_Device_usb_kbd::m_KeyCodesAZERTY[256] = {
-//Add support for apple keycodes
-};
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+u8 CWII_IPC_HLE_Device_usb_kbd::m_KeyCodesQWERTY[256] = {
+//Add support for apple keycodes
+};
+
+u8 CWII_IPC_HLE_Device_usb_kbd::m_KeyCodesAZERTY[256] = {
+//Add support for apple keycodes
+};
diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Usb_Kbd_linux.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Usb_Kbd_linux.h
index a451184ac1..80b7a093e5 100644
--- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Usb_Kbd_linux.h
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Usb_Kbd_linux.h
@@ -1,25 +1,25 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-u8 CWII_IPC_HLE_Device_usb_kbd::m_KeyCodesQWERTY[256] = {
-//Add support for Linux keycodes
-};
-
-u8 CWII_IPC_HLE_Device_usb_kbd::m_KeyCodesAZERTY[256] = {
-//Add support for Linux keycodes
-};
-
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+u8 CWII_IPC_HLE_Device_usb_kbd::m_KeyCodesQWERTY[256] = {
+//Add support for Linux keycodes
+};
+
+u8 CWII_IPC_HLE_Device_usb_kbd::m_KeyCodesAZERTY[256] = {
+//Add support for Linux keycodes
+};
+
diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Usb_Kbd_win32.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Usb_Kbd_win32.h
index 9cb31e31b4..1b7e06724c 100644
--- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Usb_Kbd_win32.h
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Usb_Kbd_win32.h
@@ -1,192 +1,192 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-u8 CWII_IPC_HLE_Device_usb_kbd::m_KeyCodesQWERTY[256] = {
-
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x2A, // Backspace
- 0x2B, // Tab
- 0x00, 0x00,
- 0x00, // Clear
- 0x28, // Return
- 0x00, 0x00,
- 0x00, // Shift
- 0x00, // Control
- 0x00, // ALT
- 0x48, // Pause
- 0x39, // Capital
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x29, // Escape
- 0x00, 0x00, 0x00, 0x00,
- 0x2C, // Space
- 0x4B, // Prior
- 0x4E, // Next
- 0x4D, // End
- 0x4A, // Home
- 0x50, // Left
- 0x52, // Up
- 0x4F, // Right
- 0x51, // Down
- 0x00, 0x00, 0x00,
- 0x46, // Print screen
- 0x49, // Insert
- 0x4C, // Delete
- 0x00,
- // 0 -> 9
- 0x27, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
- 0x25, 0x26,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00,
- // A -> Z
- 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
- 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13,
- 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
- 0x1C, 0x1D,
- 0x00, 0x00, 0x00, 0x00,
- 0x00,
- // Numpad 0 -> 9
- 0x62, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
- 0x60, 0x61,
- 0x55, // Multiply
- 0x57, // Add
- 0x00, // Separator
- 0x56, // Substract
- 0x63, // Decimal
- 0x54, // Divide
- // F1 -> F12
- 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41,
- 0x42, 0x43, 0x44, 0x45,
- // F13 -> F24
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x53, // Numlock
- 0x47, // Scroll lock
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- // Modifier keys
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x33, // ';'
- 0x2E, // Plus
- 0x36, // Comma
- 0x2D, // Minus
- 0x37, // Period
- 0x38, // '/'
- 0x35, // '~'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
- 0x2F, // '['
- 0x32, // '\'
- 0x30, // ']'
- 0x34, // '''
- 0x00, //
- 0x00, // Nothing interesting past this point.
-
-};
-
-u8 CWII_IPC_HLE_Device_usb_kbd::m_KeyCodesAZERTY[256] = {
-
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x2A, // Backspace
- 0x2B, // Tab
- 0x00, 0x00,
- 0x00, // Clear
- 0x28, // Return
- 0x00, 0x00,
- 0x00, // Shift
- 0x00, // Control
- 0x00, // ALT
- 0x48, // Pause
- 0x39, // Capital
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x29, // Escape
- 0x00, 0x00, 0x00, 0x00,
- 0x2C, // Space
- 0x4B, // Prior
- 0x4E, // Next
- 0x4D, // End
- 0x4A, // Home
- 0x50, // Left
- 0x52, // Up
- 0x4F, // Right
- 0x51, // Down
- 0x00, 0x00, 0x00,
- 0x46, // Print screen
- 0x49, // Insert
- 0x4C, // Delete
- 0x00,
- // 0 -> 9
- 0x27, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
- 0x25, 0x26,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00,
- // A -> Z
- 0x14, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
- 0x0C, 0x0D, 0x0E, 0x0F, 0x33, 0x11, 0x12, 0x13,
- 0x04, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1D, 0x1B,
- 0x1C, 0x1A,
- 0x00, 0x00, 0x00, 0x00,
- 0x00,
- // Numpad 0 -> 9
- 0x62, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
- 0x60, 0x61,
- 0x55, // Multiply
- 0x57, // Add
- 0x00, // Separator
- 0x56, // Substract
- 0x63, // Decimal
- 0x54, // Divide
- // F1 -> F12
- 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41,
- 0x42, 0x43, 0x44, 0x45,
- // F13 -> F24
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x53, // Numlock
- 0x47, // Scroll lock
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- // Modifier keys
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x30, // '$'
- 0x2E, // Plus
- 0x10, // Comma
- 0x00, // Minus
- 0x36, // Period
- 0x37, // '/'
- 0x34, // 'ù'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
- 0x2D, // ')'
- 0x32, // '\'
- 0x2F, // '^'
- 0x00, // '²'
- 0x38, // '!'
- 0x00, // Nothing interesting past this point.
-
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+u8 CWII_IPC_HLE_Device_usb_kbd::m_KeyCodesQWERTY[256] = {
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x2A, // Backspace
+ 0x2B, // Tab
+ 0x00, 0x00,
+ 0x00, // Clear
+ 0x28, // Return
+ 0x00, 0x00,
+ 0x00, // Shift
+ 0x00, // Control
+ 0x00, // ALT
+ 0x48, // Pause
+ 0x39, // Capital
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x29, // Escape
+ 0x00, 0x00, 0x00, 0x00,
+ 0x2C, // Space
+ 0x4B, // Prior
+ 0x4E, // Next
+ 0x4D, // End
+ 0x4A, // Home
+ 0x50, // Left
+ 0x52, // Up
+ 0x4F, // Right
+ 0x51, // Down
+ 0x00, 0x00, 0x00,
+ 0x46, // Print screen
+ 0x49, // Insert
+ 0x4C, // Delete
+ 0x00,
+ // 0 -> 9
+ 0x27, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
+ 0x25, 0x26,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ // A -> Z
+ 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
+ 0x1C, 0x1D,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ // Numpad 0 -> 9
+ 0x62, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+ 0x60, 0x61,
+ 0x55, // Multiply
+ 0x57, // Add
+ 0x00, // Separator
+ 0x56, // Substract
+ 0x63, // Decimal
+ 0x54, // Divide
+ // F1 -> F12
+ 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41,
+ 0x42, 0x43, 0x44, 0x45,
+ // F13 -> F24
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x53, // Numlock
+ 0x47, // Scroll lock
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Modifier keys
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x33, // ';'
+ 0x2E, // Plus
+ 0x36, // Comma
+ 0x2D, // Minus
+ 0x37, // Period
+ 0x38, // '/'
+ 0x35, // '~'
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+ 0x2F, // '['
+ 0x32, // '\'
+ 0x30, // ']'
+ 0x34, // '''
+ 0x00, //
+ 0x00, // Nothing interesting past this point.
+
+};
+
+u8 CWII_IPC_HLE_Device_usb_kbd::m_KeyCodesAZERTY[256] = {
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x2A, // Backspace
+ 0x2B, // Tab
+ 0x00, 0x00,
+ 0x00, // Clear
+ 0x28, // Return
+ 0x00, 0x00,
+ 0x00, // Shift
+ 0x00, // Control
+ 0x00, // ALT
+ 0x48, // Pause
+ 0x39, // Capital
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x29, // Escape
+ 0x00, 0x00, 0x00, 0x00,
+ 0x2C, // Space
+ 0x4B, // Prior
+ 0x4E, // Next
+ 0x4D, // End
+ 0x4A, // Home
+ 0x50, // Left
+ 0x52, // Up
+ 0x4F, // Right
+ 0x51, // Down
+ 0x00, 0x00, 0x00,
+ 0x46, // Print screen
+ 0x49, // Insert
+ 0x4C, // Delete
+ 0x00,
+ // 0 -> 9
+ 0x27, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
+ 0x25, 0x26,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ // A -> Z
+ 0x14, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x33, 0x11, 0x12, 0x13,
+ 0x04, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1D, 0x1B,
+ 0x1C, 0x1A,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ // Numpad 0 -> 9
+ 0x62, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+ 0x60, 0x61,
+ 0x55, // Multiply
+ 0x57, // Add
+ 0x00, // Separator
+ 0x56, // Substract
+ 0x63, // Decimal
+ 0x54, // Divide
+ // F1 -> F12
+ 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41,
+ 0x42, 0x43, 0x44, 0x45,
+ // F13 -> F24
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x53, // Numlock
+ 0x47, // Scroll lock
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Modifier keys
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x30, // '$'
+ 0x2E, // Plus
+ 0x10, // Comma
+ 0x00, // Minus
+ 0x36, // Period
+ 0x37, // '/'
+ 0x34, // 'ù'
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+ 0x2D, // ')'
+ 0x32, // '\'
+ 0x2F, // '^'
+ 0x00, // '²'
+ 0x38, // '!'
+ 0x00, // Nothing interesting past this point.
+
}; \ No newline at end of file
diff --git a/Source/Core/DSPCore/Src/DSPAnalyzer.cpp b/Source/Core/DSPCore/Src/DSPAnalyzer.cpp
index db08157299..e851d44ba0 100644
--- a/Source/Core/DSPCore/Src/DSPAnalyzer.cpp
+++ b/Source/Core/DSPCore/Src/DSPAnalyzer.cpp
@@ -1,133 +1,133 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "DSPAnalyzer.h"
-#include "DSPInterpreter.h"
-#include "DSPTables.h"
-#include "DSPMemoryMap.h"
-
-namespace DSPAnalyzer {
-
-// Holds data about all instructions in RAM.
-u8 code_flags[ISPACE];
-
-// Good candidates for idle skipping is mail wait loops. If we're time slicing
-// between the main CPU and the DSP, if the DSP runs into one of these, it might
-// as well give up its time slice immediately, after executing once.
-
-// Max signature length is 6. A 0 in a signature is ignored.
-#define NUM_IDLE_SIGS 5
-#define MAX_IDLE_SIG_SIZE 6
-
-// 0xFFFF means ignore.
-const u16 idle_skip_sigs[NUM_IDLE_SIGS][MAX_IDLE_SIG_SIZE + 1] =
-{
- // From AX:
- { 0x26fc, // LRS $30, @DMBH
- 0x02c0, 0x8000, // ANDCF $30, #0x8000
- 0x029d, 0xFFFF, // JLZ 0x027a
- 0, 0 }, // RET
- { 0x27fc, // LRS $31, @DMBH
- 0x03c0, 0x8000, // ANDCF $31, #0x8000
- 0x029d, 0xFFFF, // JLZ 0x027a
- 0, 0 }, // RET
- { 0x26fe, // LRS $30, @CMBH
- 0x02c0, 0x8000, // ANDCF $30, #0x8000
- 0x029c, 0xFFFF, // JLNZ 0x0280
- 0, 0 }, // RET
- { 0x27fe, // LRS $31, @CMBH
- 0x03c0, 0x8000, // ANDCF $31, #0x8000
- 0x029c, 0xFFFF, // JLNZ 0x0280
- 0, 0 }, // RET
-
- // From Zelda:
- { 0x00de, 0xFFFE, // LR $AC0.M, @CMBH
- 0x02c0, 0x8000, // ANDCF $AC0.M, #0x8000
- 0x029c, 0xFFFF, // JLNZ 0x05cf
- 0 }
-};
-
-void Reset()
-{
- memset(code_flags, 0, sizeof(code_flags));
-}
-
-void AnalyzeRange(int start_addr, int end_addr)
-{
- // First we run an extremely simplified version of a disassembler to find
- // where all instructions start.
-
- // This may not be 100% accurate in case of jump tables!
- // It could get desynced, which would be bad. We'll see if that's an issue.
- int addr = start_addr;
- while (addr < end_addr)
- {
- UDSPInstruction inst = dsp_imem_read(addr);
- const DSPOPCTemplate *opcode = GetOpTemplate(inst);
- if (!opcode)
- {
- addr++;
- continue;
- }
- code_flags[addr] |= CODE_START_OF_INST;
- addr += opcode->size;
-
- // Look for loops.
- if ((inst.hex & 0xffe0) == 0x0060 || (inst.hex & 0xff00) == 0x1100) {
- // BLOOP, BLOOPI
- u16 loop_end = dsp_imem_read(addr + 1);
- code_flags[loop_end] |= CODE_LOOP_END;
- } else if ((inst.hex & 0xffe0) == 0x0040 || (inst.hex & 0xff00) == 0x1000) {
- // LOOP, LOOPI
- code_flags[addr + 1] |= CODE_LOOP_END;
- }
- }
-
- // Next, we'll scan for potential idle skips.
- for (int s = 0; s < NUM_IDLE_SIGS; s++)
- {
- for (int addr = start_addr; addr < end_addr; addr++)
- {
- bool found = false;
- for (int i = 0; i < MAX_IDLE_SIG_SIZE + 1; i++)
- {
- if (idle_skip_sigs[s][i] == 0)
- found = true;
- if (idle_skip_sigs[s][i] == 0xFFFF)
- continue;
- if (idle_skip_sigs[s][i] != dsp_imem_read(addr + i))
- break;
- }
- if (found)
- {
- NOTICE_LOG(DSPLLE, "Idle skip location found at %02x", addr);
- code_flags[addr] |= CODE_IDLE_SKIP;
- // TODO: actually use this flag somewhere.
- }
- }
- }
- NOTICE_LOG(DSPLLE, "Finished analysis.");
-}
-
-void Analyze()
-{
- Reset();
- AnalyzeRange(0x0000, 0x1000); // IRAM
- AnalyzeRange(0x8000, 0x9000); // IROM
-}
-
-} // namespace
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "DSPAnalyzer.h"
+#include "DSPInterpreter.h"
+#include "DSPTables.h"
+#include "DSPMemoryMap.h"
+
+namespace DSPAnalyzer {
+
+// Holds data about all instructions in RAM.
+u8 code_flags[ISPACE];
+
+// Good candidates for idle skipping is mail wait loops. If we're time slicing
+// between the main CPU and the DSP, if the DSP runs into one of these, it might
+// as well give up its time slice immediately, after executing once.
+
+// Max signature length is 6. A 0 in a signature is ignored.
+#define NUM_IDLE_SIGS 5
+#define MAX_IDLE_SIG_SIZE 6
+
+// 0xFFFF means ignore.
+const u16 idle_skip_sigs[NUM_IDLE_SIGS][MAX_IDLE_SIG_SIZE + 1] =
+{
+ // From AX:
+ { 0x26fc, // LRS $30, @DMBH
+ 0x02c0, 0x8000, // ANDCF $30, #0x8000
+ 0x029d, 0xFFFF, // JLZ 0x027a
+ 0, 0 }, // RET
+ { 0x27fc, // LRS $31, @DMBH
+ 0x03c0, 0x8000, // ANDCF $31, #0x8000
+ 0x029d, 0xFFFF, // JLZ 0x027a
+ 0, 0 }, // RET
+ { 0x26fe, // LRS $30, @CMBH
+ 0x02c0, 0x8000, // ANDCF $30, #0x8000
+ 0x029c, 0xFFFF, // JLNZ 0x0280
+ 0, 0 }, // RET
+ { 0x27fe, // LRS $31, @CMBH
+ 0x03c0, 0x8000, // ANDCF $31, #0x8000
+ 0x029c, 0xFFFF, // JLNZ 0x0280
+ 0, 0 }, // RET
+
+ // From Zelda:
+ { 0x00de, 0xFFFE, // LR $AC0.M, @CMBH
+ 0x02c0, 0x8000, // ANDCF $AC0.M, #0x8000
+ 0x029c, 0xFFFF, // JLNZ 0x05cf
+ 0 }
+};
+
+void Reset()
+{
+ memset(code_flags, 0, sizeof(code_flags));
+}
+
+void AnalyzeRange(int start_addr, int end_addr)
+{
+ // First we run an extremely simplified version of a disassembler to find
+ // where all instructions start.
+
+ // This may not be 100% accurate in case of jump tables!
+ // It could get desynced, which would be bad. We'll see if that's an issue.
+ int addr = start_addr;
+ while (addr < end_addr)
+ {
+ UDSPInstruction inst = dsp_imem_read(addr);
+ const DSPOPCTemplate *opcode = GetOpTemplate(inst);
+ if (!opcode)
+ {
+ addr++;
+ continue;
+ }
+ code_flags[addr] |= CODE_START_OF_INST;
+ addr += opcode->size;
+
+ // Look for loops.
+ if ((inst.hex & 0xffe0) == 0x0060 || (inst.hex & 0xff00) == 0x1100) {
+ // BLOOP, BLOOPI
+ u16 loop_end = dsp_imem_read(addr + 1);
+ code_flags[loop_end] |= CODE_LOOP_END;
+ } else if ((inst.hex & 0xffe0) == 0x0040 || (inst.hex & 0xff00) == 0x1000) {
+ // LOOP, LOOPI
+ code_flags[addr + 1] |= CODE_LOOP_END;
+ }
+ }
+
+ // Next, we'll scan for potential idle skips.
+ for (int s = 0; s < NUM_IDLE_SIGS; s++)
+ {
+ for (int addr = start_addr; addr < end_addr; addr++)
+ {
+ bool found = false;
+ for (int i = 0; i < MAX_IDLE_SIG_SIZE + 1; i++)
+ {
+ if (idle_skip_sigs[s][i] == 0)
+ found = true;
+ if (idle_skip_sigs[s][i] == 0xFFFF)
+ continue;
+ if (idle_skip_sigs[s][i] != dsp_imem_read(addr + i))
+ break;
+ }
+ if (found)
+ {
+ NOTICE_LOG(DSPLLE, "Idle skip location found at %02x", addr);
+ code_flags[addr] |= CODE_IDLE_SKIP;
+ // TODO: actually use this flag somewhere.
+ }
+ }
+ }
+ NOTICE_LOG(DSPLLE, "Finished analysis.");
+}
+
+void Analyze()
+{
+ Reset();
+ AnalyzeRange(0x0000, 0x1000); // IRAM
+ AnalyzeRange(0x8000, 0x9000); // IROM
+}
+
+} // namespace
diff --git a/Source/Core/DSPCore/Src/DSPAnalyzer.h b/Source/Core/DSPCore/Src/DSPAnalyzer.h
index 1b29ede4af..65b83a205b 100644
--- a/Source/Core/DSPCore/Src/DSPAnalyzer.h
+++ b/Source/Core/DSPCore/Src/DSPAnalyzer.h
@@ -1,49 +1,49 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-// Basic code analysis.
-
-#include "DSPInterpreter.h"
-
-namespace DSPAnalyzer {
-
-#define ISPACE 65536
-
-// Useful things to detect:
-// * Loop endpoints - so that we can avoid checking for loops every cycle.
-
-enum
-{
- CODE_START_OF_INST = 1,
- CODE_IDLE_SKIP = 2,
- CODE_LOOP_END = 4,
-};
-
-// Easy to query array covering the whole of instruction memory.
-// Just index by address.
-// This one will be helpful for debuggers and jits.
-extern u8 code_flags[ISPACE];
-
-// This one should be called every time IRAM changes - which is basically
-// every time that a new ucode gets uploaded, and never else. At that point,
-// we can do as much static analysis as we want - but we should always throw
-// all old analysis away. Luckily the entire address space is only 64K code
-// words and the actual code space 8K instructions in total, so we can do
-// some pretty expensive analysis if necessary.
-void Analyze();
-
-} // namespace
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Basic code analysis.
+
+#include "DSPInterpreter.h"
+
+namespace DSPAnalyzer {
+
+#define ISPACE 65536
+
+// Useful things to detect:
+// * Loop endpoints - so that we can avoid checking for loops every cycle.
+
+enum
+{
+ CODE_START_OF_INST = 1,
+ CODE_IDLE_SKIP = 2,
+ CODE_LOOP_END = 4,
+};
+
+// Easy to query array covering the whole of instruction memory.
+// Just index by address.
+// This one will be helpful for debuggers and jits.
+extern u8 code_flags[ISPACE];
+
+// This one should be called every time IRAM changes - which is basically
+// every time that a new ucode gets uploaded, and never else. At that point,
+// we can do as much static analysis as we want - but we should always throw
+// all old analysis away. Luckily the entire address space is only 64K code
+// words and the actual code space 8K instructions in total, so we can do
+// some pretty expensive analysis if necessary.
+void Analyze();
+
+} // namespace
diff --git a/Source/Core/DSPCore/Src/DSPBreakpoints.cpp b/Source/Core/DSPCore/Src/DSPBreakpoints.cpp
index ec48a249fc..0d1537ed1d 100644
--- a/Source/Core/DSPCore/Src/DSPBreakpoints.cpp
+++ b/Source/Core/DSPCore/Src/DSPBreakpoints.cpp
@@ -1,19 +1,19 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "DSPBreakpoints.h"
-
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "DSPBreakpoints.h"
+
diff --git a/Source/Core/DSPCore/Src/DSPBreakpoints.h b/Source/Core/DSPCore/Src/DSPBreakpoints.h
index 98ff5f609d..752c1f9080 100644
--- a/Source/Core/DSPCore/Src/DSPBreakpoints.h
+++ b/Source/Core/DSPCore/Src/DSPBreakpoints.h
@@ -1,63 +1,63 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _DSP_BREAKPOINTS
-#define _DSP_BREAKPOINTS
-
-#include "Common.h"
-
-// super fast breakpoints for a limited range.
-// To be used interchangably with the BreakPoints class.
-class DSPBreakpoints
-{
-public:
- DSPBreakpoints() {Clear();}
- // is address breakpoint
- bool IsAddressBreakPoint(u32 addr) {
- return b[addr] != 0;
- }
-
- // AddBreakPoint
- bool Add(u32 addr, bool temp=false) {
- bool was_one = b[addr] != 0;
- if (!was_one) {
- b[addr] = temp ? 2 : 1;
- return true;
- } else {
- return false;
- }
- }
- // Remove Breakpoint
- bool Remove(u32 addr) {
- bool was_one = b[addr] != 0;
- b[addr] = 0;
- return was_one;
- }
- void Clear() {
- for (int i = 0; i < 65536; i++)
- b[i] = 0;
- }
-
- void DeleteByAddress(u32 addr) {
- b[addr] = 0;
- }
-
-private:
- u8 b[65536];
-};
-
-#endif
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _DSP_BREAKPOINTS
+#define _DSP_BREAKPOINTS
+
+#include "Common.h"
+
+// super fast breakpoints for a limited range.
+// To be used interchangably with the BreakPoints class.
+class DSPBreakpoints
+{
+public:
+ DSPBreakpoints() {Clear();}
+ // is address breakpoint
+ bool IsAddressBreakPoint(u32 addr) {
+ return b[addr] != 0;
+ }
+
+ // AddBreakPoint
+ bool Add(u32 addr, bool temp=false) {
+ bool was_one = b[addr] != 0;
+ if (!was_one) {
+ b[addr] = temp ? 2 : 1;
+ return true;
+ } else {
+ return false;
+ }
+ }
+ // Remove Breakpoint
+ bool Remove(u32 addr) {
+ bool was_one = b[addr] != 0;
+ b[addr] = 0;
+ return was_one;
+ }
+ void Clear() {
+ for (int i = 0; i < 65536; i++)
+ b[i] = 0;
+ }
+
+ void DeleteByAddress(u32 addr) {
+ b[addr] = 0;
+ }
+
+private:
+ u8 b[65536];
+};
+
+#endif
diff --git a/Source/Core/DSPCore/Src/DSPCodeUtil.cpp b/Source/Core/DSPCore/Src/DSPCodeUtil.cpp
index 3f81b67e04..d0dd510949 100644
--- a/Source/Core/DSPCore/Src/DSPCodeUtil.cpp
+++ b/Source/Core/DSPCore/Src/DSPCodeUtil.cpp
@@ -1,235 +1,235 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include <iostream>
-#include <vector>
-
-#include "Common.h"
-#include "FileUtil.h"
-#include "StringUtil.h"
-#include "DSPCodeUtil.h"
-#include "assemble.h"
-#include "disassemble.h"
-
-
-bool Assemble(const char *text, std::vector<u16> &code)
-{
- AssemblerSettings settings;
- settings.pc = 0;
- // settings.decode_registers = false;
- // settings.decode_names = false;
- settings.print_tabs = false;
- settings.ext_separator = '\'';
-
- // TODO: fix the terrible api of the assembler.
- DSPAssembler assembler(settings);
- if (!assembler.Assemble(text, code)) {
- std::cerr << assembler.GetErrorString() << std::endl;
- return false;
- }
-
- return true;
-}
-
-bool Disassemble(const std::vector<u16> &code, bool line_numbers, std::string &text)
-{
- if (code.empty())
- return false;
-
- AssemblerSettings settings;
-
- // These two prevent roundtripping.
- settings.show_hex = false;
- settings.show_pc = line_numbers;
- settings.ext_separator = '\'';
- settings.decode_names = false;
- settings.decode_registers = true;
-
- DSPDisassembler disasm(settings);
- bool success = disasm.Disassemble(0, code, 0x0000, text);
- return success;
-}
-
-bool Compare(const std::vector<u16> &code1, const std::vector<u16> &code2)
-{
- if (code1.size() != code2.size())
- printf("Size difference! 1=%i 2=%i\n", (int)code1.size(), (int)code2.size());
- u32 count_equal = 0;
- const int min_size = (int)std::min(code1.size(), code2.size());
-
- AssemblerSettings settings;
- DSPDisassembler disassembler(settings);
- for (int i = 0; i < min_size; i++)
- {
- if (code1[i] == code2[i])
- count_equal++;
- else
- {
- std::string line1, line2;
- u16 pc = i;
- disassembler.DisOpcode(&code1[0], 0x0000, 2, &pc, line1);
- pc = i;
- disassembler.DisOpcode(&code2[0], 0x0000, 2, &pc, line2);
- printf("!! %04x : %04x vs %04x - %s vs %s\n", i, code1[i], code2[i], line1.c_str(), line2.c_str());
- }
- }
- if (code2.size() != code1.size())
- {
- printf("Extra code words:\n");
- const std::vector<u16> &longest = code1.size() > code2.size() ? code1 : code2;
- for (int i = min_size; i < (int)longest.size(); i++)
- {
- u16 pc = i;
- std::string line;
- disassembler.DisOpcode(&longest[0], 0x0000, 2, &pc, line);
- printf("!! %s\n", line.c_str());
- }
- }
- printf("Equal instruction words: %i / %i\n", count_equal, min_size);
- return code1.size() == code2.size() && code1.size() == count_equal;
-}
-
-void GenRandomCode(int size, std::vector<u16> &code)
-{
- code.resize(size);
- for (int i = 0; i < size; i++)
- {
- code[i] = rand() ^ (rand() << 8);
- }
-}
-
-void CodeToHeader(const std::vector<u16> &code, std::string _filename,
- const char *name, std::string &header)
-{
- std::vector<u16> code_copy = code;
- // Add some nops at the end to align the size a bit.
- while (code_copy.size() & 7)
- code_copy.push_back(0);
- char buffer[1024];
- header.clear();
- header.reserve(code.size() * 4);
- header.append("#define NUM_UCODES 1\n\n");
- std::string filename;
- SplitPath(_filename, NULL, &filename, NULL);
- header.append(StringFromFormat("const char* UCODE_NAMES[NUM_UCODES] = {\"%s\"};\n\n", filename.c_str()));
- header.append("#ifndef _MSCVER\n");
- header.append("const unsigned short dsp_code[NUM_UCODES][0x1000] = {\n");
- header.append("#else\n");
- header.append("const unsigned short dsp_code[NUM_UCODES][0x1000] __attribute__ ((aligned (64))) = {\n");
- header.append("#endif\n\n");
-
- header.append("\t{\n\t\t");
- for (u32 j = 0; j < code.size(); j++)
- {
- if (j && ((j & 15) == 0))
- header.append("\n\t\t");
- sprintf(buffer, "0x%04x, ", code[j]);
- header.append(buffer);
- }
- header.append("\n\t},\n");
-
- header.append("};\n");
-}
-
-void CodesToHeader(const std::vector<u16> *codes, const std::vector<std::string>* filenames,
- int numCodes, const char *name, std::string &header)
-{
- char buffer[1024];
- int reserveSize = 0;
- for(int i = 0; i < numCodes; i++)
- reserveSize += (int)codes[i].size();
-
-
- header.clear();
- header.reserve(reserveSize * 4);
- sprintf(buffer, "#define NUM_UCODES %d\n\n", numCodes);
- header.append(buffer);
- header.append("const char* UCODE_NAMES[NUM_UCODES] = {\n");
- for (int i = 0; i < numCodes; i++)
- {
- std::string filename;
- if (! SplitPath(filenames->at(i), NULL, &filename, NULL))
- filename = filenames->at(i);
- sprintf(buffer, "\t\"%s\",\n", filename.c_str());
- header.append(buffer);
- }
- header.append("};\n\n");
- header.append("#ifndef _MSCVER\n");
- header.append("const unsigned short dsp_ucode[NUM_UCODES][0x1000] = {\n");
- header.append("#else\n");
- header.append("const unsigned short dsp_ucode[NUM_UCODES][0x1000] __attribute__ ((aligned (64))) = {\n");
- header.append("#endif\n\n");
-
- for(int i = 0; i < numCodes; i++) {
- if(codes[i].size() == 0)
- continue;
-
- std::vector<u16> code_copy = codes[i];
- // Add some nops at the end to align the size a bit.
- while (code_copy.size() & 7)
- code_copy.push_back(0);
-
- header.append("\t{\n\t\t");
- for (u32 j = 0; j < codes[i].size(); j++)
- {
- if (j && ((j & 15) == 0))
- header.append("\n\t\t");
- sprintf(buffer, "0x%04x, ", codes[i][j]);
- header.append(buffer);
- }
- header.append("\n\t},\n");
- }
- header.append("};\n");
-}
-
-void CodeToBinaryStringBE(const std::vector<u16> &code, std::string &str)
-{
- str.resize(code.size() * 2);
- for (int i = 0; i < (int)code.size(); i++)
- {
- str[i * 2 + 0] = code[i] >> 8;
- str[i * 2 + 1] = code[i] & 0xff;
- }
-}
-
-void BinaryStringBEToCode(const std::string &str, std::vector<u16> &code)
-{
- code.resize(str.size() / 2);
- for (int i = 0; i < (int)code.size(); i++)
- {
- code[i] = ((u16)(u8)str[i * 2 + 0] << 8) | ((u16)(u8)str[i * 2 + 1]);
- }
-}
-
-bool LoadBinary(const char *filename, std::vector<u16> &code)
-{
- std::string buffer;
- if (!File::ReadFileToString(false, filename, buffer))
- return false;
-
- BinaryStringBEToCode(buffer, code);
- return true;
-}
-
-bool SaveBinary(const std::vector<u16> &code, const char *filename)
-{
- std::string buffer;
- CodeToBinaryStringBE(code, buffer);
- if (!File::WriteStringToFile(false, buffer, filename))
- return false;
- return true;
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include <iostream>
+#include <vector>
+
+#include "Common.h"
+#include "FileUtil.h"
+#include "StringUtil.h"
+#include "DSPCodeUtil.h"
+#include "assemble.h"
+#include "disassemble.h"
+
+
+bool Assemble(const char *text, std::vector<u16> &code)
+{
+ AssemblerSettings settings;
+ settings.pc = 0;
+ // settings.decode_registers = false;
+ // settings.decode_names = false;
+ settings.print_tabs = false;
+ settings.ext_separator = '\'';
+
+ // TODO: fix the terrible api of the assembler.
+ DSPAssembler assembler(settings);
+ if (!assembler.Assemble(text, code)) {
+ std::cerr << assembler.GetErrorString() << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+bool Disassemble(const std::vector<u16> &code, bool line_numbers, std::string &text)
+{
+ if (code.empty())
+ return false;
+
+ AssemblerSettings settings;
+
+ // These two prevent roundtripping.
+ settings.show_hex = false;
+ settings.show_pc = line_numbers;
+ settings.ext_separator = '\'';
+ settings.decode_names = false;
+ settings.decode_registers = true;
+
+ DSPDisassembler disasm(settings);
+ bool success = disasm.Disassemble(0, code, 0x0000, text);
+ return success;
+}
+
+bool Compare(const std::vector<u16> &code1, const std::vector<u16> &code2)
+{
+ if (code1.size() != code2.size())
+ printf("Size difference! 1=%i 2=%i\n", (int)code1.size(), (int)code2.size());
+ u32 count_equal = 0;
+ const int min_size = (int)std::min(code1.size(), code2.size());
+
+ AssemblerSettings settings;
+ DSPDisassembler disassembler(settings);
+ for (int i = 0; i < min_size; i++)
+ {
+ if (code1[i] == code2[i])
+ count_equal++;
+ else
+ {
+ std::string line1, line2;
+ u16 pc = i;
+ disassembler.DisOpcode(&code1[0], 0x0000, 2, &pc, line1);
+ pc = i;
+ disassembler.DisOpcode(&code2[0], 0x0000, 2, &pc, line2);
+ printf("!! %04x : %04x vs %04x - %s vs %s\n", i, code1[i], code2[i], line1.c_str(), line2.c_str());
+ }
+ }
+ if (code2.size() != code1.size())
+ {
+ printf("Extra code words:\n");
+ const std::vector<u16> &longest = code1.size() > code2.size() ? code1 : code2;
+ for (int i = min_size; i < (int)longest.size(); i++)
+ {
+ u16 pc = i;
+ std::string line;
+ disassembler.DisOpcode(&longest[0], 0x0000, 2, &pc, line);
+ printf("!! %s\n", line.c_str());
+ }
+ }
+ printf("Equal instruction words: %i / %i\n", count_equal, min_size);
+ return code1.size() == code2.size() && code1.size() == count_equal;
+}
+
+void GenRandomCode(int size, std::vector<u16> &code)
+{
+ code.resize(size);
+ for (int i = 0; i < size; i++)
+ {
+ code[i] = rand() ^ (rand() << 8);
+ }
+}
+
+void CodeToHeader(const std::vector<u16> &code, std::string _filename,
+ const char *name, std::string &header)
+{
+ std::vector<u16> code_copy = code;
+ // Add some nops at the end to align the size a bit.
+ while (code_copy.size() & 7)
+ code_copy.push_back(0);
+ char buffer[1024];
+ header.clear();
+ header.reserve(code.size() * 4);
+ header.append("#define NUM_UCODES 1\n\n");
+ std::string filename;
+ SplitPath(_filename, NULL, &filename, NULL);
+ header.append(StringFromFormat("const char* UCODE_NAMES[NUM_UCODES] = {\"%s\"};\n\n", filename.c_str()));
+ header.append("#ifndef _MSCVER\n");
+ header.append("const unsigned short dsp_code[NUM_UCODES][0x1000] = {\n");
+ header.append("#else\n");
+ header.append("const unsigned short dsp_code[NUM_UCODES][0x1000] __attribute__ ((aligned (64))) = {\n");
+ header.append("#endif\n\n");
+
+ header.append("\t{\n\t\t");
+ for (u32 j = 0; j < code.size(); j++)
+ {
+ if (j && ((j & 15) == 0))
+ header.append("\n\t\t");
+ sprintf(buffer, "0x%04x, ", code[j]);
+ header.append(buffer);
+ }
+ header.append("\n\t},\n");
+
+ header.append("};\n");
+}
+
+void CodesToHeader(const std::vector<u16> *codes, const std::vector<std::string>* filenames,
+ int numCodes, const char *name, std::string &header)
+{
+ char buffer[1024];
+ int reserveSize = 0;
+ for(int i = 0; i < numCodes; i++)
+ reserveSize += (int)codes[i].size();
+
+
+ header.clear();
+ header.reserve(reserveSize * 4);
+ sprintf(buffer, "#define NUM_UCODES %d\n\n", numCodes);
+ header.append(buffer);
+ header.append("const char* UCODE_NAMES[NUM_UCODES] = {\n");
+ for (int i = 0; i < numCodes; i++)
+ {
+ std::string filename;
+ if (! SplitPath(filenames->at(i), NULL, &filename, NULL))
+ filename = filenames->at(i);
+ sprintf(buffer, "\t\"%s\",\n", filename.c_str());
+ header.append(buffer);
+ }
+ header.append("};\n\n");
+ header.append("#ifndef _MSCVER\n");
+ header.append("const unsigned short dsp_ucode[NUM_UCODES][0x1000] = {\n");
+ header.append("#else\n");
+ header.append("const unsigned short dsp_ucode[NUM_UCODES][0x1000] __attribute__ ((aligned (64))) = {\n");
+ header.append("#endif\n\n");
+
+ for(int i = 0; i < numCodes; i++) {
+ if(codes[i].size() == 0)
+ continue;
+
+ std::vector<u16> code_copy = codes[i];
+ // Add some nops at the end to align the size a bit.
+ while (code_copy.size() & 7)
+ code_copy.push_back(0);
+
+ header.append("\t{\n\t\t");
+ for (u32 j = 0; j < codes[i].size(); j++)
+ {
+ if (j && ((j & 15) == 0))
+ header.append("\n\t\t");
+ sprintf(buffer, "0x%04x, ", codes[i][j]);
+ header.append(buffer);
+ }
+ header.append("\n\t},\n");
+ }
+ header.append("};\n");
+}
+
+void CodeToBinaryStringBE(const std::vector<u16> &code, std::string &str)
+{
+ str.resize(code.size() * 2);
+ for (int i = 0; i < (int)code.size(); i++)
+ {
+ str[i * 2 + 0] = code[i] >> 8;
+ str[i * 2 + 1] = code[i] & 0xff;
+ }
+}
+
+void BinaryStringBEToCode(const std::string &str, std::vector<u16> &code)
+{
+ code.resize(str.size() / 2);
+ for (int i = 0; i < (int)code.size(); i++)
+ {
+ code[i] = ((u16)(u8)str[i * 2 + 0] << 8) | ((u16)(u8)str[i * 2 + 1]);
+ }
+}
+
+bool LoadBinary(const char *filename, std::vector<u16> &code)
+{
+ std::string buffer;
+ if (!File::ReadFileToString(false, filename, buffer))
+ return false;
+
+ BinaryStringBEToCode(buffer, code);
+ return true;
+}
+
+bool SaveBinary(const std::vector<u16> &code, const char *filename)
+{
+ std::string buffer;
+ CodeToBinaryStringBE(code, buffer);
+ if (!File::WriteStringToFile(false, buffer, filename))
+ return false;
+ return true;
+}
diff --git a/Source/Core/DSPCore/Src/DSPCodeUtil.h b/Source/Core/DSPCore/Src/DSPCodeUtil.h
index 3d204e359e..bcf4a78048 100644
--- a/Source/Core/DSPCore/Src/DSPCodeUtil.h
+++ b/Source/Core/DSPCore/Src/DSPCodeUtil.h
@@ -1,43 +1,43 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _DSPCODEUTIL_H
-#define _DSPCODEUTIL_H
-
-#include <string>
-#include <vector>
-
-#include "Common.h"
-
-bool Assemble(const char *text, std::vector<u16> &code);
-bool Disassemble(const std::vector<u16> &code, bool line_numbers, std::string &text);
-bool Compare(const std::vector<u16> &code1, const std::vector<u16> &code2);
-void GenRandomCode(int size, std::vector<u16> &code);
-void CodeToHeader(const std::vector<u16> &code, std::string _filename,
- const char *name, std::string &header);
-void CodesToHeader(const std::vector<u16> *codes, const std::vector<std::string> *filenames,
- int numCodes, const char *name, std::string &header);
-
-// Big-endian, for writing straight to file using File::WriteStringToFile.
-void CodeToBinaryStringBE(const std::vector<u16> &code, std::string &str);
-void BinaryStringBEToCode(const std::string &str, std::vector<u16> &code);
-
-// Load code (big endian binary).
-bool LoadBinary(const char *filename, std::vector<u16> &code);
-bool SaveBinary(const std::vector<u16> &code, const char *filename);
-
-#endif // _DSPCODEUTIL_H
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _DSPCODEUTIL_H
+#define _DSPCODEUTIL_H
+
+#include <string>
+#include <vector>
+
+#include "Common.h"
+
+bool Assemble(const char *text, std::vector<u16> &code);
+bool Disassemble(const std::vector<u16> &code, bool line_numbers, std::string &text);
+bool Compare(const std::vector<u16> &code1, const std::vector<u16> &code2);
+void GenRandomCode(int size, std::vector<u16> &code);
+void CodeToHeader(const std::vector<u16> &code, std::string _filename,
+ const char *name, std::string &header);
+void CodesToHeader(const std::vector<u16> *codes, const std::vector<std::string> *filenames,
+ int numCodes, const char *name, std::string &header);
+
+// Big-endian, for writing straight to file using File::WriteStringToFile.
+void CodeToBinaryStringBE(const std::vector<u16> &code, std::string &str);
+void BinaryStringBEToCode(const std::string &str, std::vector<u16> &code);
+
+// Load code (big endian binary).
+bool LoadBinary(const char *filename, std::vector<u16> &code);
+bool SaveBinary(const std::vector<u16> &code, const char *filename);
+
+#endif // _DSPCODEUTIL_H
diff --git a/Source/Core/DSPCore/Src/DSPCore.cpp b/Source/Core/DSPCore/Src/DSPCore.cpp
index c143852251..0dafd25259 100644
--- a/Source/Core/DSPCore/Src/DSPCore.cpp
+++ b/Source/Core/DSPCore/Src/DSPCore.cpp
@@ -1,256 +1,256 @@
-/*====================================================================
-
- filename: gdsp_interpreter.cpp
- project: GCemu
- created: 2004-6-18
- mail: duddie@walla.com
-
- Copyright (c) 2005 Duddie & Tratax
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- ====================================================================*/
-
-#include "Common.h"
-#include "Thread.h"
-#include "DSPCore.h"
-#include "DSPHost.h"
-#include "DSPAnalyzer.h"
-#include "MemoryUtil.h"
-
-#include "DSPHWInterface.h"
-#include "DSPIntUtil.h"
-
-SDSP g_dsp;
-DSPBreakpoints dsp_breakpoints;
-DSPCoreState core_state = DSPCORE_RUNNING;
-Common::Event step_event;
-
-static bool LoadRom(const char *fname, int size_in_words, u16 *rom)
-{
- FILE *pFile = fopen(fname, "rb");
- const size_t size_in_bytes = size_in_words * sizeof(u16);
- if (pFile)
- {
- size_t read_bytes = fread(rom, 1, size_in_bytes, pFile);
- if (read_bytes != size_in_bytes)
- {
- PanicAlert("ROM %s too short : %i/%i", fname, (int)read_bytes, (int)size_in_bytes);
- fclose(pFile);
- return false;
- }
- fclose(pFile);
-
- // Byteswap the rom.
- for (int i = 0; i < DSP_IROM_SIZE; i++)
- rom[i] = Common::swap16(rom[i]);
-
- return true;
- }
- // Always keep ROMs write protected.
- WriteProtectMemory(g_dsp.irom, size_in_bytes, false);
- return false;
-}
-
-bool DSPCore_Init(const char *irom_filename, const char *coef_filename)
-{
- g_dsp.step_counter = 0;
-
- g_dsp.irom = (u16*)AllocateMemoryPages(DSP_IROM_BYTE_SIZE);
- g_dsp.iram = (u16*)AllocateMemoryPages(DSP_IRAM_BYTE_SIZE);
- g_dsp.dram = (u16*)AllocateMemoryPages(DSP_DRAM_BYTE_SIZE);
- g_dsp.coef = (u16*)AllocateMemoryPages(DSP_COEF_BYTE_SIZE);
-
- // Fill roms with zeros.
- memset(g_dsp.irom, 0, DSP_IROM_BYTE_SIZE);
- memset(g_dsp.coef, 0, DSP_COEF_BYTE_SIZE);
-
- // Try to load real ROM contents. Failing this, only homebrew will work correctly with the DSP.
- LoadRom(irom_filename, DSP_IROM_SIZE, g_dsp.irom);
- LoadRom(coef_filename, DSP_COEF_SIZE, g_dsp.coef);
-
- for (int i = 0; i < 32; i++)
- {
- g_dsp.r[i] = 0;
- }
-
- for (int i = 0; i < 4; i++)
- {
- g_dsp.reg_stack_ptr[i] = 0;
- for (int j = 0; j < DSP_STACK_DEPTH; j++)
- {
- g_dsp.reg_stack[i][j] = 0;
- }
- }
-
- // Fill IRAM with HALT opcodes.
- for (int i = 0; i < DSP_IRAM_SIZE; i++)
- {
- g_dsp.iram[i] = 0x0021; // HALT opcode
- }
-
- // Just zero out DRAM.
- for (int i = 0; i < DSP_DRAM_SIZE; i++)
- {
- g_dsp.dram[i] = 0;
- }
-
- // Copied from a real console after the custom UCode has been loaded.
- // These are the indexing wrapping registers.
- g_dsp.r[DSP_REG_WR0] = 0xffff;
- g_dsp.r[DSP_REG_WR1] = 0xffff;
- g_dsp.r[DSP_REG_WR2] = 0xffff;
- g_dsp.r[DSP_REG_WR3] = 0xffff;
-
- g_dsp.cr = 0x804;
- gdsp_ifx_init();
-
- // Mostly keep IRAM write protected. We unprotect only when DMA-ing
- // in new ucodes.
- WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false);
- DSPAnalyzer::Analyze();
-
- step_event.Init();
- return true;
-}
-
-void DSPCore_Shutdown()
-{
- step_event.Shutdown();
- FreeMemoryPages(g_dsp.irom, DSP_IROM_BYTE_SIZE);
- FreeMemoryPages(g_dsp.iram, DSP_IRAM_BYTE_SIZE);
- FreeMemoryPages(g_dsp.dram, DSP_DRAM_BYTE_SIZE);
- FreeMemoryPages(g_dsp.coef, DSP_COEF_BYTE_SIZE);
-}
-
-void DSPCore_Reset()
-{
- _assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "reset while exception");
- g_dsp.pc = DSP_RESET_VECTOR;
- g_dsp.exception_in_progress_hack = false;
-
- g_dsp.r[DSP_REG_WR0] = 0xffff;
- g_dsp.r[DSP_REG_WR1] = 0xffff;
- g_dsp.r[DSP_REG_WR2] = 0xffff;
- g_dsp.r[DSP_REG_WR3] = 0xffff;
-
-}
-
-void DSPCore_SetException(u8 level)
-{
- g_dsp.exceptions |= 1 << level;
-}
-
-void DSPCore_CheckExternalInterrupt()
-{
- // check if there is an external interrupt
- if (g_dsp.cr & CR_EXTERNAL_INT && !g_dsp.exception_in_progress_hack)
- {
-#ifdef DEBUG_EXP
- NOTICE_LOG(DSPLLE, "trying External interupt fired");
-#endif
- if (dsp_SR_is_flag_set(SR_EXT_INT_ENABLE))
- {
-#ifdef DEBUG_EXP
- NOTICE_LOG(DSPLLE, "External interupt fired");
-#endif
- // level 7 is the interrupt exception
- DSPCore_SetException(EXP_INT);
-
- g_dsp.cr &= ~CR_EXTERNAL_INT;
- }
- }
-}
-
-void DSPCore_CheckExceptions()
-{
- if (g_dsp.exceptions != 0 && !g_dsp.exception_in_progress_hack) {
-#ifdef DEBUG_EXP
- NOTICE_LOG(DSPLLE, "trying exception %d fired", g_dsp.exceptions);
-#endif
- // check exceptions
- for (int i = 0; i < 8; i++) {
- // Seems 7 must pass or zelda dies
- if (dsp_SR_is_flag_set(SR_INT_ENABLE) || i == EXP_INT) {
- if (g_dsp.exceptions & (1 << i)) {
- _assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception");
-
- dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc);
- dsp_reg_store_stack(DSP_STACK_D, g_dsp.r[DSP_REG_SR]);
-
- g_dsp.pc = i * 2;
- g_dsp.exceptions &= ~(1 << i);
-#ifdef DEBUG_EXP
- NOTICE_LOG(DSPLLE, "exception %d fired");
-#endif
- g_dsp.exception_in_progress_hack = true;
- break;
- }
- }
- }
- }
-}
-
-// Delegate to JIT (when it is written) or interpreter as appropriate.
-// Handle state changes and stepping.
-int DSPCore_RunCycles(int cycles)
-{
- while (cycles > 0) {
- reswitch:
- switch (core_state)
- {
- case DSPCORE_RUNNING:
-#if 1 // Set to 0 to disable breakpoints, for a speed boost.
- cycles = DSPInterpreter::RunCyclesDebug(cycles);
-#else
- cycles = DSPInterpreter::RunCycles(cycles);
-#endif
- break;
-
- case DSPCORE_STEPPING:
- step_event.Wait();
- if (core_state != DSPCORE_STEPPING)
- goto reswitch;
-
- DSPInterpreter::Step();
- cycles--;
-
- DSPHost_UpdateDebugger();
- break;
- }
- }
- return cycles;
-}
-
-void DSPCore_SetState(DSPCoreState new_state)
-{
- core_state = new_state;
- // kick the event, in case we are waiting
- if (new_state == DSPCORE_RUNNING)
- step_event.Set();
- // Sleep(10);
- DSPHost_UpdateDebugger();
-}
-
-DSPCoreState DSPCore_GetState()
-{
- return core_state;
-}
-
-void DSPCore_Step()
-{
- if (core_state == DSPCORE_STEPPING)
- step_event.Set();
-}
+/*====================================================================
+
+ filename: gdsp_interpreter.cpp
+ project: GCemu
+ created: 2004-6-18
+ mail: duddie@walla.com
+
+ Copyright (c) 2005 Duddie & Tratax
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ ====================================================================*/
+
+#include "Common.h"
+#include "Thread.h"
+#include "DSPCore.h"
+#include "DSPHost.h"
+#include "DSPAnalyzer.h"
+#include "MemoryUtil.h"
+
+#include "DSPHWInterface.h"
+#include "DSPIntUtil.h"
+
+SDSP g_dsp;
+DSPBreakpoints dsp_breakpoints;
+DSPCoreState core_state = DSPCORE_RUNNING;
+Common::Event step_event;
+
+static bool LoadRom(const char *fname, int size_in_words, u16 *rom)
+{
+ FILE *pFile = fopen(fname, "rb");
+ const size_t size_in_bytes = size_in_words * sizeof(u16);
+ if (pFile)
+ {
+ size_t read_bytes = fread(rom, 1, size_in_bytes, pFile);
+ if (read_bytes != size_in_bytes)
+ {
+ PanicAlert("ROM %s too short : %i/%i", fname, (int)read_bytes, (int)size_in_bytes);
+ fclose(pFile);
+ return false;
+ }
+ fclose(pFile);
+
+ // Byteswap the rom.
+ for (int i = 0; i < DSP_IROM_SIZE; i++)
+ rom[i] = Common::swap16(rom[i]);
+
+ return true;
+ }
+ // Always keep ROMs write protected.
+ WriteProtectMemory(g_dsp.irom, size_in_bytes, false);
+ return false;
+}
+
+bool DSPCore_Init(const char *irom_filename, const char *coef_filename)
+{
+ g_dsp.step_counter = 0;
+
+ g_dsp.irom = (u16*)AllocateMemoryPages(DSP_IROM_BYTE_SIZE);
+ g_dsp.iram = (u16*)AllocateMemoryPages(DSP_IRAM_BYTE_SIZE);
+ g_dsp.dram = (u16*)AllocateMemoryPages(DSP_DRAM_BYTE_SIZE);
+ g_dsp.coef = (u16*)AllocateMemoryPages(DSP_COEF_BYTE_SIZE);
+
+ // Fill roms with zeros.
+ memset(g_dsp.irom, 0, DSP_IROM_BYTE_SIZE);
+ memset(g_dsp.coef, 0, DSP_COEF_BYTE_SIZE);
+
+ // Try to load real ROM contents. Failing this, only homebrew will work correctly with the DSP.
+ LoadRom(irom_filename, DSP_IROM_SIZE, g_dsp.irom);
+ LoadRom(coef_filename, DSP_COEF_SIZE, g_dsp.coef);
+
+ for (int i = 0; i < 32; i++)
+ {
+ g_dsp.r[i] = 0;
+ }
+
+ for (int i = 0; i < 4; i++)
+ {
+ g_dsp.reg_stack_ptr[i] = 0;
+ for (int j = 0; j < DSP_STACK_DEPTH; j++)
+ {
+ g_dsp.reg_stack[i][j] = 0;
+ }
+ }
+
+ // Fill IRAM with HALT opcodes.
+ for (int i = 0; i < DSP_IRAM_SIZE; i++)
+ {
+ g_dsp.iram[i] = 0x0021; // HALT opcode
+ }
+
+ // Just zero out DRAM.
+ for (int i = 0; i < DSP_DRAM_SIZE; i++)
+ {
+ g_dsp.dram[i] = 0;
+ }
+
+ // Copied from a real console after the custom UCode has been loaded.
+ // These are the indexing wrapping registers.
+ g_dsp.r[DSP_REG_WR0] = 0xffff;
+ g_dsp.r[DSP_REG_WR1] = 0xffff;
+ g_dsp.r[DSP_REG_WR2] = 0xffff;
+ g_dsp.r[DSP_REG_WR3] = 0xffff;
+
+ g_dsp.cr = 0x804;
+ gdsp_ifx_init();
+
+ // Mostly keep IRAM write protected. We unprotect only when DMA-ing
+ // in new ucodes.
+ WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false);
+ DSPAnalyzer::Analyze();
+
+ step_event.Init();
+ return true;
+}
+
+void DSPCore_Shutdown()
+{
+ step_event.Shutdown();
+ FreeMemoryPages(g_dsp.irom, DSP_IROM_BYTE_SIZE);
+ FreeMemoryPages(g_dsp.iram, DSP_IRAM_BYTE_SIZE);
+ FreeMemoryPages(g_dsp.dram, DSP_DRAM_BYTE_SIZE);
+ FreeMemoryPages(g_dsp.coef, DSP_COEF_BYTE_SIZE);
+}
+
+void DSPCore_Reset()
+{
+ _assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "reset while exception");
+ g_dsp.pc = DSP_RESET_VECTOR;
+ g_dsp.exception_in_progress_hack = false;
+
+ g_dsp.r[DSP_REG_WR0] = 0xffff;
+ g_dsp.r[DSP_REG_WR1] = 0xffff;
+ g_dsp.r[DSP_REG_WR2] = 0xffff;
+ g_dsp.r[DSP_REG_WR3] = 0xffff;
+
+}
+
+void DSPCore_SetException(u8 level)
+{
+ g_dsp.exceptions |= 1 << level;
+}
+
+void DSPCore_CheckExternalInterrupt()
+{
+ // check if there is an external interrupt
+ if (g_dsp.cr & CR_EXTERNAL_INT && !g_dsp.exception_in_progress_hack)
+ {
+#ifdef DEBUG_EXP
+ NOTICE_LOG(DSPLLE, "trying External interupt fired");
+#endif
+ if (dsp_SR_is_flag_set(SR_EXT_INT_ENABLE))
+ {
+#ifdef DEBUG_EXP
+ NOTICE_LOG(DSPLLE, "External interupt fired");
+#endif
+ // level 7 is the interrupt exception
+ DSPCore_SetException(EXP_INT);
+
+ g_dsp.cr &= ~CR_EXTERNAL_INT;
+ }
+ }
+}
+
+void DSPCore_CheckExceptions()
+{
+ if (g_dsp.exceptions != 0 && !g_dsp.exception_in_progress_hack) {
+#ifdef DEBUG_EXP
+ NOTICE_LOG(DSPLLE, "trying exception %d fired", g_dsp.exceptions);
+#endif
+ // check exceptions
+ for (int i = 0; i < 8; i++) {
+ // Seems 7 must pass or zelda dies
+ if (dsp_SR_is_flag_set(SR_INT_ENABLE) || i == EXP_INT) {
+ if (g_dsp.exceptions & (1 << i)) {
+ _assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception");
+
+ dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc);
+ dsp_reg_store_stack(DSP_STACK_D, g_dsp.r[DSP_REG_SR]);
+
+ g_dsp.pc = i * 2;
+ g_dsp.exceptions &= ~(1 << i);
+#ifdef DEBUG_EXP
+ NOTICE_LOG(DSPLLE, "exception %d fired");
+#endif
+ g_dsp.exception_in_progress_hack = true;
+ break;
+ }
+ }
+ }
+ }
+}
+
+// Delegate to JIT (when it is written) or interpreter as appropriate.
+// Handle state changes and stepping.
+int DSPCore_RunCycles(int cycles)
+{
+ while (cycles > 0) {
+ reswitch:
+ switch (core_state)
+ {
+ case DSPCORE_RUNNING:
+#if 1 // Set to 0 to disable breakpoints, for a speed boost.
+ cycles = DSPInterpreter::RunCyclesDebug(cycles);
+#else
+ cycles = DSPInterpreter::RunCycles(cycles);
+#endif
+ break;
+
+ case DSPCORE_STEPPING:
+ step_event.Wait();
+ if (core_state != DSPCORE_STEPPING)
+ goto reswitch;
+
+ DSPInterpreter::Step();
+ cycles--;
+
+ DSPHost_UpdateDebugger();
+ break;
+ }
+ }
+ return cycles;
+}
+
+void DSPCore_SetState(DSPCoreState new_state)
+{
+ core_state = new_state;
+ // kick the event, in case we are waiting
+ if (new_state == DSPCORE_RUNNING)
+ step_event.Set();
+ // Sleep(10);
+ DSPHost_UpdateDebugger();
+}
+
+DSPCoreState DSPCore_GetState()
+{
+ return core_state;
+}
+
+void DSPCore_Step()
+{
+ if (core_state == DSPCORE_STEPPING)
+ step_event.Set();
+}
diff --git a/Source/Core/DSPCore/Src/DSPCore.h b/Source/Core/DSPCore/Src/DSPCore.h
index 24d31eed48..b1293e70f6 100644
--- a/Source/Core/DSPCore/Src/DSPCore.h
+++ b/Source/Core/DSPCore/Src/DSPCore.h
@@ -1,240 +1,240 @@
-/*====================================================================
-
- filename: DSPCore.h
- project: GCemu
- created: 2004-6-18
- mail: duddie@walla.com
-
- Copyright (c) 2005 Duddie & Tratax
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- ====================================================================*/
-
-#ifndef _DSPCORE_H
-#define _DSPCORE_H
-
-#include "DSPBreakpoints.h"
-
-#define DSP_IRAM_BYTE_SIZE 0x2000
-#define DSP_IRAM_SIZE 0x1000
-#define DSP_IRAM_MASK 0x0fff
-
-#define DSP_IROM_BYTE_SIZE 0x2000
-#define DSP_IROM_SIZE 0x1000
-#define DSP_IROM_MASK 0x0fff
-
-#define DSP_DRAM_BYTE_SIZE 0x2000
-#define DSP_DRAM_SIZE 0x1000
-#define DSP_DRAM_MASK 0x0fff
-
-#define DSP_COEF_BYTE_SIZE 0x2000
-#define DSP_COEF_SIZE 0x1000
-#define DSP_COEF_MASK 0x0fff
-
-#define DSP_RESET_VECTOR 0x8000
-
-#define DSP_STACK_DEPTH 0x20
-#define DSP_STACK_MASK 0x1f
-
-#define DSP_CR_IMEM 2
-#define DSP_CR_DMEM 0
-#define DSP_CR_TO_CPU 1
-#define DSP_CR_FROM_CPU 0
-
-
-// Register table taken from libasnd
-#define DSP_REG_AR0 0x00 // address registers
-#define DSP_REG_AR1 0x01
-#define DSP_REG_AR2 0x02
-#define DSP_REG_AR3 0x03
-
-#define DSP_REG_IX0 0x04 // indexing registers (actually, mostly used as increments)
-#define DSP_REG_IX1 0x05
-#define DSP_REG_IX2 0x06
-#define DSP_REG_IX3 0x07
-
-#define DSP_REG_WR0 0x08 // address wrapping registers. should be initialized to 0xFFFF if not used.
-#define DSP_REG_WR1 0x09
-#define DSP_REG_WR2 0x0a
-#define DSP_REG_WR3 0x0b
-
-#define DSP_REG_ST0 0x0c // stacks.
-#define DSP_REG_ST1 0x0d
-#define DSP_REG_ST2 0x0e
-#define DSP_REG_ST3 0x0f
-
-#define DSP_REG_CR 0x12 // Seems to be the top 8 bits of LRS/SRS.
-#define DSP_REG_SR 0x13
-
-#define DSP_REG_PRODL 0x14 // product.
-#define DSP_REG_PRODM 0x15
-#define DSP_REG_PRODH 0x16
-#define DSP_REG_PRODM2 0x17
-
-#define DSP_REG_AXL0 0x18
-#define DSP_REG_AXL1 0x19
-#define DSP_REG_AXH0 0x1a
-#define DSP_REG_AXH1 0x1b
-
-#define DSP_REG_ACC0 0x1c // accumulator (global)
-#define DSP_REG_ACC1 0x1d
-
-#define DSP_REG_ACL0 0x1c // Low accumulator
-#define DSP_REG_ACL1 0x1d
-#define DSP_REG_ACM0 0x1e // Mid accumulator
-#define DSP_REG_ACM1 0x1f
-#define DSP_REG_ACH0 0x10 // Sign extended 8 bit register 0
-#define DSP_REG_ACH1 0x11 // Sign extended 8 bit register 1
-
-// Hardware registers address
-
-#define DSP_COEF_A1_0 0xa0
-
-#define DSP_DSMAH 0xce
-#define DSP_DSMAL 0xcf
-#define DSP_DSCR 0xc9 // DSP DMA Control Reg
-#define DSP_DSPA 0xcd // DSP DMA Block Length
-#define DSP_DSBL 0xcb // DSP DMA DMEM Address
-#define DSP_DSMAH 0xce // DSP DMA Mem Address H
-#define DSP_DSMAL 0xcf // DSP DMA Mem Address L
-
-#define DSP_FORMAT 0xd1
-#define DSP_ACDATA1 0xd3 // used only by Zelda ucodes
-#define DSP_ACSAH 0xd4
-#define DSP_ACSAL 0xd5
-#define DSP_ACEAH 0xd6
-#define DSP_ACEAL 0xd7
-#define DSP_ACCAH 0xd8
-#define DSP_ACCAL 0xd9
-#define DSP_PRED_SCALE 0xda
-#define DSP_YN1 0xdb
-#define DSP_YN2 0xdc
-#define DSP_ACCELERATOR 0xdd // ADPCM accelerator read. Used by AX.
-#define DSP_GAIN 0xde
-
-#define DSP_DIRQ 0xfb // DSP Irq Rest
-#define DSP_DMBH 0xfc // DSP Mailbox H
-#define DSP_DMBL 0xfd // DSP Mailbox L
-#define DSP_CMBH 0xfe // CPU Mailbox H
-#define DSP_CMBL 0xff // CPU Mailbox L
-
-#define DMA_TO_DSP 0
-#define DMA_TO_CPU 1
-
-// Stacks
-#define DSP_STACK_C 0
-#define DSP_STACK_D 1
-
-// cr (Not g_dsp.r[CR]) bits
-// See HW/DSP.cpp.
-#define CR_HALT 0x0004
-#define CR_EXTERNAL_INT 0x0002
-
-
-// SR bits
-#define SR_CARRY 0x0001
-#define SR_2 0x0002 // overflow???
-#define SR_ARITH_ZERO 0x0004
-#define SR_SIGN 0x0008
-#define SR_10 0x0010 // seem to be set by tst
-#define SR_TOP2BITS 0x0020 // this is an odd one. (set by tst)
-#define SR_LOGIC_ZERO 0x0040
-#define SR_INT_ENABLE 0x0200 // Not 100% sure but duddie says so. This should replace the hack, if so.
-#define SR_EXT_INT_ENABLE 0x0800 // Appears in zelda - seems to disable external interupts
-#define SR_MUL_MODIFY 0x2000 // 1 = normal. 0 = x2 (M0, M2)
-#define SR_40_MODE_BIT 0x4000 // 0 = "16", 1 = "40" (SET16, SET40) Controls sign extension when loading mid accums.
-#define SR_MUL_UNSIGNED 0x8000 // 0 = normal. 1 = unsigned (CLR15, SET15) If set, treats operands as unsigned. Tested with mulx only so far.
-
-// This should be the bits affected by CMP. Does not include logic zero.
-#define SR_CMP_MASK 0x3f
-
-// exceptions vector
-#define EXP_RESET 0 // 0x0000
-#define EXP_STOVF 1 // 0x0002 stack under/over flow
-#define EXP_4 2 // 0x0004
-#define EXP_6 3 // 0x0006
-#define EXP_8 4 // 0x0008
-#define EXP_ACCOV 5 // 0x000a accelerator address overflow
-#define EXP_c 6 // 0x000c
-#define EXP_INT 7 // 0x000e external int? (mail?)
-
-struct SDSP
-{
- u16 r[32];
- u16 pc;
-#if PROFILE
- u16 err_pc;
-#endif
-
- // This is NOT the same cr as r[DSP_REG_CR].
- // This register is shared with the main emulation, see DSP.cpp
- // The plugin has control over 0x0C07 of this reg.
- // Bits are defined in a struct in DSP.cpp.
- u16 cr;
-
- u8 reg_stack_ptr[4];
- u8 exceptions; // pending exceptions?
- bool exception_in_progress_hack; // is this the same as "exception enabled"?
-
- // Let's make stack depth 32 for now. The real DSP has different depths
- // for the different stacks, but it would be strange if any ucode relied on stack
- // overflows since on the DSP, when the stack overflows, you're screwed.
- u16 reg_stack[4][DSP_STACK_DEPTH];
-
- // For debugging.
- u32 iram_crc;
- u64 step_counter;
-
- // When state saving, all of the above can just be memcpy'd into the save state.
- // The below needs special handling.
- u16 *iram;
- u16 *dram;
- u16 *irom;
- u16 *coef;
-
- // This one doesn't really belong here.
- u8 *cpu_ram;
-};
-
-extern SDSP g_dsp;
-extern DSPBreakpoints dsp_breakpoints;
-
-bool DSPCore_Init(const char *irom_filename, const char *coef_filename);
-
-void DSPCore_Reset();
-void DSPCore_Shutdown(); // Frees all allocated memory.
-
-void DSPCore_CheckExternalInterrupt();
-void DSPCore_CheckExceptions();
-
-// sets a flag in the pending exception register.
-void DSPCore_SetException(u8 level);
-
-enum DSPCoreState
-{
- DSPCORE_RUNNING = 0,
- DSPCORE_STEPPING = 1,
-};
-
-int DSPCore_RunCycles(int cycles);
-
-// These are meant to be called from the UI thread.
-void DSPCore_SetState(DSPCoreState new_state);
-DSPCoreState DSPCore_GetState();
-
-void DSPCore_Step();
-
-#endif // _DSPCORE_H
+/*====================================================================
+
+ filename: DSPCore.h
+ project: GCemu
+ created: 2004-6-18
+ mail: duddie@walla.com
+
+ Copyright (c) 2005 Duddie & Tratax
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ ====================================================================*/
+
+#ifndef _DSPCORE_H
+#define _DSPCORE_H
+
+#include "DSPBreakpoints.h"
+
+#define DSP_IRAM_BYTE_SIZE 0x2000
+#define DSP_IRAM_SIZE 0x1000
+#define DSP_IRAM_MASK 0x0fff
+
+#define DSP_IROM_BYTE_SIZE 0x2000
+#define DSP_IROM_SIZE 0x1000
+#define DSP_IROM_MASK 0x0fff
+
+#define DSP_DRAM_BYTE_SIZE 0x2000
+#define DSP_DRAM_SIZE 0x1000
+#define DSP_DRAM_MASK 0x0fff
+
+#define DSP_COEF_BYTE_SIZE 0x2000
+#define DSP_COEF_SIZE 0x1000
+#define DSP_COEF_MASK 0x0fff
+
+#define DSP_RESET_VECTOR 0x8000
+
+#define DSP_STACK_DEPTH 0x20
+#define DSP_STACK_MASK 0x1f
+
+#define DSP_CR_IMEM 2
+#define DSP_CR_DMEM 0
+#define DSP_CR_TO_CPU 1
+#define DSP_CR_FROM_CPU 0
+
+
+// Register table taken from libasnd
+#define DSP_REG_AR0 0x00 // address registers
+#define DSP_REG_AR1 0x01
+#define DSP_REG_AR2 0x02
+#define DSP_REG_AR3 0x03
+
+#define DSP_REG_IX0 0x04 // indexing registers (actually, mostly used as increments)
+#define DSP_REG_IX1 0x05
+#define DSP_REG_IX2 0x06
+#define DSP_REG_IX3 0x07
+
+#define DSP_REG_WR0 0x08 // address wrapping registers. should be initialized to 0xFFFF if not used.
+#define DSP_REG_WR1 0x09
+#define DSP_REG_WR2 0x0a
+#define DSP_REG_WR3 0x0b
+
+#define DSP_REG_ST0 0x0c // stacks.
+#define DSP_REG_ST1 0x0d
+#define DSP_REG_ST2 0x0e
+#define DSP_REG_ST3 0x0f
+
+#define DSP_REG_CR 0x12 // Seems to be the top 8 bits of LRS/SRS.
+#define DSP_REG_SR 0x13
+
+#define DSP_REG_PRODL 0x14 // product.
+#define DSP_REG_PRODM 0x15
+#define DSP_REG_PRODH 0x16
+#define DSP_REG_PRODM2 0x17
+
+#define DSP_REG_AXL0 0x18
+#define DSP_REG_AXL1 0x19
+#define DSP_REG_AXH0 0x1a
+#define DSP_REG_AXH1 0x1b
+
+#define DSP_REG_ACC0 0x1c // accumulator (global)
+#define DSP_REG_ACC1 0x1d
+
+#define DSP_REG_ACL0 0x1c // Low accumulator
+#define DSP_REG_ACL1 0x1d
+#define DSP_REG_ACM0 0x1e // Mid accumulator
+#define DSP_REG_ACM1 0x1f
+#define DSP_REG_ACH0 0x10 // Sign extended 8 bit register 0
+#define DSP_REG_ACH1 0x11 // Sign extended 8 bit register 1
+
+// Hardware registers address
+
+#define DSP_COEF_A1_0 0xa0
+
+#define DSP_DSMAH 0xce
+#define DSP_DSMAL 0xcf
+#define DSP_DSCR 0xc9 // DSP DMA Control Reg
+#define DSP_DSPA 0xcd // DSP DMA Block Length
+#define DSP_DSBL 0xcb // DSP DMA DMEM Address
+#define DSP_DSMAH 0xce // DSP DMA Mem Address H
+#define DSP_DSMAL 0xcf // DSP DMA Mem Address L
+
+#define DSP_FORMAT 0xd1
+#define DSP_ACDATA1 0xd3 // used only by Zelda ucodes
+#define DSP_ACSAH 0xd4
+#define DSP_ACSAL 0xd5
+#define DSP_ACEAH 0xd6
+#define DSP_ACEAL 0xd7
+#define DSP_ACCAH 0xd8
+#define DSP_ACCAL 0xd9
+#define DSP_PRED_SCALE 0xda
+#define DSP_YN1 0xdb
+#define DSP_YN2 0xdc
+#define DSP_ACCELERATOR 0xdd // ADPCM accelerator read. Used by AX.
+#define DSP_GAIN 0xde
+
+#define DSP_DIRQ 0xfb // DSP Irq Rest
+#define DSP_DMBH 0xfc // DSP Mailbox H
+#define DSP_DMBL 0xfd // DSP Mailbox L
+#define DSP_CMBH 0xfe // CPU Mailbox H
+#define DSP_CMBL 0xff // CPU Mailbox L
+
+#define DMA_TO_DSP 0
+#define DMA_TO_CPU 1
+
+// Stacks
+#define DSP_STACK_C 0
+#define DSP_STACK_D 1
+
+// cr (Not g_dsp.r[CR]) bits
+// See HW/DSP.cpp.
+#define CR_HALT 0x0004
+#define CR_EXTERNAL_INT 0x0002
+
+
+// SR bits
+#define SR_CARRY 0x0001
+#define SR_2 0x0002 // overflow???
+#define SR_ARITH_ZERO 0x0004
+#define SR_SIGN 0x0008
+#define SR_10 0x0010 // seem to be set by tst
+#define SR_TOP2BITS 0x0020 // this is an odd one. (set by tst)
+#define SR_LOGIC_ZERO 0x0040
+#define SR_INT_ENABLE 0x0200 // Not 100% sure but duddie says so. This should replace the hack, if so.
+#define SR_EXT_INT_ENABLE 0x0800 // Appears in zelda - seems to disable external interupts
+#define SR_MUL_MODIFY 0x2000 // 1 = normal. 0 = x2 (M0, M2)
+#define SR_40_MODE_BIT 0x4000 // 0 = "16", 1 = "40" (SET16, SET40) Controls sign extension when loading mid accums.
+#define SR_MUL_UNSIGNED 0x8000 // 0 = normal. 1 = unsigned (CLR15, SET15) If set, treats operands as unsigned. Tested with mulx only so far.
+
+// This should be the bits affected by CMP. Does not include logic zero.
+#define SR_CMP_MASK 0x3f
+
+// exceptions vector
+#define EXP_RESET 0 // 0x0000
+#define EXP_STOVF 1 // 0x0002 stack under/over flow
+#define EXP_4 2 // 0x0004
+#define EXP_6 3 // 0x0006
+#define EXP_8 4 // 0x0008
+#define EXP_ACCOV 5 // 0x000a accelerator address overflow
+#define EXP_c 6 // 0x000c
+#define EXP_INT 7 // 0x000e external int? (mail?)
+
+struct SDSP
+{
+ u16 r[32];
+ u16 pc;
+#if PROFILE
+ u16 err_pc;
+#endif
+
+ // This is NOT the same cr as r[DSP_REG_CR].
+ // This register is shared with the main emulation, see DSP.cpp
+ // The plugin has control over 0x0C07 of this reg.
+ // Bits are defined in a struct in DSP.cpp.
+ u16 cr;
+
+ u8 reg_stack_ptr[4];
+ u8 exceptions; // pending exceptions?
+ bool exception_in_progress_hack; // is this the same as "exception enabled"?
+
+ // Let's make stack depth 32 for now. The real DSP has different depths
+ // for the different stacks, but it would be strange if any ucode relied on stack
+ // overflows since on the DSP, when the stack overflows, you're screwed.
+ u16 reg_stack[4][DSP_STACK_DEPTH];
+
+ // For debugging.
+ u32 iram_crc;
+ u64 step_counter;
+
+ // When state saving, all of the above can just be memcpy'd into the save state.
+ // The below needs special handling.
+ u16 *iram;
+ u16 *dram;
+ u16 *irom;
+ u16 *coef;
+
+ // This one doesn't really belong here.
+ u8 *cpu_ram;
+};
+
+extern SDSP g_dsp;
+extern DSPBreakpoints dsp_breakpoints;
+
+bool DSPCore_Init(const char *irom_filename, const char *coef_filename);
+
+void DSPCore_Reset();
+void DSPCore_Shutdown(); // Frees all allocated memory.
+
+void DSPCore_CheckExternalInterrupt();
+void DSPCore_CheckExceptions();
+
+// sets a flag in the pending exception register.
+void DSPCore_SetException(u8 level);
+
+enum DSPCoreState
+{
+ DSPCORE_RUNNING = 0,
+ DSPCORE_STEPPING = 1,
+};
+
+int DSPCore_RunCycles(int cycles);
+
+// These are meant to be called from the UI thread.
+void DSPCore_SetState(DSPCoreState new_state);
+DSPCoreState DSPCore_GetState();
+
+void DSPCore_Step();
+
+#endif // _DSPCORE_H
diff --git a/Source/Core/DSPCore/Src/DSPHost.h b/Source/Core/DSPCore/Src/DSPHost.h
index 60791deeb1..0abddd85f3 100644
--- a/Source/Core/DSPCore/Src/DSPHost.h
+++ b/Source/Core/DSPCore/Src/DSPHost.h
@@ -1,35 +1,35 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _DSPHOST_H
-#define _DSPHOST_H
-
-// The user of the DSPCore library must supply a few functions so that the
-// emulation core can access the environment it runs in. If the emulation
-// core isn't used, for example in an asm/disasm tool, then most of these
-// can be stubbed out.
-#define DEBUG_EXP 1
-
-u8 DSPHost_ReadHostMemory(u32 addr);
-void DSPHost_WriteHostMemory(u8 value, u32 addr);
-bool DSPHost_OnThread();
-bool DSPHost_Running();
-void DSPHost_InterruptRequest();
-u32 DSPHost_CodeLoaded(const u8 *ptr, int size);
-void DSPHost_UpdateDebugger();
-
-#endif
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _DSPHOST_H
+#define _DSPHOST_H
+
+// The user of the DSPCore library must supply a few functions so that the
+// emulation core can access the environment it runs in. If the emulation
+// core isn't used, for example in an asm/disasm tool, then most of these
+// can be stubbed out.
+#define DEBUG_EXP 1
+
+u8 DSPHost_ReadHostMemory(u32 addr);
+void DSPHost_WriteHostMemory(u8 value, u32 addr);
+bool DSPHost_OnThread();
+bool DSPHost_Running();
+void DSPHost_InterruptRequest();
+u32 DSPHost_CodeLoaded(const u8 *ptr, int size);
+void DSPHost_UpdateDebugger();
+
+#endif
diff --git a/Source/Core/DSPCore/Src/DSPIntCCUtil.cpp b/Source/Core/DSPCore/Src/DSPIntCCUtil.cpp
index bb391a4a91..171a783331 100644
--- a/Source/Core/DSPCore/Src/DSPIntCCUtil.cpp
+++ b/Source/Core/DSPCore/Src/DSPIntCCUtil.cpp
@@ -1,140 +1,140 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-// Additional copyrights go to Duddie and Tratax (c) 2004
-
-
-// HELPER FUNCTIONS
-
-#include "DSPIntCCUtil.h"
-#include "DSPCore.h"
-#include "DSPInterpreter.h"
-
-namespace DSPInterpreter {
-
-void Update_SR_Register64(s64 _Value)
-{
- g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
-
- if (_Value < 0)
- {
- g_dsp.r[DSP_REG_SR] |= SR_SIGN;
- }
-
- if (_Value == 0)
- {
- g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
- }
-
- // weird
- if ((_Value >> 62) == 0)
- {
- g_dsp.r[DSP_REG_SR] |= 0x20;
- }
-}
-
-void Update_SR_Register16(s16 _Value)
-{
- g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
-
- if (_Value < 0)
- {
- g_dsp.r[DSP_REG_SR] |= SR_SIGN;
- }
-
- if (_Value == 0)
- {
- g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
- }
-
- // weird
- if ((_Value >> 14) == 0)
- {
- g_dsp.r[DSP_REG_SR] |= 0x20;
- }
-}
-
-void Update_SR_LZ(s64 value) {
-
- if (value == 0)
- {
- g_dsp.r[DSP_REG_SR] |= SR_LOGIC_ZERO;
- }
- else
- {
- g_dsp.r[DSP_REG_SR] &= ~SR_LOGIC_ZERO;
- }
-
-}
-
-int GetMultiplyModifier()
-{
- if (g_dsp.r[DSP_REG_SR] & SR_MUL_MODIFY)
- return 1;
- else
- return 2;
-}
-
-inline bool isCarry() {
- return (g_dsp.r[DSP_REG_SR] & SR_CARRY) ? true : false;
-}
-inline bool isSign() {
- return ((g_dsp.r[DSP_REG_SR] & SR_2) != (g_dsp.r[DSP_REG_SR] & SR_SIGN));
-}
-inline bool isZero() {
- return (g_dsp.r[DSP_REG_SR] & SR_ARITH_ZERO) ? true : false;
-}
-
-//see gdsp_registers.h for flags
-bool CheckCondition(u8 _Condition)
-{
- switch (_Condition & 0xf)
- {
- case 0x0: //NS - NOT SIGN
- return !isSign();
- case 0x1: // S - SIGN
- return isSign();
- case 0x2: // G - GREATER
- return !isSign() && !isZero();
- case 0x3: // LE - LESS EQUAL
- return isSign() || isZero();
- case 0x4: // NZ - NOT ZERO
- return !isZero();
- case 0x5: // Z - ZERO
- return isZero();
- case 0x6: // L - LESS
- // Should be that once we set 0x01
- return !isCarry();
- // if (isSign())
- case 0x7: // GE - GREATER EQUAL
- // Should be that once we set 0x01
- return isCarry();
- // if (! isSign() || isZero())
- case 0xc: // LNZ - LOGIC NOT ZERO
- return !(g_dsp.r[DSP_REG_SR] & SR_LOGIC_ZERO);
- case 0xd: // LZ - LOGIC ZERO
- return (g_dsp.r[DSP_REG_SR] & SR_LOGIC_ZERO) != 0;
-
- case 0xf: // Empty - always true.
- return true;
- default:
- ERROR_LOG(DSPLLE, "Unknown condition check: 0x%04x\n", _Condition & 0xf);
- return false;
- }
-}
-
-} // namespace
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Additional copyrights go to Duddie and Tratax (c) 2004
+
+
+// HELPER FUNCTIONS
+
+#include "DSPIntCCUtil.h"
+#include "DSPCore.h"
+#include "DSPInterpreter.h"
+
+namespace DSPInterpreter {
+
+void Update_SR_Register64(s64 _Value)
+{
+ g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
+
+ if (_Value < 0)
+ {
+ g_dsp.r[DSP_REG_SR] |= SR_SIGN;
+ }
+
+ if (_Value == 0)
+ {
+ g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
+ }
+
+ // weird
+ if ((_Value >> 62) == 0)
+ {
+ g_dsp.r[DSP_REG_SR] |= 0x20;
+ }
+}
+
+void Update_SR_Register16(s16 _Value)
+{
+ g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
+
+ if (_Value < 0)
+ {
+ g_dsp.r[DSP_REG_SR] |= SR_SIGN;
+ }
+
+ if (_Value == 0)
+ {
+ g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
+ }
+
+ // weird
+ if ((_Value >> 14) == 0)
+ {
+ g_dsp.r[DSP_REG_SR] |= 0x20;
+ }
+}
+
+void Update_SR_LZ(s64 value) {
+
+ if (value == 0)
+ {
+ g_dsp.r[DSP_REG_SR] |= SR_LOGIC_ZERO;
+ }
+ else
+ {
+ g_dsp.r[DSP_REG_SR] &= ~SR_LOGIC_ZERO;
+ }
+
+}
+
+int GetMultiplyModifier()
+{
+ if (g_dsp.r[DSP_REG_SR] & SR_MUL_MODIFY)
+ return 1;
+ else
+ return 2;
+}
+
+inline bool isCarry() {
+ return (g_dsp.r[DSP_REG_SR] & SR_CARRY) ? true : false;
+}
+inline bool isSign() {
+ return ((g_dsp.r[DSP_REG_SR] & SR_2) != (g_dsp.r[DSP_REG_SR] & SR_SIGN));
+}
+inline bool isZero() {
+ return (g_dsp.r[DSP_REG_SR] & SR_ARITH_ZERO) ? true : false;
+}
+
+//see gdsp_registers.h for flags
+bool CheckCondition(u8 _Condition)
+{
+ switch (_Condition & 0xf)
+ {
+ case 0x0: //NS - NOT SIGN
+ return !isSign();
+ case 0x1: // S - SIGN
+ return isSign();
+ case 0x2: // G - GREATER
+ return !isSign() && !isZero();
+ case 0x3: // LE - LESS EQUAL
+ return isSign() || isZero();
+ case 0x4: // NZ - NOT ZERO
+ return !isZero();
+ case 0x5: // Z - ZERO
+ return isZero();
+ case 0x6: // L - LESS
+ // Should be that once we set 0x01
+ return !isCarry();
+ // if (isSign())
+ case 0x7: // GE - GREATER EQUAL
+ // Should be that once we set 0x01
+ return isCarry();
+ // if (! isSign() || isZero())
+ case 0xc: // LNZ - LOGIC NOT ZERO
+ return !(g_dsp.r[DSP_REG_SR] & SR_LOGIC_ZERO);
+ case 0xd: // LZ - LOGIC ZERO
+ return (g_dsp.r[DSP_REG_SR] & SR_LOGIC_ZERO) != 0;
+
+ case 0xf: // Empty - always true.
+ return true;
+ default:
+ ERROR_LOG(DSPLLE, "Unknown condition check: 0x%04x\n", _Condition & 0xf);
+ return false;
+ }
+}
+
+} // namespace
diff --git a/Source/Core/DSPCore/Src/DSPIntCCUtil.h b/Source/Core/DSPCore/Src/DSPIntCCUtil.h
index def95e0b97..135e861062 100644
--- a/Source/Core/DSPCore/Src/DSPIntCCUtil.h
+++ b/Source/Core/DSPCore/Src/DSPIntCCUtil.h
@@ -1,39 +1,39 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-// Additional copyrights go to Duddie and Tratax (c) 2004
-
-#ifndef _GDSP_CONDITION_CODES_H
-#define _GDSP_CONDITION_CODES_H
-
-// Anything to do with SR and conditions goes here.
-
-#include "Common.h"
-
-namespace DSPInterpreter {
-
-bool CheckCondition(u8 _Condition);
-
-int GetMultiplyModifier();
-
-void Update_SR_Register16(s16 _Value);
-void Update_SR_Register64(s64 _Value);
-void Update_SR_LZ(s64 value);
-
-} // namespace
-
-#endif // _GDSP_CONDITION_CODES_H
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Additional copyrights go to Duddie and Tratax (c) 2004
+
+#ifndef _GDSP_CONDITION_CODES_H
+#define _GDSP_CONDITION_CODES_H
+
+// Anything to do with SR and conditions goes here.
+
+#include "Common.h"
+
+namespace DSPInterpreter {
+
+bool CheckCondition(u8 _Condition);
+
+int GetMultiplyModifier();
+
+void Update_SR_Register16(s16 _Value);
+void Update_SR_Register64(s64 _Value);
+void Update_SR_LZ(s64 value);
+
+} // namespace
+
+#endif // _GDSP_CONDITION_CODES_H
diff --git a/Source/Core/DSPCore/Src/DSPInterpreter.h b/Source/Core/DSPCore/Src/DSPInterpreter.h
index d8f4d84f58..fe5f1afcc9 100644
--- a/Source/Core/DSPCore/Src/DSPInterpreter.h
+++ b/Source/Core/DSPCore/Src/DSPInterpreter.h
@@ -1,171 +1,171 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _DSPINTERPRETER_H
-#define _DSPINTERPRETER_H
-
-#include "DSPTables.h"
-
-#define DSP_REG_MASK 0x1f
-
-namespace DSPInterpreter {
-
-void Step();
-void Run();
-
-// If these simply return the same number of cycles as was passed into them,
-// chances are that the DSP is halted.
-// The difference between them is that the debug one obeys breakpoints.
-int RunCycles(int cycles);
-int RunCyclesDebug(int cycles);
-
-void Stop();
-
-void WriteCR(u16 val);
-u16 ReadCR();
-
-
-typedef void (*DSPInterpreterFunc)(const UDSPInstruction& opc);
-
-// All the opcode functions.
-void unknown(const UDSPInstruction& opc);
-void call(const UDSPInstruction& opc);
-void callr(const UDSPInstruction& opc);
-void ifcc(const UDSPInstruction& opc);
-void jcc(const UDSPInstruction& opc);
-void jmprcc(const UDSPInstruction& opc);
-void ret(const UDSPInstruction& opc);
-void halt(const UDSPInstruction& opc);
-void loop(const UDSPInstruction& opc);
-void loopi(const UDSPInstruction& opc);
-void bloop(const UDSPInstruction& opc);
-void bloopi(const UDSPInstruction& opc);
-void mrr(const UDSPInstruction& opc);
-void lrr(const UDSPInstruction& opc);
-void lrrd(const UDSPInstruction& opc);
-void lrri(const UDSPInstruction& opc);
-void lrrn(const UDSPInstruction& opc);
-void srr(const UDSPInstruction& opc);
-void srrd(const UDSPInstruction& opc);
-void srri(const UDSPInstruction& opc);
-void srrn(const UDSPInstruction& opc);
-void lri(const UDSPInstruction& opc);
-void lris(const UDSPInstruction& opc);
-void lr(const UDSPInstruction& opc);
-void sr(const UDSPInstruction& opc);
-void si(const UDSPInstruction& opc);
-void tstaxh(const UDSPInstruction& opc);
-void clr(const UDSPInstruction& opc);
-void clrl(const UDSPInstruction& opc);
-void clrp(const UDSPInstruction& opc);
-void mulc(const UDSPInstruction& opc);
-void cmpar(const UDSPInstruction& opc);
-void cmp(const UDSPInstruction& opc);
-void tst(const UDSPInstruction& opc);
-void addaxl(const UDSPInstruction& opc);
-void addarn(const UDSPInstruction& opc);
-void mulcac(const UDSPInstruction& opc);
-void movr(const UDSPInstruction& opc);
-void movax(const UDSPInstruction& opc);
-void xorr(const UDSPInstruction& opc);
-void andr(const UDSPInstruction& opc);
-void andc(const UDSPInstruction& opc);
-void orr(const UDSPInstruction& opc);
-void orc(const UDSPInstruction& opc);
-void orf(const UDSPInstruction& opc);
-void add(const UDSPInstruction& opc);
-void addp(const UDSPInstruction& opc);
-void cmpis(const UDSPInstruction& opc);
-void addpaxz(const UDSPInstruction& opc);
-void movpz(const UDSPInstruction& opc);
-void decm(const UDSPInstruction& opc);
-void dec(const UDSPInstruction& opc);
-void inc(const UDSPInstruction& opc);
-void incm(const UDSPInstruction& opc);
-void neg(const UDSPInstruction& opc);
-void addax(const UDSPInstruction& opc);
-void addr(const UDSPInstruction& opc);
-void subr(const UDSPInstruction& opc);
-void subp(const UDSPInstruction& opc);
-void subax(const UDSPInstruction& opc);
-void addis(const UDSPInstruction& opc);
-void addi(const UDSPInstruction& opc);
-void lsl16(const UDSPInstruction& opc);
-void madd(const UDSPInstruction& opc);
-void msub(const UDSPInstruction& opc);
-void lsr16(const UDSPInstruction& opc);
-void asr16(const UDSPInstruction& opc);
-void lsl(const UDSPInstruction& opc);
-void lsr(const UDSPInstruction& opc);
-void asl(const UDSPInstruction& opc);
-void asr(const UDSPInstruction& opc);
-void lsrn(const UDSPInstruction& opc);
-void asrn(const UDSPInstruction& opc);
-void dar(const UDSPInstruction& opc);
-void iar(const UDSPInstruction& opc);
-void sbclr(const UDSPInstruction& opc);
-void sbset(const UDSPInstruction& opc);
-void mov(const UDSPInstruction& opc);
-void movp(const UDSPInstruction& opc);
-void mul(const UDSPInstruction& opc);
-void mulac(const UDSPInstruction& opc);
-void mulmv(const UDSPInstruction& opc);
-void mulmvz(const UDSPInstruction& opc);
-void mulx(const UDSPInstruction& opc);
-void mulxac(const UDSPInstruction& opc);
-void mulxmv(const UDSPInstruction& opc);
-void mulxmvz(const UDSPInstruction& opc);
-void mulcmvz(const UDSPInstruction& opc);
-void mulcmv(const UDSPInstruction& opc);
-void movnp(const UDSPInstruction& opc);
-void sub(const UDSPInstruction& opc);
-void maddx(const UDSPInstruction& opc);
-void msubx(const UDSPInstruction& opc);
-void maddc(const UDSPInstruction& opc);
-void msubc(const UDSPInstruction& opc);
-void srs(const UDSPInstruction& opc);
-void lrs(const UDSPInstruction& opc);
-void nx(const UDSPInstruction& opc);
-void cmpi(const UDSPInstruction& opc);
-void rti(const UDSPInstruction& opc);
-void ilrr(const UDSPInstruction& opc);
-void ilrrd(const UDSPInstruction& opc);
-void ilrri(const UDSPInstruction& opc);
-void ilrrn(const UDSPInstruction& opc);
-void andcf(const UDSPInstruction& opc);
-void andf(const UDSPInstruction& opc);
-void xori(const UDSPInstruction& opc);
-void andi(const UDSPInstruction& opc);
-void ori(const UDSPInstruction& opc);
-
-// FIXME inside
-void srbith(const UDSPInstruction& opc);
-
-// END OF FIXMEs
-
-// TODO: PENDING IMPLEMENTATION / UNIMPLEMENTED
-void tstaxl(const UDSPInstruction& opc);
-// The mysterious a100
-
-// END OF UNIMPLEMENTED
-
-// Helpers
-inline void tsta(int reg);
-
-} // namespace
-
-#endif // _DSPINTERPRETER_H
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _DSPINTERPRETER_H
+#define _DSPINTERPRETER_H
+
+#include "DSPTables.h"
+
+#define DSP_REG_MASK 0x1f
+
+namespace DSPInterpreter {
+
+void Step();
+void Run();
+
+// If these simply return the same number of cycles as was passed into them,
+// chances are that the DSP is halted.
+// The difference between them is that the debug one obeys breakpoints.
+int RunCycles(int cycles);
+int RunCyclesDebug(int cycles);
+
+void Stop();
+
+void WriteCR(u16 val);
+u16 ReadCR();
+
+
+typedef void (*DSPInterpreterFunc)(const UDSPInstruction& opc);
+
+// All the opcode functions.
+void unknown(const UDSPInstruction& opc);
+void call(const UDSPInstruction& opc);
+void callr(const UDSPInstruction& opc);
+void ifcc(const UDSPInstruction& opc);
+void jcc(const UDSPInstruction& opc);
+void jmprcc(const UDSPInstruction& opc);
+void ret(const UDSPInstruction& opc);
+void halt(const UDSPInstruction& opc);
+void loop(const UDSPInstruction& opc);
+void loopi(const UDSPInstruction& opc);
+void bloop(const UDSPInstruction& opc);
+void bloopi(const UDSPInstruction& opc);
+void mrr(const UDSPInstruction& opc);
+void lrr(const UDSPInstruction& opc);
+void lrrd(const UDSPInstruction& opc);
+void lrri(const UDSPInstruction& opc);
+void lrrn(const UDSPInstruction& opc);
+void srr(const UDSPInstruction& opc);
+void srrd(const UDSPInstruction& opc);
+void srri(const UDSPInstruction& opc);
+void srrn(const UDSPInstruction& opc);
+void lri(const UDSPInstruction& opc);
+void lris(const UDSPInstruction& opc);
+void lr(const UDSPInstruction& opc);
+void sr(const UDSPInstruction& opc);
+void si(const UDSPInstruction& opc);
+void tstaxh(const UDSPInstruction& opc);
+void clr(const UDSPInstruction& opc);
+void clrl(const UDSPInstruction& opc);
+void clrp(const UDSPInstruction& opc);
+void mulc(const UDSPInstruction& opc);
+void cmpar(const UDSPInstruction& opc);
+void cmp(const UDSPInstruction& opc);
+void tst(const UDSPInstruction& opc);
+void addaxl(const UDSPInstruction& opc);
+void addarn(const UDSPInstruction& opc);
+void mulcac(const UDSPInstruction& opc);
+void movr(const UDSPInstruction& opc);
+void movax(const UDSPInstruction& opc);
+void xorr(const UDSPInstruction& opc);
+void andr(const UDSPInstruction& opc);
+void andc(const UDSPInstruction& opc);
+void orr(const UDSPInstruction& opc);
+void orc(const UDSPInstruction& opc);
+void orf(const UDSPInstruction& opc);
+void add(const UDSPInstruction& opc);
+void addp(const UDSPInstruction& opc);
+void cmpis(const UDSPInstruction& opc);
+void addpaxz(const UDSPInstruction& opc);
+void movpz(const UDSPInstruction& opc);
+void decm(const UDSPInstruction& opc);
+void dec(const UDSPInstruction& opc);
+void inc(const UDSPInstruction& opc);
+void incm(const UDSPInstruction& opc);
+void neg(const UDSPInstruction& opc);
+void addax(const UDSPInstruction& opc);
+void addr(const UDSPInstruction& opc);
+void subr(const UDSPInstruction& opc);
+void subp(const UDSPInstruction& opc);
+void subax(const UDSPInstruction& opc);
+void addis(const UDSPInstruction& opc);
+void addi(const UDSPInstruction& opc);
+void lsl16(const UDSPInstruction& opc);
+void madd(const UDSPInstruction& opc);
+void msub(const UDSPInstruction& opc);
+void lsr16(const UDSPInstruction& opc);
+void asr16(const UDSPInstruction& opc);
+void lsl(const UDSPInstruction& opc);
+void lsr(const UDSPInstruction& opc);
+void asl(const UDSPInstruction& opc);
+void asr(const UDSPInstruction& opc);
+void lsrn(const UDSPInstruction& opc);
+void asrn(const UDSPInstruction& opc);
+void dar(const UDSPInstruction& opc);
+void iar(const UDSPInstruction& opc);
+void sbclr(const UDSPInstruction& opc);
+void sbset(const UDSPInstruction& opc);
+void mov(const UDSPInstruction& opc);
+void movp(const UDSPInstruction& opc);
+void mul(const UDSPInstruction& opc);
+void mulac(const UDSPInstruction& opc);
+void mulmv(const UDSPInstruction& opc);
+void mulmvz(const UDSPInstruction& opc);
+void mulx(const UDSPInstruction& opc);
+void mulxac(const UDSPInstruction& opc);
+void mulxmv(const UDSPInstruction& opc);
+void mulxmvz(const UDSPInstruction& opc);
+void mulcmvz(const UDSPInstruction& opc);
+void mulcmv(const UDSPInstruction& opc);
+void movnp(const UDSPInstruction& opc);
+void sub(const UDSPInstruction& opc);
+void maddx(const UDSPInstruction& opc);
+void msubx(const UDSPInstruction& opc);
+void maddc(const UDSPInstruction& opc);
+void msubc(const UDSPInstruction& opc);
+void srs(const UDSPInstruction& opc);
+void lrs(const UDSPInstruction& opc);
+void nx(const UDSPInstruction& opc);
+void cmpi(const UDSPInstruction& opc);
+void rti(const UDSPInstruction& opc);
+void ilrr(const UDSPInstruction& opc);
+void ilrrd(const UDSPInstruction& opc);
+void ilrri(const UDSPInstruction& opc);
+void ilrrn(const UDSPInstruction& opc);
+void andcf(const UDSPInstruction& opc);
+void andf(const UDSPInstruction& opc);
+void xori(const UDSPInstruction& opc);
+void andi(const UDSPInstruction& opc);
+void ori(const UDSPInstruction& opc);
+
+// FIXME inside
+void srbith(const UDSPInstruction& opc);
+
+// END OF FIXMEs
+
+// TODO: PENDING IMPLEMENTATION / UNIMPLEMENTED
+void tstaxl(const UDSPInstruction& opc);
+// The mysterious a100
+
+// END OF UNIMPLEMENTED
+
+// Helpers
+inline void tsta(int reg);
+
+} // namespace
+
+#endif // _DSPINTERPRETER_H
diff --git a/Source/Core/DSPCore/Src/DSPJit.cpp b/Source/Core/DSPCore/Src/DSPJit.cpp
index cbf7d1ebeb..540380f6de 100644
--- a/Source/Core/DSPCore/Src/DSPJit.cpp
+++ b/Source/Core/DSPCore/Src/DSPJit.cpp
@@ -1,22 +1,22 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "DSPJit.h"
-
-namespace DSPJit {
-
-};
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "DSPJit.h"
+
+namespace DSPJit {
+
+};
diff --git a/Source/Core/DSPCore/Src/DSPJit.h b/Source/Core/DSPCore/Src/DSPJit.h
index 32e34672e2..9f05faedf1 100644
--- a/Source/Core/DSPCore/Src/DSPJit.h
+++ b/Source/Core/DSPCore/Src/DSPJit.h
@@ -1,28 +1,28 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _DSPJIT_H
-#define _DSPJIT_H
-
-namespace DSPJit {
-
-// TODO(XK): Fill
-
-
-} // namespace
-
-#endif // _DSPJIT_H
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _DSPJIT_H
+#define _DSPJIT_H
+
+namespace DSPJit {
+
+// TODO(XK): Fill
+
+
+} // namespace
+
+#endif // _DSPJIT_H
diff --git a/Source/Core/DSPCore/Src/DSPTables.cpp b/Source/Core/DSPCore/Src/DSPTables.cpp
index 4913e0cc60..b9162de01a 100644
--- a/Source/Core/DSPCore/Src/DSPTables.cpp
+++ b/Source/Core/DSPCore/Src/DSPTables.cpp
@@ -1,583 +1,583 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-// Additional copyrights go to Duddie (c) 2005 (duddie@walla.com)
-
-/* NOTES BY HERMES:
-
-LZ flag: original opcodes andf and andcf are swaped. Also "jzr" and "jnz" are swaped but now named 'jlz' and 'jlnz'
-As you can see it obtain the same result but now LZ=1 correctly
-
-Added conditional instructions:
-
-conditional names:
-
-NZ -> NOT ZERO
-Z -> ZERO
-
-NS -> NOT SIGN
-S -> SIGN
-
-LZ -> LOGIC ZERO (only used with andcf-andf instructions?)
-LNZ -> LOGIC NOT ZERO
-
-G -> GREATER
-LE-> LESS EQUAL
-
-GE-> GREATER EQUAL
-L -> LESS
-
-Examples:
-
-jnz, ifs, retlnz
-
-*/
-
-
-#include "Common.h"
-#include "DSPTables.h"
-
-#include "DSPInterpreter.h"
-#include "DSPJit.h"
-#include "DSPIntExtOps.h"
-
-void nop(const UDSPInstruction& opc)
-{
- // The real nop is 0. Anything else is bad.
- if (opc.hex)
- DSPInterpreter::unknown(opc);
-}
-
-// Unknown Ops
-// All AX games: a100
-// Zelda Four Swords: 02ca
-
-// TODO: Fill up the tables with the corresponding instructions
-const DSPOPCTemplate opcodes[] =
-{
- {"NOP", 0x0000, 0xffff, nop, nop, 1, 0, {}, NULL, NULL},
-
- {"DAR", 0x0004, 0xfffc, DSPInterpreter::dar, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL},
- {"IAR", 0x0008, 0xfffc, DSPInterpreter::iar, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL},
-
- {"HALT", 0x0021, 0xffff, DSPInterpreter::halt, nop, 1, 0, {}, NULL, NULL},
-
- {"RETNS", 0x02d0, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
- {"RETS", 0x02d1, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
- {"RETG", 0x02d2, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
- {"RETLE", 0x02d3, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
- {"RETNZ", 0x02d4, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
- {"RETZ", 0x02d5, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
- {"RETL", 0x02d6, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
- {"RETGE", 0x02d7, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
- {"RETLNZ", 0x02dc, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
- {"RETLZ", 0x02dd, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
- {"RET", 0x02df, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
- {"RTI", 0x02ff, 0xffff, DSPInterpreter::rti, nop, 1, 0, {}, NULL, NULL},
-
- {"CALLNS", 0x02b0, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"CALLS", 0x02b1, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"CALLG", 0x02b2, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"CALLLE", 0x02b3, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"CALLNE", 0x02b4, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"CALLZ", 0x02b5, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"CALLL", 0x02b6, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"CALLGE", 0x02b7, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"CALLLNZ", 0x02bc, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"CALLLZ", 0x02bd, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"CALL", 0x02bf, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
-
- {"IFNS", 0x0270, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
- {"IFS", 0x0271, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
- {"IFG", 0x0272, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
- {"IFLE", 0x0273, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
- {"IFNZ", 0x0274, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
- {"IFZ", 0x0275, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
- {"IFL", 0x0276, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
- {"IFGE", 0x0277, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
- {"IFLNZ", 0x027c, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
- {"IFLZ", 0x027d, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
- {"IF", 0x027f, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL}, // This is just nop
-
- {"JNS", 0x0290, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"JS", 0x0291, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"JG", 0x0292, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"JLE", 0x0293, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"JNZ", 0x0294, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"JZ", 0x0295, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"JL", 0x0296, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"JGE", 0x0297, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"JLNZ", 0x029c, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"JLZ", 0x029d, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"JMP", 0x029f, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
-
-
- {"JRNS", 0x1700, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"JRS", 0x1701, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"JRG", 0x1702, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"JRLE", 0x1703, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"JRNZ", 0x1704, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"JRZ", 0x1705, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"JRL", 0x1706, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"JRGE", 0x1707, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"JRLNZ", 0x170c, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"JRLZ", 0x170d, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"JMPR", 0x170f, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
-
- {"CALLRNS", 0x1710, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"CALLRS", 0x1711, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"CALLRG", 0x1712, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"CALLRLE", 0x1713, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"CALLRNZ", 0x1714, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"CALLRZ", 0x1715, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"CALLRL", 0x1716, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"CALLRGE", 0x1717, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"CALLRLNZ",0x171c, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"CALLRLZ", 0x171d, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"CALLR", 0x171f, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
-
- {"SBCLR", 0x1200, 0xfff8, DSPInterpreter::sbclr, nop, 1, 1, {{P_IMM, 1, 0, 0, 0x0007}}, NULL, NULL},
- {"SBSET", 0x1300, 0xfff8, DSPInterpreter::sbset, nop, 1, 1, {{P_IMM, 1, 0, 0, 0x0007}}, NULL, NULL},
-
- // actually, given the masks these should probably be 0x3f. need investigation.
- {"LSL", 0x1400, 0xfec0, DSPInterpreter::lsl, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, NULL, NULL},
- {"LSR", 0x1440, 0xfec0, DSPInterpreter::lsr, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, NULL, NULL},
- {"ASL", 0x1480, 0xfec0, DSPInterpreter::asl, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, NULL, NULL},
- {"ASR", 0x14c0, 0xfec0, DSPInterpreter::asr, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, NULL, NULL},
-
- // discovered by ector!
- {"LSRN", 0x02ca, 0xffff, DSPInterpreter::lsrn, nop, 1, 0, {}, NULL, NULL},
- {"ASRN", 0x02cb, 0xffff, DSPInterpreter::asrn, nop, 1, 0, {}, NULL, NULL},
-
- {"LRI", 0x0080, 0xffe0, DSPInterpreter::lri, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"LR", 0x00c0, 0xffe0, DSPInterpreter::lr, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_MEM, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"SR", 0x00e0, 0xffe0, DSPInterpreter::sr, nop, 2, 2, {{P_MEM, 2, 1, 0, 0xffff}, {P_REG, 1, 0, 0, 0x001f}}, NULL, NULL},
-
- {"MRR", 0x1c00, 0xfc00, DSPInterpreter::mrr, nop, 1, 2, {{P_REG, 1, 0, 5, 0x03e0}, {P_REG, 1, 0, 0, 0x001f}}, NULL, NULL},
-
- {"SI", 0x1600, 0xff00, DSPInterpreter::si, nop, 2, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
-
- {"LRS", 0x2000, 0xf800, DSPInterpreter::lrs, nop, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_MEM, 1, 0, 0, 0x00ff}}, NULL, NULL},
- {"SRS", 0x2800, 0xf800, DSPInterpreter::srs, nop, 1, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_REG18, 1, 0, 8, 0x0700}}, NULL, NULL},
-
- {"LRIS", 0x0800, 0xf800, DSPInterpreter::lris, nop, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_IMM, 1, 0, 0, 0x00ff}}, NULL, NULL},
-
- {"ADDIS", 0x0400, 0xfe00, DSPInterpreter::addis, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}}, NULL, NULL},
- {"CMPIS", 0x0600, 0xfe00, DSPInterpreter::cmpis, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}}, NULL, NULL},
- {"ANDI", 0x0240, 0xfeff, DSPInterpreter::andi, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL,},
- {"ANDCF", 0x02c0, 0xfeff, DSPInterpreter::andcf, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL,},
-
- {"XORI", 0x0220, 0xfeff, DSPInterpreter::xori, nop, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"ANDF", 0x02a0, 0xfeff, DSPInterpreter::andf, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
-
- {"ORI", 0x0260, 0xfeff, DSPInterpreter::ori, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"ORF", 0x02e0, 0xfeff, DSPInterpreter::orf, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL}, // Hermes: ??? (has it commented out)
-
- {"ADDI", 0x0200, 0xfeff, DSPInterpreter::addi, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL}, // F|RES: missing S64
- {"CMPI", 0x0280, 0xfeff, DSPInterpreter::cmpi, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
-
- {"ILRR", 0x0210, 0xfedc, DSPInterpreter::ilrr, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL},
- {"ILRRD", 0x0214, 0xfedc, DSPInterpreter::ilrrd, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL}, // Hermes doesn't list this
- {"ILRRI", 0x0218, 0xfedc, DSPInterpreter::ilrri, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL},
- {"ILRRN", 0x0222, 0xfedc, DSPInterpreter::ilrrn, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL},
-
- // load and store value pointed by indexing reg and increment; LRR/SRR variants
- {"LRR", 0x1800, 0xff80, DSPInterpreter::lrr, nop, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}}, NULL, NULL},
- {"LRRD", 0x1880, 0xff80, DSPInterpreter::lrrd, nop, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}}, NULL, NULL},
- {"LRRI", 0x1900, 0xff80, DSPInterpreter::lrri, nop, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}}, NULL, NULL},
- {"LRRN", 0x1980, 0xff80, DSPInterpreter::lrrn, nop, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}}, NULL, NULL},
-
- {"SRR", 0x1a00, 0xff80, DSPInterpreter::srr, nop, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}}, NULL, NULL},
- {"SRRD", 0x1a80, 0xff80, DSPInterpreter::srrd, nop, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}}, NULL, NULL},
- {"SRRI", 0x1b00, 0xff80, DSPInterpreter::srri, nop, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}}, NULL, NULL},
- {"SRRN", 0x1b80, 0xff80, DSPInterpreter::srrn, nop, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}}, NULL, NULL},
-
- // LOOPS
- {"LOOP", 0x0040, 0xffe0, DSPInterpreter::loop, nop, 1, 1, {{P_REG, 1, 0, 0, 0x001f}}, NULL, NULL},
- {"BLOOP", 0x0060, 0xffe0, DSPInterpreter::bloop, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
- {"LOOPI", 0x1000, 0xff00, DSPInterpreter::loopi, nop, 1, 1, {{P_IMM, 1, 0, 0, 0x00ff}}, NULL, NULL},
- {"BLOOPI", 0x1100, 0xff00, DSPInterpreter::bloopi, nop, 2, 2, {{P_IMM, 1, 0, 0, 0x00ff}, {P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
-
- {"ADDARN", 0x0010, 0xfff0, DSPInterpreter::addarn, nop, 1, 2, {{P_REG, 1, 0, 0, 0x0003}, {P_REG04, 1, 0, 2, 0x000c}}, NULL, NULL},
-
-
- // opcodes that can be extended
- // extended opcodes, note size of opcode will be set to 0
-
- {"NX", 0x8000, 0xf700, DSPInterpreter::nx, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"M2", 0x8a00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"M0", 0x8b00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-
- {"CLR15", 0x8c00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"SET15", 0x8d00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-
- {"SET16", 0x8e00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"SET40", 0x8f00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-
-
- {"INCM", 0x7400, 0xfeff, DSPInterpreter::incm, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"INC", 0x7600, 0xfeff, DSPInterpreter::inc, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"DECM", 0x7800, 0xfeff, DSPInterpreter::decm, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"DEC", 0x7a00, 0xfeff, DSPInterpreter::dec, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"NEG", 0x7c00, 0xfeff, DSPInterpreter::neg, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MOVNP", 0x7e00, 0xfeff, DSPInterpreter::movnp, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-
-
- {"TST", 0xb100, 0xf7ff, DSPInterpreter::tst, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-
- // Definitely not TSTAXL, it affects one of the accumulators. (a100 or a900, same op, one parameter).
- {"TSTAXL", 0xa100, 0xffff, DSPInterpreter::tstaxl, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-
- {"TSTAXH", 0x8600, 0xfeff, DSPInterpreter::tstaxh, nop, 1 | P_EXT, 1, {{P_REG1A, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-
- {"CMP", 0x8200, 0xffff, DSPInterpreter::cmp, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-
- // This op does NOT exist, at least not under this name, in duddie's docs!
- {"CMPAR" , 0xc100, 0xe7ff, DSPInterpreter::cmpar, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-
- {"CLRL", 0xfc00, 0xffff, DSPInterpreter::clrl, nop, 1 | P_EXT, 1, {{P_ACCL, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // clear acl0
- {"CLR", 0x8100, 0xf7ff, DSPInterpreter::clr, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // clear acc0
- {"CLRP", 0x8400, 0xffff, DSPInterpreter::clrp, nop, 1 | P_EXT, 0, {}, },
-
- {"MOV", 0x6c00, 0xfeff, DSPInterpreter::mov, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_ACC_D, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MOVAX", 0x6800, 0xfcff, DSPInterpreter::movax, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MOVR", 0x6000, 0xf8ff, DSPInterpreter::movr, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MOVP", 0x6e00, 0xfeff, DSPInterpreter::movp, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MOVPZ", 0xfe00, 0xfeff, DSPInterpreter::movpz, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-
- {"ADDPAXZ", 0xf800, 0xfcff, DSPInterpreter::addpaxz, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 9, 0x0200}, {P_REG1A, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, //Think the args are wrong
- {"ADDP", 0x4e00, 0xfeff, DSPInterpreter::addp, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-
- {"LSL16", 0xf000, 0xfeff, DSPInterpreter::lsl16, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"LSR16", 0xf400, 0xfeff, DSPInterpreter::lsr16, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"ASR16", 0x9100, 0xf7ff, DSPInterpreter::asr16, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-
- {"XORR", 0x3000, 0xfcff, DSPInterpreter::xorr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"ANDR", 0x3400, 0xfcff, DSPInterpreter::andr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"ORR", 0x3800, 0xfcff, DSPInterpreter::orr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"ANDC", 0x3C00, 0xfeff, DSPInterpreter::andc, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // Hermes doesn't list this
- {"ORC", 0x3E00, 0xfeff, DSPInterpreter::orc, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // Hermes doesn't list this
-
- {"MULX", 0xa000, 0xe7ff, DSPInterpreter::mulx, nop, 1 | P_EXT, 2, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MULXMVZ", 0xa200, 0xe6ff, DSPInterpreter::mulxmvz, nop, 1 | P_EXT, 3, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MULXAC", 0xa400, 0xe6ff, DSPInterpreter::mulxac, nop, 1 | P_EXT, 3, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MULXMV", 0xa600, 0xe6ff, DSPInterpreter::mulxmv, nop, 1 | P_EXT, 3, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-
- {"MUL", 0x9000, 0xf7ff, DSPInterpreter::mul, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MULMVZ", 0x9200, 0xf6ff, DSPInterpreter::mulmvz, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MULAC", 0x9400, 0xf6ff, DSPInterpreter::mulac, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MULMV", 0x9600, 0xf6ff, DSPInterpreter::mulmv, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-
- {"MULC", 0xc000, 0xe7ff, DSPInterpreter::mulc, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MULCMVZ", 0xc200, 0xe6ff, DSPInterpreter::mulcmvz, nop, 1 | P_EXT, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MULCAC", 0xc400, 0xe6ff, DSPInterpreter::mulcac, nop, 1 | P_EXT, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MULCMV", 0xc600, 0xe6ff, DSPInterpreter::mulcmv, nop, 1 | P_EXT, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-
- {"ADDR", 0x4000, 0xf8ff, DSPInterpreter::addr, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"ADDAX", 0x4800, 0xfcff, DSPInterpreter::addax, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"ADD", 0x4c00, 0xfeff, DSPInterpreter::add, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_ACC_D, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"ADDAXL", 0x7000, 0xfcff, DSPInterpreter::addaxl, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-
- {"SUBR", 0x5000, 0xf8ff, DSPInterpreter::subr, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"SUBAX", 0x5800, 0xfcff, DSPInterpreter::subax, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"SUB", 0x5c00, 0xfeff, DSPInterpreter::sub, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_ACC_D, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"SUBP", 0x5e00, 0xfeff, DSPInterpreter::subp, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-
- {"MADD", 0xf200, 0xfeff, DSPInterpreter::madd, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MSUB", 0xf600, 0xfeff, DSPInterpreter::msub , nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MADDX", 0xe000, 0xfcff, DSPInterpreter::maddx, nop, 1 | P_EXT, 2, {{P_REGM18, 1, 0, 8, 0x0200}, {P_REGM19, 1, 0, 7, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MSUBX", 0xe400, 0xfcff, DSPInterpreter::msubx, nop, 1 | P_EXT, 2, {{P_REGM18, 1, 0, 8, 0x0200}, {P_REGM19, 1, 0, 7, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MADDC", 0xe800, 0xfcff, DSPInterpreter::maddc, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
- {"MSUBC", 0xec00, 0xfcff, DSPInterpreter::msubc, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
-};
-
-const DSPOPCTemplate cw =
- {"CW", 0x0000, 0x0000, nop, nop, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}}, NULL, NULL,};
-
-
-const DSPOPCTemplate opcodes_ext[] =
-{
- // FIXME: guessing this is cr need checking
- {"DR", 0x0004, 0x00fc, nop, /*DSPInterpreter::Ext::dr*/ nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
- {"IR", 0x0008, 0x00fc, nop, /*DSPInterpreter::Ext::ir*/ nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
- {"NR", 0x000c, 0x00fc, nop, /*DSPInterpreter::Ext::nr*/ nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
- {"MV", 0x0010, 0x00f0, nop, /*DSPInterpreter::Ext::mv*/ nop, 1, 2, {{P_REG18, 1, 0, 2, 0x000c}, {P_REG1C, 1, 0, 0, 0x0003}}, NULL, NULL,},
-
- {"S", 0x0020, 0x00e4, nop, /*DSPInterpreter::Ext::s*/ nop, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}}, NULL, NULL,},
- {"SN", 0x0024, 0x00e4, nop, /*DSPInterpreter::Ext::sn*/ nop, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}}, NULL, NULL,},
-
- {"L", 0x0040, 0x00c4, nop, /*DSPInterpreter::Ext::l*/ nop, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
- {"LN", 0x0044, 0x00c4, nop, /*DSPInterpreter::Ext::ln*/ nop, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
-
- {"LS", 0x0080, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}}, NULL, NULL,},
- {"SL", 0x0082, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}}, NULL, NULL,},
- {"LSN", 0x0084, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}}, NULL, NULL,},
- {"SLN", 0x0086, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}}, NULL, NULL,},
- {"LSM", 0x0088, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}}, NULL, NULL,},
- {"SLM", 0x008a, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}}, NULL, NULL,},
- {"LSNM", 0x008c, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}}, NULL, NULL,},
- {"SLNM", 0x008e, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}}, NULL, NULL,},
-
- /* FIXME: what are the LDX functions for? they have the same opcode as LD ones but different mask
- {"LDX", 0x00c0, 0x00cf, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}}, NULL, NULL,},
- {"LDXN", 0x00c4, 0x00cf, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}}, NULL, NULL,},
- {"LDXM", 0x00c8, 0x00cf, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}}, NULL, NULL,},
- {"LDXNM", 0x00cc, 0x00cf, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}}, NULL, NULL,},*/
-
- {"LD", 0x00c0, 0x00cc, nop, /*DSPInterpreter::Ext::ld*/ nop, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
- {"LDN", 0x00c4, 0x00cc, nop, /*DSPInterpreter::Ext::ldn*/ nop, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
- {"LDM", 0x00c8, 0x00cc, nop, /*DSPInterpreter::Ext::ldm*/ nop, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
- {"LDNM", 0x00cc, 0x00cc, nop, /*DSPInterpreter::Ext::ldnm*/ nop, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
-
- {"XXX", 0x0000, 0x0000, nop, nop, 1, 1, {{P_VAL, 1, 0, 0, 0x00ff}}, NULL, NULL,},
-};
-
-const int opcodes_size = sizeof(opcodes) / sizeof(DSPOPCTemplate);
-const int opcodes_ext_size = sizeof(opcodes_ext) / sizeof(DSPOPCTemplate);
-
-const pdlabel_t pdlabels[] =
-{
- {0xffa0, "COEF_A1_0", "COEF_A1_0",},
- {0xffa1, "COEF_A2_0", "COEF_A2_0",},
- {0xffa2, "COEF_A1_1", "COEF_A1_1",},
- {0xffa3, "COEF_A2_1", "COEF_A2_1",},
- {0xffa4, "COEF_A1_2", "COEF_A1_2",},
- {0xffa5, "COEF_A2_2", "COEF_A2_2",},
- {0xffa6, "COEF_A1_3", "COEF_A1_3",},
- {0xffa7, "COEF_A2_3", "COEF_A2_3",},
- {0xffa8, "COEF_A1_4", "COEF_A1_4",},
- {0xffa9, "COEF_A2_4", "COEF_A2_4",},
- {0xffaa, "COEF_A1_5", "COEF_A1_5",},
- {0xffab, "COEF_A2_5", "COEF_A2_5",},
- {0xffac, "COEF_A1_6", "COEF_A1_6",},
- {0xffad, "COEF_A2_6", "COEF_A2_6",},
- {0xffae, "COEF_A1_7", "COEF_A1_7",},
- {0xffaf, "COEF_A2_7", "COEF_A2_7",},
-
- {0xffb0, "0xffb0", 0,},
- {0xffb1, "0xffb1", 0,},
- {0xffb2, "0xffb2", 0,},
- {0xffb3, "0xffb3", 0,},
- {0xffb4, "0xffb4", 0,},
- {0xffb5, "0xffb5", 0,},
- {0xffb6, "0xffb6", 0,},
- {0xffb7, "0xffb7", 0,},
- {0xffb8, "0xffb8", 0,},
- {0xffb9, "0xffb9", 0,},
- {0xffba, "0xffba", 0,},
- {0xffbb, "0xffbb", 0,},
- {0xffbc, "0xffbc", 0,},
- {0xffbd, "0xffbd", 0,},
- {0xffbe, "0xffbe", 0,},
- {0xffbf, "0xffbf", 0,},
-
- {0xffc0, "0xffc0", 0,},
- {0xffc1, "0xffc1", 0,},
- {0xffc2, "0xffc2", 0,},
- {0xffc3, "0xffc3", 0,},
- {0xffc4, "0xffc4", 0,},
- {0xffc5, "0xffc5", 0,},
- {0xffc6, "0xffc6", 0,},
- {0xffc7, "0xffc7", 0,},
- {0xffc8, "0xffc8", 0,},
- {0xffc9, "DSCR", "DSP DMA Control Reg",},
- {0xffca, "0xffca", 0,},
- {0xffcb, "DSBL", "DSP DMA Block Length",},
- {0xffcc, "0xffcc", 0,},
- {0xffcd, "DSPA", "DSP DMA DMEM Address",},
- {0xffce, "DSMAH", "DSP DMA Mem Address H",},
- {0xffcf, "DSMAL", "DSP DMA Mem Address L",},
-
- {0xffd0, "0xffd0",0,},
- {0xffd1, "SampleFormat", "SampleFormat",},
- {0xffd2, "0xffd2",0,},
- {0xffd3, "UnkZelda", "Unk Zelda reads/writes from/to it",},
- {0xffd4, "ACSAH", "Accelerator start address H",},
- {0xffd5, "ACSAL", "Accelerator start address L",},
- {0xffd6, "ACEAH", "Accelerator end address H",},
- {0xffd7, "ACEAL", "Accelerator end address L",},
- {0xffd8, "ACCAH", "Accelerator current address H",},
- {0xffd9, "ACCAL", "Accelerator current address L",},
- {0xffda, "pred_scale", "pred_scale",},
- {0xffdb, "yn1", "yn1",},
- {0xffdc, "yn2", "yn2",},
- {0xffdd, "ARAM", "Direct Read from ARAM (uses ADPCM)",},
- {0xffde, "GAIN", "Gain",},
- {0xffdf, "0xffdf", 0,},
-
- {0xffe0, "0xffe0",0,},
- {0xffe1, "0xffe1",0,},
- {0xffe2, "0xffe2",0,},
- {0xffe3, "0xffe3",0,},
- {0xffe4, "0xffe4",0,},
- {0xffe5, "0xffe5",0,},
- {0xffe6, "0xffe6",0,},
- {0xffe7, "0xffe7",0,},
- {0xffe8, "0xffe8",0,},
- {0xffe9, "0xffe9",0,},
- {0xffea, "0xffea",0,},
- {0xffeb, "0xffeb",0,},
- {0xffec, "0xffec",0,},
- {0xffed, "0xffed",0,},
- {0xffee, "0xffee",0,},
- {0xffef, "AMDM", "ARAM DMA Request Mask",},
-
- {0xfff0, "0xfff0",0,},
- {0xfff1, "0xfff1",0,},
- {0xfff2, "0xfff2",0,},
- {0xfff3, "0xfff3",0,},
- {0xfff4, "0xfff4",0,},
- {0xfff5, "0xfff5",0,},
- {0xfff6, "0xfff6",0,},
- {0xfff7, "0xfff7",0,},
- {0xfff8, "0xfff8",0,},
- {0xfff9, "0xfff9",0,},
- {0xfffa, "0xfffa",0,},
- {0xfffb, "DIRQ", "DSP IRQ Request",},
- {0xfffc, "DMBH", "DSP Mailbox H",},
- {0xfffd, "DMBL", "DSP Mailbox L",},
- {0xfffe, "CMBH", "CPU Mailbox H",},
- {0xffff, "CMBL", "CPU Mailbox L",},
-};
-
-const u32 pdlabels_size = sizeof(pdlabels) / sizeof(pdlabel_t);
-
-const pdlabel_t regnames[] =
-{
- {0x00, "AR0", "Addr Reg 00",},
- {0x01, "AR1", "Addr Reg 01",},
- {0x02, "AR2", "Addr Reg 02",},
- {0x03, "AR3", "Addr Reg 03",},
- {0x04, "IX0", "Index Reg 0",},
- {0x05, "IX1", "Index Reg 1",},
- {0x06, "IX2", "Index Reg 2",},
- {0x07, "IX3", "Index Reg 3",},
- {0x08, "WR0", "Wrapping Register 0",},
- {0x09, "WR1", "Wrapping Register 1",},
- {0x0a, "WR2", "Wrapping Register 2",},
- {0x0b, "WR3", "Wrapping Register 3",},
- {0x0c, "ST0", "Call stack",},
- {0x0d, "ST1", "Data stack",},
- {0x0e, "ST2", "Loop addr stack",},
- {0x0f, "ST3", "Loop counter",},
- {0x10, "AC0.H", "Accu High 0",},
- {0x11, "AC1.H", "Accu High 1",},
- {0x12, "CR", "Config Register",},
- {0x13, "SR", "Special Register",},
- {0x14, "PROD.L", "Prod L",},
- {0x15, "PROD.M1", "Prod M1",},
- {0x16, "PROD.H", "Prod H",},
- {0x17, "PROD.M2", "Prod M2",},
- {0x18, "AX0.L", "Extra Accu L 0",},
- {0x19, "AX1.L", "Extra Accu L 1",},
- {0x1a, "AX0.H", "Extra Accu H 0",},
- {0x1b, "AX1.H", "Extra Accu H 1",},
- {0x1c, "AC0.L", "Accu Low 0",},
- {0x1d, "AC1.L", "Accu Low 1",},
- {0x1e, "AC0.M", "Accu Mid 0",},
- {0x1f, "AC1.M", "Accu Mid 1",},
-
- // To resolve combined register names.
- {0x20, "ACC0", "Accu Full 0",},
- {0x21, "ACC1", "Accu Full 1",},
- {0x22, "AX0", "Extra Accu 0",},
- {0x23, "AX1", "Extra Accu 1",},
-};
-
-u8 opSize[OPTABLE_SIZE];
-dspInstFunc opTable[OPTABLE_SIZE];
-dspInstFunc prologueTable[OPTABLE_SIZE];
-dspInstFunc epilogueTable[OPTABLE_SIZE];
-
-const char* pdname(u16 val)
-{
- static char tmpstr[12]; // nasty
-
- for (int i = 0; i < (int)(sizeof(pdlabels) / sizeof(pdlabel_t)); i++)
- {
- if (pdlabels[i].addr == val)
- return pdlabels[i].name;
- }
-
- sprintf(tmpstr, "0x%04x", val);
- return tmpstr;
-}
-
-const char *pdregname(int val)
-{
- return regnames[val].name;
-}
-
-const char *pdregnamelong(int val)
-{
- return regnames[val].description;
-}
-
-const DSPOPCTemplate *GetOpTemplate(const UDSPInstruction &inst)
-{
- for (int i = 0; i < opcodes_size; i++)
- {
- u16 mask = opcodes[i].opcode_mask;
- if (opcodes[i].size & P_EXT) {
- // Ignore extension bits.
- mask &= 0xFF00;
- }
- if ((mask & inst.hex) == opcodes[i].opcode)
- return &opcodes[i];
- }
- return NULL;
-}
-
-
-// This function could use the above GetOpTemplate, but then we'd lose the
-// nice property that it catches colliding op masks.
-void InitInstructionTable()
-{
- for (int i = 0; i < OPTABLE_SIZE; i++)
- {
- opTable[i] = DSPInterpreter::unknown;
- prologueTable[i] = NULL;
- epilogueTable[i] = NULL;
- opSize[i] = 0;
- }
-
- for (int i = 0; i < OPTABLE_SIZE; i++)
- {
- for (int j = 0; j < opcodes_size; j++)
- {
- u16 mask = opcodes[j].opcode_mask;
- if (opcodes[j].size & P_EXT) {
- // Ignore extension bits.
- mask &= 0xFF00;
- }
- if ((mask & i) == opcodes[j].opcode)
- {
- if (opTable[i] == DSPInterpreter::unknown)
- {
- opTable[i] = opcodes[j].interpFunc;
- opSize[i] = opcodes[j].size & 3;
- prologueTable[i] = opcodes[j].prologue;
- epilogueTable[i] = opcodes[j].epilogue;
- }
- else
- {
- ERROR_LOG(DSPLLE, "opcode table place %d already in use for %s", i, opcodes[j].name);
- }
- }
- }
- }
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Additional copyrights go to Duddie (c) 2005 (duddie@walla.com)
+
+/* NOTES BY HERMES:
+
+LZ flag: original opcodes andf and andcf are swaped. Also "jzr" and "jnz" are swaped but now named 'jlz' and 'jlnz'
+As you can see it obtain the same result but now LZ=1 correctly
+
+Added conditional instructions:
+
+conditional names:
+
+NZ -> NOT ZERO
+Z -> ZERO
+
+NS -> NOT SIGN
+S -> SIGN
+
+LZ -> LOGIC ZERO (only used with andcf-andf instructions?)
+LNZ -> LOGIC NOT ZERO
+
+G -> GREATER
+LE-> LESS EQUAL
+
+GE-> GREATER EQUAL
+L -> LESS
+
+Examples:
+
+jnz, ifs, retlnz
+
+*/
+
+
+#include "Common.h"
+#include "DSPTables.h"
+
+#include "DSPInterpreter.h"
+#include "DSPJit.h"
+#include "DSPIntExtOps.h"
+
+void nop(const UDSPInstruction& opc)
+{
+ // The real nop is 0. Anything else is bad.
+ if (opc.hex)
+ DSPInterpreter::unknown(opc);
+}
+
+// Unknown Ops
+// All AX games: a100
+// Zelda Four Swords: 02ca
+
+// TODO: Fill up the tables with the corresponding instructions
+const DSPOPCTemplate opcodes[] =
+{
+ {"NOP", 0x0000, 0xffff, nop, nop, 1, 0, {}, NULL, NULL},
+
+ {"DAR", 0x0004, 0xfffc, DSPInterpreter::dar, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL},
+ {"IAR", 0x0008, 0xfffc, DSPInterpreter::iar, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL},
+
+ {"HALT", 0x0021, 0xffff, DSPInterpreter::halt, nop, 1, 0, {}, NULL, NULL},
+
+ {"RETNS", 0x02d0, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
+ {"RETS", 0x02d1, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
+ {"RETG", 0x02d2, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
+ {"RETLE", 0x02d3, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
+ {"RETNZ", 0x02d4, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
+ {"RETZ", 0x02d5, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
+ {"RETL", 0x02d6, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
+ {"RETGE", 0x02d7, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
+ {"RETLNZ", 0x02dc, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
+ {"RETLZ", 0x02dd, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
+ {"RET", 0x02df, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
+ {"RTI", 0x02ff, 0xffff, DSPInterpreter::rti, nop, 1, 0, {}, NULL, NULL},
+
+ {"CALLNS", 0x02b0, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"CALLS", 0x02b1, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"CALLG", 0x02b2, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"CALLLE", 0x02b3, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"CALLNE", 0x02b4, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"CALLZ", 0x02b5, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"CALLL", 0x02b6, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"CALLGE", 0x02b7, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"CALLLNZ", 0x02bc, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"CALLLZ", 0x02bd, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"CALL", 0x02bf, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+
+ {"IFNS", 0x0270, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
+ {"IFS", 0x0271, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
+ {"IFG", 0x0272, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
+ {"IFLE", 0x0273, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
+ {"IFNZ", 0x0274, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
+ {"IFZ", 0x0275, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
+ {"IFL", 0x0276, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
+ {"IFGE", 0x0277, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
+ {"IFLNZ", 0x027c, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
+ {"IFLZ", 0x027d, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
+ {"IF", 0x027f, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL}, // This is just nop
+
+ {"JNS", 0x0290, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"JS", 0x0291, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"JG", 0x0292, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"JLE", 0x0293, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"JNZ", 0x0294, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"JZ", 0x0295, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"JL", 0x0296, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"JGE", 0x0297, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"JLNZ", 0x029c, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"JLZ", 0x029d, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"JMP", 0x029f, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+
+
+ {"JRNS", 0x1700, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"JRS", 0x1701, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"JRG", 0x1702, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"JRLE", 0x1703, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"JRNZ", 0x1704, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"JRZ", 0x1705, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"JRL", 0x1706, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"JRGE", 0x1707, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"JRLNZ", 0x170c, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"JRLZ", 0x170d, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"JMPR", 0x170f, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+
+ {"CALLRNS", 0x1710, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"CALLRS", 0x1711, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"CALLRG", 0x1712, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"CALLRLE", 0x1713, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"CALLRNZ", 0x1714, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"CALLRZ", 0x1715, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"CALLRL", 0x1716, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"CALLRGE", 0x1717, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"CALLRLNZ",0x171c, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"CALLRLZ", 0x171d, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"CALLR", 0x171f, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+
+ {"SBCLR", 0x1200, 0xfff8, DSPInterpreter::sbclr, nop, 1, 1, {{P_IMM, 1, 0, 0, 0x0007}}, NULL, NULL},
+ {"SBSET", 0x1300, 0xfff8, DSPInterpreter::sbset, nop, 1, 1, {{P_IMM, 1, 0, 0, 0x0007}}, NULL, NULL},
+
+ // actually, given the masks these should probably be 0x3f. need investigation.
+ {"LSL", 0x1400, 0xfec0, DSPInterpreter::lsl, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, NULL, NULL},
+ {"LSR", 0x1440, 0xfec0, DSPInterpreter::lsr, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, NULL, NULL},
+ {"ASL", 0x1480, 0xfec0, DSPInterpreter::asl, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, NULL, NULL},
+ {"ASR", 0x14c0, 0xfec0, DSPInterpreter::asr, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, NULL, NULL},
+
+ // discovered by ector!
+ {"LSRN", 0x02ca, 0xffff, DSPInterpreter::lsrn, nop, 1, 0, {}, NULL, NULL},
+ {"ASRN", 0x02cb, 0xffff, DSPInterpreter::asrn, nop, 1, 0, {}, NULL, NULL},
+
+ {"LRI", 0x0080, 0xffe0, DSPInterpreter::lri, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"LR", 0x00c0, 0xffe0, DSPInterpreter::lr, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_MEM, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"SR", 0x00e0, 0xffe0, DSPInterpreter::sr, nop, 2, 2, {{P_MEM, 2, 1, 0, 0xffff}, {P_REG, 1, 0, 0, 0x001f}}, NULL, NULL},
+
+ {"MRR", 0x1c00, 0xfc00, DSPInterpreter::mrr, nop, 1, 2, {{P_REG, 1, 0, 5, 0x03e0}, {P_REG, 1, 0, 0, 0x001f}}, NULL, NULL},
+
+ {"SI", 0x1600, 0xff00, DSPInterpreter::si, nop, 2, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
+
+ {"LRS", 0x2000, 0xf800, DSPInterpreter::lrs, nop, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_MEM, 1, 0, 0, 0x00ff}}, NULL, NULL},
+ {"SRS", 0x2800, 0xf800, DSPInterpreter::srs, nop, 1, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_REG18, 1, 0, 8, 0x0700}}, NULL, NULL},
+
+ {"LRIS", 0x0800, 0xf800, DSPInterpreter::lris, nop, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_IMM, 1, 0, 0, 0x00ff}}, NULL, NULL},
+
+ {"ADDIS", 0x0400, 0xfe00, DSPInterpreter::addis, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}}, NULL, NULL},
+ {"CMPIS", 0x0600, 0xfe00, DSPInterpreter::cmpis, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}}, NULL, NULL},
+ {"ANDI", 0x0240, 0xfeff, DSPInterpreter::andi, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL,},
+ {"ANDCF", 0x02c0, 0xfeff, DSPInterpreter::andcf, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL,},
+
+ {"XORI", 0x0220, 0xfeff, DSPInterpreter::xori, nop, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"ANDF", 0x02a0, 0xfeff, DSPInterpreter::andf, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
+
+ {"ORI", 0x0260, 0xfeff, DSPInterpreter::ori, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"ORF", 0x02e0, 0xfeff, DSPInterpreter::orf, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL}, // Hermes: ??? (has it commented out)
+
+ {"ADDI", 0x0200, 0xfeff, DSPInterpreter::addi, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL}, // F|RES: missing S64
+ {"CMPI", 0x0280, 0xfeff, DSPInterpreter::cmpi, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
+
+ {"ILRR", 0x0210, 0xfedc, DSPInterpreter::ilrr, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL},
+ {"ILRRD", 0x0214, 0xfedc, DSPInterpreter::ilrrd, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL}, // Hermes doesn't list this
+ {"ILRRI", 0x0218, 0xfedc, DSPInterpreter::ilrri, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL},
+ {"ILRRN", 0x0222, 0xfedc, DSPInterpreter::ilrrn, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL},
+
+ // load and store value pointed by indexing reg and increment; LRR/SRR variants
+ {"LRR", 0x1800, 0xff80, DSPInterpreter::lrr, nop, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}}, NULL, NULL},
+ {"LRRD", 0x1880, 0xff80, DSPInterpreter::lrrd, nop, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}}, NULL, NULL},
+ {"LRRI", 0x1900, 0xff80, DSPInterpreter::lrri, nop, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}}, NULL, NULL},
+ {"LRRN", 0x1980, 0xff80, DSPInterpreter::lrrn, nop, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}}, NULL, NULL},
+
+ {"SRR", 0x1a00, 0xff80, DSPInterpreter::srr, nop, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}}, NULL, NULL},
+ {"SRRD", 0x1a80, 0xff80, DSPInterpreter::srrd, nop, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}}, NULL, NULL},
+ {"SRRI", 0x1b00, 0xff80, DSPInterpreter::srri, nop, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}}, NULL, NULL},
+ {"SRRN", 0x1b80, 0xff80, DSPInterpreter::srrn, nop, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}}, NULL, NULL},
+
+ // LOOPS
+ {"LOOP", 0x0040, 0xffe0, DSPInterpreter::loop, nop, 1, 1, {{P_REG, 1, 0, 0, 0x001f}}, NULL, NULL},
+ {"BLOOP", 0x0060, 0xffe0, DSPInterpreter::bloop, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+ {"LOOPI", 0x1000, 0xff00, DSPInterpreter::loopi, nop, 1, 1, {{P_IMM, 1, 0, 0, 0x00ff}}, NULL, NULL},
+ {"BLOOPI", 0x1100, 0xff00, DSPInterpreter::bloopi, nop, 2, 2, {{P_IMM, 1, 0, 0, 0x00ff}, {P_ADDR_I, 2, 1, 0, 0xffff}}, NULL, NULL},
+
+ {"ADDARN", 0x0010, 0xfff0, DSPInterpreter::addarn, nop, 1, 2, {{P_REG, 1, 0, 0, 0x0003}, {P_REG04, 1, 0, 2, 0x000c}}, NULL, NULL},
+
+
+ // opcodes that can be extended
+ // extended opcodes, note size of opcode will be set to 0
+
+ {"NX", 0x8000, 0xf700, DSPInterpreter::nx, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"M2", 0x8a00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"M0", 0x8b00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+
+ {"CLR15", 0x8c00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"SET15", 0x8d00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+
+ {"SET16", 0x8e00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"SET40", 0x8f00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+
+
+ {"INCM", 0x7400, 0xfeff, DSPInterpreter::incm, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"INC", 0x7600, 0xfeff, DSPInterpreter::inc, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"DECM", 0x7800, 0xfeff, DSPInterpreter::decm, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"DEC", 0x7a00, 0xfeff, DSPInterpreter::dec, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"NEG", 0x7c00, 0xfeff, DSPInterpreter::neg, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MOVNP", 0x7e00, 0xfeff, DSPInterpreter::movnp, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+
+
+ {"TST", 0xb100, 0xf7ff, DSPInterpreter::tst, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+
+ // Definitely not TSTAXL, it affects one of the accumulators. (a100 or a900, same op, one parameter).
+ {"TSTAXL", 0xa100, 0xffff, DSPInterpreter::tstaxl, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+
+ {"TSTAXH", 0x8600, 0xfeff, DSPInterpreter::tstaxh, nop, 1 | P_EXT, 1, {{P_REG1A, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+
+ {"CMP", 0x8200, 0xffff, DSPInterpreter::cmp, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+
+ // This op does NOT exist, at least not under this name, in duddie's docs!
+ {"CMPAR" , 0xc100, 0xe7ff, DSPInterpreter::cmpar, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+
+ {"CLRL", 0xfc00, 0xffff, DSPInterpreter::clrl, nop, 1 | P_EXT, 1, {{P_ACCL, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // clear acl0
+ {"CLR", 0x8100, 0xf7ff, DSPInterpreter::clr, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // clear acc0
+ {"CLRP", 0x8400, 0xffff, DSPInterpreter::clrp, nop, 1 | P_EXT, 0, {}, },
+
+ {"MOV", 0x6c00, 0xfeff, DSPInterpreter::mov, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_ACC_D, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MOVAX", 0x6800, 0xfcff, DSPInterpreter::movax, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MOVR", 0x6000, 0xf8ff, DSPInterpreter::movr, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MOVP", 0x6e00, 0xfeff, DSPInterpreter::movp, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MOVPZ", 0xfe00, 0xfeff, DSPInterpreter::movpz, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+
+ {"ADDPAXZ", 0xf800, 0xfcff, DSPInterpreter::addpaxz, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 9, 0x0200}, {P_REG1A, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, //Think the args are wrong
+ {"ADDP", 0x4e00, 0xfeff, DSPInterpreter::addp, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+
+ {"LSL16", 0xf000, 0xfeff, DSPInterpreter::lsl16, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"LSR16", 0xf400, 0xfeff, DSPInterpreter::lsr16, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"ASR16", 0x9100, 0xf7ff, DSPInterpreter::asr16, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+
+ {"XORR", 0x3000, 0xfcff, DSPInterpreter::xorr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"ANDR", 0x3400, 0xfcff, DSPInterpreter::andr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"ORR", 0x3800, 0xfcff, DSPInterpreter::orr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"ANDC", 0x3C00, 0xfeff, DSPInterpreter::andc, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // Hermes doesn't list this
+ {"ORC", 0x3E00, 0xfeff, DSPInterpreter::orc, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // Hermes doesn't list this
+
+ {"MULX", 0xa000, 0xe7ff, DSPInterpreter::mulx, nop, 1 | P_EXT, 2, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MULXMVZ", 0xa200, 0xe6ff, DSPInterpreter::mulxmvz, nop, 1 | P_EXT, 3, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MULXAC", 0xa400, 0xe6ff, DSPInterpreter::mulxac, nop, 1 | P_EXT, 3, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MULXMV", 0xa600, 0xe6ff, DSPInterpreter::mulxmv, nop, 1 | P_EXT, 3, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+
+ {"MUL", 0x9000, 0xf7ff, DSPInterpreter::mul, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MULMVZ", 0x9200, 0xf6ff, DSPInterpreter::mulmvz, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MULAC", 0x9400, 0xf6ff, DSPInterpreter::mulac, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MULMV", 0x9600, 0xf6ff, DSPInterpreter::mulmv, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+
+ {"MULC", 0xc000, 0xe7ff, DSPInterpreter::mulc, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MULCMVZ", 0xc200, 0xe6ff, DSPInterpreter::mulcmvz, nop, 1 | P_EXT, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MULCAC", 0xc400, 0xe6ff, DSPInterpreter::mulcac, nop, 1 | P_EXT, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MULCMV", 0xc600, 0xe6ff, DSPInterpreter::mulcmv, nop, 1 | P_EXT, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+
+ {"ADDR", 0x4000, 0xf8ff, DSPInterpreter::addr, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"ADDAX", 0x4800, 0xfcff, DSPInterpreter::addax, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"ADD", 0x4c00, 0xfeff, DSPInterpreter::add, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_ACC_D, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"ADDAXL", 0x7000, 0xfcff, DSPInterpreter::addaxl, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+
+ {"SUBR", 0x5000, 0xf8ff, DSPInterpreter::subr, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"SUBAX", 0x5800, 0xfcff, DSPInterpreter::subax, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"SUB", 0x5c00, 0xfeff, DSPInterpreter::sub, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_ACC_D, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"SUBP", 0x5e00, 0xfeff, DSPInterpreter::subp, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+
+ {"MADD", 0xf200, 0xfeff, DSPInterpreter::madd, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MSUB", 0xf600, 0xfeff, DSPInterpreter::msub , nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MADDX", 0xe000, 0xfcff, DSPInterpreter::maddx, nop, 1 | P_EXT, 2, {{P_REGM18, 1, 0, 8, 0x0200}, {P_REGM19, 1, 0, 7, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MSUBX", 0xe400, 0xfcff, DSPInterpreter::msubx, nop, 1 | P_EXT, 2, {{P_REGM18, 1, 0, 8, 0x0200}, {P_REGM19, 1, 0, 7, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MADDC", 0xe800, 0xfcff, DSPInterpreter::maddc, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+ {"MSUBC", 0xec00, 0xfcff, DSPInterpreter::msubc, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
+};
+
+const DSPOPCTemplate cw =
+ {"CW", 0x0000, 0x0000, nop, nop, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}}, NULL, NULL,};
+
+
+const DSPOPCTemplate opcodes_ext[] =
+{
+ // FIXME: guessing this is cr need checking
+ {"DR", 0x0004, 0x00fc, nop, /*DSPInterpreter::Ext::dr*/ nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
+ {"IR", 0x0008, 0x00fc, nop, /*DSPInterpreter::Ext::ir*/ nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
+ {"NR", 0x000c, 0x00fc, nop, /*DSPInterpreter::Ext::nr*/ nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
+ {"MV", 0x0010, 0x00f0, nop, /*DSPInterpreter::Ext::mv*/ nop, 1, 2, {{P_REG18, 1, 0, 2, 0x000c}, {P_REG1C, 1, 0, 0, 0x0003}}, NULL, NULL,},
+
+ {"S", 0x0020, 0x00e4, nop, /*DSPInterpreter::Ext::s*/ nop, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}}, NULL, NULL,},
+ {"SN", 0x0024, 0x00e4, nop, /*DSPInterpreter::Ext::sn*/ nop, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}}, NULL, NULL,},
+
+ {"L", 0x0040, 0x00c4, nop, /*DSPInterpreter::Ext::l*/ nop, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
+ {"LN", 0x0044, 0x00c4, nop, /*DSPInterpreter::Ext::ln*/ nop, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
+
+ {"LS", 0x0080, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}}, NULL, NULL,},
+ {"SL", 0x0082, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}}, NULL, NULL,},
+ {"LSN", 0x0084, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}}, NULL, NULL,},
+ {"SLN", 0x0086, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}}, NULL, NULL,},
+ {"LSM", 0x0088, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}}, NULL, NULL,},
+ {"SLM", 0x008a, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}}, NULL, NULL,},
+ {"LSNM", 0x008c, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}}, NULL, NULL,},
+ {"SLNM", 0x008e, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}}, NULL, NULL,},
+
+ /* FIXME: what are the LDX functions for? they have the same opcode as LD ones but different mask
+ {"LDX", 0x00c0, 0x00cf, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}}, NULL, NULL,},
+ {"LDXN", 0x00c4, 0x00cf, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}}, NULL, NULL,},
+ {"LDXM", 0x00c8, 0x00cf, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}}, NULL, NULL,},
+ {"LDXNM", 0x00cc, 0x00cf, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}}, NULL, NULL,},*/
+
+ {"LD", 0x00c0, 0x00cc, nop, /*DSPInterpreter::Ext::ld*/ nop, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
+ {"LDN", 0x00c4, 0x00cc, nop, /*DSPInterpreter::Ext::ldn*/ nop, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
+ {"LDM", 0x00c8, 0x00cc, nop, /*DSPInterpreter::Ext::ldm*/ nop, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
+ {"LDNM", 0x00cc, 0x00cc, nop, /*DSPInterpreter::Ext::ldnm*/ nop, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
+
+ {"XXX", 0x0000, 0x0000, nop, nop, 1, 1, {{P_VAL, 1, 0, 0, 0x00ff}}, NULL, NULL,},
+};
+
+const int opcodes_size = sizeof(opcodes) / sizeof(DSPOPCTemplate);
+const int opcodes_ext_size = sizeof(opcodes_ext) / sizeof(DSPOPCTemplate);
+
+const pdlabel_t pdlabels[] =
+{
+ {0xffa0, "COEF_A1_0", "COEF_A1_0",},
+ {0xffa1, "COEF_A2_0", "COEF_A2_0",},
+ {0xffa2, "COEF_A1_1", "COEF_A1_1",},
+ {0xffa3, "COEF_A2_1", "COEF_A2_1",},
+ {0xffa4, "COEF_A1_2", "COEF_A1_2",},
+ {0xffa5, "COEF_A2_2", "COEF_A2_2",},
+ {0xffa6, "COEF_A1_3", "COEF_A1_3",},
+ {0xffa7, "COEF_A2_3", "COEF_A2_3",},
+ {0xffa8, "COEF_A1_4", "COEF_A1_4",},
+ {0xffa9, "COEF_A2_4", "COEF_A2_4",},
+ {0xffaa, "COEF_A1_5", "COEF_A1_5",},
+ {0xffab, "COEF_A2_5", "COEF_A2_5",},
+ {0xffac, "COEF_A1_6", "COEF_A1_6",},
+ {0xffad, "COEF_A2_6", "COEF_A2_6",},
+ {0xffae, "COEF_A1_7", "COEF_A1_7",},
+ {0xffaf, "COEF_A2_7", "COEF_A2_7",},
+
+ {0xffb0, "0xffb0", 0,},
+ {0xffb1, "0xffb1", 0,},
+ {0xffb2, "0xffb2", 0,},
+ {0xffb3, "0xffb3", 0,},
+ {0xffb4, "0xffb4", 0,},
+ {0xffb5, "0xffb5", 0,},
+ {0xffb6, "0xffb6", 0,},
+ {0xffb7, "0xffb7", 0,},
+ {0xffb8, "0xffb8", 0,},
+ {0xffb9, "0xffb9", 0,},
+ {0xffba, "0xffba", 0,},
+ {0xffbb, "0xffbb", 0,},
+ {0xffbc, "0xffbc", 0,},
+ {0xffbd, "0xffbd", 0,},
+ {0xffbe, "0xffbe", 0,},
+ {0xffbf, "0xffbf", 0,},
+
+ {0xffc0, "0xffc0", 0,},
+ {0xffc1, "0xffc1", 0,},
+ {0xffc2, "0xffc2", 0,},
+ {0xffc3, "0xffc3", 0,},
+ {0xffc4, "0xffc4", 0,},
+ {0xffc5, "0xffc5", 0,},
+ {0xffc6, "0xffc6", 0,},
+ {0xffc7, "0xffc7", 0,},
+ {0xffc8, "0xffc8", 0,},
+ {0xffc9, "DSCR", "DSP DMA Control Reg",},
+ {0xffca, "0xffca", 0,},
+ {0xffcb, "DSBL", "DSP DMA Block Length",},
+ {0xffcc, "0xffcc", 0,},
+ {0xffcd, "DSPA", "DSP DMA DMEM Address",},
+ {0xffce, "DSMAH", "DSP DMA Mem Address H",},
+ {0xffcf, "DSMAL", "DSP DMA Mem Address L",},
+
+ {0xffd0, "0xffd0",0,},
+ {0xffd1, "SampleFormat", "SampleFormat",},
+ {0xffd2, "0xffd2",0,},
+ {0xffd3, "UnkZelda", "Unk Zelda reads/writes from/to it",},
+ {0xffd4, "ACSAH", "Accelerator start address H",},
+ {0xffd5, "ACSAL", "Accelerator start address L",},
+ {0xffd6, "ACEAH", "Accelerator end address H",},
+ {0xffd7, "ACEAL", "Accelerator end address L",},
+ {0xffd8, "ACCAH", "Accelerator current address H",},
+ {0xffd9, "ACCAL", "Accelerator current address L",},
+ {0xffda, "pred_scale", "pred_scale",},
+ {0xffdb, "yn1", "yn1",},
+ {0xffdc, "yn2", "yn2",},
+ {0xffdd, "ARAM", "Direct Read from ARAM (uses ADPCM)",},
+ {0xffde, "GAIN", "Gain",},
+ {0xffdf, "0xffdf", 0,},
+
+ {0xffe0, "0xffe0",0,},
+ {0xffe1, "0xffe1",0,},
+ {0xffe2, "0xffe2",0,},
+ {0xffe3, "0xffe3",0,},
+ {0xffe4, "0xffe4",0,},
+ {0xffe5, "0xffe5",0,},
+ {0xffe6, "0xffe6",0,},
+ {0xffe7, "0xffe7",0,},
+ {0xffe8, "0xffe8",0,},
+ {0xffe9, "0xffe9",0,},
+ {0xffea, "0xffea",0,},
+ {0xffeb, "0xffeb",0,},
+ {0xffec, "0xffec",0,},
+ {0xffed, "0xffed",0,},
+ {0xffee, "0xffee",0,},
+ {0xffef, "AMDM", "ARAM DMA Request Mask",},
+
+ {0xfff0, "0xfff0",0,},
+ {0xfff1, "0xfff1",0,},
+ {0xfff2, "0xfff2",0,},
+ {0xfff3, "0xfff3",0,},
+ {0xfff4, "0xfff4",0,},
+ {0xfff5, "0xfff5",0,},
+ {0xfff6, "0xfff6",0,},
+ {0xfff7, "0xfff7",0,},
+ {0xfff8, "0xfff8",0,},
+ {0xfff9, "0xfff9",0,},
+ {0xfffa, "0xfffa",0,},
+ {0xfffb, "DIRQ", "DSP IRQ Request",},
+ {0xfffc, "DMBH", "DSP Mailbox H",},
+ {0xfffd, "DMBL", "DSP Mailbox L",},
+ {0xfffe, "CMBH", "CPU Mailbox H",},
+ {0xffff, "CMBL", "CPU Mailbox L",},
+};
+
+const u32 pdlabels_size = sizeof(pdlabels) / sizeof(pdlabel_t);
+
+const pdlabel_t regnames[] =
+{
+ {0x00, "AR0", "Addr Reg 00",},
+ {0x01, "AR1", "Addr Reg 01",},
+ {0x02, "AR2", "Addr Reg 02",},
+ {0x03, "AR3", "Addr Reg 03",},
+ {0x04, "IX0", "Index Reg 0",},
+ {0x05, "IX1", "Index Reg 1",},
+ {0x06, "IX2", "Index Reg 2",},
+ {0x07, "IX3", "Index Reg 3",},
+ {0x08, "WR0", "Wrapping Register 0",},
+ {0x09, "WR1", "Wrapping Register 1",},
+ {0x0a, "WR2", "Wrapping Register 2",},
+ {0x0b, "WR3", "Wrapping Register 3",},
+ {0x0c, "ST0", "Call stack",},
+ {0x0d, "ST1", "Data stack",},
+ {0x0e, "ST2", "Loop addr stack",},
+ {0x0f, "ST3", "Loop counter",},
+ {0x10, "AC0.H", "Accu High 0",},
+ {0x11, "AC1.H", "Accu High 1",},
+ {0x12, "CR", "Config Register",},
+ {0x13, "SR", "Special Register",},
+ {0x14, "PROD.L", "Prod L",},
+ {0x15, "PROD.M1", "Prod M1",},
+ {0x16, "PROD.H", "Prod H",},
+ {0x17, "PROD.M2", "Prod M2",},
+ {0x18, "AX0.L", "Extra Accu L 0",},
+ {0x19, "AX1.L", "Extra Accu L 1",},
+ {0x1a, "AX0.H", "Extra Accu H 0",},
+ {0x1b, "AX1.H", "Extra Accu H 1",},
+ {0x1c, "AC0.L", "Accu Low 0",},
+ {0x1d, "AC1.L", "Accu Low 1",},
+ {0x1e, "AC0.M", "Accu Mid 0",},
+ {0x1f, "AC1.M", "Accu Mid 1",},
+
+ // To resolve combined register names.
+ {0x20, "ACC0", "Accu Full 0",},
+ {0x21, "ACC1", "Accu Full 1",},
+ {0x22, "AX0", "Extra Accu 0",},
+ {0x23, "AX1", "Extra Accu 1",},
+};
+
+u8 opSize[OPTABLE_SIZE];
+dspInstFunc opTable[OPTABLE_SIZE];
+dspInstFunc prologueTable[OPTABLE_SIZE];
+dspInstFunc epilogueTable[OPTABLE_SIZE];
+
+const char* pdname(u16 val)
+{
+ static char tmpstr[12]; // nasty
+
+ for (int i = 0; i < (int)(sizeof(pdlabels) / sizeof(pdlabel_t)); i++)
+ {
+ if (pdlabels[i].addr == val)
+ return pdlabels[i].name;
+ }
+
+ sprintf(tmpstr, "0x%04x", val);
+ return tmpstr;
+}
+
+const char *pdregname(int val)
+{
+ return regnames[val].name;
+}
+
+const char *pdregnamelong(int val)
+{
+ return regnames[val].description;
+}
+
+const DSPOPCTemplate *GetOpTemplate(const UDSPInstruction &inst)
+{
+ for (int i = 0; i < opcodes_size; i++)
+ {
+ u16 mask = opcodes[i].opcode_mask;
+ if (opcodes[i].size & P_EXT) {
+ // Ignore extension bits.
+ mask &= 0xFF00;
+ }
+ if ((mask & inst.hex) == opcodes[i].opcode)
+ return &opcodes[i];
+ }
+ return NULL;
+}
+
+
+// This function could use the above GetOpTemplate, but then we'd lose the
+// nice property that it catches colliding op masks.
+void InitInstructionTable()
+{
+ for (int i = 0; i < OPTABLE_SIZE; i++)
+ {
+ opTable[i] = DSPInterpreter::unknown;
+ prologueTable[i] = NULL;
+ epilogueTable[i] = NULL;
+ opSize[i] = 0;
+ }
+
+ for (int i = 0; i < OPTABLE_SIZE; i++)
+ {
+ for (int j = 0; j < opcodes_size; j++)
+ {
+ u16 mask = opcodes[j].opcode_mask;
+ if (opcodes[j].size & P_EXT) {
+ // Ignore extension bits.
+ mask &= 0xFF00;
+ }
+ if ((mask & i) == opcodes[j].opcode)
+ {
+ if (opTable[i] == DSPInterpreter::unknown)
+ {
+ opTable[i] = opcodes[j].interpFunc;
+ opSize[i] = opcodes[j].size & 3;
+ prologueTable[i] = opcodes[j].prologue;
+ epilogueTable[i] = opcodes[j].epilogue;
+ }
+ else
+ {
+ ERROR_LOG(DSPLLE, "opcode table place %d already in use for %s", i, opcodes[j].name);
+ }
+ }
+ }
+ }
+}
diff --git a/Source/Core/DSPCore/Src/DSPTables.h b/Source/Core/DSPCore/Src/DSPTables.h
index 8e0f66207c..a56a112b72 100644
--- a/Source/Core/DSPCore/Src/DSPTables.h
+++ b/Source/Core/DSPCore/Src/DSPTables.h
@@ -1,168 +1,168 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-// Additional copyrights go to Duddie (c) 2005 (duddie@walla.com)
-
-#ifndef _DSPTABLES_H
-#define _DSPTABLES_H
-
-#include "Common.h"
-
-// The non-ADDR ones that end with _D are the opposite one - if the bit specify
-// ACC0, then ACC_D will be ACC1.
-
-// The values of these are very important.
-// For the reg ones, the value >> 8 is the base register.
-// & 0x80 means it's a "D".
-
-enum partype_t
-{
- P_NONE = 0x0000,
- P_VAL = 0x0001,
- P_IMM = 0x0002,
- P_MEM = 0x0003,
- P_STR = 0x0004,
- P_ADDR_I = 0x0005,
- P_ADDR_D = 0x0006,
- P_REG = 0x8000,
- P_REG04 = P_REG | 0x0400, // IX
- P_REG08 = P_REG | 0x0800,
- P_REG18 = P_REG | 0x1800,
- P_REGM18 = P_REG | 0x1810, // used in multiply instructions
- P_REG19 = P_REG | 0x1900,
- P_REGM19 = P_REG | 0x1910, // used in multiply instructions
- P_REG1A = P_REG | 0x1a80,
- P_REG1C = P_REG | 0x1c00,
-// P_ACC = P_REG | 0x1c10, // used for global accum (gcdsptool's value)
- P_ACC_D = P_REG | 0x1c80,
- P_ACCL = P_REG | 0x1c00, // used for low part of accum
- P_ACCM = P_REG | 0x1e00, // used for mid part of accum
- // The following are not in gcdsptool
- P_ACCM_D = P_REG | 0x1e80,
- P_ACC = P_REG | 0x2000, // used for full accum.
- P_AX = P_REG | 0x2200,
- P_REGS_MASK = 0x03f80, // gcdsptool's value = 0x01f80
- P_REF = P_REG | 0x4000,
- P_PRG = P_REF | P_REG,
-
- // The following seem like junk:
- // P_REG10 = P_REG | 0x1000,
- // P_AX_D = P_REG | 0x2280,
-};
-
-#define P_EXT 0x80
-
-#define OPTABLE_SIZE 65536
-
-union UDSPInstruction
-{
- u16 hex;
-
- UDSPInstruction(u16 _hex) { hex = _hex; }
- UDSPInstruction() { hex = 0; }
-
- struct
- {
- signed shift : 6;
- unsigned negating : 1;
- unsigned arithmetic : 1;
- unsigned areg : 1;
- unsigned op : 7;
- };
- struct
- {
- unsigned ushift : 6;
- };
-
- // TODO: Figure out more instruction structures (add structs here)
-};
-
-typedef void (*dspInstFunc)(const UDSPInstruction&);
-
-struct param2_t
-{
- partype_t type;
- u8 size;
- u8 loc;
- s8 lshift;
- u16 mask;
-};
-
-typedef struct
-{
- const char *name;
- u16 opcode;
- u16 opcode_mask;
-
- dspInstFunc interpFunc;
- dspInstFunc jitFunc;
-
- u8 size;
- u8 param_count;
- param2_t params[8];
- dspInstFunc prologue;
- dspInstFunc epilogue;
-} DSPOPCTemplate;
-
-typedef DSPOPCTemplate opc_t;
-
-// Opcodes
-extern const DSPOPCTemplate opcodes[];
-extern const int opcodes_size;
-extern const DSPOPCTemplate opcodes_ext[];
-extern const int opcodes_ext_size;
-extern u8 opSize[OPTABLE_SIZE];
-extern const DSPOPCTemplate cw;
-
-extern dspInstFunc opTable[];
-extern dspInstFunc prologueTable[OPTABLE_SIZE];
-extern dspInstFunc epilogueTable[OPTABLE_SIZE];
-
-// Predefined labels
-struct pdlabel_t
-{
- u16 addr;
- const char* name;
- const char* description;
-};
-
-extern const pdlabel_t regnames[];
-extern const pdlabel_t pdlabels[];
-extern const u32 pdlabels_size;
-
-const char *pdname(u16 val);
-const char *pdregname(int val);
-const char *pdregnamelong(int val);
-
-void InitInstructionTable();
-
-inline void ExecuteInstruction(const UDSPInstruction& inst)
-{
- // TODO: Move the prologuetable calls into the relevant instructions themselves.
- // Better not do things like this until things work correctly though.
- if (prologueTable[inst.hex])
- prologueTable[inst.hex](inst);
- opTable[inst.hex](inst);
- if (epilogueTable[inst.hex])
- epilogueTable[inst.hex](inst);
-}
-
-// This one's pretty slow, try to use it only at init or seldomly.
-// returns NULL if no matching instruction.
-const DSPOPCTemplate *GetOpTemplate(const UDSPInstruction &inst);
-
-#endif // _DSPTABLES_H
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Additional copyrights go to Duddie (c) 2005 (duddie@walla.com)
+
+#ifndef _DSPTABLES_H
+#define _DSPTABLES_H
+
+#include "Common.h"
+
+// The non-ADDR ones that end with _D are the opposite one - if the bit specify
+// ACC0, then ACC_D will be ACC1.
+
+// The values of these are very important.
+// For the reg ones, the value >> 8 is the base register.
+// & 0x80 means it's a "D".
+
+enum partype_t
+{
+ P_NONE = 0x0000,
+ P_VAL = 0x0001,
+ P_IMM = 0x0002,
+ P_MEM = 0x0003,
+ P_STR = 0x0004,
+ P_ADDR_I = 0x0005,
+ P_ADDR_D = 0x0006,
+ P_REG = 0x8000,
+ P_REG04 = P_REG | 0x0400, // IX
+ P_REG08 = P_REG | 0x0800,
+ P_REG18 = P_REG | 0x1800,
+ P_REGM18 = P_REG | 0x1810, // used in multiply instructions
+ P_REG19 = P_REG | 0x1900,
+ P_REGM19 = P_REG | 0x1910, // used in multiply instructions
+ P_REG1A = P_REG | 0x1a80,
+ P_REG1C = P_REG | 0x1c00,
+// P_ACC = P_REG | 0x1c10, // used for global accum (gcdsptool's value)
+ P_ACC_D = P_REG | 0x1c80,
+ P_ACCL = P_REG | 0x1c00, // used for low part of accum
+ P_ACCM = P_REG | 0x1e00, // used for mid part of accum
+ // The following are not in gcdsptool
+ P_ACCM_D = P_REG | 0x1e80,
+ P_ACC = P_REG | 0x2000, // used for full accum.
+ P_AX = P_REG | 0x2200,
+ P_REGS_MASK = 0x03f80, // gcdsptool's value = 0x01f80
+ P_REF = P_REG | 0x4000,
+ P_PRG = P_REF | P_REG,
+
+ // The following seem like junk:
+ // P_REG10 = P_REG | 0x1000,
+ // P_AX_D = P_REG | 0x2280,
+};
+
+#define P_EXT 0x80
+
+#define OPTABLE_SIZE 65536
+
+union UDSPInstruction
+{
+ u16 hex;
+
+ UDSPInstruction(u16 _hex) { hex = _hex; }
+ UDSPInstruction() { hex = 0; }
+
+ struct
+ {
+ signed shift : 6;
+ unsigned negating : 1;
+ unsigned arithmetic : 1;
+ unsigned areg : 1;
+ unsigned op : 7;
+ };
+ struct
+ {
+ unsigned ushift : 6;
+ };
+
+ // TODO: Figure out more instruction structures (add structs here)
+};
+
+typedef void (*dspInstFunc)(const UDSPInstruction&);
+
+struct param2_t
+{
+ partype_t type;
+ u8 size;
+ u8 loc;
+ s8 lshift;
+ u16 mask;
+};
+
+typedef struct
+{
+ const char *name;
+ u16 opcode;
+ u16 opcode_mask;
+
+ dspInstFunc interpFunc;
+ dspInstFunc jitFunc;
+
+ u8 size;
+ u8 param_count;
+ param2_t params[8];
+ dspInstFunc prologue;
+ dspInstFunc epilogue;
+} DSPOPCTemplate;
+
+typedef DSPOPCTemplate opc_t;
+
+// Opcodes
+extern const DSPOPCTemplate opcodes[];
+extern const int opcodes_size;
+extern const DSPOPCTemplate opcodes_ext[];
+extern const int opcodes_ext_size;
+extern u8 opSize[OPTABLE_SIZE];
+extern const DSPOPCTemplate cw;
+
+extern dspInstFunc opTable[];
+extern dspInstFunc prologueTable[OPTABLE_SIZE];
+extern dspInstFunc epilogueTable[OPTABLE_SIZE];
+
+// Predefined labels
+struct pdlabel_t
+{
+ u16 addr;
+ const char* name;
+ const char* description;
+};
+
+extern const pdlabel_t regnames[];
+extern const pdlabel_t pdlabels[];
+extern const u32 pdlabels_size;
+
+const char *pdname(u16 val);
+const char *pdregname(int val);
+const char *pdregnamelong(int val);
+
+void InitInstructionTable();
+
+inline void ExecuteInstruction(const UDSPInstruction& inst)
+{
+ // TODO: Move the prologuetable calls into the relevant instructions themselves.
+ // Better not do things like this until things work correctly though.
+ if (prologueTable[inst.hex])
+ prologueTable[inst.hex](inst);
+ opTable[inst.hex](inst);
+ if (epilogueTable[inst.hex])
+ epilogueTable[inst.hex](inst);
+}
+
+// This one's pretty slow, try to use it only at init or seldomly.
+// returns NULL if no matching instruction.
+const DSPOPCTemplate *GetOpTemplate(const UDSPInstruction &inst);
+
+#endif // _DSPTABLES_H
diff --git a/Source/Core/DSPCore/Src/DspIntArithmetic.cpp b/Source/Core/DSPCore/Src/DspIntArithmetic.cpp
index 83b7791516..45b16ddf16 100644
--- a/Source/Core/DSPCore/Src/DspIntArithmetic.cpp
+++ b/Source/Core/DSPCore/Src/DspIntArithmetic.cpp
@@ -1,734 +1,734 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-// Additional copyrights go to Duddie and Tratax (c) 2004
-
-#include "DSPInterpreter.h"
-#include "DSPIntCCUtil.h"
-#include "DSPIntUtil.h"
-
-// Arithmetic and accumulator control.
-
-namespace DSPInterpreter {
-
-// CLR $acR
-// 1000 r001 xxxx xxxx
-// Clears accumulator $acR
-void clr(const UDSPInstruction& opc)
-{
- u8 reg = (opc.hex >> 11) & 0x1;
-
- dsp_set_long_acc(reg, 0);
-
- Update_SR_Register64((s64)0); // really?
-}
-
-// CLRL $acR.l
-// 1111 110r xxxx xxxx
-// Clears $acR.l - low 16 bits of accumulator $acR.
-void clrl(const UDSPInstruction& opc)
-{
- u16 reg = DSP_REG_ACL0 + ((opc.hex >> 11) & 0x1);
- g_dsp.r[reg] = 0;
-
- // Should this be 64bit?
- // nakee: it says the whole reg in duddie's doc sounds weird
- Update_SR_Register64((s64)reg);
-}
-
-
-// ADDAXL $acD, $axS.l
-// 0111 00sd xxxx xxxx
-// Adds secondary accumulator $axS.l to accumulator register $acD.
-void addaxl(const UDSPInstruction& opc)
-{
- u8 sreg = (opc.hex >> 9) & 0x1;
- u8 dreg = (opc.hex >> 8) & 0x1;
-
- s64 acc = dsp_get_long_acc(dreg);
- s64 acx = dsp_get_ax_l(sreg);
-
- acc += acx;
-
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// TSTAXH $axR.h
-// 1000 011r xxxx xxxx
-// Test high part of secondary accumulator $axR.h.
-void tstaxh(const UDSPInstruction& opc)
-{
- u8 reg = (opc.hex >> 8) & 0x1;
- s16 val = dsp_get_ax_h(reg);
-
- Update_SR_Register16(val);
-}
-
-// SUB $acD, $ac(1-D)
-// 0101 110d xxxx xxxx
-// Subtracts accumulator $ac(1-D) from accumulator register $acD.
-void sub(const UDSPInstruction& opc)
-{
- u8 D = (opc.hex >> 8) & 0x1;
- s64 acc1 = dsp_get_long_acc(D);
- s64 acc2 = dsp_get_long_acc(1 - D);
-
- acc1 -= acc2;
-
- dsp_set_long_acc(D, acc1);
-
- Update_SR_Register64(acc1);
-}
-
-// MOVR $acD, $axS.R
-// 0110 0srd xxxx xxxx
-// Moves register $axS.R (sign extended) to middle accumulator $acD.hm.
-// Sets $acD.l to 0.
-// TODO: Check what happens to acD.h.
-void movr(const UDSPInstruction& opc)
-{
- u8 areg = (opc.hex >> 8) & 0x1;
- u8 sreg = ((opc.hex >> 9) & 0x3) + DSP_REG_AXL0;
-
- s64 acc = (s16)g_dsp.r[sreg];
- acc <<= 16;
- acc &= ~0xffff;
-
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// MOVAX $acD, $axS
-// 0110 10sd xxxx xxxx
-// Moves secondary accumulator $axS to accumulator $axD.
-void movax(const UDSPInstruction& opc)
-{
- u8 dreg = (opc.hex >> 8) & 0x1;
- u8 sreg = (opc.hex >> 9) & 0x1;
-
- s64 acx = dsp_get_long_acx(sreg);
- dsp_set_long_acc(dreg, acx);
-
- Update_SR_Register64(acx);
-}
-
-// XORR $acD.m, $axS.h
-// 0011 00sd xxxx xxxx
-// Logic XOR (exclusive or) middle part of accumulator $acD.m with
-// high part of secondary accumulator $axS.h.
-void xorr(const UDSPInstruction& opc)
-{
- u8 sreg = (opc.hex >> 9) & 0x1;
- u8 dreg = (opc.hex >> 8) & 0x1;
-
- g_dsp.r[DSP_REG_ACM0 + dreg] ^= g_dsp.r[DSP_REG_AXH0 + sreg];
-
- s64 acc = dsp_get_long_acc(dreg);
- Update_SR_Register64(acc);
-}
-
-// ANDR $acD.m, $axS.h
-// 0011 01sd xxxx xxxx
-// Logic AND middle part of accumulator $acD.m with high part of
-// secondary accumulator $axS.h.
-void andr(const UDSPInstruction& opc)
-{
- u8 sreg = (opc.hex >> 9) & 0x1;
- u8 dreg = (opc.hex >> 8) & 0x1;
-
- g_dsp.r[DSP_REG_ACM0 + dreg] &= g_dsp.r[DSP_REG_AXH0 + sreg];
-
- s64 acc = dsp_get_long_acc(dreg);
-
- Update_SR_Register64(acc);
-}
-
-// ORR $acD.m, $axS.h
-// 0011 10sd xxxx xxxx
-// Logic OR middle part of accumulator $acD.m with high part of
-// secondary accumulator $axS.h.
-void orr(const UDSPInstruction& opc)
-{
- u8 sreg = (opc.hex >> 9) & 0x1;
- u8 dreg = (opc.hex >> 8) & 0x1;
-
- g_dsp.r[DSP_REG_ACM0 + dreg] |= g_dsp.r[DSP_REG_AXH0 + sreg];
-
- s64 acc = dsp_get_long_acc(dreg);
-
- Update_SR_Register64(acc);
-}
-
-// ANDC $acD.m, $ac(1-D).m
-// 0011 110d xxxx xxxx
-// Logic AND middle part of accumulator $acD.m with middle part of
-// accumulator $ax(1-D).m.s
-void andc(const UDSPInstruction& opc)
-{
- u8 D = (opc.hex >> 8) & 0x1;
-
- u16 ac1 = dsp_get_acc_m(D);
- u16 ac2 = dsp_get_acc_m(1 - D);
-
- dsp_set_long_acc(D, ac1 & ac2);
-
- Update_SR_Register64(dsp_get_long_acc(D));
-}
-
-// ORC $acD.m, $ac(1-D).m
-// 0011 111d xxxx xxxx
-// Logic OR middle part of accumulator $acD.m with middle part of
-// accumulator $ax(1-D).m.
-void orc(const UDSPInstruction& opc)
-{
- u8 D = (opc.hex >> 8) & 0x1;
-
- u16 ac1 = dsp_get_acc_m(D);
- u16 ac2 = dsp_get_acc_m(1 - D);
-
- dsp_set_long_acc(D, ac1 | ac2);
-
- Update_SR_Register64(dsp_get_long_acc(D));
-}
-
-void orf(const UDSPInstruction& opc)
-{
- ERROR_LOG(DSPLLE, "orf not implemented");
-}
-
-// Hermes switched andf and andcf, so check to make sure they are still correct
-// ANDCF $acD.m, #I
-// 0000 001r 1100 0000
-// iiii iiii iiii iiii
-// Set logic zero (LZ) flag in status register $sr if result of logic AND of
-// accumulator mid part $acD.m with immediate value I is equal I.
-void andcf(const UDSPInstruction& opc)
-{
- u8 reg = (opc.hex >> 8) & 0x1;
- u16 imm = dsp_fetch_code();
- u16 val = dsp_get_acc_m(reg);
-
- Update_SR_LZ(((val & imm) == imm) ? 0 : 1);
-}
-
-// Hermes switched andf and andcf, so check to make sure they are still correct
-
-// ANDF $acD.m, #I
-// 0000 001r 1010 0000
-// iiii iiii iiii iiii
-// Set logic zero (LZ) flag in status register $sr if result of logical AND
-// operation of accumulator mid part $acD.m with immediate value I is equal
-// immediate value 0.
-void andf(const UDSPInstruction& opc)
-{
- u8 reg = DSP_REG_ACM0 + ((opc.hex >> 8) & 0x1);
- u16 imm = dsp_fetch_code();
- u16 val = g_dsp.r[reg];
-
- Update_SR_LZ(((val & imm) == 0) ? 0 : 1);
-}
-
-// CMPI $amD, #I
-// 0000 001r 1000 0000
-// iiii iiii iiii iiii
-// Compares mid accumulator $acD.hm ($amD) with sign extended immediate value I.
-// Although flags are being set regarding whole accumulator register.
-void cmpi(const UDSPInstruction& opc)
-{
- int reg = (opc.hex >> 8) & 0x1;
-
- // Immediate is considered to be at M level in the 40-bit accumulator.
- s64 imm = (s64)(s16)dsp_fetch_code() << 16;
- s64 val = dsp_get_long_acc(reg);
- Update_SR_Register64(val - imm);
-}
-
-// XORI $acD.m, #I
-// 0000 001r 0010 0000
-// iiii iiii iiii iiii
-// Logic exclusive or (XOR) of accumulator mid part $acD.m with
-// immediate value I.
-void xori(const UDSPInstruction& opc)
-{
- u8 reg = DSP_REG_ACM0 + ((opc.hex >> 8) & 0x1);
- u16 imm = dsp_fetch_code();
- g_dsp.r[reg] ^= imm;
-
- Update_SR_Register16((s16)g_dsp.r[reg]);
-}
-
-// ANDI $acD.m, #I
-// 0000 001r 0100 0000
-// iiii iiii iiii iiii
-// Logic AND of accumulator mid part $acD.m with immediate value I.
-void andi(const UDSPInstruction& opc)
-{
- u8 reg = DSP_REG_ACM0 + ((opc.hex >> 8) & 0x1);
- u16 imm = dsp_fetch_code();
- g_dsp.r[reg] &= imm;
-
- Update_SR_Register16((s16)g_dsp.r[reg]);
-}
-
-
-// F|RES: i am not sure if this shouldnt be the whole ACC
-// ORI $acD.m, #I
-// 0000 001r 0110 0000
-// iiii iiii iiii iiii
-// Logic OR of accumulator mid part $acD.m with immediate value I.
-void ori(const UDSPInstruction& opc)
-{
- u8 reg = DSP_REG_ACM0 + ((opc.hex >> 8) & 0x1);
- u16 imm = dsp_fetch_code();
- g_dsp.r[reg] |= imm;
-
- Update_SR_Register16((s16)g_dsp.r[reg]);
-}
-
-//-------------------------------------------------------------
-
-
-// ADD $acD, $ac(1-D)
-// 0100 110d xxxx xxxx
-// Adds accumulator $ac(1-D) to accumulator register $acD.
-void add(const UDSPInstruction& opc)
-{
- u8 areg = (opc.hex >> 8) & 0x1;
- s64 acc0 = dsp_get_long_acc(0);
- s64 acc1 = dsp_get_long_acc(1);
-
- s64 res = acc0 + acc1;
-
- dsp_set_long_acc(areg, res);
-
- Update_SR_Register64(res);
-}
-
-// ADDP $acD
-// 0100 111d xxxx xxxx
-// Adds product register to accumulator register.
-void addp(const UDSPInstruction& opc)
-{
- u8 dreg = (opc.hex >> 8) & 0x1;
- s64 acc = dsp_get_long_acc(dreg);
- acc += dsp_get_long_prod();
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// SUBP $acD
-// 0101 111d xxxx xxxx
-// Subtracts product register from accumulator register.
-void subp(const UDSPInstruction& opc)
-{
- u8 dreg = (opc.hex >> 8) & 0x1;
- s64 acc = dsp_get_long_acc(dreg);
- acc -= dsp_get_long_prod();
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register64(acc);
-}
-
-
-// CMPIS $acD, #I
-// 0000 011d iiii iiii
-// Compares accumulator with short immediate. Comaprison is executed
-// by subtracting short immediate (8bit sign extended) from mid accumulator
-// $acD.hm and computing flags based on whole accumulator $acD.
-void cmpis(const UDSPInstruction& opc)
-{
- u8 areg = (opc.hex >> 8) & 0x1;
-
- s64 acc = dsp_get_long_acc(areg);
- s64 val = (s8)opc.hex;
- val <<= 16;
-
- s64 res = acc - val;
-
- Update_SR_Register64(res);
-}
-
-
-// DECM $acsD
-// 0111 100d xxxx xxxx
-// Decrement 24-bit mid-accumulator $acsD.
-void decm(const UDSPInstruction& opc)
-{
- u8 dreg = (opc.hex >> 8) & 0x01;
-
- s64 sub = 0x10000;
- s64 acc = dsp_get_long_acc(dreg);
- acc -= sub;
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// DEC $acD
-// 0111 101d xxxx xxxx
-// Decrement accumulator $acD.
-void dec(const UDSPInstruction& opc)
-{
- u8 dreg = (opc.hex >> 8) & 0x01;
-
- s64 acc = dsp_get_long_acc(dreg) - 1;
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// INCM $acsD
-// 0111 010d xxxx xxxx
-// Increment 24-bit mid-accumulator $acsD.
-void incm(const UDSPInstruction& opc)
-{
- u8 dreg = (opc.hex >> 8) & 0x1;
-
- s64 sub = 0x10000;
- s64 acc = dsp_get_long_acc(dreg);
- acc += sub;
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// INC $acD
-// 0111 011d xxxx xxxx
-// Increment accumulator $acD.
-void inc(const UDSPInstruction& opc)
-{
- u8 dreg = (opc.hex >> 8) & 0x1;
-
- s64 acc = dsp_get_long_acc(dreg) + 1;
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// NEG $acD
-// 0111 110d xxxx xxxx
-// Negate accumulator $acD.
-void neg(const UDSPInstruction& opc)
-{
- u8 areg = (opc.hex >> 8) & 0x1;
-
- s64 acc = dsp_get_long_acc(areg);
- acc = 0 - acc;
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// MOV $acD, $ac(1-D)
-// 0110 110d xxxx xxxx
-// Moves accumulator $ax(1-D) to accumulator $axD.
-void mov(const UDSPInstruction& opc)
-{
- u8 D = (opc.hex >> 8) & 0x1;
- u64 acc = dsp_get_long_acc(1 - D);
- dsp_set_long_acc(D, acc);
-
- Update_SR_Register64(acc);
-}
-
-// ADDAX $acD, $axS
-// 0100 10sd xxxx xxxx
-// Adds secondary accumulator $axS to accumulator register $acD.
-void addax(const UDSPInstruction& opc)
-{
- u8 areg = (opc.hex >> 8) & 0x1;
- u8 sreg = (opc.hex >> 9) & 0x1;
-
- s64 ax = dsp_get_long_acx(sreg);
- s64 acc = dsp_get_long_acc(areg);
- acc += ax;
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// ADDR $acD, $(DSP_REG_AXL0+S)
-// 0100 0ssd xxxx xxxx
-// Adds register $(DSP_REG_AXL0+S) to accumulator $acD register.
-void addr(const UDSPInstruction& opc)
-{
- u8 areg = (opc.hex >> 8) & 0x1;
- u8 sreg = ((opc.hex >> 9) & 0x3) + DSP_REG_AXL0;
-
- s64 ax = (s16)g_dsp.r[sreg];
- ax <<= 16;
-
- s64 acc = dsp_get_long_acc(areg);
- acc += ax;
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// SUBR $acD, $(DSP_REG_AXL0+S)
-// 0101 0ssd xxxx xxxx
-// Subtracts register $(DSP_REG_AXL0+S) from accumulator $acD register.
-void subr(const UDSPInstruction& opc)
-{
- u8 areg = (opc.hex >> 8) & 0x1;
- u8 sreg = ((opc.hex >> 9) & 0x3) + DSP_REG_AXL0;
-
- s64 ax = (s16)g_dsp.r[sreg];
- ax <<= 16;
-
- s64 acc = dsp_get_long_acc(areg);
- acc -= ax;
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// SUBAX $acD, $axS
-// 0101 10sd xxxx xxxx
-// Subtracts secondary accumulator $axS from accumulator register $acD.
-void subax(const UDSPInstruction& opc)
-{
- int regD = (opc.hex >> 8) & 0x1;
- int regS = (opc.hex >> 9) & 0x1;
-
- s64 acc = dsp_get_long_acc(regD) - dsp_get_long_acx(regS);
-
- dsp_set_long_acc(regD, acc);
- Update_SR_Register64(acc);
-}
-
-// ADDIS $acD, #I
-// 0000 010d iiii iiii
-// Adds short immediate (8-bit sign extended) to mid accumulator $acD.hm.
-void addis(const UDSPInstruction& opc)
-{
- u8 areg = (opc.hex >> 8) & 0x1;
-
- s64 Imm = (s8)(u8)opc.hex;
- Imm <<= 16;
- s64 acc = dsp_get_long_acc(areg);
- acc += Imm;
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// ADDI $amR, #I
-// 0000 001r 0000 0000
-// iiii iiii iiii iiii
-// Adds immediate (16-bit sign extended) to mid accumulator $acD.hm.
-void addi(const UDSPInstruction& opc)
-{
- u8 areg = (opc.hex >> 8) & 0x1;
-
- s64 sub = (s16)dsp_fetch_code();
- sub <<= 16;
- s64 acc = dsp_get_long_acc(areg);
- acc += sub;
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// LSL16 $acR
-// 1111 000r xxxx xxxx
-// Logically shifts left accumulator $acR by 16.
-void lsl16(const UDSPInstruction& opc)
-{
- u8 areg = (opc.hex >> 8) & 0x1;
-
- s64 acc = dsp_get_long_acc(areg);
- acc <<= 16;
- dsp_set_long_acc(areg, acc);
- Update_SR_Register64(acc);
-}
-
-// LSR16 $acR
-// 1111 010r xxxx xxxx
-// Logically shifts right accumulator $acR by 16.
-void lsr16(const UDSPInstruction& opc)
-{
- u8 areg = (opc.hex >> 8) & 0x1;
-
- u64 acc = dsp_get_long_acc(areg);
-
- acc >>= 16;
- dsp_set_long_acc(areg, acc);
- Update_SR_Register64(acc);
-}
-
-// ASR16 $acR
-// 1001 r001 xxxx xxxx
-// Arithmetically shifts right accumulator $acR by 16.
-void asr16(const UDSPInstruction& opc)
-{
- u8 areg = (opc.hex >> 11) & 0x1;
-
- s64 acc = dsp_get_long_acc(areg);
-
- acc >>= 16;
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// LSL $acR, #I
-// 0001 010r 00ii iiii
-// Logically shifts left accumulator $acR by number specified by value I.
-void lsl(const UDSPInstruction& opc)
-{
- u16 shift = opc.ushift;
- u64 acc = dsp_get_long_acc(opc.areg);
-
- acc <<= shift;
- dsp_set_long_acc(opc.areg, acc);
- Update_SR_Register64(acc);
-}
-
-// LSR $acR, #I
-// 0001 010r 01ii iiii
-// Logically shifts left accumulator $acR by number specified by value
-// calculated by negating sign extended bits 0-6.
-void lsr(const UDSPInstruction& opc)
-{
- u16 shift = -opc.ushift;
- u64 acc = dsp_get_long_acc(opc.areg);
- // Lop off the extraneous sign extension our 64-bit fake accum causes
- acc &= 0x000000FFFFFFFFFFULL;
- acc >>= shift;
- dsp_set_long_acc(opc.areg, (s64)acc);
- Update_SR_Register64(acc);
-}
-
-// ASL $acR, #I
-// 0001 010r 10ii iiii
-// Logically shifts left accumulator $acR by number specified by value I.
-void asl(const UDSPInstruction& opc)
-{
- u16 shift = opc.ushift;
-
- // arithmetic shift
- u64 acc = dsp_get_long_acc(opc.areg);
- acc <<= shift;
-
- dsp_set_long_acc(opc.areg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// ASR $acR, #I
-// 0001 010r 11ii iiii
-// Arithmetically shifts right accumulator $acR by number specified by
-// value calculated by negating sign extended bits 0-6.
-void asr(const UDSPInstruction& opc)
-{
- u16 shift = -opc.ushift;
-
- // arithmetic shift
- s64 acc = dsp_get_long_acc(opc.areg);
- acc >>= shift;
-
- dsp_set_long_acc(opc.areg, acc);
-
- Update_SR_Register64(acc);
-}
-
-
-// (NEW)
-// LSRN (fixed parameters)
-// 0000 0010 1100 1010
-// Logically shifts right accumulator $ACC0 by signed 16-bit value $AC1.M
-// (if value negative, becomes left shift).
-void lsrn(const UDSPInstruction& opc)
-{
- s16 shift = (s16)g_dsp.r[DSP_REG_ACM1];
- u64 acc = dsp_get_long_acc(0);
- // Lop off the extraneous sign extension our 64-bit fake accum causes
- acc &= 0x000000FFFFFFFFFFULL;
- if (shift > 0) {
- acc >>= shift;
- } else if (shift < 0) {
- acc <<= -shift;
- }
- dsp_set_long_acc(0, (s64)acc);
- Update_SR_Register64(acc);
-}
-
-// (NEW)
-// ASRN (fixed parameters)
-// 0000 0010 1100 1011
-// Arithmetically shifts right accumulator $ACC0 by signed 16-bit value $AC1.M
-// (if value negative, becomes left shift).
-void asrn(const UDSPInstruction& opc)
-{
- s16 shift = (s16)g_dsp.r[DSP_REG_ACM1];
- s64 acc = dsp_get_long_acc(0);
- if (shift > 0) {
- acc >>= shift;
- } else if (shift < 0) {
- acc <<= -shift;
- }
- dsp_set_long_acc(0, acc);
- Update_SR_Register64(acc);
-}
-
-
-// CMPAR $acS axR.h
-// 1100 0001 xxxx xxxx
-// Compares accumulator $acS with accumulator axR.h.
-// Not described by Duddie's doc - at least not as a separate instruction.
-void cmpar(const UDSPInstruction& opc)
-{
- u8 rreg = ((opc.hex >> 12) & 0x1) + DSP_REG_AXH0;
- u8 sreg = (opc.hex >> 11) & 0x1;
-
- // we compare
- s64 rr = (s16)g_dsp.r[rreg];
- rr <<= 16;
-
- s64 sr = dsp_get_long_acc(sreg);
-
- Update_SR_Register64(sr - rr);
-}
-
-// CMP
-// 1000 0010 xxxx xxxx
-// Compares accumulator $ac0 with accumulator $ac1.
-void cmp(const UDSPInstruction& opc)
-{
- s64 acc0 = dsp_get_long_acc(0);
- s64 acc1 = dsp_get_long_acc(1);
-
- Update_SR_Register64(acc0 - acc1);
-}
-
-// TST
-// 1011 r001 xxxx xxxx
-// Test accumulator %acR.
-void tst(const UDSPInstruction& opc)
-{
- s8 reg = (opc.hex >> 11) & 0x1;
- s64 acc = dsp_get_long_acc(reg);
-
- Update_SR_Register64(acc);
-}
-
-} // namespace
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Additional copyrights go to Duddie and Tratax (c) 2004
+
+#include "DSPInterpreter.h"
+#include "DSPIntCCUtil.h"
+#include "DSPIntUtil.h"
+
+// Arithmetic and accumulator control.
+
+namespace DSPInterpreter {
+
+// CLR $acR
+// 1000 r001 xxxx xxxx
+// Clears accumulator $acR
+void clr(const UDSPInstruction& opc)
+{
+ u8 reg = (opc.hex >> 11) & 0x1;
+
+ dsp_set_long_acc(reg, 0);
+
+ Update_SR_Register64((s64)0); // really?
+}
+
+// CLRL $acR.l
+// 1111 110r xxxx xxxx
+// Clears $acR.l - low 16 bits of accumulator $acR.
+void clrl(const UDSPInstruction& opc)
+{
+ u16 reg = DSP_REG_ACL0 + ((opc.hex >> 11) & 0x1);
+ g_dsp.r[reg] = 0;
+
+ // Should this be 64bit?
+ // nakee: it says the whole reg in duddie's doc sounds weird
+ Update_SR_Register64((s64)reg);
+}
+
+
+// ADDAXL $acD, $axS.l
+// 0111 00sd xxxx xxxx
+// Adds secondary accumulator $axS.l to accumulator register $acD.
+void addaxl(const UDSPInstruction& opc)
+{
+ u8 sreg = (opc.hex >> 9) & 0x1;
+ u8 dreg = (opc.hex >> 8) & 0x1;
+
+ s64 acc = dsp_get_long_acc(dreg);
+ s64 acx = dsp_get_ax_l(sreg);
+
+ acc += acx;
+
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// TSTAXH $axR.h
+// 1000 011r xxxx xxxx
+// Test high part of secondary accumulator $axR.h.
+void tstaxh(const UDSPInstruction& opc)
+{
+ u8 reg = (opc.hex >> 8) & 0x1;
+ s16 val = dsp_get_ax_h(reg);
+
+ Update_SR_Register16(val);
+}
+
+// SUB $acD, $ac(1-D)
+// 0101 110d xxxx xxxx
+// Subtracts accumulator $ac(1-D) from accumulator register $acD.
+void sub(const UDSPInstruction& opc)
+{
+ u8 D = (opc.hex >> 8) & 0x1;
+ s64 acc1 = dsp_get_long_acc(D);
+ s64 acc2 = dsp_get_long_acc(1 - D);
+
+ acc1 -= acc2;
+
+ dsp_set_long_acc(D, acc1);
+
+ Update_SR_Register64(acc1);
+}
+
+// MOVR $acD, $axS.R
+// 0110 0srd xxxx xxxx
+// Moves register $axS.R (sign extended) to middle accumulator $acD.hm.
+// Sets $acD.l to 0.
+// TODO: Check what happens to acD.h.
+void movr(const UDSPInstruction& opc)
+{
+ u8 areg = (opc.hex >> 8) & 0x1;
+ u8 sreg = ((opc.hex >> 9) & 0x3) + DSP_REG_AXL0;
+
+ s64 acc = (s16)g_dsp.r[sreg];
+ acc <<= 16;
+ acc &= ~0xffff;
+
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// MOVAX $acD, $axS
+// 0110 10sd xxxx xxxx
+// Moves secondary accumulator $axS to accumulator $axD.
+void movax(const UDSPInstruction& opc)
+{
+ u8 dreg = (opc.hex >> 8) & 0x1;
+ u8 sreg = (opc.hex >> 9) & 0x1;
+
+ s64 acx = dsp_get_long_acx(sreg);
+ dsp_set_long_acc(dreg, acx);
+
+ Update_SR_Register64(acx);
+}
+
+// XORR $acD.m, $axS.h
+// 0011 00sd xxxx xxxx
+// Logic XOR (exclusive or) middle part of accumulator $acD.m with
+// high part of secondary accumulator $axS.h.
+void xorr(const UDSPInstruction& opc)
+{
+ u8 sreg = (opc.hex >> 9) & 0x1;
+ u8 dreg = (opc.hex >> 8) & 0x1;
+
+ g_dsp.r[DSP_REG_ACM0 + dreg] ^= g_dsp.r[DSP_REG_AXH0 + sreg];
+
+ s64 acc = dsp_get_long_acc(dreg);
+ Update_SR_Register64(acc);
+}
+
+// ANDR $acD.m, $axS.h
+// 0011 01sd xxxx xxxx
+// Logic AND middle part of accumulator $acD.m with high part of
+// secondary accumulator $axS.h.
+void andr(const UDSPInstruction& opc)
+{
+ u8 sreg = (opc.hex >> 9) & 0x1;
+ u8 dreg = (opc.hex >> 8) & 0x1;
+
+ g_dsp.r[DSP_REG_ACM0 + dreg] &= g_dsp.r[DSP_REG_AXH0 + sreg];
+
+ s64 acc = dsp_get_long_acc(dreg);
+
+ Update_SR_Register64(acc);
+}
+
+// ORR $acD.m, $axS.h
+// 0011 10sd xxxx xxxx
+// Logic OR middle part of accumulator $acD.m with high part of
+// secondary accumulator $axS.h.
+void orr(const UDSPInstruction& opc)
+{
+ u8 sreg = (opc.hex >> 9) & 0x1;
+ u8 dreg = (opc.hex >> 8) & 0x1;
+
+ g_dsp.r[DSP_REG_ACM0 + dreg] |= g_dsp.r[DSP_REG_AXH0 + sreg];
+
+ s64 acc = dsp_get_long_acc(dreg);
+
+ Update_SR_Register64(acc);
+}
+
+// ANDC $acD.m, $ac(1-D).m
+// 0011 110d xxxx xxxx
+// Logic AND middle part of accumulator $acD.m with middle part of
+// accumulator $ax(1-D).m.s
+void andc(const UDSPInstruction& opc)
+{
+ u8 D = (opc.hex >> 8) & 0x1;
+
+ u16 ac1 = dsp_get_acc_m(D);
+ u16 ac2 = dsp_get_acc_m(1 - D);
+
+ dsp_set_long_acc(D, ac1 & ac2);
+
+ Update_SR_Register64(dsp_get_long_acc(D));
+}
+
+// ORC $acD.m, $ac(1-D).m
+// 0011 111d xxxx xxxx
+// Logic OR middle part of accumulator $acD.m with middle part of
+// accumulator $ax(1-D).m.
+void orc(const UDSPInstruction& opc)
+{
+ u8 D = (opc.hex >> 8) & 0x1;
+
+ u16 ac1 = dsp_get_acc_m(D);
+ u16 ac2 = dsp_get_acc_m(1 - D);
+
+ dsp_set_long_acc(D, ac1 | ac2);
+
+ Update_SR_Register64(dsp_get_long_acc(D));
+}
+
+void orf(const UDSPInstruction& opc)
+{
+ ERROR_LOG(DSPLLE, "orf not implemented");
+}
+
+// Hermes switched andf and andcf, so check to make sure they are still correct
+// ANDCF $acD.m, #I
+// 0000 001r 1100 0000
+// iiii iiii iiii iiii
+// Set logic zero (LZ) flag in status register $sr if result of logic AND of
+// accumulator mid part $acD.m with immediate value I is equal I.
+void andcf(const UDSPInstruction& opc)
+{
+ u8 reg = (opc.hex >> 8) & 0x1;
+ u16 imm = dsp_fetch_code();
+ u16 val = dsp_get_acc_m(reg);
+
+ Update_SR_LZ(((val & imm) == imm) ? 0 : 1);
+}
+
+// Hermes switched andf and andcf, so check to make sure they are still correct
+
+// ANDF $acD.m, #I
+// 0000 001r 1010 0000
+// iiii iiii iiii iiii
+// Set logic zero (LZ) flag in status register $sr if result of logical AND
+// operation of accumulator mid part $acD.m with immediate value I is equal
+// immediate value 0.
+void andf(const UDSPInstruction& opc)
+{
+ u8 reg = DSP_REG_ACM0 + ((opc.hex >> 8) & 0x1);
+ u16 imm = dsp_fetch_code();
+ u16 val = g_dsp.r[reg];
+
+ Update_SR_LZ(((val & imm) == 0) ? 0 : 1);
+}
+
+// CMPI $amD, #I
+// 0000 001r 1000 0000
+// iiii iiii iiii iiii
+// Compares mid accumulator $acD.hm ($amD) with sign extended immediate value I.
+// Although flags are being set regarding whole accumulator register.
+void cmpi(const UDSPInstruction& opc)
+{
+ int reg = (opc.hex >> 8) & 0x1;
+
+ // Immediate is considered to be at M level in the 40-bit accumulator.
+ s64 imm = (s64)(s16)dsp_fetch_code() << 16;
+ s64 val = dsp_get_long_acc(reg);
+ Update_SR_Register64(val - imm);
+}
+
+// XORI $acD.m, #I
+// 0000 001r 0010 0000
+// iiii iiii iiii iiii
+// Logic exclusive or (XOR) of accumulator mid part $acD.m with
+// immediate value I.
+void xori(const UDSPInstruction& opc)
+{
+ u8 reg = DSP_REG_ACM0 + ((opc.hex >> 8) & 0x1);
+ u16 imm = dsp_fetch_code();
+ g_dsp.r[reg] ^= imm;
+
+ Update_SR_Register16((s16)g_dsp.r[reg]);
+}
+
+// ANDI $acD.m, #I
+// 0000 001r 0100 0000
+// iiii iiii iiii iiii
+// Logic AND of accumulator mid part $acD.m with immediate value I.
+void andi(const UDSPInstruction& opc)
+{
+ u8 reg = DSP_REG_ACM0 + ((opc.hex >> 8) & 0x1);
+ u16 imm = dsp_fetch_code();
+ g_dsp.r[reg] &= imm;
+
+ Update_SR_Register16((s16)g_dsp.r[reg]);
+}
+
+
+// F|RES: i am not sure if this shouldnt be the whole ACC
+// ORI $acD.m, #I
+// 0000 001r 0110 0000
+// iiii iiii iiii iiii
+// Logic OR of accumulator mid part $acD.m with immediate value I.
+void ori(const UDSPInstruction& opc)
+{
+ u8 reg = DSP_REG_ACM0 + ((opc.hex >> 8) & 0x1);
+ u16 imm = dsp_fetch_code();
+ g_dsp.r[reg] |= imm;
+
+ Update_SR_Register16((s16)g_dsp.r[reg]);
+}
+
+//-------------------------------------------------------------
+
+
+// ADD $acD, $ac(1-D)
+// 0100 110d xxxx xxxx
+// Adds accumulator $ac(1-D) to accumulator register $acD.
+void add(const UDSPInstruction& opc)
+{
+ u8 areg = (opc.hex >> 8) & 0x1;
+ s64 acc0 = dsp_get_long_acc(0);
+ s64 acc1 = dsp_get_long_acc(1);
+
+ s64 res = acc0 + acc1;
+
+ dsp_set_long_acc(areg, res);
+
+ Update_SR_Register64(res);
+}
+
+// ADDP $acD
+// 0100 111d xxxx xxxx
+// Adds product register to accumulator register.
+void addp(const UDSPInstruction& opc)
+{
+ u8 dreg = (opc.hex >> 8) & 0x1;
+ s64 acc = dsp_get_long_acc(dreg);
+ acc += dsp_get_long_prod();
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// SUBP $acD
+// 0101 111d xxxx xxxx
+// Subtracts product register from accumulator register.
+void subp(const UDSPInstruction& opc)
+{
+ u8 dreg = (opc.hex >> 8) & 0x1;
+ s64 acc = dsp_get_long_acc(dreg);
+ acc -= dsp_get_long_prod();
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+
+// CMPIS $acD, #I
+// 0000 011d iiii iiii
+// Compares accumulator with short immediate. Comaprison is executed
+// by subtracting short immediate (8bit sign extended) from mid accumulator
+// $acD.hm and computing flags based on whole accumulator $acD.
+void cmpis(const UDSPInstruction& opc)
+{
+ u8 areg = (opc.hex >> 8) & 0x1;
+
+ s64 acc = dsp_get_long_acc(areg);
+ s64 val = (s8)opc.hex;
+ val <<= 16;
+
+ s64 res = acc - val;
+
+ Update_SR_Register64(res);
+}
+
+
+// DECM $acsD
+// 0111 100d xxxx xxxx
+// Decrement 24-bit mid-accumulator $acsD.
+void decm(const UDSPInstruction& opc)
+{
+ u8 dreg = (opc.hex >> 8) & 0x01;
+
+ s64 sub = 0x10000;
+ s64 acc = dsp_get_long_acc(dreg);
+ acc -= sub;
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// DEC $acD
+// 0111 101d xxxx xxxx
+// Decrement accumulator $acD.
+void dec(const UDSPInstruction& opc)
+{
+ u8 dreg = (opc.hex >> 8) & 0x01;
+
+ s64 acc = dsp_get_long_acc(dreg) - 1;
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// INCM $acsD
+// 0111 010d xxxx xxxx
+// Increment 24-bit mid-accumulator $acsD.
+void incm(const UDSPInstruction& opc)
+{
+ u8 dreg = (opc.hex >> 8) & 0x1;
+
+ s64 sub = 0x10000;
+ s64 acc = dsp_get_long_acc(dreg);
+ acc += sub;
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// INC $acD
+// 0111 011d xxxx xxxx
+// Increment accumulator $acD.
+void inc(const UDSPInstruction& opc)
+{
+ u8 dreg = (opc.hex >> 8) & 0x1;
+
+ s64 acc = dsp_get_long_acc(dreg) + 1;
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// NEG $acD
+// 0111 110d xxxx xxxx
+// Negate accumulator $acD.
+void neg(const UDSPInstruction& opc)
+{
+ u8 areg = (opc.hex >> 8) & 0x1;
+
+ s64 acc = dsp_get_long_acc(areg);
+ acc = 0 - acc;
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// MOV $acD, $ac(1-D)
+// 0110 110d xxxx xxxx
+// Moves accumulator $ax(1-D) to accumulator $axD.
+void mov(const UDSPInstruction& opc)
+{
+ u8 D = (opc.hex >> 8) & 0x1;
+ u64 acc = dsp_get_long_acc(1 - D);
+ dsp_set_long_acc(D, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// ADDAX $acD, $axS
+// 0100 10sd xxxx xxxx
+// Adds secondary accumulator $axS to accumulator register $acD.
+void addax(const UDSPInstruction& opc)
+{
+ u8 areg = (opc.hex >> 8) & 0x1;
+ u8 sreg = (opc.hex >> 9) & 0x1;
+
+ s64 ax = dsp_get_long_acx(sreg);
+ s64 acc = dsp_get_long_acc(areg);
+ acc += ax;
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// ADDR $acD, $(DSP_REG_AXL0+S)
+// 0100 0ssd xxxx xxxx
+// Adds register $(DSP_REG_AXL0+S) to accumulator $acD register.
+void addr(const UDSPInstruction& opc)
+{
+ u8 areg = (opc.hex >> 8) & 0x1;
+ u8 sreg = ((opc.hex >> 9) & 0x3) + DSP_REG_AXL0;
+
+ s64 ax = (s16)g_dsp.r[sreg];
+ ax <<= 16;
+
+ s64 acc = dsp_get_long_acc(areg);
+ acc += ax;
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// SUBR $acD, $(DSP_REG_AXL0+S)
+// 0101 0ssd xxxx xxxx
+// Subtracts register $(DSP_REG_AXL0+S) from accumulator $acD register.
+void subr(const UDSPInstruction& opc)
+{
+ u8 areg = (opc.hex >> 8) & 0x1;
+ u8 sreg = ((opc.hex >> 9) & 0x3) + DSP_REG_AXL0;
+
+ s64 ax = (s16)g_dsp.r[sreg];
+ ax <<= 16;
+
+ s64 acc = dsp_get_long_acc(areg);
+ acc -= ax;
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// SUBAX $acD, $axS
+// 0101 10sd xxxx xxxx
+// Subtracts secondary accumulator $axS from accumulator register $acD.
+void subax(const UDSPInstruction& opc)
+{
+ int regD = (opc.hex >> 8) & 0x1;
+ int regS = (opc.hex >> 9) & 0x1;
+
+ s64 acc = dsp_get_long_acc(regD) - dsp_get_long_acx(regS);
+
+ dsp_set_long_acc(regD, acc);
+ Update_SR_Register64(acc);
+}
+
+// ADDIS $acD, #I
+// 0000 010d iiii iiii
+// Adds short immediate (8-bit sign extended) to mid accumulator $acD.hm.
+void addis(const UDSPInstruction& opc)
+{
+ u8 areg = (opc.hex >> 8) & 0x1;
+
+ s64 Imm = (s8)(u8)opc.hex;
+ Imm <<= 16;
+ s64 acc = dsp_get_long_acc(areg);
+ acc += Imm;
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// ADDI $amR, #I
+// 0000 001r 0000 0000
+// iiii iiii iiii iiii
+// Adds immediate (16-bit sign extended) to mid accumulator $acD.hm.
+void addi(const UDSPInstruction& opc)
+{
+ u8 areg = (opc.hex >> 8) & 0x1;
+
+ s64 sub = (s16)dsp_fetch_code();
+ sub <<= 16;
+ s64 acc = dsp_get_long_acc(areg);
+ acc += sub;
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// LSL16 $acR
+// 1111 000r xxxx xxxx
+// Logically shifts left accumulator $acR by 16.
+void lsl16(const UDSPInstruction& opc)
+{
+ u8 areg = (opc.hex >> 8) & 0x1;
+
+ s64 acc = dsp_get_long_acc(areg);
+ acc <<= 16;
+ dsp_set_long_acc(areg, acc);
+ Update_SR_Register64(acc);
+}
+
+// LSR16 $acR
+// 1111 010r xxxx xxxx
+// Logically shifts right accumulator $acR by 16.
+void lsr16(const UDSPInstruction& opc)
+{
+ u8 areg = (opc.hex >> 8) & 0x1;
+
+ u64 acc = dsp_get_long_acc(areg);
+
+ acc >>= 16;
+ dsp_set_long_acc(areg, acc);
+ Update_SR_Register64(acc);
+}
+
+// ASR16 $acR
+// 1001 r001 xxxx xxxx
+// Arithmetically shifts right accumulator $acR by 16.
+void asr16(const UDSPInstruction& opc)
+{
+ u8 areg = (opc.hex >> 11) & 0x1;
+
+ s64 acc = dsp_get_long_acc(areg);
+
+ acc >>= 16;
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// LSL $acR, #I
+// 0001 010r 00ii iiii
+// Logically shifts left accumulator $acR by number specified by value I.
+void lsl(const UDSPInstruction& opc)
+{
+ u16 shift = opc.ushift;
+ u64 acc = dsp_get_long_acc(opc.areg);
+
+ acc <<= shift;
+ dsp_set_long_acc(opc.areg, acc);
+ Update_SR_Register64(acc);
+}
+
+// LSR $acR, #I
+// 0001 010r 01ii iiii
+// Logically shifts left accumulator $acR by number specified by value
+// calculated by negating sign extended bits 0-6.
+void lsr(const UDSPInstruction& opc)
+{
+ u16 shift = -opc.ushift;
+ u64 acc = dsp_get_long_acc(opc.areg);
+ // Lop off the extraneous sign extension our 64-bit fake accum causes
+ acc &= 0x000000FFFFFFFFFFULL;
+ acc >>= shift;
+ dsp_set_long_acc(opc.areg, (s64)acc);
+ Update_SR_Register64(acc);
+}
+
+// ASL $acR, #I
+// 0001 010r 10ii iiii
+// Logically shifts left accumulator $acR by number specified by value I.
+void asl(const UDSPInstruction& opc)
+{
+ u16 shift = opc.ushift;
+
+ // arithmetic shift
+ u64 acc = dsp_get_long_acc(opc.areg);
+ acc <<= shift;
+
+ dsp_set_long_acc(opc.areg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// ASR $acR, #I
+// 0001 010r 11ii iiii
+// Arithmetically shifts right accumulator $acR by number specified by
+// value calculated by negating sign extended bits 0-6.
+void asr(const UDSPInstruction& opc)
+{
+ u16 shift = -opc.ushift;
+
+ // arithmetic shift
+ s64 acc = dsp_get_long_acc(opc.areg);
+ acc >>= shift;
+
+ dsp_set_long_acc(opc.areg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+
+// (NEW)
+// LSRN (fixed parameters)
+// 0000 0010 1100 1010
+// Logically shifts right accumulator $ACC0 by signed 16-bit value $AC1.M
+// (if value negative, becomes left shift).
+void lsrn(const UDSPInstruction& opc)
+{
+ s16 shift = (s16)g_dsp.r[DSP_REG_ACM1];
+ u64 acc = dsp_get_long_acc(0);
+ // Lop off the extraneous sign extension our 64-bit fake accum causes
+ acc &= 0x000000FFFFFFFFFFULL;
+ if (shift > 0) {
+ acc >>= shift;
+ } else if (shift < 0) {
+ acc <<= -shift;
+ }
+ dsp_set_long_acc(0, (s64)acc);
+ Update_SR_Register64(acc);
+}
+
+// (NEW)
+// ASRN (fixed parameters)
+// 0000 0010 1100 1011
+// Arithmetically shifts right accumulator $ACC0 by signed 16-bit value $AC1.M
+// (if value negative, becomes left shift).
+void asrn(const UDSPInstruction& opc)
+{
+ s16 shift = (s16)g_dsp.r[DSP_REG_ACM1];
+ s64 acc = dsp_get_long_acc(0);
+ if (shift > 0) {
+ acc >>= shift;
+ } else if (shift < 0) {
+ acc <<= -shift;
+ }
+ dsp_set_long_acc(0, acc);
+ Update_SR_Register64(acc);
+}
+
+
+// CMPAR $acS axR.h
+// 1100 0001 xxxx xxxx
+// Compares accumulator $acS with accumulator axR.h.
+// Not described by Duddie's doc - at least not as a separate instruction.
+void cmpar(const UDSPInstruction& opc)
+{
+ u8 rreg = ((opc.hex >> 12) & 0x1) + DSP_REG_AXH0;
+ u8 sreg = (opc.hex >> 11) & 0x1;
+
+ // we compare
+ s64 rr = (s16)g_dsp.r[rreg];
+ rr <<= 16;
+
+ s64 sr = dsp_get_long_acc(sreg);
+
+ Update_SR_Register64(sr - rr);
+}
+
+// CMP
+// 1000 0010 xxxx xxxx
+// Compares accumulator $ac0 with accumulator $ac1.
+void cmp(const UDSPInstruction& opc)
+{
+ s64 acc0 = dsp_get_long_acc(0);
+ s64 acc1 = dsp_get_long_acc(1);
+
+ Update_SR_Register64(acc0 - acc1);
+}
+
+// TST
+// 1011 r001 xxxx xxxx
+// Test accumulator %acR.
+void tst(const UDSPInstruction& opc)
+{
+ s8 reg = (opc.hex >> 11) & 0x1;
+ s64 acc = dsp_get_long_acc(reg);
+
+ Update_SR_Register64(acc);
+}
+
+} // namespace
diff --git a/Source/Core/DSPCore/Src/DspIntBranch.cpp b/Source/Core/DSPCore/Src/DspIntBranch.cpp
index f37cc71ba0..721428d8f0 100644
--- a/Source/Core/DSPCore/Src/DspIntBranch.cpp
+++ b/Source/Core/DSPCore/Src/DspIntBranch.cpp
@@ -1,249 +1,249 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-// Additional copyrights go to Duddie and Tratax (c) 2004
-
-#include "DSPInterpreter.h"
-#include "DSPCore.h"
-#include "DSPMemoryMap.h"
-#include "DSPStacks.h"
-
-#include "DSPIntCCUtil.h"
-#include "DSPIntUtil.h"
-
-namespace DSPInterpreter {
-
-// Generic call implementation
-// CALLcc addressA
-// 0000 0010 1011 cccc
-// aaaa aaaa aaaa aaaa
-// Call function if condition cc has been met. Push program counter of
-// instruction following "call" to $st0. Set program counter to address
-// represented by value that follows this "call" instruction.
-void call(const UDSPInstruction& opc)
-{
- // must be outside the if.
- u16 dest = dsp_fetch_code();
- if (CheckCondition(opc.hex & 0xf))
- {
- dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc);
- g_dsp.pc = dest;
- }
-}
-
-// Generic callr implementation
-// CALLRcc $R
-// 0001 0111 rrr1 cccc
-// Call function if condition cc has been met. Push program counter of
-// instruction following "call" to call stack $st0. Set program counter to
-// register $R.
-void callr(const UDSPInstruction& opc)
-{
- if (CheckCondition(opc.hex & 0xf))
- {
- u8 reg = (opc.hex >> 5) & 0x7;
- u16 addr = dsp_op_read_reg(reg);
- dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc);
- g_dsp.pc = addr;
- }
-}
-
-// Generic if implementation
-// IFcc
-// 0000 0010 0111 cccc
-// Execute following opcode if the condition has been met.
-void ifcc(const UDSPInstruction& opc)
-{
- if (!CheckCondition(opc.hex & 0xf))
- {
- // skip the next opcode - we have to lookup its size.
- g_dsp.pc += opSize[dsp_peek_code()];
- }
-}
-
-// Generic jmp implementation
-// Jcc addressA
-// 0000 0010 1001 cccc
-// aaaa aaaa aaaa aaaa
-// Jump to addressA if condition cc has been met. Set program counter to
-// address represented by value that follows this "jmp" instruction.
-void jcc(const UDSPInstruction& opc)
-{
- u16 dest = dsp_fetch_code();
- if (CheckCondition(opc.hex & 0xf))
- {
- g_dsp.pc = dest;
- }
-}
-
-// Generic jmpr implementation
-// JMPcc $R
-// 0001 0111 rrr0 cccc
-// Jump to address; set program counter to a value from register $R.
-void jmprcc(const UDSPInstruction& opc)
-{
- if (CheckCondition(opc.hex & 0xf))
- {
- u8 reg = (opc.hex >> 5) & 0x7;
- g_dsp.pc = dsp_op_read_reg(reg);
- }
-}
-
-// Generic ret implementation
-// RETcc
-// 0000 0010 1101 cccc
-// Return from subroutine if condition cc has been met. Pops stored PC
-// from call stack $st0 and sets $pc to this location.
-void ret(const UDSPInstruction& opc)
-{
- if (CheckCondition(opc.hex & 0xf))
- {
- g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C);
- }
-}
-
-// RTI
-// 0000 0010 1111 1111
-// Return from exception. Pops stored status register $sr from data stack
-// $st1 and program counter PC from call stack $st0 and sets $pc to this
-// location.
-void rti(const UDSPInstruction& opc)
-{
- g_dsp.r[DSP_REG_SR] = dsp_reg_load_stack(DSP_STACK_D);
- g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C);
-
- g_dsp.exception_in_progress_hack = false;
-}
-
-// HALT
-// 0000 0000 0020 0001
-// Stops execution of DSP code. Sets bit DSP_CR_HALT in register DREG_CR.
-void halt(const UDSPInstruction& opc)
-{
- g_dsp.cr |= 0x4;
- g_dsp.pc--;
-}
-
-
-// LOOP handling: Loop stack is used to control execution of repeated blocks of
-// instructions. Whenever there is value on stack $st2 and current PC is equal
-// value at $st2, then value at stack $st3 is decremented. If value is not zero
-// then PC is modified with calue from call stack $st0. Otherwise values from
-// callstack $st0 and both loop stacks $st2 and $st3 are poped and execution
-// continues at next opcode.
-
-
-// LOOP $R
-// 0000 0000 010r rrrr
-// Repeatedly execute following opcode until counter specified by value
-// from register $R reaches zero. Each execution decrement counter. Register
-// $R remains unchanged. If register $R is set to zero at the beginning of loop
-// then looped instruction will not get executed.
-// Actually, this instruction simply prepares the loop stacks for the above.
-// The looping hardware takes care of the rest.
-void loop(const UDSPInstruction& opc)
-{
- u16 reg = opc.hex & 0x1f;
- u16 cnt = g_dsp.r[reg];
- u16 loop_pc = g_dsp.pc;
-
- if (cnt)
- {
- dsp_reg_store_stack(0, g_dsp.pc);
- dsp_reg_store_stack(2, loop_pc);
- dsp_reg_store_stack(3, cnt);
- }
-}
-
-// LOOPI #I
-// 0001 0000 iiii iiii
-// Repeatedly execute following opcode until counter specified by
-// immediate value I reaches zero. Each execution decrement counter. If
-// immediate value I is set to zero at the beginning of loop then looped
-// instruction will not get executed.
-// Actually, this instruction simply prepares the loop stacks for the above.
-// The looping hardware takes care of the rest.
-void loopi(const UDSPInstruction& opc)
-{
- u16 cnt = opc.hex & 0xff;
- u16 loop_pc = g_dsp.pc;
-
- if (cnt)
- {
- dsp_reg_store_stack(0, g_dsp.pc);
- dsp_reg_store_stack(2, loop_pc);
- dsp_reg_store_stack(3, cnt);
- }
-}
-
-
-// BLOOP $R, addrA
-// 0000 0000 011r rrrr
-// aaaa aaaa aaaa aaaa
-// Repeatedly execute block of code starting at following opcode until
-// counter specified by value from register $R reaches zero. Block ends at
-// specified address addrA inclusive, ie. opcode at addrA is the last opcode
-// included in loop. Counter is pushed on loop stack $st3, end of block address
-// is pushed on loop stack $st2 and repeat address is pushed on call stack $st0.
-// Up to 4 nested loops is allowed.
-void bloop(const UDSPInstruction& opc)
-{
- u16 reg = opc.hex & 0x1f;
- u16 cnt = g_dsp.r[reg];
- u16 loop_pc = dsp_fetch_code();
-
- if (cnt)
- {
- dsp_reg_store_stack(0, g_dsp.pc);
- dsp_reg_store_stack(2, loop_pc);
- dsp_reg_store_stack(3, cnt);
- }
- else
- {
- g_dsp.pc = loop_pc;
- g_dsp.pc += opSize[dsp_peek_code()];
- }
-}
-
-// BLOOPI #I, addrA
-// 0001 0001 iiii iiii
-// aaaa aaaa aaaa aaaa
-// Repeatedly execute block of code starting at following opcode until
-// counter specified by immediate value I reaches zero. Block ends at specified
-// address addrA inclusive, ie. opcode at addrA is the last opcode included in
-// loop. Counter is pushed on loop stack $st3, end of block address is pushed
-// on loop stack $st2 and repeat address is pushed on call stack $st0. Up to 4
-// nested loops is allowed.
-void bloopi(const UDSPInstruction& opc)
-{
- u16 cnt = opc.hex & 0xff;
- u16 loop_pc = dsp_fetch_code();
-
- if (cnt)
- {
- dsp_reg_store_stack(0, g_dsp.pc);
- dsp_reg_store_stack(2, loop_pc);
- dsp_reg_store_stack(3, cnt);
- }
- else
- {
- g_dsp.pc = loop_pc;
- g_dsp.pc += opSize[dsp_peek_code()];
- }
-}
-
-} // namespace
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Additional copyrights go to Duddie and Tratax (c) 2004
+
+#include "DSPInterpreter.h"
+#include "DSPCore.h"
+#include "DSPMemoryMap.h"
+#include "DSPStacks.h"
+
+#include "DSPIntCCUtil.h"
+#include "DSPIntUtil.h"
+
+namespace DSPInterpreter {
+
+// Generic call implementation
+// CALLcc addressA
+// 0000 0010 1011 cccc
+// aaaa aaaa aaaa aaaa
+// Call function if condition cc has been met. Push program counter of
+// instruction following "call" to $st0. Set program counter to address
+// represented by value that follows this "call" instruction.
+void call(const UDSPInstruction& opc)
+{
+ // must be outside the if.
+ u16 dest = dsp_fetch_code();
+ if (CheckCondition(opc.hex & 0xf))
+ {
+ dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc);
+ g_dsp.pc = dest;
+ }
+}
+
+// Generic callr implementation
+// CALLRcc $R
+// 0001 0111 rrr1 cccc
+// Call function if condition cc has been met. Push program counter of
+// instruction following "call" to call stack $st0. Set program counter to
+// register $R.
+void callr(const UDSPInstruction& opc)
+{
+ if (CheckCondition(opc.hex & 0xf))
+ {
+ u8 reg = (opc.hex >> 5) & 0x7;
+ u16 addr = dsp_op_read_reg(reg);
+ dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc);
+ g_dsp.pc = addr;
+ }
+}
+
+// Generic if implementation
+// IFcc
+// 0000 0010 0111 cccc
+// Execute following opcode if the condition has been met.
+void ifcc(const UDSPInstruction& opc)
+{
+ if (!CheckCondition(opc.hex & 0xf))
+ {
+ // skip the next opcode - we have to lookup its size.
+ g_dsp.pc += opSize[dsp_peek_code()];
+ }
+}
+
+// Generic jmp implementation
+// Jcc addressA
+// 0000 0010 1001 cccc
+// aaaa aaaa aaaa aaaa
+// Jump to addressA if condition cc has been met. Set program counter to
+// address represented by value that follows this "jmp" instruction.
+void jcc(const UDSPInstruction& opc)
+{
+ u16 dest = dsp_fetch_code();
+ if (CheckCondition(opc.hex & 0xf))
+ {
+ g_dsp.pc = dest;
+ }
+}
+
+// Generic jmpr implementation
+// JMPcc $R
+// 0001 0111 rrr0 cccc
+// Jump to address; set program counter to a value from register $R.
+void jmprcc(const UDSPInstruction& opc)
+{
+ if (CheckCondition(opc.hex & 0xf))
+ {
+ u8 reg = (opc.hex >> 5) & 0x7;
+ g_dsp.pc = dsp_op_read_reg(reg);
+ }
+}
+
+// Generic ret implementation
+// RETcc
+// 0000 0010 1101 cccc
+// Return from subroutine if condition cc has been met. Pops stored PC
+// from call stack $st0 and sets $pc to this location.
+void ret(const UDSPInstruction& opc)
+{
+ if (CheckCondition(opc.hex & 0xf))
+ {
+ g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C);
+ }
+}
+
+// RTI
+// 0000 0010 1111 1111
+// Return from exception. Pops stored status register $sr from data stack
+// $st1 and program counter PC from call stack $st0 and sets $pc to this
+// location.
+void rti(const UDSPInstruction& opc)
+{
+ g_dsp.r[DSP_REG_SR] = dsp_reg_load_stack(DSP_STACK_D);
+ g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C);
+
+ g_dsp.exception_in_progress_hack = false;
+}
+
+// HALT
+// 0000 0000 0020 0001
+// Stops execution of DSP code. Sets bit DSP_CR_HALT in register DREG_CR.
+void halt(const UDSPInstruction& opc)
+{
+ g_dsp.cr |= 0x4;
+ g_dsp.pc--;
+}
+
+
+// LOOP handling: Loop stack is used to control execution of repeated blocks of
+// instructions. Whenever there is value on stack $st2 and current PC is equal
+// value at $st2, then value at stack $st3 is decremented. If value is not zero
+// then PC is modified with calue from call stack $st0. Otherwise values from
+// callstack $st0 and both loop stacks $st2 and $st3 are poped and execution
+// continues at next opcode.
+
+
+// LOOP $R
+// 0000 0000 010r rrrr
+// Repeatedly execute following opcode until counter specified by value
+// from register $R reaches zero. Each execution decrement counter. Register
+// $R remains unchanged. If register $R is set to zero at the beginning of loop
+// then looped instruction will not get executed.
+// Actually, this instruction simply prepares the loop stacks for the above.
+// The looping hardware takes care of the rest.
+void loop(const UDSPInstruction& opc)
+{
+ u16 reg = opc.hex & 0x1f;
+ u16 cnt = g_dsp.r[reg];
+ u16 loop_pc = g_dsp.pc;
+
+ if (cnt)
+ {
+ dsp_reg_store_stack(0, g_dsp.pc);
+ dsp_reg_store_stack(2, loop_pc);
+ dsp_reg_store_stack(3, cnt);
+ }
+}
+
+// LOOPI #I
+// 0001 0000 iiii iiii
+// Repeatedly execute following opcode until counter specified by
+// immediate value I reaches zero. Each execution decrement counter. If
+// immediate value I is set to zero at the beginning of loop then looped
+// instruction will not get executed.
+// Actually, this instruction simply prepares the loop stacks for the above.
+// The looping hardware takes care of the rest.
+void loopi(const UDSPInstruction& opc)
+{
+ u16 cnt = opc.hex & 0xff;
+ u16 loop_pc = g_dsp.pc;
+
+ if (cnt)
+ {
+ dsp_reg_store_stack(0, g_dsp.pc);
+ dsp_reg_store_stack(2, loop_pc);
+ dsp_reg_store_stack(3, cnt);
+ }
+}
+
+
+// BLOOP $R, addrA
+// 0000 0000 011r rrrr
+// aaaa aaaa aaaa aaaa
+// Repeatedly execute block of code starting at following opcode until
+// counter specified by value from register $R reaches zero. Block ends at
+// specified address addrA inclusive, ie. opcode at addrA is the last opcode
+// included in loop. Counter is pushed on loop stack $st3, end of block address
+// is pushed on loop stack $st2 and repeat address is pushed on call stack $st0.
+// Up to 4 nested loops is allowed.
+void bloop(const UDSPInstruction& opc)
+{
+ u16 reg = opc.hex & 0x1f;
+ u16 cnt = g_dsp.r[reg];
+ u16 loop_pc = dsp_fetch_code();
+
+ if (cnt)
+ {
+ dsp_reg_store_stack(0, g_dsp.pc);
+ dsp_reg_store_stack(2, loop_pc);
+ dsp_reg_store_stack(3, cnt);
+ }
+ else
+ {
+ g_dsp.pc = loop_pc;
+ g_dsp.pc += opSize[dsp_peek_code()];
+ }
+}
+
+// BLOOPI #I, addrA
+// 0001 0001 iiii iiii
+// aaaa aaaa aaaa aaaa
+// Repeatedly execute block of code starting at following opcode until
+// counter specified by immediate value I reaches zero. Block ends at specified
+// address addrA inclusive, ie. opcode at addrA is the last opcode included in
+// loop. Counter is pushed on loop stack $st3, end of block address is pushed
+// on loop stack $st2 and repeat address is pushed on call stack $st0. Up to 4
+// nested loops is allowed.
+void bloopi(const UDSPInstruction& opc)
+{
+ u16 cnt = opc.hex & 0xff;
+ u16 loop_pc = dsp_fetch_code();
+
+ if (cnt)
+ {
+ dsp_reg_store_stack(0, g_dsp.pc);
+ dsp_reg_store_stack(2, loop_pc);
+ dsp_reg_store_stack(3, cnt);
+ }
+ else
+ {
+ g_dsp.pc = loop_pc;
+ g_dsp.pc += opSize[dsp_peek_code()];
+ }
+}
+
+} // namespace
diff --git a/Source/Core/DSPCore/Src/DspIntLoadStore.cpp b/Source/Core/DSPCore/Src/DspIntLoadStore.cpp
index 5346a4ed41..b2603f6c54 100644
--- a/Source/Core/DSPCore/Src/DspIntLoadStore.cpp
+++ b/Source/Core/DSPCore/Src/DspIntLoadStore.cpp
@@ -1,266 +1,266 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-// Additional copyrights go to Duddie and Tratax (c) 2004
-
-#include "DSPInterpreter.h"
-
-#include "DSPMemoryMap.h"
-#include "DSPIntUtil.h"
-
-namespace DSPInterpreter {
-
-// SRS @M, $(0x18+S)
-// 0010 1sss mmmm mmmm
-// Move value from register $(0x18+D) to data memory pointed by address CR[0-7] | M.
-// That is, the upper 8 bits of the address are the bottom 8 bits from CR, and the
-// lower 8 bits are from the 8-bit immediate.
-// Note: pc+=2 in duddie's doc seems wrong
-void srs(const UDSPInstruction& opc)
-{
- u8 reg = ((opc.hex >> 8) & 0x7) + 0x18;
- u16 addr = (g_dsp.r[DSP_REG_CR] << 8) | (opc.hex & 0xFF);
- dsp_dmem_write(addr, g_dsp.r[reg]);
-}
-
-// LRS $(0x18+D), @M
-// 0010 0ddd mmmm mmmm
-// Move value from data memory pointed by address CR[0-7] | M to register $(0x18+D).
-// That is, the upper 8 bits of the address are the bottom 8 bits from CR, and the
-// lower 8 bits are from the 8-bit immediate.
-void lrs(const UDSPInstruction& opc)
-{
- u8 reg = ((opc.hex >> 8) & 0x7) + 0x18;
- u16 addr = (g_dsp.r[DSP_REG_CR] << 8) | (opc.hex & 0xFF);
- g_dsp.r[reg] = dsp_dmem_read(addr);
-}
-
-// LR $D, @M
-// 0000 0000 110d dddd
-// mmmm mmmm mmmm mmmm
-// Move value from data memory pointed by address M to register $D.
-// FIXME: Perform additional operation depending on destination register.
-void lr(const UDSPInstruction& opc)
-{
- u8 reg = opc.hex & DSP_REG_MASK;
- u16 addr = dsp_fetch_code();
- u16 val = dsp_dmem_read(addr);
- dsp_op_write_reg(reg, val);
- dsp_conditional_extend_accum(reg);
-}
-
-// SR @M, $S
-// 0000 0000 111s ssss
-// mmmm mmmm mmmm mmmm
-// Store value from register $S to a memory pointed by address M.
-// FIXME: Perform additional operation depending on destination register.
-void sr(const UDSPInstruction& opc)
-{
- u8 reg = opc.hex & DSP_REG_MASK;
- u16 addr = dsp_fetch_code();
- u16 val = dsp_op_read_reg(reg);
- dsp_dmem_write(addr, val);
-}
-
-// SI @M, #I
-// 0001 0110 mmmm mmmm
-// iiii iiii iiii iiii
-// Store 16-bit immediate value I to a memory location pointed by address
-// M (M is 8-bit value sign extended).
-void si(const UDSPInstruction& opc)
-{
- u16 addr = (s8)opc.hex;
- u16 imm = dsp_fetch_code();
- dsp_dmem_write(addr, imm);
-}
-
-// LRR $D, @$S
-// 0001 1000 0ssd dddd
-// Move value from data memory pointed by addressing register $S to register $D.
-// FIXME: Perform additional operation depending on destination register.
-void lrr(const UDSPInstruction& opc)
-{
- u8 sreg = (opc.hex >> 5) & 0x3;
- u8 dreg = opc.hex & 0x1f;
-
- u16 val = dsp_dmem_read(g_dsp.r[sreg]);
- dsp_op_write_reg(dreg, val);
-}
-
-// LRRD $D, @$S
-// 0001 1000 1ssd dddd
-// Move value from data memory pointed by addressing register $S toregister $D.
-// Decrement register $S.
-// FIXME: Perform additional operation depending on destination register.
-void lrrd(const UDSPInstruction& opc)
-{
- u8 sreg = (opc.hex >> 5) & 0x3;
- u8 dreg = opc.hex & 0x1f;
-
- u16 val = dsp_dmem_read(g_dsp.r[sreg]);
- dsp_op_write_reg(dreg, val);
- dsp_decrement_addr_reg(sreg);
-}
-
-// LRRI $D, @$S
-// 0001 1001 0ssd dddd
-// Move value from data memory pointed by addressing register $S to register $D.
-// Increment register $S.
-// FIXME: Perform additional operation depending on destination register.
-void lrri(const UDSPInstruction& opc)
-{
- u8 sreg = (opc.hex >> 5) & 0x3;
- u8 dreg = opc.hex & 0x1f;
-
- u16 val = dsp_dmem_read(g_dsp.r[sreg]);
- dsp_op_write_reg(dreg, val);
- dsp_increment_addr_reg(sreg);
-}
-
-// LRRN $D, @$S
-// 0001 1001 1ssd dddd
-// Move value from data memory pointed by addressing register $S to register $D.
-// Add indexing register $(0x4+S) to register $S.
-// FIXME: Perform additional operation depending on destination register.
-void lrrn(const UDSPInstruction& opc)
-{
- u8 sreg = (opc.hex >> 5) & 0x3;
- u8 dreg = opc.hex & 0x1f;
-
- u16 val = dsp_dmem_read(g_dsp.r[sreg]);
- dsp_op_write_reg(dreg, val);
- // g_dsp.r[sreg] += g_dsp.r[DSP_REG_IX0 + sreg];
- dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
-}
-
-// SRR @$D, $S
-// 0001 1010 0dds ssss
-// Store value from source register $S to a memory location pointed by
-// addressing register $D.
-// FIXME: Perform additional operation depending on source register.
-void srr(const UDSPInstruction& opc)
-{
- u8 dreg = (opc.hex >> 5) & 0x3;
- u8 sreg = opc.hex & 0x1f;
-
- u16 val = dsp_op_read_reg(sreg);
- dsp_dmem_write(g_dsp.r[dreg], val);
-}
-
-// SRRD @$D, $S
-// 0001 1010 1dds ssss
-// Store value from source register $S to a memory location pointed by
-// addressing register $D. Decrement register $D.
-// FIXME: Perform additional operation depending on source register.
-void srrd(const UDSPInstruction& opc)
-{
- u8 dreg = (opc.hex >> 5) & 0x3;
- u8 sreg = opc.hex & 0x1f;
-
- u16 val = dsp_op_read_reg(sreg);
- dsp_dmem_write(g_dsp.r[dreg], val);
- dsp_decrement_addr_reg(dreg);
-}
-
-// SRRI @$D, $S
-// 0001 1011 0dds ssss
-// Store value from source register $S to a memory location pointed by
-// addressing register $D. Increment register $D.
-// FIXME: Perform additional operation depending on source register.
-void srri(const UDSPInstruction& opc)
-{
- u8 dreg = (opc.hex >> 5) & 0x3;
- u8 sreg = opc.hex & 0x1f;
-
- u16 val = dsp_op_read_reg(sreg);
- dsp_dmem_write(g_dsp.r[dreg], val);
- dsp_increment_addr_reg(dreg);
-}
-
-// SRRN @$D, $S
-// 0001 1011 1dds ssss
-// Store value from source register $S to a memory location pointed by
-// addressing register $D. Add DSP_REG_IX0 register to register $D.
-// FIXME: Perform additional operation depending on source register.
-void srrn(const UDSPInstruction& opc)
-{
- u8 dreg = (opc.hex >> 5) & 0x3;
- u8 sreg = opc.hex & 0x1f;
-
- u16 val = dsp_op_read_reg(sreg);
- dsp_dmem_write(g_dsp.r[dreg], val);
- // g_dsp.r[dreg] += g_dsp.r[DSP_REG_IX0 + dreg];
- dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]);
-}
-
-// ILRR $acD.m, @$arS
-// 0000 001d 0001 00ss
-// Move value from instruction memory pointed by addressing register
-// $arS to mid accumulator register $acD.m.
-void ilrr(const UDSPInstruction& opc)
-{
- u16 reg = opc.hex & 0x3;
- u16 dreg = DSP_REG_ACM0 + ((opc.hex >> 8) & 1);
-
- g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
-}
-
-// ILRRD $acD.m, @$arS
-// 0000 001d 0001 01ss
-// Move value from instruction memory pointed by addressing register
-// $arS to mid accumulator register $acD.m. Decrement addressing register $arS.
-void ilrrd(const UDSPInstruction& opc)
-{
- u16 reg = opc.hex & 0x3;
- u16 dreg = DSP_REG_ACM0 + ((opc.hex >> 8) & 1);
-
- g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
-
- dsp_decrement_addr_reg(reg);
-}
-
-// ILRRI $acD.m, @$S
-// 0000 001d 0001 10ss
-// Move value from instruction memory pointed by addressing register
-// $arS to mid accumulator register $acD.m. Increment addressing register $arS.
-void ilrri(const UDSPInstruction& opc)
-{
- u16 reg = opc.hex & 0x3;
- u16 dreg = DSP_REG_ACM0 + ((opc.hex >> 8) & 1);
-
- g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
-
- dsp_increment_addr_reg(reg);
-}
-
-// ILRRN $acD.m, @$arS
-// 0000 001d 0001 11ss
-// Move value from instruction memory pointed by addressing register
-// $arS to mid accumulator register $acD.m. Add corresponding indexing
-// register $ixS to addressing register $arS.
-void ilrrn(const UDSPInstruction& opc)
-{
- u16 reg = opc.hex & 0x3;
- u16 dreg = DSP_REG_ACM0 + ((opc.hex >> 8) & 1);
-
- g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
-
- // g_dsp.r[reg] += g_dsp.r[DSP_REG_IX0 + reg];
- dsp_increase_addr_reg(reg, (s16)g_dsp.r[DSP_REG_IX0 + reg]);
-}
-
-} // namespace
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Additional copyrights go to Duddie and Tratax (c) 2004
+
+#include "DSPInterpreter.h"
+
+#include "DSPMemoryMap.h"
+#include "DSPIntUtil.h"
+
+namespace DSPInterpreter {
+
+// SRS @M, $(0x18+S)
+// 0010 1sss mmmm mmmm
+// Move value from register $(0x18+D) to data memory pointed by address CR[0-7] | M.
+// That is, the upper 8 bits of the address are the bottom 8 bits from CR, and the
+// lower 8 bits are from the 8-bit immediate.
+// Note: pc+=2 in duddie's doc seems wrong
+void srs(const UDSPInstruction& opc)
+{
+ u8 reg = ((opc.hex >> 8) & 0x7) + 0x18;
+ u16 addr = (g_dsp.r[DSP_REG_CR] << 8) | (opc.hex & 0xFF);
+ dsp_dmem_write(addr, g_dsp.r[reg]);
+}
+
+// LRS $(0x18+D), @M
+// 0010 0ddd mmmm mmmm
+// Move value from data memory pointed by address CR[0-7] | M to register $(0x18+D).
+// That is, the upper 8 bits of the address are the bottom 8 bits from CR, and the
+// lower 8 bits are from the 8-bit immediate.
+void lrs(const UDSPInstruction& opc)
+{
+ u8 reg = ((opc.hex >> 8) & 0x7) + 0x18;
+ u16 addr = (g_dsp.r[DSP_REG_CR] << 8) | (opc.hex & 0xFF);
+ g_dsp.r[reg] = dsp_dmem_read(addr);
+}
+
+// LR $D, @M
+// 0000 0000 110d dddd
+// mmmm mmmm mmmm mmmm
+// Move value from data memory pointed by address M to register $D.
+// FIXME: Perform additional operation depending on destination register.
+void lr(const UDSPInstruction& opc)
+{
+ u8 reg = opc.hex & DSP_REG_MASK;
+ u16 addr = dsp_fetch_code();
+ u16 val = dsp_dmem_read(addr);
+ dsp_op_write_reg(reg, val);
+ dsp_conditional_extend_accum(reg);
+}
+
+// SR @M, $S
+// 0000 0000 111s ssss
+// mmmm mmmm mmmm mmmm
+// Store value from register $S to a memory pointed by address M.
+// FIXME: Perform additional operation depending on destination register.
+void sr(const UDSPInstruction& opc)
+{
+ u8 reg = opc.hex & DSP_REG_MASK;
+ u16 addr = dsp_fetch_code();
+ u16 val = dsp_op_read_reg(reg);
+ dsp_dmem_write(addr, val);
+}
+
+// SI @M, #I
+// 0001 0110 mmmm mmmm
+// iiii iiii iiii iiii
+// Store 16-bit immediate value I to a memory location pointed by address
+// M (M is 8-bit value sign extended).
+void si(const UDSPInstruction& opc)
+{
+ u16 addr = (s8)opc.hex;
+ u16 imm = dsp_fetch_code();
+ dsp_dmem_write(addr, imm);
+}
+
+// LRR $D, @$S
+// 0001 1000 0ssd dddd
+// Move value from data memory pointed by addressing register $S to register $D.
+// FIXME: Perform additional operation depending on destination register.
+void lrr(const UDSPInstruction& opc)
+{
+ u8 sreg = (opc.hex >> 5) & 0x3;
+ u8 dreg = opc.hex & 0x1f;
+
+ u16 val = dsp_dmem_read(g_dsp.r[sreg]);
+ dsp_op_write_reg(dreg, val);
+}
+
+// LRRD $D, @$S
+// 0001 1000 1ssd dddd
+// Move value from data memory pointed by addressing register $S toregister $D.
+// Decrement register $S.
+// FIXME: Perform additional operation depending on destination register.
+void lrrd(const UDSPInstruction& opc)
+{
+ u8 sreg = (opc.hex >> 5) & 0x3;
+ u8 dreg = opc.hex & 0x1f;
+
+ u16 val = dsp_dmem_read(g_dsp.r[sreg]);
+ dsp_op_write_reg(dreg, val);
+ dsp_decrement_addr_reg(sreg);
+}
+
+// LRRI $D, @$S
+// 0001 1001 0ssd dddd
+// Move value from data memory pointed by addressing register $S to register $D.
+// Increment register $S.
+// FIXME: Perform additional operation depending on destination register.
+void lrri(const UDSPInstruction& opc)
+{
+ u8 sreg = (opc.hex >> 5) & 0x3;
+ u8 dreg = opc.hex & 0x1f;
+
+ u16 val = dsp_dmem_read(g_dsp.r[sreg]);
+ dsp_op_write_reg(dreg, val);
+ dsp_increment_addr_reg(sreg);
+}
+
+// LRRN $D, @$S
+// 0001 1001 1ssd dddd
+// Move value from data memory pointed by addressing register $S to register $D.
+// Add indexing register $(0x4+S) to register $S.
+// FIXME: Perform additional operation depending on destination register.
+void lrrn(const UDSPInstruction& opc)
+{
+ u8 sreg = (opc.hex >> 5) & 0x3;
+ u8 dreg = opc.hex & 0x1f;
+
+ u16 val = dsp_dmem_read(g_dsp.r[sreg]);
+ dsp_op_write_reg(dreg, val);
+ // g_dsp.r[sreg] += g_dsp.r[DSP_REG_IX0 + sreg];
+ dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
+}
+
+// SRR @$D, $S
+// 0001 1010 0dds ssss
+// Store value from source register $S to a memory location pointed by
+// addressing register $D.
+// FIXME: Perform additional operation depending on source register.
+void srr(const UDSPInstruction& opc)
+{
+ u8 dreg = (opc.hex >> 5) & 0x3;
+ u8 sreg = opc.hex & 0x1f;
+
+ u16 val = dsp_op_read_reg(sreg);
+ dsp_dmem_write(g_dsp.r[dreg], val);
+}
+
+// SRRD @$D, $S
+// 0001 1010 1dds ssss
+// Store value from source register $S to a memory location pointed by
+// addressing register $D. Decrement register $D.
+// FIXME: Perform additional operation depending on source register.
+void srrd(const UDSPInstruction& opc)
+{
+ u8 dreg = (opc.hex >> 5) & 0x3;
+ u8 sreg = opc.hex & 0x1f;
+
+ u16 val = dsp_op_read_reg(sreg);
+ dsp_dmem_write(g_dsp.r[dreg], val);
+ dsp_decrement_addr_reg(dreg);
+}
+
+// SRRI @$D, $S
+// 0001 1011 0dds ssss
+// Store value from source register $S to a memory location pointed by
+// addressing register $D. Increment register $D.
+// FIXME: Perform additional operation depending on source register.
+void srri(const UDSPInstruction& opc)
+{
+ u8 dreg = (opc.hex >> 5) & 0x3;
+ u8 sreg = opc.hex & 0x1f;
+
+ u16 val = dsp_op_read_reg(sreg);
+ dsp_dmem_write(g_dsp.r[dreg], val);
+ dsp_increment_addr_reg(dreg);
+}
+
+// SRRN @$D, $S
+// 0001 1011 1dds ssss
+// Store value from source register $S to a memory location pointed by
+// addressing register $D. Add DSP_REG_IX0 register to register $D.
+// FIXME: Perform additional operation depending on source register.
+void srrn(const UDSPInstruction& opc)
+{
+ u8 dreg = (opc.hex >> 5) & 0x3;
+ u8 sreg = opc.hex & 0x1f;
+
+ u16 val = dsp_op_read_reg(sreg);
+ dsp_dmem_write(g_dsp.r[dreg], val);
+ // g_dsp.r[dreg] += g_dsp.r[DSP_REG_IX0 + dreg];
+ dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]);
+}
+
+// ILRR $acD.m, @$arS
+// 0000 001d 0001 00ss
+// Move value from instruction memory pointed by addressing register
+// $arS to mid accumulator register $acD.m.
+void ilrr(const UDSPInstruction& opc)
+{
+ u16 reg = opc.hex & 0x3;
+ u16 dreg = DSP_REG_ACM0 + ((opc.hex >> 8) & 1);
+
+ g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
+}
+
+// ILRRD $acD.m, @$arS
+// 0000 001d 0001 01ss
+// Move value from instruction memory pointed by addressing register
+// $arS to mid accumulator register $acD.m. Decrement addressing register $arS.
+void ilrrd(const UDSPInstruction& opc)
+{
+ u16 reg = opc.hex & 0x3;
+ u16 dreg = DSP_REG_ACM0 + ((opc.hex >> 8) & 1);
+
+ g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
+
+ dsp_decrement_addr_reg(reg);
+}
+
+// ILRRI $acD.m, @$S
+// 0000 001d 0001 10ss
+// Move value from instruction memory pointed by addressing register
+// $arS to mid accumulator register $acD.m. Increment addressing register $arS.
+void ilrri(const UDSPInstruction& opc)
+{
+ u16 reg = opc.hex & 0x3;
+ u16 dreg = DSP_REG_ACM0 + ((opc.hex >> 8) & 1);
+
+ g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
+
+ dsp_increment_addr_reg(reg);
+}
+
+// ILRRN $acD.m, @$arS
+// 0000 001d 0001 11ss
+// Move value from instruction memory pointed by addressing register
+// $arS to mid accumulator register $acD.m. Add corresponding indexing
+// register $ixS to addressing register $arS.
+void ilrrn(const UDSPInstruction& opc)
+{
+ u16 reg = opc.hex & 0x3;
+ u16 dreg = DSP_REG_ACM0 + ((opc.hex >> 8) & 1);
+
+ g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
+
+ // g_dsp.r[reg] += g_dsp.r[DSP_REG_IX0 + reg];
+ dsp_increase_addr_reg(reg, (s16)g_dsp.r[DSP_REG_IX0 + reg]);
+}
+
+} // namespace
diff --git a/Source/Core/DSPCore/Src/DspIntMisc.cpp b/Source/Core/DSPCore/Src/DspIntMisc.cpp
index df60210d98..3b9deee559 100644
--- a/Source/Core/DSPCore/Src/DspIntMisc.cpp
+++ b/Source/Core/DSPCore/Src/DspIntMisc.cpp
@@ -1,202 +1,202 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-// Additional copyrights go to Duddie and Tratax (c) 2004
-
-
-#include "DSPInterpreter.h"
-
-#include "DSPCore.h"
-#include "DSPIntUtil.h"
-
-namespace DSPInterpreter {
-
-void unknown(const UDSPInstruction& opc)
-{
- //_assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception");
- ERROR_LOG(DSPLLE, "LLE: Unrecognized opcode 0x%04x, pc 0x%04x", opc.hex, g_dsp.pc);
-}
-
-// MRR $D, $S
-// 0001 11dd ddds ssss
-// Move value from register $S to register $D.
-// FIXME: Perform additional operation depending on destination register.
-void mrr(const UDSPInstruction& opc)
-{
- u8 sreg = opc.hex & 0x1f;
- u8 dreg = (opc.hex >> 5) & 0x1f;
-
- u16 val = dsp_op_read_reg(sreg);
- dsp_op_write_reg(dreg, val);
-}
-
-// LRI $D, #I
-// 0000 0000 100d dddd
-// iiii iiii iiii iiii
-// Load immediate value I to register $D.
-// FIXME: Perform additional operation depending on destination register.
-
-// DSPSpy discovery: This, and possibly other instructions that load a register,
-// has a different behaviour in S40 mode if loaded to AC0.M: The value gets sign extended
-// to the whole accumulator! This does not happen in S16 mode.
-void lri(const UDSPInstruction& opc)
-{
- u8 reg = opc.hex & DSP_REG_MASK;
- u16 imm = dsp_fetch_code();
- dsp_op_write_reg(reg, imm);
- dsp_conditional_extend_accum(reg);
-}
-
-// LRIS $(0x18+D), #I
-// 0000 1ddd iiii iiii
-// Load immediate value I (8-bit sign extended) to accumulator register.
-// FIXME: Perform additional operation depending on destination register.
-void lris(const UDSPInstruction& opc)
-{
- u8 reg = ((opc.hex >> 8) & 0x7) + DSP_REG_AXL0;
- u16 imm = (s8)opc.hex;
- dsp_op_write_reg(reg, imm);
- dsp_conditional_extend_accum(reg);
-}
-
-
-// TSTAXL $acR
-// 1000 r001 xxxx xxxx
-// r specifies one of the main accumulators.
-// Definitely not a test instruction - it changes the accums.
-// Not affected by m0/m2. Not affected by s16/s40.
-void tstaxl(const UDSPInstruction& opc)
-{
- // This is probably all wrong.
- //u8 reg = (opc.hex >> 8) & 0x1;
- //s16 val = dsp_get_ax_l(reg);
- //Update_SR_Register16(val);
-}
-
-// ADDARN $arD, $ixS
-// 0000 0000 0001 ssdd
-// Adds indexing register $ixS to an addressing register $arD.
-void addarn(const UDSPInstruction& opc)
-{
- u8 dreg = opc.hex & 0x3;
- u8 sreg = (opc.hex >> 2) & 0x3;
-
- // g_dsp.r[dreg] += (s16)g_dsp.r[DSP_REG_IX0 + sreg];
-
- dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
-
- // It is critical for the Zelda ucode that this one wraps correctly.
-}
-
-// NX
-// 1000 -000 xxxx xxxx
-// No operation, but can be extended with extended opcode.
-void nx(const UDSPInstruction& opc)
-{
- // This opcode is supposed to do nothing - it's used if you want to use
- // an opcode extension but not do anything. At least according to duddie.
-}
-
-//-------------------------------------------------------------
-// DAR $arD ?
-// 0000 0000 0000 01dd
-// Decrement address register $arD.
-void dar(const UDSPInstruction& opc)
-{
- dsp_decrement_addr_reg(opc.hex & 0x3);
-}
-
-// IAR $arD ?
-// 0000 0000 0000 10dd
-// Increment address register $arD.
-void iar(const UDSPInstruction& opc)
-{
- dsp_increment_addr_reg(opc.hex & 0x3);
-}
-
-// SBCLR #I
-// 0001 0011 0000 0iii
-// bit of status register $sr. Bit number is calculated by adding 6 to
-// immediate value I.
-void sbclr(const UDSPInstruction& opc)
-{
- u8 bit = (opc.hex & 0xff) + 6;
- g_dsp.r[DSP_REG_SR] &= ~(1 << bit);
-}
-
-// SBSET #I
-// 0001 0010 0000 0iii
-// Set bit of status register $sr. Bit number is calculated by adding 6 to
-// immediate value I.
-void sbset(const UDSPInstruction& opc)
-{
- u8 bit = (opc.hex & 0xff) + 6;
- g_dsp.r[DSP_REG_SR] |= (1 << bit);
-}
-
-
-// FIXME inside
-// This is a bunch of flag setters, flipping bits in SR. So far so good,
-// but it's harder to know exactly what effect they have.
-// M0/M2 change the multiplier mode (it can multiply by 2 for free).
-//
-// SET16 changes something very important: see the LRI instruction above.
-// Hermes' demo sets the following defaults:
-// SET40
-// CLR15
-// M0
-void srbith(const UDSPInstruction& opc)
-{
- switch ((opc.hex >> 8) & 0xf)
- {
- // M0 seems to be the default. M2 is used in functions in Zelda
- // and then reset with M0 at the end. Like the other bits here, it's
- // done around loops with lots of multiplications.
- // I've confirmed with DSPSpy that they flip this bit.
- case 0xa: // M2
- g_dsp.r[DSP_REG_SR] &= ~SR_MUL_MODIFY;
- break;
- case 0xb: // M0
- g_dsp.r[DSP_REG_SR] |= SR_MUL_MODIFY;
- break;
-
- // If set, treat multiplicands as unsigned.
- // If clear, treat them as signed.
- case 0xc: // CLR15
- g_dsp.r[DSP_REG_SR] &= ~SR_MUL_UNSIGNED;
- break;
- case 0xd: // SET15
- g_dsp.r[DSP_REG_SR] |= SR_MUL_UNSIGNED;
- break;
-
- // Automatic 40-bit sign extension when loading ACx.M.
- // 40 seems to be the default.
- // Confirmed these by using DSPSpy and copying the value of SR to R00 after setting.
- case 0xe: // SET16 (really, clear SR's 0x4000)
- g_dsp.r[DSP_REG_SR] &= ~SR_40_MODE_BIT;
- break;
-
- case 0xf: // SET40 (really, set SR's 0x4000)
- g_dsp.r[DSP_REG_SR] |= SR_40_MODE_BIT;
- break;
-
- default:
- break;
- }
-}
-
-} // namespace
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Additional copyrights go to Duddie and Tratax (c) 2004
+
+
+#include "DSPInterpreter.h"
+
+#include "DSPCore.h"
+#include "DSPIntUtil.h"
+
+namespace DSPInterpreter {
+
+void unknown(const UDSPInstruction& opc)
+{
+ //_assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception");
+ ERROR_LOG(DSPLLE, "LLE: Unrecognized opcode 0x%04x, pc 0x%04x", opc.hex, g_dsp.pc);
+}
+
+// MRR $D, $S
+// 0001 11dd ddds ssss
+// Move value from register $S to register $D.
+// FIXME: Perform additional operation depending on destination register.
+void mrr(const UDSPInstruction& opc)
+{
+ u8 sreg = opc.hex & 0x1f;
+ u8 dreg = (opc.hex >> 5) & 0x1f;
+
+ u16 val = dsp_op_read_reg(sreg);
+ dsp_op_write_reg(dreg, val);
+}
+
+// LRI $D, #I
+// 0000 0000 100d dddd
+// iiii iiii iiii iiii
+// Load immediate value I to register $D.
+// FIXME: Perform additional operation depending on destination register.
+
+// DSPSpy discovery: This, and possibly other instructions that load a register,
+// has a different behaviour in S40 mode if loaded to AC0.M: The value gets sign extended
+// to the whole accumulator! This does not happen in S16 mode.
+void lri(const UDSPInstruction& opc)
+{
+ u8 reg = opc.hex & DSP_REG_MASK;
+ u16 imm = dsp_fetch_code();
+ dsp_op_write_reg(reg, imm);
+ dsp_conditional_extend_accum(reg);
+}
+
+// LRIS $(0x18+D), #I
+// 0000 1ddd iiii iiii
+// Load immediate value I (8-bit sign extended) to accumulator register.
+// FIXME: Perform additional operation depending on destination register.
+void lris(const UDSPInstruction& opc)
+{
+ u8 reg = ((opc.hex >> 8) & 0x7) + DSP_REG_AXL0;
+ u16 imm = (s8)opc.hex;
+ dsp_op_write_reg(reg, imm);
+ dsp_conditional_extend_accum(reg);
+}
+
+
+// TSTAXL $acR
+// 1000 r001 xxxx xxxx
+// r specifies one of the main accumulators.
+// Definitely not a test instruction - it changes the accums.
+// Not affected by m0/m2. Not affected by s16/s40.
+void tstaxl(const UDSPInstruction& opc)
+{
+ // This is probably all wrong.
+ //u8 reg = (opc.hex >> 8) & 0x1;
+ //s16 val = dsp_get_ax_l(reg);
+ //Update_SR_Register16(val);
+}
+
+// ADDARN $arD, $ixS
+// 0000 0000 0001 ssdd
+// Adds indexing register $ixS to an addressing register $arD.
+void addarn(const UDSPInstruction& opc)
+{
+ u8 dreg = opc.hex & 0x3;
+ u8 sreg = (opc.hex >> 2) & 0x3;
+
+ // g_dsp.r[dreg] += (s16)g_dsp.r[DSP_REG_IX0 + sreg];
+
+ dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
+
+ // It is critical for the Zelda ucode that this one wraps correctly.
+}
+
+// NX
+// 1000 -000 xxxx xxxx
+// No operation, but can be extended with extended opcode.
+void nx(const UDSPInstruction& opc)
+{
+ // This opcode is supposed to do nothing - it's used if you want to use
+ // an opcode extension but not do anything. At least according to duddie.
+}
+
+//-------------------------------------------------------------
+// DAR $arD ?
+// 0000 0000 0000 01dd
+// Decrement address register $arD.
+void dar(const UDSPInstruction& opc)
+{
+ dsp_decrement_addr_reg(opc.hex & 0x3);
+}
+
+// IAR $arD ?
+// 0000 0000 0000 10dd
+// Increment address register $arD.
+void iar(const UDSPInstruction& opc)
+{
+ dsp_increment_addr_reg(opc.hex & 0x3);
+}
+
+// SBCLR #I
+// 0001 0011 0000 0iii
+// bit of status register $sr. Bit number is calculated by adding 6 to
+// immediate value I.
+void sbclr(const UDSPInstruction& opc)
+{
+ u8 bit = (opc.hex & 0xff) + 6;
+ g_dsp.r[DSP_REG_SR] &= ~(1 << bit);
+}
+
+// SBSET #I
+// 0001 0010 0000 0iii
+// Set bit of status register $sr. Bit number is calculated by adding 6 to
+// immediate value I.
+void sbset(const UDSPInstruction& opc)
+{
+ u8 bit = (opc.hex & 0xff) + 6;
+ g_dsp.r[DSP_REG_SR] |= (1 << bit);
+}
+
+
+// FIXME inside
+// This is a bunch of flag setters, flipping bits in SR. So far so good,
+// but it's harder to know exactly what effect they have.
+// M0/M2 change the multiplier mode (it can multiply by 2 for free).
+//
+// SET16 changes something very important: see the LRI instruction above.
+// Hermes' demo sets the following defaults:
+// SET40
+// CLR15
+// M0
+void srbith(const UDSPInstruction& opc)
+{
+ switch ((opc.hex >> 8) & 0xf)
+ {
+ // M0 seems to be the default. M2 is used in functions in Zelda
+ // and then reset with M0 at the end. Like the other bits here, it's
+ // done around loops with lots of multiplications.
+ // I've confirmed with DSPSpy that they flip this bit.
+ case 0xa: // M2
+ g_dsp.r[DSP_REG_SR] &= ~SR_MUL_MODIFY;
+ break;
+ case 0xb: // M0
+ g_dsp.r[DSP_REG_SR] |= SR_MUL_MODIFY;
+ break;
+
+ // If set, treat multiplicands as unsigned.
+ // If clear, treat them as signed.
+ case 0xc: // CLR15
+ g_dsp.r[DSP_REG_SR] &= ~SR_MUL_UNSIGNED;
+ break;
+ case 0xd: // SET15
+ g_dsp.r[DSP_REG_SR] |= SR_MUL_UNSIGNED;
+ break;
+
+ // Automatic 40-bit sign extension when loading ACx.M.
+ // 40 seems to be the default.
+ // Confirmed these by using DSPSpy and copying the value of SR to R00 after setting.
+ case 0xe: // SET16 (really, clear SR's 0x4000)
+ g_dsp.r[DSP_REG_SR] &= ~SR_40_MODE_BIT;
+ break;
+
+ case 0xf: // SET40 (really, set SR's 0x4000)
+ g_dsp.r[DSP_REG_SR] |= SR_40_MODE_BIT;
+ break;
+
+ default:
+ break;
+ }
+}
+
+} // namespace
diff --git a/Source/Core/DSPCore/Src/DspIntMultiplier.cpp b/Source/Core/DSPCore/Src/DspIntMultiplier.cpp
index bf2e29fd62..13167e6fae 100644
--- a/Source/Core/DSPCore/Src/DspIntMultiplier.cpp
+++ b/Source/Core/DSPCore/Src/DspIntMultiplier.cpp
@@ -1,502 +1,502 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-// Additional copyrights go to Duddie and Tratax (c) 2004
-
-
-// Multiplier and product register control
-
-#include "DSPInterpreter.h"
-
-#include "DSPIntCCUtil.h"
-#include "DSPIntUtil.h"
-
-namespace DSPInterpreter {
-
-// Sets prod as a side effect.
-// Only MULX family instructions have unsigned support.
-s64 dsp_multiply_conditional_unsigned(u16 a, u16 b)
-{
- s64 prod;
-#if 0 // Makes games sound horrible. TODO: activate and figure out why - it's been verified through DSPSpy :/
- if (g_dsp.r[DSP_REG_SR] & SR_MUL_UNSIGNED)
- prod = (u64)a * (u64)b; // won't overflow 32-bits
- else
-#endif
- prod = (s32)(s16)a * (s32)(s16)b; // won't overflow 32-bits
-
- // Conditionally multiply by 2.
- if ((g_dsp.r[DSP_REG_SR] & SR_MUL_MODIFY) == 0)
- prod <<= 1;
-
- // Store the product, and return it, in case the caller wants to read it.
- dsp_set_long_prod(prod);
- return prod;
-}
-
-// Sets prod as a side effect.
-s64 dsp_multiply(u16 a, u16 b)
-{
- s64 prod;
- prod = (s32)(s16)a * (s32)(s16)b; // won't overflow 32-bits
-
- // Conditionally multiply by 2.
- if ((g_dsp.r[DSP_REG_SR] & SR_MUL_MODIFY) == 0)
- prod <<= 1;
-
- // Store the product, and return it, in case the caller wants to read it.
- dsp_set_long_prod(prod);
- return prod;
-}
-
-s64 dsp_multiply_add(u16 a, u16 b)
-{
- s64 prod = (s32)(s16)a * (s32)(s16)b; // won't overflow 32-bits
-
- // Conditionally multiply by 2.
- if ((g_dsp.r[DSP_REG_SR] & SR_MUL_MODIFY) == 0)
- prod <<= 1;
-
- // Add the original prod value.
- prod += dsp_get_long_prod();
-
- // Store the product, and return it, in case the caller wants to read it.
- dsp_set_long_prod(prod);
- return prod;
-}
-
-s64 dsp_multiply_sub(u16 a, u16 b)
-{
- s64 prod = (s32)(s16)a * (s32)(s16)b; // won't overflow 32-bits
-
- // Conditionally multiply by 2.
- if ((g_dsp.r[DSP_REG_SR] & SR_MUL_MODIFY) == 0)
- prod <<= 1;
-
- // Subtract from the original prod value.
- prod = dsp_get_long_prod() - prod;
-
- // Store the product, and return it, in case the caller wants to read it.
- dsp_set_long_prod(prod);
- return prod;
-}
-
-
-
-// CLRP
-// 1000 0100 xxxx xxxx
-// Clears product register $prod.
-void clrp(const UDSPInstruction& opc)
-{
- // Magic numbers taken from duddie's doc
- // These are probably a bad idea to put here.
- g_dsp.r[0x14] = 0x0000;
- g_dsp.r[0x15] = 0xfff0;
- g_dsp.r[0x16] = 0x00ff;
- g_dsp.r[0x17] = 0x0010;
-}
-
-// MOVP $acD
-// 0110 111d xxxx xxxx
-// Moves multiply product from $prod register to accumulator $acD register.
-void movp(const UDSPInstruction& opc)
-{
- u8 dreg = (opc.hex >> 8) & 0x1;
-
- s64 prod = dsp_get_long_prod();
- dsp_set_long_acc(dreg, prod);
-
- Update_SR_Register64(prod);
-}
-
-// MOVNP $acD
-// 0111 111d xxxx xxxx
-// Moves negative of multiply product from $prod register to accumulator
-// $acD register.
-void movnp(const UDSPInstruction& opc)
-{
- u8 dreg = (opc.hex >> 8) & 0x1;
-
- s64 prod = dsp_get_long_prod();
- s64 acc = -prod;
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// ADDPAXZ $acD, $axS
-// 1111 10sd xxxx xxxx
-// Adds secondary accumulator $axS to product register and stores result
-// in accumulator register. Low 16-bits of $acD ($acD.l) are set to 0.
-void addpaxz(const UDSPInstruction& opc)
-{
- u8 dreg = (opc.hex >> 8) & 0x1;
- u8 sreg = (opc.hex >> 9) & 0x1;
-
- s64 prod = dsp_get_long_prod() & ~0xffff; // hm, should we really mask here?
- s64 ax = dsp_get_long_acx(sreg);
- s64 acc = (prod + ax) & ~0xffff;
-
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// MOVPZ $acD
-// 1111 111d xxxx xxxx
-// Moves multiply product from $prod register to accumulator $acD
-// register and sets $acD.l to 0
-void movpz(const UDSPInstruction& opc)
-{
- u8 dreg = (opc.hex >> 8) & 0x01;
-
- // overwrite acc and clear low part
- s64 prod = dsp_get_long_prod();
- s64 acc = prod & ~0xffff;
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register64(acc);
-}
-
-
-// MULC $acS.m, $axT.h
-// 110s t000 xxxx xxxx
-// Multiply mid part of accumulator register $acS.m by high part $axS.h of
-// secondary accumulator $axS (treat them both as signed).
-void mulc(const UDSPInstruction& opc)
-{
- u8 sreg = (opc.hex >> 11) & 0x1;
- u8 treg = (opc.hex >> 12) & 0x1;
- s64 prod = dsp_multiply(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
- Update_SR_Register64(prod);
-}
-
-// MULCMVZ $acS.m, $axT.h, $acR
-// 110s t01r xxxx xxxx
-// (fixed possible bug in duddie's description, s->t)
-// Multiply mid part of accumulator register $acS.m by high part $axT.h of
-// secondary accumulator $axT (treat them both as signed). Move product
-// register before multiplication to accumulator $acR, set low part of
-// accumulator $acR.l to zero.
-void mulcmvz(const UDSPInstruction& opc)
-{
- s64 TempProd = dsp_get_long_prod();
-
- // update prod
- u8 sreg = (opc.hex >> 12) & 0x1;
- u8 treg = (opc.hex >> 11) & 0x1;
- dsp_multiply(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
-
- // update acc
- u8 rreg = (opc.hex >> 8) & 0x1;
- s64 acc = TempProd & ~0xffff; // clear lower 4 bytes
- dsp_set_long_acc(rreg, acc);
-
- Update_SR_Register64(acc);
-}
-
-// MULCMV $acS.m, $axT.h, $acR
-// 110s t11r xxxx xxxx
-// Multiply mid part of accumulator register $acS.m by high part $axT.h of
-// secondary accumulator $axT (treat them both as signed). Move product
-// register before multiplication to accumulator $acR.
-// possible mistake in duddie's doc axT.h rather than axS.h
-void mulcmv(const UDSPInstruction& opc)
-{
- s64 old_prod = dsp_get_long_prod();
-
- // update prod
- u8 sreg = (opc.hex >> 12) & 0x1;
- u8 treg = (opc.hex >> 11) & 0x1;
- dsp_multiply(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
-
- // update acc
- u8 rreg = (opc.hex >> 8) & 0x1;
- dsp_set_long_acc(rreg, old_prod);
-
- Update_SR_Register64(old_prod);
-}
-
-// MULCAC $acS.m, $axT.h, $acR
-// 110s t10r xxxx xxxx
-// Multiply mid part of accumulator register $acS.m by high part $axS.h of
-// secondary accumulator $axS (treat them both as signed). Add product
-// register before multiplication to accumulator $acR.
-void mulcac(const UDSPInstruction& opc)
-{
- s64 old_prod = dsp_get_long_prod();
-
- // update prod
- u8 sreg = (opc.hex >> 12) & 0x1;
- u8 treg = (opc.hex >> 11) & 0x1;
- dsp_multiply(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
-
- // update acc
- u8 rreg = (opc.hex >> 8) & 0x1;
- s64 acc = old_prod + dsp_get_long_acc(rreg);
- dsp_set_long_acc(rreg, acc);
-
- Update_SR_Register64(acc);
-}
-
-
-// MUL $axS.l, $axS.h
-// 1001 s000 xxxx xxxx
-// Multiply low part $axS.l of secondary accumulator $axS by high part
-// $axS.h of secondary accumulator $axS (treat them both as signed).
-void mul(const UDSPInstruction& opc)
-{
- u8 sreg = (opc.hex >> 11) & 0x1;
- s64 prod = dsp_multiply(dsp_get_ax_h(sreg), dsp_get_ax_l(sreg));
- // FIXME: no update in duddie's docs
- Update_SR_Register64(prod);
-}
-
-// MULAC $axS.l, $axS.h, $acR
-// 1001 s10r xxxx xxxx
-// Add product register to accumulator register $acR. Multiply low part
-// $axS.l of secondary accumulator $axS by high part $axS.h of secondary
-// accumulator $axS (treat them both as signed).
-void mulac(const UDSPInstruction& opc)
-{
- // add old prod to acc
- u8 rreg = (opc.hex >> 8) & 0x1;
- s64 acR = dsp_get_long_acc(rreg) + dsp_get_long_prod();
- dsp_set_long_acc(rreg, acR);
-
- // calculate new prod
- u8 sreg = (opc.hex >> 11) & 0x1;
- s64 prod = dsp_multiply(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg));
-
- // FIXME: no update in duddie's docs
- Update_SR_Register64(prod);
-}
-
-// MULMV $axS.l, $axS.h, $acR
-// 1001 s11r xxxx xxxx
-// Move product register to accumulator register $acR. Multiply low part
-// $axS.l of secondary accumulator $axS by high part $axS.h of secondary
-// accumulator $axS (treat them both as signed).
-void mulmv(const UDSPInstruction& opc)
-{
- u8 rreg = (opc.hex >> 8) & 0x1;
- u8 sreg = ((opc.hex >> 11) & 0x1);
- s64 prod = dsp_get_long_prod();
- s64 acc = prod;
- dsp_set_long_acc(rreg, acc);
-
- prod = dsp_multiply(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg));
- Update_SR_Register64(prod);
-}
-
-// MULMVZ $axS.l, $axS.h, $acR
-// 1001 s01r xxxx xxxx
-// Move product register to accumulator register $acR and clear low part
-// of accumulator register $acR.l. Multiply low part $axS.l of secondary
-// accumulator $axS by high part $axS.h of secondary accumulator $axS (treat
-// them both as signed).
-void mulmvz(const UDSPInstruction& opc)
-{
- u8 sreg = (opc.hex >> 11) & 0x1;
- u8 rreg = (opc.hex >> 8) & 0x1;
-
- // overwrite acc and clear low part
- s64 prod = dsp_get_long_prod();
- s64 acc = prod & ~0xffff;
- dsp_set_long_acc(rreg, acc);
-
- // math prod
- prod = dsp_multiply(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg));
- Update_SR_Register64(prod);
-}
-
-// MULX $ax0.S, $ax1.T
-// 101s t000 xxxx xxxx
-// Multiply one part $ax0 by one part $ax1 (treat them both as signed).
-// Part is selected by S and T bits. Zero selects low part, one selects high part.
-void mulx(const UDSPInstruction& opc)
-{
- u8 sreg = ((opc.hex >> 12) & 0x1);
- u8 treg = ((opc.hex >> 11) & 0x1);
-
- u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
- u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
-
- s64 prod = dsp_multiply_conditional_unsigned(val1, val2);
- Update_SR_Register64(prod);
-}
-
-// MULXAC $ax0.S, $ax1.T, $acR
-// 101s t01r xxxx xxxx
-// Add product register to accumulator register $acR. Multiply one part
-// $ax0 by one part $ax1 (treat them both as signed). Part is selected by S and
-// T bits. Zero selects low part, one selects high part.
-void mulxac(const UDSPInstruction& opc)
-{
- // add old prod to acc
- u8 rreg = (opc.hex >> 8) & 0x1;
- s64 acR = dsp_get_long_acc(rreg) + dsp_get_long_prod();
- dsp_set_long_acc(rreg, acR);
-
- // math new prod
- u8 sreg = (opc.hex >> 12) & 0x1;
- u8 treg = (opc.hex >> 11) & 0x1;
-
- u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
- u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
-
- s64 prod = dsp_multiply_conditional_unsigned(val1, val2);
- Update_SR_Register64(prod);
-}
-
-// MULXMV $ax0.S, $ax1.T, $acR
-// 101s t11r xxxx xxxx
-// Move product register to accumulator register $acR. Multiply one part
-// $ax0 by one part $ax1 (treat them both as signed). Part is selected by S and
-// T bits. Zero selects low part, one selects high part.
-void mulxmv(const UDSPInstruction& opc)
-{
- // add old prod to acc
- u8 rreg = ((opc.hex >> 8) & 0x1);
- s64 acR = dsp_get_long_prod();
- dsp_set_long_acc(rreg, acR);
-
- // math new prod
- u8 sreg = (opc.hex >> 12) & 0x1;
- u8 treg = (opc.hex >> 11) & 0x1;
-
- s16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
- s16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
-
- s64 prod = dsp_multiply_conditional_unsigned(val1, val2);
- Update_SR_Register64(prod);
-}
-
-// MULXMV $ax0.S, $ax1.T, $acR
-// 101s t01r xxxx xxxx
-// Move product register to accumulator register $acR and clear low part
-// of accumulator register $acR.l. Multiply one part $ax0 by one part $ax1 (treat
-// them both as signed). Part is selected by S and T bits. Zero selects low part,
-// one selects high part.
-void mulxmvz(const UDSPInstruction& opc)
-{
- // overwrite acc and clear low part
- u8 rreg = (opc.hex >> 8) & 0x1;
- s64 prod = dsp_get_long_prod();
- s64 acc = prod & ~0xffff;
- dsp_set_long_acc(rreg, acc);
-
- // math prod
- u8 sreg = (opc.hex >> 12) & 0x1;
- u8 treg = (opc.hex >> 11) & 0x1;
-
- u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
- u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
-
- prod = dsp_multiply_conditional_unsigned(val1, val2);
- Update_SR_Register64(prod);
-}
-
-// MADDX ax0.S ax1.T
-// 1110 00st xxxx xxxx
-// Multiply one part of secondary accumulator $ax0 (selected by S) by
-// one part of secondary accumulator $ax1 (selected by T) (treat them both as
-// signed) and add result to product register.
-void maddx(const UDSPInstruction& opc)
-{
- u8 sreg = (opc.hex >> 9) & 0x1;
- u8 treg = (opc.hex >> 8) & 0x1;
-
- u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
- u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
-
- s64 prod = dsp_multiply_add(val1, val2);
- Update_SR_Register64(prod);
-}
-
-// MSUBX $(0x18+S*2), $(0x19+T*2)
-// 1110 01st xxxx xxxx
-// Multiply one part of secondary accumulator $ax0 (selected by S) by
-// one part of secondary accumulator $ax1 (selected by T) (treat them both as
-// signed) and subtract result from product register.
-void msubx(const UDSPInstruction& opc)
-{
- u8 sreg = (opc.hex >> 9) & 0x1;
- u8 treg = (opc.hex >> 8) & 0x1;
-
- u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
- u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
-
- s64 prod = dsp_multiply_sub(val1, val2);
- Update_SR_Register64(prod);
-}
-
-// MADDC $acS.m, $axT.h
-// 1110 10st xxxx xxxx
-// Multiply middle part of accumulator $acS.m by high part of secondary
-// accumulator $axT.h (treat them both as signed) and add result to product
-// register.
-void maddc(const UDSPInstruction& opc)
-{
- u32 sreg = (opc.hex >> 9) & 0x1;
- u32 treg = (opc.hex >> 8) & 0x1;
-
- s64 prod = dsp_multiply_add(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
- Update_SR_Register64(prod);
-}
-
-// MSUBC $acS.m, $axT.h
-// 1110 11st xxxx xxxx
-// Multiply middle part of accumulator $acS.m by high part of secondary
-// accumulator $axT.h (treat them both as signed) and subtract result from
-// product register.
-void msubc(const UDSPInstruction& opc)
-{
- u32 sreg = (opc.hex >> 9) & 0x1;
- u32 treg = (opc.hex >> 8) & 0x1;
-
- s64 prod = dsp_multiply_sub(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
- Update_SR_Register64(prod);
-}
-
-// MADD $axS.l, $axS.h
-// 1111 001s xxxx xxxx
-// Multiply low part $axS.l of secondary accumulator $axS by high part
-// $axS.h of secondary accumulator $axS (treat them both as signed) and add
-// result to product register.
-void madd(const UDSPInstruction& opc)
-{
- u8 sreg = (opc.hex >> 8) & 0x1;
-
- s64 prod = dsp_multiply_add(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg));
- Update_SR_Register64(prod);
-}
-
-// MSUB $axS.l, $axS.h
-// 1111 011s xxxx xxxx
-// Multiply low part $axS.l of secondary accumulator $axS by high part
-// $axS.h of secondary accumulator $axS (treat them both as signed) and
-// subtract result from product register.
-void msub(const UDSPInstruction& opc)
-{
- u8 sreg = (opc.hex >> 8) & 0x1;
-
- s64 prod = dsp_multiply_sub(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg));
- Update_SR_Register64(prod);
-}
-
-} // namespace
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Additional copyrights go to Duddie and Tratax (c) 2004
+
+
+// Multiplier and product register control
+
+#include "DSPInterpreter.h"
+
+#include "DSPIntCCUtil.h"
+#include "DSPIntUtil.h"
+
+namespace DSPInterpreter {
+
+// Sets prod as a side effect.
+// Only MULX family instructions have unsigned support.
+s64 dsp_multiply_conditional_unsigned(u16 a, u16 b)
+{
+ s64 prod;
+#if 0 // Makes games sound horrible. TODO: activate and figure out why - it's been verified through DSPSpy :/
+ if (g_dsp.r[DSP_REG_SR] & SR_MUL_UNSIGNED)
+ prod = (u64)a * (u64)b; // won't overflow 32-bits
+ else
+#endif
+ prod = (s32)(s16)a * (s32)(s16)b; // won't overflow 32-bits
+
+ // Conditionally multiply by 2.
+ if ((g_dsp.r[DSP_REG_SR] & SR_MUL_MODIFY) == 0)
+ prod <<= 1;
+
+ // Store the product, and return it, in case the caller wants to read it.
+ dsp_set_long_prod(prod);
+ return prod;
+}
+
+// Sets prod as a side effect.
+s64 dsp_multiply(u16 a, u16 b)
+{
+ s64 prod;
+ prod = (s32)(s16)a * (s32)(s16)b; // won't overflow 32-bits
+
+ // Conditionally multiply by 2.
+ if ((g_dsp.r[DSP_REG_SR] & SR_MUL_MODIFY) == 0)
+ prod <<= 1;
+
+ // Store the product, and return it, in case the caller wants to read it.
+ dsp_set_long_prod(prod);
+ return prod;
+}
+
+s64 dsp_multiply_add(u16 a, u16 b)
+{
+ s64 prod = (s32)(s16)a * (s32)(s16)b; // won't overflow 32-bits
+
+ // Conditionally multiply by 2.
+ if ((g_dsp.r[DSP_REG_SR] & SR_MUL_MODIFY) == 0)
+ prod <<= 1;
+
+ // Add the original prod value.
+ prod += dsp_get_long_prod();
+
+ // Store the product, and return it, in case the caller wants to read it.
+ dsp_set_long_prod(prod);
+ return prod;
+}
+
+s64 dsp_multiply_sub(u16 a, u16 b)
+{
+ s64 prod = (s32)(s16)a * (s32)(s16)b; // won't overflow 32-bits
+
+ // Conditionally multiply by 2.
+ if ((g_dsp.r[DSP_REG_SR] & SR_MUL_MODIFY) == 0)
+ prod <<= 1;
+
+ // Subtract from the original prod value.
+ prod = dsp_get_long_prod() - prod;
+
+ // Store the product, and return it, in case the caller wants to read it.
+ dsp_set_long_prod(prod);
+ return prod;
+}
+
+
+
+// CLRP
+// 1000 0100 xxxx xxxx
+// Clears product register $prod.
+void clrp(const UDSPInstruction& opc)
+{
+ // Magic numbers taken from duddie's doc
+ // These are probably a bad idea to put here.
+ g_dsp.r[0x14] = 0x0000;
+ g_dsp.r[0x15] = 0xfff0;
+ g_dsp.r[0x16] = 0x00ff;
+ g_dsp.r[0x17] = 0x0010;
+}
+
+// MOVP $acD
+// 0110 111d xxxx xxxx
+// Moves multiply product from $prod register to accumulator $acD register.
+void movp(const UDSPInstruction& opc)
+{
+ u8 dreg = (opc.hex >> 8) & 0x1;
+
+ s64 prod = dsp_get_long_prod();
+ dsp_set_long_acc(dreg, prod);
+
+ Update_SR_Register64(prod);
+}
+
+// MOVNP $acD
+// 0111 111d xxxx xxxx
+// Moves negative of multiply product from $prod register to accumulator
+// $acD register.
+void movnp(const UDSPInstruction& opc)
+{
+ u8 dreg = (opc.hex >> 8) & 0x1;
+
+ s64 prod = dsp_get_long_prod();
+ s64 acc = -prod;
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// ADDPAXZ $acD, $axS
+// 1111 10sd xxxx xxxx
+// Adds secondary accumulator $axS to product register and stores result
+// in accumulator register. Low 16-bits of $acD ($acD.l) are set to 0.
+void addpaxz(const UDSPInstruction& opc)
+{
+ u8 dreg = (opc.hex >> 8) & 0x1;
+ u8 sreg = (opc.hex >> 9) & 0x1;
+
+ s64 prod = dsp_get_long_prod() & ~0xffff; // hm, should we really mask here?
+ s64 ax = dsp_get_long_acx(sreg);
+ s64 acc = (prod + ax) & ~0xffff;
+
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// MOVPZ $acD
+// 1111 111d xxxx xxxx
+// Moves multiply product from $prod register to accumulator $acD
+// register and sets $acD.l to 0
+void movpz(const UDSPInstruction& opc)
+{
+ u8 dreg = (opc.hex >> 8) & 0x01;
+
+ // overwrite acc and clear low part
+ s64 prod = dsp_get_long_prod();
+ s64 acc = prod & ~0xffff;
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+
+// MULC $acS.m, $axT.h
+// 110s t000 xxxx xxxx
+// Multiply mid part of accumulator register $acS.m by high part $axS.h of
+// secondary accumulator $axS (treat them both as signed).
+void mulc(const UDSPInstruction& opc)
+{
+ u8 sreg = (opc.hex >> 11) & 0x1;
+ u8 treg = (opc.hex >> 12) & 0x1;
+ s64 prod = dsp_multiply(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
+ Update_SR_Register64(prod);
+}
+
+// MULCMVZ $acS.m, $axT.h, $acR
+// 110s t01r xxxx xxxx
+// (fixed possible bug in duddie's description, s->t)
+// Multiply mid part of accumulator register $acS.m by high part $axT.h of
+// secondary accumulator $axT (treat them both as signed). Move product
+// register before multiplication to accumulator $acR, set low part of
+// accumulator $acR.l to zero.
+void mulcmvz(const UDSPInstruction& opc)
+{
+ s64 TempProd = dsp_get_long_prod();
+
+ // update prod
+ u8 sreg = (opc.hex >> 12) & 0x1;
+ u8 treg = (opc.hex >> 11) & 0x1;
+ dsp_multiply(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
+
+ // update acc
+ u8 rreg = (opc.hex >> 8) & 0x1;
+ s64 acc = TempProd & ~0xffff; // clear lower 4 bytes
+ dsp_set_long_acc(rreg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+// MULCMV $acS.m, $axT.h, $acR
+// 110s t11r xxxx xxxx
+// Multiply mid part of accumulator register $acS.m by high part $axT.h of
+// secondary accumulator $axT (treat them both as signed). Move product
+// register before multiplication to accumulator $acR.
+// possible mistake in duddie's doc axT.h rather than axS.h
+void mulcmv(const UDSPInstruction& opc)
+{
+ s64 old_prod = dsp_get_long_prod();
+
+ // update prod
+ u8 sreg = (opc.hex >> 12) & 0x1;
+ u8 treg = (opc.hex >> 11) & 0x1;
+ dsp_multiply(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
+
+ // update acc
+ u8 rreg = (opc.hex >> 8) & 0x1;
+ dsp_set_long_acc(rreg, old_prod);
+
+ Update_SR_Register64(old_prod);
+}
+
+// MULCAC $acS.m, $axT.h, $acR
+// 110s t10r xxxx xxxx
+// Multiply mid part of accumulator register $acS.m by high part $axS.h of
+// secondary accumulator $axS (treat them both as signed). Add product
+// register before multiplication to accumulator $acR.
+void mulcac(const UDSPInstruction& opc)
+{
+ s64 old_prod = dsp_get_long_prod();
+
+ // update prod
+ u8 sreg = (opc.hex >> 12) & 0x1;
+ u8 treg = (opc.hex >> 11) & 0x1;
+ dsp_multiply(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
+
+ // update acc
+ u8 rreg = (opc.hex >> 8) & 0x1;
+ s64 acc = old_prod + dsp_get_long_acc(rreg);
+ dsp_set_long_acc(rreg, acc);
+
+ Update_SR_Register64(acc);
+}
+
+
+// MUL $axS.l, $axS.h
+// 1001 s000 xxxx xxxx
+// Multiply low part $axS.l of secondary accumulator $axS by high part
+// $axS.h of secondary accumulator $axS (treat them both as signed).
+void mul(const UDSPInstruction& opc)
+{
+ u8 sreg = (opc.hex >> 11) & 0x1;
+ s64 prod = dsp_multiply(dsp_get_ax_h(sreg), dsp_get_ax_l(sreg));
+ // FIXME: no update in duddie's docs
+ Update_SR_Register64(prod);
+}
+
+// MULAC $axS.l, $axS.h, $acR
+// 1001 s10r xxxx xxxx
+// Add product register to accumulator register $acR. Multiply low part
+// $axS.l of secondary accumulator $axS by high part $axS.h of secondary
+// accumulator $axS (treat them both as signed).
+void mulac(const UDSPInstruction& opc)
+{
+ // add old prod to acc
+ u8 rreg = (opc.hex >> 8) & 0x1;
+ s64 acR = dsp_get_long_acc(rreg) + dsp_get_long_prod();
+ dsp_set_long_acc(rreg, acR);
+
+ // calculate new prod
+ u8 sreg = (opc.hex >> 11) & 0x1;
+ s64 prod = dsp_multiply(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg));
+
+ // FIXME: no update in duddie's docs
+ Update_SR_Register64(prod);
+}
+
+// MULMV $axS.l, $axS.h, $acR
+// 1001 s11r xxxx xxxx
+// Move product register to accumulator register $acR. Multiply low part
+// $axS.l of secondary accumulator $axS by high part $axS.h of secondary
+// accumulator $axS (treat them both as signed).
+void mulmv(const UDSPInstruction& opc)
+{
+ u8 rreg = (opc.hex >> 8) & 0x1;
+ u8 sreg = ((opc.hex >> 11) & 0x1);
+ s64 prod = dsp_get_long_prod();
+ s64 acc = prod;
+ dsp_set_long_acc(rreg, acc);
+
+ prod = dsp_multiply(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg));
+ Update_SR_Register64(prod);
+}
+
+// MULMVZ $axS.l, $axS.h, $acR
+// 1001 s01r xxxx xxxx
+// Move product register to accumulator register $acR and clear low part
+// of accumulator register $acR.l. Multiply low part $axS.l of secondary
+// accumulator $axS by high part $axS.h of secondary accumulator $axS (treat
+// them both as signed).
+void mulmvz(const UDSPInstruction& opc)
+{
+ u8 sreg = (opc.hex >> 11) & 0x1;
+ u8 rreg = (opc.hex >> 8) & 0x1;
+
+ // overwrite acc and clear low part
+ s64 prod = dsp_get_long_prod();
+ s64 acc = prod & ~0xffff;
+ dsp_set_long_acc(rreg, acc);
+
+ // math prod
+ prod = dsp_multiply(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg));
+ Update_SR_Register64(prod);
+}
+
+// MULX $ax0.S, $ax1.T
+// 101s t000 xxxx xxxx
+// Multiply one part $ax0 by one part $ax1 (treat them both as signed).
+// Part is selected by S and T bits. Zero selects low part, one selects high part.
+void mulx(const UDSPInstruction& opc)
+{
+ u8 sreg = ((opc.hex >> 12) & 0x1);
+ u8 treg = ((opc.hex >> 11) & 0x1);
+
+ u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
+ u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
+
+ s64 prod = dsp_multiply_conditional_unsigned(val1, val2);
+ Update_SR_Register64(prod);
+}
+
+// MULXAC $ax0.S, $ax1.T, $acR
+// 101s t01r xxxx xxxx
+// Add product register to accumulator register $acR. Multiply one part
+// $ax0 by one part $ax1 (treat them both as signed). Part is selected by S and
+// T bits. Zero selects low part, one selects high part.
+void mulxac(const UDSPInstruction& opc)
+{
+ // add old prod to acc
+ u8 rreg = (opc.hex >> 8) & 0x1;
+ s64 acR = dsp_get_long_acc(rreg) + dsp_get_long_prod();
+ dsp_set_long_acc(rreg, acR);
+
+ // math new prod
+ u8 sreg = (opc.hex >> 12) & 0x1;
+ u8 treg = (opc.hex >> 11) & 0x1;
+
+ u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
+ u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
+
+ s64 prod = dsp_multiply_conditional_unsigned(val1, val2);
+ Update_SR_Register64(prod);
+}
+
+// MULXMV $ax0.S, $ax1.T, $acR
+// 101s t11r xxxx xxxx
+// Move product register to accumulator register $acR. Multiply one part
+// $ax0 by one part $ax1 (treat them both as signed). Part is selected by S and
+// T bits. Zero selects low part, one selects high part.
+void mulxmv(const UDSPInstruction& opc)
+{
+ // add old prod to acc
+ u8 rreg = ((opc.hex >> 8) & 0x1);
+ s64 acR = dsp_get_long_prod();
+ dsp_set_long_acc(rreg, acR);
+
+ // math new prod
+ u8 sreg = (opc.hex >> 12) & 0x1;
+ u8 treg = (opc.hex >> 11) & 0x1;
+
+ s16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
+ s16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
+
+ s64 prod = dsp_multiply_conditional_unsigned(val1, val2);
+ Update_SR_Register64(prod);
+}
+
+// MULXMV $ax0.S, $ax1.T, $acR
+// 101s t01r xxxx xxxx
+// Move product register to accumulator register $acR and clear low part
+// of accumulator register $acR.l. Multiply one part $ax0 by one part $ax1 (treat
+// them both as signed). Part is selected by S and T bits. Zero selects low part,
+// one selects high part.
+void mulxmvz(const UDSPInstruction& opc)
+{
+ // overwrite acc and clear low part
+ u8 rreg = (opc.hex >> 8) & 0x1;
+ s64 prod = dsp_get_long_prod();
+ s64 acc = prod & ~0xffff;
+ dsp_set_long_acc(rreg, acc);
+
+ // math prod
+ u8 sreg = (opc.hex >> 12) & 0x1;
+ u8 treg = (opc.hex >> 11) & 0x1;
+
+ u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
+ u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
+
+ prod = dsp_multiply_conditional_unsigned(val1, val2);
+ Update_SR_Register64(prod);
+}
+
+// MADDX ax0.S ax1.T
+// 1110 00st xxxx xxxx
+// Multiply one part of secondary accumulator $ax0 (selected by S) by
+// one part of secondary accumulator $ax1 (selected by T) (treat them both as
+// signed) and add result to product register.
+void maddx(const UDSPInstruction& opc)
+{
+ u8 sreg = (opc.hex >> 9) & 0x1;
+ u8 treg = (opc.hex >> 8) & 0x1;
+
+ u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
+ u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
+
+ s64 prod = dsp_multiply_add(val1, val2);
+ Update_SR_Register64(prod);
+}
+
+// MSUBX $(0x18+S*2), $(0x19+T*2)
+// 1110 01st xxxx xxxx
+// Multiply one part of secondary accumulator $ax0 (selected by S) by
+// one part of secondary accumulator $ax1 (selected by T) (treat them both as
+// signed) and subtract result from product register.
+void msubx(const UDSPInstruction& opc)
+{
+ u8 sreg = (opc.hex >> 9) & 0x1;
+ u8 treg = (opc.hex >> 8) & 0x1;
+
+ u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
+ u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
+
+ s64 prod = dsp_multiply_sub(val1, val2);
+ Update_SR_Register64(prod);
+}
+
+// MADDC $acS.m, $axT.h
+// 1110 10st xxxx xxxx
+// Multiply middle part of accumulator $acS.m by high part of secondary
+// accumulator $axT.h (treat them both as signed) and add result to product
+// register.
+void maddc(const UDSPInstruction& opc)
+{
+ u32 sreg = (opc.hex >> 9) & 0x1;
+ u32 treg = (opc.hex >> 8) & 0x1;
+
+ s64 prod = dsp_multiply_add(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
+ Update_SR_Register64(prod);
+}
+
+// MSUBC $acS.m, $axT.h
+// 1110 11st xxxx xxxx
+// Multiply middle part of accumulator $acS.m by high part of secondary
+// accumulator $axT.h (treat them both as signed) and subtract result from
+// product register.
+void msubc(const UDSPInstruction& opc)
+{
+ u32 sreg = (opc.hex >> 9) & 0x1;
+ u32 treg = (opc.hex >> 8) & 0x1;
+
+ s64 prod = dsp_multiply_sub(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
+ Update_SR_Register64(prod);
+}
+
+// MADD $axS.l, $axS.h
+// 1111 001s xxxx xxxx
+// Multiply low part $axS.l of secondary accumulator $axS by high part
+// $axS.h of secondary accumulator $axS (treat them both as signed) and add
+// result to product register.
+void madd(const UDSPInstruction& opc)
+{
+ u8 sreg = (opc.hex >> 8) & 0x1;
+
+ s64 prod = dsp_multiply_add(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg));
+ Update_SR_Register64(prod);
+}
+
+// MSUB $axS.l, $axS.h
+// 1111 011s xxxx xxxx
+// Multiply low part $axS.l of secondary accumulator $axS by high part
+// $axS.h of secondary accumulator $axS (treat them both as signed) and
+// subtract result from product register.
+void msub(const UDSPInstruction& opc)
+{
+ u8 sreg = (opc.hex >> 8) & 0x1;
+
+ s64 prod = dsp_multiply_sub(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg));
+ Update_SR_Register64(prod);
+}
+
+} // namespace
diff --git a/Source/Core/DSPCore/Src/LabelMap.cpp b/Source/Core/DSPCore/Src/LabelMap.cpp
index 6d3a475857..2765d302b9 100644
--- a/Source/Core/DSPCore/Src/LabelMap.cpp
+++ b/Source/Core/DSPCore/Src/LabelMap.cpp
@@ -1,85 +1,85 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "LabelMap.h"
-#include "DSPTables.h"
-
-LabelMap::LabelMap()
-{
-
-}
-
-void LabelMap::RegisterDefaults()
-{
- for (int i = 0; i < 0x24; i++)
- {
- if (regnames[i].name)
- RegisterLabel(regnames[i].name, regnames[i].addr);
- }
- for (int i = 0; i < (int)pdlabels_size; i++)
- {
- if (pdlabels[i].name)
- RegisterLabel(pdlabels[i].name, pdlabels[i].addr);
- }
-}
-
-void LabelMap::RegisterLabel(const std::string &label, u16 lval, LabelType type)
-{
- u16 old_value;
- if (GetLabelValue(label, &old_value) && old_value != lval)
- {
- printf("WARNING: Redefined label %s to %04x - old value %04x\n",
- label.c_str(), lval, old_value);
- DeleteLabel(label);
- }
- labels.push_back(label_t(label, lval, type));
-}
-
-void LabelMap::DeleteLabel(const std::string &label)
-{
- for (std::vector<label_t>::iterator iter = labels.begin();
- iter != labels.end(); ++iter)
- {
- if (!label.compare(iter->name))
- {
- labels.erase(iter);
- return;
- }
- }
-}
-
-bool LabelMap::GetLabelValue(const std::string &label, u16 *value, LabelType type) const
-{
- for (u32 i = 0; i < labels.size(); i++)
- {
- if (!label.compare(labels[i].name))
- {
- if (type & labels[i].type) {
- *value = labels[i].addr;
- return true;
- } else {
- printf("WARNING: Wrong label type requested. %s\n", label.c_str());
- }
- }
- }
- return false;
-}
-
-void LabelMap::Clear()
-{
- labels.clear();
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "LabelMap.h"
+#include "DSPTables.h"
+
+LabelMap::LabelMap()
+{
+
+}
+
+void LabelMap::RegisterDefaults()
+{
+ for (int i = 0; i < 0x24; i++)
+ {
+ if (regnames[i].name)
+ RegisterLabel(regnames[i].name, regnames[i].addr);
+ }
+ for (int i = 0; i < (int)pdlabels_size; i++)
+ {
+ if (pdlabels[i].name)
+ RegisterLabel(pdlabels[i].name, pdlabels[i].addr);
+ }
+}
+
+void LabelMap::RegisterLabel(const std::string &label, u16 lval, LabelType type)
+{
+ u16 old_value;
+ if (GetLabelValue(label, &old_value) && old_value != lval)
+ {
+ printf("WARNING: Redefined label %s to %04x - old value %04x\n",
+ label.c_str(), lval, old_value);
+ DeleteLabel(label);
+ }
+ labels.push_back(label_t(label, lval, type));
+}
+
+void LabelMap::DeleteLabel(const std::string &label)
+{
+ for (std::vector<label_t>::iterator iter = labels.begin();
+ iter != labels.end(); ++iter)
+ {
+ if (!label.compare(iter->name))
+ {
+ labels.erase(iter);
+ return;
+ }
+ }
+}
+
+bool LabelMap::GetLabelValue(const std::string &label, u16 *value, LabelType type) const
+{
+ for (u32 i = 0; i < labels.size(); i++)
+ {
+ if (!label.compare(labels[i].name))
+ {
+ if (type & labels[i].type) {
+ *value = labels[i].addr;
+ return true;
+ } else {
+ printf("WARNING: Wrong label type requested. %s\n", label.c_str());
+ }
+ }
+ }
+ return false;
+}
+
+void LabelMap::Clear()
+{
+ labels.clear();
+}
diff --git a/Source/Core/DSPCore/Src/LabelMap.h b/Source/Core/DSPCore/Src/LabelMap.h
index 3b37712204..6fceef7347 100644
--- a/Source/Core/DSPCore/Src/LabelMap.h
+++ b/Source/Core/DSPCore/Src/LabelMap.h
@@ -1,55 +1,55 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _LABELMAP_H
-#define _LABELMAP_H
-
-#include <string>
-#include <vector>
-
-#include "Common.h"
-
-enum LabelType
-{
- LABEL_IADDR = 1, // Jump addresses, etc
- LABEL_DADDR = 2, // Data addresses, etc
- LABEL_VALUE = 4,
- LABEL_ANY = 0xFF,
-};
-
-class LabelMap
-{
- struct label_t
- {
- label_t(const std::string &lbl, s32 address, LabelType ltype) : name(lbl), addr(address), type(ltype) {}
- std::string name;
- s32 addr;
- LabelType type;
- };
- std::vector<label_t> labels;
-
-public:
- LabelMap();
- ~LabelMap() { }
- void RegisterDefaults();
- void RegisterLabel(const std::string &label, u16 lval, LabelType type = LABEL_VALUE);
- void DeleteLabel(const std::string &label);
- bool GetLabelValue(const std::string &label, u16 *value, LabelType type = LABEL_ANY) const;
- void Clear();
-};
-
-#endif // _LABELMAP_H
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _LABELMAP_H
+#define _LABELMAP_H
+
+#include <string>
+#include <vector>
+
+#include "Common.h"
+
+enum LabelType
+{
+ LABEL_IADDR = 1, // Jump addresses, etc
+ LABEL_DADDR = 2, // Data addresses, etc
+ LABEL_VALUE = 4,
+ LABEL_ANY = 0xFF,
+};
+
+class LabelMap
+{
+ struct label_t
+ {
+ label_t(const std::string &lbl, s32 address, LabelType ltype) : name(lbl), addr(address), type(ltype) {}
+ std::string name;
+ s32 addr;
+ LabelType type;
+ };
+ std::vector<label_t> labels;
+
+public:
+ LabelMap();
+ ~LabelMap() { }
+ void RegisterDefaults();
+ void RegisterLabel(const std::string &label, u16 lval, LabelType type = LABEL_VALUE);
+ void DeleteLabel(const std::string &label);
+ bool GetLabelValue(const std::string &label, u16 *value, LabelType type = LABEL_ANY) const;
+ void Clear();
+};
+
+#endif // _LABELMAP_H
diff --git a/Source/Core/DSPCore/Src/assemble.cpp b/Source/Core/DSPCore/Src/assemble.cpp
index 2f14d70381..7516b4182f 100644
--- a/Source/Core/DSPCore/Src/assemble.cpp
+++ b/Source/Core/DSPCore/Src/assemble.cpp
@@ -1,1016 +1,1016 @@
-/*====================================================================
-
-$Id: assemble.cpp,v 1.3 2008-11-11 01:04:26 wntrmute Exp $
-
-project: GameCube DSP Tool (gcdsp)
-mail: duddie@walla.com
-
-Copyright (c) 2005 Duddie
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Revision 1.4 2008/10/04 10:30:00 Hermes
-added function to export the code to .h file
-added support for '/ *' '* /' and '//' for comentaries
-added some sintax detection when use registers
-
-$Log: not supported by cvs2svn $
-Revision 1.2 2005/09/14 02:19:29 wntrmute
-added header guards
-use standard main function
-
-Revision 1.1 2005/08/24 22:13:34 wntrmute
-Initial import
-
-
-====================================================================*/
-
-#include <cstdio>
-#include <cstdlib>
-
-#include <map>
-#include <iostream>
-#include <fstream>
-
-#include "Common.h"
-#include "FileUtil.h"
-#include "DSPInterpreter.h"
-#include "DSPTables.h"
-#include "disassemble.h"
-#include "assemble.h"
-
-static const char *err_string[] =
-{
- "",
- "Unknown Error",
- "Unknown opcode",
- "Not enough parameters",
- "Too many parameters",
- "Wrong parameter",
- "Expected parameter of type 'string'",
- "Expected parameter of type 'value'",
- "Expected parameter of type 'register'",
- "Expected parameter of type 'memory pointer'",
- "Expected parameter of type 'immediate'",
- "Incorrect binary value",
- "Incorrect hexadecimal value",
- "Incorrect decimal value",
- "Label already exists",
- "Label not defined",
- "No matching brackets",
- "This opcode cannot be extended",
- "Given extending params for non extensible opcode",
- "Wrong parameter: must be accumulator register",
- "Wrong parameter: must be mid accumulator register",
- "Invalid register",
- "Number out of range"
-};
-
-DSPAssembler::DSPAssembler(const AssemblerSettings &settings) :
- m_cur_addr(0),
- m_cur_pass(0),
- m_current_param(0),
- settings_(settings),
- gdg_buffer(NULL)
-{
-}
-
-DSPAssembler::~DSPAssembler()
-{
- if(gdg_buffer)
- free(gdg_buffer);
-}
-
-bool DSPAssembler::Assemble(const char *text, std::vector<u16> &code, std::vector<int> *line_numbers)
-{
- if (line_numbers)
- line_numbers->clear();
- const char *fname = "tmp.asm";
- if (!File::WriteStringToFile(true, text, fname))
- return false;
- InitPass(1);
- if (!AssembleFile(fname, 1))
- return false;
-
- // We now have the size of the output buffer
- if (m_totalSize > 0)
- {
- gdg_buffer = (char *)malloc(m_totalSize * sizeof(u16) + 4);
- if(!gdg_buffer)
- return false;
-
- memset(gdg_buffer, 0, m_totalSize * sizeof(u16));
- } else
- return false;
-
- InitPass(2);
- if (!AssembleFile(fname, 2))
- return false;
-
- code.resize(m_totalSize);
- for (int i = 0; i < m_totalSize; i++) {
- code[i] = *(u16 *)(gdg_buffer + i * 2);
- }
-
- if(gdg_buffer) {
- free(gdg_buffer);
- gdg_buffer = NULL;
- }
-
- last_error_str = "(no errors)";
- last_error = ERR_OK;
-
- return true;
-}
-
-void DSPAssembler::ShowError(err_t err_code, const char *extra_info)
-{
- failed = true;
- char error_buffer[1024];
- char *buf_ptr = error_buffer;
- buf_ptr += sprintf(buf_ptr, "%i : %s ", code_line, cur_line.c_str());
- if (!extra_info)
- extra_info = "-";
-
- if (m_current_param == 0)
- buf_ptr += sprintf(buf_ptr, "ERROR: %s Line: %d : %s\n", err_string[err_code], code_line, extra_info);
- else
- buf_ptr += sprintf(buf_ptr, "ERROR: %s Line: %d Param: %d : %s\n",
- err_string[err_code], code_line, m_current_param, extra_info);
- last_error_str = error_buffer;
- last_error = err_code;
-}
-
-char *skip_spaces(char *ptr)
-{
- while (*ptr == ' ')
- ptr++;
- return ptr;
-}
-
-const char *skip_spaces(const char *ptr)
-{
- while (*ptr == ' ')
- ptr++;
- return ptr;
-}
-
-// Parse a standalone value - it can be a number in one of several formats or a label.
-s32 DSPAssembler::ParseValue(const char *str)
-{
- bool negative = false;
- s32 val = 0;
- const char *ptr = str;
-
- if (ptr[0] == '#')
- {
- ptr++;
- negative = true; // Wow! Double # (needed one to get in here) negates???
- }
- if (ptr[0] == '-')
- {
- ptr++;
- negative = true;
- }
- if (ptr[0] == '0')
- {
- if (ptr[1] >= '0' && ptr[1] <= '9')
- {
- for (int i = 0; ptr[i] != 0; i++)
- {
- val *= 10;
- if (ptr[i] >= '0' && ptr[i] <= '9')
- val += ptr[i] - '0';
- else
- ShowError(ERR_INCORRECT_DEC, str);
- }
- }
- else
- {
- switch (ptr[1])
- {
- case 'X': // hex
- for (int i = 2 ; ptr[i] != 0 ; i++)
- {
- val <<= 4;
- if (ptr[i] >= 'a' && ptr[i] <= 'f')
- val += (ptr[i]-'a'+10);
- else if (ptr[i] >= 'A' && ptr[i] <= 'F')
- val += (ptr[i]-'A'+10);
- else if (ptr[i] >= '0' && ptr[i] <= '9')
- val += (ptr[i] - '0');
- else
- ShowError(ERR_INCORRECT_HEX, str);
- }
- break;
- case '\'': // binary
- for (int i = 2; ptr[i] != 0; i++)
- {
- val *=2;
- if(ptr[i] >= '0' && ptr[i] <= '1')
- val += ptr[i] - '0';
- else
- ShowError(ERR_INCORRECT_BIN, str);
- }
- break;
- default:
- // value is 0 or error
- val = 0;
- break;
- }
- }
- }
- else
- {
- // Symbol starts with a digit - it's a dec number.
- if (ptr[0] >= '0' && ptr[0] <= '9')
- {
- for (int i = 0; ptr[i] != 0; i++)
- {
- val *= 10;
- if (ptr[i] >= '0' && ptr[i] <= '9')
- val += ptr[i] - '0';
- else
- ShowError(ERR_INCORRECT_DEC, str);
- }
- }
- else // Everything else is a label.
- {
- // Lookup label
- u16 value;
- if (labels.GetLabelValue(ptr, &value))
- return value;
- if (m_cur_pass == 2)
- ShowError(ERR_UNKNOWN_LABEL, str);
- }
- }
- if (negative)
- return -val;
- return val;
-}
-
-// Modifies both src and dst!
-// What does it do, really??
-char *DSPAssembler::FindBrackets(char *src, char *dst)
-{
- s32 len = (s32) strlen(src);
- s32 first = -1;
- s32 count = 0;
- s32 i, j;
- j = 0;
- for (i = 0 ; i < len ; i++)
- {
- if (src[i] == '(')
- {
- if (first < 0)
- {
- count = 1;
- src[i] = 0x0;
- first = i;
- }
- else
- {
- count++;
- dst[j++] = src[i];
- }
- }
- else if (src[i] == ')')
- {
- if (--count == 0)
- {
- dst[j] = 0;
- return &src[i+1];
- }
- else
- {
- dst[j++] = src[i];
- }
- }
- else
- {
- if (first >= 0)
- dst[j++] = src[i];
- }
- }
- if (count)
- ShowError(ERR_NO_MATCHING_BRACKETS);
- return NULL;
-}
-
-// Bizarre in-place expression evaluator.
-u32 DSPAssembler::ParseExpression(const char *ptr)
-{
- char *pbuf;
- s32 val = 0;
-
- char *d_buffer = (char *)malloc(1024);
- char *s_buffer = (char *)malloc(1024);
- strcpy(s_buffer, ptr);
-
- while ((pbuf = FindBrackets(s_buffer, d_buffer)) != NULL)
- {
- val = ParseExpression(d_buffer);
- sprintf(d_buffer, "%s%d%s", s_buffer, val, pbuf);
- strcpy(s_buffer, d_buffer);
- }
-
- int j = 0;
- for (int i = 0; i < ((s32)strlen(s_buffer) + 1) ; i++)
- {
- char c = s_buffer[i];
- if (c != ' ')
- d_buffer[j++] = c;
- }
-
- for (int i = 0; i < ((s32)strlen(d_buffer) + 1) ; i++)
- {
- char c = d_buffer[i];
- if (c == '-')
- {
- if (i == 0)
- c = '#';
- else
- {
- switch (d_buffer[i - 1])
- {
- case '/':
- case '%':
- case '*':
- c = '#';
- }
- }
- }
- d_buffer[i] = c;
- }
-
- while ((pbuf = strstr(d_buffer, "+")) != NULL)
- {
- *pbuf = 0x0;
- val = ParseExpression(d_buffer) + ParseExpression(pbuf+1);
- sprintf(d_buffer, "%d", val);
- }
-
- while ((pbuf = strstr(d_buffer, "-")) != NULL)
- {
- *pbuf = 0x0;
- val = ParseExpression(d_buffer) - ParseExpression(pbuf+1);
- if (val < 0)
- {
- val = 0x10000 + (val & 0xffff); // ATTENTION: avoid a terrible bug!!! number cannot write with '-' in sprintf
- fprintf(stderr, "WARNING: Number Underflow at Line: %d \n", code_line);
- }
- sprintf(d_buffer, "%d", val);
- }
-
- while ((pbuf = strstr(d_buffer, "*")) != NULL)
- {
- *pbuf = 0x0;
- val = ParseExpression(d_buffer) * ParseExpression(pbuf+1);
- sprintf(d_buffer, "%d", val);
- }
-
- while ((pbuf = strstr(d_buffer, "/")) != NULL)
- {
- *pbuf = 0x0;
- val = ParseExpression(d_buffer) / ParseExpression(pbuf+1);
- sprintf(d_buffer, "%d", val);
- }
-
- while ((pbuf = strstr(d_buffer, "|")) != NULL)
- {
- *pbuf = 0x0;
- val = ParseExpression(d_buffer) | ParseExpression(pbuf+1);
- sprintf(d_buffer, "%d", val);
- }
-
- while ((pbuf = strstr(d_buffer, "&")) != NULL)
- {
- *pbuf = 0x0;
- val = ParseExpression(d_buffer) & ParseExpression(pbuf+1);
- sprintf(d_buffer, "%d", val);
- }
-
- val = ParseValue(d_buffer);
- free(d_buffer);
- free(s_buffer);
- return val;
-}
-
-// Destroys parstr
-u32 DSPAssembler::GetParams(char *parstr, param_t *par)
-{
- u32 count = 0;
- char *tmpstr = skip_spaces(parstr);
- tmpstr = strtok(tmpstr, ",\x00");
- for (int i = 0; i < 10; i++)
- {
- if (tmpstr == NULL)
- break;
- tmpstr = skip_spaces(tmpstr);
- if (strlen(tmpstr) == 0)
- break;
- if (tmpstr)
- count++;
- else
- break;
-
- par[i].type = P_NONE;
- switch (tmpstr[0])
- {
- case '"':
- par[i].str = strtok(tmpstr, "\"");
- par[i].type = P_STR;
- break;
- case '#':
- par[i].val = ParseExpression(tmpstr + 1);
- par[i].type = P_IMM;
- break;
- case '@':
- if (tmpstr[1] == '$')
- {
- par[i].val = ParseExpression(tmpstr + 2);
- par[i].type = P_PRG;
- }
- else
- {
- par[i].val = ParseExpression(tmpstr + 1);
- par[i].type = P_MEM;
- }
- break;
- case '$':
- par[i].val = ParseExpression(tmpstr + 1);
- par[i].type = P_REG;
- break;
-
- default:
- par[i].val = ParseExpression(tmpstr);
- par[i].type = P_VAL;
- break;
- }
- tmpstr = strtok(NULL, ",\x00");
- }
- return count;
-}
-
-const opc_t *DSPAssembler::FindOpcode(const char *opcode, u32 par_count, const opc_t * const opcod, int opcod_size)
-{
- if (opcode[0] == 'C' && opcode[1] == 'W')
- return &cw;
-
- AliasMap::const_iterator alias_iter = aliases.find(opcode);
- if (alias_iter != aliases.end())
- opcode = alias_iter->second.c_str();
- for (int i = 0; i < opcod_size; i++)
- {
- const opc_t *opc = &opcod[i];
- if (strcmp(opc->name, opcode) == 0)
- {
- if (par_count < opc->param_count)
- {
- ShowError(ERR_NOT_ENOUGH_PARAMETERS);
- }
- if (par_count > opc->param_count)
- {
- ShowError(ERR_TOO_MANY_PARAMETERS);
- }
- return opc;
- }
- }
- ShowError(ERR_UNKNOWN_OPCODE);
- return NULL;
-}
-
-// weird...
-u16 get_mask_shifted_down(u16 mask)
-{
- while (!(mask & 1))
- mask >>= 1;
- return mask;
-}
-
-bool DSPAssembler::VerifyParams(const opc_t *opc, param_t *par, int count, bool ext)
-{
- for (int i = 0; i < count; i++)
- {
- const int current_param = i + 1; // just for display.
- if (opc->params[i].type != par[i].type || (par[i].type & P_REG))
- {
- if (par[i].type == P_VAL &&
- (opc->params[i].type == P_ADDR_I || opc->params[i].type == P_ADDR_D))
- {
- // Data and instruction addresses are valid as VAL values.
- continue;
- }
-
- if ((opc->params[i].type & P_REG) && (par[i].type & P_REG))
- {
- // Just a temp. Should be replaced with more purposeful vars.
- int value;
-
- // modified by Hermes: test the register range
- switch ((unsigned)opc->params[i].type)
- {
- case P_REG18:
- case P_REG19:
- case P_REG1A:
- value = (opc->params[i].type >> 8) & 31;
- if ((int)par[i].val < value ||
- (int)par[i].val > value + get_mask_shifted_down(opc->params[i].mask))
- {
- if (ext) fprintf(stderr, "(ext) ");
- fprintf(stderr, "%s (param %i)", cur_line.c_str(), current_param);
- ShowError(ERR_INVALID_REGISTER);
- }
- break;
- case P_PRG:
- if ((int)par[i].val < 0 || (int)par[i].val > 0x3)
- {
- if (ext) fprintf(stderr, "(ext) ");
- fprintf(stderr, "%s (param %i)", cur_line.c_str(), current_param);
- ShowError(ERR_INVALID_REGISTER);
- }
- break;
- case P_ACC:
- if ((int)par[i].val < 0x20 || (int)par[i].val > 0x21)
- {
- if (ext) fprintf(stderr, "(ext) ");
- if (par[i].val >= 0x1e && par[i].val <= 0x1f) {
- fprintf(stderr, "%i : %s", code_line, cur_line.c_str());
- fprintf(stderr, "WARNING: $ACM%d register used instead of $ACC%d register Line: %d Param: %d Ext: %d\n",
- (par[i].val & 1), (par[i].val & 1), code_line, current_param, ext);
- }
- else if (par[i].val >= 0x1c && par[i].val <= 0x1d) {
- fprintf(stderr, "WARNING: $ACL%d register used instead of $ACC%d register Line: %d Param: %d\n",
- (par[i].val & 1), (par[i].val & 1), code_line, current_param);
- }
- else
- ShowError(ERR_WRONG_PARAMETER_ACC);
- }
- break;
- case P_ACCM:
- if ((int)par[i].val < 0x1e || (int)par[i].val > 0x1f)
- {
- if (ext) fprintf(stderr, "(ext) ");
- if (par[i].val >= 0x1c && par[i].val <= 0x1d)
- fprintf(stderr, "WARNING: $ACL%d register used instead of $ACM%d register Line: %d Param: %d\n",
- (par[i].val & 1), (par[i].val & 1), code_line, current_param);
- else if (par[i].val >= 0x20 && par[i].val <= 0x21)
- fprintf(stderr, "WARNING: $ACC%d register used instead of $ACM%d register Line: %d Param: %d\n",
- (par[i].val & 1), (par[i].val & 1), code_line, current_param);
- else
- ShowError(ERR_WRONG_PARAMETER_ACC);
- }
- break;
-
- case P_ACCL:
- if ((int)par[i].val < 0x1c || (int)par[i].val > 0x1d)
- {
- if (ext) fprintf(stderr, "(ext) ");
- if (par[i].val >= 0x1e && par[i].val <= 0x1f)
- {
- fprintf(stderr, "%s", cur_line.c_str());
- fprintf(stderr, "WARNING: $ACM%d register used instead of $ACL%d register Line: %d Param: %d\n",
- (par[i].val & 1), (par[i].val & 1), code_line, current_param);
- }
- else if (par[i].val >= 0x20 && par[i].val <= 0x21) {
- fprintf(stderr, "%s", cur_line.c_str());
- fprintf(stderr, "WARNING: $ACC%d register used instead of $ACL%d register Line: %d Param: %d\n",
- (par[i].val & 1), (par[i].val & 1), code_line, current_param);
- }
- else
- ShowError(ERR_WRONG_PARAMETER_ACC);
- }
- break;
-/* case P_ACCM_D: //P_ACC_MID:
- if ((int)par[i].val < 0x1e || (int)par[i].val > 0x1f)
- {
- ShowError(ERR_WRONG_PARAMETER_MID_ACC);
- }
- break;*/
- }
- continue;
- }
-
- switch (par[i].type & (P_REG | 7))
- {
- case P_REG:
- if (ext) fprintf(stderr, "(ext) ");
- ShowError(ERR_EXPECTED_PARAM_REG);
- break;
- case P_MEM:
- if (ext) fprintf(stderr, "(ext) ");
- ShowError(ERR_EXPECTED_PARAM_MEM);
- break;
- case P_VAL:
- if (ext) fprintf(stderr, "(ext) ");
- ShowError(ERR_EXPECTED_PARAM_VAL);
- break;
- case P_IMM:
- if (ext) fprintf(stderr, "(ext) ");
- ShowError(ERR_EXPECTED_PARAM_IMM);
- break;
- }
- ShowError(ERR_WRONG_PARAMETER);
- break;
- }
- else if ((opc->params[i].type & 3) != 0 && (par[i].type & 3) != 0)
- {
- // modified by Hermes: test NUMBER range
- int value = get_mask_shifted_down(opc->params[i].mask);
- unsigned int valueu = 0xffff & ~(value >> 1);
- if ((int)par[i].val < 0)
- {
- if (value == 7) // value 7 por sbclr/sbset
- {
- fprintf(stderr,"Value must be from 0x0 to 0x%x\n", value);
- ShowError(ERR_OUT_RANGE_NUMBER);
- }
- else if (opc->params[i].type == P_MEM)
- {
- if (value < 256)
- fprintf(stderr, "Address value must be from 0x%x to 0x%x\n",valueu, (value>>1));
- else
- fprintf(stderr, "Address value must be from 0x0 to 0x%x\n", value);
-
- ShowError(ERR_OUT_RANGE_NUMBER);
- }
- else if ((int)par[i].val < -((value >> 1) + 1))
- {
- if (value < 128)
- fprintf(stderr, "Value must be from -0x%x to 0x%x, is %i\n",
- (value >> 1) + 1, value >> 1, par[i].val);
- else
- fprintf(stderr, "Value must be from -0x%x to 0x%x or 0x0 to 0x%x, is %i\n",
- (value >> 1) + 1, value >> 1, value, par[i].val);
-
- ShowError(ERR_OUT_RANGE_NUMBER);
- }
- }
- else
- {
- if (value == 7) // value 7 por sbclr/sbset
- {
- if (par[i].val > (unsigned)value)
- {
- fprintf(stderr,"Value must be from 0x%x to 0x%x, is %i\n",valueu, value, par[i].val);
- ShowError(ERR_OUT_RANGE_NUMBER);
- }
- }
- else if (opc->params[i].type == P_MEM)
- {
- if (value < 256)
- value >>= 1; // addressing 8 bit with sign
- if (par[i].val > (unsigned)value &&
- (par[i].val < valueu || par[i].val > (unsigned)0xffff))
- {
- if (value < 256)
- fprintf(stderr,"Address value must be from 0x%x to 0x%x, is %04x\n", valueu, value, par[i].val);
- else
- fprintf(stderr,"Address value must be minor of 0x%x\n", value+1);
- ShowError(ERR_OUT_RANGE_NUMBER);
- }
- }
- else
- {
- if (value < 128)
- value >>= 1; // special case ASL/ASR/LSL/LSR
- if (par[i].val > (unsigned)value)
- {
- if (value < 64)
- fprintf(stderr,"Value must be from -0x%x to 0x%x, is %i\n", (value + 1), value, par[i].val);
- else
- fprintf(stderr,"Value must be minor of 0x%x, is %i\n", value + 1, par[i].val);
- ShowError(ERR_OUT_RANGE_NUMBER);
- }
- }
- }
- continue;
- }
- }
- m_current_param = 0;
- return true;
-}
-
-
-// Merge opcode with params.
-void DSPAssembler::BuildCode(const opc_t *opc, param_t *par, u32 par_count, u16 *outbuf)
-{
- outbuf[m_cur_addr] |= opc->opcode;
- for (u32 i = 0; i < par_count; i++)
- {
- // Ignore the "reverse" parameters since they are implicit.
- if (opc->params[i].type != P_ACC_D && opc->params[i].type != P_ACCM_D)
- {
- u16 t16 = outbuf[m_cur_addr + opc->params[i].loc];
- u16 v16 = par[i].val;
- if (opc->params[i].lshift > 0)
- v16 <<= opc->params[i].lshift;
- else
- v16 >>= -opc->params[i].lshift;
- v16 &= opc->params[i].mask;
- outbuf[m_cur_addr + opc->params[i].loc] = t16 | v16;
- }
- }
-}
-
-void DSPAssembler::InitPass(int pass)
-{
- failed = false;
- if (pass == 1)
- {
- // Reset label table. Pre-populate with hw addresses and registers.
- labels.Clear();
- labels.RegisterDefaults();
- aliases.clear();
- aliases["S15"] = "SET15";
- aliases["S16"] = "SET16";
- aliases["S40"] = "SET40";
- }
- m_cur_addr = 0;
- m_totalSize = 0;
- cur_segment = SEGMENT_CODE;
- segment_addr[SEGMENT_CODE] = 0;
- segment_addr[SEGMENT_DATA] = 0;
- segment_addr[SEGMENT_OVERLAY] = 0;
-}
-
-bool DSPAssembler::AssembleFile(const char *fname, int pass)
-{
- int disable_text = 0; // modified by Hermes
-
- std::ifstream fsrc(fname);
-
- if (fsrc.fail())
- {
- std::cerr << "Cannot open file " << fname << std::endl;
- return false;
- }
-
- //printf("%s: Pass %d\n", fname, pass);
- code_line = 0;
- m_cur_pass = pass;
-
-#define LINEBUF_SIZE 1024
- char line[LINEBUF_SIZE] = {0};
- while (!failed && !fsrc.fail() && !fsrc.eof())
- {
- int opcode_size = 0;
- fsrc.getline(line, LINEBUF_SIZE);
- if(fsrc.fail())
- break;
-
- cur_line = line;
- //printf("A: %s\n", line);
- code_line++;
-
- param_t params[10] = {{0}};
- param_t params_ext[10] = {{0}};
-
- bool upper = true;
- for (int i = 0; i < LINEBUF_SIZE; i++)
- {
- char c = line[i];
- // This stuff handles /**/ and // comments.
- // modified by Hermes : added // and /* */ for long commentaries
- if (c == '/')
- {
- if (i < 1023)
- {
- if (line[i+1] == '/')
- c = 0x00;
- else if (line[i+1] == '*')
- {
- // toggle comment mode.
- disable_text = !disable_text;
- }
- }
- }
- else if (c == '*')
- {
- if (i < 1023 && line[i+1] == '/' && disable_text)
- {
- disable_text = 0;
- c = 32;
- line[i + 1] = 32;
- }
- }
-
- // turn text into spaces if disable_text is on (in a comment).
- if (disable_text && ((unsigned char)c) > 32) c = 32;
-
- if (c == 0x0a || c == 0x0d || c == ';')
- c = 0x00;
- if (c == 0x09) // tabs to spaces
- c = ' ';
- if (c == '"')
- upper = !upper;
- if (upper && c >= 'a' && c <= 'z') // convert to uppercase
- c = c - 'a' + 'A';
- line[i] = c;
- if (c == 0)
- break; // modified by Hermes
- }
- char *ptr = line;
-
- std::string label;
-
- size_t col_pos = std::string(line).find(":");
- if (col_pos != std::string::npos)
- {
- bool valid = true;
-
- for(int j = 0; j < (int)col_pos; j++)
- {
- if (j == 0)
- if (!((ptr[j] >= 'A' && ptr[j] <= 'Z') || (ptr[j] == '_')))
- valid = false;
- if (!((ptr[j] >= '0' && ptr[j] <= '9') || (ptr[j] >= 'A' && ptr[j] <= 'Z') || (ptr[j] == '_')))
- valid = false;
- }
- if (valid)
- {
- label = std::string(line).substr(0, col_pos);
- ptr += col_pos + 1;
- }
- }
-
- char *opcode = NULL;
- opcode = strtok(ptr, " ");
- char *opcode_ext = NULL;
-
- u32 params_count = 0;
- u32 params_count_ext = 0;
- if (opcode)
- {
- if ((opcode_ext = strstr(opcode, "'")) != NULL)
- {
- opcode_ext[0] = '\0';
- opcode_ext++;
- if (strlen(opcode_ext) == 0)
- opcode_ext = NULL;
- }
- // now we have opcode and label
-
- params_count = 0;
- params_count_ext = 0;
-
- char *paramstr = strtok(NULL, "\0");
- char *paramstr_ext = 0;
- // there is valid opcode so probably we have parameters
-
- if (paramstr)
- {
- if ((paramstr_ext = strstr(paramstr, ":")) != NULL)
- {
- paramstr_ext[0] = '\0';
- paramstr_ext++;
- }
- }
-
- if (paramstr)
- params_count = GetParams(paramstr, params);
- if (paramstr_ext)
- params_count_ext = GetParams(paramstr_ext, params_ext);
- }
-
- if (!label.empty())
- {
- // there is a valid label so lets store it in labels table
- u32 lval = m_cur_addr;
- if (opcode)
- {
- if (strcmp(opcode, "EQU") == 0)
- {
- lval = params[0].val;
- opcode = NULL;
- }
- }
- if (pass == 1)
- labels.RegisterLabel(label, lval);
- }
-
- if (opcode == NULL)
- continue;
-
- // check if opcode is reserved compiler word
- if (strcmp("INCLUDE", opcode) == 0)
- {
- if (params[0].type == P_STR)
- {
- char *tmpstr;
- u32 thisCodeline = code_line;
-
- if (include_dir.size())
- {
- tmpstr = (char *)malloc(include_dir.size() + strlen(params[0].str) + 2);
- sprintf(tmpstr, "%s/%s", include_dir.c_str(), params[0].str);
- }
- else
- {
- tmpstr = (char *)malloc(strlen(params[0].str) + 1);
- strcpy(tmpstr, params[0].str);
- }
-
- AssembleFile(tmpstr, pass);
-
- code_line = thisCodeline;
-
- free(tmpstr);
- }
- else
- ShowError(ERR_EXPECTED_PARAM_STR);
- continue;
- }
-
- if (strcmp("INCDIR", opcode) == 0)
- {
- if (params[0].type == P_STR)
- include_dir = params[0].str;
- else
- ShowError(ERR_EXPECTED_PARAM_STR);
- continue;
- }
-
- if (strcmp("ORG", opcode) == 0)
- {
- if (params[0].type == P_VAL)
- m_cur_addr = params[0].val;
- else
- ShowError(ERR_EXPECTED_PARAM_VAL);
- continue;
- }
-
- if (strcmp("SEGMENT", opcode) == 0)
- {
- if (params[0].type == P_STR)
- {
- segment_addr[cur_segment] = m_cur_addr;
- if (strcmp("DATA", params[0].str) == 0)
- cur_segment = SEGMENT_DATA;
- if (strcmp("CODE", params[0].str) == 0)
- cur_segment = SEGMENT_CODE;
- m_cur_addr = segment_addr[cur_segment];
- }
- else
- ShowError(ERR_EXPECTED_PARAM_STR);
- continue;
- }
-
- const opc_t *opc = FindOpcode(opcode, params_count, opcodes, opcodes_size);
- if (!opc)
- opc = &cw;
-
- opcode_size = opc->size & ~P_EXT;
-
- VerifyParams(opc, params, params_count);
-
- const opc_t *opc_ext = NULL;
- // Check for opcode extensions.
- if (opc->size & P_EXT)
- {
- if (opcode_ext)
- {
- opc_ext = FindOpcode(opcode_ext, params_count_ext, opcodes_ext, opcodes_ext_size);
- VerifyParams(opc_ext, params_ext, params_count_ext, true);
- }
- else if (params_count_ext)
- ShowError(ERR_EXT_PAR_NOT_EXT);
- }
- else
- {
- if (opcode_ext)
- ShowError(ERR_EXT_CANT_EXTEND_OPCODE);
- if (params_count_ext)
- ShowError(ERR_EXT_PAR_NOT_EXT);
- }
-
- if (pass == 2)
- {
- // generate binary
- ((u16 *)gdg_buffer)[m_cur_addr] = 0x0000;
- BuildCode(opc, params, params_count, (u16 *)gdg_buffer);
- if (opc_ext)
- BuildCode(opc_ext, params_ext, params_count_ext, (u16 *)gdg_buffer);
- }
-
- m_cur_addr += opcode_size;
- m_totalSize += opcode_size;
- };
-
- if (!failed)
- fsrc.close();
-
- return !failed;
-}
+/*====================================================================
+
+$Id: assemble.cpp,v 1.3 2008-11-11 01:04:26 wntrmute Exp $
+
+project: GameCube DSP Tool (gcdsp)
+mail: duddie@walla.com
+
+Copyright (c) 2005 Duddie
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+Revision 1.4 2008/10/04 10:30:00 Hermes
+added function to export the code to .h file
+added support for '/ *' '* /' and '//' for comentaries
+added some sintax detection when use registers
+
+$Log: not supported by cvs2svn $
+Revision 1.2 2005/09/14 02:19:29 wntrmute
+added header guards
+use standard main function
+
+Revision 1.1 2005/08/24 22:13:34 wntrmute
+Initial import
+
+
+====================================================================*/
+
+#include <cstdio>
+#include <cstdlib>
+
+#include <map>
+#include <iostream>
+#include <fstream>
+
+#include "Common.h"
+#include "FileUtil.h"
+#include "DSPInterpreter.h"
+#include "DSPTables.h"
+#include "disassemble.h"
+#include "assemble.h"
+
+static const char *err_string[] =
+{
+ "",
+ "Unknown Error",
+ "Unknown opcode",
+ "Not enough parameters",
+ "Too many parameters",
+ "Wrong parameter",
+ "Expected parameter of type 'string'",
+ "Expected parameter of type 'value'",
+ "Expected parameter of type 'register'",
+ "Expected parameter of type 'memory pointer'",
+ "Expected parameter of type 'immediate'",
+ "Incorrect binary value",
+ "Incorrect hexadecimal value",
+ "Incorrect decimal value",
+ "Label already exists",
+ "Label not defined",
+ "No matching brackets",
+ "This opcode cannot be extended",
+ "Given extending params for non extensible opcode",
+ "Wrong parameter: must be accumulator register",
+ "Wrong parameter: must be mid accumulator register",
+ "Invalid register",
+ "Number out of range"
+};
+
+DSPAssembler::DSPAssembler(const AssemblerSettings &settings) :
+ m_cur_addr(0),
+ m_cur_pass(0),
+ m_current_param(0),
+ settings_(settings),
+ gdg_buffer(NULL)
+{
+}
+
+DSPAssembler::~DSPAssembler()
+{
+ if(gdg_buffer)
+ free(gdg_buffer);
+}
+
+bool DSPAssembler::Assemble(const char *text, std::vector<u16> &code, std::vector<int> *line_numbers)
+{
+ if (line_numbers)
+ line_numbers->clear();
+ const char *fname = "tmp.asm";
+ if (!File::WriteStringToFile(true, text, fname))
+ return false;
+ InitPass(1);
+ if (!AssembleFile(fname, 1))
+ return false;
+
+ // We now have the size of the output buffer
+ if (m_totalSize > 0)
+ {
+ gdg_buffer = (char *)malloc(m_totalSize * sizeof(u16) + 4);
+ if(!gdg_buffer)
+ return false;
+
+ memset(gdg_buffer, 0, m_totalSize * sizeof(u16));
+ } else
+ return false;
+
+ InitPass(2);
+ if (!AssembleFile(fname, 2))
+ return false;
+
+ code.resize(m_totalSize);
+ for (int i = 0; i < m_totalSize; i++) {
+ code[i] = *(u16 *)(gdg_buffer + i * 2);
+ }
+
+ if(gdg_buffer) {
+ free(gdg_buffer);
+ gdg_buffer = NULL;
+ }
+
+ last_error_str = "(no errors)";
+ last_error = ERR_OK;
+
+ return true;
+}
+
+void DSPAssembler::ShowError(err_t err_code, const char *extra_info)
+{
+ failed = true;
+ char error_buffer[1024];
+ char *buf_ptr = error_buffer;
+ buf_ptr += sprintf(buf_ptr, "%i : %s ", code_line, cur_line.c_str());
+ if (!extra_info)
+ extra_info = "-";
+
+ if (m_current_param == 0)
+ buf_ptr += sprintf(buf_ptr, "ERROR: %s Line: %d : %s\n", err_string[err_code], code_line, extra_info);
+ else
+ buf_ptr += sprintf(buf_ptr, "ERROR: %s Line: %d Param: %d : %s\n",
+ err_string[err_code], code_line, m_current_param, extra_info);
+ last_error_str = error_buffer;
+ last_error = err_code;
+}
+
+char *skip_spaces(char *ptr)
+{
+ while (*ptr == ' ')
+ ptr++;
+ return ptr;
+}
+
+const char *skip_spaces(const char *ptr)
+{
+ while (*ptr == ' ')
+ ptr++;
+ return ptr;
+}
+
+// Parse a standalone value - it can be a number in one of several formats or a label.
+s32 DSPAssembler::ParseValue(const char *str)
+{
+ bool negative = false;
+ s32 val = 0;
+ const char *ptr = str;
+
+ if (ptr[0] == '#')
+ {
+ ptr++;
+ negative = true; // Wow! Double # (needed one to get in here) negates???
+ }
+ if (ptr[0] == '-')
+ {
+ ptr++;
+ negative = true;
+ }
+ if (ptr[0] == '0')
+ {
+ if (ptr[1] >= '0' && ptr[1] <= '9')
+ {
+ for (int i = 0; ptr[i] != 0; i++)
+ {
+ val *= 10;
+ if (ptr[i] >= '0' && ptr[i] <= '9')
+ val += ptr[i] - '0';
+ else
+ ShowError(ERR_INCORRECT_DEC, str);
+ }
+ }
+ else
+ {
+ switch (ptr[1])
+ {
+ case 'X': // hex
+ for (int i = 2 ; ptr[i] != 0 ; i++)
+ {
+ val <<= 4;
+ if (ptr[i] >= 'a' && ptr[i] <= 'f')
+ val += (ptr[i]-'a'+10);
+ else if (ptr[i] >= 'A' && ptr[i] <= 'F')
+ val += (ptr[i]-'A'+10);
+ else if (ptr[i] >= '0' && ptr[i] <= '9')
+ val += (ptr[i] - '0');
+ else
+ ShowError(ERR_INCORRECT_HEX, str);
+ }
+ break;
+ case '\'': // binary
+ for (int i = 2; ptr[i] != 0; i++)
+ {
+ val *=2;
+ if(ptr[i] >= '0' && ptr[i] <= '1')
+ val += ptr[i] - '0';
+ else
+ ShowError(ERR_INCORRECT_BIN, str);
+ }
+ break;
+ default:
+ // value is 0 or error
+ val = 0;
+ break;
+ }
+ }
+ }
+ else
+ {
+ // Symbol starts with a digit - it's a dec number.
+ if (ptr[0] >= '0' && ptr[0] <= '9')
+ {
+ for (int i = 0; ptr[i] != 0; i++)
+ {
+ val *= 10;
+ if (ptr[i] >= '0' && ptr[i] <= '9')
+ val += ptr[i] - '0';
+ else
+ ShowError(ERR_INCORRECT_DEC, str);
+ }
+ }
+ else // Everything else is a label.
+ {
+ // Lookup label
+ u16 value;
+ if (labels.GetLabelValue(ptr, &value))
+ return value;
+ if (m_cur_pass == 2)
+ ShowError(ERR_UNKNOWN_LABEL, str);
+ }
+ }
+ if (negative)
+ return -val;
+ return val;
+}
+
+// Modifies both src and dst!
+// What does it do, really??
+char *DSPAssembler::FindBrackets(char *src, char *dst)
+{
+ s32 len = (s32) strlen(src);
+ s32 first = -1;
+ s32 count = 0;
+ s32 i, j;
+ j = 0;
+ for (i = 0 ; i < len ; i++)
+ {
+ if (src[i] == '(')
+ {
+ if (first < 0)
+ {
+ count = 1;
+ src[i] = 0x0;
+ first = i;
+ }
+ else
+ {
+ count++;
+ dst[j++] = src[i];
+ }
+ }
+ else if (src[i] == ')')
+ {
+ if (--count == 0)
+ {
+ dst[j] = 0;
+ return &src[i+1];
+ }
+ else
+ {
+ dst[j++] = src[i];
+ }
+ }
+ else
+ {
+ if (first >= 0)
+ dst[j++] = src[i];
+ }
+ }
+ if (count)
+ ShowError(ERR_NO_MATCHING_BRACKETS);
+ return NULL;
+}
+
+// Bizarre in-place expression evaluator.
+u32 DSPAssembler::ParseExpression(const char *ptr)
+{
+ char *pbuf;
+ s32 val = 0;
+
+ char *d_buffer = (char *)malloc(1024);
+ char *s_buffer = (char *)malloc(1024);
+ strcpy(s_buffer, ptr);
+
+ while ((pbuf = FindBrackets(s_buffer, d_buffer)) != NULL)
+ {
+ val = ParseExpression(d_buffer);
+ sprintf(d_buffer, "%s%d%s", s_buffer, val, pbuf);
+ strcpy(s_buffer, d_buffer);
+ }
+
+ int j = 0;
+ for (int i = 0; i < ((s32)strlen(s_buffer) + 1) ; i++)
+ {
+ char c = s_buffer[i];
+ if (c != ' ')
+ d_buffer[j++] = c;
+ }
+
+ for (int i = 0; i < ((s32)strlen(d_buffer) + 1) ; i++)
+ {
+ char c = d_buffer[i];
+ if (c == '-')
+ {
+ if (i == 0)
+ c = '#';
+ else
+ {
+ switch (d_buffer[i - 1])
+ {
+ case '/':
+ case '%':
+ case '*':
+ c = '#';
+ }
+ }
+ }
+ d_buffer[i] = c;
+ }
+
+ while ((pbuf = strstr(d_buffer, "+")) != NULL)
+ {
+ *pbuf = 0x0;
+ val = ParseExpression(d_buffer) + ParseExpression(pbuf+1);
+ sprintf(d_buffer, "%d", val);
+ }
+
+ while ((pbuf = strstr(d_buffer, "-")) != NULL)
+ {
+ *pbuf = 0x0;
+ val = ParseExpression(d_buffer) - ParseExpression(pbuf+1);
+ if (val < 0)
+ {
+ val = 0x10000 + (val & 0xffff); // ATTENTION: avoid a terrible bug!!! number cannot write with '-' in sprintf
+ fprintf(stderr, "WARNING: Number Underflow at Line: %d \n", code_line);
+ }
+ sprintf(d_buffer, "%d", val);
+ }
+
+ while ((pbuf = strstr(d_buffer, "*")) != NULL)
+ {
+ *pbuf = 0x0;
+ val = ParseExpression(d_buffer) * ParseExpression(pbuf+1);
+ sprintf(d_buffer, "%d", val);
+ }
+
+ while ((pbuf = strstr(d_buffer, "/")) != NULL)
+ {
+ *pbuf = 0x0;
+ val = ParseExpression(d_buffer) / ParseExpression(pbuf+1);
+ sprintf(d_buffer, "%d", val);
+ }
+
+ while ((pbuf = strstr(d_buffer, "|")) != NULL)
+ {
+ *pbuf = 0x0;
+ val = ParseExpression(d_buffer) | ParseExpression(pbuf+1);
+ sprintf(d_buffer, "%d", val);
+ }
+
+ while ((pbuf = strstr(d_buffer, "&")) != NULL)
+ {
+ *pbuf = 0x0;
+ val = ParseExpression(d_buffer) & ParseExpression(pbuf+1);
+ sprintf(d_buffer, "%d", val);
+ }
+
+ val = ParseValue(d_buffer);
+ free(d_buffer);
+ free(s_buffer);
+ return val;
+}
+
+// Destroys parstr
+u32 DSPAssembler::GetParams(char *parstr, param_t *par)
+{
+ u32 count = 0;
+ char *tmpstr = skip_spaces(parstr);
+ tmpstr = strtok(tmpstr, ",\x00");
+ for (int i = 0; i < 10; i++)
+ {
+ if (tmpstr == NULL)
+ break;
+ tmpstr = skip_spaces(tmpstr);
+ if (strlen(tmpstr) == 0)
+ break;
+ if (tmpstr)
+ count++;
+ else
+ break;
+
+ par[i].type = P_NONE;
+ switch (tmpstr[0])
+ {
+ case '"':
+ par[i].str = strtok(tmpstr, "\"");
+ par[i].type = P_STR;
+ break;
+ case '#':
+ par[i].val = ParseExpression(tmpstr + 1);
+ par[i].type = P_IMM;
+ break;
+ case '@':
+ if (tmpstr[1] == '$')
+ {
+ par[i].val = ParseExpression(tmpstr + 2);
+ par[i].type = P_PRG;
+ }
+ else
+ {
+ par[i].val = ParseExpression(tmpstr + 1);
+ par[i].type = P_MEM;
+ }
+ break;
+ case '$':
+ par[i].val = ParseExpression(tmpstr + 1);
+ par[i].type = P_REG;
+ break;
+
+ default:
+ par[i].val = ParseExpression(tmpstr);
+ par[i].type = P_VAL;
+ break;
+ }
+ tmpstr = strtok(NULL, ",\x00");
+ }
+ return count;
+}
+
+const opc_t *DSPAssembler::FindOpcode(const char *opcode, u32 par_count, const opc_t * const opcod, int opcod_size)
+{
+ if (opcode[0] == 'C' && opcode[1] == 'W')
+ return &cw;
+
+ AliasMap::const_iterator alias_iter = aliases.find(opcode);
+ if (alias_iter != aliases.end())
+ opcode = alias_iter->second.c_str();
+ for (int i = 0; i < opcod_size; i++)
+ {
+ const opc_t *opc = &opcod[i];
+ if (strcmp(opc->name, opcode) == 0)
+ {
+ if (par_count < opc->param_count)
+ {
+ ShowError(ERR_NOT_ENOUGH_PARAMETERS);
+ }
+ if (par_count > opc->param_count)
+ {
+ ShowError(ERR_TOO_MANY_PARAMETERS);
+ }
+ return opc;
+ }
+ }
+ ShowError(ERR_UNKNOWN_OPCODE);
+ return NULL;
+}
+
+// weird...
+u16 get_mask_shifted_down(u16 mask)
+{
+ while (!(mask & 1))
+ mask >>= 1;
+ return mask;
+}
+
+bool DSPAssembler::VerifyParams(const opc_t *opc, param_t *par, int count, bool ext)
+{
+ for (int i = 0; i < count; i++)
+ {
+ const int current_param = i + 1; // just for display.
+ if (opc->params[i].type != par[i].type || (par[i].type & P_REG))
+ {
+ if (par[i].type == P_VAL &&
+ (opc->params[i].type == P_ADDR_I || opc->params[i].type == P_ADDR_D))
+ {
+ // Data and instruction addresses are valid as VAL values.
+ continue;
+ }
+
+ if ((opc->params[i].type & P_REG) && (par[i].type & P_REG))
+ {
+ // Just a temp. Should be replaced with more purposeful vars.
+ int value;
+
+ // modified by Hermes: test the register range
+ switch ((unsigned)opc->params[i].type)
+ {
+ case P_REG18:
+ case P_REG19:
+ case P_REG1A:
+ value = (opc->params[i].type >> 8) & 31;
+ if ((int)par[i].val < value ||
+ (int)par[i].val > value + get_mask_shifted_down(opc->params[i].mask))
+ {
+ if (ext) fprintf(stderr, "(ext) ");
+ fprintf(stderr, "%s (param %i)", cur_line.c_str(), current_param);
+ ShowError(ERR_INVALID_REGISTER);
+ }
+ break;
+ case P_PRG:
+ if ((int)par[i].val < 0 || (int)par[i].val > 0x3)
+ {
+ if (ext) fprintf(stderr, "(ext) ");
+ fprintf(stderr, "%s (param %i)", cur_line.c_str(), current_param);
+ ShowError(ERR_INVALID_REGISTER);
+ }
+ break;
+ case P_ACC:
+ if ((int)par[i].val < 0x20 || (int)par[i].val > 0x21)
+ {
+ if (ext) fprintf(stderr, "(ext) ");
+ if (par[i].val >= 0x1e && par[i].val <= 0x1f) {
+ fprintf(stderr, "%i : %s", code_line, cur_line.c_str());
+ fprintf(stderr, "WARNING: $ACM%d register used instead of $ACC%d register Line: %d Param: %d Ext: %d\n",
+ (par[i].val & 1), (par[i].val & 1), code_line, current_param, ext);
+ }
+ else if (par[i].val >= 0x1c && par[i].val <= 0x1d) {
+ fprintf(stderr, "WARNING: $ACL%d register used instead of $ACC%d register Line: %d Param: %d\n",
+ (par[i].val & 1), (par[i].val & 1), code_line, current_param);
+ }
+ else
+ ShowError(ERR_WRONG_PARAMETER_ACC);
+ }
+ break;
+ case P_ACCM:
+ if ((int)par[i].val < 0x1e || (int)par[i].val > 0x1f)
+ {
+ if (ext) fprintf(stderr, "(ext) ");
+ if (par[i].val >= 0x1c && par[i].val <= 0x1d)
+ fprintf(stderr, "WARNING: $ACL%d register used instead of $ACM%d register Line: %d Param: %d\n",
+ (par[i].val & 1), (par[i].val & 1), code_line, current_param);
+ else if (par[i].val >= 0x20 && par[i].val <= 0x21)
+ fprintf(stderr, "WARNING: $ACC%d register used instead of $ACM%d register Line: %d Param: %d\n",
+ (par[i].val & 1), (par[i].val & 1), code_line, current_param);
+ else
+ ShowError(ERR_WRONG_PARAMETER_ACC);
+ }
+ break;
+
+ case P_ACCL:
+ if ((int)par[i].val < 0x1c || (int)par[i].val > 0x1d)
+ {
+ if (ext) fprintf(stderr, "(ext) ");
+ if (par[i].val >= 0x1e && par[i].val <= 0x1f)
+ {
+ fprintf(stderr, "%s", cur_line.c_str());
+ fprintf(stderr, "WARNING: $ACM%d register used instead of $ACL%d register Line: %d Param: %d\n",
+ (par[i].val & 1), (par[i].val & 1), code_line, current_param);
+ }
+ else if (par[i].val >= 0x20 && par[i].val <= 0x21) {
+ fprintf(stderr, "%s", cur_line.c_str());
+ fprintf(stderr, "WARNING: $ACC%d register used instead of $ACL%d register Line: %d Param: %d\n",
+ (par[i].val & 1), (par[i].val & 1), code_line, current_param);
+ }
+ else
+ ShowError(ERR_WRONG_PARAMETER_ACC);
+ }
+ break;
+/* case P_ACCM_D: //P_ACC_MID:
+ if ((int)par[i].val < 0x1e || (int)par[i].val > 0x1f)
+ {
+ ShowError(ERR_WRONG_PARAMETER_MID_ACC);
+ }
+ break;*/
+ }
+ continue;
+ }
+
+ switch (par[i].type & (P_REG | 7))
+ {
+ case P_REG:
+ if (ext) fprintf(stderr, "(ext) ");
+ ShowError(ERR_EXPECTED_PARAM_REG);
+ break;
+ case P_MEM:
+ if (ext) fprintf(stderr, "(ext) ");
+ ShowError(ERR_EXPECTED_PARAM_MEM);
+ break;
+ case P_VAL:
+ if (ext) fprintf(stderr, "(ext) ");
+ ShowError(ERR_EXPECTED_PARAM_VAL);
+ break;
+ case P_IMM:
+ if (ext) fprintf(stderr, "(ext) ");
+ ShowError(ERR_EXPECTED_PARAM_IMM);
+ break;
+ }
+ ShowError(ERR_WRONG_PARAMETER);
+ break;
+ }
+ else if ((opc->params[i].type & 3) != 0 && (par[i].type & 3) != 0)
+ {
+ // modified by Hermes: test NUMBER range
+ int value = get_mask_shifted_down(opc->params[i].mask);
+ unsigned int valueu = 0xffff & ~(value >> 1);
+ if ((int)par[i].val < 0)
+ {
+ if (value == 7) // value 7 por sbclr/sbset
+ {
+ fprintf(stderr,"Value must be from 0x0 to 0x%x\n", value);
+ ShowError(ERR_OUT_RANGE_NUMBER);
+ }
+ else if (opc->params[i].type == P_MEM)
+ {
+ if (value < 256)
+ fprintf(stderr, "Address value must be from 0x%x to 0x%x\n",valueu, (value>>1));
+ else
+ fprintf(stderr, "Address value must be from 0x0 to 0x%x\n", value);
+
+ ShowError(ERR_OUT_RANGE_NUMBER);
+ }
+ else if ((int)par[i].val < -((value >> 1) + 1))
+ {
+ if (value < 128)
+ fprintf(stderr, "Value must be from -0x%x to 0x%x, is %i\n",
+ (value >> 1) + 1, value >> 1, par[i].val);
+ else
+ fprintf(stderr, "Value must be from -0x%x to 0x%x or 0x0 to 0x%x, is %i\n",
+ (value >> 1) + 1, value >> 1, value, par[i].val);
+
+ ShowError(ERR_OUT_RANGE_NUMBER);
+ }
+ }
+ else
+ {
+ if (value == 7) // value 7 por sbclr/sbset
+ {
+ if (par[i].val > (unsigned)value)
+ {
+ fprintf(stderr,"Value must be from 0x%x to 0x%x, is %i\n",valueu, value, par[i].val);
+ ShowError(ERR_OUT_RANGE_NUMBER);
+ }
+ }
+ else if (opc->params[i].type == P_MEM)
+ {
+ if (value < 256)
+ value >>= 1; // addressing 8 bit with sign
+ if (par[i].val > (unsigned)value &&
+ (par[i].val < valueu || par[i].val > (unsigned)0xffff))
+ {
+ if (value < 256)
+ fprintf(stderr,"Address value must be from 0x%x to 0x%x, is %04x\n", valueu, value, par[i].val);
+ else
+ fprintf(stderr,"Address value must be minor of 0x%x\n", value+1);
+ ShowError(ERR_OUT_RANGE_NUMBER);
+ }
+ }
+ else
+ {
+ if (value < 128)
+ value >>= 1; // special case ASL/ASR/LSL/LSR
+ if (par[i].val > (unsigned)value)
+ {
+ if (value < 64)
+ fprintf(stderr,"Value must be from -0x%x to 0x%x, is %i\n", (value + 1), value, par[i].val);
+ else
+ fprintf(stderr,"Value must be minor of 0x%x, is %i\n", value + 1, par[i].val);
+ ShowError(ERR_OUT_RANGE_NUMBER);
+ }
+ }
+ }
+ continue;
+ }
+ }
+ m_current_param = 0;
+ return true;
+}
+
+
+// Merge opcode with params.
+void DSPAssembler::BuildCode(const opc_t *opc, param_t *par, u32 par_count, u16 *outbuf)
+{
+ outbuf[m_cur_addr] |= opc->opcode;
+ for (u32 i = 0; i < par_count; i++)
+ {
+ // Ignore the "reverse" parameters since they are implicit.
+ if (opc->params[i].type != P_ACC_D && opc->params[i].type != P_ACCM_D)
+ {
+ u16 t16 = outbuf[m_cur_addr + opc->params[i].loc];
+ u16 v16 = par[i].val;
+ if (opc->params[i].lshift > 0)
+ v16 <<= opc->params[i].lshift;
+ else
+ v16 >>= -opc->params[i].lshift;
+ v16 &= opc->params[i].mask;
+ outbuf[m_cur_addr + opc->params[i].loc] = t16 | v16;
+ }
+ }
+}
+
+void DSPAssembler::InitPass(int pass)
+{
+ failed = false;
+ if (pass == 1)
+ {
+ // Reset label table. Pre-populate with hw addresses and registers.
+ labels.Clear();
+ labels.RegisterDefaults();
+ aliases.clear();
+ aliases["S15"] = "SET15";
+ aliases["S16"] = "SET16";
+ aliases["S40"] = "SET40";
+ }
+ m_cur_addr = 0;
+ m_totalSize = 0;
+ cur_segment = SEGMENT_CODE;
+ segment_addr[SEGMENT_CODE] = 0;
+ segment_addr[SEGMENT_DATA] = 0;
+ segment_addr[SEGMENT_OVERLAY] = 0;
+}
+
+bool DSPAssembler::AssembleFile(const char *fname, int pass)
+{
+ int disable_text = 0; // modified by Hermes
+
+ std::ifstream fsrc(fname);
+
+ if (fsrc.fail())
+ {
+ std::cerr << "Cannot open file " << fname << std::endl;
+ return false;
+ }
+
+ //printf("%s: Pass %d\n", fname, pass);
+ code_line = 0;
+ m_cur_pass = pass;
+
+#define LINEBUF_SIZE 1024
+ char line[LINEBUF_SIZE] = {0};
+ while (!failed && !fsrc.fail() && !fsrc.eof())
+ {
+ int opcode_size = 0;
+ fsrc.getline(line, LINEBUF_SIZE);
+ if(fsrc.fail())
+ break;
+
+ cur_line = line;
+ //printf("A: %s\n", line);
+ code_line++;
+
+ param_t params[10] = {{0}};
+ param_t params_ext[10] = {{0}};
+
+ bool upper = true;
+ for (int i = 0; i < LINEBUF_SIZE; i++)
+ {
+ char c = line[i];
+ // This stuff handles /**/ and // comments.
+ // modified by Hermes : added // and /* */ for long commentaries
+ if (c == '/')
+ {
+ if (i < 1023)
+ {
+ if (line[i+1] == '/')
+ c = 0x00;
+ else if (line[i+1] == '*')
+ {
+ // toggle comment mode.
+ disable_text = !disable_text;
+ }
+ }
+ }
+ else if (c == '*')
+ {
+ if (i < 1023 && line[i+1] == '/' && disable_text)
+ {
+ disable_text = 0;
+ c = 32;
+ line[i + 1] = 32;
+ }
+ }
+
+ // turn text into spaces if disable_text is on (in a comment).
+ if (disable_text && ((unsigned char)c) > 32) c = 32;
+
+ if (c == 0x0a || c == 0x0d || c == ';')
+ c = 0x00;
+ if (c == 0x09) // tabs to spaces
+ c = ' ';
+ if (c == '"')
+ upper = !upper;
+ if (upper && c >= 'a' && c <= 'z') // convert to uppercase
+ c = c - 'a' + 'A';
+ line[i] = c;
+ if (c == 0)
+ break; // modified by Hermes
+ }
+ char *ptr = line;
+
+ std::string label;
+
+ size_t col_pos = std::string(line).find(":");
+ if (col_pos != std::string::npos)
+ {
+ bool valid = true;
+
+ for(int j = 0; j < (int)col_pos; j++)
+ {
+ if (j == 0)
+ if (!((ptr[j] >= 'A' && ptr[j] <= 'Z') || (ptr[j] == '_')))
+ valid = false;
+ if (!((ptr[j] >= '0' && ptr[j] <= '9') || (ptr[j] >= 'A' && ptr[j] <= 'Z') || (ptr[j] == '_')))
+ valid = false;
+ }
+ if (valid)
+ {
+ label = std::string(line).substr(0, col_pos);
+ ptr += col_pos + 1;
+ }
+ }
+
+ char *opcode = NULL;
+ opcode = strtok(ptr, " ");
+ char *opcode_ext = NULL;
+
+ u32 params_count = 0;
+ u32 params_count_ext = 0;
+ if (opcode)
+ {
+ if ((opcode_ext = strstr(opcode, "'")) != NULL)
+ {
+ opcode_ext[0] = '\0';
+ opcode_ext++;
+ if (strlen(opcode_ext) == 0)
+ opcode_ext = NULL;
+ }
+ // now we have opcode and label
+
+ params_count = 0;
+ params_count_ext = 0;
+
+ char *paramstr = strtok(NULL, "\0");
+ char *paramstr_ext = 0;
+ // there is valid opcode so probably we have parameters
+
+ if (paramstr)
+ {
+ if ((paramstr_ext = strstr(paramstr, ":")) != NULL)
+ {
+ paramstr_ext[0] = '\0';
+ paramstr_ext++;
+ }
+ }
+
+ if (paramstr)
+ params_count = GetParams(paramstr, params);
+ if (paramstr_ext)
+ params_count_ext = GetParams(paramstr_ext, params_ext);
+ }
+
+ if (!label.empty())
+ {
+ // there is a valid label so lets store it in labels table
+ u32 lval = m_cur_addr;
+ if (opcode)
+ {
+ if (strcmp(opcode, "EQU") == 0)
+ {
+ lval = params[0].val;
+ opcode = NULL;
+ }
+ }
+ if (pass == 1)
+ labels.RegisterLabel(label, lval);
+ }
+
+ if (opcode == NULL)
+ continue;
+
+ // check if opcode is reserved compiler word
+ if (strcmp("INCLUDE", opcode) == 0)
+ {
+ if (params[0].type == P_STR)
+ {
+ char *tmpstr;
+ u32 thisCodeline = code_line;
+
+ if (include_dir.size())
+ {
+ tmpstr = (char *)malloc(include_dir.size() + strlen(params[0].str) + 2);
+ sprintf(tmpstr, "%s/%s", include_dir.c_str(), params[0].str);
+ }
+ else
+ {
+ tmpstr = (char *)malloc(strlen(params[0].str) + 1);
+ strcpy(tmpstr, params[0].str);
+ }
+
+ AssembleFile(tmpstr, pass);
+
+ code_line = thisCodeline;
+
+ free(tmpstr);
+ }
+ else
+ ShowError(ERR_EXPECTED_PARAM_STR);
+ continue;
+ }
+
+ if (strcmp("INCDIR", opcode) == 0)
+ {
+ if (params[0].type == P_STR)
+ include_dir = params[0].str;
+ else
+ ShowError(ERR_EXPECTED_PARAM_STR);
+ continue;
+ }
+
+ if (strcmp("ORG", opcode) == 0)
+ {
+ if (params[0].type == P_VAL)
+ m_cur_addr = params[0].val;
+ else
+ ShowError(ERR_EXPECTED_PARAM_VAL);
+ continue;
+ }
+
+ if (strcmp("SEGMENT", opcode) == 0)
+ {
+ if (params[0].type == P_STR)
+ {
+ segment_addr[cur_segment] = m_cur_addr;
+ if (strcmp("DATA", params[0].str) == 0)
+ cur_segment = SEGMENT_DATA;
+ if (strcmp("CODE", params[0].str) == 0)
+ cur_segment = SEGMENT_CODE;
+ m_cur_addr = segment_addr[cur_segment];
+ }
+ else
+ ShowError(ERR_EXPECTED_PARAM_STR);
+ continue;
+ }
+
+ const opc_t *opc = FindOpcode(opcode, params_count, opcodes, opcodes_size);
+ if (!opc)
+ opc = &cw;
+
+ opcode_size = opc->size & ~P_EXT;
+
+ VerifyParams(opc, params, params_count);
+
+ const opc_t *opc_ext = NULL;
+ // Check for opcode extensions.
+ if (opc->size & P_EXT)
+ {
+ if (opcode_ext)
+ {
+ opc_ext = FindOpcode(opcode_ext, params_count_ext, opcodes_ext, opcodes_ext_size);
+ VerifyParams(opc_ext, params_ext, params_count_ext, true);
+ }
+ else if (params_count_ext)
+ ShowError(ERR_EXT_PAR_NOT_EXT);
+ }
+ else
+ {
+ if (opcode_ext)
+ ShowError(ERR_EXT_CANT_EXTEND_OPCODE);
+ if (params_count_ext)
+ ShowError(ERR_EXT_PAR_NOT_EXT);
+ }
+
+ if (pass == 2)
+ {
+ // generate binary
+ ((u16 *)gdg_buffer)[m_cur_addr] = 0x0000;
+ BuildCode(opc, params, params_count, (u16 *)gdg_buffer);
+ if (opc_ext)
+ BuildCode(opc_ext, params_ext, params_count_ext, (u16 *)gdg_buffer);
+ }
+
+ m_cur_addr += opcode_size;
+ m_totalSize += opcode_size;
+ };
+
+ if (!failed)
+ fsrc.close();
+
+ return !failed;
+}
diff --git a/Source/Core/DSPCore/Src/assemble.h b/Source/Core/DSPCore/Src/assemble.h
index 304b97aaab..f140d0e69e 100644
--- a/Source/Core/DSPCore/Src/assemble.h
+++ b/Source/Core/DSPCore/Src/assemble.h
@@ -1,139 +1,139 @@
-/*====================================================================
-
- project: GameCube DSP Tool (gcdsp)
- created: 2005.03.04
- mail: duddie@walla.com
-
- Copyright (c) 2005 Duddie
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- ====================================================================*/
-
-#ifndef _DSP_ASSEMBLE_H
-#define _DSP_ASSEMBLE_H
-
-#include <string>
-#include <map>
-
-#include "Common.h"
-#include "disassemble.h"
-#include "DSPTables.h"
-#include "LabelMap.h"
-
-enum err_t
-{
- ERR_OK = 0,
- ERR_UNKNOWN,
- ERR_UNKNOWN_OPCODE,
- ERR_NOT_ENOUGH_PARAMETERS,
- ERR_TOO_MANY_PARAMETERS,
- ERR_WRONG_PARAMETER,
- ERR_EXPECTED_PARAM_STR,
- ERR_EXPECTED_PARAM_VAL,
- ERR_EXPECTED_PARAM_REG,
- ERR_EXPECTED_PARAM_MEM,
- ERR_EXPECTED_PARAM_IMM,
- ERR_INCORRECT_BIN,
- ERR_INCORRECT_HEX,
- ERR_INCORRECT_DEC,
- ERR_LABEL_EXISTS,
- ERR_UNKNOWN_LABEL,
- ERR_NO_MATCHING_BRACKETS,
- ERR_EXT_CANT_EXTEND_OPCODE,
- ERR_EXT_PAR_NOT_EXT,
- ERR_WRONG_PARAMETER_ACC,
- ERR_WRONG_PARAMETER_MID_ACC,
- ERR_INVALID_REGISTER,
- ERR_OUT_RANGE_NUMBER
-};
-
-
-// Unless you want labels to carry over between files, you probably
-// want to create a new DSPAssembler for every file you assemble.
-class DSPAssembler
-{
-public:
- DSPAssembler(const AssemblerSettings &settings);
- ~DSPAssembler();
-
- // line_numbers is optional (and not yet implemented). It'll receieve a list of ints,
- // one for each word of code, indicating the source assembler code line number it came from.
-
- // If returns false, call GetErrorString to get some text to present to the user.
- bool Assemble(const char *text, std::vector<u16> &code, std::vector<int> *line_numbers = NULL);
-
- std::string GetErrorString() const { return last_error_str; }
- err_t GetError() const { return last_error; }
-
-private:
- struct param_t
- {
- u32 val;
- partype_t type;
- char *str;
- };
-
- enum segment_t
- {
- SEGMENT_CODE = 0,
- SEGMENT_DATA,
- SEGMENT_OVERLAY,
- SEGMENT_MAX
- };
-
- // Utility functions
- s32 ParseValue(const char *str);
- u32 ParseExpression(const char *ptr);
-
- u32 GetParams(char *parstr, param_t *par);
-
- void InitPass(int pass);
- bool AssembleFile(const char *fname, int pass);
-
- void ShowError(err_t err_code, const char *extra_info = NULL);
- // void ShowWarning(err_t err_code, const char *extra_info = NULL);
-
- char *FindBrackets(char *src, char *dst);
- const opc_t *FindOpcode(const char *opcode, u32 par_count, const opc_t * const opcod, int opcod_size);
- bool VerifyParams(const opc_t *opc, param_t *par, int count, bool ext = false);
- void BuildCode(const opc_t *opc, param_t *par, u32 par_count, u16 *outbuf);
-
- char *gdg_buffer;
-
- std::string include_dir;
- std::string cur_line;
-
- u32 m_cur_addr;
- int m_totalSize;
- u8 m_cur_pass;
-
- LabelMap labels;
-
- u32 code_line;
- bool failed;
- std::string last_error_str;
- err_t last_error;
-
- typedef std::map<std::string, std::string> AliasMap;
- AliasMap aliases;
-
- segment_t cur_segment;
- u32 segment_addr[SEGMENT_MAX];
- int m_current_param;
- const AssemblerSettings settings_;
-};
-
-#endif // _DSP_ASSEMBLE_H
+/*====================================================================
+
+ project: GameCube DSP Tool (gcdsp)
+ created: 2005.03.04
+ mail: duddie@walla.com
+
+ Copyright (c) 2005 Duddie
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ ====================================================================*/
+
+#ifndef _DSP_ASSEMBLE_H
+#define _DSP_ASSEMBLE_H
+
+#include <string>
+#include <map>
+
+#include "Common.h"
+#include "disassemble.h"
+#include "DSPTables.h"
+#include "LabelMap.h"
+
+enum err_t
+{
+ ERR_OK = 0,
+ ERR_UNKNOWN,
+ ERR_UNKNOWN_OPCODE,
+ ERR_NOT_ENOUGH_PARAMETERS,
+ ERR_TOO_MANY_PARAMETERS,
+ ERR_WRONG_PARAMETER,
+ ERR_EXPECTED_PARAM_STR,
+ ERR_EXPECTED_PARAM_VAL,
+ ERR_EXPECTED_PARAM_REG,
+ ERR_EXPECTED_PARAM_MEM,
+ ERR_EXPECTED_PARAM_IMM,
+ ERR_INCORRECT_BIN,
+ ERR_INCORRECT_HEX,
+ ERR_INCORRECT_DEC,
+ ERR_LABEL_EXISTS,
+ ERR_UNKNOWN_LABEL,
+ ERR_NO_MATCHING_BRACKETS,
+ ERR_EXT_CANT_EXTEND_OPCODE,
+ ERR_EXT_PAR_NOT_EXT,
+ ERR_WRONG_PARAMETER_ACC,
+ ERR_WRONG_PARAMETER_MID_ACC,
+ ERR_INVALID_REGISTER,
+ ERR_OUT_RANGE_NUMBER
+};
+
+
+// Unless you want labels to carry over between files, you probably
+// want to create a new DSPAssembler for every file you assemble.
+class DSPAssembler
+{
+public:
+ DSPAssembler(const AssemblerSettings &settings);
+ ~DSPAssembler();
+
+ // line_numbers is optional (and not yet implemented). It'll receieve a list of ints,
+ // one for each word of code, indicating the source assembler code line number it came from.
+
+ // If returns false, call GetErrorString to get some text to present to the user.
+ bool Assemble(const char *text, std::vector<u16> &code, std::vector<int> *line_numbers = NULL);
+
+ std::string GetErrorString() const { return last_error_str; }
+ err_t GetError() const { return last_error; }
+
+private:
+ struct param_t
+ {
+ u32 val;
+ partype_t type;
+ char *str;
+ };
+
+ enum segment_t
+ {
+ SEGMENT_CODE = 0,
+ SEGMENT_DATA,
+ SEGMENT_OVERLAY,
+ SEGMENT_MAX
+ };
+
+ // Utility functions
+ s32 ParseValue(const char *str);
+ u32 ParseExpression(const char *ptr);
+
+ u32 GetParams(char *parstr, param_t *par);
+
+ void InitPass(int pass);
+ bool AssembleFile(const char *fname, int pass);
+
+ void ShowError(err_t err_code, const char *extra_info = NULL);
+ // void ShowWarning(err_t err_code, const char *extra_info = NULL);
+
+ char *FindBrackets(char *src, char *dst);
+ const opc_t *FindOpcode(const char *opcode, u32 par_count, const opc_t * const opcod, int opcod_size);
+ bool VerifyParams(const opc_t *opc, param_t *par, int count, bool ext = false);
+ void BuildCode(const opc_t *opc, param_t *par, u32 par_count, u16 *outbuf);
+
+ char *gdg_buffer;
+
+ std::string include_dir;
+ std::string cur_line;
+
+ u32 m_cur_addr;
+ int m_totalSize;
+ u8 m_cur_pass;
+
+ LabelMap labels;
+
+ u32 code_line;
+ bool failed;
+ std::string last_error_str;
+ err_t last_error;
+
+ typedef std::map<std::string, std::string> AliasMap;
+ AliasMap aliases;
+
+ segment_t cur_segment;
+ u32 segment_addr[SEGMENT_MAX];
+ int m_current_param;
+ const AssemblerSettings settings_;
+};
+
+#endif // _DSP_ASSEMBLE_H
diff --git a/Source/Core/DebuggerUICommon/Src/DebuggerUIUtil.cpp b/Source/Core/DebuggerUICommon/Src/DebuggerUIUtil.cpp
index 6ee1e213b7..db1b28c09a 100644
--- a/Source/Core/DebuggerUICommon/Src/DebuggerUIUtil.cpp
+++ b/Source/Core/DebuggerUICommon/Src/DebuggerUIUtil.cpp
@@ -1,23 +1,23 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-
-#include "DebuggerUIUtil.h"
-
-// The default font
-wxFont DebuggerFont = wxFont(9, wxMODERN, wxNORMAL, wxNORMAL, false, wxT("monospace"));
-
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+
+#include "DebuggerUIUtil.h"
+
+// The default font
+wxFont DebuggerFont = wxFont(9, wxMODERN, wxNORMAL, wxNORMAL, false, wxT("monospace"));
+
diff --git a/Source/Core/DebuggerUICommon/Src/DebuggerUIUtil.h b/Source/Core/DebuggerUICommon/Src/DebuggerUIUtil.h
index fc75e9478e..12f11a2b62 100644
--- a/Source/Core/DebuggerUICommon/Src/DebuggerUIUtil.h
+++ b/Source/Core/DebuggerUICommon/Src/DebuggerUIUtil.h
@@ -1,36 +1,36 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _DEBUGGER_UI_UTIL_H
-#define _DEBUGGER_UI_UTIL_H
-
-#include <wx/wx.h>
-
-#define wxUSE_XPM_IN_MSW 1
-#define USE_XPM_BITMAPS 1
-
-// Defined in CodeWindow.cpp
-extern wxFont DebuggerFont;
-
-// define this to use XPMs everywhere (by default, BMPs are used under Win)
-// BMPs use less space, but aren't compiled into the executable on other platforms
-
-#if USE_XPM_BITMAPS && defined (__WXMSW__) && !wxUSE_XPM_IN_MSW
-#error You need to enable XPM support to use XPM bitmaps with toolbar!
-#endif // USE_XPM_BITMAPS
-
-#endif
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _DEBUGGER_UI_UTIL_H
+#define _DEBUGGER_UI_UTIL_H
+
+#include <wx/wx.h>
+
+#define wxUSE_XPM_IN_MSW 1
+#define USE_XPM_BITMAPS 1
+
+// Defined in CodeWindow.cpp
+extern wxFont DebuggerFont;
+
+// define this to use XPMs everywhere (by default, BMPs are used under Win)
+// BMPs use less space, but aren't compiled into the executable on other platforms
+
+#if USE_XPM_BITMAPS && defined (__WXMSW__) && !wxUSE_XPM_IN_MSW
+#error You need to enable XPM support to use XPM bitmaps with toolbar!
+#endif // USE_XPM_BITMAPS
+
+#endif
diff --git a/Source/Core/DiscIO/Src/NANDContentLoader.h b/Source/Core/DiscIO/Src/NANDContentLoader.h
index 0494eba5c7..c4fe87911a 100644
--- a/Source/Core/DiscIO/Src/NANDContentLoader.h
+++ b/Source/Core/DiscIO/Src/NANDContentLoader.h
@@ -1,100 +1,100 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _NAND_CONTENT_LOADER_H
-#define _NAND_CONTENT_LOADER_H
-
-#include <string>
-#include <vector>
-#include <map>
-
-#include "Common.h"
-#include "Blob.h"
-#include "Volume.h"
-
-namespace DiscIO
-{
-
-struct SNANDContent
-{
- u32 m_ContentID;
- u16 m_Index;
- u16 m_Type;
- u32 m_Size;
- u8 m_SHA1Hash[20];
- u8 m_Header[36]; //all of the above
-
- u8* m_pData;
-};
-
-// pure virtual interface so just the NANDContentManager can create these files only
-class INANDContentLoader
-{
-public:
-
- INANDContentLoader() {}
-
- virtual ~INANDContentLoader() {}
-
- virtual bool IsValid() const = 0;
- virtual u64 GetTitleID() const = 0;
- virtual u16 GetIosVersion() const = 0;
- virtual u32 GetBootIndex() const = 0;
- virtual size_t GetContentSize() const = 0;
- virtual const SNANDContent* GetContentByIndex(int _Index) const = 0;
- virtual const u8* GetTicketView() const = 0;
- virtual const u8* GetTmdHeader() const = 0;
- virtual const std::vector<SNANDContent>& GetContent() const = 0;
- virtual const u16 GetTitleVersion() const = 0;
- virtual const u16 GetNumEntries() const = 0;
- virtual const DiscIO::IVolume::ECountry GetCountry() const = 0;
-
- enum
- {
- TICKET_VIEW_SIZE = 0x58,
- TMD_HEADER_SIZE = 0x1e4,
- CONTENT_HEADER_SIZE = 0x24
- };
-};
-
-
-// we open the NAND Content files to often... lets cache them
-class CNANDContentManager
-{
-public:
-
- static CNANDContentManager& Access() { return m_Instance; }
-
- const INANDContentLoader& GetNANDLoader(const std::string& _rName);
-
-private:
-
- CNANDContentManager() {};
-
- ~CNANDContentManager();
-
- static CNANDContentManager m_Instance;
-
- typedef std::map<std::string, INANDContentLoader*> CNANDContentMap;
- CNANDContentMap m_Map;
-
-};
-
-}
-
-#endif
-
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _NAND_CONTENT_LOADER_H
+#define _NAND_CONTENT_LOADER_H
+
+#include <string>
+#include <vector>
+#include <map>
+
+#include "Common.h"
+#include "Blob.h"
+#include "Volume.h"
+
+namespace DiscIO
+{
+
+struct SNANDContent
+{
+ u32 m_ContentID;
+ u16 m_Index;
+ u16 m_Type;
+ u32 m_Size;
+ u8 m_SHA1Hash[20];
+ u8 m_Header[36]; //all of the above
+
+ u8* m_pData;
+};
+
+// pure virtual interface so just the NANDContentManager can create these files only
+class INANDContentLoader
+{
+public:
+
+ INANDContentLoader() {}
+
+ virtual ~INANDContentLoader() {}
+
+ virtual bool IsValid() const = 0;
+ virtual u64 GetTitleID() const = 0;
+ virtual u16 GetIosVersion() const = 0;
+ virtual u32 GetBootIndex() const = 0;
+ virtual size_t GetContentSize() const = 0;
+ virtual const SNANDContent* GetContentByIndex(int _Index) const = 0;
+ virtual const u8* GetTicketView() const = 0;
+ virtual const u8* GetTmdHeader() const = 0;
+ virtual const std::vector<SNANDContent>& GetContent() const = 0;
+ virtual const u16 GetTitleVersion() const = 0;
+ virtual const u16 GetNumEntries() const = 0;
+ virtual const DiscIO::IVolume::ECountry GetCountry() const = 0;
+
+ enum
+ {
+ TICKET_VIEW_SIZE = 0x58,
+ TMD_HEADER_SIZE = 0x1e4,
+ CONTENT_HEADER_SIZE = 0x24
+ };
+};
+
+
+// we open the NAND Content files to often... lets cache them
+class CNANDContentManager
+{
+public:
+
+ static CNANDContentManager& Access() { return m_Instance; }
+
+ const INANDContentLoader& GetNANDLoader(const std::string& _rName);
+
+private:
+
+ CNANDContentManager() {};
+
+ ~CNANDContentManager();
+
+ static CNANDContentManager m_Instance;
+
+ typedef std::map<std::string, INANDContentLoader*> CNANDContentMap;
+ CNANDContentMap m_Map;
+
+};
+
+}
+
+#endif
+
diff --git a/Source/Core/DiscIO/Src/VolumeWad.h b/Source/Core/DiscIO/Src/VolumeWad.h
index 6d37d8fdf8..2d72bb0aa9 100644
--- a/Source/Core/DiscIO/Src/VolumeWad.h
+++ b/Source/Core/DiscIO/Src/VolumeWad.h
@@ -1,52 +1,52 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#pragma once
-
-#include "Volume.h"
-#include "Blob.h"
-#include "NANDContentLoader.h"
-
-// --- this volume type is used for Wad files ---
-// Some of this code might look redundant with the CNANDContentLoader class, however,
-// We do not do any decryption here, we do raw read, so things are -Faster-
-
-namespace DiscIO
-{
-class CVolumeWAD : public IVolume
-{
-public:
- CVolumeWAD(IBlobReader* _pReader);
- ~CVolumeWAD();
- bool Read(u64 _Offset, u64 _Length, u8* _pBuffer) const;
- bool RAWRead(u64 _Offset, u64 _Length, u8* _pBuffer) const { return false; }
- bool GetTitleID(u8* _pBuffer) const;
- std::string GetUniqueID() const;
- std::string GetMakerID() const;
- std::string GetName() const;
- u32 GetFSTSize() const { return 0; }
- std::string GetApploaderDate() const { return "0"; }
- ECountry GetCountry() const;
- u64 GetSize() const;
-
-private:
- IBlobReader* m_pReader;
- u64 m_titleID;
- u32 OpeningBnrOffset, hdr_size, cert_size, tick_size, tmd_size, data_size;
-};
-
-} // namespace
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#pragma once
+
+#include "Volume.h"
+#include "Blob.h"
+#include "NANDContentLoader.h"
+
+// --- this volume type is used for Wad files ---
+// Some of this code might look redundant with the CNANDContentLoader class, however,
+// We do not do any decryption here, we do raw read, so things are -Faster-
+
+namespace DiscIO
+{
+class CVolumeWAD : public IVolume
+{
+public:
+ CVolumeWAD(IBlobReader* _pReader);
+ ~CVolumeWAD();
+ bool Read(u64 _Offset, u64 _Length, u8* _pBuffer) const;
+ bool RAWRead(u64 _Offset, u64 _Length, u8* _pBuffer) const { return false; }
+ bool GetTitleID(u8* _pBuffer) const;
+ std::string GetUniqueID() const;
+ std::string GetMakerID() const;
+ std::string GetName() const;
+ u32 GetFSTSize() const { return 0; }
+ std::string GetApploaderDate() const { return "0"; }
+ ECountry GetCountry() const;
+ u64 GetSize() const;
+
+private:
+ IBlobReader* m_pReader;
+ u64 m_titleID;
+ u32 OpeningBnrOffset, hdr_size, cert_size, tick_size, tmd_size, data_size;
+};
+
+} // namespace
diff --git a/Source/Core/DiscIO/Src/WiiWad.cpp b/Source/Core/DiscIO/Src/WiiWad.cpp
index 73f22f31b5..10efafacdf 100644
--- a/Source/Core/DiscIO/Src/WiiWad.cpp
+++ b/Source/Core/DiscIO/Src/WiiWad.cpp
@@ -1,156 +1,156 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "stdafx.h"
-#include "NANDContentLoader.h"
-
-#include <algorithm>
-#include <cctype>
-#include "MathUtil.h"
-#include "FileUtil.h"
-#include "Log.h"
-#include "WiiWad.h"
-
-namespace DiscIO
-{
-
-class CBlobBigEndianReader
-{
-public:
- CBlobBigEndianReader(DiscIO::IBlobReader& _rReader) : m_rReader(_rReader) {}
-
- u32 Read32(u64 _Offset)
- {
- u32 Temp;
- m_rReader.Read(_Offset, 4, (u8*)&Temp);
- return(Common::swap32(Temp));
- }
-
-private:
- DiscIO::IBlobReader& m_rReader;
-};
-
-WiiWAD::WiiWAD(const std::string& _rName)
-{
- DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rName.c_str());
- if (pReader == NULL)
- {
- m_Valid = false;
- return;
- }
-
- m_Valid = ParseWAD(*pReader);
- delete pReader;
-}
-
-WiiWAD::~WiiWAD()
-{
- if (m_Valid)
- {
- delete m_pCertificateChain;
- delete m_pTicket;
- delete m_pTMD;
- delete m_pDataApp;
- delete m_pFooter;
- }
-}
-
-u8* WiiWAD::CreateWADEntry(DiscIO::IBlobReader& _rReader, u32 _Size, u64 _Offset)
-{
- if (_Size > 0)
- {
- u8* pTmpBuffer = new u8[_Size];
- _dbg_assert_msg_(BOOT, pTmpBuffer!=0, "WiiWAD: Cant allocate memory for WAD entry");
-
- if (!_rReader.Read(_Offset, _Size, pTmpBuffer))
- {
- ERROR_LOG(DISCIO, "WiiWAD: Could not read from file");
- PanicAlert("WiiWAD: Could not read from file");
- }
- return pTmpBuffer;
- }
- return NULL;
-}
-
-
-bool WiiWAD::ParseWAD(DiscIO::IBlobReader& _rReader)
-{
- CBlobBigEndianReader ReaderBig(_rReader);
-
- // get header size
- u32 HeaderSize = ReaderBig.Read32(0);
- if (HeaderSize != 0x20)
- {
- _dbg_assert_msg_(BOOT, (HeaderSize==0x20), "WiiWAD: Header size != 0x20");
- return false;
- }
-
- // get header
- u8 Header[0x20];
- _rReader.Read(0, HeaderSize, Header);
- u32 HeaderType = ReaderBig.Read32(0x4);
- if ((0x49730000 != HeaderType) && (0x69620000 != HeaderType))
- return false;
-
- m_CertificateChainSize = ReaderBig.Read32(0x8);
- u32 Reserved = ReaderBig.Read32(0xC);
- m_TicketSize = ReaderBig.Read32(0x10);
- m_TMDSize = ReaderBig.Read32(0x14);
- m_DataAppSize = ReaderBig.Read32(0x18);
- m_FooterSize = ReaderBig.Read32(0x1C);
- _dbg_assert_msg_(BOOT, Reserved==0x00, "WiiWAD: Reserved must be 0x00");
-
- u32 Offset = 0x40;
- m_pCertificateChain = CreateWADEntry(_rReader, m_CertificateChainSize, Offset); Offset += ROUND_UP(m_CertificateChainSize, 0x40);
- m_pTicket = CreateWADEntry(_rReader, m_TicketSize, Offset); Offset += ROUND_UP(m_TicketSize, 0x40);
- m_pTMD = CreateWADEntry(_rReader, m_TMDSize, Offset); Offset += ROUND_UP(m_TMDSize, 0x40);
- m_pDataApp = CreateWADEntry(_rReader, m_DataAppSize, Offset); Offset += ROUND_UP(m_DataAppSize, 0x40);
- m_pFooter = CreateWADEntry(_rReader, m_FooterSize, Offset); Offset += ROUND_UP(m_FooterSize, 0x40);
-
- return true;
-}
-
-bool WiiWAD::IsWiiWAD(const std::string& _rName)
-{
- DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rName.c_str());
- if (pReader == NULL)
- return false;
-
- CBlobBigEndianReader Reader(*pReader);
- bool Result = false;
-
- // check for wii wad
- if (Reader.Read32(0x00) == 0x20)
- {
- u32 WADTYpe = Reader.Read32(0x04);
- switch(WADTYpe)
- {
- case 0x49730000:
- case 0x69620000:
- Result = true;
- }
- }
-
- delete pReader;
-
- return Result;
-}
-
-
-
-} // namespace end
-
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "stdafx.h"
+#include "NANDContentLoader.h"
+
+#include <algorithm>
+#include <cctype>
+#include "MathUtil.h"
+#include "FileUtil.h"
+#include "Log.h"
+#include "WiiWad.h"
+
+namespace DiscIO
+{
+
+class CBlobBigEndianReader
+{
+public:
+ CBlobBigEndianReader(DiscIO::IBlobReader& _rReader) : m_rReader(_rReader) {}
+
+ u32 Read32(u64 _Offset)
+ {
+ u32 Temp;
+ m_rReader.Read(_Offset, 4, (u8*)&Temp);
+ return(Common::swap32(Temp));
+ }
+
+private:
+ DiscIO::IBlobReader& m_rReader;
+};
+
+WiiWAD::WiiWAD(const std::string& _rName)
+{
+ DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rName.c_str());
+ if (pReader == NULL)
+ {
+ m_Valid = false;
+ return;
+ }
+
+ m_Valid = ParseWAD(*pReader);
+ delete pReader;
+}
+
+WiiWAD::~WiiWAD()
+{
+ if (m_Valid)
+ {
+ delete m_pCertificateChain;
+ delete m_pTicket;
+ delete m_pTMD;
+ delete m_pDataApp;
+ delete m_pFooter;
+ }
+}
+
+u8* WiiWAD::CreateWADEntry(DiscIO::IBlobReader& _rReader, u32 _Size, u64 _Offset)
+{
+ if (_Size > 0)
+ {
+ u8* pTmpBuffer = new u8[_Size];
+ _dbg_assert_msg_(BOOT, pTmpBuffer!=0, "WiiWAD: Cant allocate memory for WAD entry");
+
+ if (!_rReader.Read(_Offset, _Size, pTmpBuffer))
+ {
+ ERROR_LOG(DISCIO, "WiiWAD: Could not read from file");
+ PanicAlert("WiiWAD: Could not read from file");
+ }
+ return pTmpBuffer;
+ }
+ return NULL;
+}
+
+
+bool WiiWAD::ParseWAD(DiscIO::IBlobReader& _rReader)
+{
+ CBlobBigEndianReader ReaderBig(_rReader);
+
+ // get header size
+ u32 HeaderSize = ReaderBig.Read32(0);
+ if (HeaderSize != 0x20)
+ {
+ _dbg_assert_msg_(BOOT, (HeaderSize==0x20), "WiiWAD: Header size != 0x20");
+ return false;
+ }
+
+ // get header
+ u8 Header[0x20];
+ _rReader.Read(0, HeaderSize, Header);
+ u32 HeaderType = ReaderBig.Read32(0x4);
+ if ((0x49730000 != HeaderType) && (0x69620000 != HeaderType))
+ return false;
+
+ m_CertificateChainSize = ReaderBig.Read32(0x8);
+ u32 Reserved = ReaderBig.Read32(0xC);
+ m_TicketSize = ReaderBig.Read32(0x10);
+ m_TMDSize = ReaderBig.Read32(0x14);
+ m_DataAppSize = ReaderBig.Read32(0x18);
+ m_FooterSize = ReaderBig.Read32(0x1C);
+ _dbg_assert_msg_(BOOT, Reserved==0x00, "WiiWAD: Reserved must be 0x00");
+
+ u32 Offset = 0x40;
+ m_pCertificateChain = CreateWADEntry(_rReader, m_CertificateChainSize, Offset); Offset += ROUND_UP(m_CertificateChainSize, 0x40);
+ m_pTicket = CreateWADEntry(_rReader, m_TicketSize, Offset); Offset += ROUND_UP(m_TicketSize, 0x40);
+ m_pTMD = CreateWADEntry(_rReader, m_TMDSize, Offset); Offset += ROUND_UP(m_TMDSize, 0x40);
+ m_pDataApp = CreateWADEntry(_rReader, m_DataAppSize, Offset); Offset += ROUND_UP(m_DataAppSize, 0x40);
+ m_pFooter = CreateWADEntry(_rReader, m_FooterSize, Offset); Offset += ROUND_UP(m_FooterSize, 0x40);
+
+ return true;
+}
+
+bool WiiWAD::IsWiiWAD(const std::string& _rName)
+{
+ DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rName.c_str());
+ if (pReader == NULL)
+ return false;
+
+ CBlobBigEndianReader Reader(*pReader);
+ bool Result = false;
+
+ // check for wii wad
+ if (Reader.Read32(0x00) == 0x20)
+ {
+ u32 WADTYpe = Reader.Read32(0x04);
+ switch(WADTYpe)
+ {
+ case 0x49730000:
+ case 0x69620000:
+ Result = true;
+ }
+ }
+
+ delete pReader;
+
+ return Result;
+}
+
+
+
+} // namespace end
+
diff --git a/Source/Core/DiscIO/Src/WiiWad.h b/Source/Core/DiscIO/Src/WiiWad.h
index 10b2ad867e..e07df2aa3a 100644
--- a/Source/Core/DiscIO/Src/WiiWad.h
+++ b/Source/Core/DiscIO/Src/WiiWad.h
@@ -1,78 +1,78 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _WII_WAD_H
-#define _WII_WAD_H
-
-#include <string>
-#include <vector>
-#include <map>
-
-#include "Common.h"
-#include "Blob.h"
-#include "Volume.h"
-
-namespace DiscIO
-{
-
-class WiiWAD
-{
-public:
-
- WiiWAD(const std::string& _rName);
-
- ~WiiWAD();
-
- bool IsValid() const { return m_Valid; }
- u32 GetCertificateChainSize() const { return m_CertificateChainSize; }
- u32 GetTicketSize() const { return m_TicketSize; }
- u32 GetTMDSize() const { return m_TMDSize; }
- u32 GetDataAppSize() const { return m_DataAppSize; }
- u32 GetFooterSize() const { return m_FooterSize; }
-
- u8* GetCertificateChain() const { return m_pCertificateChain; }
- u8* GetTicket() const { return m_pTicket; }
- u8* GetTMD() const { return m_pTMD; }
- u8* GetDataApp() const { return m_pDataApp; }
- u8* GetFooter() const { return m_pFooter; }
-
- static bool IsWiiWAD(const std::string& _rName);
-
-private:
-
- bool m_Valid;
-
- u32 m_CertificateChainSize;
- u32 m_TicketSize;
- u32 m_TMDSize;
- u32 m_DataAppSize;
- u32 m_FooterSize;
-
- u8* m_pCertificateChain;
- u8* m_pTicket;
- u8* m_pTMD;
- u8* m_pDataApp;
- u8* m_pFooter;
-
- u8* CreateWADEntry(DiscIO::IBlobReader& _rReader, u32 _Size, u64 _Offset);
- bool ParseWAD(DiscIO::IBlobReader& _rReader);
-};
-
-}
-
-#endif
-
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _WII_WAD_H
+#define _WII_WAD_H
+
+#include <string>
+#include <vector>
+#include <map>
+
+#include "Common.h"
+#include "Blob.h"
+#include "Volume.h"
+
+namespace DiscIO
+{
+
+class WiiWAD
+{
+public:
+
+ WiiWAD(const std::string& _rName);
+
+ ~WiiWAD();
+
+ bool IsValid() const { return m_Valid; }
+ u32 GetCertificateChainSize() const { return m_CertificateChainSize; }
+ u32 GetTicketSize() const { return m_TicketSize; }
+ u32 GetTMDSize() const { return m_TMDSize; }
+ u32 GetDataAppSize() const { return m_DataAppSize; }
+ u32 GetFooterSize() const { return m_FooterSize; }
+
+ u8* GetCertificateChain() const { return m_pCertificateChain; }
+ u8* GetTicket() const { return m_pTicket; }
+ u8* GetTMD() const { return m_pTMD; }
+ u8* GetDataApp() const { return m_pDataApp; }
+ u8* GetFooter() const { return m_pFooter; }
+
+ static bool IsWiiWAD(const std::string& _rName);
+
+private:
+
+ bool m_Valid;
+
+ u32 m_CertificateChainSize;
+ u32 m_TicketSize;
+ u32 m_TMDSize;
+ u32 m_DataAppSize;
+ u32 m_FooterSize;
+
+ u8* m_pCertificateChain;
+ u8* m_pTicket;
+ u8* m_pTMD;
+ u8* m_pDataApp;
+ u8* m_pFooter;
+
+ u8* CreateWADEntry(DiscIO::IBlobReader& _rReader, u32 _Size, u64 _Offset);
+ bool ParseWAD(DiscIO::IBlobReader& _rReader);
+};
+
+}
+
+#endif
+
diff --git a/Source/Core/DolphinWX/Src/NetEvent.cpp b/Source/Core/DolphinWX/Src/NetEvent.cpp
index 246879c0a8..6fc7280b1e 100644
--- a/Source/Core/DolphinWX/Src/NetEvent.cpp
+++ b/Source/Core/DolphinWX/Src/NetEvent.cpp
@@ -1,288 +1,288 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "NetWindow.h"
-
-void ClientSide::OnClientData(unsigned char data)
-{
- unsigned char sent = 0;
- u32 buffer_size;
- size_t recv_size;
- char *buffer = NULL;
-
- switch (data)
- {
- case 0x10: // Player joined server
- {
- // Read GameFound
- m_socket.Receive((char*)&sent, 1, recv_size);
-
- // Read nickname
- m_socket.Receive((char*)&buffer_size, 4, recv_size);
- buffer = new char[buffer_size+1];
- m_socket.Receive(buffer, buffer_size+1, recv_size);
- Event->AppendText(wxString::Format(wxT("*Player : %s is now connected to Host...\n"), buffer));
-
- if (sent != 0x1F)
- for (int i = 0; i < 4; i++)
- Event->AppendText(_("WARNING : Game Not Found on Client Side!\n"));
-
- m_numplayers++;
- Event->SendEvent(HOST_NEWPLAYER);
- break;
- }
- case 0x11: // Player left server
- {
- // Read Nickname
- m_socket.Receive((char*)&buffer_size, 4, recv_size);
- buffer = new char[buffer_size+1];
- m_socket.Receive(buffer, buffer_size+1, recv_size);
-
- Event->AppendText(wxString::Format(wxT("*Player : %s left the game\n\n"), buffer));
-
- m_numplayers--;
- Event->SendEvent(HOST_PLAYERLEFT);
- break;
- }
- case 0x15: // Ping Player
- {
- m_socket.Receive((char*)&buffer_size, 4, recv_size);
- m_socket.Send((const char*)&buffer_size, 4);
-
- break;
- }
- case 0x20: // IP request
- {
- //buffer_size = m_addr.size();
- //m_socket.Send((const char*)&buffer_size, 4);
- m_socket.Send((const char*)&data, 1);
- m_socket.Send(m_addr.c_str(), m_addr.size() + 1);
-
- break;
- }
- case 0x30: // Chat message received from server
- {
- m_socket.Receive((char*)&buffer_size, 4, recv_size);
- buffer = new char[buffer_size+1];
- m_socket.Receive(buffer, buffer_size+1, recv_size);
-
- if (recv_size > 1024)
- {
- //something wrong...
- delete[] buffer;
- return;
- }
-
- Event->AppendText(wxString::FromAscii(buffer));
-
- break;
- }
- case 0x35: // ChangeGame message received
- {
- m_socket.Receive((char*)&buffer_size, 4, recv_size);
- buffer = new char[buffer_size+1];
- m_socket.Receive(buffer, buffer_size+1, recv_size);
-
- m_selectedgame = std::string(buffer);
- Event->AppendText(wxString::Format(wxT("*Host changed Game to : %s\n"), buffer));
-
- // Tell the server if the game's been found
- m_socket.Send((const char*)&data, 1);
- CheckGameFound();
-
- Event->SendEvent(GUI_UPDATE);
-
- break;
- }
- case 0x40: // Ready message received
- {
- m_socket.Receive((char*)&buffer_size, 4, recv_size);
- buffer = new char[buffer_size+1];
- m_socket.Receive(buffer, buffer_size+1, recv_size);
-
- if (recv_size > 1024)
- {
- delete[] buffer;
- return;
- }
-
- Event->AppendText(wxString::FromAscii(buffer));
-
- break;
- }
- case 0x50: // Everyone is Ready message received
- {
- // Load the game and start synching
- m_netptr->LoadGame();
-
- break;
- }
- case 0xA1: // Received pad data from host in versus mode
- {
- if (m_data_received)
- wxThread::Sleep(10);
-
- m_socket.Receive((char*)m_netvalues[0], 8, recv_size);
- m_data_received = true;
-
-#ifdef NET_DEBUG
- char sent[64];
- sprintf(sent, "Received Values: 0x%08x : 0x%08x \n", m_netvalues[0][0], m_netvalues[0][1]);
- Event->AppendText(wxString::FromAscii(sent));
-#endif
- break;
- }
- }
-
- delete[] buffer;
-}
-
-void ServerSide::OnServerData(int sock, unsigned char data)
-{
- size_t recv_size;
- char *buffer = NULL;
- unsigned char sent;
- unsigned int four_bytes;
-
- switch (data)
- {
- case 0x15: // Ping Request
- {
- m_client[sock].socket.Receive((char*)&four_bytes, 4, recv_size);
- m_client[sock].socket.Send((const char*)&four_bytes, 4);
-
- break;
- }
- case 0x20: // IP request response
- {
- buffer = new char[24];
- // Read IP Address
- m_client[sock].socket.Receive(buffer, 24, recv_size);
-
- Event->AppendText(wxString::Format(wxT("> Your IP is : %s\n"), buffer));
-
- break;
- }
- case 0x30: // Chat message
- {
- buffer = new char[1024];
-
- m_client[sock].socket.Receive((char*)&four_bytes, 4, recv_size);
- m_client[sock].socket.Receive((char*)buffer, four_bytes + 1, recv_size);
-
- if (recv_size > 1024)
- {
- //something wrong...
- delete[] buffer;
- return;
- }
-
- sent = 0x30;
- // Send to all
- for (int i=0; i < m_numplayers ; i++)
- {
- if (i == sock)
- continue;
-
- m_client[i].socket.Send((const char*)&sent, 1);
-
- m_client[1].socket.Send((const char*)&four_bytes, 4);
- m_client[i].socket.Send(buffer, recv_size);
- }
-
- Event->AppendText(wxString::FromAscii(buffer));
-
- break;
- }
- case 0x35: // Change game response received
- {
- // Receive isGameFound response (0x1F / 0x1A)
- m_client[sock].socket.Receive((char*)&sent, 1, recv_size);
-
- // If game is not found
- if (sent != 0x1F)
- {
- sent = 0x30;
-
- wxString error_str = wxString::Format(
- wxT("WARNING : Player %s does Not have this Game !\n"), m_client[sock].nick.c_str());
- four_bytes = (int)error_str.size();
-
- for (int i=0; i < 2; i++)
- Event->AppendText(error_str);
-
- // Send to all
- for (int i=0; i < m_numplayers ; i++)
- {
- if (i == sock)
- continue;
- m_client[i].socket.Send((const char*)&sent, 1);
-
- m_client[i].socket.Send((const char*)&four_bytes, 4);
- m_client[i].socket.Send(error_str.mb_str(), four_bytes + 1);
- }
- }
-
- break;
- }
- case 0x40: // Ready message received
- {
- std::string buffer_str;
-
- m_client[sock].ready = !m_client[sock].ready;
-
- if (m_client[sock].ready)
- buffer_str = ">> "+m_client[sock].nick+" is now ready !\n";
- else
- buffer_str = ">> "+m_client[sock].nick+" is now Unready !\n";
-
- four_bytes = (int)buffer_str.size();
-
- // Send to all
- for (int i=0; i < m_numplayers ; i++)
- {
- m_client[i].socket.Send((const char*)&data, 1);
-
- m_client[i].socket.Send((const char*)&four_bytes, 4);
- m_client[i].socket.Send(buffer_str.c_str(), four_bytes+1);
- }
-
- Event->AppendText(wxString::FromAscii(buffer_str.c_str()));
- IsEveryoneReady();
-
- break;
- }
- case 0xA1: // Received pad data from a client
- {
- if (m_data_received)
- wxThread::Sleep(10);
-
- m_client[sock].socket.Receive((char*)m_netvalues[sock], 8, recv_size);
- m_data_received = true;
-
-#ifdef NET_DEBUG
- char sent[64];
- sprintf(sent, "Received Values: 0x%08x : 0x%08x \n", m_netvalues[sock][0], m_netvalues[sock][1]);
- Event->AppendText(wxString::FromAscii(sent));
-#endif
- break;
- }
- }
-
- delete[] buffer;
-}
-
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "NetWindow.h"
+
+void ClientSide::OnClientData(unsigned char data)
+{
+ unsigned char sent = 0;
+ u32 buffer_size;
+ size_t recv_size;
+ char *buffer = NULL;
+
+ switch (data)
+ {
+ case 0x10: // Player joined server
+ {
+ // Read GameFound
+ m_socket.Receive((char*)&sent, 1, recv_size);
+
+ // Read nickname
+ m_socket.Receive((char*)&buffer_size, 4, recv_size);
+ buffer = new char[buffer_size+1];
+ m_socket.Receive(buffer, buffer_size+1, recv_size);
+ Event->AppendText(wxString::Format(wxT("*Player : %s is now connected to Host...\n"), buffer));
+
+ if (sent != 0x1F)
+ for (int i = 0; i < 4; i++)
+ Event->AppendText(_("WARNING : Game Not Found on Client Side!\n"));
+
+ m_numplayers++;
+ Event->SendEvent(HOST_NEWPLAYER);
+ break;
+ }
+ case 0x11: // Player left server
+ {
+ // Read Nickname
+ m_socket.Receive((char*)&buffer_size, 4, recv_size);
+ buffer = new char[buffer_size+1];
+ m_socket.Receive(buffer, buffer_size+1, recv_size);
+
+ Event->AppendText(wxString::Format(wxT("*Player : %s left the game\n\n"), buffer));
+
+ m_numplayers--;
+ Event->SendEvent(HOST_PLAYERLEFT);
+ break;
+ }
+ case 0x15: // Ping Player
+ {
+ m_socket.Receive((char*)&buffer_size, 4, recv_size);
+ m_socket.Send((const char*)&buffer_size, 4);
+
+ break;
+ }
+ case 0x20: // IP request
+ {
+ //buffer_size = m_addr.size();
+ //m_socket.Send((const char*)&buffer_size, 4);
+ m_socket.Send((const char*)&data, 1);
+ m_socket.Send(m_addr.c_str(), m_addr.size() + 1);
+
+ break;
+ }
+ case 0x30: // Chat message received from server
+ {
+ m_socket.Receive((char*)&buffer_size, 4, recv_size);
+ buffer = new char[buffer_size+1];
+ m_socket.Receive(buffer, buffer_size+1, recv_size);
+
+ if (recv_size > 1024)
+ {
+ //something wrong...
+ delete[] buffer;
+ return;
+ }
+
+ Event->AppendText(wxString::FromAscii(buffer));
+
+ break;
+ }
+ case 0x35: // ChangeGame message received
+ {
+ m_socket.Receive((char*)&buffer_size, 4, recv_size);
+ buffer = new char[buffer_size+1];
+ m_socket.Receive(buffer, buffer_size+1, recv_size);
+
+ m_selectedgame = std::string(buffer);
+ Event->AppendText(wxString::Format(wxT("*Host changed Game to : %s\n"), buffer));
+
+ // Tell the server if the game's been found
+ m_socket.Send((const char*)&data, 1);
+ CheckGameFound();
+
+ Event->SendEvent(GUI_UPDATE);
+
+ break;
+ }
+ case 0x40: // Ready message received
+ {
+ m_socket.Receive((char*)&buffer_size, 4, recv_size);
+ buffer = new char[buffer_size+1];
+ m_socket.Receive(buffer, buffer_size+1, recv_size);
+
+ if (recv_size > 1024)
+ {
+ delete[] buffer;
+ return;
+ }
+
+ Event->AppendText(wxString::FromAscii(buffer));
+
+ break;
+ }
+ case 0x50: // Everyone is Ready message received
+ {
+ // Load the game and start synching
+ m_netptr->LoadGame();
+
+ break;
+ }
+ case 0xA1: // Received pad data from host in versus mode
+ {
+ if (m_data_received)
+ wxThread::Sleep(10);
+
+ m_socket.Receive((char*)m_netvalues[0], 8, recv_size);
+ m_data_received = true;
+
+#ifdef NET_DEBUG
+ char sent[64];
+ sprintf(sent, "Received Values: 0x%08x : 0x%08x \n", m_netvalues[0][0], m_netvalues[0][1]);
+ Event->AppendText(wxString::FromAscii(sent));
+#endif
+ break;
+ }
+ }
+
+ delete[] buffer;
+}
+
+void ServerSide::OnServerData(int sock, unsigned char data)
+{
+ size_t recv_size;
+ char *buffer = NULL;
+ unsigned char sent;
+ unsigned int four_bytes;
+
+ switch (data)
+ {
+ case 0x15: // Ping Request
+ {
+ m_client[sock].socket.Receive((char*)&four_bytes, 4, recv_size);
+ m_client[sock].socket.Send((const char*)&four_bytes, 4);
+
+ break;
+ }
+ case 0x20: // IP request response
+ {
+ buffer = new char[24];
+ // Read IP Address
+ m_client[sock].socket.Receive(buffer, 24, recv_size);
+
+ Event->AppendText(wxString::Format(wxT("> Your IP is : %s\n"), buffer));
+
+ break;
+ }
+ case 0x30: // Chat message
+ {
+ buffer = new char[1024];
+
+ m_client[sock].socket.Receive((char*)&four_bytes, 4, recv_size);
+ m_client[sock].socket.Receive((char*)buffer, four_bytes + 1, recv_size);
+
+ if (recv_size > 1024)
+ {
+ //something wrong...
+ delete[] buffer;
+ return;
+ }
+
+ sent = 0x30;
+ // Send to all
+ for (int i=0; i < m_numplayers ; i++)
+ {
+ if (i == sock)
+ continue;
+
+ m_client[i].socket.Send((const char*)&sent, 1);
+
+ m_client[1].socket.Send((const char*)&four_bytes, 4);
+ m_client[i].socket.Send(buffer, recv_size);
+ }
+
+ Event->AppendText(wxString::FromAscii(buffer));
+
+ break;
+ }
+ case 0x35: // Change game response received
+ {
+ // Receive isGameFound response (0x1F / 0x1A)
+ m_client[sock].socket.Receive((char*)&sent, 1, recv_size);
+
+ // If game is not found
+ if (sent != 0x1F)
+ {
+ sent = 0x30;
+
+ wxString error_str = wxString::Format(
+ wxT("WARNING : Player %s does Not have this Game !\n"), m_client[sock].nick.c_str());
+ four_bytes = (int)error_str.size();
+
+ for (int i=0; i < 2; i++)
+ Event->AppendText(error_str);
+
+ // Send to all
+ for (int i=0; i < m_numplayers ; i++)
+ {
+ if (i == sock)
+ continue;
+ m_client[i].socket.Send((const char*)&sent, 1);
+
+ m_client[i].socket.Send((const char*)&four_bytes, 4);
+ m_client[i].socket.Send(error_str.mb_str(), four_bytes + 1);
+ }
+ }
+
+ break;
+ }
+ case 0x40: // Ready message received
+ {
+ std::string buffer_str;
+
+ m_client[sock].ready = !m_client[sock].ready;
+
+ if (m_client[sock].ready)
+ buffer_str = ">> "+m_client[sock].nick+" is now ready !\n";
+ else
+ buffer_str = ">> "+m_client[sock].nick+" is now Unready !\n";
+
+ four_bytes = (int)buffer_str.size();
+
+ // Send to all
+ for (int i=0; i < m_numplayers ; i++)
+ {
+ m_client[i].socket.Send((const char*)&data, 1);
+
+ m_client[i].socket.Send((const char*)&four_bytes, 4);
+ m_client[i].socket.Send(buffer_str.c_str(), four_bytes+1);
+ }
+
+ Event->AppendText(wxString::FromAscii(buffer_str.c_str()));
+ IsEveryoneReady();
+
+ break;
+ }
+ case 0xA1: // Received pad data from a client
+ {
+ if (m_data_received)
+ wxThread::Sleep(10);
+
+ m_client[sock].socket.Receive((char*)m_netvalues[sock], 8, recv_size);
+ m_data_received = true;
+
+#ifdef NET_DEBUG
+ char sent[64];
+ sprintf(sent, "Received Values: 0x%08x : 0x%08x \n", m_netvalues[sock][0], m_netvalues[sock][1]);
+ Event->AppendText(wxString::FromAscii(sent));
+#endif
+ break;
+ }
+ }
+
+ delete[] buffer;
+}
+
diff --git a/Source/Core/DolphinWX/Src/NetFunctions.cpp b/Source/Core/DolphinWX/Src/NetFunctions.cpp
index fb34fa358f..5c544970b7 100644
--- a/Source/Core/DolphinWX/Src/NetFunctions.cpp
+++ b/Source/Core/DolphinWX/Src/NetFunctions.cpp
@@ -1,590 +1,590 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "NetWindow.h"
-#include "HW/SI_DeviceGCController.h"
-
-NetPlay *NetClass_ptr = NULL;
-
-void NetPlay::IsGameFound(unsigned char * ptr, std::string m_selected)
-{
- m_critical.Enter();
-
- m_selectedGame = m_selected;
-
- if (m_games.find(m_selected) != std::string::npos)
- *ptr = 0x1F;
- else
- *ptr = 0x1A;
-
- m_critical.Leave();
-}
-
-void NetPlay::OnNetEvent(wxCommandEvent& event)
-{
- switch (event.GetId())
- {
- case HOST_FULL:
- {
- AppendText(_(" Server is Full !\n*You have been Disconnected.\n\n"));
- m_isHosting = 2;
- }
- break;
- case HOST_ERROR:
- {
- if (m_isHosting == 0)
- {
- AppendText(_("ERROR : Network Error !\n*You have been Disconnected.\n\n"));
- m_isHosting = 2;
- }
- else
- {
- m_numClients--;
- AppendText( wxString::Format(wxT("ERROR : Network Error !\n"
- "*Player : %s has been dropped from the game.\n\n"),
- (const char *)event.GetString().mb_str()) );
- }
- }
- break;
- case HOST_DISCONNECTED:
- {
- // Event sent from Client's thread, it means that the thread
- // has been killed and so we tell the GUI thread.
- AppendText(_("*Connection to Host lost.\n*You have been Disconnected.\n\n"));
- m_isHosting = 2;
- m_numClients--;
- }
- break;
- case HOST_PLAYERLEFT:
- {
- m_numClients--;
- }
- break;
- case HOST_NEWPLAYER:
- {
- m_numClients++;
- m_NetModel = event.GetInt();
- }
- break;
- case CLIENTS_READY:
- {
- m_clients_ready = true;
-
- // Tell clients everyone is ready...
- if (m_ready)
- LoadGame();
- }
- break;
- case CLIENTS_NOTREADY:
- {
- m_clients_ready = false;
- }
- break;
- case GUI_UPDATE:
- UpdateNetWindow(false);
- break;
- case ADD_TEXT:
- AppendText(event.GetString());
- break;
- case ADD_INFO:
- UpdateNetWindow(true, event.GetString());
- break;
- }
-}
-
-void ServerSide::IsEveryoneReady()
-{
- int nb_ready = 0;
-
- for (int i=0; i < m_numplayers ; i++)
- if (m_client[i].ready)
- nb_ready++;
-
- if (nb_ready == m_numplayers)
- Event->SendEvent(CLIENTS_READY);
- else
- Event->SendEvent(CLIENTS_NOTREADY);
-}
-
-// Actual Core function which is called on every frame
-int CSIDevice_GCController::GetNetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus)
-{
- if (NetClass_ptr != NULL)
- return NetClass_ptr->GetNetPads(numPAD, PadStatus, PADStatus) ? 1 : 0;
- else
- return 2;
-}
-
-void NetPlay::LoadGame()
-{
- // Two implementations, one "p2p" implementation which sends to peer
- // and receive from peer 2 players max. and another which uses server model
- // and always sends to the server which then send it back to all the clients
- // -> P2P model is faster, but is limited to 2 players
- // -> Server model is slower, but supports up to 4 players
-
- if (m_isHosting == 1)
- {
- long ping[3] = {0};
- unsigned char value = 0x50;
-
- // Get ping
- m_sock_server->Write(0, 0, 0, ping);
- float fping = (ping[0]+ping[1]+ping[2])/(float)m_numClients;
-
- // Tell client everyone is ready
- for (int i=0; i < m_numClients ; i++)
- m_sock_server->Write(i, (const char*)&value, 1);
-
- // Sleep a bit to start the game at more or less the same time than the peer
- wxMilliSleep(fping/2);
-
- m_Logging->AppendText(wxString::Format(wxT("** Everyone is ready... Loading Game ! **\n"
- "** Ping to client(s) is : %f ms\n"), fping));
- }
- else
- m_Logging->AppendText(_("** Everyone is ready... Loading Game ! **\n"));
-
- // TODO : Throttle should be on by default, to avoid stuttering
- //soundStream->GetMixer()->SetThrottle(true);
-
- int line_p = 0;
- int line_n = 0;
-
- m_critical.Enter();
- std::string tmp = m_games.substr(0, m_games.find(m_selectedGame));
-
- for (int i=0; i < (int)tmp.size(); i++)
- if (tmp.c_str()[i] == '\n')
- line_n++;
-
- // Enable
- NetClass_ptr = this;
- m_timer.Start();
- m_data_received = false;
- m_critical.Leave();
-
- // Find corresponding game path
- for (int i=0; i < (int)m_paths.size(); i++)
- {
- if (m_paths.c_str()[i] == '\n')
- line_p++;
-
- if (line_n == line_p) {
- // Game path found, get its string
- int str_pos = line_p > 0 ? i+1 : i;
- int str_end = (int)m_paths.find('\n', str_pos);
- // Boot the selected game
- BootManager::BootCore(m_paths.substr(str_pos, str_end - str_pos));
- break;
- }
- }
-}
-
-bool NetPlay::GetNetPads(u8 padnb, SPADStatus PadStatus, u32 *netValues)
-{
- if (m_numClients < 1)
- {
- m_Logging->AppendText(_("** WARNING : "
- "Ping too high (>2000ms) or connection lost ! \n"
- "** WARNING : Stopping Netplay... \n"));
- NetClass_ptr = NULL;
- return false;
- }
-
- // Store current pad status in netValues[]
- netValues[0] = (u32)((u8)PadStatus.stickY);
- netValues[0] |= (u32)((u8)PadStatus.stickX << 8);
- netValues[0] |= (u32)((u16)PadStatus.button << 16);
- netValues[0] |= 0x00800000;
- netValues[1] = (u8)PadStatus.triggerRight;
- netValues[1] |= (u32)((u8)PadStatus.triggerLeft << 8);
- netValues[1] |= (u32)((u8)PadStatus.substickY << 16);
- netValues[1] |= (u32)((u8)PadStatus.substickX << 24);
-
- if (m_NetModel == 0) // Use 2 players Model
- {
- if (padnb == 0)
- {
- // Update the timer and increment total frame number
- m_frame++;
-
- if (m_frame == 1)
- {
- // We make sure everyone's pad is enabled
- for (int i = 0; i < m_numClients+1; i++)
- SerialInterface::ChangeDevice(SI_GC_CONTROLLER, i);
-
- // Better disable unused ports
- for (int i = m_numClients+1; i < 4; i++)
- SerialInterface::ChangeDevice(SI_DUMMY, i);
- }
-
- if (m_timer.GetTimeDifference() > 1000)
- m_timer.Update();
-
-#ifdef NET_DEBUG
- char sent[64];
- sprintf(sent, "Sent Values: 0x%08x : 0x%08x \n", netValues[0], netValues[1]);
- m_Logging->AppendText(wxString::FromAscii(sent));
-#endif
- unsigned char player = 0;
-
-#ifdef USE_TCP
- unsigned char init_value = 0xA1;
-
- if (m_isHosting == 1) {
- // Send pads values
- m_sock_server->Write(0, (const char*)&init_value, 1);
- m_sock_server->Write(0, (const char*)netValues, 8);
- }
- else {
- // Send pads values
- m_sock_client->Write((const char*)&init_value, 1);
- m_sock_client->Write((const char*)netValues, 8);
- player = 1;
- }
-#else // UDP
- u32 padsValues[3];
-
- padsValues[0] = m_frame;
- padsValues[1] = netValues[0];
- padsValues[2] = netValues[1];
-
- if (m_isHosting == 1) {
- // Send pads values
- m_sock_server->WriteUDP(0, (const char*)padsValues, 12);
- }
- else {
- // Send pads values
- m_sock_client->WriteUDP((const char*)padsValues, 12);
- player = 1;
- }
-#endif
-
- if (!m_data_received)
- {
- // Save pad values
- m_pads[player].nHi[m_loopframe] = netValues[0];
- m_pads[player].nLow[m_loopframe] = netValues[1];
-
- // Try to read from peer...
- if (m_isHosting == 1)
- m_data_received = m_sock_server->isNewPadData(0, false);
- else
- m_data_received = m_sock_client->isNewPadData(0, false);
-
- if (m_data_received)
- {
- // Set our practical frame delay
- m_frameDelay = m_loopframe;
- m_loopframe = 0;
-
- // First Data has been received !
- m_Logging->AppendText(_("** Data received from Peer. Starting Sync !"));
- m_Logging->AppendText(wxString::Format(wxT(" Frame Delay : %d **\n"), m_frameDelay));
- }
- else {
- if (m_loopframe > 126)
- {
- m_Logging->AppendText(_("** WARNING : "
- "Ping too high (>2000ms) or connection lost ! \n"
- "** WARNING : Stopping Netplay... \n"));
- NetClass_ptr = NULL;
- }
-
- m_loopframe++;
- return false;
- }
- }
-
- if (m_data_received)
- {
- // We have successfully received the data, now use it...
- // If we received data, we can update our pads on each frame, here's the behaviour :
- // we received our init number, so we should receive our pad values on each frames
- // with a frame delay of 'm_frameDelay' frames from the peer. So here, we just wait
- // for the pad status. note : if the peer can't keep up, sending the values
- // (i.e : framerate is too low) we have to wait for it thus slowing down emulation
-
- // Save current pad values, it will be used in 'm_frameDelay' frames :D
- int saveslot = (m_loopframe - 1 < 0 ? m_frameDelay : m_loopframe - 1);
- u32 recvedValues[2];
-
- m_pads[player].nHi[saveslot] = netValues[0];
- m_pads[player].nLow[saveslot] = netValues[1];
-
- // Read the socket for pad values
- if (m_isHosting == 1)
- m_sock_server->isNewPadData(recvedValues, true);
- else
- m_sock_client->isNewPadData(recvedValues, true);
-
- if (player == 0)
- {
- // Store received peer values
- m_pads[1].nHi[m_loopframe] = recvedValues[0];
- m_pads[1].nLow[m_loopframe] = recvedValues[1];
-
- // Apply synced pad values
- netValues[0] = m_pads[0].nHi[m_loopframe];
- netValues[1] = m_pads[0].nLow[m_loopframe];
- }
- else
- {
- // Apply received pad values
- netValues[0] = recvedValues[0];
- netValues[1] = recvedValues[1];
- }
- }
-
-#ifdef NET_DEBUG
- char usedval[64];
- sprintf(usedval, "Player 1 Values: 0x%08x : 0x%08x \n", netValues[0], netValues[1]);
- m_Logging->AppendText(wxString::FromAscii(usedval));
-#endif
- return true;
- }
- else if (padnb == 1)
- {
- if (m_data_received)
- {
- netValues[0] = m_pads[1].nHi[m_loopframe];
- netValues[1] = m_pads[1].nLow[m_loopframe];
-
- // Reset the loop to avoid reading unused values
- if (m_loopframe == m_frameDelay)
- m_loopframe = 0;
- else
- m_loopframe++;
- }
- else
- return false;
-#ifdef NET_DEBUG
- char usedval[64];
- sprintf(usedval, "Player 2 Values: 0x%08x : 0x%08x \n", netValues[0], netValues[1]);
- m_Logging->AppendText(wxString::FromAscii(usedval));
-#endif
-
- return true;
- }
- }
- else
- {
- // TODO : :D
- return false;
- }
-
- return false;
-}
-
-void NetPlay::ChangeSelectedGame(std::string game)
-{
- wxCriticalSectionLocker lock(m_critical);
- if (m_isHosting == 0)
- {
- m_selectedGame = game;
- return;
- }
-
- if (game != m_selectedGame)
- {
- unsigned char value = 0x35;
- int game_size = (int)game.size();
-
- // Send command then Game String
- for (int i=0; i < m_numClients ; i++)
- {
- m_sock_server->Write(i, (const char*)&value, 1); // 0x35 -> Change game
-
- m_sock_server->Write(i, (const char*)&game_size, 4);
- m_sock_server->Write(i, game.c_str(), game_size + 1);
- }
-
- m_selectedGame = game;
- UpdateNetWindow(false);
- m_Logging->AppendText(wxString::Format(wxT("*Game has been changed to : %s\n"), game.c_str()));
- }
-}
-
-void NetPlay::OnQuit(wxCloseEvent& WXUNUSED(event))
-{
- // Disable netplay
- NetClass_ptr = NULL;
-
- // Destroy the Window
- Destroy();
-
- // Then Kill the threads
- if (m_isHosting == 0)
- m_sock_client->Delete();
- else if (m_isHosting == 1) {
- m_sock_server->Delete();
- }
-
-}
-
-void NetPlay::OnDisconnect(wxCommandEvent& WXUNUSED(event))
-{
- wxCloseEvent close;
- OnQuit(close);
-}
-
-bool ClientSide::isNewPadData(u32 *netValues, bool current, bool isVersus)
-{
-#ifdef USE_TCP
- if (current)
- {
- while (1)
- {
- m_CriticalSection.Enter();
- if (m_data_received && isVersus)
- {
- netValues[0] = m_netvalues[0][0];
- netValues[1] = m_netvalues[0][1];
- m_data_received = false;
-
- m_CriticalSection.Leave();
- break;
- }
- m_CriticalSection.Leave();
-
- if (TestDestroy())
- break;
- }
-
- return true;
- }
- else
- wxCriticalSectionLocker lock(m_CriticalSection);
-
- return m_data_received;
-#else
- size_t recv_size;
-
- if (current)
- {
- m_CriticalSection.Enter();
-
- if (isVersus)
- {
- if (m_netvalues[0][1] != 0)
- {
- netValues[0] = m_netvalues[0][1];
- netValues[1] = m_netvalues[0][2];
- }
- else
- {
- while (true)
- {
- u32 frame_saved = m_netvalues[0][0];
- bool pass = RecvT(m_socketUDP, (char*)&m_netvalues[0], 12, recv_size, 5);
-
- if (m_netvalues[0][0] < frame_saved+1)
- continue;
- if (m_netvalues[0][0] > frame_saved+1 || !pass)
- PanicAlert("Network ERROR !");
-
- netValues[0] = m_netvalues[0][1];
- netValues[1] = m_netvalues[0][2];
- break;
- }
- }
- }
-
- m_netvalues[0][1] = 0;
- m_CriticalSection.Leave();
-
- return true;
- }
- else
- return RecvT(m_socketUDP, (char*)&m_netvalues[0], 12, recv_size, 1/1000);
-
-#endif
-
-}
-
-bool ServerSide::isNewPadData(u32 *netValues, bool current, int client)
-{
-#ifdef USE_TCP
- if (current)
- {
- while (1)
- {
- m_CriticalSection.Enter();
- if (m_data_received)
- {
- netValues[0] = m_netvalues[client][0];
- netValues[1] = m_netvalues[client][1];
- m_data_received = false;
-
- m_CriticalSection.Leave();
- break;
- }
- m_CriticalSection.Leave();
-
- if (TestDestroy())
- break;
- }
-
- return true;
- }
- else
- wxCriticalSectionLocker lock(m_CriticalSection);
-
- return m_data_received;
-#else
- size_t recv_size;
-
- if (current)
- {
- m_CriticalSection.Enter();
-
- if (m_netvalues[0][1] != 0)
- {
- netValues[0] = m_netvalues[client][1];
- netValues[1] = m_netvalues[client][2];
- }
- else
- {
- while (true)
- {
- u32 frame_saved = m_netvalues[client][0];
- bool pass = RecvT(m_socketUDP, (char*)&m_netvalues[client], 12, recv_size, 5);
-
- if (m_netvalues[client][0] < frame_saved+1)
- continue;
- if (m_netvalues[client][0] > frame_saved+1 || !pass)
- PanicAlert("Network ERROR !");
-
- netValues[0] = m_netvalues[client][1];
- netValues[1] = m_netvalues[client][2];
- break;
- }
- }
-
- m_netvalues[client][1] = 0;
- m_CriticalSection.Leave();
-
- return true;
- }
- else
- return RecvT(m_socketUDP, (char*)&m_netvalues[client], 12, recv_size, 1/1000);
-
-#endif
-}
-
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "NetWindow.h"
+#include "HW/SI_DeviceGCController.h"
+
+NetPlay *NetClass_ptr = NULL;
+
+void NetPlay::IsGameFound(unsigned char * ptr, std::string m_selected)
+{
+ m_critical.Enter();
+
+ m_selectedGame = m_selected;
+
+ if (m_games.find(m_selected) != std::string::npos)
+ *ptr = 0x1F;
+ else
+ *ptr = 0x1A;
+
+ m_critical.Leave();
+}
+
+void NetPlay::OnNetEvent(wxCommandEvent& event)
+{
+ switch (event.GetId())
+ {
+ case HOST_FULL:
+ {
+ AppendText(_(" Server is Full !\n*You have been Disconnected.\n\n"));
+ m_isHosting = 2;
+ }
+ break;
+ case HOST_ERROR:
+ {
+ if (m_isHosting == 0)
+ {
+ AppendText(_("ERROR : Network Error !\n*You have been Disconnected.\n\n"));
+ m_isHosting = 2;
+ }
+ else
+ {
+ m_numClients--;
+ AppendText( wxString::Format(wxT("ERROR : Network Error !\n"
+ "*Player : %s has been dropped from the game.\n\n"),
+ (const char *)event.GetString().mb_str()) );
+ }
+ }
+ break;
+ case HOST_DISCONNECTED:
+ {
+ // Event sent from Client's thread, it means that the thread
+ // has been killed and so we tell the GUI thread.
+ AppendText(_("*Connection to Host lost.\n*You have been Disconnected.\n\n"));
+ m_isHosting = 2;
+ m_numClients--;
+ }
+ break;
+ case HOST_PLAYERLEFT:
+ {
+ m_numClients--;
+ }
+ break;
+ case HOST_NEWPLAYER:
+ {
+ m_numClients++;
+ m_NetModel = event.GetInt();
+ }
+ break;
+ case CLIENTS_READY:
+ {
+ m_clients_ready = true;
+
+ // Tell clients everyone is ready...
+ if (m_ready)
+ LoadGame();
+ }
+ break;
+ case CLIENTS_NOTREADY:
+ {
+ m_clients_ready = false;
+ }
+ break;
+ case GUI_UPDATE:
+ UpdateNetWindow(false);
+ break;
+ case ADD_TEXT:
+ AppendText(event.GetString());
+ break;
+ case ADD_INFO:
+ UpdateNetWindow(true, event.GetString());
+ break;
+ }
+}
+
+void ServerSide::IsEveryoneReady()
+{
+ int nb_ready = 0;
+
+ for (int i=0; i < m_numplayers ; i++)
+ if (m_client[i].ready)
+ nb_ready++;
+
+ if (nb_ready == m_numplayers)
+ Event->SendEvent(CLIENTS_READY);
+ else
+ Event->SendEvent(CLIENTS_NOTREADY);
+}
+
+// Actual Core function which is called on every frame
+int CSIDevice_GCController::GetNetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus)
+{
+ if (NetClass_ptr != NULL)
+ return NetClass_ptr->GetNetPads(numPAD, PadStatus, PADStatus) ? 1 : 0;
+ else
+ return 2;
+}
+
+void NetPlay::LoadGame()
+{
+ // Two implementations, one "p2p" implementation which sends to peer
+ // and receive from peer 2 players max. and another which uses server model
+ // and always sends to the server which then send it back to all the clients
+ // -> P2P model is faster, but is limited to 2 players
+ // -> Server model is slower, but supports up to 4 players
+
+ if (m_isHosting == 1)
+ {
+ long ping[3] = {0};
+ unsigned char value = 0x50;
+
+ // Get ping
+ m_sock_server->Write(0, 0, 0, ping);
+ float fping = (ping[0]+ping[1]+ping[2])/(float)m_numClients;
+
+ // Tell client everyone is ready
+ for (int i=0; i < m_numClients ; i++)
+ m_sock_server->Write(i, (const char*)&value, 1);
+
+ // Sleep a bit to start the game at more or less the same time than the peer
+ wxMilliSleep(fping/2);
+
+ m_Logging->AppendText(wxString::Format(wxT("** Everyone is ready... Loading Game ! **\n"
+ "** Ping to client(s) is : %f ms\n"), fping));
+ }
+ else
+ m_Logging->AppendText(_("** Everyone is ready... Loading Game ! **\n"));
+
+ // TODO : Throttle should be on by default, to avoid stuttering
+ //soundStream->GetMixer()->SetThrottle(true);
+
+ int line_p = 0;
+ int line_n = 0;
+
+ m_critical.Enter();
+ std::string tmp = m_games.substr(0, m_games.find(m_selectedGame));
+
+ for (int i=0; i < (int)tmp.size(); i++)
+ if (tmp.c_str()[i] == '\n')
+ line_n++;
+
+ // Enable
+ NetClass_ptr = this;
+ m_timer.Start();
+ m_data_received = false;
+ m_critical.Leave();
+
+ // Find corresponding game path
+ for (int i=0; i < (int)m_paths.size(); i++)
+ {
+ if (m_paths.c_str()[i] == '\n')
+ line_p++;
+
+ if (line_n == line_p) {
+ // Game path found, get its string
+ int str_pos = line_p > 0 ? i+1 : i;
+ int str_end = (int)m_paths.find('\n', str_pos);
+ // Boot the selected game
+ BootManager::BootCore(m_paths.substr(str_pos, str_end - str_pos));
+ break;
+ }
+ }
+}
+
+bool NetPlay::GetNetPads(u8 padnb, SPADStatus PadStatus, u32 *netValues)
+{
+ if (m_numClients < 1)
+ {
+ m_Logging->AppendText(_("** WARNING : "
+ "Ping too high (>2000ms) or connection lost ! \n"
+ "** WARNING : Stopping Netplay... \n"));
+ NetClass_ptr = NULL;
+ return false;
+ }
+
+ // Store current pad status in netValues[]
+ netValues[0] = (u32)((u8)PadStatus.stickY);
+ netValues[0] |= (u32)((u8)PadStatus.stickX << 8);
+ netValues[0] |= (u32)((u16)PadStatus.button << 16);
+ netValues[0] |= 0x00800000;
+ netValues[1] = (u8)PadStatus.triggerRight;
+ netValues[1] |= (u32)((u8)PadStatus.triggerLeft << 8);
+ netValues[1] |= (u32)((u8)PadStatus.substickY << 16);
+ netValues[1] |= (u32)((u8)PadStatus.substickX << 24);
+
+ if (m_NetModel == 0) // Use 2 players Model
+ {
+ if (padnb == 0)
+ {
+ // Update the timer and increment total frame number
+ m_frame++;
+
+ if (m_frame == 1)
+ {
+ // We make sure everyone's pad is enabled
+ for (int i = 0; i < m_numClients+1; i++)
+ SerialInterface::ChangeDevice(SI_GC_CONTROLLER, i);
+
+ // Better disable unused ports
+ for (int i = m_numClients+1; i < 4; i++)
+ SerialInterface::ChangeDevice(SI_DUMMY, i);
+ }
+
+ if (m_timer.GetTimeDifference() > 1000)
+ m_timer.Update();
+
+#ifdef NET_DEBUG
+ char sent[64];
+ sprintf(sent, "Sent Values: 0x%08x : 0x%08x \n", netValues[0], netValues[1]);
+ m_Logging->AppendText(wxString::FromAscii(sent));
+#endif
+ unsigned char player = 0;
+
+#ifdef USE_TCP
+ unsigned char init_value = 0xA1;
+
+ if (m_isHosting == 1) {
+ // Send pads values
+ m_sock_server->Write(0, (const char*)&init_value, 1);
+ m_sock_server->Write(0, (const char*)netValues, 8);
+ }
+ else {
+ // Send pads values
+ m_sock_client->Write((const char*)&init_value, 1);
+ m_sock_client->Write((const char*)netValues, 8);
+ player = 1;
+ }
+#else // UDP
+ u32 padsValues[3];
+
+ padsValues[0] = m_frame;
+ padsValues[1] = netValues[0];
+ padsValues[2] = netValues[1];
+
+ if (m_isHosting == 1) {
+ // Send pads values
+ m_sock_server->WriteUDP(0, (const char*)padsValues, 12);
+ }
+ else {
+ // Send pads values
+ m_sock_client->WriteUDP((const char*)padsValues, 12);
+ player = 1;
+ }
+#endif
+
+ if (!m_data_received)
+ {
+ // Save pad values
+ m_pads[player].nHi[m_loopframe] = netValues[0];
+ m_pads[player].nLow[m_loopframe] = netValues[1];
+
+ // Try to read from peer...
+ if (m_isHosting == 1)
+ m_data_received = m_sock_server->isNewPadData(0, false);
+ else
+ m_data_received = m_sock_client->isNewPadData(0, false);
+
+ if (m_data_received)
+ {
+ // Set our practical frame delay
+ m_frameDelay = m_loopframe;
+ m_loopframe = 0;
+
+ // First Data has been received !
+ m_Logging->AppendText(_("** Data received from Peer. Starting Sync !"));
+ m_Logging->AppendText(wxString::Format(wxT(" Frame Delay : %d **\n"), m_frameDelay));
+ }
+ else {
+ if (m_loopframe > 126)
+ {
+ m_Logging->AppendText(_("** WARNING : "
+ "Ping too high (>2000ms) or connection lost ! \n"
+ "** WARNING : Stopping Netplay... \n"));
+ NetClass_ptr = NULL;
+ }
+
+ m_loopframe++;
+ return false;
+ }
+ }
+
+ if (m_data_received)
+ {
+ // We have successfully received the data, now use it...
+ // If we received data, we can update our pads on each frame, here's the behaviour :
+ // we received our init number, so we should receive our pad values on each frames
+ // with a frame delay of 'm_frameDelay' frames from the peer. So here, we just wait
+ // for the pad status. note : if the peer can't keep up, sending the values
+ // (i.e : framerate is too low) we have to wait for it thus slowing down emulation
+
+ // Save current pad values, it will be used in 'm_frameDelay' frames :D
+ int saveslot = (m_loopframe - 1 < 0 ? m_frameDelay : m_loopframe - 1);
+ u32 recvedValues[2];
+
+ m_pads[player].nHi[saveslot] = netValues[0];
+ m_pads[player].nLow[saveslot] = netValues[1];
+
+ // Read the socket for pad values
+ if (m_isHosting == 1)
+ m_sock_server->isNewPadData(recvedValues, true);
+ else
+ m_sock_client->isNewPadData(recvedValues, true);
+
+ if (player == 0)
+ {
+ // Store received peer values
+ m_pads[1].nHi[m_loopframe] = recvedValues[0];
+ m_pads[1].nLow[m_loopframe] = recvedValues[1];
+
+ // Apply synced pad values
+ netValues[0] = m_pads[0].nHi[m_loopframe];
+ netValues[1] = m_pads[0].nLow[m_loopframe];
+ }
+ else
+ {
+ // Apply received pad values
+ netValues[0] = recvedValues[0];
+ netValues[1] = recvedValues[1];
+ }
+ }
+
+#ifdef NET_DEBUG
+ char usedval[64];
+ sprintf(usedval, "Player 1 Values: 0x%08x : 0x%08x \n", netValues[0], netValues[1]);
+ m_Logging->AppendText(wxString::FromAscii(usedval));
+#endif
+ return true;
+ }
+ else if (padnb == 1)
+ {
+ if (m_data_received)
+ {
+ netValues[0] = m_pads[1].nHi[m_loopframe];
+ netValues[1] = m_pads[1].nLow[m_loopframe];
+
+ // Reset the loop to avoid reading unused values
+ if (m_loopframe == m_frameDelay)
+ m_loopframe = 0;
+ else
+ m_loopframe++;
+ }
+ else
+ return false;
+#ifdef NET_DEBUG
+ char usedval[64];
+ sprintf(usedval, "Player 2 Values: 0x%08x : 0x%08x \n", netValues[0], netValues[1]);
+ m_Logging->AppendText(wxString::FromAscii(usedval));
+#endif
+
+ return true;
+ }
+ }
+ else
+ {
+ // TODO : :D
+ return false;
+ }
+
+ return false;
+}
+
+void NetPlay::ChangeSelectedGame(std::string game)
+{
+ wxCriticalSectionLocker lock(m_critical);
+ if (m_isHosting == 0)
+ {
+ m_selectedGame = game;
+ return;
+ }
+
+ if (game != m_selectedGame)
+ {
+ unsigned char value = 0x35;
+ int game_size = (int)game.size();
+
+ // Send command then Game String
+ for (int i=0; i < m_numClients ; i++)
+ {
+ m_sock_server->Write(i, (const char*)&value, 1); // 0x35 -> Change game
+
+ m_sock_server->Write(i, (const char*)&game_size, 4);
+ m_sock_server->Write(i, game.c_str(), game_size + 1);
+ }
+
+ m_selectedGame = game;
+ UpdateNetWindow(false);
+ m_Logging->AppendText(wxString::Format(wxT("*Game has been changed to : %s\n"), game.c_str()));
+ }
+}
+
+void NetPlay::OnQuit(wxCloseEvent& WXUNUSED(event))
+{
+ // Disable netplay
+ NetClass_ptr = NULL;
+
+ // Destroy the Window
+ Destroy();
+
+ // Then Kill the threads
+ if (m_isHosting == 0)
+ m_sock_client->Delete();
+ else if (m_isHosting == 1) {
+ m_sock_server->Delete();
+ }
+
+}
+
+void NetPlay::OnDisconnect(wxCommandEvent& WXUNUSED(event))
+{
+ wxCloseEvent close;
+ OnQuit(close);
+}
+
+bool ClientSide::isNewPadData(u32 *netValues, bool current, bool isVersus)
+{
+#ifdef USE_TCP
+ if (current)
+ {
+ while (1)
+ {
+ m_CriticalSection.Enter();
+ if (m_data_received && isVersus)
+ {
+ netValues[0] = m_netvalues[0][0];
+ netValues[1] = m_netvalues[0][1];
+ m_data_received = false;
+
+ m_CriticalSection.Leave();
+ break;
+ }
+ m_CriticalSection.Leave();
+
+ if (TestDestroy())
+ break;
+ }
+
+ return true;
+ }
+ else
+ wxCriticalSectionLocker lock(m_CriticalSection);
+
+ return m_data_received;
+#else
+ size_t recv_size;
+
+ if (current)
+ {
+ m_CriticalSection.Enter();
+
+ if (isVersus)
+ {
+ if (m_netvalues[0][1] != 0)
+ {
+ netValues[0] = m_netvalues[0][1];
+ netValues[1] = m_netvalues[0][2];
+ }
+ else
+ {
+ while (true)
+ {
+ u32 frame_saved = m_netvalues[0][0];
+ bool pass = RecvT(m_socketUDP, (char*)&m_netvalues[0], 12, recv_size, 5);
+
+ if (m_netvalues[0][0] < frame_saved+1)
+ continue;
+ if (m_netvalues[0][0] > frame_saved+1 || !pass)
+ PanicAlert("Network ERROR !");
+
+ netValues[0] = m_netvalues[0][1];
+ netValues[1] = m_netvalues[0][2];
+ break;
+ }
+ }
+ }
+
+ m_netvalues[0][1] = 0;
+ m_CriticalSection.Leave();
+
+ return true;
+ }
+ else
+ return RecvT(m_socketUDP, (char*)&m_netvalues[0], 12, recv_size, 1/1000);
+
+#endif
+
+}
+
+bool ServerSide::isNewPadData(u32 *netValues, bool current, int client)
+{
+#ifdef USE_TCP
+ if (current)
+ {
+ while (1)
+ {
+ m_CriticalSection.Enter();
+ if (m_data_received)
+ {
+ netValues[0] = m_netvalues[client][0];
+ netValues[1] = m_netvalues[client][1];
+ m_data_received = false;
+
+ m_CriticalSection.Leave();
+ break;
+ }
+ m_CriticalSection.Leave();
+
+ if (TestDestroy())
+ break;
+ }
+
+ return true;
+ }
+ else
+ wxCriticalSectionLocker lock(m_CriticalSection);
+
+ return m_data_received;
+#else
+ size_t recv_size;
+
+ if (current)
+ {
+ m_CriticalSection.Enter();
+
+ if (m_netvalues[0][1] != 0)
+ {
+ netValues[0] = m_netvalues[client][1];
+ netValues[1] = m_netvalues[client][2];
+ }
+ else
+ {
+ while (true)
+ {
+ u32 frame_saved = m_netvalues[client][0];
+ bool pass = RecvT(m_socketUDP, (char*)&m_netvalues[client], 12, recv_size, 5);
+
+ if (m_netvalues[client][0] < frame_saved+1)
+ continue;
+ if (m_netvalues[client][0] > frame_saved+1 || !pass)
+ PanicAlert("Network ERROR !");
+
+ netValues[0] = m_netvalues[client][1];
+ netValues[1] = m_netvalues[client][2];
+ break;
+ }
+ }
+
+ m_netvalues[client][1] = 0;
+ m_CriticalSection.Leave();
+
+ return true;
+ }
+ else
+ return RecvT(m_socketUDP, (char*)&m_netvalues[client], 12, recv_size, 1/1000);
+
+#endif
+}
+
diff --git a/Source/Core/DolphinWX/Src/NetSockets.cpp b/Source/Core/DolphinWX/Src/NetSockets.cpp
index 4889eab66d..fe9d065d36 100644
--- a/Source/Core/DolphinWX/Src/NetSockets.cpp
+++ b/Source/Core/DolphinWX/Src/NetSockets.cpp
@@ -1,595 +1,595 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "NetWindow.h"
-
-//--------------------------------
-// GUI EVENTS
-//--------------------------------
-
-void NetEvent::AppendText(const wxString text)
-{
- // I have the feeling SendEvent may be a bit safer/better...
-#if 1
- SendEvent(ADD_TEXT, std::string(text.mb_str()));
-#else
- wxMutexGuiEnter();
- m_netptr->AppendText(text);
- wxMutexGuiLeave();
-#endif
-}
-
-void NetEvent::SendEvent(int EventType, const std::string text, int integer)
-{
- wxCommandEvent event(wxEVT_HOST_COMMAND, wxID_ANY);
-
- event.SetId( EventType );
- event.SetInt( integer );
- event.SetString( wxString::FromAscii(text.c_str()) );
-
- m_netptr->AddPendingEvent(event);
-}
-
-//--------------------------------
-// SERVER SIDE THREAD
-//--------------------------------
-
-ServerSide::ServerSide(NetPlay* netptr, sf::SocketTCP socket, sf::SocketUDP socketUDP, int netmodel, std::string nick)
- : wxThread()
-{
- m_numplayers = 0;
- m_data_received = false;
- m_netmodel = netmodel;
- m_socket = socket;
- m_socketUDP = socketUDP;
- m_netptr = netptr;
- m_nick = nick;
- Event = new NetEvent(m_netptr);
-}
-
-char ServerSide::GetSocket(sf::SocketTCP Socket)
-{
- for (int i=0; i < m_numplayers; i++)
- {
- if(m_client[i].socket == Socket)
- return i;
- }
-
- return 0xE;
-}
-
-bool ServerSide::RecvT(sf::SocketUDP Socket, char * Data, size_t Max, size_t& Recvd, float Time)
-{
- sf::SelectorUDP Selector;
- sf::IPAddress Addr;
- unsigned short Port;
- Selector.Add(Socket);
-
- if (Selector.Wait(Time) > 0)
- {
- Socket.Receive(Data, Max, Recvd, Addr, Port);
- return true;
- }
- else
- {
- return false;
- }
-}
-
-void *ServerSide::Entry()
-{
- // Add listening socket
- m_selector.Add(m_socket);
-
- while (1)
- {
- char nbSocketReady = m_selector.Wait(0.5);
-
- for (char i = 0; i < nbSocketReady; ++i)
- {
- m_CriticalSection.Enter();
-
- sf::SocketTCP Socket = m_selector.GetSocketReady(i);
-
- if (Socket == m_socket)
- {
- // Incoming connection
- Event->AppendText(_("*Connection Request... "));
-
- sf::SocketTCP Incoming;
- sf::IPAddress Address;
- m_socket.Accept(Incoming, &Address);
-
- unsigned char sent = 0x12;
- if ((m_netmodel == 0 && m_numplayers > 0) || m_numplayers == 3)
- {
- Incoming.Send((const char *)&sent, 1); // Tell it the server is full...
- Incoming.Close(); // Then close the connection
-
- Event->AppendText(_(" Server is Full !\n"));
- }
- else
- {
- Event->AppendText(_(" Connection accepted\n"));
- m_client[m_numplayers].socket = Incoming;
- m_client[m_numplayers].address = Address;
-
- if (SyncValues(m_numplayers, Address))
- {
- // Add it to the selector
- m_selector.Add(Incoming);
- Event->SendEvent(HOST_NEWPLAYER);
-
- m_numplayers++;
- }
- else
- {
- Event->AppendText(_("ERROR : Unable to establish UDP connection !\n"));
- Incoming.Close();
- }
- }
- }
- else
- {
- unsigned char recv;
- int socket_nb;
- size_t recv_size;
- sf::Socket::Status recv_status;
- socket_nb = GetSocket(Socket);
-
- if ((recv_status = Socket.Receive((char *)&recv, 1, recv_size)) == sf::Socket::Done)
- {
-#ifdef NET_DEBUG
- char recv_str[32];
- sprintf(recv_str, "received: 0x%02x | %c\n", recv, recv);
- Event->AppendText(wxString::FromAscii(recv_str));
-#endif
- OnServerData(socket_nb, recv);
- }
- else
- {
- if (recv_status == sf::Socket::Disconnected)
- {
- Event->SendEvent(HOST_PLAYERLEFT);
- m_numplayers--;
-
- std::string player_left = m_client[socket_nb].nick;
- Event->AppendText( wxString::Format(wxT("*Player : %s left the game.\n\n"),
- player_left.c_str()) );
-
- // We need to adjust the struct...
- for (int j = socket_nb; j < m_numplayers; j++)
- {
- m_client[j].socket = m_client[j+1].socket;
- m_client[j].nick = m_client[j+1].nick;
- m_client[j].ready = m_client[j+1].ready;
- }
-
- // Send disconnected message to all
- unsigned char send = 0x11;
- unsigned int str_size = (int)player_left.size();
-
- for (int j=0; j < m_numplayers ; j++)
- {
- m_client[j].socket.Send((const char*)&send, 1);
- m_client[j].socket.Send((const char*)&str_size, 4);
- m_client[j].socket.Send(player_left.c_str(), (int)str_size + 1);
- }
- }
- else
- {
- // Hopefully this should never happen, the client is not
- // Even warned that he is being dropped...
- Event->SendEvent(HOST_ERROR, m_client[socket_nb].nick);
- }
-
- m_selector.Remove(Socket);
- Socket.Close();
- }
- }
-
- m_CriticalSection.Leave();
- }
-
- if(TestDestroy())
- {
- // Stop listening
- m_socket.Close();
-
- // Delete the Thread and close clients sockets
- for (int i=0; i < m_numplayers ; i++)
- m_client[i].socket.Close();
-
- break;
- }
- }
-
- return NULL;
-}
-
-bool ServerSide::SyncValues(unsigned char socketnb, sf::IPAddress Address)
-{
- sf::SocketTCP Socket = m_client[socketnb].socket;
-
- std::string buffer_str = m_netptr->GetSelectedGame();
- char *buffer = NULL;
- unsigned char init_number;
- u32 buffer_size = (u32)buffer_str.size();
- size_t received;
- bool errorUDP = false;
-
- // First, Send the number of connected clients & netmodel
- Socket.Send((const char *)&m_numplayers, 1);
- Socket.Send((const char *)&m_netmodel, 4);
-
- // Send the Game String
- Socket.Send((const char *)&buffer_size, 4);
- Socket.Send(buffer_str.c_str(), buffer_size + 1);
-
- // Send the host Nickname
- buffer_size = (u32)m_nick.size();
- Socket.Send((const char *)&buffer_size, 4);
- Socket.Send(m_nick.c_str(), buffer_size + 1);
-
- // Read client's UDP Port
- Socket.Receive((char *)&m_client[m_numplayers].port, sizeof(short), received);
-
- // Read returned nickname
- Socket.Receive((char *)&buffer_size, 4, received);
- buffer = new char[buffer_size + 1];
- Socket.Receive(buffer, buffer_size + 1, received);
-
- m_client[socketnb].nick = std::string(buffer);
- m_client[socketnb].ready = false;
-
- ///////////////////
- // Test UDP Socket
- ///////////////////
- if (m_socketUDP.Send((const char*)&m_numplayers, 1, Address, m_client[m_numplayers].port) == sf::Socket::Done)
- {
- // Test UDP Socket Receive, 2s timeout
- if (!RecvT(m_socketUDP, (char*)&init_number, 1, received, 2))
- errorUDP = true;
- }
- else
- errorUDP = true;
-
- // Check if the client has the game
- Socket.Receive((char *)&init_number, 1, received);
-
- delete[] buffer;
-
- if (!errorUDP)
- {
- // Send to all connected clients
- if (m_numplayers > 0)
- {
- unsigned char send = 0x10;
- buffer_size = (int)m_client[socketnb].nick.size();
- for (int i=0; i < m_numplayers ; i++)
- {
- // Do not send to connecting player
- if (i == socketnb)
- continue;
-
- m_client[i].socket.Send((const char *)&send, 1); // Init new connection
- m_client[i].socket.Send((const char *)&init_number, 1); // Send Game found ?
- m_client[i].socket.Send((const char *)&buffer_size, 4); // Send client nickname
- m_client[i].socket.Send(m_client[socketnb].nick.c_str(), buffer_size + 1);
- }
- }
-
- Event->AppendText( wxString::Format(wxT("*Connection established to %s (%s:%d)\n"),
- m_client[socketnb].nick.c_str(), Address.ToString().c_str(), m_client[m_numplayers].port) );
-
- if (init_number != 0x1F) // Not Found
- for (int i = 0; i < 4; i++)
- Event->AppendText(_("WARNING : Game Not Found on Client Side !\n"));
-
- // UDP connecton successful
- init_number = 0x16;
- Socket.Send((const char *)&init_number, 1);
- }
- else // UDP Error, disconnect client
- {
- // UDP connecton failed
- init_number = 0x17;
- Socket.Send((const char *)&init_number, 1);
- return false;
- }
-
- return true;
-}
-
-void ServerSide::Write(int socknb, const char *data, size_t size, long *ping)
-{
- wxCriticalSectionLocker lock(m_CriticalSection);
-
- if (ping != NULL)
- {
- // Ask for ping
- unsigned char value = 0x15;
- size_t recv_size;
- u32 four_bytes = 0x101A7FA6;
-
- Common::Timer timer;
- timer.Start();
-
- for (int i=0; i < m_numplayers ; i++)
- {
- m_client[i].socket.Send((const char*)&value, 1);
-
- timer.Update();
- m_client[i].socket.Send((const char*)&four_bytes, 4);
- m_client[i].socket.Receive((char*)&four_bytes, 4, recv_size);
- ping[i] = (long)timer.GetTimeDifference();
- }
-
- return;
- }
-
- // Send the data safely, without intefering with another call
- m_client[socknb].socket.Send(data, size);
-}
-
-void ServerSide::WriteUDP(int socknb, const char *data, size_t size)
-{
- wxCriticalSectionLocker lock(m_CriticalSection);
-
- m_socketUDP.Send(data, size, m_client[socknb].address, m_client[socknb].port);
-}
-
-//--------------------------------
-// CLIENT SIDE THREAD
-//--------------------------------
-
-ClientSide::ClientSide(NetPlay* netptr, sf::SocketTCP socket, sf::SocketUDP socketUDP, std::string addr, std::string nick)
- : wxThread()
-{
- m_numplayers = 0;
- m_data_received = false;
- m_netmodel = 0;
- m_socket = socket;
- m_socketUDP = socketUDP;
- m_port = m_socketUDP.GetPort();
- m_netptr = netptr;
- m_nick = nick;
- m_addr = addr;
- Event = new NetEvent(m_netptr);
-}
-
-bool ClientSide::RecvT(sf::SocketUDP Socket, char * Data, size_t Max, size_t& Recvd, float Time)
-{
- sf::SelectorUDP Selector;
- sf::IPAddress Addr;
- unsigned short Port;
- Selector.Add(Socket);
-
- if (Selector.Wait(Time) > 0)
- {
- Socket.Receive(Data, Max, Recvd, Addr, Port);
- return true;
- }
- else
- {
- return false;
- }
-}
-
-void *ClientSide::Entry()
-{
- Event->AppendText(_("*Connection Request... "));
-
- // If we get here, the connection is already accepted, however the game may be full
- if (SyncValues())
- {
- // Tell the server if the client has the game
- CheckGameFound();
-
- // Check UDP connection
- unsigned char value;
- size_t val_sz;
- m_socket.Receive((char *)&value, 1, val_sz);
-
- if (value == 0x16) // UDP connection successful
- {
- Event->AppendText(_("Connection successful !\n"));
- Event->AppendText( wxString::Format(wxT("*Connection established to %s (%s)\n*Game is : %s\n"),
- m_hostnick.c_str(), m_addr.c_str(), m_selectedgame.c_str() ) );
- }
- else
- {
- Event->AppendText(_("UDP Connection FAILED !\n"
- "ERROR : Unable to establish UDP Connection, please Check UDP Port forwarding !"));
- m_socket.Close();
- Event->SendEvent(HOST_ERROR);
- return NULL;
- }
- }
- else // Server is Full
- {
- m_socket.Close();
- Event->SendEvent(HOST_FULL);
- return NULL;
- }
-
- m_netptr->ChangeSelectedGame(m_selectedgame);
- Event->SendEvent(HOST_NEWPLAYER, "NULL", m_netmodel);
- Event->SendEvent(GUI_UPDATE);
-
- m_selector.Add(m_socket);
-
- while (1)
- {
- unsigned char recv;
- size_t recv_size;
- sf::Socket::Status recv_status;
-
- // we use a selector because of the useful timeout
- if (m_selector.Wait(0.5) > 0)
- {
- m_CriticalSection.Enter();
-
- if ((recv_status = m_socket.Receive((char *)&recv, 1, recv_size)) == sf::Socket::Done)
- {
-#ifdef NET_DEBUG
- char recv_str[32];
- sprintf(recv_str, "received: 0x%02x | %c\n", recv, recv);
- Event->AppendText(wxString::FromAscii(recv_str));
-#endif
- OnClientData(recv);
- }
- else
- {
- if (recv_status == sf::Socket::Disconnected)
- {
- Event->SendEvent(HOST_DISCONNECTED);
- }
- else
- {
- Event->SendEvent(HOST_ERROR);
- }
-
- m_selector.Remove(m_socket);
- m_socket.Close();
-
- return NULL;
- }
-
- m_CriticalSection.Leave();
- }
-
- if(TestDestroy())
- {
- m_socket.Close();
-
- break;
- }
- }
-
- return NULL;
-}
-
-bool ClientSide::SyncValues()
-{
- unsigned int buffer_size = (int)m_nick.size();
- unsigned char byterecv;
- bool errorUDP;
- char *buffer = NULL;
- size_t recv_size;
-
- unsigned short server_port;
- std::string host = m_addr.substr(0, m_addr.find(':'));
- TryParseInt(m_addr.substr(m_addr.find(':')+1).c_str(), (int *)&server_port);
-
- // First, Read the init number : nbplayers (0-2) or server full (0x12)
- m_socket.Receive((char *)&m_numplayers, 1, recv_size);
- if (m_numplayers == 0x12)
- return false;
- m_socket.Receive((char *)&m_netmodel, 4, recv_size);
-
- // Send client's UDP Port
- m_socket.Send((const char *)&m_port, sizeof(short));
-
- // Send client's nickname
- m_socket.Send((const char *)&buffer_size, 4);
- m_socket.Send(m_nick.c_str(), buffer_size + 1);
-
- // Read the Game String
- m_socket.Receive((char *)&buffer_size, 4, recv_size);
- buffer = new char[buffer_size + 1];
- m_socket.Receive(buffer, buffer_size + 1, recv_size);
- m_selectedgame = std::string(buffer);
-
- // Read the host Nickname
- m_socket.Receive((char *)&buffer_size, 4, recv_size);
- buffer = new char[buffer_size + 1];
- m_socket.Receive(buffer, buffer_size + 1, recv_size);
- m_hostnick = std::string(buffer);
-
- ///////////////////
- // Test UDP Socket
- ///////////////////
- if (m_socketUDP.Send((const char*)&m_numplayers, 1, host.c_str(), server_port) == sf::Socket::Done)
- {
- // Test UDP Socket Receive, 2s timeout
- if (!RecvT(m_socketUDP, (char*)&byterecv, 1, recv_size, 2))
- errorUDP = true;
- }
- else
- errorUDP = true;
-
- delete[] buffer;
- return true;
-}
-
-void ClientSide::CheckGameFound()
-{
- unsigned char send_value;
-
- // Check if the game selected by Host is in Client's Game List
- m_netptr->IsGameFound(&send_value, m_selectedgame);
-
- if (send_value == 0x1F) // Found
- {
- m_socket.Send((const char *)&send_value, 1);
- }
- else
- {
- m_socket.Send((const char *)&send_value, 1);
-
- for (int i = 0; i < 2; i++)
- Event->AppendText(_("WARNING : You do not have the Selected Game !\n"));
- }
-}
-
-void ClientSide::Write(const char *data, size_t size, long *ping)
-{
- wxCriticalSectionLocker lock(m_CriticalSection);
-
- if (ping != NULL)
- {
- // Ask for ping
- unsigned char value = 0x15;
- size_t recv_size;
- int four_bytes = 0x101A7FA6;
-
- Common::Timer timer;
- timer.Start();
-
- m_socket.Send((const char*)&value, 1);
- m_socket.Send((const char*)&four_bytes, 4);
- m_socket.Receive((char*)&four_bytes, 4, recv_size);
-
- *ping = (long)timer.GetTimeElapsed();
-
- return;
- }
-
- m_socket.Send(data, size);
-}
-
-void ClientSide::WriteUDP(const char *data, size_t size)
-{
- wxCriticalSectionLocker lock(m_CriticalSection);
-
- unsigned short server_port;
- std::string host = m_addr.substr(0, m_addr.find(':'));
- TryParseInt(m_addr.substr(m_addr.find(':')+1).c_str(), (int *)&server_port);
-
- m_socketUDP.Send(data, size, host.c_str(), server_port);
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "NetWindow.h"
+
+//--------------------------------
+// GUI EVENTS
+//--------------------------------
+
+void NetEvent::AppendText(const wxString text)
+{
+ // I have the feeling SendEvent may be a bit safer/better...
+#if 1
+ SendEvent(ADD_TEXT, std::string(text.mb_str()));
+#else
+ wxMutexGuiEnter();
+ m_netptr->AppendText(text);
+ wxMutexGuiLeave();
+#endif
+}
+
+void NetEvent::SendEvent(int EventType, const std::string text, int integer)
+{
+ wxCommandEvent event(wxEVT_HOST_COMMAND, wxID_ANY);
+
+ event.SetId( EventType );
+ event.SetInt( integer );
+ event.SetString( wxString::FromAscii(text.c_str()) );
+
+ m_netptr->AddPendingEvent(event);
+}
+
+//--------------------------------
+// SERVER SIDE THREAD
+//--------------------------------
+
+ServerSide::ServerSide(NetPlay* netptr, sf::SocketTCP socket, sf::SocketUDP socketUDP, int netmodel, std::string nick)
+ : wxThread()
+{
+ m_numplayers = 0;
+ m_data_received = false;
+ m_netmodel = netmodel;
+ m_socket = socket;
+ m_socketUDP = socketUDP;
+ m_netptr = netptr;
+ m_nick = nick;
+ Event = new NetEvent(m_netptr);
+}
+
+char ServerSide::GetSocket(sf::SocketTCP Socket)
+{
+ for (int i=0; i < m_numplayers; i++)
+ {
+ if(m_client[i].socket == Socket)
+ return i;
+ }
+
+ return 0xE;
+}
+
+bool ServerSide::RecvT(sf::SocketUDP Socket, char * Data, size_t Max, size_t& Recvd, float Time)
+{
+ sf::SelectorUDP Selector;
+ sf::IPAddress Addr;
+ unsigned short Port;
+ Selector.Add(Socket);
+
+ if (Selector.Wait(Time) > 0)
+ {
+ Socket.Receive(Data, Max, Recvd, Addr, Port);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void *ServerSide::Entry()
+{
+ // Add listening socket
+ m_selector.Add(m_socket);
+
+ while (1)
+ {
+ char nbSocketReady = m_selector.Wait(0.5);
+
+ for (char i = 0; i < nbSocketReady; ++i)
+ {
+ m_CriticalSection.Enter();
+
+ sf::SocketTCP Socket = m_selector.GetSocketReady(i);
+
+ if (Socket == m_socket)
+ {
+ // Incoming connection
+ Event->AppendText(_("*Connection Request... "));
+
+ sf::SocketTCP Incoming;
+ sf::IPAddress Address;
+ m_socket.Accept(Incoming, &Address);
+
+ unsigned char sent = 0x12;
+ if ((m_netmodel == 0 && m_numplayers > 0) || m_numplayers == 3)
+ {
+ Incoming.Send((const char *)&sent, 1); // Tell it the server is full...
+ Incoming.Close(); // Then close the connection
+
+ Event->AppendText(_(" Server is Full !\n"));
+ }
+ else
+ {
+ Event->AppendText(_(" Connection accepted\n"));
+ m_client[m_numplayers].socket = Incoming;
+ m_client[m_numplayers].address = Address;
+
+ if (SyncValues(m_numplayers, Address))
+ {
+ // Add it to the selector
+ m_selector.Add(Incoming);
+ Event->SendEvent(HOST_NEWPLAYER);
+
+ m_numplayers++;
+ }
+ else
+ {
+ Event->AppendText(_("ERROR : Unable to establish UDP connection !\n"));
+ Incoming.Close();
+ }
+ }
+ }
+ else
+ {
+ unsigned char recv;
+ int socket_nb;
+ size_t recv_size;
+ sf::Socket::Status recv_status;
+ socket_nb = GetSocket(Socket);
+
+ if ((recv_status = Socket.Receive((char *)&recv, 1, recv_size)) == sf::Socket::Done)
+ {
+#ifdef NET_DEBUG
+ char recv_str[32];
+ sprintf(recv_str, "received: 0x%02x | %c\n", recv, recv);
+ Event->AppendText(wxString::FromAscii(recv_str));
+#endif
+ OnServerData(socket_nb, recv);
+ }
+ else
+ {
+ if (recv_status == sf::Socket::Disconnected)
+ {
+ Event->SendEvent(HOST_PLAYERLEFT);
+ m_numplayers--;
+
+ std::string player_left = m_client[socket_nb].nick;
+ Event->AppendText( wxString::Format(wxT("*Player : %s left the game.\n\n"),
+ player_left.c_str()) );
+
+ // We need to adjust the struct...
+ for (int j = socket_nb; j < m_numplayers; j++)
+ {
+ m_client[j].socket = m_client[j+1].socket;
+ m_client[j].nick = m_client[j+1].nick;
+ m_client[j].ready = m_client[j+1].ready;
+ }
+
+ // Send disconnected message to all
+ unsigned char send = 0x11;
+ unsigned int str_size = (int)player_left.size();
+
+ for (int j=0; j < m_numplayers ; j++)
+ {
+ m_client[j].socket.Send((const char*)&send, 1);
+ m_client[j].socket.Send((const char*)&str_size, 4);
+ m_client[j].socket.Send(player_left.c_str(), (int)str_size + 1);
+ }
+ }
+ else
+ {
+ // Hopefully this should never happen, the client is not
+ // Even warned that he is being dropped...
+ Event->SendEvent(HOST_ERROR, m_client[socket_nb].nick);
+ }
+
+ m_selector.Remove(Socket);
+ Socket.Close();
+ }
+ }
+
+ m_CriticalSection.Leave();
+ }
+
+ if(TestDestroy())
+ {
+ // Stop listening
+ m_socket.Close();
+
+ // Delete the Thread and close clients sockets
+ for (int i=0; i < m_numplayers ; i++)
+ m_client[i].socket.Close();
+
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+bool ServerSide::SyncValues(unsigned char socketnb, sf::IPAddress Address)
+{
+ sf::SocketTCP Socket = m_client[socketnb].socket;
+
+ std::string buffer_str = m_netptr->GetSelectedGame();
+ char *buffer = NULL;
+ unsigned char init_number;
+ u32 buffer_size = (u32)buffer_str.size();
+ size_t received;
+ bool errorUDP = false;
+
+ // First, Send the number of connected clients & netmodel
+ Socket.Send((const char *)&m_numplayers, 1);
+ Socket.Send((const char *)&m_netmodel, 4);
+
+ // Send the Game String
+ Socket.Send((const char *)&buffer_size, 4);
+ Socket.Send(buffer_str.c_str(), buffer_size + 1);
+
+ // Send the host Nickname
+ buffer_size = (u32)m_nick.size();
+ Socket.Send((const char *)&buffer_size, 4);
+ Socket.Send(m_nick.c_str(), buffer_size + 1);
+
+ // Read client's UDP Port
+ Socket.Receive((char *)&m_client[m_numplayers].port, sizeof(short), received);
+
+ // Read returned nickname
+ Socket.Receive((char *)&buffer_size, 4, received);
+ buffer = new char[buffer_size + 1];
+ Socket.Receive(buffer, buffer_size + 1, received);
+
+ m_client[socketnb].nick = std::string(buffer);
+ m_client[socketnb].ready = false;
+
+ ///////////////////
+ // Test UDP Socket
+ ///////////////////
+ if (m_socketUDP.Send((const char*)&m_numplayers, 1, Address, m_client[m_numplayers].port) == sf::Socket::Done)
+ {
+ // Test UDP Socket Receive, 2s timeout
+ if (!RecvT(m_socketUDP, (char*)&init_number, 1, received, 2))
+ errorUDP = true;
+ }
+ else
+ errorUDP = true;
+
+ // Check if the client has the game
+ Socket.Receive((char *)&init_number, 1, received);
+
+ delete[] buffer;
+
+ if (!errorUDP)
+ {
+ // Send to all connected clients
+ if (m_numplayers > 0)
+ {
+ unsigned char send = 0x10;
+ buffer_size = (int)m_client[socketnb].nick.size();
+ for (int i=0; i < m_numplayers ; i++)
+ {
+ // Do not send to connecting player
+ if (i == socketnb)
+ continue;
+
+ m_client[i].socket.Send((const char *)&send, 1); // Init new connection
+ m_client[i].socket.Send((const char *)&init_number, 1); // Send Game found ?
+ m_client[i].socket.Send((const char *)&buffer_size, 4); // Send client nickname
+ m_client[i].socket.Send(m_client[socketnb].nick.c_str(), buffer_size + 1);
+ }
+ }
+
+ Event->AppendText( wxString::Format(wxT("*Connection established to %s (%s:%d)\n"),
+ m_client[socketnb].nick.c_str(), Address.ToString().c_str(), m_client[m_numplayers].port) );
+
+ if (init_number != 0x1F) // Not Found
+ for (int i = 0; i < 4; i++)
+ Event->AppendText(_("WARNING : Game Not Found on Client Side !\n"));
+
+ // UDP connecton successful
+ init_number = 0x16;
+ Socket.Send((const char *)&init_number, 1);
+ }
+ else // UDP Error, disconnect client
+ {
+ // UDP connecton failed
+ init_number = 0x17;
+ Socket.Send((const char *)&init_number, 1);
+ return false;
+ }
+
+ return true;
+}
+
+void ServerSide::Write(int socknb, const char *data, size_t size, long *ping)
+{
+ wxCriticalSectionLocker lock(m_CriticalSection);
+
+ if (ping != NULL)
+ {
+ // Ask for ping
+ unsigned char value = 0x15;
+ size_t recv_size;
+ u32 four_bytes = 0x101A7FA6;
+
+ Common::Timer timer;
+ timer.Start();
+
+ for (int i=0; i < m_numplayers ; i++)
+ {
+ m_client[i].socket.Send((const char*)&value, 1);
+
+ timer.Update();
+ m_client[i].socket.Send((const char*)&four_bytes, 4);
+ m_client[i].socket.Receive((char*)&four_bytes, 4, recv_size);
+ ping[i] = (long)timer.GetTimeDifference();
+ }
+
+ return;
+ }
+
+ // Send the data safely, without intefering with another call
+ m_client[socknb].socket.Send(data, size);
+}
+
+void ServerSide::WriteUDP(int socknb, const char *data, size_t size)
+{
+ wxCriticalSectionLocker lock(m_CriticalSection);
+
+ m_socketUDP.Send(data, size, m_client[socknb].address, m_client[socknb].port);
+}
+
+//--------------------------------
+// CLIENT SIDE THREAD
+//--------------------------------
+
+ClientSide::ClientSide(NetPlay* netptr, sf::SocketTCP socket, sf::SocketUDP socketUDP, std::string addr, std::string nick)
+ : wxThread()
+{
+ m_numplayers = 0;
+ m_data_received = false;
+ m_netmodel = 0;
+ m_socket = socket;
+ m_socketUDP = socketUDP;
+ m_port = m_socketUDP.GetPort();
+ m_netptr = netptr;
+ m_nick = nick;
+ m_addr = addr;
+ Event = new NetEvent(m_netptr);
+}
+
+bool ClientSide::RecvT(sf::SocketUDP Socket, char * Data, size_t Max, size_t& Recvd, float Time)
+{
+ sf::SelectorUDP Selector;
+ sf::IPAddress Addr;
+ unsigned short Port;
+ Selector.Add(Socket);
+
+ if (Selector.Wait(Time) > 0)
+ {
+ Socket.Receive(Data, Max, Recvd, Addr, Port);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void *ClientSide::Entry()
+{
+ Event->AppendText(_("*Connection Request... "));
+
+ // If we get here, the connection is already accepted, however the game may be full
+ if (SyncValues())
+ {
+ // Tell the server if the client has the game
+ CheckGameFound();
+
+ // Check UDP connection
+ unsigned char value;
+ size_t val_sz;
+ m_socket.Receive((char *)&value, 1, val_sz);
+
+ if (value == 0x16) // UDP connection successful
+ {
+ Event->AppendText(_("Connection successful !\n"));
+ Event->AppendText( wxString::Format(wxT("*Connection established to %s (%s)\n*Game is : %s\n"),
+ m_hostnick.c_str(), m_addr.c_str(), m_selectedgame.c_str() ) );
+ }
+ else
+ {
+ Event->AppendText(_("UDP Connection FAILED !\n"
+ "ERROR : Unable to establish UDP Connection, please Check UDP Port forwarding !"));
+ m_socket.Close();
+ Event->SendEvent(HOST_ERROR);
+ return NULL;
+ }
+ }
+ else // Server is Full
+ {
+ m_socket.Close();
+ Event->SendEvent(HOST_FULL);
+ return NULL;
+ }
+
+ m_netptr->ChangeSelectedGame(m_selectedgame);
+ Event->SendEvent(HOST_NEWPLAYER, "NULL", m_netmodel);
+ Event->SendEvent(GUI_UPDATE);
+
+ m_selector.Add(m_socket);
+
+ while (1)
+ {
+ unsigned char recv;
+ size_t recv_size;
+ sf::Socket::Status recv_status;
+
+ // we use a selector because of the useful timeout
+ if (m_selector.Wait(0.5) > 0)
+ {
+ m_CriticalSection.Enter();
+
+ if ((recv_status = m_socket.Receive((char *)&recv, 1, recv_size)) == sf::Socket::Done)
+ {
+#ifdef NET_DEBUG
+ char recv_str[32];
+ sprintf(recv_str, "received: 0x%02x | %c\n", recv, recv);
+ Event->AppendText(wxString::FromAscii(recv_str));
+#endif
+ OnClientData(recv);
+ }
+ else
+ {
+ if (recv_status == sf::Socket::Disconnected)
+ {
+ Event->SendEvent(HOST_DISCONNECTED);
+ }
+ else
+ {
+ Event->SendEvent(HOST_ERROR);
+ }
+
+ m_selector.Remove(m_socket);
+ m_socket.Close();
+
+ return NULL;
+ }
+
+ m_CriticalSection.Leave();
+ }
+
+ if(TestDestroy())
+ {
+ m_socket.Close();
+
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+bool ClientSide::SyncValues()
+{
+ unsigned int buffer_size = (int)m_nick.size();
+ unsigned char byterecv;
+ bool errorUDP;
+ char *buffer = NULL;
+ size_t recv_size;
+
+ unsigned short server_port;
+ std::string host = m_addr.substr(0, m_addr.find(':'));
+ TryParseInt(m_addr.substr(m_addr.find(':')+1).c_str(), (int *)&server_port);
+
+ // First, Read the init number : nbplayers (0-2) or server full (0x12)
+ m_socket.Receive((char *)&m_numplayers, 1, recv_size);
+ if (m_numplayers == 0x12)
+ return false;
+ m_socket.Receive((char *)&m_netmodel, 4, recv_size);
+
+ // Send client's UDP Port
+ m_socket.Send((const char *)&m_port, sizeof(short));
+
+ // Send client's nickname
+ m_socket.Send((const char *)&buffer_size, 4);
+ m_socket.Send(m_nick.c_str(), buffer_size + 1);
+
+ // Read the Game String
+ m_socket.Receive((char *)&buffer_size, 4, recv_size);
+ buffer = new char[buffer_size + 1];
+ m_socket.Receive(buffer, buffer_size + 1, recv_size);
+ m_selectedgame = std::string(buffer);
+
+ // Read the host Nickname
+ m_socket.Receive((char *)&buffer_size, 4, recv_size);
+ buffer = new char[buffer_size + 1];
+ m_socket.Receive(buffer, buffer_size + 1, recv_size);
+ m_hostnick = std::string(buffer);
+
+ ///////////////////
+ // Test UDP Socket
+ ///////////////////
+ if (m_socketUDP.Send((const char*)&m_numplayers, 1, host.c_str(), server_port) == sf::Socket::Done)
+ {
+ // Test UDP Socket Receive, 2s timeout
+ if (!RecvT(m_socketUDP, (char*)&byterecv, 1, recv_size, 2))
+ errorUDP = true;
+ }
+ else
+ errorUDP = true;
+
+ delete[] buffer;
+ return true;
+}
+
+void ClientSide::CheckGameFound()
+{
+ unsigned char send_value;
+
+ // Check if the game selected by Host is in Client's Game List
+ m_netptr->IsGameFound(&send_value, m_selectedgame);
+
+ if (send_value == 0x1F) // Found
+ {
+ m_socket.Send((const char *)&send_value, 1);
+ }
+ else
+ {
+ m_socket.Send((const char *)&send_value, 1);
+
+ for (int i = 0; i < 2; i++)
+ Event->AppendText(_("WARNING : You do not have the Selected Game !\n"));
+ }
+}
+
+void ClientSide::Write(const char *data, size_t size, long *ping)
+{
+ wxCriticalSectionLocker lock(m_CriticalSection);
+
+ if (ping != NULL)
+ {
+ // Ask for ping
+ unsigned char value = 0x15;
+ size_t recv_size;
+ int four_bytes = 0x101A7FA6;
+
+ Common::Timer timer;
+ timer.Start();
+
+ m_socket.Send((const char*)&value, 1);
+ m_socket.Send((const char*)&four_bytes, 4);
+ m_socket.Receive((char*)&four_bytes, 4, recv_size);
+
+ *ping = (long)timer.GetTimeElapsed();
+
+ return;
+ }
+
+ m_socket.Send(data, size);
+}
+
+void ClientSide::WriteUDP(const char *data, size_t size)
+{
+ wxCriticalSectionLocker lock(m_CriticalSection);
+
+ unsigned short server_port;
+ std::string host = m_addr.substr(0, m_addr.find(':'));
+ TryParseInt(m_addr.substr(m_addr.find(':')+1).c_str(), (int *)&server_port);
+
+ m_socketUDP.Send(data, size, host.c_str(), server_port);
+}
diff --git a/Source/Core/DolphinWX/Src/NetWindow.cpp b/Source/Core/DolphinWX/Src/NetWindow.cpp
index 455a6aef8d..01e5436da8 100644
--- a/Source/Core/DolphinWX/Src/NetWindow.cpp
+++ b/Source/Core/DolphinWX/Src/NetWindow.cpp
@@ -1,555 +1,555 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "NetWindow.h"
-
-///////////////////////
-// Main Frame window
-
-BEGIN_EVENT_TABLE(NetPlay, wxFrame)
- EVT_BUTTON(ID_BUTTON_JOIN, NetPlay::OnJoin)
- EVT_BUTTON(ID_BUTTON_HOST, NetPlay::OnHost)
-
- EVT_HOST_COMMAND(wxID_ANY, NetPlay::OnNetEvent)
-
- EVT_CHECKBOX(ID_READY, NetPlay::OnGUIEvent)
- EVT_CHECKBOX(ID_RECORD, NetPlay::OnGUIEvent)
- EVT_BUTTON(ID_CHANGEGAME, NetPlay::OnGUIEvent)
- EVT_BUTTON(ID_BUTTON_GETIP, NetPlay::OnGUIEvent)
- EVT_BUTTON(ID_BUTTON_GETPING, NetPlay::OnGUIEvent)
- EVT_BUTTON(ID_BUTTON_CHAT, NetPlay::OnGUIEvent)
- EVT_TEXT_ENTER(ID_CHAT, NetPlay::OnGUIEvent)
- EVT_BUTTON(ID_BUTTON_QUIT, NetPlay::OnDisconnect)
- EVT_CLOSE(NetPlay::OnQuit)
-END_EVENT_TABLE()
-
-NetPlay::NetPlay(wxWindow* parent, std::string GamePaths, std::string GameNames) :
- wxFrame(parent, wxID_ANY, _T("Net Play"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE & ~ wxMAXIMIZE_BOX)
-{
- m_selectedGame = 'a'; m_hostaddr = 'a';
- m_games = GameNames; m_paths = GamePaths;
- m_isHosting = 2; m_ready = m_clients_ready = false;
- m_loopframe = m_frame = m_NetModel = m_numClients = 0;
-
- DrawGUI();
-}
-
-NetPlay::~NetPlay()
-{
- ConfigIni.Load(CONFIG_FILE);
-
- ConfigIni.Set("Netplay", "Nickname", m_nick);
- ConfigIni.Set("Netplay", "UsedPort", (int)m_port);
- ConfigIni.Set("Netplay", "LastIP", m_address);
-
- ConfigIni.Save(CONFIG_FILE);
-}
-
-void NetPlay::OnJoin(wxCommandEvent& WXUNUSED(event))
-{
- unsigned short server_port;
-
- m_address = std::string(m_ConAddr->GetValue().mb_str());
- m_nick = std::string(m_SetNick->GetValue().mb_str());
-
- sf::IPAddress host = m_address.substr(0, m_address.find(':'));
- std::string port_str = m_address.substr(m_address.find(':') + 1);
-
- TryParseUInt(port_str, (u32*)&server_port); // Server port
- TryParseUInt((const char *)m_SetPort->GetValue().mb_str(), (u32*)&m_port); // User port
-
- if (m_nick.size() > 255)
- m_nick = m_nick.substr(0 , 255);
-
- SetTitle(wxT("Net Play : Connecting to Host..."));
-
- // Create the client socket
- sf::SocketTCP sock_client;
- sf::SocketUDP sock_client_UDP;
-
- if (sock_client.Connect(server_port, host, 1.5) == sf::Socket::Done)
- {
- // Try to Bind the UDP Socket
- if (sock_client_UDP.Bind(m_port))
- {
- m_sock_client = new ClientSide(this, sock_client, sock_client_UDP, m_address, m_nick);
- m_sock_client->Create();
- m_sock_client->Run();
-
- // Create the GUI
- m_isHosting = false;
- DrawNetWindow();
- }
- else
- {
- SetTitle(wxT("Net Play"));
- PanicAlert("Can't Bind UDP socket on the specified Port: %d ! \n"
- "Make sure port is forwarded and not in use !", m_port);
- }
- }
- else
- {
- SetTitle(wxT("Net Play"));
- PanicAlert("Can't connect to the specified IP Address ! \nMake sure Hosting port is forwarded !");
- }
-}
-
-void NetPlay::OnHost(wxCommandEvent& WXUNUSED(event))
-{
- TryParseInt(m_SetPort->GetValue().mb_str(), (int*)&m_port);
-
- m_nick = std::string(m_SetNick->GetValue().mb_str());
-
- if (m_GameList->GetSelection() == wxNOT_FOUND) {
- PanicAlert("No Game Selected ! Please select a Game...");
- return;
- }
- if (!m_SetPort->GetValue().size() || m_port < 1000 || m_port > 65535) {
- PanicAlert("Bad Port entered (%d) ! Please enter a working socket port...", m_port);
- return;
- }
- if (m_nick.size() > 255)
- m_nick = m_nick.substr(0 , 255);
-
- m_NetModel = m_NetMode->GetSelection();
- m_selectedGame = std::string(m_GameList_str[m_GameList->GetSelection()].mb_str());
-
- // Create the listening socket
- sf::SocketTCP sock_server;
- sf::SocketUDP sock_server_UDP;
-
- // Start the listening socket and bind UDP socket port
- if (sock_server.Listen(m_port) && sock_server_UDP.Bind(m_port))
- {
- m_sock_server = new ServerSide(this, sock_server, sock_server_UDP, m_NetModel, m_nick);
- m_sock_server->Create();
- m_sock_server->Run();
-
- // Create the GUI
- m_isHosting = true;
- DrawNetWindow();
- m_Logging->AppendText(wxString::Format(wxT("WARNING : Hosting requires port to be forwarded in firewall!\n"
- "*Creation Successful on port %d : Waiting for peers...\n"), m_port));
- }
- else
- {
- PanicAlert("Could not listen at specified port !\nMake sure hosting port is not in use !");
- return;
- }
-}
-
-void NetPlay::DrawGUI()
-{
- int str_end = -1;
- int str_start = -1;
- wxArrayString netmodes_str;
-
- for(int i = 0; i < (int)m_games.size(); i++)
- {
- str_start = str_end + 1;
- str_end = (int)m_games.find('\n', str_start);
- std::string buffer = m_games.substr(str_start, str_end - str_start);
-
- if (str_end == (int)std::string::npos || buffer.size() < 1)
- break; // we reached the end of the string
-
- m_GameList_str.Add(wxString::FromAscii(buffer.c_str()));
- }
-
- netmodes_str.Add(wxT("P2P Versus (2 players, faster)"));
- // TODO : netmodes_str.Add(wxT("Server Mode (4 players, slower)"));
-
- wxPanel *panel = new wxPanel(this);
-
- // Tabs
- m_Notebook = new wxNotebook(panel, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize);
- m_Tab_Connect = new wxPanel(m_Notebook, ID_TAB_CONN, wxDefaultPosition, wxDefaultSize);
- m_Notebook->AddPage(m_Tab_Connect, wxT("Connect"));
- m_Tab_Host = new wxPanel(m_Notebook, ID_TAB_HOST, wxDefaultPosition, wxDefaultSize);
- m_Notebook->AddPage(m_Tab_Host, wxT("Host"));
-
- // Tow window, Nickname & Port settings
- m_SetNick_text = new wxStaticText(panel, wxID_ANY, wxT(" Nickname : "), wxDefaultPosition, wxDefaultSize);
- m_SetNick = new wxTextCtrl(panel, ID_SETNICK, wxT("LOLWUT!"), wxDefaultPosition, wxDefaultSize);
- m_SetPort_text = new wxStaticText(panel, wxID_ANY, wxT(" Port to Use : "), wxDefaultPosition, wxDefaultSize);
- m_SetPort = new wxTextCtrl(panel, ID_SETPORT, wxT("12345"), wxDefaultPosition, wxDefaultSize);
-
- // CONNECTION TAB
- m_ConAddr_text = new wxStaticText(m_Tab_Connect, wxID_ANY, wxT(" IP Address :"), wxDefaultPosition, wxDefaultSize);
- m_ConAddr = new wxTextCtrl(m_Tab_Connect, ID_CONNADDR, wxT("127.0.0.1:12345"), wxDefaultPosition, wxSize(250,20), 0);
- m_UseRandomPort = new wxCheckBox(m_Tab_Connect, ID_USE_RANDOMPORT, wxT("Use random client port for connection"));
- m_JoinGame = new wxButton(m_Tab_Connect, ID_BUTTON_JOIN, wxT("Connect"), wxDefaultPosition, wxDefaultSize);
-
- // Sizers CONNECT
- wxBoxSizer* sConnectTop = new wxBoxSizer(wxHORIZONTAL);
- wxBoxSizer* sConnectSizer = new wxBoxSizer(wxVERTICAL);
-
- sConnectTop->Add(m_ConAddr_text, 0, wxALL|wxALIGN_CENTER, 5);
- sConnectTop->Add(m_ConAddr, 1, wxALL|wxEXPAND, 5);
- sConnectTop->Add(m_JoinGame, 0, wxALL|wxALIGN_RIGHT, 5);
- sConnectSizer->Add(sConnectTop, 0, wxALL|wxEXPAND, 5);
- sConnectSizer->Add(m_UseRandomPort, 0, wxALL|wxALIGN_CENTER, 5);
-
- m_Tab_Connect->SetSizer(sConnectSizer);
-
- // HOSTING TAB
- m_GameList_text = new wxStaticText(m_Tab_Host, wxID_ANY,
- wxT("Warning: Use a forwarded port ! Select Game and press Host :"), wxDefaultPosition, wxDefaultSize);
- m_GameList = new wxListBox(m_Tab_Host, ID_GAMELIST, wxDefaultPosition, wxDefaultSize,
- m_GameList_str, wxLB_SINGLE | wxLB_NEEDED_SB);
- m_HostGame = new wxButton(m_Tab_Host, ID_BUTTON_HOST, wxT("Host"), wxDefaultPosition, wxDefaultSize);
- m_NetMode = new wxChoice(m_Tab_Host, ID_NETMODE, wxDefaultPosition, wxDefaultSize, netmodes_str, 0, wxDefaultValidator);
- m_NetMode->SetSelection(0);
-
- // Sizers HOST
- wxBoxSizer *sHostBox = new wxBoxSizer(wxVERTICAL);
- wxBoxSizer *sHostBottom = new wxBoxSizer(wxHORIZONTAL);
-
- sHostBottom->Add(m_NetMode, 0, wxALL|wxALIGN_CENTER, 5);
- sHostBottom->AddStretchSpacer();
- sHostBottom->Add(m_HostGame, 0, wxALL, 10);
-
- sHostBox->Add(m_GameList_text, 0, wxALL|wxALIGN_CENTER, 5);
- sHostBox->Add(m_GameList, 1, wxALL|wxEXPAND, 6);
- sHostBox->Add(sHostBottom, 0, wxALL|wxEXPAND, 1);
-
- m_Tab_Host->SetSizer(sHostBox);
-
- // Main sizers
- wxBoxSizer* sMain = new wxBoxSizer(wxVERTICAL);
- wxBoxSizer* sMain_top = new wxBoxSizer(wxHORIZONTAL);
-
- sMain_top->Add(m_SetNick_text, 0, wxALL|wxALIGN_CENTER, 3);
- sMain_top->Add(m_SetNick, 1, wxALL|wxALIGN_CENTER, 3);
- sMain_top->AddStretchSpacer();
- sMain_top->Add(m_SetPort_text, 0, wxALL|wxALIGN_CENTER, 3);
- sMain_top->Add(m_SetPort, 1, wxALL|wxALIGN_CENTER, 3);
-
- sMain->Add(sMain_top, 0, wxALL|wxEXPAND, 5);
- sMain->Add(m_Notebook, 1, wxALL|wxEXPAND, 5);
-
- // Adjust panel to window's size, and set resizing minimum boundaries
- panel->SetSizerAndFit(sMain);
- sMain->SetSizeHints((wxWindow*)this);
-
- if (ConfigIni.Load(CONFIG_FILE))
- {
- ConfigIni.Get("Netplay", "Nickname", &m_nick, "Unnamed");
- ConfigIni.Get("Netplay", "UsedPort", (int*)&m_port, 12345);
- ConfigIni.Get("Netplay", "LastIP", &m_address, "127.0.0.1:54321");
-
- m_SetNick->SetValue(wxString::FromAscii(m_nick.c_str()));
- m_SetPort->SetValue(wxString::Format(wxT("%d"), m_port));
- m_ConAddr->SetValue(wxString::FromAscii(m_address.c_str()));
- }
-
- Center(); Show();
-}
-
-void NetPlay::DrawNetWindow()
-{
- // Remove everything from the precedent GUI :D
- DestroyChildren();
-
- SetTitle(wxT("Net Play : Connection Window"));
-
- wxPanel *panel = new wxPanel(this);
- wxBoxSizer* sMain = new wxBoxSizer(wxVERTICAL);
- wxBoxSizer* sTop = new wxBoxSizer(wxVERTICAL);
- wxBoxSizer* sBottom = new wxBoxSizer(wxHORIZONTAL);
-
- m_Game_str = new wxButton(panel, wxID_ANY, wxT(" Game : "), wxDefaultPosition, wxSize(400, 25), wxBU_LEFT);
- m_Game_str->Disable();
-
- m_Logging = new wxTextCtrl(panel, ID_LOGGING_TXT, wxEmptyString,
- wxDefaultPosition, wxSize(400, 250),
- wxTE_RICH2 | wxTE_MULTILINE | wxTE_READONLY);
-
- m_Chat = new wxTextCtrl(panel, ID_CHAT, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
- m_Chat_ok = new wxButton(panel, ID_BUTTON_CHAT, wxT("Send"));;
-
- m_Ready = new wxCheckBox(panel, ID_READY, wxT("Click here when ready"), wxDefaultPosition, wxDefaultSize, 0);
- m_RecordGame = new wxCheckBox(panel, ID_RECORD, wxT("Record Game Input"), wxDefaultPosition, wxDefaultSize, 0);
- // TODO: Fix the recording ?
- m_RecordGame->Disable();
-
- m_ConInfo_text = new wxStaticText(panel, ID_CONNINFO_TXT, wxT(" Fps : 0 | Ping : 00 ms"));
- m_GetPing = new wxButton(panel, ID_BUTTON_GETPING, wxT("Ping"), wxDefaultPosition, wxDefaultSize);
- m_Disconnect = new wxButton(panel, ID_BUTTON_QUIT, wxT("Disconnect"), wxDefaultPosition, wxDefaultSize);
-
- wxBoxSizer* sChat = new wxBoxSizer(wxHORIZONTAL);
-
- sTop->Add(m_Game_str, 0, wxALL|wxEXPAND, 1);
- sTop->Add(m_Logging, 1, wxALL|wxEXPAND, 5);
- sChat->Add(m_Chat, 1, wxALL|wxEXPAND, 2);
- sChat->Add(m_Chat_ok, 0, wxALL, 2);
- sTop->Add(sChat, 0, wxALL|wxEXPAND, 2);
-
- wxBoxSizer* sBottom0 = new wxBoxSizer(wxHORIZONTAL);
- wxBoxSizer* sBottom1 = new wxBoxSizer(wxHORIZONTAL);
- wxBoxSizer* sBottomM = new wxBoxSizer(wxHORIZONTAL);
- wxBoxSizer* sBottom2 = new wxBoxSizer(wxVERTICAL);
-
- sBottom0->Add(m_Ready, 0, wxALL, 5);
- sBottom0->Add(m_RecordGame, 0, wxALL, 5);
- sBottomM->Add(m_ConInfo_text, 0, wxALL, 5);
- sBottom1->Add(m_Disconnect, 0, wxALL|wxALIGN_LEFT, 5);
- sBottom1->AddStretchSpacer(1);
- sBottom1->Add(m_GetPing, 0, wxALL|wxALIGN_RIGHT, 5);
-
- sBottom2->Add(sBottom0, 0, wxALL, 0);
- sBottom2->Add(sBottomM, 0, wxALL | wxALIGN_LEFT, 0);
- sBottom2->Add(sBottom1, 0, wxALL | wxEXPAND, 5);
-
- sBottom->Add(sBottom2, 2, wxALL | wxEXPAND | wxALIGN_CENTER, 0);
-
- if (m_isHosting)
- {
- m_wtfismyip = new wxButton(panel, ID_BUTTON_GETIP, wxT("What is my IP"));
- m_ChangeGame = new wxButton(panel, ID_CHANGEGAME, wxT("Change Game"));
-
- wxStaticBoxSizer* sBottom3 = new wxStaticBoxSizer(wxVERTICAL, panel, wxT("Host"));
-
- sBottom3->Add(m_ChangeGame, 0, wxALL | wxEXPAND, 5);
- sBottom3->Add(m_wtfismyip, 0, wxALL | wxEXPAND, 5);
- sBottom->Add(sBottom3, 1, wxALL | wxEXPAND, 0);
-
- UpdateNetWindow(false);
- }
-
- sMain->Add(sTop, 1, wxALL | wxEXPAND, 5);
- sMain->Add(sBottom, 0, wxALL | wxEXPAND | wxALIGN_CENTER, 2);
-
- panel->SetSizerAndFit(sMain);
- sMain->SetSizeHints((wxWindow*)this);
-
- Show();
-}
-
-// String of the type : FPSxPINGxFRAME_DELAY
-void NetPlay::UpdateNetWindow(bool update_infos, wxString infos)
-{
- std::vector<std::string> str_arr;
-
- if (update_infos)
- {
- SplitString(std::string(infos.mb_str()), "x", str_arr);
-
- m_ConInfo_text->SetLabel
- (wxString::Format(wxT(" Fps : %s | Ping : %s | Frame Delay : %s"),
- str_arr[0].c_str(), str_arr[1].c_str(),
- str_arr[2].c_str()) );
- }
- else
- {
- m_critical.Enter();
- m_Game_str->SetLabel(wxString::Format(wxT(" Game : %s"), m_selectedGame.c_str()));
- m_critical.Leave();
- }
-}
-
-void NetPlay::OnGUIEvent(wxCommandEvent& event)
-{
- unsigned char value;;
- switch (event.GetId())
- {
- case ID_READY:
- {
- std::string buffer;
- value = 0x40;
-
- if (!m_ready)
- buffer = ">> "+m_nick+" is now ready !\n";
- else
- buffer = ">> "+m_nick+" is now Unready !\n";
-
- m_ready = !m_ready;
-
- if (m_isHosting == 1)
- {
- if (m_numClients > 0)
- {
- int buffer_size = (int)buffer.size();
- for (int i=0; i < m_numClients ; i++)
- {
- m_sock_server->Write(i, (const char*)&value, 1);
-
- m_sock_server->Write(i, (const char*)&buffer_size, 4);
- m_sock_server->Write(i, buffer.c_str(), buffer_size + 1);
- }
- }
-
- m_Logging->AppendText(wxString::FromAscii(buffer.c_str()));
-
- // Everyone is ready
- if (m_ready && m_clients_ready)
- LoadGame();
- }
- else {
- if (m_numClients > 0)
- m_sock_client->Write((const char*)&value, 1); // 0x40 -> Ready
- }
- break;
- }
- case ID_BUTTON_GETIP:
- {
- if (m_numClients == 0) // Get IP Address from the Internet
- {
- // simple IP address caching
- if (m_hostaddr.at(0) != 'a')
- {
- m_Logging->AppendText(wxString::FromAscii(m_hostaddr.c_str()));
- return;
- }
-
- char buffer[8];
- sprintf(buffer, "%d", m_port);
-
- m_hostaddr = "> Your IP is : " + sf::IPAddress::GetPublicAddress().ToString() +
- ':' + std::string(buffer) + '\n';
- m_Logging->AppendText(wxString::FromAscii(m_hostaddr.c_str()));
- }
- else // Ask client to send server IP
- {
- value = 0x20;
- m_sock_server->Write(0, (const char*)&value, 1);
- }
- break;
- }
- case ID_BUTTON_GETPING:
- {
- if (m_numClients == 0)
- return;
-
- long ping[3] = {0};
- float fping;
-
- if (m_isHosting == 1) {
- m_sock_server->Write(0, 0, 0, ping);
- fping = (ping[0]+ping[1]+ping[2])/(float)m_numClients;
- }
- else {
- m_sock_client->Write(0, 0, ping);
- fping = ping[0];
- }
-
- UpdateNetWindow( true, wxString::Format(wxT("000x%fx%d"), fping, (int)ceil(fping/(1000.0/60.0))) );
- break;
- }
- case ID_BUTTON_CHAT:
- case ID_CHAT:
- {
- value = 0x30;
- wxString chat_str = wxString::Format(wxT("> %s : %s\n"), m_nick.c_str(), m_Chat->GetValue().c_str());
- int chat_size = (int)chat_str.size();
-
- // If there's no distant connection, we write but we don't send
- if (m_numClients == 0) {
- m_Logging->AppendText(chat_str);
- return;
- }
- // Max size that we handle is 1024, there's no need for more
- if ((chat_str.size()+1) * sizeof(char) > 1024) {
- m_Logging->AppendText(wxT("ERROR : Packet too large !\n"));
- return;
- }
-
- // Send to all
- if (m_isHosting == 1)
- {
- for (int i=0; i < m_numClients ; i++) {
- // Send Chat command
- m_sock_server->Write(i, (const char*)&value, 1); // 0x30 -> Chat
-
- // Send Chat string
- m_sock_server->Write(i, (const char*)&chat_size, 4);
- m_sock_server->Write(i, chat_str.mb_str(), chat_size + 1);
- }
- }
- else {
- m_sock_client->Write((const char*)&value, 1);
- m_sock_client->Write((const char*)&chat_size, 4);
- m_sock_client->Write(chat_str.mb_str(), chat_size + 1);
- }
-
- m_Chat->Clear();
-
- // Do not wait for the server, just write as soon as sent
- m_Logging->AppendText(chat_str);
-
- break;
- }
- case ID_RECORD:
- // TODO :
- // Record raw pad data
- break;
- case ID_CHANGEGAME:
- {
- GameListPopup PopUp(this, m_GameList_str);
- PopUp.ShowModal();
- break;
- }
- }
-}
-
-/////////////////////////
-// GameList popup window
-
-BEGIN_EVENT_TABLE(GameListPopup, wxDialog)
- EVT_BUTTON(wxID_OK, GameListPopup::OnButtons)
- EVT_BUTTON(wxID_CANCEL, GameListPopup::OnButtons)
-END_EVENT_TABLE()
-
-GameListPopup::GameListPopup(NetPlay *parent, wxArrayString GameNames) :
- wxDialog(parent, wxID_ANY, _T("Choose a Game :"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
-{
- m_netParent = parent;
- m_GameList_str = GameNames;
- m_GameList = new wxListBox(this, ID_GAMELIST, wxDefaultPosition, wxSize(300, 250),
- GameNames, wxLB_SINGLE | wxLB_SORT | wxLB_NEEDED_SB);
- m_Cancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize);
- m_Accept = new wxButton(this, wxID_OK, wxT("Apply"), wxDefaultPosition, wxDefaultSize);
-
- wxBoxSizer* sButtons = new wxBoxSizer(wxHORIZONTAL);
- wxBoxSizer* sMain = new wxBoxSizer(wxVERTICAL);
-
- sButtons->Add(m_Cancel, 0, wxALL, 0);
- sButtons->AddStretchSpacer(1);
- sButtons->Add(m_Accept, 0, wxALL | wxALIGN_RIGHT, 0);
-
- sMain->Add(m_GameList, 0, wxALL | wxEXPAND, 2);
- sMain->Add(sButtons, 0, wxALL | wxEXPAND, 5);
-
- SetSizerAndFit(sMain);
- Center(); Layout(); Show();
-}
-
-void GameListPopup::OnButtons(wxCommandEvent& event)
-{
- switch (event.GetId())
- {
- case wxID_OK:
- if (m_GameList->GetSelection() != wxNOT_FOUND)
- m_netParent->ChangeSelectedGame(std::string(m_GameList_str[m_GameList->GetSelection()].mb_str()));
- Destroy();
- break;
- case wxID_CANCEL:
- Destroy();
- break;
- }
-}
-
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "NetWindow.h"
+
+///////////////////////
+// Main Frame window
+
+BEGIN_EVENT_TABLE(NetPlay, wxFrame)
+ EVT_BUTTON(ID_BUTTON_JOIN, NetPlay::OnJoin)
+ EVT_BUTTON(ID_BUTTON_HOST, NetPlay::OnHost)
+
+ EVT_HOST_COMMAND(wxID_ANY, NetPlay::OnNetEvent)
+
+ EVT_CHECKBOX(ID_READY, NetPlay::OnGUIEvent)
+ EVT_CHECKBOX(ID_RECORD, NetPlay::OnGUIEvent)
+ EVT_BUTTON(ID_CHANGEGAME, NetPlay::OnGUIEvent)
+ EVT_BUTTON(ID_BUTTON_GETIP, NetPlay::OnGUIEvent)
+ EVT_BUTTON(ID_BUTTON_GETPING, NetPlay::OnGUIEvent)
+ EVT_BUTTON(ID_BUTTON_CHAT, NetPlay::OnGUIEvent)
+ EVT_TEXT_ENTER(ID_CHAT, NetPlay::OnGUIEvent)
+ EVT_BUTTON(ID_BUTTON_QUIT, NetPlay::OnDisconnect)
+ EVT_CLOSE(NetPlay::OnQuit)
+END_EVENT_TABLE()
+
+NetPlay::NetPlay(wxWindow* parent, std::string GamePaths, std::string GameNames) :
+ wxFrame(parent, wxID_ANY, _T("Net Play"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE & ~ wxMAXIMIZE_BOX)
+{
+ m_selectedGame = 'a'; m_hostaddr = 'a';
+ m_games = GameNames; m_paths = GamePaths;
+ m_isHosting = 2; m_ready = m_clients_ready = false;
+ m_loopframe = m_frame = m_NetModel = m_numClients = 0;
+
+ DrawGUI();
+}
+
+NetPlay::~NetPlay()
+{
+ ConfigIni.Load(CONFIG_FILE);
+
+ ConfigIni.Set("Netplay", "Nickname", m_nick);
+ ConfigIni.Set("Netplay", "UsedPort", (int)m_port);
+ ConfigIni.Set("Netplay", "LastIP", m_address);
+
+ ConfigIni.Save(CONFIG_FILE);
+}
+
+void NetPlay::OnJoin(wxCommandEvent& WXUNUSED(event))
+{
+ unsigned short server_port;
+
+ m_address = std::string(m_ConAddr->GetValue().mb_str());
+ m_nick = std::string(m_SetNick->GetValue().mb_str());
+
+ sf::IPAddress host = m_address.substr(0, m_address.find(':'));
+ std::string port_str = m_address.substr(m_address.find(':') + 1);
+
+ TryParseUInt(port_str, (u32*)&server_port); // Server port
+ TryParseUInt((const char *)m_SetPort->GetValue().mb_str(), (u32*)&m_port); // User port
+
+ if (m_nick.size() > 255)
+ m_nick = m_nick.substr(0 , 255);
+
+ SetTitle(wxT("Net Play : Connecting to Host..."));
+
+ // Create the client socket
+ sf::SocketTCP sock_client;
+ sf::SocketUDP sock_client_UDP;
+
+ if (sock_client.Connect(server_port, host, 1.5) == sf::Socket::Done)
+ {
+ // Try to Bind the UDP Socket
+ if (sock_client_UDP.Bind(m_port))
+ {
+ m_sock_client = new ClientSide(this, sock_client, sock_client_UDP, m_address, m_nick);
+ m_sock_client->Create();
+ m_sock_client->Run();
+
+ // Create the GUI
+ m_isHosting = false;
+ DrawNetWindow();
+ }
+ else
+ {
+ SetTitle(wxT("Net Play"));
+ PanicAlert("Can't Bind UDP socket on the specified Port: %d ! \n"
+ "Make sure port is forwarded and not in use !", m_port);
+ }
+ }
+ else
+ {
+ SetTitle(wxT("Net Play"));
+ PanicAlert("Can't connect to the specified IP Address ! \nMake sure Hosting port is forwarded !");
+ }
+}
+
+void NetPlay::OnHost(wxCommandEvent& WXUNUSED(event))
+{
+ TryParseInt(m_SetPort->GetValue().mb_str(), (int*)&m_port);
+
+ m_nick = std::string(m_SetNick->GetValue().mb_str());
+
+ if (m_GameList->GetSelection() == wxNOT_FOUND) {
+ PanicAlert("No Game Selected ! Please select a Game...");
+ return;
+ }
+ if (!m_SetPort->GetValue().size() || m_port < 1000 || m_port > 65535) {
+ PanicAlert("Bad Port entered (%d) ! Please enter a working socket port...", m_port);
+ return;
+ }
+ if (m_nick.size() > 255)
+ m_nick = m_nick.substr(0 , 255);
+
+ m_NetModel = m_NetMode->GetSelection();
+ m_selectedGame = std::string(m_GameList_str[m_GameList->GetSelection()].mb_str());
+
+ // Create the listening socket
+ sf::SocketTCP sock_server;
+ sf::SocketUDP sock_server_UDP;
+
+ // Start the listening socket and bind UDP socket port
+ if (sock_server.Listen(m_port) && sock_server_UDP.Bind(m_port))
+ {
+ m_sock_server = new ServerSide(this, sock_server, sock_server_UDP, m_NetModel, m_nick);
+ m_sock_server->Create();
+ m_sock_server->Run();
+
+ // Create the GUI
+ m_isHosting = true;
+ DrawNetWindow();
+ m_Logging->AppendText(wxString::Format(wxT("WARNING : Hosting requires port to be forwarded in firewall!\n"
+ "*Creation Successful on port %d : Waiting for peers...\n"), m_port));
+ }
+ else
+ {
+ PanicAlert("Could not listen at specified port !\nMake sure hosting port is not in use !");
+ return;
+ }
+}
+
+void NetPlay::DrawGUI()
+{
+ int str_end = -1;
+ int str_start = -1;
+ wxArrayString netmodes_str;
+
+ for(int i = 0; i < (int)m_games.size(); i++)
+ {
+ str_start = str_end + 1;
+ str_end = (int)m_games.find('\n', str_start);
+ std::string buffer = m_games.substr(str_start, str_end - str_start);
+
+ if (str_end == (int)std::string::npos || buffer.size() < 1)
+ break; // we reached the end of the string
+
+ m_GameList_str.Add(wxString::FromAscii(buffer.c_str()));
+ }
+
+ netmodes_str.Add(wxT("P2P Versus (2 players, faster)"));
+ // TODO : netmodes_str.Add(wxT("Server Mode (4 players, slower)"));
+
+ wxPanel *panel = new wxPanel(this);
+
+ // Tabs
+ m_Notebook = new wxNotebook(panel, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize);
+ m_Tab_Connect = new wxPanel(m_Notebook, ID_TAB_CONN, wxDefaultPosition, wxDefaultSize);
+ m_Notebook->AddPage(m_Tab_Connect, wxT("Connect"));
+ m_Tab_Host = new wxPanel(m_Notebook, ID_TAB_HOST, wxDefaultPosition, wxDefaultSize);
+ m_Notebook->AddPage(m_Tab_Host, wxT("Host"));
+
+ // Tow window, Nickname & Port settings
+ m_SetNick_text = new wxStaticText(panel, wxID_ANY, wxT(" Nickname : "), wxDefaultPosition, wxDefaultSize);
+ m_SetNick = new wxTextCtrl(panel, ID_SETNICK, wxT("LOLWUT!"), wxDefaultPosition, wxDefaultSize);
+ m_SetPort_text = new wxStaticText(panel, wxID_ANY, wxT(" Port to Use : "), wxDefaultPosition, wxDefaultSize);
+ m_SetPort = new wxTextCtrl(panel, ID_SETPORT, wxT("12345"), wxDefaultPosition, wxDefaultSize);
+
+ // CONNECTION TAB
+ m_ConAddr_text = new wxStaticText(m_Tab_Connect, wxID_ANY, wxT(" IP Address :"), wxDefaultPosition, wxDefaultSize);
+ m_ConAddr = new wxTextCtrl(m_Tab_Connect, ID_CONNADDR, wxT("127.0.0.1:12345"), wxDefaultPosition, wxSize(250,20), 0);
+ m_UseRandomPort = new wxCheckBox(m_Tab_Connect, ID_USE_RANDOMPORT, wxT("Use random client port for connection"));
+ m_JoinGame = new wxButton(m_Tab_Connect, ID_BUTTON_JOIN, wxT("Connect"), wxDefaultPosition, wxDefaultSize);
+
+ // Sizers CONNECT
+ wxBoxSizer* sConnectTop = new wxBoxSizer(wxHORIZONTAL);
+ wxBoxSizer* sConnectSizer = new wxBoxSizer(wxVERTICAL);
+
+ sConnectTop->Add(m_ConAddr_text, 0, wxALL|wxALIGN_CENTER, 5);
+ sConnectTop->Add(m_ConAddr, 1, wxALL|wxEXPAND, 5);
+ sConnectTop->Add(m_JoinGame, 0, wxALL|wxALIGN_RIGHT, 5);
+ sConnectSizer->Add(sConnectTop, 0, wxALL|wxEXPAND, 5);
+ sConnectSizer->Add(m_UseRandomPort, 0, wxALL|wxALIGN_CENTER, 5);
+
+ m_Tab_Connect->SetSizer(sConnectSizer);
+
+ // HOSTING TAB
+ m_GameList_text = new wxStaticText(m_Tab_Host, wxID_ANY,
+ wxT("Warning: Use a forwarded port ! Select Game and press Host :"), wxDefaultPosition, wxDefaultSize);
+ m_GameList = new wxListBox(m_Tab_Host, ID_GAMELIST, wxDefaultPosition, wxDefaultSize,
+ m_GameList_str, wxLB_SINGLE | wxLB_NEEDED_SB);
+ m_HostGame = new wxButton(m_Tab_Host, ID_BUTTON_HOST, wxT("Host"), wxDefaultPosition, wxDefaultSize);
+ m_NetMode = new wxChoice(m_Tab_Host, ID_NETMODE, wxDefaultPosition, wxDefaultSize, netmodes_str, 0, wxDefaultValidator);
+ m_NetMode->SetSelection(0);
+
+ // Sizers HOST
+ wxBoxSizer *sHostBox = new wxBoxSizer(wxVERTICAL);
+ wxBoxSizer *sHostBottom = new wxBoxSizer(wxHORIZONTAL);
+
+ sHostBottom->Add(m_NetMode, 0, wxALL|wxALIGN_CENTER, 5);
+ sHostBottom->AddStretchSpacer();
+ sHostBottom->Add(m_HostGame, 0, wxALL, 10);
+
+ sHostBox->Add(m_GameList_text, 0, wxALL|wxALIGN_CENTER, 5);
+ sHostBox->Add(m_GameList, 1, wxALL|wxEXPAND, 6);
+ sHostBox->Add(sHostBottom, 0, wxALL|wxEXPAND, 1);
+
+ m_Tab_Host->SetSizer(sHostBox);
+
+ // Main sizers
+ wxBoxSizer* sMain = new wxBoxSizer(wxVERTICAL);
+ wxBoxSizer* sMain_top = new wxBoxSizer(wxHORIZONTAL);
+
+ sMain_top->Add(m_SetNick_text, 0, wxALL|wxALIGN_CENTER, 3);
+ sMain_top->Add(m_SetNick, 1, wxALL|wxALIGN_CENTER, 3);
+ sMain_top->AddStretchSpacer();
+ sMain_top->Add(m_SetPort_text, 0, wxALL|wxALIGN_CENTER, 3);
+ sMain_top->Add(m_SetPort, 1, wxALL|wxALIGN_CENTER, 3);
+
+ sMain->Add(sMain_top, 0, wxALL|wxEXPAND, 5);
+ sMain->Add(m_Notebook, 1, wxALL|wxEXPAND, 5);
+
+ // Adjust panel to window's size, and set resizing minimum boundaries
+ panel->SetSizerAndFit(sMain);
+ sMain->SetSizeHints((wxWindow*)this);
+
+ if (ConfigIni.Load(CONFIG_FILE))
+ {
+ ConfigIni.Get("Netplay", "Nickname", &m_nick, "Unnamed");
+ ConfigIni.Get("Netplay", "UsedPort", (int*)&m_port, 12345);
+ ConfigIni.Get("Netplay", "LastIP", &m_address, "127.0.0.1:54321");
+
+ m_SetNick->SetValue(wxString::FromAscii(m_nick.c_str()));
+ m_SetPort->SetValue(wxString::Format(wxT("%d"), m_port));
+ m_ConAddr->SetValue(wxString::FromAscii(m_address.c_str()));
+ }
+
+ Center(); Show();
+}
+
+void NetPlay::DrawNetWindow()
+{
+ // Remove everything from the precedent GUI :D
+ DestroyChildren();
+
+ SetTitle(wxT("Net Play : Connection Window"));
+
+ wxPanel *panel = new wxPanel(this);
+ wxBoxSizer* sMain = new wxBoxSizer(wxVERTICAL);
+ wxBoxSizer* sTop = new wxBoxSizer(wxVERTICAL);
+ wxBoxSizer* sBottom = new wxBoxSizer(wxHORIZONTAL);
+
+ m_Game_str = new wxButton(panel, wxID_ANY, wxT(" Game : "), wxDefaultPosition, wxSize(400, 25), wxBU_LEFT);
+ m_Game_str->Disable();
+
+ m_Logging = new wxTextCtrl(panel, ID_LOGGING_TXT, wxEmptyString,
+ wxDefaultPosition, wxSize(400, 250),
+ wxTE_RICH2 | wxTE_MULTILINE | wxTE_READONLY);
+
+ m_Chat = new wxTextCtrl(panel, ID_CHAT, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
+ m_Chat_ok = new wxButton(panel, ID_BUTTON_CHAT, wxT("Send"));;
+
+ m_Ready = new wxCheckBox(panel, ID_READY, wxT("Click here when ready"), wxDefaultPosition, wxDefaultSize, 0);
+ m_RecordGame = new wxCheckBox(panel, ID_RECORD, wxT("Record Game Input"), wxDefaultPosition, wxDefaultSize, 0);
+ // TODO: Fix the recording ?
+ m_RecordGame->Disable();
+
+ m_ConInfo_text = new wxStaticText(panel, ID_CONNINFO_TXT, wxT(" Fps : 0 | Ping : 00 ms"));
+ m_GetPing = new wxButton(panel, ID_BUTTON_GETPING, wxT("Ping"), wxDefaultPosition, wxDefaultSize);
+ m_Disconnect = new wxButton(panel, ID_BUTTON_QUIT, wxT("Disconnect"), wxDefaultPosition, wxDefaultSize);
+
+ wxBoxSizer* sChat = new wxBoxSizer(wxHORIZONTAL);
+
+ sTop->Add(m_Game_str, 0, wxALL|wxEXPAND, 1);
+ sTop->Add(m_Logging, 1, wxALL|wxEXPAND, 5);
+ sChat->Add(m_Chat, 1, wxALL|wxEXPAND, 2);
+ sChat->Add(m_Chat_ok, 0, wxALL, 2);
+ sTop->Add(sChat, 0, wxALL|wxEXPAND, 2);
+
+ wxBoxSizer* sBottom0 = new wxBoxSizer(wxHORIZONTAL);
+ wxBoxSizer* sBottom1 = new wxBoxSizer(wxHORIZONTAL);
+ wxBoxSizer* sBottomM = new wxBoxSizer(wxHORIZONTAL);
+ wxBoxSizer* sBottom2 = new wxBoxSizer(wxVERTICAL);
+
+ sBottom0->Add(m_Ready, 0, wxALL, 5);
+ sBottom0->Add(m_RecordGame, 0, wxALL, 5);
+ sBottomM->Add(m_ConInfo_text, 0, wxALL, 5);
+ sBottom1->Add(m_Disconnect, 0, wxALL|wxALIGN_LEFT, 5);
+ sBottom1->AddStretchSpacer(1);
+ sBottom1->Add(m_GetPing, 0, wxALL|wxALIGN_RIGHT, 5);
+
+ sBottom2->Add(sBottom0, 0, wxALL, 0);
+ sBottom2->Add(sBottomM, 0, wxALL | wxALIGN_LEFT, 0);
+ sBottom2->Add(sBottom1, 0, wxALL | wxEXPAND, 5);
+
+ sBottom->Add(sBottom2, 2, wxALL | wxEXPAND | wxALIGN_CENTER, 0);
+
+ if (m_isHosting)
+ {
+ m_wtfismyip = new wxButton(panel, ID_BUTTON_GETIP, wxT("What is my IP"));
+ m_ChangeGame = new wxButton(panel, ID_CHANGEGAME, wxT("Change Game"));
+
+ wxStaticBoxSizer* sBottom3 = new wxStaticBoxSizer(wxVERTICAL, panel, wxT("Host"));
+
+ sBottom3->Add(m_ChangeGame, 0, wxALL | wxEXPAND, 5);
+ sBottom3->Add(m_wtfismyip, 0, wxALL | wxEXPAND, 5);
+ sBottom->Add(sBottom3, 1, wxALL | wxEXPAND, 0);
+
+ UpdateNetWindow(false);
+ }
+
+ sMain->Add(sTop, 1, wxALL | wxEXPAND, 5);
+ sMain->Add(sBottom, 0, wxALL | wxEXPAND | wxALIGN_CENTER, 2);
+
+ panel->SetSizerAndFit(sMain);
+ sMain->SetSizeHints((wxWindow*)this);
+
+ Show();
+}
+
+// String of the type : FPSxPINGxFRAME_DELAY
+void NetPlay::UpdateNetWindow(bool update_infos, wxString infos)
+{
+ std::vector<std::string> str_arr;
+
+ if (update_infos)
+ {
+ SplitString(std::string(infos.mb_str()), "x", str_arr);
+
+ m_ConInfo_text->SetLabel
+ (wxString::Format(wxT(" Fps : %s | Ping : %s | Frame Delay : %s"),
+ str_arr[0].c_str(), str_arr[1].c_str(),
+ str_arr[2].c_str()) );
+ }
+ else
+ {
+ m_critical.Enter();
+ m_Game_str->SetLabel(wxString::Format(wxT(" Game : %s"), m_selectedGame.c_str()));
+ m_critical.Leave();
+ }
+}
+
+void NetPlay::OnGUIEvent(wxCommandEvent& event)
+{
+ unsigned char value;;
+ switch (event.GetId())
+ {
+ case ID_READY:
+ {
+ std::string buffer;
+ value = 0x40;
+
+ if (!m_ready)
+ buffer = ">> "+m_nick+" is now ready !\n";
+ else
+ buffer = ">> "+m_nick+" is now Unready !\n";
+
+ m_ready = !m_ready;
+
+ if (m_isHosting == 1)
+ {
+ if (m_numClients > 0)
+ {
+ int buffer_size = (int)buffer.size();
+ for (int i=0; i < m_numClients ; i++)
+ {
+ m_sock_server->Write(i, (const char*)&value, 1);
+
+ m_sock_server->Write(i, (const char*)&buffer_size, 4);
+ m_sock_server->Write(i, buffer.c_str(), buffer_size + 1);
+ }
+ }
+
+ m_Logging->AppendText(wxString::FromAscii(buffer.c_str()));
+
+ // Everyone is ready
+ if (m_ready && m_clients_ready)
+ LoadGame();
+ }
+ else {
+ if (m_numClients > 0)
+ m_sock_client->Write((const char*)&value, 1); // 0x40 -> Ready
+ }
+ break;
+ }
+ case ID_BUTTON_GETIP:
+ {
+ if (m_numClients == 0) // Get IP Address from the Internet
+ {
+ // simple IP address caching
+ if (m_hostaddr.at(0) != 'a')
+ {
+ m_Logging->AppendText(wxString::FromAscii(m_hostaddr.c_str()));
+ return;
+ }
+
+ char buffer[8];
+ sprintf(buffer, "%d", m_port);
+
+ m_hostaddr = "> Your IP is : " + sf::IPAddress::GetPublicAddress().ToString() +
+ ':' + std::string(buffer) + '\n';
+ m_Logging->AppendText(wxString::FromAscii(m_hostaddr.c_str()));
+ }
+ else // Ask client to send server IP
+ {
+ value = 0x20;
+ m_sock_server->Write(0, (const char*)&value, 1);
+ }
+ break;
+ }
+ case ID_BUTTON_GETPING:
+ {
+ if (m_numClients == 0)
+ return;
+
+ long ping[3] = {0};
+ float fping;
+
+ if (m_isHosting == 1) {
+ m_sock_server->Write(0, 0, 0, ping);
+ fping = (ping[0]+ping[1]+ping[2])/(float)m_numClients;
+ }
+ else {
+ m_sock_client->Write(0, 0, ping);
+ fping = ping[0];
+ }
+
+ UpdateNetWindow( true, wxString::Format(wxT("000x%fx%d"), fping, (int)ceil(fping/(1000.0/60.0))) );
+ break;
+ }
+ case ID_BUTTON_CHAT:
+ case ID_CHAT:
+ {
+ value = 0x30;
+ wxString chat_str = wxString::Format(wxT("> %s : %s\n"), m_nick.c_str(), m_Chat->GetValue().c_str());
+ int chat_size = (int)chat_str.size();
+
+ // If there's no distant connection, we write but we don't send
+ if (m_numClients == 0) {
+ m_Logging->AppendText(chat_str);
+ return;
+ }
+ // Max size that we handle is 1024, there's no need for more
+ if ((chat_str.size()+1) * sizeof(char) > 1024) {
+ m_Logging->AppendText(wxT("ERROR : Packet too large !\n"));
+ return;
+ }
+
+ // Send to all
+ if (m_isHosting == 1)
+ {
+ for (int i=0; i < m_numClients ; i++) {
+ // Send Chat command
+ m_sock_server->Write(i, (const char*)&value, 1); // 0x30 -> Chat
+
+ // Send Chat string
+ m_sock_server->Write(i, (const char*)&chat_size, 4);
+ m_sock_server->Write(i, chat_str.mb_str(), chat_size + 1);
+ }
+ }
+ else {
+ m_sock_client->Write((const char*)&value, 1);
+ m_sock_client->Write((const char*)&chat_size, 4);
+ m_sock_client->Write(chat_str.mb_str(), chat_size + 1);
+ }
+
+ m_Chat->Clear();
+
+ // Do not wait for the server, just write as soon as sent
+ m_Logging->AppendText(chat_str);
+
+ break;
+ }
+ case ID_RECORD:
+ // TODO :
+ // Record raw pad data
+ break;
+ case ID_CHANGEGAME:
+ {
+ GameListPopup PopUp(this, m_GameList_str);
+ PopUp.ShowModal();
+ break;
+ }
+ }
+}
+
+/////////////////////////
+// GameList popup window
+
+BEGIN_EVENT_TABLE(GameListPopup, wxDialog)
+ EVT_BUTTON(wxID_OK, GameListPopup::OnButtons)
+ EVT_BUTTON(wxID_CANCEL, GameListPopup::OnButtons)
+END_EVENT_TABLE()
+
+GameListPopup::GameListPopup(NetPlay *parent, wxArrayString GameNames) :
+ wxDialog(parent, wxID_ANY, _T("Choose a Game :"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
+{
+ m_netParent = parent;
+ m_GameList_str = GameNames;
+ m_GameList = new wxListBox(this, ID_GAMELIST, wxDefaultPosition, wxSize(300, 250),
+ GameNames, wxLB_SINGLE | wxLB_SORT | wxLB_NEEDED_SB);
+ m_Cancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize);
+ m_Accept = new wxButton(this, wxID_OK, wxT("Apply"), wxDefaultPosition, wxDefaultSize);
+
+ wxBoxSizer* sButtons = new wxBoxSizer(wxHORIZONTAL);
+ wxBoxSizer* sMain = new wxBoxSizer(wxVERTICAL);
+
+ sButtons->Add(m_Cancel, 0, wxALL, 0);
+ sButtons->AddStretchSpacer(1);
+ sButtons->Add(m_Accept, 0, wxALL | wxALIGN_RIGHT, 0);
+
+ sMain->Add(m_GameList, 0, wxALL | wxEXPAND, 2);
+ sMain->Add(sButtons, 0, wxALL | wxEXPAND, 5);
+
+ SetSizerAndFit(sMain);
+ Center(); Layout(); Show();
+}
+
+void GameListPopup::OnButtons(wxCommandEvent& event)
+{
+ switch (event.GetId())
+ {
+ case wxID_OK:
+ if (m_GameList->GetSelection() != wxNOT_FOUND)
+ m_netParent->ChangeSelectedGame(std::string(m_GameList_str[m_GameList->GetSelection()].mb_str()));
+ Destroy();
+ break;
+ case wxID_CANCEL:
+ Destroy();
+ break;
+ }
+}
+
diff --git a/Source/Core/DolphinWX/Src/NetWindow.h b/Source/Core/DolphinWX/Src/NetWindow.h
index 7c0c8bd942..c64a97ca15 100644
--- a/Source/Core/DolphinWX/Src/NetWindow.h
+++ b/Source/Core/DolphinWX/Src/NetWindow.h
@@ -1,317 +1,317 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _NETWINDOW_H_
-#define _NETWINDOW_H_
-
-#include <SFML/Network.hpp>
-#include <string>
-#include <wx/wx.h>
-#include <wx/sizer.h>
-#include <wx/dialog.h>
-#include <wx/notebook.h>
-#include <wx/gbsizer.h>
-#include <wx/listbox.h>
-
-#include <wx/thread.h>
-
-#include "Globals.h"
-#include "BootManager.h"
-#include "Common.h"
-#include "Core.h"
-#include "pluginspecs_pad.h"
-#include "HW/SI.h"
-#include "HW/SI_Device.h"
-#include "HW/SI_DeviceGCController.h"
-#include "Timer.h"
-
-#ifdef _DEBUG
- #define NET_DEBUG
-#endif
-
-// Use TCP instead of UDP to send pad data @ 60fps. Suitable and better for LAN netplay,
-// Unrealistic for Internet netplay, unless you have an uberfast connexion (<10ms ping)
-// #define USE_TCP
-
-class NetPlay;
-
-struct Netpads {
- int nHi[128];
- int nLow[128];
-};
-
-struct Clients {
- std::string nick;
- sf::SocketTCP socket;
- unsigned short port;
- sf::IPAddress address;
- bool ready;
-};
-
-class NetEvent
-{
- public:
- NetEvent(NetPlay* netptr) { m_netptr = netptr; }
- ~NetEvent() {};
-
- void SendEvent(int EventType, std::string="NULL", int=NULL);
- void AppendText(const wxString text);
-
- private:
- NetPlay *m_netptr;
-};
-
-class ServerSide : public wxThread
-{
- public:
- ServerSide(NetPlay* netptr, sf::SocketTCP, sf::SocketUDP, int netmodel, std::string nick);
- ~ServerSide() {};
-
- virtual void *Entry();
-
- void Write(int socknb, const char *data, size_t size, long *ping=NULL);
- void WriteUDP(int socknb, const char *data, size_t size);
- bool isNewPadData(u32 *netValues, bool current, int client=0);
-
- private:
- bool SyncValues(unsigned char, sf::IPAddress);
- bool RecvT(sf::SocketUDP Socket, char * Data, size_t Max, size_t& Recvd, float Time = 0);
- char GetSocket(sf::SocketTCP Socket);
- void OnServerData(int sock, unsigned char data);
- void IsEveryoneReady();
-
- NetPlay *m_netptr;
- NetEvent *Event;
-
- u32 m_netvalues[3][3];
- bool m_data_received; // New Pad data received ?
-
- unsigned char m_numplayers;
- int m_netmodel;
- std::string m_nick;
-
- Clients m_client[3]; // Connected client objects
- sf::SelectorTCP m_selector;
- sf::SocketTCP m_socket; // Server 'listening' socket
- sf::SocketUDP m_socketUDP;
-
- wxCriticalSection m_CriticalSection;
-};
-
-class ClientSide : public wxThread
-{
- public:
- ClientSide(NetPlay* netptr, sf::SocketTCP, sf::SocketUDP, std::string addr, std::string nick);
- ~ClientSide() {}
-
- virtual void *Entry();
-
- void Write(const char *data, size_t size, long *ping=NULL);
- void WriteUDP(const char *data, size_t size);
- bool isNewPadData(u32 *netValues, bool current, bool isVersus=true);
-
- private:
- bool SyncValues();
- void CheckGameFound();
- void OnClientData(unsigned char data);
- bool RecvT(sf::SocketUDP Socket, char * Data, size_t Max, size_t& Recvd, float Time=0);
-
- NetPlay *m_netptr;
- NetEvent *Event;
-
- u32 m_netvalues[3][3];
- bool m_data_received; // New Pad data received ?
-
- unsigned char m_numplayers;
- int m_netmodel;
- std::string m_nick;
- std::string m_hostnick;
- std::string m_selectedgame;
-
- sf::SelectorTCP m_selector;
- sf::SocketTCP m_socket; // Client I/O socket
- sf::SocketUDP m_socketUDP;
- unsigned short m_port;
- std::string m_addr; // Contains the server addr
-
- wxCriticalSection m_CriticalSection;
-};
-
-class NetPlay : public wxFrame
-{
- public:
- NetPlay(wxWindow* parent, std::string GamePath = "", std::string GameName = "");
- ~NetPlay();
-
- void UpdateNetWindow(bool update_infos, wxString=wxT("NULL"));
- void AppendText(const wxString text) { m_Logging->AppendText(text); }
-
- // Send and receive pads values
- bool GetNetPads(u8 pad_nb, SPADStatus, u32 *netvalues);
- void ChangeSelectedGame(std::string game);
- void IsGameFound(unsigned char*, std::string);
- std::string GetSelectedGame() { wxCriticalSectionLocker lock(m_critical); return m_selectedGame; }
-
- void LoadGame();
-
- protected:
- // Protects our vars from being fuxored by threads
- wxCriticalSection m_critical;
-
- // this draws the GUI, ya rly
- void DrawGUI();
- void DrawNetWindow();
-
- // event handlers
- void OnGUIEvent(wxCommandEvent& event);
- void OnDisconnect(wxCommandEvent& event);
- void OnNetEvent(wxCommandEvent& event);
- void OnQuit(wxCloseEvent& event);
-
- void OnJoin(wxCommandEvent& event);
- void OnHost(wxCommandEvent& event);
-
- // Net play vars (used ingame)
- int m_frame;
- int m_lastframe;
- Common::Timer m_timer;
- int m_loopframe;
- int m_frameDelay;
- bool m_data_received;// True if first frame data received
-
- // Basic vars
- std::string m_paths; // Game paths list
- std::string m_games; // Game names list
-
- std::string m_selectedGame;// Selected game's string
- std::string m_hostaddr; // Used with OnGetIP to cache it
- bool m_ready, m_clients_ready;
- std::string m_nick;
-
- int m_NetModel; // Using P2P model (0) or Server model (1)
- int m_isHosting; // 0 = false ; 1 = true ; 2 = Not set
- unsigned char m_numClients; // starting from 0, 4 players max thus 3 clients
- std::string m_address; // The address entered into connection box
- unsigned short m_port;
-
- Netpads m_pads[4]; // this struct is used to save synced pad values
- IniFile ConfigIni;
-
- // Sockets objects
- ServerSide *m_sock_server;
- ClientSide *m_sock_client;
-
- // -----------
- // GUI objects
- // -----------
- wxNotebook *m_Notebook;
- wxPanel *m_Tab_Connect;
- wxPanel *m_Tab_Host;
- wxStaticText *m_SetNick_text;
- wxTextCtrl *m_SetNick;
- wxChoice *m_NetMode;
-
- // Host tab :
- wxArrayString m_GameList_str;
- wxStaticText *m_GameList_text;
- wxListBox *m_GameList;
- wxStaticText *m_SetPort_text;
- wxTextCtrl *m_SetPort;
- wxButton *m_HostGame;
-
- // Connect tab :
- wxTextCtrl *m_ConAddr;
- wxStaticText *m_ConAddr_text;
- wxButton *m_JoinGame;
- wxCheckBox *m_UseRandomPort;
-
- // Connection window
- wxButton *m_Game_str;
- wxTextCtrl *m_Logging;
- wxTextCtrl *m_Chat;
- wxButton *m_Chat_ok;
- // Right part
- wxButton *m_wtfismyip;
- wxButton *m_ChangeGame;
- // Left Part
- wxButton *m_Disconnect;
- wxStaticText *m_ConInfo_text;
- wxButton *m_GetPing;
- wxCheckBox *m_Ready;
- wxCheckBox *m_RecordGame;
-
- // wxWidgets event table
- DECLARE_EVENT_TABLE()
-};
-
-class GameListPopup : public wxDialog
-{
- public:
- GameListPopup(NetPlay *net_ptr, wxArrayString GameNames);
- ~GameListPopup() {}
- protected:
- void OnButtons(wxCommandEvent& event);
- wxArrayString m_GameList_str;
- NetPlay* m_netParent;
- wxListBox *m_GameList;
- wxButton *m_Accept;
- wxButton *m_Cancel;
- DECLARE_EVENT_TABLE()
-};
-
-enum
-{
- ID_NOTEBOOK,
- ID_TAB_HOST,
- ID_TAB_CONN,
- ID_BUTTON_HOST,
- ID_BUTTON_JOIN,
- ID_NETMODE,
- ID_GAMELIST,
- ID_LOGGING_TXT,
- ID_CHAT,
- ID_SETNICK,
- ID_SETPORT,
- ID_CONNADDR,
- ID_CONNINFO_TXT,
- ID_USE_RANDOMPORT,
- ID_BUTTON_GETPING,
- ID_BUTTON_GETIP,
- ID_CHANGEGAME,
- ID_BUTTON_QUIT,
- ID_BUTTON_CHAT,
- ID_READY,
- ID_RECORD,
-
- ID_SOCKET,
- ID_SERVER,
-
- HOST_FULL = 200, // ...
- HOST_ERROR, // Sent on socket error
- HOST_DISCONNECTED,
- HOST_NEWPLAYER,
- HOST_PLAYERLEFT,
- CLIENTS_READY,
- CLIENTS_NOTREADY,
- GUI_UPDATE, // Refresh the shown selectedgame on GUI
- ADD_TEXT, // Add text to m_Logging (string)
- ADD_INFO, // Sent when updating net infos (string)
- NET_EVENT
-};
-
-#endif // _NETWINDOW_H_
-
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _NETWINDOW_H_
+#define _NETWINDOW_H_
+
+#include <SFML/Network.hpp>
+#include <string>
+#include <wx/wx.h>
+#include <wx/sizer.h>
+#include <wx/dialog.h>
+#include <wx/notebook.h>
+#include <wx/gbsizer.h>
+#include <wx/listbox.h>
+
+#include <wx/thread.h>
+
+#include "Globals.h"
+#include "BootManager.h"
+#include "Common.h"
+#include "Core.h"
+#include "pluginspecs_pad.h"
+#include "HW/SI.h"
+#include "HW/SI_Device.h"
+#include "HW/SI_DeviceGCController.h"
+#include "Timer.h"
+
+#ifdef _DEBUG
+ #define NET_DEBUG
+#endif
+
+// Use TCP instead of UDP to send pad data @ 60fps. Suitable and better for LAN netplay,
+// Unrealistic for Internet netplay, unless you have an uberfast connexion (<10ms ping)
+// #define USE_TCP
+
+class NetPlay;
+
+struct Netpads {
+ int nHi[128];
+ int nLow[128];
+};
+
+struct Clients {
+ std::string nick;
+ sf::SocketTCP socket;
+ unsigned short port;
+ sf::IPAddress address;
+ bool ready;
+};
+
+class NetEvent
+{
+ public:
+ NetEvent(NetPlay* netptr) { m_netptr = netptr; }
+ ~NetEvent() {};
+
+ void SendEvent(int EventType, std::string="NULL", int=NULL);
+ void AppendText(const wxString text);
+
+ private:
+ NetPlay *m_netptr;
+};
+
+class ServerSide : public wxThread
+{
+ public:
+ ServerSide(NetPlay* netptr, sf::SocketTCP, sf::SocketUDP, int netmodel, std::string nick);
+ ~ServerSide() {};
+
+ virtual void *Entry();
+
+ void Write(int socknb, const char *data, size_t size, long *ping=NULL);
+ void WriteUDP(int socknb, const char *data, size_t size);
+ bool isNewPadData(u32 *netValues, bool current, int client=0);
+
+ private:
+ bool SyncValues(unsigned char, sf::IPAddress);
+ bool RecvT(sf::SocketUDP Socket, char * Data, size_t Max, size_t& Recvd, float Time = 0);
+ char GetSocket(sf::SocketTCP Socket);
+ void OnServerData(int sock, unsigned char data);
+ void IsEveryoneReady();
+
+ NetPlay *m_netptr;
+ NetEvent *Event;
+
+ u32 m_netvalues[3][3];
+ bool m_data_received; // New Pad data received ?
+
+ unsigned char m_numplayers;
+ int m_netmodel;
+ std::string m_nick;
+
+ Clients m_client[3]; // Connected client objects
+ sf::SelectorTCP m_selector;
+ sf::SocketTCP m_socket; // Server 'listening' socket
+ sf::SocketUDP m_socketUDP;
+
+ wxCriticalSection m_CriticalSection;
+};
+
+class ClientSide : public wxThread
+{
+ public:
+ ClientSide(NetPlay* netptr, sf::SocketTCP, sf::SocketUDP, std::string addr, std::string nick);
+ ~ClientSide() {}
+
+ virtual void *Entry();
+
+ void Write(const char *data, size_t size, long *ping=NULL);
+ void WriteUDP(const char *data, size_t size);
+ bool isNewPadData(u32 *netValues, bool current, bool isVersus=true);
+
+ private:
+ bool SyncValues();
+ void CheckGameFound();
+ void OnClientData(unsigned char data);
+ bool RecvT(sf::SocketUDP Socket, char * Data, size_t Max, size_t& Recvd, float Time=0);
+
+ NetPlay *m_netptr;
+ NetEvent *Event;
+
+ u32 m_netvalues[3][3];
+ bool m_data_received; // New Pad data received ?
+
+ unsigned char m_numplayers;
+ int m_netmodel;
+ std::string m_nick;
+ std::string m_hostnick;
+ std::string m_selectedgame;
+
+ sf::SelectorTCP m_selector;
+ sf::SocketTCP m_socket; // Client I/O socket
+ sf::SocketUDP m_socketUDP;
+ unsigned short m_port;
+ std::string m_addr; // Contains the server addr
+
+ wxCriticalSection m_CriticalSection;
+};
+
+class NetPlay : public wxFrame
+{
+ public:
+ NetPlay(wxWindow* parent, std::string GamePath = "", std::string GameName = "");
+ ~NetPlay();
+
+ void UpdateNetWindow(bool update_infos, wxString=wxT("NULL"));
+ void AppendText(const wxString text) { m_Logging->AppendText(text); }
+
+ // Send and receive pads values
+ bool GetNetPads(u8 pad_nb, SPADStatus, u32 *netvalues);
+ void ChangeSelectedGame(std::string game);
+ void IsGameFound(unsigned char*, std::string);
+ std::string GetSelectedGame() { wxCriticalSectionLocker lock(m_critical); return m_selectedGame; }
+
+ void LoadGame();
+
+ protected:
+ // Protects our vars from being fuxored by threads
+ wxCriticalSection m_critical;
+
+ // this draws the GUI, ya rly
+ void DrawGUI();
+ void DrawNetWindow();
+
+ // event handlers
+ void OnGUIEvent(wxCommandEvent& event);
+ void OnDisconnect(wxCommandEvent& event);
+ void OnNetEvent(wxCommandEvent& event);
+ void OnQuit(wxCloseEvent& event);
+
+ void OnJoin(wxCommandEvent& event);
+ void OnHost(wxCommandEvent& event);
+
+ // Net play vars (used ingame)
+ int m_frame;
+ int m_lastframe;
+ Common::Timer m_timer;
+ int m_loopframe;
+ int m_frameDelay;
+ bool m_data_received;// True if first frame data received
+
+ // Basic vars
+ std::string m_paths; // Game paths list
+ std::string m_games; // Game names list
+
+ std::string m_selectedGame;// Selected game's string
+ std::string m_hostaddr; // Used with OnGetIP to cache it
+ bool m_ready, m_clients_ready;
+ std::string m_nick;
+
+ int m_NetModel; // Using P2P model (0) or Server model (1)
+ int m_isHosting; // 0 = false ; 1 = true ; 2 = Not set
+ unsigned char m_numClients; // starting from 0, 4 players max thus 3 clients
+ std::string m_address; // The address entered into connection box
+ unsigned short m_port;
+
+ Netpads m_pads[4]; // this struct is used to save synced pad values
+ IniFile ConfigIni;
+
+ // Sockets objects
+ ServerSide *m_sock_server;
+ ClientSide *m_sock_client;
+
+ // -----------
+ // GUI objects
+ // -----------
+ wxNotebook *m_Notebook;
+ wxPanel *m_Tab_Connect;
+ wxPanel *m_Tab_Host;
+ wxStaticText *m_SetNick_text;
+ wxTextCtrl *m_SetNick;
+ wxChoice *m_NetMode;
+
+ // Host tab :
+ wxArrayString m_GameList_str;
+ wxStaticText *m_GameList_text;
+ wxListBox *m_GameList;
+ wxStaticText *m_SetPort_text;
+ wxTextCtrl *m_SetPort;
+ wxButton *m_HostGame;
+
+ // Connect tab :
+ wxTextCtrl *m_ConAddr;
+ wxStaticText *m_ConAddr_text;
+ wxButton *m_JoinGame;
+ wxCheckBox *m_UseRandomPort;
+
+ // Connection window
+ wxButton *m_Game_str;
+ wxTextCtrl *m_Logging;
+ wxTextCtrl *m_Chat;
+ wxButton *m_Chat_ok;
+ // Right part
+ wxButton *m_wtfismyip;
+ wxButton *m_ChangeGame;
+ // Left Part
+ wxButton *m_Disconnect;
+ wxStaticText *m_ConInfo_text;
+ wxButton *m_GetPing;
+ wxCheckBox *m_Ready;
+ wxCheckBox *m_RecordGame;
+
+ // wxWidgets event table
+ DECLARE_EVENT_TABLE()
+};
+
+class GameListPopup : public wxDialog
+{
+ public:
+ GameListPopup(NetPlay *net_ptr, wxArrayString GameNames);
+ ~GameListPopup() {}
+ protected:
+ void OnButtons(wxCommandEvent& event);
+ wxArrayString m_GameList_str;
+ NetPlay* m_netParent;
+ wxListBox *m_GameList;
+ wxButton *m_Accept;
+ wxButton *m_Cancel;
+ DECLARE_EVENT_TABLE()
+};
+
+enum
+{
+ ID_NOTEBOOK,
+ ID_TAB_HOST,
+ ID_TAB_CONN,
+ ID_BUTTON_HOST,
+ ID_BUTTON_JOIN,
+ ID_NETMODE,
+ ID_GAMELIST,
+ ID_LOGGING_TXT,
+ ID_CHAT,
+ ID_SETNICK,
+ ID_SETPORT,
+ ID_CONNADDR,
+ ID_CONNINFO_TXT,
+ ID_USE_RANDOMPORT,
+ ID_BUTTON_GETPING,
+ ID_BUTTON_GETIP,
+ ID_CHANGEGAME,
+ ID_BUTTON_QUIT,
+ ID_BUTTON_CHAT,
+ ID_READY,
+ ID_RECORD,
+
+ ID_SOCKET,
+ ID_SERVER,
+
+ HOST_FULL = 200, // ...
+ HOST_ERROR, // Sent on socket error
+ HOST_DISCONNECTED,
+ HOST_NEWPLAYER,
+ HOST_PLAYERLEFT,
+ CLIENTS_READY,
+ CLIENTS_NOTREADY,
+ GUI_UPDATE, // Refresh the shown selectedgame on GUI
+ ADD_TEXT, // Add text to m_Logging (string)
+ ADD_INFO, // Sent when updating net infos (string)
+ NET_EVENT
+};
+
+#endif // _NETWINDOW_H_
+
diff --git a/Source/Core/DolphinWX/Src/Summarize.h b/Source/Core/DolphinWX/Src/Summarize.h
index e0f1c68335..49608767ff 100644
--- a/Source/Core/DolphinWX/Src/Summarize.h
+++ b/Source/Core/DolphinWX/Src/Summarize.h
@@ -1,127 +1,127 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef __SUMMARIZE_H__
-#define __SUMMARIZE_H__
-
-std::string Summarize_Plug()
-{
- return StringFromFormat(
- "Plugin Information\n\n"
- "Default GFX Plugin: %s\n"
- "Default DSP Plugin: %s\n"
- "Default PAD Plugin: %s\n"
- "Default WiiMote Plugin: %s\n\n"
- "Current GFX Plugin: %s\n"
- "Current DSP Plugin: %s\n"
- "Current PAD Plugin[0]: %s\n"
- "Current PAD Plugin[1]: %s\n"
- "Current PAD Plugin[2]: %s\n"
- "Current PAD Plugin[3]: %s\n"
- "Current WiiMote Plugin[0]: %s\n",
- SConfig::GetInstance().m_DefaultGFXPlugin.c_str(),
- SConfig::GetInstance().m_DefaultDSPPlugin.c_str(),
- SConfig::GetInstance().m_DefaultPADPlugin.c_str(),
- SConfig::GetInstance().m_DefaultWiiMotePlugin.c_str(),
- Core::GetStartupParameter().m_strVideoPlugin.c_str(),
- Core::GetStartupParameter().m_strDSPPlugin.c_str(),
- Core::GetStartupParameter().m_strPadPlugin[0].c_str(),
- Core::GetStartupParameter().m_strPadPlugin[1].c_str(),
- Core::GetStartupParameter().m_strPadPlugin[2].c_str(),
- Core::GetStartupParameter().m_strPadPlugin[3].c_str(),
- Core::GetStartupParameter().m_strWiimotePlugin[0].c_str()
- );
-}
-
-std::string Summarize_Settings()
-{
- return StringFromFormat(
- "Dolphin Settings\n\n"
- "Always HLE Bios: %s\n"
- "Use Dynarec: %s\n"
- "Use Dual Core: %s\n"
- "DSP Thread: %s\n"
- "Skip Idle: %s\n"
- "Lock Threads: %s\n"
- "Use Dual Core: %s\n"
- "Default GCM: %s\n"
- "DVD Root: %s\n"
- "Optimize Quantizers: %s\n"
- "Enable Cheats: %s\n"
- "Selected Language: %d\n"
- "Memcard A: %s\n"
- "Memcard B: %s\n"
- "Slot A: %d\n"
- "Slot B: %d\n"
- "Serial Port 1: %d\n"
- "Run Compare Server: %s\n"
- "Run Compare Client: %s\n"
- "TLB Hack: %s\n"
- "Frame Limit: %d\n"
- "[Wii]Widescreen: %s\n"
- "[Wii]Progressive Scan: %s\n",
- Core::GetStartupParameter().bHLEBios?"True":"False",
- Core::GetStartupParameter().bUseJIT?"True":"False",
- Core::GetStartupParameter().bUseDualCore?"True":"False",
- Core::GetStartupParameter().bDSPThread?"True":"False",
- Core::GetStartupParameter().bSkipIdle?"True":"False",
- Core::GetStartupParameter().bLockThreads?"True":"False",
- Core::GetStartupParameter().bUseDualCore?"True":"False",
- Core::GetStartupParameter().m_strDefaultGCM.c_str(),
- Core::GetStartupParameter().m_strDVDRoot.c_str(),
- Core::GetStartupParameter().bOptimizeQuantizers?"True":"False",
- Core::GetStartupParameter().bEnableCheats?"True":"False",
- Core::GetStartupParameter().SelectedLanguage, //FIXME show language based on index
- SConfig::GetInstance().m_strMemoryCardA.c_str(),
- SConfig::GetInstance().m_strMemoryCardB.c_str(),
- SConfig::GetInstance().m_EXIDevice[0], //FIXME
- SConfig::GetInstance().m_EXIDevice[1], //FIXME
- SConfig::GetInstance().m_EXIDevice[2], //FIXME
- Core::GetStartupParameter().bRunCompareServer?"True":"False",
- Core::GetStartupParameter().bRunCompareClient?"True":"False",
- Core::GetStartupParameter().iTLBHack?"True":"False",
- SConfig::GetInstance().m_Framelimit*5,
- Core::GetStartupParameter().bWidescreen?"True":"False",
- Core::GetStartupParameter().bProgressiveScan?"True":"False"
- );
-}
-
-std::string Summarize_CPU()
-{
- return StringFromFormat(
- "Processor Information: \n%s\n",
- cpu_info.Summarize().c_str()
- );
-}
-
-std::string Summarize_Drives()
-{
- char ** drives = cdio_get_devices();
- std::string drive;
- for (int i = 0; drives[i] != NULL && i < 24; i++)
- {
-
- drive += StringFromFormat(
- "CD/DVD Drive%d: %s\n",
- i+1,
- drives[i]
- );
- }
- return drive;
-}
-
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef __SUMMARIZE_H__
+#define __SUMMARIZE_H__
+
+std::string Summarize_Plug()
+{
+ return StringFromFormat(
+ "Plugin Information\n\n"
+ "Default GFX Plugin: %s\n"
+ "Default DSP Plugin: %s\n"
+ "Default PAD Plugin: %s\n"
+ "Default WiiMote Plugin: %s\n\n"
+ "Current GFX Plugin: %s\n"
+ "Current DSP Plugin: %s\n"
+ "Current PAD Plugin[0]: %s\n"
+ "Current PAD Plugin[1]: %s\n"
+ "Current PAD Plugin[2]: %s\n"
+ "Current PAD Plugin[3]: %s\n"
+ "Current WiiMote Plugin[0]: %s\n",
+ SConfig::GetInstance().m_DefaultGFXPlugin.c_str(),
+ SConfig::GetInstance().m_DefaultDSPPlugin.c_str(),
+ SConfig::GetInstance().m_DefaultPADPlugin.c_str(),
+ SConfig::GetInstance().m_DefaultWiiMotePlugin.c_str(),
+ Core::GetStartupParameter().m_strVideoPlugin.c_str(),
+ Core::GetStartupParameter().m_strDSPPlugin.c_str(),
+ Core::GetStartupParameter().m_strPadPlugin[0].c_str(),
+ Core::GetStartupParameter().m_strPadPlugin[1].c_str(),
+ Core::GetStartupParameter().m_strPadPlugin[2].c_str(),
+ Core::GetStartupParameter().m_strPadPlugin[3].c_str(),
+ Core::GetStartupParameter().m_strWiimotePlugin[0].c_str()
+ );
+}
+
+std::string Summarize_Settings()
+{
+ return StringFromFormat(
+ "Dolphin Settings\n\n"
+ "Always HLE Bios: %s\n"
+ "Use Dynarec: %s\n"
+ "Use Dual Core: %s\n"
+ "DSP Thread: %s\n"
+ "Skip Idle: %s\n"
+ "Lock Threads: %s\n"
+ "Use Dual Core: %s\n"
+ "Default GCM: %s\n"
+ "DVD Root: %s\n"
+ "Optimize Quantizers: %s\n"
+ "Enable Cheats: %s\n"
+ "Selected Language: %d\n"
+ "Memcard A: %s\n"
+ "Memcard B: %s\n"
+ "Slot A: %d\n"
+ "Slot B: %d\n"
+ "Serial Port 1: %d\n"
+ "Run Compare Server: %s\n"
+ "Run Compare Client: %s\n"
+ "TLB Hack: %s\n"
+ "Frame Limit: %d\n"
+ "[Wii]Widescreen: %s\n"
+ "[Wii]Progressive Scan: %s\n",
+ Core::GetStartupParameter().bHLEBios?"True":"False",
+ Core::GetStartupParameter().bUseJIT?"True":"False",
+ Core::GetStartupParameter().bUseDualCore?"True":"False",
+ Core::GetStartupParameter().bDSPThread?"True":"False",
+ Core::GetStartupParameter().bSkipIdle?"True":"False",
+ Core::GetStartupParameter().bLockThreads?"True":"False",
+ Core::GetStartupParameter().bUseDualCore?"True":"False",
+ Core::GetStartupParameter().m_strDefaultGCM.c_str(),
+ Core::GetStartupParameter().m_strDVDRoot.c_str(),
+ Core::GetStartupParameter().bOptimizeQuantizers?"True":"False",
+ Core::GetStartupParameter().bEnableCheats?"True":"False",
+ Core::GetStartupParameter().SelectedLanguage, //FIXME show language based on index
+ SConfig::GetInstance().m_strMemoryCardA.c_str(),
+ SConfig::GetInstance().m_strMemoryCardB.c_str(),
+ SConfig::GetInstance().m_EXIDevice[0], //FIXME
+ SConfig::GetInstance().m_EXIDevice[1], //FIXME
+ SConfig::GetInstance().m_EXIDevice[2], //FIXME
+ Core::GetStartupParameter().bRunCompareServer?"True":"False",
+ Core::GetStartupParameter().bRunCompareClient?"True":"False",
+ Core::GetStartupParameter().iTLBHack?"True":"False",
+ SConfig::GetInstance().m_Framelimit*5,
+ Core::GetStartupParameter().bWidescreen?"True":"False",
+ Core::GetStartupParameter().bProgressiveScan?"True":"False"
+ );
+}
+
+std::string Summarize_CPU()
+{
+ return StringFromFormat(
+ "Processor Information: \n%s\n",
+ cpu_info.Summarize().c_str()
+ );
+}
+
+std::string Summarize_Drives()
+{
+ char ** drives = cdio_get_devices();
+ std::string drive;
+ for (int i = 0; drives[i] != NULL && i < 24; i++)
+ {
+
+ drive += StringFromFormat(
+ "CD/DVD Drive%d: %s\n",
+ i+1,
+ drives[i]
+ );
+ }
+ return drive;
+}
+
#endif //__SUMMARIZE_H__ \ No newline at end of file
diff --git a/Source/Core/DolphinWX/resources/Dolphin.xpm b/Source/Core/DolphinWX/resources/Dolphin.xpm
index 229eeb0a6a..8d3df77781 100644
--- a/Source/Core/DolphinWX/resources/Dolphin.xpm
+++ b/Source/Core/DolphinWX/resources/Dolphin.xpm
@@ -1,129 +1,129 @@
-/* XPM */
-static const char *Dolphin_xpm[] = {
-"32 32 94 2",
-" c None",
-". c #000000",
-"+ c #1A496C",
-"@ c #091A27",
-"# c #3AA4F0",
-"$ c #3AA3EF",
-"% c #3CA1EA",
-"& c #1A4A6D",
-"* c #3AA2ED",
-"= c #F7FAFA",
-"- c #FFFFFF",
-"; c #FDFDFD",
-"> c #49A1E0",
-", c #3BA2EC",
-"' c #FBFDFC",
-") c #FEFFFD",
-"! c #4EA3E0",
-"~ c #3DA1E9",
-"{ c #D1E1EB",
-"] c #8ABBDE",
-"^ c #F2F6F7",
-"/ c #FAFBFC",
-"( c #CEDEEA",
-"_ c #E5EEF2",
-": c #BBD2E1",
-"< c #B3CFE5",
-"[ c #FFFFFE",
-"} c #FEFFFE",
-"| c #E8F0F3",
-"1 c #E4ECF1",
-"2 c #E5EDF0",
-"3 c #E9F0F3",
-"4 c #FEFEFE",
-"5 c #F9FBFB",
-"6 c #B0CCE0",
-"7 c #FEFEFF",
-"8 c #F9FAFB",
-"9 c #43A1E4",
-"0 c #EFF3F6",
-"a c #F0F5F7",
-"b c #97C1DE",
-"c c #FEFEFD",
-"d c #FDFDFC",
-"e c #97BEDB",
-"f c #FBFCFC",
-"g c #EDF3F6",
-"h c #6EADDA",
-"i c #F3F6F8",
-"j c #3BA1EA",
-"k c #6EADDB",
-"l c #F4F8F9",
-"m c #F1F6F7",
-"n c #3FA1E7",
-"o c #9BC1DD",
-"p c #FCFDFC",
-"q c #FBFDFB",
-"r c #B9D1E1",
-"s c #E0EBF2",
-"t c #D3E3EF",
-"u c #FFFEFE",
-"v c #F2F7F7",
-"w c #D5E4F0",
-"x c #F6F9F9",
-"y c #BDD5E5",
-"z c #EBF1F4",
-"A c #DEEAF2",
-"B c #AAC9DE",
-"C c #FEFFFF",
-"D c #EFF4F6",
-"E c #F8FAFB",
-"F c #A0C4E1",
-"G c #D6E5F0",
-"H c #FAFCFC",
-"I c #BDD5E7",
-"J c #EEF3F7",
-"K c #F3F7FA",
-"L c #C7D8E4",
-"M c #CDDEEC",
-"N c #DAE6ED",
-"O c #9AC2DF",
-"P c #E8EFF4",
-"Q c #ACCDE3",
-"R c #8DBBDC",
-"S c #D5E3EB",
-"T c #FDFFFE",
-"U c #FCFDFD",
-"V c #FEFDFD",
-"W c #F7F9FA",
-"X c #FDFEFD",
-"Y c #E7EFF4",
-"Z c #A4C7E0",
-"` c #F9FDFB",
-" . c #F6FBFC",
-".. c #B8D1E3",
-" . . + . . . . . . . . . . . . . . . . . . . . . . . . ",
-". @ . . # # # # # # # # # # # # # # # # # # # # # # # # . . ",
-". . # # # # # # # # # # # # $ . . . . . % # # # # # # # # # . ",
-"& . # # # # # # # # # # # * . = - - - ; . > # # # # # # # # . ",
-". # # # # # # # # # # # , . ' ) - - - - ) . ! # # # # # # # # . ",
-". # # # # # # $ . . # $ . ; - - - - - - - - . ~ # # # # # # # . ",
-". # # # # . . . { ] . . ^ ) - - - - - - - - / . # # # # # # # . ",
-". # # # . ( _ . : < . . [ } - - - - - - - - [ . # # # # # # # . ",
-". # # # # . | 1 2 3 . . 4 - - - - - - - - - 5 . $ # # # # # # . ",
-". # # # # . 6 [ } 7 . . 4 - - - - - - - - - 8 . 9 # # # # # # . ",
-". # # # # . 0 } - - - - - - - - - - - - - - - 4 . # # # # # # . ",
-". # # # # . a ) - [ - - - - - - - - - - - - - ; . # # # # # # . ",
-". # # # # . b = c 4 - - - - - - - - - - - - d . ~ # # # # # # . ",
-". # # # # # . . . e f - - - - - - - - - - g . , # # # # # # # . ",
-". # # # # # # # # . h i - - - - - - - - ) . j # # # # # # # # . ",
-". # # # # # # # # # . k l - - - - - - - } m . n # # # # # # # . ",
-". # # # # # # # # # # . o } - - - - - - - - p . , # # # # # # . ",
-". # # # # # # # # # # $ . } - - - - - - - - 4 q . # # # # # # . ",
-". # # # # # # # # # # . r - - - - - - - - - } 4 s . # # # # # . ",
-". # # # # # # # # # # . t - - - - - - - - - u v . # # # # # # . ",
-". # # # # # # # # # # . w - - - - - - - - - x . # # # # # # # . ",
-". # # # # # # # # # # . y [ - - - - - - - - z . # # # # # # # . ",
-". # # # # # # # # # # $ . ) - - [ - - - - - A . # # # # # # # . ",
-". # # # # # # # # # # . B C - - [ D E - - - F . # # # # # # # . ",
-". # # # # # # # # # # . G - - - H . I - - J . # # # # # # # # . ",
-". # # # # # # # # # # . K - - - L . M - [ N . # # # # # # # # . ",
-". # # # # # # # # # . O - - - - . . P - - 5 Q . $ # # # # # # . ",
-". # # # # # # # # . R q - - - - . . i - - - 7 l . # # # # # # . ",
-" . # # # # # # # . S T [ [ U V . . 5 W ; - X Y . # # # # # . ",
-" . # # # # # # # . Z ` .... . ~ , . . . . . . # # # # # # . ",
-" . . # # # # # # . . . . # # # # # # # # # # # # # # . . ",
-" . . . . . . . . . . . . . . . . . . . . . . . . "};
+/* XPM */
+static const char *Dolphin_xpm[] = {
+"32 32 94 2",
+" c None",
+". c #000000",
+"+ c #1A496C",
+"@ c #091A27",
+"# c #3AA4F0",
+"$ c #3AA3EF",
+"% c #3CA1EA",
+"& c #1A4A6D",
+"* c #3AA2ED",
+"= c #F7FAFA",
+"- c #FFFFFF",
+"; c #FDFDFD",
+"> c #49A1E0",
+", c #3BA2EC",
+"' c #FBFDFC",
+") c #FEFFFD",
+"! c #4EA3E0",
+"~ c #3DA1E9",
+"{ c #D1E1EB",
+"] c #8ABBDE",
+"^ c #F2F6F7",
+"/ c #FAFBFC",
+"( c #CEDEEA",
+"_ c #E5EEF2",
+": c #BBD2E1",
+"< c #B3CFE5",
+"[ c #FFFFFE",
+"} c #FEFFFE",
+"| c #E8F0F3",
+"1 c #E4ECF1",
+"2 c #E5EDF0",
+"3 c #E9F0F3",
+"4 c #FEFEFE",
+"5 c #F9FBFB",
+"6 c #B0CCE0",
+"7 c #FEFEFF",
+"8 c #F9FAFB",
+"9 c #43A1E4",
+"0 c #EFF3F6",
+"a c #F0F5F7",
+"b c #97C1DE",
+"c c #FEFEFD",
+"d c #FDFDFC",
+"e c #97BEDB",
+"f c #FBFCFC",
+"g c #EDF3F6",
+"h c #6EADDA",
+"i c #F3F6F8",
+"j c #3BA1EA",
+"k c #6EADDB",
+"l c #F4F8F9",
+"m c #F1F6F7",
+"n c #3FA1E7",
+"o c #9BC1DD",
+"p c #FCFDFC",
+"q c #FBFDFB",
+"r c #B9D1E1",
+"s c #E0EBF2",
+"t c #D3E3EF",
+"u c #FFFEFE",
+"v c #F2F7F7",
+"w c #D5E4F0",
+"x c #F6F9F9",
+"y c #BDD5E5",
+"z c #EBF1F4",
+"A c #DEEAF2",
+"B c #AAC9DE",
+"C c #FEFFFF",
+"D c #EFF4F6",
+"E c #F8FAFB",
+"F c #A0C4E1",
+"G c #D6E5F0",
+"H c #FAFCFC",
+"I c #BDD5E7",
+"J c #EEF3F7",
+"K c #F3F7FA",
+"L c #C7D8E4",
+"M c #CDDEEC",
+"N c #DAE6ED",
+"O c #9AC2DF",
+"P c #E8EFF4",
+"Q c #ACCDE3",
+"R c #8DBBDC",
+"S c #D5E3EB",
+"T c #FDFFFE",
+"U c #FCFDFD",
+"V c #FEFDFD",
+"W c #F7F9FA",
+"X c #FDFEFD",
+"Y c #E7EFF4",
+"Z c #A4C7E0",
+"` c #F9FDFB",
+" . c #F6FBFC",
+".. c #B8D1E3",
+" . . + . . . . . . . . . . . . . . . . . . . . . . . . ",
+". @ . . # # # # # # # # # # # # # # # # # # # # # # # # . . ",
+". . # # # # # # # # # # # # $ . . . . . % # # # # # # # # # . ",
+"& . # # # # # # # # # # # * . = - - - ; . > # # # # # # # # . ",
+". # # # # # # # # # # # , . ' ) - - - - ) . ! # # # # # # # # . ",
+". # # # # # # $ . . # $ . ; - - - - - - - - . ~ # # # # # # # . ",
+". # # # # . . . { ] . . ^ ) - - - - - - - - / . # # # # # # # . ",
+". # # # . ( _ . : < . . [ } - - - - - - - - [ . # # # # # # # . ",
+". # # # # . | 1 2 3 . . 4 - - - - - - - - - 5 . $ # # # # # # . ",
+". # # # # . 6 [ } 7 . . 4 - - - - - - - - - 8 . 9 # # # # # # . ",
+". # # # # . 0 } - - - - - - - - - - - - - - - 4 . # # # # # # . ",
+". # # # # . a ) - [ - - - - - - - - - - - - - ; . # # # # # # . ",
+". # # # # . b = c 4 - - - - - - - - - - - - d . ~ # # # # # # . ",
+". # # # # # . . . e f - - - - - - - - - - g . , # # # # # # # . ",
+". # # # # # # # # . h i - - - - - - - - ) . j # # # # # # # # . ",
+". # # # # # # # # # . k l - - - - - - - } m . n # # # # # # # . ",
+". # # # # # # # # # # . o } - - - - - - - - p . , # # # # # # . ",
+". # # # # # # # # # # $ . } - - - - - - - - 4 q . # # # # # # . ",
+". # # # # # # # # # # . r - - - - - - - - - } 4 s . # # # # # . ",
+". # # # # # # # # # # . t - - - - - - - - - u v . # # # # # # . ",
+". # # # # # # # # # # . w - - - - - - - - - x . # # # # # # # . ",
+". # # # # # # # # # # . y [ - - - - - - - - z . # # # # # # # . ",
+". # # # # # # # # # # $ . ) - - [ - - - - - A . # # # # # # # . ",
+". # # # # # # # # # # . B C - - [ D E - - - F . # # # # # # # . ",
+". # # # # # # # # # # . G - - - H . I - - J . # # # # # # # # . ",
+". # # # # # # # # # # . K - - - L . M - [ N . # # # # # # # # . ",
+". # # # # # # # # # . O - - - - . . P - - 5 Q . $ # # # # # # . ",
+". # # # # # # # # . R q - - - - . . i - - - 7 l . # # # # # # . ",
+" . # # # # # # # . S T [ [ U V . . 5 W ; - X Y . # # # # # . ",
+" . # # # # # # # . Z ` .... . ~ , . . . . . . # # # # # # . ",
+" . . # # # # # # . . . . # # # # # # # # # # # # # # . . ",
+" . . . . . . . . . . . . . . . . . . . . . . . . "};
diff --git a/Source/Core/DolphinWX/resources/Flag_Europe.xpm b/Source/Core/DolphinWX/resources/Flag_Europe.xpm
index 49ff790a9f..def46811a6 100644
--- a/Source/Core/DolphinWX/resources/Flag_Europe.xpm
+++ b/Source/Core/DolphinWX/resources/Flag_Europe.xpm
@@ -1,83 +1,83 @@
-/* XPM */
-static const char *const Flag_Europe_xpm[] = {
-"96 32 48 1",
-" c None",
-". c #000000",
-"+ c #0000FD",
-"@ c #0000FF",
-"# c #0808F7",
-"$ c #5C5CA3",
-"% c #1717E8",
-"& c #767680",
-"* c #EDED00",
-"= c #A5A54D",
-"- c #2E2EB9",
-"; c #96961A",
-"> c #4A4A8E",
-", c #0000FB",
-"' c #0000F4",
-") c #0808EC",
-"! c #5C5C9B",
-"~ c #1717DD",
-"{ c #0000EE",
-"] c #767677",
-"^ c #A5A547",
-"/ c #0000DD",
-"( c #2E2EA0",
-"_ c #969616",
-": c #4A4A7B",
-"< c #0000D2",
-"[ c #0000C6",
-"} c #0808BF",
-"| c #5C5C7E",
-"1 c #1717B4",
-"2 c #0000B9",
-"3 c #76765C",
-"4 c #A5A537",
-"5 c #0808B3",
-"6 c #5C5C76",
-"7 c #1717A8",
-"8 c #0000A9",
-"9 c #2E2E7A",
-"0 c #969611",
-"a c #4A4A5E",
-"b c #767654",
-"c c #A5A533",
-"d c #000097",
-"e c #2E2E6D",
-"f c #96960F",
-"g c #4A4A54",
-"h c #000081",
-"i c #000077",
-" ",
-" ",
-" ",
-" ",
-" ",
-"................................ ",
-".++++++++++++++++++++++++++++++. ",
-".@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@. ",
-".@@@@@@@@@@@@@#$%@@@@@@@@@@@@@@. ",
-".@@@@@@@@@#$%@&*=@#$%@@@@@@@@@@. ",
-".@@@@@@@@@&*=@-;>@&*=@@@@@@@@@@. ",
-".@@@@@@@@@-;>@@@@@-;>@@@@@@@@@@. ",
-".,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,. ",
-".''''''')!~''''''''')!~''''''''. ",
-".{{{{{{{]*^{{{{{{{{{]*^{{{{{{{{. ",
-".///////(_://///////(_:////////. ",
-".<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<. ",
-".[[[[[[[[[}|1[[[[[}|1[[[[[[[[[[. ",
-".2222222223*4256723*42222222222. ",
-".88888888890a8b*c890a8888888888. ",
-".dddddddddddddefgdddddddddddddd. ",
-".hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh. ",
-".iiiiiiiiiiiiiiiiiiiiiiiiiiiiii. ",
-".iiiiiiiiiiiiiiiiiiiiiiiiiiiiii. ",
-"................................ ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" "};
+/* XPM */
+static const char *const Flag_Europe_xpm[] = {
+"96 32 48 1",
+" c None",
+". c #000000",
+"+ c #0000FD",
+"@ c #0000FF",
+"# c #0808F7",
+"$ c #5C5CA3",
+"% c #1717E8",
+"& c #767680",
+"* c #EDED00",
+"= c #A5A54D",
+"- c #2E2EB9",
+"; c #96961A",
+"> c #4A4A8E",
+", c #0000FB",
+"' c #0000F4",
+") c #0808EC",
+"! c #5C5C9B",
+"~ c #1717DD",
+"{ c #0000EE",
+"] c #767677",
+"^ c #A5A547",
+"/ c #0000DD",
+"( c #2E2EA0",
+"_ c #969616",
+": c #4A4A7B",
+"< c #0000D2",
+"[ c #0000C6",
+"} c #0808BF",
+"| c #5C5C7E",
+"1 c #1717B4",
+"2 c #0000B9",
+"3 c #76765C",
+"4 c #A5A537",
+"5 c #0808B3",
+"6 c #5C5C76",
+"7 c #1717A8",
+"8 c #0000A9",
+"9 c #2E2E7A",
+"0 c #969611",
+"a c #4A4A5E",
+"b c #767654",
+"c c #A5A533",
+"d c #000097",
+"e c #2E2E6D",
+"f c #96960F",
+"g c #4A4A54",
+"h c #000081",
+"i c #000077",
+" ",
+" ",
+" ",
+" ",
+" ",
+"................................ ",
+".++++++++++++++++++++++++++++++. ",
+".@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@. ",
+".@@@@@@@@@@@@@#$%@@@@@@@@@@@@@@. ",
+".@@@@@@@@@#$%@&*=@#$%@@@@@@@@@@. ",
+".@@@@@@@@@&*=@-;>@&*=@@@@@@@@@@. ",
+".@@@@@@@@@-;>@@@@@-;>@@@@@@@@@@. ",
+".,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,. ",
+".''''''')!~''''''''')!~''''''''. ",
+".{{{{{{{]*^{{{{{{{{{]*^{{{{{{{{. ",
+".///////(_://///////(_:////////. ",
+".<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<. ",
+".[[[[[[[[[}|1[[[[[}|1[[[[[[[[[[. ",
+".2222222223*4256723*42222222222. ",
+".88888888890a8b*c890a8888888888. ",
+".dddddddddddddefgdddddddddddddd. ",
+".hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh. ",
+".iiiiiiiiiiiiiiiiiiiiiiiiiiiiii. ",
+".iiiiiiiiiiiiiiiiiiiiiiiiiiiiii. ",
+"................................ ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
diff --git a/Source/Core/DolphinWX/resources/Flag_France.xpm b/Source/Core/DolphinWX/resources/Flag_France.xpm
index 157277efec..51cde44d8c 100644
--- a/Source/Core/DolphinWX/resources/Flag_France.xpm
+++ b/Source/Core/DolphinWX/resources/Flag_France.xpm
@@ -1,80 +1,80 @@
-/* XPM */
-static const char *const Flag_France_xpm[] = {
-"96 32 45 1",
-" c None",
-". c #000000",
-"+ c #0000FF",
-"@ c #FFFFFF",
-"# c #FF0000",
-"$ c #0000FC",
-"% c #0000F8",
-"& c #FCFCFC",
-"* c #FC0000",
-"= c #0000F2",
-"- c #F8F8F8",
-"; c #F80000",
-"> c #0000EC",
-", c #F2F2F2",
-"' c #F20000",
-") c #0000E3",
-"! c #ECECEC",
-"~ c #EC0000",
-"{ c #0000DB",
-"] c #E3E3E3",
-"^ c #E30000",
-"/ c #0000D2",
-"( c #DBDBDB",
-"_ c #DB0000",
-": c #0000C8",
-"< c #D2D2D2",
-"[ c #D20000",
-"} c #0000BD",
-"| c #C8C8C8",
-"1 c #C80000",
-"2 c #0000B1",
-"3 c #BDBDBD",
-"4 c #BD0000",
-"5 c #0000A3",
-"6 c #B1B1B1",
-"7 c #B10000",
-"8 c #000093",
-"9 c #A3A3A3",
-"0 c #A30000",
-"a c #000080",
-"b c #939393",
-"c c #930000",
-"d c #000077",
-"e c #808080",
-"f c #800000",
-" ",
-" ",
-" ",
-" ",
-" ",
-"................................ ",
-".++++++++++@@@@@@@@@@@#########. ",
-".++++++++++@@@@@@@@@@@#########. ",
-".++++++++++@@@@@@@@@@@#########. ",
-".++++++++++@@@@@@@@@@@#########. ",
-".$$$$$$$$$$@@@@@@@@@@@#########. ",
-".%%%%%%%%%%&&&&&&&&&&&*********. ",
-".==========-----------;;;;;;;;;. ",
-".>>>>>>>>>>,,,,,,,,,,,'''''''''. ",
-".))))))))))!!!!!!!!!!!~~~~~~~~~. ",
-".{{{{{{{{{{]]]]]]]]]]]^^^^^^^^^. ",
-".//////////(((((((((((_________. ",
-".::::::::::<<<<<<<<<<<[[[[[[[[[. ",
-".}}}}}}}}}}|||||||||||111111111. ",
-".222222222233333333333444444444. ",
-".555555555566666666666777777777. ",
-".888888888899999999999000000000. ",
-".aaaaaaaaaabbbbbbbbbbbccccccccc. ",
-".ddddddddddeeeeeeeeeeefffffffff. ",
-"................................ ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" "};
+/* XPM */
+static const char *const Flag_France_xpm[] = {
+"96 32 45 1",
+" c None",
+". c #000000",
+"+ c #0000FF",
+"@ c #FFFFFF",
+"# c #FF0000",
+"$ c #0000FC",
+"% c #0000F8",
+"& c #FCFCFC",
+"* c #FC0000",
+"= c #0000F2",
+"- c #F8F8F8",
+"; c #F80000",
+"> c #0000EC",
+", c #F2F2F2",
+"' c #F20000",
+") c #0000E3",
+"! c #ECECEC",
+"~ c #EC0000",
+"{ c #0000DB",
+"] c #E3E3E3",
+"^ c #E30000",
+"/ c #0000D2",
+"( c #DBDBDB",
+"_ c #DB0000",
+": c #0000C8",
+"< c #D2D2D2",
+"[ c #D20000",
+"} c #0000BD",
+"| c #C8C8C8",
+"1 c #C80000",
+"2 c #0000B1",
+"3 c #BDBDBD",
+"4 c #BD0000",
+"5 c #0000A3",
+"6 c #B1B1B1",
+"7 c #B10000",
+"8 c #000093",
+"9 c #A3A3A3",
+"0 c #A30000",
+"a c #000080",
+"b c #939393",
+"c c #930000",
+"d c #000077",
+"e c #808080",
+"f c #800000",
+" ",
+" ",
+" ",
+" ",
+" ",
+"................................ ",
+".++++++++++@@@@@@@@@@@#########. ",
+".++++++++++@@@@@@@@@@@#########. ",
+".++++++++++@@@@@@@@@@@#########. ",
+".++++++++++@@@@@@@@@@@#########. ",
+".$$$$$$$$$$@@@@@@@@@@@#########. ",
+".%%%%%%%%%%&&&&&&&&&&&*********. ",
+".==========-----------;;;;;;;;;. ",
+".>>>>>>>>>>,,,,,,,,,,,'''''''''. ",
+".))))))))))!!!!!!!!!!!~~~~~~~~~. ",
+".{{{{{{{{{{]]]]]]]]]]]^^^^^^^^^. ",
+".//////////(((((((((((_________. ",
+".::::::::::<<<<<<<<<<<[[[[[[[[[. ",
+".}}}}}}}}}}|||||||||||111111111. ",
+".222222222233333333333444444444. ",
+".555555555566666666666777777777. ",
+".888888888899999999999000000000. ",
+".aaaaaaaaaabbbbbbbbbbbccccccccc. ",
+".ddddddddddeeeeeeeeeeefffffffff. ",
+"................................ ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
diff --git a/Source/Core/DolphinWX/resources/Flag_Japan.xpm b/Source/Core/DolphinWX/resources/Flag_Japan.xpm
index 794bbc0b78..47be025c6b 100644
--- a/Source/Core/DolphinWX/resources/Flag_Japan.xpm
+++ b/Source/Core/DolphinWX/resources/Flag_Japan.xpm
@@ -1,102 +1,102 @@
-/* XPM */
-static const char * const Flag_Japan_xpm[] = {
-"96 32 67 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-"@ c #FECACA",
-"# c #FD8080",
-"$ c #FD6161",
-"% c #FD7676",
-"& c #FEB6B6",
-"* c #FEFEFE",
-"= c #FFEDED",
-"- c #FF4C4C",
-"; c #FF0000",
-"> c #FF2F2F",
-", c #FFD7D7",
-"' c #FEF5F5",
-") c #FE2E2E",
-"! c #FE1313",
-"~ c #FEDDDD",
-"{ c #F9F9F9",
-"] c #FC7777",
-"^ c #FD4545",
-"/ c #F4F4F4",
-"( c #F4F3F3",
-"_ c #FA1313",
-": c #FB0000",
-"< c #FA0000",
-"[ c #F4D4D4",
-"} c #EFEFEF",
-"| c #EFCFCF",
-"1 c #F10000",
-"2 c #EF9F9F",
-"3 c #E4E4E4",
-"4 c #E2BEBE",
-"5 c #DD0000",
-"6 c #E19090",
-"7 c #D9D9D9",
-"8 c #D8D0D0",
-"9 c #CA0404",
-"0 c #CA0000",
-"a c #D5A9A9",
-"b c #D0D0D0",
-"c c #BC4242",
-"d c #B40000",
-"e c #B71A1A",
-"f c #CFCFCF",
-"g c #C6C6C6",
-"h c #BEA7A7",
-"i c #990808",
-"j c #980000",
-"k c #B78787",
-"l c #BBBBBB",
-"m c #A88989",
-"n c #7B0B0B",
-"o c #770000",
-"p c #780202",
-"q c #9E6B6B",
-"r c #AEAEAE",
-"s c #A89C9C",
-"t c #8F4E4E",
-"u c #7F1B1B",
-"v c #7A0A0A",
-"w c #7D1515",
-"x c #8B4242",
-"y c #A48F8F",
-"z c #A0A0A0",
-"A c #8F8F8F",
-"B c #7C7C7C",
-" ",
-" ",
-" ",
-" ",
-" ",
-"................................ ",
-".++++++++++++++++++++++++++++++. ",
-".++++++++++++++++++++++++++++++. ",
-".++++++++++++++++++++++++++++++. ",
-".++++++++++++@#$%&*++++++++++++. ",
-".++++++++++=-;;;;;>,+++++++++++. ",
-".*********');;;;;;;!~**********. ",
-".{{{{{{{{{];;;;;;;;;^{{{{{{{{{{. ",
-".////////(_:::::::::<[/////////. ",
-".}}}}}}}}|111111111112}}}}}}}}}. ",
-".333333334555555555556333333333. ",
-".77777777890000000000a777777777. ",
-".bbbbbbbbbcdddddddddefbbbbbbbbb. ",
-".ggggggggghijjjjjjjjkgggggggggg. ",
-".llllllllllmnooooopqlllllllllll. ",
-".rrrrrrrrrrrstuvwxyrrrrrrrrrrrr. ",
-".zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz. ",
-".AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA. ",
-".BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB. ",
-"................................ ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" "};
+/* XPM */
+static const char * const Flag_Japan_xpm[] = {
+"96 32 67 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+"@ c #FECACA",
+"# c #FD8080",
+"$ c #FD6161",
+"% c #FD7676",
+"& c #FEB6B6",
+"* c #FEFEFE",
+"= c #FFEDED",
+"- c #FF4C4C",
+"; c #FF0000",
+"> c #FF2F2F",
+", c #FFD7D7",
+"' c #FEF5F5",
+") c #FE2E2E",
+"! c #FE1313",
+"~ c #FEDDDD",
+"{ c #F9F9F9",
+"] c #FC7777",
+"^ c #FD4545",
+"/ c #F4F4F4",
+"( c #F4F3F3",
+"_ c #FA1313",
+": c #FB0000",
+"< c #FA0000",
+"[ c #F4D4D4",
+"} c #EFEFEF",
+"| c #EFCFCF",
+"1 c #F10000",
+"2 c #EF9F9F",
+"3 c #E4E4E4",
+"4 c #E2BEBE",
+"5 c #DD0000",
+"6 c #E19090",
+"7 c #D9D9D9",
+"8 c #D8D0D0",
+"9 c #CA0404",
+"0 c #CA0000",
+"a c #D5A9A9",
+"b c #D0D0D0",
+"c c #BC4242",
+"d c #B40000",
+"e c #B71A1A",
+"f c #CFCFCF",
+"g c #C6C6C6",
+"h c #BEA7A7",
+"i c #990808",
+"j c #980000",
+"k c #B78787",
+"l c #BBBBBB",
+"m c #A88989",
+"n c #7B0B0B",
+"o c #770000",
+"p c #780202",
+"q c #9E6B6B",
+"r c #AEAEAE",
+"s c #A89C9C",
+"t c #8F4E4E",
+"u c #7F1B1B",
+"v c #7A0A0A",
+"w c #7D1515",
+"x c #8B4242",
+"y c #A48F8F",
+"z c #A0A0A0",
+"A c #8F8F8F",
+"B c #7C7C7C",
+" ",
+" ",
+" ",
+" ",
+" ",
+"................................ ",
+".++++++++++++++++++++++++++++++. ",
+".++++++++++++++++++++++++++++++. ",
+".++++++++++++++++++++++++++++++. ",
+".++++++++++++@#$%&*++++++++++++. ",
+".++++++++++=-;;;;;>,+++++++++++. ",
+".*********');;;;;;;!~**********. ",
+".{{{{{{{{{];;;;;;;;;^{{{{{{{{{{. ",
+".////////(_:::::::::<[/////////. ",
+".}}}}}}}}|111111111112}}}}}}}}}. ",
+".333333334555555555556333333333. ",
+".77777777890000000000a777777777. ",
+".bbbbbbbbbcdddddddddefbbbbbbbbb. ",
+".ggggggggghijjjjjjjjkgggggggggg. ",
+".llllllllllmnooooopqlllllllllll. ",
+".rrrrrrrrrrrstuvwxyrrrrrrrrrrrr. ",
+".zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz. ",
+".AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA. ",
+".BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB. ",
+"................................ ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
diff --git a/Source/Core/DolphinWX/resources/Flag_Taiwan.xpm b/Source/Core/DolphinWX/resources/Flag_Taiwan.xpm
index 6696789270..2dbb119f81 100644
--- a/Source/Core/DolphinWX/resources/Flag_Taiwan.xpm
+++ b/Source/Core/DolphinWX/resources/Flag_Taiwan.xpm
@@ -1,124 +1,124 @@
-/* XPM */
-static const char * Flag_Taiwan_xpm[] = {
-"96 32 89 1",
-" c None",
-". c #000000",
-"# c #000099",
-"$ c #000098",
-"% c #03039A",
-"& c #000094",
-"' c #05059B",
-"( c #050095",
-") c #DC0014",
-"* c #FF0000",
-"+ c #FD0001",
-", c #04049B",
-"- c #000096",
-"! c #020299",
-"0 c #2424A7",
-"1 c #04049A",
-"2 c #000097",
-"3 c #000093",
-"4 c #6262BF",
-"5 c #2828A8",
-"6 c #6C6CC1",
-"7 c #3E3EB1",
-"8 c #3B3BB0",
-"9 c #00008F",
-": c #01019A",
-"; c #1919A3",
-"< c #4040B0",
-"= c #6363C0",
-"> c #D6D6EE",
-"? c #D9D9ED",
-"@ c #C5C5E7",
-"A c #3F3FB0",
-"B c #3D3DAF",
-"C c #020297",
-"D c #010199",
-"E c #5E5EBE",
-"F c #DFDFF2",
-"G c white",
-"H c #BFBFE5",
-"I c #2626A7",
-"J c #4242B0",
-"K c #7D7DCA",
-"L c #FAFAFD",
-"M c #FBFBFD",
-"N c #FCFCFD",
-"O c #FCFCFE",
-"P c #DADAF0",
-"Q c #6A6AC2",
-"R c #1B1BA3",
-"S c #000199",
-"T c #0E0E9B",
-"U c #5858BC",
-"V c #D3D3ED",
-"W c #2727A6",
-"X c #060699",
-"Y c #1212A0",
-"Z c #6464C0",
-"[ c #8080CC",
-"] c #F4F4FA",
-"^ c #F8F8FB",
-"_ c #7070C4",
-"` c #4949B5",
-"a c #000095",
-"b c #040499",
-"c c #000092",
-"d c #6767C2",
-"e c #8686CA",
-"f c #7070C5",
-"g c #2B2BA9",
-"h c #00009A",
-"i c #01049C",
-"j c #1619A4",
-"k c #393CB3",
-"l c #00029A",
-"m c #1619A5",
-"n c #020096",
-"o c #DB0014",
-"p c #FC0001",
-"q c #0A0092",
-"r c #060090",
-"s c #0B0092",
-"t c #0F008E",
-"u c #DD0013",
-"v c #FD0000",
-"w c #E5000F",
-"x c #E6010F",
-"y c #E60110",
-"z c #FB0002",
-"{ c #FE0000",
-" ",
-" ",
-" ",
-" ",
-" ",
-"................................ ",
-".#####$%#&'$$$##()*+***********. ",
-".###$$,-!0&1!$##()*+***********. ",
-".##$#23456789:$#()*+***********. ",
-".###2;<=>?@ABCD#()*+***********. ",
-".###$CEFGGGHI&D$()*+***********. ",
-".##D-JKLMNOPQR-S()*+***********. ",
-".###$TUGGNGVWX$#()*+***********. ",
-".###2YZ[]^P_`aD$()*+***********. ",
-".###$bcdEefg3D$#()*+***********. ",
-".hhhhhijiklm#hhhno*p***********. ",
-".qqqqqqrsrqrqqqqtu*v***********. ",
-".wwwwwwxwywxwwwwwz*{***********. ",
-".******************************. ",
-".{{{{{{{{{{{{{{{{{*{***********. ",
-".******************************. ",
-".******************************. ",
-".******************************. ",
-".******************************. ",
-"................................ ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
+/* XPM */
+static const char * Flag_Taiwan_xpm[] = {
+"96 32 89 1",
+" c None",
+". c #000000",
+"# c #000099",
+"$ c #000098",
+"% c #03039A",
+"& c #000094",
+"' c #05059B",
+"( c #050095",
+") c #DC0014",
+"* c #FF0000",
+"+ c #FD0001",
+", c #04049B",
+"- c #000096",
+"! c #020299",
+"0 c #2424A7",
+"1 c #04049A",
+"2 c #000097",
+"3 c #000093",
+"4 c #6262BF",
+"5 c #2828A8",
+"6 c #6C6CC1",
+"7 c #3E3EB1",
+"8 c #3B3BB0",
+"9 c #00008F",
+": c #01019A",
+"; c #1919A3",
+"< c #4040B0",
+"= c #6363C0",
+"> c #D6D6EE",
+"? c #D9D9ED",
+"@ c #C5C5E7",
+"A c #3F3FB0",
+"B c #3D3DAF",
+"C c #020297",
+"D c #010199",
+"E c #5E5EBE",
+"F c #DFDFF2",
+"G c white",
+"H c #BFBFE5",
+"I c #2626A7",
+"J c #4242B0",
+"K c #7D7DCA",
+"L c #FAFAFD",
+"M c #FBFBFD",
+"N c #FCFCFD",
+"O c #FCFCFE",
+"P c #DADAF0",
+"Q c #6A6AC2",
+"R c #1B1BA3",
+"S c #000199",
+"T c #0E0E9B",
+"U c #5858BC",
+"V c #D3D3ED",
+"W c #2727A6",
+"X c #060699",
+"Y c #1212A0",
+"Z c #6464C0",
+"[ c #8080CC",
+"] c #F4F4FA",
+"^ c #F8F8FB",
+"_ c #7070C4",
+"` c #4949B5",
+"a c #000095",
+"b c #040499",
+"c c #000092",
+"d c #6767C2",
+"e c #8686CA",
+"f c #7070C5",
+"g c #2B2BA9",
+"h c #00009A",
+"i c #01049C",
+"j c #1619A4",
+"k c #393CB3",
+"l c #00029A",
+"m c #1619A5",
+"n c #020096",
+"o c #DB0014",
+"p c #FC0001",
+"q c #0A0092",
+"r c #060090",
+"s c #0B0092",
+"t c #0F008E",
+"u c #DD0013",
+"v c #FD0000",
+"w c #E5000F",
+"x c #E6010F",
+"y c #E60110",
+"z c #FB0002",
+"{ c #FE0000",
+" ",
+" ",
+" ",
+" ",
+" ",
+"................................ ",
+".#####$%#&'$$$##()*+***********. ",
+".###$$,-!0&1!$##()*+***********. ",
+".##$#23456789:$#()*+***********. ",
+".###2;<=>?@ABCD#()*+***********. ",
+".###$CEFGGGHI&D$()*+***********. ",
+".##D-JKLMNOPQR-S()*+***********. ",
+".###$TUGGNGVWX$#()*+***********. ",
+".###2YZ[]^P_`aD$()*+***********. ",
+".###$bcdEefg3D$#()*+***********. ",
+".hhhhhijiklm#hhhno*p***********. ",
+".qqqqqqrsrqrqqqqtu*v***********. ",
+".wwwwwwxwywxwwwwwz*{***********. ",
+".******************************. ",
+".{{{{{{{{{{{{{{{{{*{***********. ",
+".******************************. ",
+".******************************. ",
+".******************************. ",
+".******************************. ",
+"................................ ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
" "}; \ No newline at end of file
diff --git a/Source/Core/DolphinWX/resources/Flag_USA.xpm b/Source/Core/DolphinWX/resources/Flag_USA.xpm
index 90ccbedd8d..0a991bd02e 100644
--- a/Source/Core/DolphinWX/resources/Flag_USA.xpm
+++ b/Source/Core/DolphinWX/resources/Flag_USA.xpm
@@ -1,65 +1,65 @@
-/* XPM */
-static const char * Flag_USA_xpm[] = {
-"96 32 30 1",
-" c None",
-". c #000000",
-"+ c #0000FF",
-"@ c #CE7070",
-"# c #B0BF99",
-"$ c #F1F1F1",
-"% c #FFFFFF",
-"& c #0000FD",
-"* c #CF8484",
-"= c #DA9090",
-"- c #0000F3",
-"; c #B0BF96",
-"> c #0000DF",
-", c #0000CB",
-"' c #B0BF8C",
-") c #D98E8E",
-"! c #0000B5",
-"~ c #CA6C6C",
-"{ c #000098",
-"] c #B0BF80",
-"^ c #000077",
-"/ c #C26464",
-"( c #DBDBDB",
-"_ c #C17676",
-": c #B55757",
-"< c #BBBBBB",
-"[ c #AC6161",
-"} c #A34545",
-"| c #8B8B8B",
-"1 c #8E4343",
-" ",
-" ",
-" ",
-" ",
-" ",
-"................................ ",
-".++++++++++++++@@@@@@@@@@@@@@@@. ",
-".+#+#+#+#+#+#++$%%%%%%%%%%%%%%%. ",
-".&&&&&&&&&&&&&&*===============. ",
-".-;-;-;-;-;-;--@@@@@@@@@@@@@@@@. ",
-".>>>>>>>>>>>>>>$%%%%%%%%%%%%%%%. ",
-".,',',',',',',,*))))))))))))))). ",
-".!!!!!!!!!!!!!!@~~~~~~~~~~~~~~~. ",
-".{]{]{]{]{]{]{{$$$$$$$$$$$$$$$$. ",
-".^^^^^^^^^^^^^^****************. ",
-".^^^^^^^^^^^^^^@///////////////. ",
-".((((((((((((((((((((((((((((((. ",
-".______________________________. ",
-".::::::::::::::::::::::::::::::. ",
-".<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<. ",
-".[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[. ",
-".}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}. ",
-".||||||||||||||||||||||||||||||. ",
-".111111111111111111111111111111. ",
-"................................ ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" "};
+/* XPM */
+static const char * Flag_USA_xpm[] = {
+"96 32 30 1",
+" c None",
+". c #000000",
+"+ c #0000FF",
+"@ c #CE7070",
+"# c #B0BF99",
+"$ c #F1F1F1",
+"% c #FFFFFF",
+"& c #0000FD",
+"* c #CF8484",
+"= c #DA9090",
+"- c #0000F3",
+"; c #B0BF96",
+"> c #0000DF",
+", c #0000CB",
+"' c #B0BF8C",
+") c #D98E8E",
+"! c #0000B5",
+"~ c #CA6C6C",
+"{ c #000098",
+"] c #B0BF80",
+"^ c #000077",
+"/ c #C26464",
+"( c #DBDBDB",
+"_ c #C17676",
+": c #B55757",
+"< c #BBBBBB",
+"[ c #AC6161",
+"} c #A34545",
+"| c #8B8B8B",
+"1 c #8E4343",
+" ",
+" ",
+" ",
+" ",
+" ",
+"................................ ",
+".++++++++++++++@@@@@@@@@@@@@@@@. ",
+".+#+#+#+#+#+#++$%%%%%%%%%%%%%%%. ",
+".&&&&&&&&&&&&&&*===============. ",
+".-;-;-;-;-;-;--@@@@@@@@@@@@@@@@. ",
+".>>>>>>>>>>>>>>$%%%%%%%%%%%%%%%. ",
+".,',',',',',',,*))))))))))))))). ",
+".!!!!!!!!!!!!!!@~~~~~~~~~~~~~~~. ",
+".{]{]{]{]{]{]{{$$$$$$$$$$$$$$$$. ",
+".^^^^^^^^^^^^^^****************. ",
+".^^^^^^^^^^^^^^@///////////////. ",
+".((((((((((((((((((((((((((((((. ",
+".______________________________. ",
+".::::::::::::::::::::::::::::::. ",
+".<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<. ",
+".[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[. ",
+".}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}. ",
+".||||||||||||||||||||||||||||||. ",
+".111111111111111111111111111111. ",
+"................................ ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
diff --git a/Source/Core/VideoCommon/Src/AVIDump.cpp b/Source/Core/VideoCommon/Src/AVIDump.cpp
index 3447efbacf..acb4fde624 100644
--- a/Source/Core/VideoCommon/Src/AVIDump.cpp
+++ b/Source/Core/VideoCommon/Src/AVIDump.cpp
@@ -1,179 +1,179 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "AVIDump.h"
-#include "tchar.h"
-
-#include <cstdio>
-#include <cstring>
-#include <vfw.h>
-#include <winerror.h>
-
-#include "FileUtil.h"
-#include "CommonPaths.h"
-#include "Log.h"
-
-static HWND m_emuWnd;
-static int m_width;
-static int m_height;
-static LONG m_byteBuffer;
-static LONG m_frameCount;
-static LONG m_totalBytes;
-static PAVIFILE m_file;
-static int m_fileCount;
-static PAVISTREAM m_stream;
-static PAVISTREAM m_streamCompressed;
-static AVISTREAMINFO m_header;
-static AVICOMPRESSOPTIONS m_options;
-static AVICOMPRESSOPTIONS *m_arrayOptions[1];
-static BITMAPINFOHEADER m_bitmap;
-
-bool AVIDump::Start(HWND hWnd, int w, int h)
-{
- m_emuWnd = hWnd;
- m_fileCount = 0;
-
- m_width = w;
- m_height = h;
-
- return CreateFile();
-}
-
-bool AVIDump::CreateFile()
-{
- m_totalBytes = 0;
- m_frameCount = 0;
- char movie_file_name[255];
- sprintf(movie_file_name, "%s/framedump%d.avi", FULL_FRAMES_DIR, m_fileCount);
- // Create path
- File::CreateFullPath(movie_file_name);
-
- // Ask to delete file
- if (File::Exists(movie_file_name))
- {
- if (AskYesNo("Delete the existing file '%s'?", movie_file_name))
- File::Delete(movie_file_name);
- }
-
- AVIFileInit();
- NOTICE_LOG(VIDEO, "Opening AVI file (%s) for dumping", movie_file_name);
- // TODO: Make this work with AVIFileOpenW without it throwing REGDB_E_CLASSNOTREG
- HRESULT hr = AVIFileOpenA(&m_file, movie_file_name, OF_WRITE | OF_CREATE, NULL);
- if (FAILED(hr)) {
- if (hr == AVIERR_BADFORMAT) NOTICE_LOG(VIDEO, "The file couldn't be read, indicating a corrupt file or an unrecognized format.");
- if (hr == AVIERR_MEMORY) NOTICE_LOG(VIDEO, "The file could not be opened because of insufficient memory.");
- if (hr == AVIERR_FILEREAD) NOTICE_LOG(VIDEO, "A disk error occurred while reading the file.");
- if (hr == AVIERR_FILEOPEN) NOTICE_LOG(VIDEO, "A disk error occurred while opening the file.");
- if (hr == REGDB_E_CLASSNOTREG) NOTICE_LOG(VIDEO, "AVI class not registered");
- Stop();
- return false;
- }
- SetBitmapFormat();
- NOTICE_LOG(VIDEO, "Setting video format...");
- if (!SetVideoFormat()) {
- NOTICE_LOG(VIDEO, "Setting video format failed");
- Stop();
- return false;
- }
- if (!m_fileCount) {
- if (!SetCompressionOptions()) {
- NOTICE_LOG(VIDEO, "SetCompressionOptions failed");
- Stop();
- return false;
- }
- }
- if (FAILED(AVIMakeCompressedStream(&m_streamCompressed, m_stream, &m_options, NULL))) {
- NOTICE_LOG(VIDEO, "AVIMakeCompressedStream failed");
- Stop();
- return false;
- }
- if (FAILED(AVIStreamSetFormat(m_streamCompressed, 0, &m_bitmap, m_bitmap.biSize))) {
- NOTICE_LOG(VIDEO, "AVIStreamSetFormat failed");
- Stop();
- return false;
- }
-
- return true;
-}
-
-void AVIDump::CloseFile()
-{
- if (m_streamCompressed) {
- AVIStreamClose(m_streamCompressed);
- m_streamCompressed = NULL;
- }
- if (m_stream) {
- AVIStreamClose(m_stream);
- m_stream = NULL;
- }
- if (m_file) {
- AVIFileRelease(m_file);
- m_file = NULL;
- }
- AVIFileExit();
-}
-
-void AVIDump::Stop()
-{
- CloseFile();
- m_fileCount = 0;
- NOTICE_LOG(VIDEO, "Stop");
-}
-
-void AVIDump::AddFrame(char *data)
-{
- AVIStreamWrite(m_streamCompressed, ++m_frameCount, 1, (LPVOID) data, m_bitmap.biSizeImage, AVIIF_KEYFRAME, NULL, &m_byteBuffer);
- m_totalBytes += m_byteBuffer;
- // Close the recording if the file is more than 2gb
- // VfW can't properly save files over 2gb in size, but can keep writing to them up to 4gb.
- if (m_totalBytes >= 2000000000) {
- CloseFile();
- m_fileCount++;
- CreateFile();
- }
-}
-
-void AVIDump::SetBitmapFormat()
-{
- memset(&m_bitmap, 0, sizeof(m_bitmap));
- m_bitmap.biSize = 0x28;
- m_bitmap.biPlanes = 1;
- m_bitmap.biBitCount = 24;
- m_bitmap.biWidth = m_width;
- m_bitmap.biHeight = m_height;
- m_bitmap.biSizeImage = 3 * m_width * m_height;
-}
-
-bool AVIDump::SetCompressionOptions()
-{
- memset(&m_options, 0, sizeof(m_options));
- m_arrayOptions[0] = &m_options;
-
- return (AVISaveOptions(m_emuWnd, 0, 1, &m_stream, m_arrayOptions) != 0);
-}
-
-bool AVIDump::SetVideoFormat()
-{
- memset(&m_header, 0, sizeof(m_header));
- m_header.fccType = streamtypeVIDEO;
- m_header.dwScale = 1;
- // TODO: Decect FPS using NTSC/PAL
- m_header.dwRate = 60;
- m_header.dwSuggestedBufferSize = m_bitmap.biSizeImage;
-
- return SUCCEEDED(AVIFileCreateStream(m_file, &m_stream, &m_header));
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "AVIDump.h"
+#include "tchar.h"
+
+#include <cstdio>
+#include <cstring>
+#include <vfw.h>
+#include <winerror.h>
+
+#include "FileUtil.h"
+#include "CommonPaths.h"
+#include "Log.h"
+
+static HWND m_emuWnd;
+static int m_width;
+static int m_height;
+static LONG m_byteBuffer;
+static LONG m_frameCount;
+static LONG m_totalBytes;
+static PAVIFILE m_file;
+static int m_fileCount;
+static PAVISTREAM m_stream;
+static PAVISTREAM m_streamCompressed;
+static AVISTREAMINFO m_header;
+static AVICOMPRESSOPTIONS m_options;
+static AVICOMPRESSOPTIONS *m_arrayOptions[1];
+static BITMAPINFOHEADER m_bitmap;
+
+bool AVIDump::Start(HWND hWnd, int w, int h)
+{
+ m_emuWnd = hWnd;
+ m_fileCount = 0;
+
+ m_width = w;
+ m_height = h;
+
+ return CreateFile();
+}
+
+bool AVIDump::CreateFile()
+{
+ m_totalBytes = 0;
+ m_frameCount = 0;
+ char movie_file_name[255];
+ sprintf(movie_file_name, "%s/framedump%d.avi", FULL_FRAMES_DIR, m_fileCount);
+ // Create path
+ File::CreateFullPath(movie_file_name);
+
+ // Ask to delete file
+ if (File::Exists(movie_file_name))
+ {
+ if (AskYesNo("Delete the existing file '%s'?", movie_file_name))
+ File::Delete(movie_file_name);
+ }
+
+ AVIFileInit();
+ NOTICE_LOG(VIDEO, "Opening AVI file (%s) for dumping", movie_file_name);
+ // TODO: Make this work with AVIFileOpenW without it throwing REGDB_E_CLASSNOTREG
+ HRESULT hr = AVIFileOpenA(&m_file, movie_file_name, OF_WRITE | OF_CREATE, NULL);
+ if (FAILED(hr)) {
+ if (hr == AVIERR_BADFORMAT) NOTICE_LOG(VIDEO, "The file couldn't be read, indicating a corrupt file or an unrecognized format.");
+ if (hr == AVIERR_MEMORY) NOTICE_LOG(VIDEO, "The file could not be opened because of insufficient memory.");
+ if (hr == AVIERR_FILEREAD) NOTICE_LOG(VIDEO, "A disk error occurred while reading the file.");
+ if (hr == AVIERR_FILEOPEN) NOTICE_LOG(VIDEO, "A disk error occurred while opening the file.");
+ if (hr == REGDB_E_CLASSNOTREG) NOTICE_LOG(VIDEO, "AVI class not registered");
+ Stop();
+ return false;
+ }
+ SetBitmapFormat();
+ NOTICE_LOG(VIDEO, "Setting video format...");
+ if (!SetVideoFormat()) {
+ NOTICE_LOG(VIDEO, "Setting video format failed");
+ Stop();
+ return false;
+ }
+ if (!m_fileCount) {
+ if (!SetCompressionOptions()) {
+ NOTICE_LOG(VIDEO, "SetCompressionOptions failed");
+ Stop();
+ return false;
+ }
+ }
+ if (FAILED(AVIMakeCompressedStream(&m_streamCompressed, m_stream, &m_options, NULL))) {
+ NOTICE_LOG(VIDEO, "AVIMakeCompressedStream failed");
+ Stop();
+ return false;
+ }
+ if (FAILED(AVIStreamSetFormat(m_streamCompressed, 0, &m_bitmap, m_bitmap.biSize))) {
+ NOTICE_LOG(VIDEO, "AVIStreamSetFormat failed");
+ Stop();
+ return false;
+ }
+
+ return true;
+}
+
+void AVIDump::CloseFile()
+{
+ if (m_streamCompressed) {
+ AVIStreamClose(m_streamCompressed);
+ m_streamCompressed = NULL;
+ }
+ if (m_stream) {
+ AVIStreamClose(m_stream);
+ m_stream = NULL;
+ }
+ if (m_file) {
+ AVIFileRelease(m_file);
+ m_file = NULL;
+ }
+ AVIFileExit();
+}
+
+void AVIDump::Stop()
+{
+ CloseFile();
+ m_fileCount = 0;
+ NOTICE_LOG(VIDEO, "Stop");
+}
+
+void AVIDump::AddFrame(char *data)
+{
+ AVIStreamWrite(m_streamCompressed, ++m_frameCount, 1, (LPVOID) data, m_bitmap.biSizeImage, AVIIF_KEYFRAME, NULL, &m_byteBuffer);
+ m_totalBytes += m_byteBuffer;
+ // Close the recording if the file is more than 2gb
+ // VfW can't properly save files over 2gb in size, but can keep writing to them up to 4gb.
+ if (m_totalBytes >= 2000000000) {
+ CloseFile();
+ m_fileCount++;
+ CreateFile();
+ }
+}
+
+void AVIDump::SetBitmapFormat()
+{
+ memset(&m_bitmap, 0, sizeof(m_bitmap));
+ m_bitmap.biSize = 0x28;
+ m_bitmap.biPlanes = 1;
+ m_bitmap.biBitCount = 24;
+ m_bitmap.biWidth = m_width;
+ m_bitmap.biHeight = m_height;
+ m_bitmap.biSizeImage = 3 * m_width * m_height;
+}
+
+bool AVIDump::SetCompressionOptions()
+{
+ memset(&m_options, 0, sizeof(m_options));
+ m_arrayOptions[0] = &m_options;
+
+ return (AVISaveOptions(m_emuWnd, 0, 1, &m_stream, m_arrayOptions) != 0);
+}
+
+bool AVIDump::SetVideoFormat()
+{
+ memset(&m_header, 0, sizeof(m_header));
+ m_header.fccType = streamtypeVIDEO;
+ m_header.dwScale = 1;
+ // TODO: Decect FPS using NTSC/PAL
+ m_header.dwRate = 60;
+ m_header.dwSuggestedBufferSize = m_bitmap.biSizeImage;
+
+ return SUCCEEDED(AVIFileCreateStream(m_file, &m_stream, &m_header));
+}
diff --git a/Source/Core/VideoCommon/Src/BPFunctions.h b/Source/Core/VideoCommon/Src/BPFunctions.h
index c22e9aa0b6..aa476e0d83 100644
--- a/Source/Core/VideoCommon/Src/BPFunctions.h
+++ b/Source/Core/VideoCommon/Src/BPFunctions.h
@@ -1,60 +1,60 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-
-// ------------------------------------------
-// The plugins has to define these functions
-// ------------------------------------------
-
-#ifndef _BPFUNCTIONS_H_
-#define _BPFUNCTIONS_H_
-
-#include "BPMemory.h"
-#include "VideoCommon.h"
-
-namespace BPFunctions
-{
-
-enum
-{
- CONFIG_ISWII = 0,
- CONFIG_DISABLEFOG,
- CONFIG_SHOWEFBREGIONS
-};
-
-void FlushPipeline();
-void SetGenerationMode(const Bypass &bp);
-void SetScissor(const Bypass &bp);
-void SetLineWidth(const Bypass &bp);
-void SetDepthMode(const Bypass &bp);
-void SetBlendMode(const Bypass &bp);
-void SetDitherMode(const Bypass &bp);
-void SetLogicOpMode(const Bypass &bp);
-void SetColorMask(const Bypass &bp);
-float GetRendererTargetScaleX();
-float GetRendererTargetScaleY();
-void CopyEFB(const Bypass &bp, const TRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const bool &scaleByHalf);
-void RenderToXFB(const Bypass &bp, const TRectangle &multirc, const float &yScale, const float &xfbLines, u32 xfbAddr, const u32 &dstWidth, const u32 &dstHeight);
-void ClearScreen(const Bypass &bp, const TRectangle &multirc);
-void RestoreRenderState(const Bypass &bp);
-u8 *GetPointer(const u32 &address);
-bool GetConfig(const int &type);
-void SetSamplerState(const Bypass &bp);
-void SetInterlacingMode(const Bypass &bp);
-};
-
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+
+// ------------------------------------------
+// The plugins has to define these functions
+// ------------------------------------------
+
+#ifndef _BPFUNCTIONS_H_
+#define _BPFUNCTIONS_H_
+
+#include "BPMemory.h"
+#include "VideoCommon.h"
+
+namespace BPFunctions
+{
+
+enum
+{
+ CONFIG_ISWII = 0,
+ CONFIG_DISABLEFOG,
+ CONFIG_SHOWEFBREGIONS
+};
+
+void FlushPipeline();
+void SetGenerationMode(const Bypass &bp);
+void SetScissor(const Bypass &bp);
+void SetLineWidth(const Bypass &bp);
+void SetDepthMode(const Bypass &bp);
+void SetBlendMode(const Bypass &bp);
+void SetDitherMode(const Bypass &bp);
+void SetLogicOpMode(const Bypass &bp);
+void SetColorMask(const Bypass &bp);
+float GetRendererTargetScaleX();
+float GetRendererTargetScaleY();
+void CopyEFB(const Bypass &bp, const TRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const bool &scaleByHalf);
+void RenderToXFB(const Bypass &bp, const TRectangle &multirc, const float &yScale, const float &xfbLines, u32 xfbAddr, const u32 &dstWidth, const u32 &dstHeight);
+void ClearScreen(const Bypass &bp, const TRectangle &multirc);
+void RestoreRenderState(const Bypass &bp);
+u8 *GetPointer(const u32 &address);
+bool GetConfig(const int &type);
+void SetSamplerState(const Bypass &bp);
+void SetInterlacingMode(const Bypass &bp);
+};
+
#endif // _BPFUNCTIONS_H_ \ No newline at end of file
diff --git a/Source/Core/VideoCommon/Src/BPStructs.cpp b/Source/Core/VideoCommon/Src/BPStructs.cpp
index 19540bfca3..3780edb0b3 100644
--- a/Source/Core/VideoCommon/Src/BPStructs.cpp
+++ b/Source/Core/VideoCommon/Src/BPStructs.cpp
@@ -1,610 +1,610 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include <cmath>
-
-#include "Profiler.h"
-#include "Statistics.h"
-#include "VideoCommon.h"
-#include "PixelShaderManager.h"
-#include "BPFunctions.h"
-#include "BPStructs.h"
-#include "TextureDecoder.h"
-#include "OpcodeDecoding.h"
-#include "VertexLoader.h"
-#include "VertexShaderManager.h"
-
-using namespace BPFunctions;
-
-void BPInit()
-{
- memset(&bpmem, 0, sizeof(bpmem));
- bpmem.bpMask = 0xFFFFFF;
-}
-
-// ----------------------------------------------------------------------------------------------------------
-// Write to the Bypass Memory (Bypass Raster State Registers)
-/* ------------------
- Called:
- At the end of every: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg
- TODO:
- Turn into function table. The (future) DisplayList (DL) jit can then call the functions directly,
- getting rid of dynamic dispatch. Unfortunately, few games use DLs properly - most\
- just stuff geometry in them and don't put state changes there. */
-// ----------------------------------------------------------------------------------------------------------
-void BPWritten(const Bypass& bp)
-{
- // --------------------------------------------------------------------------------------------------------
- // First the pipeline is flushed then update the bpmem with the new value.
- // Some of the BP cases have to call certain functions while others just update the bpmem.
- // some bp cases check the changes variable, because they might not have to be updated all the time
- // NOTE: it seems not all bp cases like checking changes, so calling if (bp.changes == 0 ? false : true)
- // had to be ditched and the games seem to work fine with out it.
- // NOTE2: Yet Another Gamecube Documentation calls them Bypass Registers
- // --------------------------------------------------------------------------------------------------------
-
- // Debugging only, this lets you skip a bp update
- //static int times = 0;
- //static bool enable = false;
-
- //switch (bp.address)
- //{
- //case BPMEM_CONSTANTALPHA:
- // {
- // if (times-- == 0 && enable)
- // return;
- // else
- // break;
- // }
- //default: break;
- //}
-
- FlushPipeline();
- ((u32*)&bpmem)[bp.address] = bp.newvalue;
-
- switch (bp.address)
- {
- case BPMEM_GENMODE: // Set the Generation Mode
- {
- PRIM_LOG("genmode: texgen=%d, col=%d, ms_en=%d, tev=%d, culmode=%d, ind=%d, zfeeze=%d",
- bpmem.genMode.numtexgens, bpmem.genMode.numcolchans,
- bpmem.genMode.ms_en, bpmem.genMode.numtevstages+1, bpmem.genMode.cullmode,
- bpmem.genMode.numindstages, bpmem.genMode.zfreeze);
- SetGenerationMode(bp);
- break;
- }
- case BPMEM_IND_MTXA: // Index Matrix Changed
- case BPMEM_IND_MTXB:
- case BPMEM_IND_MTXC:
- case BPMEM_IND_MTXA+3:
- case BPMEM_IND_MTXB+3:
- case BPMEM_IND_MTXC+3:
- case BPMEM_IND_MTXA+6:
- case BPMEM_IND_MTXB+6:
- case BPMEM_IND_MTXC+6:
- PixelShaderManager::SetIndMatrixChanged((bp.address - BPMEM_IND_MTXA) / 3);
- break;
- case BPMEM_RAS1_SS0: // Index Texture Coordinate Scale 0
- PixelShaderManager::SetIndTexScaleChanged(0x03);
- case BPMEM_RAS1_SS1: // Index Texture Coordinate Scale 1
- PixelShaderManager::SetIndTexScaleChanged(0x0c);
- break;
- case BPMEM_SCISSORTL: // Scissor Rectable Top, Left
- case BPMEM_SCISSORBR: // Scissor Rectable Bottom, Right
- case BPMEM_SCISSOROFFSET: // Scissor Offset
- SetScissor(bp);
- break;
- case BPMEM_LINEPTWIDTH: // Line Width
- SetLineWidth(bp);
- break;
- case BPMEM_ZMODE: // Depth Control
- PRIM_LOG("zmode: test=%d, func=%d, upd=%d", bpmem.zmode.testenable, bpmem.zmode.func,
- bpmem.zmode.updateenable);
- SetDepthMode(bp);
- break;
- case BPMEM_BLENDMODE: // Blending Control
- {
- if (bp.changes & 0xFFFF)
- {
- PRIM_LOG("blendmode: en=%d, open=%d, colupd=%d, alphaupd=%d, dst=%d, src=%d, sub=%d, mode=%d",
- bpmem.blendmode.blendenable, bpmem.blendmode.logicopenable, bpmem.blendmode.colorupdate, bpmem.blendmode.alphaupdate,
- bpmem.blendmode.dstfactor, bpmem.blendmode.srcfactor, bpmem.blendmode.subtract, bpmem.blendmode.logicmode);
- // Set LogicOp Blending Mode
- if (bp.changes & 2)
- SetLogicOpMode(bp);
- // Set Dithering Mode
- if (bp.changes & 4)
- SetDitherMode(bp);
- // Set Blending Mode
- if (bp.changes & 0xFE1)
- SetBlendMode(bp);
- // Set Color Mask
- if (bp.changes & 0x18)
- SetColorMask(bp);
- }
- break;
- }
- case BPMEM_CONSTANTALPHA: // Set Destination Alpha
- {
- PRIM_LOG("constalpha: alp=%d, en=%d", bpmem.dstalpha.alpha, bpmem.dstalpha.enable);
- PixelShaderManager::SetDestAlpha(bpmem.dstalpha);
- break;
- }
- // This is called when the game is done drawing the new frame (eg: like in DX: Begin(); Draw(); End();)
- // Triggers an interrupt on the PPC side so that the game knows when the GPU has finished drawing.
- // Tokens are similar.
- case BPMEM_SETDRAWDONE:
- switch (bp.newvalue & 0xFF)
- {
- case 0x02:
- g_VideoInitialize.pSetPEFinish(); // may generate interrupt
- DEBUG_LOG(VIDEO, "GXSetDrawDone SetPEFinish (value: 0x%02X)", (bp.newvalue & 0xFFFF));
- break;
-
- default:
- WARN_LOG(VIDEO, "GXSetDrawDone ??? (value 0x%02X)", (bp.newvalue & 0xFFFF));
- break;
- }
- break;
- case BPMEM_PE_TOKEN_ID: // Pixel Engine Token ID
- g_VideoInitialize.pSetPEToken(static_cast<u16>(bp.newvalue & 0xFFFF), FALSE);
- DEBUG_LOG(VIDEO, "SetPEToken 0x%04x", (bp.newvalue & 0xFFFF));
- break;
- case BPMEM_PE_TOKEN_INT_ID: // Pixel Engine Interrupt Token ID
- g_VideoInitialize.pSetPEToken(static_cast<u16>(bp.newvalue & 0xFFFF), TRUE);
- DEBUG_LOG(VIDEO, "SetPEToken + INT 0x%04x", (bp.newvalue & 0xFFFF));
- break;
- // ------------------------
- // EFB copy command. This copies a rectangle from the EFB to either RAM in a texture format or to XFB as YUYV.
- // It can also optionally clear the EFB while copying from it. To emulate this, we of course copy first and clear afterwards.
- case BPMEM_TRIGGER_EFB_COPY: // Copy EFB Region or Render to the XFB or Clear the screen.
- {
- DVSTARTSUBPROFILE("LoadBPReg:swap");
- // The bottom right is within the rectangle
- // The values in bpmem.copyTexSrcXY and bpmem.copyTexSrcWH are updated in case 0x49 and 0x4a in this function
- TRectangle rc = {
- (int)(bpmem.copyTexSrcXY.x),
- (int)(bpmem.copyTexSrcXY.y),
- (int)((bpmem.copyTexSrcXY.x + bpmem.copyTexSrcWH.x + 1)),
- (int)((bpmem.copyTexSrcXY.y + bpmem.copyTexSrcWH.y + 1))
- };
-
- float MValueX = GetRendererTargetScaleX();
- float MValueY = GetRendererTargetScaleY();
-
- // Need another rc here to get it to scale.
- // Here the bottom right is the out of the rectangle.
- TRectangle multirc = {
- (int)(bpmem.copyTexSrcXY.x * MValueX),
- (int)(bpmem.copyTexSrcXY.y * MValueY),
- (int)((bpmem.copyTexSrcXY.x * MValueX + (bpmem.copyTexSrcWH.x + 1) * MValueX)),
- (int)((bpmem.copyTexSrcXY.y * MValueY + (bpmem.copyTexSrcWH.y + 1) * MValueY))
- };
- UPE_Copy PE_copy;
- PE_copy.Hex = bpmem.triggerEFBCopy;
-
- // Check if we are to copy from the EFB or draw to the XFB
- if (PE_copy.copy_to_xfb == 0)
- {
- if (GetConfig(CONFIG_SHOWEFBREGIONS))
- stats.efb_regions.push_back(rc);
-
- CopyEFB(bp, rc, bpmem.copyTexDest << 5,
- bpmem.zcontrol.pixel_format == PIXELFMT_Z24,
- PE_copy.intensity_fmt > 0,
- ((PE_copy.target_pixel_format / 2) + ((PE_copy.target_pixel_format & 1) * 8)),
- PE_copy.half_scale > 0);
- }
- else
- {
- // We should be able to get away with deactivating the current bbox tracking
- // here. Not sure if there's a better spot to put this.
- // the number of lines copied is determined by the y scale * source efb height
-#ifdef BBOX_SUPPORT
- *g_VideoInitialize.pBBoxActive = false;
-#endif
- const float yScale = bpmem.dispcopyyscale / 256.0f;
- const float xfbLines = ((bpmem.copyTexSrcWH.y + 1.0f) * yScale);
- RenderToXFB(bp, multirc, yScale, xfbLines,
- bpmem.copyTexDest << 5,
- bpmem.copyMipMapStrideChannels << 4,
- (u32)ceil(xfbLines));
- }
-
- // Clear the picture after it's done and submitted, to prepare for the next picture
- if (PE_copy.clear)
- ClearScreen(bp, multirc);
-
- RestoreRenderState(bp);
-
- break;
- }
- case BPMEM_LOADTLUT0: // Load a Texture Look Up Table
- case BPMEM_LOADTLUT1:
- {
- DVSTARTSUBPROFILE("LoadBPReg:GXLoadTlut");
-
- u32 tlutTMemAddr = (bp.newvalue & 0x3FF) << 9;
- u32 tlutXferCount = (bp.newvalue & 0x1FFC00) >> 5;
-
- u8 *ptr = 0;
-
- // TODO - figure out a cleaner way.
- if (GetConfig(CONFIG_ISWII))
- ptr = GetPointer(bpmem.tlutXferSrc << 5);
- else
- ptr = GetPointer((bpmem.tlutXferSrc & 0xFFFFF) << 5);
-
- if (ptr)
- memcpy_gc(texMem + tlutTMemAddr, ptr, tlutXferCount);
- else
- PanicAlert("Invalid palette pointer %08x %08x %08x", bpmem.tlutXferSrc, bpmem.tlutXferSrc << 5, (bpmem.tlutXferSrc & 0xFFFFF)<< 5);
-
- // TODO(ector) : kill all textures that use this palette
- // Not sure if it's a good idea, though. For now, we hash texture palettes
- break;
- }
- case BPMEM_FOGRANGE: // Fog Settings Control
- case BPMEM_FOGPARAM0:
- case BPMEM_FOGBMAGNITUDE:
- case BPMEM_FOGBEXPONENT:
- case BPMEM_FOGPARAM3:
- if (!GetConfig(CONFIG_DISABLEFOG))
- PixelShaderManager::SetFogParamChanged();
- break;
- case BPMEM_FOGCOLOR: // Fog Color
- PixelShaderManager::SetFogColorChanged();
- break;
- case BPMEM_ALPHACOMPARE: // Compare Alpha Values
- PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d", bpmem.alphaFunc.ref0,
- bpmem.alphaFunc.ref1, bpmem.alphaFunc.comp0, bpmem.alphaFunc.comp1, bpmem.alphaFunc.logic);
- PixelShaderManager::SetAlpha(bpmem.alphaFunc);
- break;
- case BPMEM_BIAS: // BIAS
- PRIM_LOG("ztex bias=0x%x", bpmem.ztex1.bias);
- PixelShaderManager::SetZTextureBias(bpmem.ztex1.bias);
- break;
- case BPMEM_ZTEX2: // Z Texture type
- {
- if (bp.changes & 3)
- PixelShaderManager::SetZTextureTypeChanged();
- #if defined(_DEBUG) || defined(DEBUGFAST)
- const char* pzop[] = {"DISABLE", "ADD", "REPLACE", "?"};
- const char* pztype[] = {"Z8", "Z16", "Z24", "?"};
- PRIM_LOG("ztex op=%s, type=%s", pzop[bpmem.ztex2.op], pztype[bpmem.ztex2.type]);
- #endif
- break;
- }
- // ----------------------------------
- // Display Copy Filtering Control
- // Fields: Destination, Frame2Field, Gamma, Source
- // TODO: We might have to implement the gamma one, some games might need this, if they are too dark to see.
- // ----------------------------------
- case BPMEM_DISPLAYCOPYFILER:
- case BPMEM_DISPLAYCOPYFILER+1:
- case BPMEM_DISPLAYCOPYFILER+2:
- case BPMEM_DISPLAYCOPYFILER+3:
- case BPMEM_COPYFILTER0: //GXSetCopyFilter
- case BPMEM_COPYFILTER1:
- break;
- case BPMEM_FIELDMASK: // Interlacing Control
- case BPMEM_FIELDMODE:
- SetInterlacingMode(bp);
- break;
- // ---------------------------------------------------
- // Debugging/Profiling info, we don't care about them
- // ---------------------------------------------------
- case BPMEM_CLOCK0: // Some Clock
- case BPMEM_CLOCK1: // Some Clock
- case BPMEM_SU_COUNTER: // Pixel or Poly Count
- case BPMEM_RAS_COUNTER: // Sound Count of something in the Texture Units
- case BPMEM_SETGPMETRIC: // Set the Graphic Processor Metric
- break;
- // ----------------
- // EFB Copy config
- // ----------------
- case BPMEM_EFB_TL: // EFB Source Rect. Top, Left
- case BPMEM_EFB_BR: // EFB Source Rect. Bottom, Right (w, h - 1)
- case BPMEM_EFB_ADDR: // EFB Target Address
- break;
- // --------------
- // Clear Config
- // --------------
- case BPMEM_CLEAR_AR: // Alpha and Red Components
- case BPMEM_CLEAR_GB: // Green and Blue Components
- case BPMEM_CLEAR_Z: // Z Components (24-bit Zbuffer)
- break;
- // -------------------------
- // Bounding Box support
- // -------------------------
- case BPMEM_CLEARBBOX1:
- case BPMEM_CLEARBBOX2: {
-
-#ifdef BBOX_SUPPORT
- // which is which? these are GUESSES!
- if (bp.address == BPMEM_CLEARBBOX1) {
- int right = bp.newvalue >> 10;
- int left = bp.newvalue & 0x3ff;
-
- // We should only set these if bbox is calculated properly.
- g_VideoInitialize.pBBox[0] = left;
- g_VideoInitialize.pBBox[1] = right;
- *g_VideoInitialize.pBBoxActive = true;
- // WARN_LOG(VIDEO, "ClearBBox LR: %i, %08x - %i, %i", bp.address, bp.newvalue, left, right);
- } else {
- int bottom = bp.newvalue >> 10;
- int top = bp.newvalue & 0x3ff;
-
- // We should only set these if bbox is calculated properly.
- g_VideoInitialize.pBBox[2] = top;
- g_VideoInitialize.pBBox[3] = bottom;
- *g_VideoInitialize.pBBoxActive = true;
- // WARN_LOG(VIDEO, "ClearBBox TB: %i, %08x - %i, %i", bp.address, bp.newvalue, top, bottom);
- }
-#endif
- break;
- }
- case BPMEM_ZCOMPARE: // Set the Z-Compare and EFB pixel format
- case BPMEM_TEXINVALIDATE: // Used, if game has manual control the Texture Cache, which we don't allow
- case BPMEM_MIPMAP_STRIDE: // MipMap Stride Channel
- case BPMEM_COPYYSCALE: // Display Copy Y Scale
- case BPMEM_IREF: /* 24 RID
- 21 BC3 - Ind. Tex Stage 3 NTexCoord
- 18 BI3 - Ind. Tex Stage 3 NTexMap
- 15 BC2 - Ind. Tex Stage 2 NTexCoord
- 12 BI2 - Ind. Tex Stage 2 NTexMap
- 9 BC1 - Ind. Tex Stage 1 NTexCoord
- 6 BI1 - Ind. Tex Stage 1 NTexMap
- 3 BC0 - Ind. Tex Stage 0 NTexCoord
- 0 BI0 - Ind. Tex Stage 0 NTexMap */
- break;
- case BPMEM_TEV_KSEL: // Texture Environment Swap Mode Table 0
- case BPMEM_TEV_KSEL+1:// Texture Environment Swap Mode Table 1
- case BPMEM_TEV_KSEL+2:// Texture Environment Swap Mode Table 2
- case BPMEM_TEV_KSEL+3:// Texture Environment Swap Mode Table 3
- case BPMEM_TEV_KSEL+4:// Texture Environment Swap Mode Table 4
- case BPMEM_TEV_KSEL+5:// Texture Environment Swap Mode Table 5
- case BPMEM_TEV_KSEL+6:// Texture Environment Swap Mode Table 6
- case BPMEM_TEV_KSEL+7:// Texture Environment Swap Mode Table 7
- break;
- case BPMEM_BP_MASK: // This Register can be used to limit to which bits of BP registers is actually written to. the mask is
- // only valid for the next BP command, and will reset itself.
- case BPMEM_IND_IMASK: // Index Mask ?
- break;
- case BPMEM_UNKNOWN: // This is always set to 0xF at boot of any game, so this sounds like a useless reg
- if (bp.newvalue != 0x0F)
- PanicAlert("Unknown is not 0xF! val = 0x%08x", bp.newvalue);
- break;
-
- case BPMEM_UNKNOWN1:
- case BPMEM_UNKNOWN2:
- case BPMEM_UNKNOWN3:
- case BPMEM_UNKNOWN4:
- // Cases added due to: http://code.google.com/p/dolphin-emu/issues/detail?id=360#c90
- // Are these related to BBox?
- break;
-
- // ------------------------------------------------
- // On Default, we try to look for other things
- // before we give up and say its an unknown opcode
- // ------------------------------------------------
- default:
- switch (bp.address & 0xFC) // Texture sampler filter
- {
- // -------------------------
- // Texture Environment Order
- // -------------------------
- case BPMEM_TREF:
- case BPMEM_TREF+1:
- case BPMEM_TREF+2:
- case BPMEM_TREF+3:
- case BPMEM_TREF+4:
- case BPMEM_TREF+5:
- case BPMEM_TREF+6:
- case BPMEM_TREF+7:
- break;
- // ----------------------
- // Set wrap size
- // ----------------------
- case BPMEM_SU_SSIZE:
- case BPMEM_SU_TSIZE:
- case BPMEM_SU_SSIZE+2:
- case BPMEM_SU_TSIZE+2:
- case BPMEM_SU_SSIZE+4:
- case BPMEM_SU_TSIZE+4:
- case BPMEM_SU_SSIZE+6:
- case BPMEM_SU_TSIZE+6:
- case BPMEM_SU_SSIZE+8:
- case BPMEM_SU_TSIZE+8:
- case BPMEM_SU_SSIZE+10:
- case BPMEM_SU_TSIZE+10:
- case BPMEM_SU_SSIZE+12:
- case BPMEM_SU_TSIZE+12:
- case BPMEM_SU_SSIZE+14:
- case BPMEM_SU_TSIZE+14:
- PixelShaderManager::SetTexCoordChanged((bp.address - BPMEM_SU_SSIZE) >> 1);
- break;
- // ------------------------
- // BPMEM_TX_SETMODE0 - (Texture lookup and filtering mode) LOD/BIAS Clamp, MaxAnsio, LODBIAS, DiagLoad, Min Filter, Mag Filter, Wrap T, S
- // BPMEM_TX_SETMODE1 - (LOD Stuff) - Max LOD, Min LOD
- // ------------------------
- case BPMEM_TX_SETMODE0: // (0x90 for linear)
- case BPMEM_TX_SETMODE0+1:
- case BPMEM_TX_SETMODE0+2:
- case BPMEM_TX_SETMODE0+3:
- case BPMEM_TX_SETMODE1:
- case BPMEM_TX_SETMODE1+1:
- case BPMEM_TX_SETMODE1+2:
- case BPMEM_TX_SETMODE1+3:
- case BPMEM_TX_SETMODE0_4:
- case BPMEM_TX_SETMODE0_4+1:
- case BPMEM_TX_SETMODE0_4+2:
- case BPMEM_TX_SETMODE0_4+3:
- case BPMEM_TX_SETMODE1_4:
- case BPMEM_TX_SETMODE1_4+1:
- case BPMEM_TX_SETMODE1_4+2:
- case BPMEM_TX_SETMODE1_4+3:
- SetSamplerState(bp);
- break;
- // --------------------------------------------
- // BPMEM_TX_SETIMAGE0 - Texture width, height, format
- // BPMEM_TX_SETIMAGE1 - even LOD address in TMEM - Image Type, Cache Height, Cache Width, TMEM Offset
- // BPMEM_TX_SETIMAGE2 - odd LOD address in TMEM - Cache Height, Cache Width, TMEM Offset
- // BPMEM_TX_SETIMAGE3 - Address of Texture in main memory
- // --------------------------------------------
- case BPMEM_TX_SETIMAGE0:
- case BPMEM_TX_SETIMAGE0+1:
- case BPMEM_TX_SETIMAGE0+2:
- case BPMEM_TX_SETIMAGE0+3:
- case BPMEM_TX_SETIMAGE0_4:
- case BPMEM_TX_SETIMAGE0_4+1:
- case BPMEM_TX_SETIMAGE0_4+2:
- case BPMEM_TX_SETIMAGE0_4+3:
- case BPMEM_TX_SETIMAGE1:
- case BPMEM_TX_SETIMAGE1+1:
- case BPMEM_TX_SETIMAGE1+2:
- case BPMEM_TX_SETIMAGE1+3:
- case BPMEM_TX_SETIMAGE1_4:
- case BPMEM_TX_SETIMAGE1_4+1:
- case BPMEM_TX_SETIMAGE1_4+2:
- case BPMEM_TX_SETIMAGE1_4+3:
- case BPMEM_TX_SETIMAGE2:
- case BPMEM_TX_SETIMAGE2+1:
- case BPMEM_TX_SETIMAGE2+2:
- case BPMEM_TX_SETIMAGE2+3:
- case BPMEM_TX_SETIMAGE2_4:
- case BPMEM_TX_SETIMAGE2_4+1:
- case BPMEM_TX_SETIMAGE2_4+2:
- case BPMEM_TX_SETIMAGE2_4+3:
- case BPMEM_TX_SETIMAGE3:
- case BPMEM_TX_SETIMAGE3+1:
- case BPMEM_TX_SETIMAGE3+2:
- case BPMEM_TX_SETIMAGE3+3:
- case BPMEM_TX_SETIMAGE3_4:
- case BPMEM_TX_SETIMAGE3_4+1:
- case BPMEM_TX_SETIMAGE3_4+2:
- case BPMEM_TX_SETIMAGE3_4+3:
- break;
- // -------------------------------
- // Set a TLUT
- // BPMEM_TX_SETTLUT - Format, TMEM Offset (offset of TLUT from start of TMEM high bank > > 5)
- // -------------------------------
- case BPMEM_TX_SETTLUT:
- case BPMEM_TX_SETTLUT+1:
- case BPMEM_TX_SETTLUT+2:
- case BPMEM_TX_SETTLUT+3:
- case BPMEM_TX_SETLUT_4:
- case BPMEM_TX_SETLUT_4+1:
- case BPMEM_TX_SETLUT_4+2:
- case BPMEM_TX_SETLUT_4+3:
- break;
- // ---------------------------------------------------
- // Set the TEV Color
- // ---------------------------------------------------
- case BPMEM_TEV_REGISTER_L: // Reg 1
- case BPMEM_TEV_REGISTER_H:
- case BPMEM_TEV_REGISTER_L+2: // Reg 2
- case BPMEM_TEV_REGISTER_H+2:
- case BPMEM_TEV_REGISTER_L+4: // Reg 3
- case BPMEM_TEV_REGISTER_H+4:
- case BPMEM_TEV_REGISTER_L+6: // Reg 4
- case BPMEM_TEV_REGISTER_H+6:
- {
- if (bp.address & 1)
- {
- // don't compare with changes!
- int num = (bp.address >> 1 ) & 0x3;
- PixelShaderManager::SetColorChanged(bpmem.tevregs[num].high.type, num);
- }
- break;
- }
- // ------------------------------------------------
- // On Default, we try to look for other things
- // before we give up and say its an unknown opcode
- // again ...
- // ------------------------------------------------
- default:
- switch (bp.address & 0xF0)
- {
- // --------------
- // Indirect Tev
- // --------------
- case BPMEM_IND_CMD:
- case BPMEM_IND_CMD+1:
- case BPMEM_IND_CMD+2:
- case BPMEM_IND_CMD+3:
- case BPMEM_IND_CMD+4:
- case BPMEM_IND_CMD+5:
- case BPMEM_IND_CMD+6:
- case BPMEM_IND_CMD+7:
- case BPMEM_IND_CMD+8:
- case BPMEM_IND_CMD+9:
- case BPMEM_IND_CMD+10:
- case BPMEM_IND_CMD+11:
- case BPMEM_IND_CMD+12:
- case BPMEM_IND_CMD+13:
- case BPMEM_IND_CMD+14:
- case BPMEM_IND_CMD+15:
- break;
- // --------------------------------------------------
- // Set Color/Alpha of a Tev
- // BPMEM_TEV_COLOR_ENV - Dest, Shift, Clamp, Sub, Bias, Sel A, Sel B, Sel C, Sel D
- // BPMEM_TEV_ALPHA_ENV - Dest, Shift, Clamp, Sub, Bias, Sel A, Sel B, Sel C, Sel D, T Swap, R Swap
- // --------------------------------------------------
- case BPMEM_TEV_COLOR_ENV: // Texture Environment 1
- case BPMEM_TEV_ALPHA_ENV:
- case BPMEM_TEV_COLOR_ENV+2: // Texture Environment 2
- case BPMEM_TEV_ALPHA_ENV+2:
- case BPMEM_TEV_COLOR_ENV+4: // Texture Environment 3
- case BPMEM_TEV_ALPHA_ENV+4:
- case BPMEM_TEV_COLOR_ENV+8: // Texture Environment 4
- case BPMEM_TEV_ALPHA_ENV+8:
- case BPMEM_TEV_COLOR_ENV+10: // Texture Environment 5
- case BPMEM_TEV_ALPHA_ENV+10:
- case BPMEM_TEV_COLOR_ENV+12: // Texture Environment 6
- case BPMEM_TEV_ALPHA_ENV+12:
- case BPMEM_TEV_COLOR_ENV+14: // Texture Environment 7
- case BPMEM_TEV_ALPHA_ENV+14:
- case BPMEM_TEV_COLOR_ENV+16: // Texture Environment 8
- case BPMEM_TEV_ALPHA_ENV+16:
- case BPMEM_TEV_COLOR_ENV+18: // Texture Environment 9
- case BPMEM_TEV_ALPHA_ENV+18:
- case BPMEM_TEV_COLOR_ENV+20: // Texture Environment 10
- case BPMEM_TEV_ALPHA_ENV+20:
- case BPMEM_TEV_COLOR_ENV+22: // Texture Environment 11
- case BPMEM_TEV_ALPHA_ENV+22:
- case BPMEM_TEV_COLOR_ENV+24: // Texture Environment 12
- case BPMEM_TEV_ALPHA_ENV+24:
- case BPMEM_TEV_COLOR_ENV+26: // Texture Environment 13
- case BPMEM_TEV_ALPHA_ENV+26:
- case BPMEM_TEV_COLOR_ENV+28: // Texture Environment 14
- case BPMEM_TEV_ALPHA_ENV+28:
- case BPMEM_TEV_COLOR_ENV+30: // Texture Environment 15
- case BPMEM_TEV_ALPHA_ENV+30:
- case BPMEM_TEV_COLOR_ENV+32: // Texture Environment 16
- case BPMEM_TEV_ALPHA_ENV+32:
- break;
- default:
- WARN_LOG(VIDEO, "Unknown Bypass opcode: address = 0x%08x value = 0x%08x", bp.address, bp.newvalue);
- break;
- }
-
- }
-
- }
-}
-
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include <cmath>
+
+#include "Profiler.h"
+#include "Statistics.h"
+#include "VideoCommon.h"
+#include "PixelShaderManager.h"
+#include "BPFunctions.h"
+#include "BPStructs.h"
+#include "TextureDecoder.h"
+#include "OpcodeDecoding.h"
+#include "VertexLoader.h"
+#include "VertexShaderManager.h"
+
+using namespace BPFunctions;
+
+void BPInit()
+{
+ memset(&bpmem, 0, sizeof(bpmem));
+ bpmem.bpMask = 0xFFFFFF;
+}
+
+// ----------------------------------------------------------------------------------------------------------
+// Write to the Bypass Memory (Bypass Raster State Registers)
+/* ------------------
+ Called:
+ At the end of every: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg
+ TODO:
+ Turn into function table. The (future) DisplayList (DL) jit can then call the functions directly,
+ getting rid of dynamic dispatch. Unfortunately, few games use DLs properly - most\
+ just stuff geometry in them and don't put state changes there. */
+// ----------------------------------------------------------------------------------------------------------
+void BPWritten(const Bypass& bp)
+{
+ // --------------------------------------------------------------------------------------------------------
+ // First the pipeline is flushed then update the bpmem with the new value.
+ // Some of the BP cases have to call certain functions while others just update the bpmem.
+ // some bp cases check the changes variable, because they might not have to be updated all the time
+ // NOTE: it seems not all bp cases like checking changes, so calling if (bp.changes == 0 ? false : true)
+ // had to be ditched and the games seem to work fine with out it.
+ // NOTE2: Yet Another Gamecube Documentation calls them Bypass Registers
+ // --------------------------------------------------------------------------------------------------------
+
+ // Debugging only, this lets you skip a bp update
+ //static int times = 0;
+ //static bool enable = false;
+
+ //switch (bp.address)
+ //{
+ //case BPMEM_CONSTANTALPHA:
+ // {
+ // if (times-- == 0 && enable)
+ // return;
+ // else
+ // break;
+ // }
+ //default: break;
+ //}
+
+ FlushPipeline();
+ ((u32*)&bpmem)[bp.address] = bp.newvalue;
+
+ switch (bp.address)
+ {
+ case BPMEM_GENMODE: // Set the Generation Mode
+ {
+ PRIM_LOG("genmode: texgen=%d, col=%d, ms_en=%d, tev=%d, culmode=%d, ind=%d, zfeeze=%d",
+ bpmem.genMode.numtexgens, bpmem.genMode.numcolchans,
+ bpmem.genMode.ms_en, bpmem.genMode.numtevstages+1, bpmem.genMode.cullmode,
+ bpmem.genMode.numindstages, bpmem.genMode.zfreeze);
+ SetGenerationMode(bp);
+ break;
+ }
+ case BPMEM_IND_MTXA: // Index Matrix Changed
+ case BPMEM_IND_MTXB:
+ case BPMEM_IND_MTXC:
+ case BPMEM_IND_MTXA+3:
+ case BPMEM_IND_MTXB+3:
+ case BPMEM_IND_MTXC+3:
+ case BPMEM_IND_MTXA+6:
+ case BPMEM_IND_MTXB+6:
+ case BPMEM_IND_MTXC+6:
+ PixelShaderManager::SetIndMatrixChanged((bp.address - BPMEM_IND_MTXA) / 3);
+ break;
+ case BPMEM_RAS1_SS0: // Index Texture Coordinate Scale 0
+ PixelShaderManager::SetIndTexScaleChanged(0x03);
+ case BPMEM_RAS1_SS1: // Index Texture Coordinate Scale 1
+ PixelShaderManager::SetIndTexScaleChanged(0x0c);
+ break;
+ case BPMEM_SCISSORTL: // Scissor Rectable Top, Left
+ case BPMEM_SCISSORBR: // Scissor Rectable Bottom, Right
+ case BPMEM_SCISSOROFFSET: // Scissor Offset
+ SetScissor(bp);
+ break;
+ case BPMEM_LINEPTWIDTH: // Line Width
+ SetLineWidth(bp);
+ break;
+ case BPMEM_ZMODE: // Depth Control
+ PRIM_LOG("zmode: test=%d, func=%d, upd=%d", bpmem.zmode.testenable, bpmem.zmode.func,
+ bpmem.zmode.updateenable);
+ SetDepthMode(bp);
+ break;
+ case BPMEM_BLENDMODE: // Blending Control
+ {
+ if (bp.changes & 0xFFFF)
+ {
+ PRIM_LOG("blendmode: en=%d, open=%d, colupd=%d, alphaupd=%d, dst=%d, src=%d, sub=%d, mode=%d",
+ bpmem.blendmode.blendenable, bpmem.blendmode.logicopenable, bpmem.blendmode.colorupdate, bpmem.blendmode.alphaupdate,
+ bpmem.blendmode.dstfactor, bpmem.blendmode.srcfactor, bpmem.blendmode.subtract, bpmem.blendmode.logicmode);
+ // Set LogicOp Blending Mode
+ if (bp.changes & 2)
+ SetLogicOpMode(bp);
+ // Set Dithering Mode
+ if (bp.changes & 4)
+ SetDitherMode(bp);
+ // Set Blending Mode
+ if (bp.changes & 0xFE1)
+ SetBlendMode(bp);
+ // Set Color Mask
+ if (bp.changes & 0x18)
+ SetColorMask(bp);
+ }
+ break;
+ }
+ case BPMEM_CONSTANTALPHA: // Set Destination Alpha
+ {
+ PRIM_LOG("constalpha: alp=%d, en=%d", bpmem.dstalpha.alpha, bpmem.dstalpha.enable);
+ PixelShaderManager::SetDestAlpha(bpmem.dstalpha);
+ break;
+ }
+ // This is called when the game is done drawing the new frame (eg: like in DX: Begin(); Draw(); End();)
+ // Triggers an interrupt on the PPC side so that the game knows when the GPU has finished drawing.
+ // Tokens are similar.
+ case BPMEM_SETDRAWDONE:
+ switch (bp.newvalue & 0xFF)
+ {
+ case 0x02:
+ g_VideoInitialize.pSetPEFinish(); // may generate interrupt
+ DEBUG_LOG(VIDEO, "GXSetDrawDone SetPEFinish (value: 0x%02X)", (bp.newvalue & 0xFFFF));
+ break;
+
+ default:
+ WARN_LOG(VIDEO, "GXSetDrawDone ??? (value 0x%02X)", (bp.newvalue & 0xFFFF));
+ break;
+ }
+ break;
+ case BPMEM_PE_TOKEN_ID: // Pixel Engine Token ID
+ g_VideoInitialize.pSetPEToken(static_cast<u16>(bp.newvalue & 0xFFFF), FALSE);
+ DEBUG_LOG(VIDEO, "SetPEToken 0x%04x", (bp.newvalue & 0xFFFF));
+ break;
+ case BPMEM_PE_TOKEN_INT_ID: // Pixel Engine Interrupt Token ID
+ g_VideoInitialize.pSetPEToken(static_cast<u16>(bp.newvalue & 0xFFFF), TRUE);
+ DEBUG_LOG(VIDEO, "SetPEToken + INT 0x%04x", (bp.newvalue & 0xFFFF));
+ break;
+ // ------------------------
+ // EFB copy command. This copies a rectangle from the EFB to either RAM in a texture format or to XFB as YUYV.
+ // It can also optionally clear the EFB while copying from it. To emulate this, we of course copy first and clear afterwards.
+ case BPMEM_TRIGGER_EFB_COPY: // Copy EFB Region or Render to the XFB or Clear the screen.
+ {
+ DVSTARTSUBPROFILE("LoadBPReg:swap");
+ // The bottom right is within the rectangle
+ // The values in bpmem.copyTexSrcXY and bpmem.copyTexSrcWH are updated in case 0x49 and 0x4a in this function
+ TRectangle rc = {
+ (int)(bpmem.copyTexSrcXY.x),
+ (int)(bpmem.copyTexSrcXY.y),
+ (int)((bpmem.copyTexSrcXY.x + bpmem.copyTexSrcWH.x + 1)),
+ (int)((bpmem.copyTexSrcXY.y + bpmem.copyTexSrcWH.y + 1))
+ };
+
+ float MValueX = GetRendererTargetScaleX();
+ float MValueY = GetRendererTargetScaleY();
+
+ // Need another rc here to get it to scale.
+ // Here the bottom right is the out of the rectangle.
+ TRectangle multirc = {
+ (int)(bpmem.copyTexSrcXY.x * MValueX),
+ (int)(bpmem.copyTexSrcXY.y * MValueY),
+ (int)((bpmem.copyTexSrcXY.x * MValueX + (bpmem.copyTexSrcWH.x + 1) * MValueX)),
+ (int)((bpmem.copyTexSrcXY.y * MValueY + (bpmem.copyTexSrcWH.y + 1) * MValueY))
+ };
+ UPE_Copy PE_copy;
+ PE_copy.Hex = bpmem.triggerEFBCopy;
+
+ // Check if we are to copy from the EFB or draw to the XFB
+ if (PE_copy.copy_to_xfb == 0)
+ {
+ if (GetConfig(CONFIG_SHOWEFBREGIONS))
+ stats.efb_regions.push_back(rc);
+
+ CopyEFB(bp, rc, bpmem.copyTexDest << 5,
+ bpmem.zcontrol.pixel_format == PIXELFMT_Z24,
+ PE_copy.intensity_fmt > 0,
+ ((PE_copy.target_pixel_format / 2) + ((PE_copy.target_pixel_format & 1) * 8)),
+ PE_copy.half_scale > 0);
+ }
+ else
+ {
+ // We should be able to get away with deactivating the current bbox tracking
+ // here. Not sure if there's a better spot to put this.
+ // the number of lines copied is determined by the y scale * source efb height
+#ifdef BBOX_SUPPORT
+ *g_VideoInitialize.pBBoxActive = false;
+#endif
+ const float yScale = bpmem.dispcopyyscale / 256.0f;
+ const float xfbLines = ((bpmem.copyTexSrcWH.y + 1.0f) * yScale);
+ RenderToXFB(bp, multirc, yScale, xfbLines,
+ bpmem.copyTexDest << 5,
+ bpmem.copyMipMapStrideChannels << 4,
+ (u32)ceil(xfbLines));
+ }
+
+ // Clear the picture after it's done and submitted, to prepare for the next picture
+ if (PE_copy.clear)
+ ClearScreen(bp, multirc);
+
+ RestoreRenderState(bp);
+
+ break;
+ }
+ case BPMEM_LOADTLUT0: // Load a Texture Look Up Table
+ case BPMEM_LOADTLUT1:
+ {
+ DVSTARTSUBPROFILE("LoadBPReg:GXLoadTlut");
+
+ u32 tlutTMemAddr = (bp.newvalue & 0x3FF) << 9;
+ u32 tlutXferCount = (bp.newvalue & 0x1FFC00) >> 5;
+
+ u8 *ptr = 0;
+
+ // TODO - figure out a cleaner way.
+ if (GetConfig(CONFIG_ISWII))
+ ptr = GetPointer(bpmem.tlutXferSrc << 5);
+ else
+ ptr = GetPointer((bpmem.tlutXferSrc & 0xFFFFF) << 5);
+
+ if (ptr)
+ memcpy_gc(texMem + tlutTMemAddr, ptr, tlutXferCount);
+ else
+ PanicAlert("Invalid palette pointer %08x %08x %08x", bpmem.tlutXferSrc, bpmem.tlutXferSrc << 5, (bpmem.tlutXferSrc & 0xFFFFF)<< 5);
+
+ // TODO(ector) : kill all textures that use this palette
+ // Not sure if it's a good idea, though. For now, we hash texture palettes
+ break;
+ }
+ case BPMEM_FOGRANGE: // Fog Settings Control
+ case BPMEM_FOGPARAM0:
+ case BPMEM_FOGBMAGNITUDE:
+ case BPMEM_FOGBEXPONENT:
+ case BPMEM_FOGPARAM3:
+ if (!GetConfig(CONFIG_DISABLEFOG))
+ PixelShaderManager::SetFogParamChanged();
+ break;
+ case BPMEM_FOGCOLOR: // Fog Color
+ PixelShaderManager::SetFogColorChanged();
+ break;
+ case BPMEM_ALPHACOMPARE: // Compare Alpha Values
+ PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d", bpmem.alphaFunc.ref0,
+ bpmem.alphaFunc.ref1, bpmem.alphaFunc.comp0, bpmem.alphaFunc.comp1, bpmem.alphaFunc.logic);
+ PixelShaderManager::SetAlpha(bpmem.alphaFunc);
+ break;
+ case BPMEM_BIAS: // BIAS
+ PRIM_LOG("ztex bias=0x%x", bpmem.ztex1.bias);
+ PixelShaderManager::SetZTextureBias(bpmem.ztex1.bias);
+ break;
+ case BPMEM_ZTEX2: // Z Texture type
+ {
+ if (bp.changes & 3)
+ PixelShaderManager::SetZTextureTypeChanged();
+ #if defined(_DEBUG) || defined(DEBUGFAST)
+ const char* pzop[] = {"DISABLE", "ADD", "REPLACE", "?"};
+ const char* pztype[] = {"Z8", "Z16", "Z24", "?"};
+ PRIM_LOG("ztex op=%s, type=%s", pzop[bpmem.ztex2.op], pztype[bpmem.ztex2.type]);
+ #endif
+ break;
+ }
+ // ----------------------------------
+ // Display Copy Filtering Control
+ // Fields: Destination, Frame2Field, Gamma, Source
+ // TODO: We might have to implement the gamma one, some games might need this, if they are too dark to see.
+ // ----------------------------------
+ case BPMEM_DISPLAYCOPYFILER:
+ case BPMEM_DISPLAYCOPYFILER+1:
+ case BPMEM_DISPLAYCOPYFILER+2:
+ case BPMEM_DISPLAYCOPYFILER+3:
+ case BPMEM_COPYFILTER0: //GXSetCopyFilter
+ case BPMEM_COPYFILTER1:
+ break;
+ case BPMEM_FIELDMASK: // Interlacing Control
+ case BPMEM_FIELDMODE:
+ SetInterlacingMode(bp);
+ break;
+ // ---------------------------------------------------
+ // Debugging/Profiling info, we don't care about them
+ // ---------------------------------------------------
+ case BPMEM_CLOCK0: // Some Clock
+ case BPMEM_CLOCK1: // Some Clock
+ case BPMEM_SU_COUNTER: // Pixel or Poly Count
+ case BPMEM_RAS_COUNTER: // Sound Count of something in the Texture Units
+ case BPMEM_SETGPMETRIC: // Set the Graphic Processor Metric
+ break;
+ // ----------------
+ // EFB Copy config
+ // ----------------
+ case BPMEM_EFB_TL: // EFB Source Rect. Top, Left
+ case BPMEM_EFB_BR: // EFB Source Rect. Bottom, Right (w, h - 1)
+ case BPMEM_EFB_ADDR: // EFB Target Address
+ break;
+ // --------------
+ // Clear Config
+ // --------------
+ case BPMEM_CLEAR_AR: // Alpha and Red Components
+ case BPMEM_CLEAR_GB: // Green and Blue Components
+ case BPMEM_CLEAR_Z: // Z Components (24-bit Zbuffer)
+ break;
+ // -------------------------
+ // Bounding Box support
+ // -------------------------
+ case BPMEM_CLEARBBOX1:
+ case BPMEM_CLEARBBOX2: {
+
+#ifdef BBOX_SUPPORT
+ // which is which? these are GUESSES!
+ if (bp.address == BPMEM_CLEARBBOX1) {
+ int right = bp.newvalue >> 10;
+ int left = bp.newvalue & 0x3ff;
+
+ // We should only set these if bbox is calculated properly.
+ g_VideoInitialize.pBBox[0] = left;
+ g_VideoInitialize.pBBox[1] = right;
+ *g_VideoInitialize.pBBoxActive = true;
+ // WARN_LOG(VIDEO, "ClearBBox LR: %i, %08x - %i, %i", bp.address, bp.newvalue, left, right);
+ } else {
+ int bottom = bp.newvalue >> 10;
+ int top = bp.newvalue & 0x3ff;
+
+ // We should only set these if bbox is calculated properly.
+ g_VideoInitialize.pBBox[2] = top;
+ g_VideoInitialize.pBBox[3] = bottom;
+ *g_VideoInitialize.pBBoxActive = true;
+ // WARN_LOG(VIDEO, "ClearBBox TB: %i, %08x - %i, %i", bp.address, bp.newvalue, top, bottom);
+ }
+#endif
+ break;
+ }
+ case BPMEM_ZCOMPARE: // Set the Z-Compare and EFB pixel format
+ case BPMEM_TEXINVALIDATE: // Used, if game has manual control the Texture Cache, which we don't allow
+ case BPMEM_MIPMAP_STRIDE: // MipMap Stride Channel
+ case BPMEM_COPYYSCALE: // Display Copy Y Scale
+ case BPMEM_IREF: /* 24 RID
+ 21 BC3 - Ind. Tex Stage 3 NTexCoord
+ 18 BI3 - Ind. Tex Stage 3 NTexMap
+ 15 BC2 - Ind. Tex Stage 2 NTexCoord
+ 12 BI2 - Ind. Tex Stage 2 NTexMap
+ 9 BC1 - Ind. Tex Stage 1 NTexCoord
+ 6 BI1 - Ind. Tex Stage 1 NTexMap
+ 3 BC0 - Ind. Tex Stage 0 NTexCoord
+ 0 BI0 - Ind. Tex Stage 0 NTexMap */
+ break;
+ case BPMEM_TEV_KSEL: // Texture Environment Swap Mode Table 0
+ case BPMEM_TEV_KSEL+1:// Texture Environment Swap Mode Table 1
+ case BPMEM_TEV_KSEL+2:// Texture Environment Swap Mode Table 2
+ case BPMEM_TEV_KSEL+3:// Texture Environment Swap Mode Table 3
+ case BPMEM_TEV_KSEL+4:// Texture Environment Swap Mode Table 4
+ case BPMEM_TEV_KSEL+5:// Texture Environment Swap Mode Table 5
+ case BPMEM_TEV_KSEL+6:// Texture Environment Swap Mode Table 6
+ case BPMEM_TEV_KSEL+7:// Texture Environment Swap Mode Table 7
+ break;
+ case BPMEM_BP_MASK: // This Register can be used to limit to which bits of BP registers is actually written to. the mask is
+ // only valid for the next BP command, and will reset itself.
+ case BPMEM_IND_IMASK: // Index Mask ?
+ break;
+ case BPMEM_UNKNOWN: // This is always set to 0xF at boot of any game, so this sounds like a useless reg
+ if (bp.newvalue != 0x0F)
+ PanicAlert("Unknown is not 0xF! val = 0x%08x", bp.newvalue);
+ break;
+
+ case BPMEM_UNKNOWN1:
+ case BPMEM_UNKNOWN2:
+ case BPMEM_UNKNOWN3:
+ case BPMEM_UNKNOWN4:
+ // Cases added due to: http://code.google.com/p/dolphin-emu/issues/detail?id=360#c90
+ // Are these related to BBox?
+ break;
+
+ // ------------------------------------------------
+ // On Default, we try to look for other things
+ // before we give up and say its an unknown opcode
+ // ------------------------------------------------
+ default:
+ switch (bp.address & 0xFC) // Texture sampler filter
+ {
+ // -------------------------
+ // Texture Environment Order
+ // -------------------------
+ case BPMEM_TREF:
+ case BPMEM_TREF+1:
+ case BPMEM_TREF+2:
+ case BPMEM_TREF+3:
+ case BPMEM_TREF+4:
+ case BPMEM_TREF+5:
+ case BPMEM_TREF+6:
+ case BPMEM_TREF+7:
+ break;
+ // ----------------------
+ // Set wrap size
+ // ----------------------
+ case BPMEM_SU_SSIZE:
+ case BPMEM_SU_TSIZE:
+ case BPMEM_SU_SSIZE+2:
+ case BPMEM_SU_TSIZE+2:
+ case BPMEM_SU_SSIZE+4:
+ case BPMEM_SU_TSIZE+4:
+ case BPMEM_SU_SSIZE+6:
+ case BPMEM_SU_TSIZE+6:
+ case BPMEM_SU_SSIZE+8:
+ case BPMEM_SU_TSIZE+8:
+ case BPMEM_SU_SSIZE+10:
+ case BPMEM_SU_TSIZE+10:
+ case BPMEM_SU_SSIZE+12:
+ case BPMEM_SU_TSIZE+12:
+ case BPMEM_SU_SSIZE+14:
+ case BPMEM_SU_TSIZE+14:
+ PixelShaderManager::SetTexCoordChanged((bp.address - BPMEM_SU_SSIZE) >> 1);
+ break;
+ // ------------------------
+ // BPMEM_TX_SETMODE0 - (Texture lookup and filtering mode) LOD/BIAS Clamp, MaxAnsio, LODBIAS, DiagLoad, Min Filter, Mag Filter, Wrap T, S
+ // BPMEM_TX_SETMODE1 - (LOD Stuff) - Max LOD, Min LOD
+ // ------------------------
+ case BPMEM_TX_SETMODE0: // (0x90 for linear)
+ case BPMEM_TX_SETMODE0+1:
+ case BPMEM_TX_SETMODE0+2:
+ case BPMEM_TX_SETMODE0+3:
+ case BPMEM_TX_SETMODE1:
+ case BPMEM_TX_SETMODE1+1:
+ case BPMEM_TX_SETMODE1+2:
+ case BPMEM_TX_SETMODE1+3:
+ case BPMEM_TX_SETMODE0_4:
+ case BPMEM_TX_SETMODE0_4+1:
+ case BPMEM_TX_SETMODE0_4+2:
+ case BPMEM_TX_SETMODE0_4+3:
+ case BPMEM_TX_SETMODE1_4:
+ case BPMEM_TX_SETMODE1_4+1:
+ case BPMEM_TX_SETMODE1_4+2:
+ case BPMEM_TX_SETMODE1_4+3:
+ SetSamplerState(bp);
+ break;
+ // --------------------------------------------
+ // BPMEM_TX_SETIMAGE0 - Texture width, height, format
+ // BPMEM_TX_SETIMAGE1 - even LOD address in TMEM - Image Type, Cache Height, Cache Width, TMEM Offset
+ // BPMEM_TX_SETIMAGE2 - odd LOD address in TMEM - Cache Height, Cache Width, TMEM Offset
+ // BPMEM_TX_SETIMAGE3 - Address of Texture in main memory
+ // --------------------------------------------
+ case BPMEM_TX_SETIMAGE0:
+ case BPMEM_TX_SETIMAGE0+1:
+ case BPMEM_TX_SETIMAGE0+2:
+ case BPMEM_TX_SETIMAGE0+3:
+ case BPMEM_TX_SETIMAGE0_4:
+ case BPMEM_TX_SETIMAGE0_4+1:
+ case BPMEM_TX_SETIMAGE0_4+2:
+ case BPMEM_TX_SETIMAGE0_4+3:
+ case BPMEM_TX_SETIMAGE1:
+ case BPMEM_TX_SETIMAGE1+1:
+ case BPMEM_TX_SETIMAGE1+2:
+ case BPMEM_TX_SETIMAGE1+3:
+ case BPMEM_TX_SETIMAGE1_4:
+ case BPMEM_TX_SETIMAGE1_4+1:
+ case BPMEM_TX_SETIMAGE1_4+2:
+ case BPMEM_TX_SETIMAGE1_4+3:
+ case BPMEM_TX_SETIMAGE2:
+ case BPMEM_TX_SETIMAGE2+1:
+ case BPMEM_TX_SETIMAGE2+2:
+ case BPMEM_TX_SETIMAGE2+3:
+ case BPMEM_TX_SETIMAGE2_4:
+ case BPMEM_TX_SETIMAGE2_4+1:
+ case BPMEM_TX_SETIMAGE2_4+2:
+ case BPMEM_TX_SETIMAGE2_4+3:
+ case BPMEM_TX_SETIMAGE3:
+ case BPMEM_TX_SETIMAGE3+1:
+ case BPMEM_TX_SETIMAGE3+2:
+ case BPMEM_TX_SETIMAGE3+3:
+ case BPMEM_TX_SETIMAGE3_4:
+ case BPMEM_TX_SETIMAGE3_4+1:
+ case BPMEM_TX_SETIMAGE3_4+2:
+ case BPMEM_TX_SETIMAGE3_4+3:
+ break;
+ // -------------------------------
+ // Set a TLUT
+ // BPMEM_TX_SETTLUT - Format, TMEM Offset (offset of TLUT from start of TMEM high bank > > 5)
+ // -------------------------------
+ case BPMEM_TX_SETTLUT:
+ case BPMEM_TX_SETTLUT+1:
+ case BPMEM_TX_SETTLUT+2:
+ case BPMEM_TX_SETTLUT+3:
+ case BPMEM_TX_SETLUT_4:
+ case BPMEM_TX_SETLUT_4+1:
+ case BPMEM_TX_SETLUT_4+2:
+ case BPMEM_TX_SETLUT_4+3:
+ break;
+ // ---------------------------------------------------
+ // Set the TEV Color
+ // ---------------------------------------------------
+ case BPMEM_TEV_REGISTER_L: // Reg 1
+ case BPMEM_TEV_REGISTER_H:
+ case BPMEM_TEV_REGISTER_L+2: // Reg 2
+ case BPMEM_TEV_REGISTER_H+2:
+ case BPMEM_TEV_REGISTER_L+4: // Reg 3
+ case BPMEM_TEV_REGISTER_H+4:
+ case BPMEM_TEV_REGISTER_L+6: // Reg 4
+ case BPMEM_TEV_REGISTER_H+6:
+ {
+ if (bp.address & 1)
+ {
+ // don't compare with changes!
+ int num = (bp.address >> 1 ) & 0x3;
+ PixelShaderManager::SetColorChanged(bpmem.tevregs[num].high.type, num);
+ }
+ break;
+ }
+ // ------------------------------------------------
+ // On Default, we try to look for other things
+ // before we give up and say its an unknown opcode
+ // again ...
+ // ------------------------------------------------
+ default:
+ switch (bp.address & 0xF0)
+ {
+ // --------------
+ // Indirect Tev
+ // --------------
+ case BPMEM_IND_CMD:
+ case BPMEM_IND_CMD+1:
+ case BPMEM_IND_CMD+2:
+ case BPMEM_IND_CMD+3:
+ case BPMEM_IND_CMD+4:
+ case BPMEM_IND_CMD+5:
+ case BPMEM_IND_CMD+6:
+ case BPMEM_IND_CMD+7:
+ case BPMEM_IND_CMD+8:
+ case BPMEM_IND_CMD+9:
+ case BPMEM_IND_CMD+10:
+ case BPMEM_IND_CMD+11:
+ case BPMEM_IND_CMD+12:
+ case BPMEM_IND_CMD+13:
+ case BPMEM_IND_CMD+14:
+ case BPMEM_IND_CMD+15:
+ break;
+ // --------------------------------------------------
+ // Set Color/Alpha of a Tev
+ // BPMEM_TEV_COLOR_ENV - Dest, Shift, Clamp, Sub, Bias, Sel A, Sel B, Sel C, Sel D
+ // BPMEM_TEV_ALPHA_ENV - Dest, Shift, Clamp, Sub, Bias, Sel A, Sel B, Sel C, Sel D, T Swap, R Swap
+ // --------------------------------------------------
+ case BPMEM_TEV_COLOR_ENV: // Texture Environment 1
+ case BPMEM_TEV_ALPHA_ENV:
+ case BPMEM_TEV_COLOR_ENV+2: // Texture Environment 2
+ case BPMEM_TEV_ALPHA_ENV+2:
+ case BPMEM_TEV_COLOR_ENV+4: // Texture Environment 3
+ case BPMEM_TEV_ALPHA_ENV+4:
+ case BPMEM_TEV_COLOR_ENV+8: // Texture Environment 4
+ case BPMEM_TEV_ALPHA_ENV+8:
+ case BPMEM_TEV_COLOR_ENV+10: // Texture Environment 5
+ case BPMEM_TEV_ALPHA_ENV+10:
+ case BPMEM_TEV_COLOR_ENV+12: // Texture Environment 6
+ case BPMEM_TEV_ALPHA_ENV+12:
+ case BPMEM_TEV_COLOR_ENV+14: // Texture Environment 7
+ case BPMEM_TEV_ALPHA_ENV+14:
+ case BPMEM_TEV_COLOR_ENV+16: // Texture Environment 8
+ case BPMEM_TEV_ALPHA_ENV+16:
+ case BPMEM_TEV_COLOR_ENV+18: // Texture Environment 9
+ case BPMEM_TEV_ALPHA_ENV+18:
+ case BPMEM_TEV_COLOR_ENV+20: // Texture Environment 10
+ case BPMEM_TEV_ALPHA_ENV+20:
+ case BPMEM_TEV_COLOR_ENV+22: // Texture Environment 11
+ case BPMEM_TEV_ALPHA_ENV+22:
+ case BPMEM_TEV_COLOR_ENV+24: // Texture Environment 12
+ case BPMEM_TEV_ALPHA_ENV+24:
+ case BPMEM_TEV_COLOR_ENV+26: // Texture Environment 13
+ case BPMEM_TEV_ALPHA_ENV+26:
+ case BPMEM_TEV_COLOR_ENV+28: // Texture Environment 14
+ case BPMEM_TEV_ALPHA_ENV+28:
+ case BPMEM_TEV_COLOR_ENV+30: // Texture Environment 15
+ case BPMEM_TEV_ALPHA_ENV+30:
+ case BPMEM_TEV_COLOR_ENV+32: // Texture Environment 16
+ case BPMEM_TEV_ALPHA_ENV+32:
+ break;
+ default:
+ WARN_LOG(VIDEO, "Unknown Bypass opcode: address = 0x%08x value = 0x%08x", bp.address, bp.newvalue);
+ break;
+ }
+
+ }
+
+ }
+}
+
diff --git a/Source/Core/VideoCommon/Src/BPStructs.h b/Source/Core/VideoCommon/Src/BPStructs.h
index fa1100db29..815b337ad5 100644
--- a/Source/Core/VideoCommon/Src/BPStructs.h
+++ b/Source/Core/VideoCommon/Src/BPStructs.h
@@ -1,27 +1,27 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _BPSTRUCTS_H_
-#define _BPSTRUCTS_H_
-
-#include "BPMemory.h"
-
-void BPInit();
-void LoadBPReg(u32 value0);
-void BPReload();
-
-#endif // _BPSTRUCTS_H_
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _BPSTRUCTS_H_
+#define _BPSTRUCTS_H_
+
+#include "BPMemory.h"
+
+void BPInit();
+void LoadBPReg(u32 value0);
+void BPReload();
+
+#endif // _BPSTRUCTS_H_
diff --git a/Source/Core/VideoCommon/Src/HiresTextures.cpp b/Source/Core/VideoCommon/Src/HiresTextures.cpp
index 80540b920e..58861fe93b 100644
--- a/Source/Core/VideoCommon/Src/HiresTextures.cpp
+++ b/Source/Core/VideoCommon/Src/HiresTextures.cpp
@@ -1,154 +1,154 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "HiresTextures.h"
-
-#include <cstring>
-#include <utility>
-#include <algorithm>
-#include "SOIL.h"
-#include "CommonPaths.h"
-#include "FileUtil.h"
-#include "FileSearch.h"
-
-namespace HiresTextures
-{
-
-std::map<std::string, std::string> textureMap;
-
-void Init(const char *gameCode)
-{
- static bool bCheckedDir;
-
- CFileSearch::XStringVector Directories;
- //Directories.push_back(std::string(FULL_HIRES_TEXTURES_DIR));
- char szDir[MAX_PATH];
- sprintf(szDir,"%s/%s",FULL_HIRES_TEXTURES_DIR,gameCode);
- Directories.push_back(std::string(szDir));
-
-
- for (u32 i = 0; i < Directories.size(); i++)
- {
- File::FSTEntry FST_Temp;
- File::ScanDirectoryTree(Directories.at(i).c_str(), FST_Temp);
- for (u32 j = 0; j < FST_Temp.children.size(); j++)
- {
- if (FST_Temp.children.at(j).isDirectory)
- {
- bool duplicate = false;
- NormalizeDirSep(&(FST_Temp.children.at(j).physicalName));
- for (u32 k = 0; k < Directories.size(); k++)
- {
- NormalizeDirSep(&Directories.at(k));
- if (strcmp(Directories.at(k).c_str(), FST_Temp.children.at(j).physicalName.c_str()) == 0)
- {
- duplicate = true;
- break;
- }
- }
- if (!duplicate)
- Directories.push_back(FST_Temp.children.at(j).physicalName.c_str());
- }
- }
- }
-
- CFileSearch::XStringVector Extensions;
- Extensions.push_back("*.png");
- Extensions.push_back("*.bmp");
- Extensions.push_back("*.tga");
- Extensions.push_back("*.dds");
- Extensions.push_back("*.jpg"); // Why not? Could be useful for large photo-like textures
-
- CFileSearch FileSearch(Extensions, Directories);
- const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames();
- char code[MAX_PATH];
- sprintf(code, "%s_", gameCode);
-
- if (rFilenames.size() > 0)
- {
- for (u32 i = 0; i < rFilenames.size(); i++)
- {
- std::string FileName;
- SplitPath(rFilenames[i], NULL, &FileName, NULL);
-
- if (FileName.substr(0, strlen(code)).compare(code) == 0 && textureMap.find(FileName) == textureMap.end())
- textureMap.insert(std::map<std::string, std::string>::value_type(FileName, rFilenames[i]));
- }
- }
-}
-
-void Shutdown()
-{
- textureMap.clear();
-}
-
-PC_TexFormat GetHiresTex(const char *fileName, int *pWidth, int *pHeight, int texformat, u8 *data)
-{
- std::string key(fileName);
-
- if(textureMap.find(key) == textureMap.end())
- return PC_TEX_FMT_NONE;
-
- int width;
- int height;
- int channels;
-
- u8 *temp = SOIL_load_image(textureMap[key].c_str(), &width, &height, &channels, SOIL_LOAD_RGBA);
-
- if (temp == NULL) {
- ERROR_LOG(VIDEO, "Custom texture %s failed to load", textureMap[key].c_str(), width, height);
- SOIL_free_image_data(temp);
- return PC_TEX_FMT_NONE;
- }
-
- if (width > 1024 || height > 1024) {
- ERROR_LOG(VIDEO, "Custom texture %s is too large (%ix%i); textures can only be 1024 pixels tall and wide", textureMap[key].c_str(), width, height);
- SOIL_free_image_data(temp);
- return PC_TEX_FMT_NONE;
- }
-
- int offset = 0;
- PC_TexFormat returnTex;
-
- switch (texformat)
- {
- case GX_TF_I4:
- case GX_TF_I8:
- case GX_TF_IA4:
- case GX_TF_IA8:
- for (int i = 0; i < width * height * 4; i += 4)
- {
- // Rather than use a luminosity function, just use the most intense color for luminance
- data[offset++] = *std::max_element(temp+i, temp+i+3);
- data[offset++] = temp[i+3];
- }
- returnTex = PC_TEX_FMT_IA8;
- break;
- default:
- memcpy(data, temp, width*height*4);
- returnTex = PC_TEX_FMT_RGBA32;
- break;
- }
-
- *pWidth = width;
- *pHeight = height;
- SOIL_free_image_data(temp);
- INFO_LOG(VIDEO, "loading custom texture from %s", textureMap[key].c_str());
- return returnTex;
-}
-
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "HiresTextures.h"
+
+#include <cstring>
+#include <utility>
+#include <algorithm>
+#include "SOIL.h"
+#include "CommonPaths.h"
+#include "FileUtil.h"
+#include "FileSearch.h"
+
+namespace HiresTextures
+{
+
+std::map<std::string, std::string> textureMap;
+
+void Init(const char *gameCode)
+{
+ static bool bCheckedDir;
+
+ CFileSearch::XStringVector Directories;
+ //Directories.push_back(std::string(FULL_HIRES_TEXTURES_DIR));
+ char szDir[MAX_PATH];
+ sprintf(szDir,"%s/%s",FULL_HIRES_TEXTURES_DIR,gameCode);
+ Directories.push_back(std::string(szDir));
+
+
+ for (u32 i = 0; i < Directories.size(); i++)
+ {
+ File::FSTEntry FST_Temp;
+ File::ScanDirectoryTree(Directories.at(i).c_str(), FST_Temp);
+ for (u32 j = 0; j < FST_Temp.children.size(); j++)
+ {
+ if (FST_Temp.children.at(j).isDirectory)
+ {
+ bool duplicate = false;
+ NormalizeDirSep(&(FST_Temp.children.at(j).physicalName));
+ for (u32 k = 0; k < Directories.size(); k++)
+ {
+ NormalizeDirSep(&Directories.at(k));
+ if (strcmp(Directories.at(k).c_str(), FST_Temp.children.at(j).physicalName.c_str()) == 0)
+ {
+ duplicate = true;
+ break;
+ }
+ }
+ if (!duplicate)
+ Directories.push_back(FST_Temp.children.at(j).physicalName.c_str());
+ }
+ }
+ }
+
+ CFileSearch::XStringVector Extensions;
+ Extensions.push_back("*.png");
+ Extensions.push_back("*.bmp");
+ Extensions.push_back("*.tga");
+ Extensions.push_back("*.dds");
+ Extensions.push_back("*.jpg"); // Why not? Could be useful for large photo-like textures
+
+ CFileSearch FileSearch(Extensions, Directories);
+ const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames();
+ char code[MAX_PATH];
+ sprintf(code, "%s_", gameCode);
+
+ if (rFilenames.size() > 0)
+ {
+ for (u32 i = 0; i < rFilenames.size(); i++)
+ {
+ std::string FileName;
+ SplitPath(rFilenames[i], NULL, &FileName, NULL);
+
+ if (FileName.substr(0, strlen(code)).compare(code) == 0 && textureMap.find(FileName) == textureMap.end())
+ textureMap.insert(std::map<std::string, std::string>::value_type(FileName, rFilenames[i]));
+ }
+ }
+}
+
+void Shutdown()
+{
+ textureMap.clear();
+}
+
+PC_TexFormat GetHiresTex(const char *fileName, int *pWidth, int *pHeight, int texformat, u8 *data)
+{
+ std::string key(fileName);
+
+ if(textureMap.find(key) == textureMap.end())
+ return PC_TEX_FMT_NONE;
+
+ int width;
+ int height;
+ int channels;
+
+ u8 *temp = SOIL_load_image(textureMap[key].c_str(), &width, &height, &channels, SOIL_LOAD_RGBA);
+
+ if (temp == NULL) {
+ ERROR_LOG(VIDEO, "Custom texture %s failed to load", textureMap[key].c_str(), width, height);
+ SOIL_free_image_data(temp);
+ return PC_TEX_FMT_NONE;
+ }
+
+ if (width > 1024 || height > 1024) {
+ ERROR_LOG(VIDEO, "Custom texture %s is too large (%ix%i); textures can only be 1024 pixels tall and wide", textureMap[key].c_str(), width, height);
+ SOIL_free_image_data(temp);
+ return PC_TEX_FMT_NONE;
+ }
+
+ int offset = 0;
+ PC_TexFormat returnTex;
+
+ switch (texformat)
+ {
+ case GX_TF_I4:
+ case GX_TF_I8:
+ case GX_TF_IA4:
+ case GX_TF_IA8:
+ for (int i = 0; i < width * height * 4; i += 4)
+ {
+ // Rather than use a luminosity function, just use the most intense color for luminance
+ data[offset++] = *std::max_element(temp+i, temp+i+3);
+ data[offset++] = temp[i+3];
+ }
+ returnTex = PC_TEX_FMT_IA8;
+ break;
+ default:
+ memcpy(data, temp, width*height*4);
+ returnTex = PC_TEX_FMT_RGBA32;
+ break;
+ }
+
+ *pWidth = width;
+ *pHeight = height;
+ SOIL_free_image_data(temp);
+ INFO_LOG(VIDEO, "loading custom texture from %s", textureMap[key].c_str());
+ return returnTex;
+}
+
+}
diff --git a/Source/DSPSpy/Config.h b/Source/DSPSpy/Config.h
index 2277d60028..5eb605a631 100644
--- a/Source/DSPSpy/Config.h
+++ b/Source/DSPSpy/Config.h
@@ -1,18 +1,18 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-// Dummy file for common to compile
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Dummy file for common to compile
diff --git a/Source/DSPSpy/Stubs.cpp b/Source/DSPSpy/Stubs.cpp
index 3771762216..cec684fcee 100644
--- a/Source/DSPSpy/Stubs.cpp
+++ b/Source/DSPSpy/Stubs.cpp
@@ -1,119 +1,119 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-// Stubs to make DSPCore compile as part of DSPSpy.
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <string>
-
-#include "Thread.h"
-
-void *AllocateMemoryPages(size_t size)
-{
- return malloc(size);
-}
-
-void FreeMemoryPages(void *pages, size_t size)
-{
- free(pages);
-}
-
-void WriteProtectMemory(void* ptr, size_t size, bool allowExecute)
-{
-}
-
-void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute)
-{
-}
-
-bool DSPHost_OnThread()
-{
- return false;
-}
-
-// Well, it's just RAM right? :)
-u8 DSPHost_ReadHostMemory(u32 address)
-{
- u8 *ptr = (u8*)address;
- return *ptr;
-}
-
-void DSPHost_WriteHostMemory(u8 value, u32 addr) {}
-
-
-void DSPHost_CodeLoaded(const u8 *code, int size)
-{
-}
-
-
-namespace Common
-{
-
-CriticalSection::CriticalSection(int)
-{
-}
-CriticalSection::~CriticalSection()
-{
-}
-
-void CriticalSection::Enter()
-{
-}
-
-void CriticalSection::Leave()
-{
-}
-
-} // namespace
-
-namespace File
-{
-
-bool WriteStringToFile(bool text_file, const std::string &str, const char *filename)
-{
- FILE *f = fopen(filename, text_file ? "w" : "wb");
- if (!f)
- return false;
- size_t len = str.size();
- if (len != fwrite(str.data(), 1, str.size(), f))
- {
- fclose(f);
- return false;
- }
- fclose(f);
- return true;
-}
-
-bool ReadFileToString(bool text_file, const char *filename, std::string &str)
-{
- FILE *f = fopen(filename, text_file ? "r" : "rb");
- if (!f)
- return false;
- fseek(f, 0, SEEK_END);
- size_t len = ftell(f);
- fseek(f, 0, SEEK_SET);
- char *buf = new char[len + 1];
- buf[fread(buf, 1, len, f)] = 0;
- str = std::string(buf, len);
- fclose(f);
- delete [] buf;
- return true;
-}
-
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Stubs to make DSPCore compile as part of DSPSpy.
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <string>
+
+#include "Thread.h"
+
+void *AllocateMemoryPages(size_t size)
+{
+ return malloc(size);
+}
+
+void FreeMemoryPages(void *pages, size_t size)
+{
+ free(pages);
+}
+
+void WriteProtectMemory(void* ptr, size_t size, bool allowExecute)
+{
+}
+
+void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute)
+{
+}
+
+bool DSPHost_OnThread()
+{
+ return false;
+}
+
+// Well, it's just RAM right? :)
+u8 DSPHost_ReadHostMemory(u32 address)
+{
+ u8 *ptr = (u8*)address;
+ return *ptr;
+}
+
+void DSPHost_WriteHostMemory(u8 value, u32 addr) {}
+
+
+void DSPHost_CodeLoaded(const u8 *code, int size)
+{
+}
+
+
+namespace Common
+{
+
+CriticalSection::CriticalSection(int)
+{
+}
+CriticalSection::~CriticalSection()
+{
+}
+
+void CriticalSection::Enter()
+{
+}
+
+void CriticalSection::Leave()
+{
+}
+
+} // namespace
+
+namespace File
+{
+
+bool WriteStringToFile(bool text_file, const std::string &str, const char *filename)
+{
+ FILE *f = fopen(filename, text_file ? "w" : "wb");
+ if (!f)
+ return false;
+ size_t len = str.size();
+ if (len != fwrite(str.data(), 1, str.size(), f))
+ {
+ fclose(f);
+ return false;
+ }
+ fclose(f);
+ return true;
+}
+
+bool ReadFileToString(bool text_file, const char *filename, std::string &str)
+{
+ FILE *f = fopen(filename, text_file ? "r" : "rb");
+ if (!f)
+ return false;
+ fseek(f, 0, SEEK_END);
+ size_t len = ftell(f);
+ fseek(f, 0, SEEK_SET);
+ char *buf = new char[len + 1];
+ buf[fread(buf, 1, len, f)] = 0;
+ str = std::string(buf, len);
+ fclose(f);
+ delete [] buf;
+ return true;
+}
+
+}
diff --git a/Source/DSPSpy/dsp_interface.cpp b/Source/DSPSpy/dsp_interface.cpp
index 08647f0bf5..d6debd30bb 100644
--- a/Source/DSPSpy/dsp_interface.cpp
+++ b/Source/DSPSpy/dsp_interface.cpp
@@ -1,43 +1,43 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "dsp_interface.h"
-
-void IDSP::SendTask(void *addr, u16 iram_addr, u16 len, u16 start)
-{
- while (CheckMailTo());
- SendMailTo(0x80F3A001);
- while (CheckMailTo());
- SendMailTo((u32)addr);
- while (CheckMailTo());
- SendMailTo(0x80F3C002);
- while (CheckMailTo());
- SendMailTo(iram_addr);
- while (CheckMailTo());
- SendMailTo(0x80F3A002);
- while (CheckMailTo());
- SendMailTo(len);
- while (CheckMailTo());
- SendMailTo(0x80F3B002);
- while (CheckMailTo());
- SendMailTo(0);
- while (CheckMailTo());
- SendMailTo(0x80F3D001);
- while (CheckMailTo());
- SendMailTo(start);
- while (CheckMailTo());
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "dsp_interface.h"
+
+void IDSP::SendTask(void *addr, u16 iram_addr, u16 len, u16 start)
+{
+ while (CheckMailTo());
+ SendMailTo(0x80F3A001);
+ while (CheckMailTo());
+ SendMailTo((u32)addr);
+ while (CheckMailTo());
+ SendMailTo(0x80F3C002);
+ while (CheckMailTo());
+ SendMailTo(iram_addr);
+ while (CheckMailTo());
+ SendMailTo(0x80F3A002);
+ while (CheckMailTo());
+ SendMailTo(len);
+ while (CheckMailTo());
+ SendMailTo(0x80F3B002);
+ while (CheckMailTo());
+ SendMailTo(0);
+ while (CheckMailTo());
+ SendMailTo(0x80F3D001);
+ while (CheckMailTo());
+ SendMailTo(start);
+ while (CheckMailTo());
} \ No newline at end of file
diff --git a/Source/DSPSpy/dsp_interface.h b/Source/DSPSpy/dsp_interface.h
index 11e41b2f48..12522746fa 100644
--- a/Source/DSPSpy/dsp_interface.h
+++ b/Source/DSPSpy/dsp_interface.h
@@ -1,50 +1,50 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _DSP_INTERFACE_H
-#define _DSP_INTERFACE_H
-
-#include <gccore.h>
-
-// DSPCR bits
-#define DSPCR_DSPRESET 0x0800 // Reset DSP
-#define DSPCR_ARDMA 0x0200 // ARAM dma in progress, if set
-#define DSPCR_DSPINTMSK 0x0100 // * interrupt mask (RW)
-#define DSPCR_DSPINT 0x0080 // * interrupt active (RWC)
-#define DSPCR_ARINTMSK 0x0040
-#define DSPCR_ARINT 0x0020
-#define DSPCR_AIINTMSK 0x0010
-#define DSPCR_AIINT 0x0008
-#define DSPCR_HALT 0x0004 // halt DSP
-#define DSPCR_PIINT 0x0002 // assert DSP PI interrupt
-#define DSPCR_RES 0x0001 // reset DSP
-
-class IDSP {
-public:
- virtual ~IDSP() {}
-
- virtual void Init() = 0;
- virtual void Reset() = 0;
- virtual u32 CheckMailTo() = 0;
- virtual void SendMailTo(u32 mail) = 0;
-
- // Yeah, yeah, having a method here makes this not a pure interface - but
- // the implementation does nothing but calling the virtual methods above.
- void SendTask(void *addr, u16 iram_addr, u16 len, u16 start);
-};
-
-#endif // _DSP_INTERFACE_H
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _DSP_INTERFACE_H
+#define _DSP_INTERFACE_H
+
+#include <gccore.h>
+
+// DSPCR bits
+#define DSPCR_DSPRESET 0x0800 // Reset DSP
+#define DSPCR_ARDMA 0x0200 // ARAM dma in progress, if set
+#define DSPCR_DSPINTMSK 0x0100 // * interrupt mask (RW)
+#define DSPCR_DSPINT 0x0080 // * interrupt active (RWC)
+#define DSPCR_ARINTMSK 0x0040
+#define DSPCR_ARINT 0x0020
+#define DSPCR_AIINTMSK 0x0010
+#define DSPCR_AIINT 0x0008
+#define DSPCR_HALT 0x0004 // halt DSP
+#define DSPCR_PIINT 0x0002 // assert DSP PI interrupt
+#define DSPCR_RES 0x0001 // reset DSP
+
+class IDSP {
+public:
+ virtual ~IDSP() {}
+
+ virtual void Init() = 0;
+ virtual void Reset() = 0;
+ virtual u32 CheckMailTo() = 0;
+ virtual void SendMailTo(u32 mail) = 0;
+
+ // Yeah, yeah, having a method here makes this not a pure interface - but
+ // the implementation does nothing but calling the virtual methods above.
+ void SendTask(void *addr, u16 iram_addr, u16 len, u16 start);
+};
+
+#endif // _DSP_INTERFACE_H
diff --git a/Source/DSPSpy/main_spy.cpp b/Source/DSPSpy/main_spy.cpp
index d61258405c..f897bc58be 100644
--- a/Source/DSPSpy/main_spy.cpp
+++ b/Source/DSPSpy/main_spy.cpp
@@ -1,565 +1,565 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-// This is a test program for running code on the Wii DSP, with full control over input
-// and automatic compare with output. VERY useful for figuring out what those little
-// ops actually do.
-// It's very unpolished though
-// Use Dolphin's dsptool to generate a new dsp_code.h.
-// Originally written by duddie and modified by FIRES. Then further modified by ector.
-
-#include <gccore.h>
-#include <malloc.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <network.h>
-#include <ogcsys.h>
-#include <time.h>
-#include <fat.h>
-#include <fcntl.h>
-
-#include <ogc/color.h>
-#include <ogc/consol.h>
-
-#ifdef HW_RVL
-#include <wiiuse/wpad.h>
-#endif
-
-#include "ConsoleHelper.h"
-
-// Pull in some constants etc from DSPCore.
-#include "../Core/DSPCore/Src/gdsp_registers.h"
-
-// This is where the DSP binary is.
-#include "dsp_code.h"
-#include "mem_dump.h"
-
-// Communication with the real DSP and with the DSP emulator.
-#include "dsp_interface.h"
-#include "real_dsp.h"
-// #include "virtual_dsp.h"
-
-// Used for communications with the DSP, such as dumping registers etc.
-u16 dspbuffer[16 * 1024] __attribute__ ((aligned (0x4000)));
-
-static void *xfb = NULL;
-void (*reboot)() = (void(*)())0x80001800;
-GXRModeObj *rmode;
-
-static vu16* const _dspReg = (u16*)0xCC005000;
-
-u16 *dspbufP;
-u16 *dspbufC;
-u32 *dspbufU;
-
-u16 dspreg_in[32] = {
- 0x0410, 0x0510, 0x0610, 0x0710, 0x0810, 0x0910, 0x0a10, 0x0b10,
- 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0855, 0x0966, 0x0a77, 0x0b88,
- 0x0014, 0xfff5, 0x00ff, 0x2200, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0003, 0x0004, 0x8000, 0x000C, 0x0007, 0x0008, 0x0009, 0x000a,
-}; /// ax_h_1 ax_h_1
-
-/* ttt ?
-
-u16 dspreg_in[32] = {
-0x0e4c, 0x03c0, 0x0bd9, 0x06a3, 0x0c06, 0x0240, 0x0010, 0x0ecc,
-0x0000, 0x0000, 0x0000, 0x0000, 0x0322, 0x0000, 0x0000, 0x0000,
-0x0000, 0x0000, 0x00ff, 0x1b41, 0x0000, 0x0040, 0x00ff, 0x0000,
-0x1000, 0x96cc, 0x0000, 0x0000, 0x3fc0, 0x96cc, 0x0000, 0x0000,
-}; */
-
-// if i set bit 0x4000 of SR my tests crashes :(
-
-/*
-// zelda 0x00da
-u16 dspreg_in[32] = {
-0x0a50, 0x0ca2, 0x04f8, 0x0ab0, 0x8039, 0x0000, 0x0000, 0x0000,
-0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x03d1, 0x0000, 0x0418, 0x0002, // r08 must have a value ... no idea why (ector: it's the looped addressing regs)
-0x0000, 0x0000, 0x00ff, 0x1804, 0xdb70, 0x4ddb, 0x0000, 0x0000,
-0x0000, 0x0000, 0x0000, 0xde6d, 0x0000, 0x0000, 0x0000, 0x004e,
-};*/
-
-u16 dspreg_out[1000][32];
-
-u32 padding[1024];
-
-// UI (interactive register editing)
-u32 ui_mode;
-
-enum {
- UIM_SEL = 1,
- UIM_EDIT_REG = 2,
- UIM_EDIT_BIN = 4,
-};
-
-// Currently selected register.
-s32 cursor_reg = 0;
-// Currently selected digit.
-s32 small_cursor_x;
-// Value currently being edited.
-u16 *reg_value;
-
-char last_message[20] = "OK";
-
-RealDSP real_dsp;
-
-// Currently running microcode
-int curUcode = 0, runningUcode = 1;
-
-int dsp_steps = 0;
-
-// When comparing regs, ignore the loop stack registers.
-bool regs_equal(int reg, u16 value1, u16 value2) {
- if (reg >= DSP_REG_ST0 && reg <= DSP_REG_ST3)
- return true;
- else
- return value1 == value2;
-}
-
-void print_reg_block(int x, int y, int sel, const u16 *regs, const u16 *compare_regs)
-{
- for (int j = 0; j < 4 ; j++)
- {
- for (int i = 0; i < 8 ; i++)
- {
- // Do not even display the loop stack registers.
- const int reg = j * 8 + i;
- CON_SetColor(sel == reg ? CON_BRIGHT_YELLOW : CON_GREEN);
- CON_Printf(x + j * 8, i + y, "%02x ", reg);
- if (j != 1 || i < 4)
- {
- u8 color1 = regs_equal(reg, regs[reg], compare_regs[reg]) ? CON_BRIGHT_WHITE : CON_BRIGHT_RED;
- for (int k = 0; k < 4; k++)
- {
- if (sel == reg && k == small_cursor_x && ui_mode == UIM_EDIT_REG)
- CON_SetColor(CON_BRIGHT_CYAN);
- else
- CON_SetColor(color1);
- CON_Printf(x + 3 + j * 8 + k, i + y, "%01x", (regs[reg] >> ((3 - k) * 4)) & 0xf);
- }
- }
- }
- }
- CON_SetColor(CON_WHITE);
-
- CON_Printf(x+2, y+9, "ACC0: %02x %04x %04x", regs[DSP_REG_ACH0]&0xff, regs[DSP_REG_ACM0], regs[DSP_REG_ACL0]);
- CON_Printf(x+2, y+10, "ACC1: %02x %04x %04x", regs[DSP_REG_ACH1]&0xff, regs[DSP_REG_ACM1], regs[DSP_REG_ACL1]);
- CON_Printf(x+2, y+11, "AX0: %04x %04x", regs[DSP_REG_AXH0], regs[DSP_REG_AXL0]);
- CON_Printf(x+2, y+12, "AX1: %04x %04x", regs[DSP_REG_AXH1], regs[DSP_REG_AXL1]);
-}
-
-void print_regs(int _step, int _dsp_steps)
-{
- const u16 *regs = _step == 0 ? dspreg_in : dspreg_out[_step - 1];
- const u16 *regs2 = dspreg_out[_step];
-
- print_reg_block(0, 2, _step == 0 ? cursor_reg : -1, regs, regs2);
- print_reg_block(33, 2, -1, regs2, regs);
-
- CON_SetColor(CON_WHITE);
- CON_Printf(33, 17, "%i / %i ", _step + 1, _dsp_steps);
-
- return;
-
- static int count = 0;
- int x = 0, y = 16;
- if (count > 2)
- CON_Clear();
- count = 0;
- CON_SetColor(CON_WHITE);
- for (int i = 0x0; i < 0xf70 ; i++)
- {
- if (dspbufC[i] != mem_dump[i])
- {
- CON_Printf(x, y, "%04x=%04x", i, dspbufC[i]);
- count++;
- x += 10;
- if (x >= 60) {
- x = 0;
- y++;
- }
- }
- }
- CON_Printf(4, 25, "%08x", count);
-}
-
-void ui_pad_sel(void)
-{
-#ifdef HW_RVL
- if (WPAD_ButtonsDown(0) & WPAD_BUTTON_RIGHT)
- cursor_reg += 8;
- if (WPAD_ButtonsDown(0) & WPAD_BUTTON_LEFT)
- cursor_reg -= 8;
- if (WPAD_ButtonsDown(0) & WPAD_BUTTON_UP)
- cursor_reg--;
- if (WPAD_ButtonsDown(0) & WPAD_BUTTON_DOWN)
- cursor_reg++;
- cursor_reg &= 0x1f;
- if (WPAD_ButtonsDown(0) & WPAD_BUTTON_A)
- {
- ui_mode = UIM_EDIT_REG;
- reg_value = &dspreg_in[cursor_reg];
- }
-#else
- if (PAD_ButtonsDown(0) & PAD_BUTTON_RIGHT)
- cursor_reg += 8;
- if (PAD_ButtonsDown(0) & PAD_BUTTON_LEFT)
- cursor_reg -= 8;
- if (PAD_ButtonsDown(0) & PAD_BUTTON_UP)
- cursor_reg--;
- if (PAD_ButtonsDown(0) & PAD_BUTTON_DOWN)
- cursor_reg++;
- cursor_reg &= 0x1f;
- if (PAD_ButtonsDown(0) & PAD_BUTTON_A)
- {
- ui_mode = UIM_EDIT_REG;
- reg_value = &dspreg_in[cursor_reg];
- }
-#endif
-}
-
-void ui_pad_edit_reg(void)
-{
-#ifdef HW_RVL
- if (WPAD_ButtonsDown(0) & WPAD_BUTTON_RIGHT)
- small_cursor_x++;
- if (WPAD_ButtonsDown(0) & WPAD_BUTTON_LEFT)
- small_cursor_x--;
- small_cursor_x &= 0x3;
-
- if (WPAD_ButtonsDown(0) & WPAD_BUTTON_UP)
- *reg_value += 0x1 << (4 * (3 - small_cursor_x));
- if (WPAD_ButtonsDown(0) & WPAD_BUTTON_DOWN)
- *reg_value -= 0x1 << (4 * (3 - small_cursor_x));
- if (WPAD_ButtonsDown(0) & WPAD_BUTTON_A)
- ui_mode = UIM_SEL;
- if (WPAD_ButtonsDown(0) & WPAD_BUTTON_1)
- *reg_value = 0;
- if (WPAD_ButtonsDown(0) & WPAD_BUTTON_2)
- *reg_value = 0xffff;
-#else
- if (PAD_ButtonsDown(0) & PAD_BUTTON_RIGHT)
- small_cursor_x++;
- if (PAD_ButtonsDown(0) & PAD_BUTTON_LEFT)
- small_cursor_x--;
- small_cursor_x &= 0x3;
-
- if (PAD_ButtonsDown(0) & PAD_BUTTON_UP)
- *reg_value += 0x1 << (4 * (3 - small_cursor_x));
- if (PAD_ButtonsDown(0) & PAD_BUTTON_DOWN)
- *reg_value -= 0x1 << (4 * (3 - small_cursor_x));
- if (PAD_ButtonsDown(0) & PAD_BUTTON_A)
- ui_mode = UIM_SEL;
- if (PAD_ButtonsDown(0) & PAD_BUTTON_X)
- *reg_value = 0;
- if (PAD_ButtonsDown(0) & PAD_BUTTON_Y)
- *reg_value = 0xffff;
-#endif
-}
-
-void handle_dsp_mail(void)
-{
- // Should put a loop around this too.
- if (DSP_CheckMailFrom())
- {
- u32 mail = DSP_ReadMailFrom();
-
- if (mail == 0x8071feed)
- {
- // DSP ready for task. Let's send one.
- // First, prepare data.
- for (int n = 0 ; n < 32 ; n++)
- dspbufC[0x00 + n] = dspreg_in[n];
- DCFlushRange(dspbufC, 0x2000);
- // Then send the code.
- DCFlushRange((void *)dsp_code[curUcode], 0x2000);
- real_dsp.SendTask((void *)MEM_VIRTUAL_TO_PHYSICAL(dsp_code[curUcode]),
- 0, 4000, 0x10);
-
- runningUcode = curUcode + 1;
- }
- else if (mail == 0x8888dead)
- {
- u16* tmpBuf = (u16 *)MEM_VIRTUAL_TO_PHYSICAL(mem_dump);
-
- while (DSP_CheckMailTo());
- DSP_SendMailTo((u32)tmpBuf);
- while (DSP_CheckMailTo());
- }
- else if (mail == 0x8888beef)
- {
- while (DSP_CheckMailTo());
- DSP_SendMailTo((u32)dspbufP);
- while (DSP_CheckMailTo());
- }
- else if (mail == 0x8888feeb)
- {
- // We got a stepful of registers.
- DCInvalidateRange(dspbufC, 0x2000);
- for (int i = 0 ; i < 32 ; i++)
- dspreg_out[dsp_steps][i] = dspbufC[0xf80 + i];
-
- dsp_steps++;
-
- while (DSP_CheckMailTo());
- DSP_SendMailTo(0x8000DEAD);
- while (DSP_CheckMailTo());
- }
-
- CON_Printf(2, 1, "UCode: %d/%d %s, Last mail: %08x", runningUcode, NUM_UCODES, UCODE_NAMES[runningUcode - 1], mail);
- }
-}
-
-void dump_all_ucodes(void)
-{
- char filename[260] = {0};
- for(int i = 0; i < NUM_UCODES; i++)
- {
- // First, change the microcode
- dsp_steps = 0;
- curUcode = i;
- runningUcode = 0;
-
- DCInvalidateRange(dspbufC, 0x2000);
- DCFlushRange(dspbufC, 0x2000);
-
- real_dsp.Reset();
- VIDEO_WaitVSync();
-
- while(runningUcode != (curUcode + 1)) {
- handle_dsp_mail();
- VIDEO_WaitVSync();
- }
-
- // Then write microcode dump to file
- sprintf(filename, "sd:/dsp_dump%d.bin", i + 1);
- FILE *f = fopen(filename, "wb");
- if (f)
- {
- // First write initial regs
- fwrite(dspreg_in, 1, 32 * 2, f);
-
- // Then write all the dumps.
- fwrite(dspreg_out, 1, dsp_steps * 32 * 2, f);
- fclose(f);
- strcpy(last_message, "Dump Successful.");
- }
- else
- {
- strcpy(last_message, "SD Write Error");
- break;
- }
- }
-}
-
-// Shove common, un-dsp-ish init things here
-void InitGeneral()
-{
- // Initialise the video system
- VIDEO_Init();
-
- // This function initialises the attached controllers
- PAD_Init();
-#ifdef HW_RVL
- WPAD_Init();
-#endif
-
- // Obtain the preferred video mode from the system
- // This will correspond to the settings in the Wii menu
- rmode = VIDEO_GetPreferredMode(NULL);
-
- // Allocate memory for the display in the uncached region
- xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
-
- // Set up the video registers with the chosen mode
- VIDEO_Configure(rmode);
- // Tell the video hardware where our display memory is
- VIDEO_SetNextFramebuffer(xfb);
- // Make the display visible
- VIDEO_SetBlack(FALSE);
- // Flush the video register changes to the hardware
- VIDEO_Flush();
- // Wait for Video setup to complete
- VIDEO_WaitVSync();
- if (rmode->viTVMode & VI_NON_INTERLACE)
- VIDEO_WaitVSync();
-
- // Initialise the console, required for printf
- CON_Init(xfb, 20, 64, rmode->fbWidth, rmode->xfbHeight, rmode->fbWidth * VI_DISPLAY_PIX_SZ);
-
- // Initialize FAT so we can write to SD.
- fatInit(8, false);
-}
-
-int main()
-{
- InitGeneral();
-
- ui_mode = UIM_SEL;
-
- dspbufP = (u16 *)MEM_VIRTUAL_TO_PHYSICAL(dspbuffer);
- dspbufC = dspbuffer;
- dspbufU = (u32 *)(MEM_K0_TO_K1(dspbuffer));
-
- DCInvalidateRange(dspbuffer, 0x2000);
- for (int j = 0; j < 0x800; j++)
- dspbufU[j] = 0xffffffff;
-
- // Initialize DSP.
- real_dsp.Init();
-
-
- int show_step = 0;
- while (true)
- {
- handle_dsp_mail();
-
- VIDEO_WaitVSync();
-
- PAD_ScanPads();
- if (PAD_ButtonsDown(0) & PAD_BUTTON_START)
- exit(0);
-#ifdef HW_RVL
- WPAD_ScanPads();
- if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME)
- exit(0);
-
- CON_Printf(2, 18, "Controls:");
- CON_Printf(4, 19, "+/- to move");
- CON_Printf(4, 20, "A to edit register, B to start over");
- CON_Printf(4, 21, "1 to move to next microcode");
- CON_Printf(4, 22, "2 to dump all microcode results to SD");
- CON_Printf(4, 23, "Home to exit");
-#else
- CON_Printf(2, 18, "Controls:");
- CON_Printf(4, 19, "L/R to move");
- CON_Printf(4, 21, "A to edit register, B to start over");
- CON_Printf(4, 20, "Z to move to next microcode");
- CON_Printf(4, 22, "Start to exit");
-#endif
-
- print_regs(show_step, dsp_steps);
-
- CON_Printf(4, 24, last_message);
-
- switch (ui_mode)
- {
- case UIM_SEL:
- ui_pad_sel();
- break;
- case UIM_EDIT_REG:
- ui_pad_edit_reg();
- break;
- case UIM_EDIT_BIN:
- // ui_pad_edit_bin();
- break;
- default:
- break;
- }
- DCFlushRange(xfb, 0x200000);
-
-#ifdef HW_RVL
- if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_1) || (PAD_ButtonsDown(0) & PAD_TRIGGER_Z))
-#else
- if (PAD_ButtonsDown(0) & PAD_TRIGGER_Z)
-#endif
- {
- curUcode++;
- if(curUcode == NUM_UCODES)
- curUcode = 0;
-
- // Reset step counters since we're in a new ucode.
- show_step = 0;
- dsp_steps = 0;
-
- DCInvalidateRange(dspbufC, 0x2000);
- for (int n = 0 ; n < 0x2000 ; n++)
- {
- // dspbufU[n/2] = 0; dspbufC[n] = 0;
- }
- DCFlushRange(dspbufC, 0x2000);
-
- // Reset the DSP.
- real_dsp.Reset();
- strcpy(last_message, "OK");
-
- // Waiting for video to synchronize (enough time to set our new microcode)
- VIDEO_WaitVSync();
- }
-
- // Use B to start over.
-#ifdef HW_RVL
- if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_B) || (PAD_ButtonsDown(0) & PAD_BUTTON_B))
-#else
- if (PAD_ButtonsDown(0) & PAD_BUTTON_B)
-#endif
- {
- dsp_steps = 0; // Let's not add the new steps after the original ones. That was just annoying.
-
- DCInvalidateRange(dspbufC, 0x2000);
- DCFlushRange(dspbufC, 0x2000);
-
- // Reset the DSP.
- real_dsp.Reset();
- strcpy(last_message, "OK");
- }
-
- // Navigate between results using + and - buttons.
-#ifdef HW_RVL
- if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_PLUS) || (PAD_ButtonsDown(0) & PAD_TRIGGER_R))
-#else
- if (PAD_ButtonsDown(0) & PAD_TRIGGER_R)
-#endif
- {
- show_step++;
- if (show_step >= dsp_steps)
- show_step = 0;
- strcpy(last_message, "OK");
- }
-#ifdef HW_RVL
- if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_MINUS) || (PAD_ButtonsDown(0) & PAD_TRIGGER_L))
-#else
- if (PAD_ButtonsDown(0) & PAD_TRIGGER_L)
-#endif
- {
- show_step--;
- if (show_step < 0)
- show_step = dsp_steps - 1;
- strcpy(last_message, "OK");
- }
-
-#ifdef HW_RVL
- // Probably could offer to save to sd gecko or something on gc...
- // The future is web-based reporting ;)
- if (WPAD_ButtonsDown(0) & WPAD_BUTTON_2)
- {
- dump_all_ucodes();
- }
-#endif
- }
-
- // Reset the DSP
- real_dsp.Reset();
-
- // Reboot back to Homebrew Channel or whatever started this binary.
- reboot();
-
- // Will never reach here, but just to be sure..
- exit(0);
- return 0;
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// This is a test program for running code on the Wii DSP, with full control over input
+// and automatic compare with output. VERY useful for figuring out what those little
+// ops actually do.
+// It's very unpolished though
+// Use Dolphin's dsptool to generate a new dsp_code.h.
+// Originally written by duddie and modified by FIRES. Then further modified by ector.
+
+#include <gccore.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <network.h>
+#include <ogcsys.h>
+#include <time.h>
+#include <fat.h>
+#include <fcntl.h>
+
+#include <ogc/color.h>
+#include <ogc/consol.h>
+
+#ifdef HW_RVL
+#include <wiiuse/wpad.h>
+#endif
+
+#include "ConsoleHelper.h"
+
+// Pull in some constants etc from DSPCore.
+#include "../Core/DSPCore/Src/gdsp_registers.h"
+
+// This is where the DSP binary is.
+#include "dsp_code.h"
+#include "mem_dump.h"
+
+// Communication with the real DSP and with the DSP emulator.
+#include "dsp_interface.h"
+#include "real_dsp.h"
+// #include "virtual_dsp.h"
+
+// Used for communications with the DSP, such as dumping registers etc.
+u16 dspbuffer[16 * 1024] __attribute__ ((aligned (0x4000)));
+
+static void *xfb = NULL;
+void (*reboot)() = (void(*)())0x80001800;
+GXRModeObj *rmode;
+
+static vu16* const _dspReg = (u16*)0xCC005000;
+
+u16 *dspbufP;
+u16 *dspbufC;
+u32 *dspbufU;
+
+u16 dspreg_in[32] = {
+ 0x0410, 0x0510, 0x0610, 0x0710, 0x0810, 0x0910, 0x0a10, 0x0b10,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0855, 0x0966, 0x0a77, 0x0b88,
+ 0x0014, 0xfff5, 0x00ff, 0x2200, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0003, 0x0004, 0x8000, 0x000C, 0x0007, 0x0008, 0x0009, 0x000a,
+}; /// ax_h_1 ax_h_1
+
+/* ttt ?
+
+u16 dspreg_in[32] = {
+0x0e4c, 0x03c0, 0x0bd9, 0x06a3, 0x0c06, 0x0240, 0x0010, 0x0ecc,
+0x0000, 0x0000, 0x0000, 0x0000, 0x0322, 0x0000, 0x0000, 0x0000,
+0x0000, 0x0000, 0x00ff, 0x1b41, 0x0000, 0x0040, 0x00ff, 0x0000,
+0x1000, 0x96cc, 0x0000, 0x0000, 0x3fc0, 0x96cc, 0x0000, 0x0000,
+}; */
+
+// if i set bit 0x4000 of SR my tests crashes :(
+
+/*
+// zelda 0x00da
+u16 dspreg_in[32] = {
+0x0a50, 0x0ca2, 0x04f8, 0x0ab0, 0x8039, 0x0000, 0x0000, 0x0000,
+0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x03d1, 0x0000, 0x0418, 0x0002, // r08 must have a value ... no idea why (ector: it's the looped addressing regs)
+0x0000, 0x0000, 0x00ff, 0x1804, 0xdb70, 0x4ddb, 0x0000, 0x0000,
+0x0000, 0x0000, 0x0000, 0xde6d, 0x0000, 0x0000, 0x0000, 0x004e,
+};*/
+
+u16 dspreg_out[1000][32];
+
+u32 padding[1024];
+
+// UI (interactive register editing)
+u32 ui_mode;
+
+enum {
+ UIM_SEL = 1,
+ UIM_EDIT_REG = 2,
+ UIM_EDIT_BIN = 4,
+};
+
+// Currently selected register.
+s32 cursor_reg = 0;
+// Currently selected digit.
+s32 small_cursor_x;
+// Value currently being edited.
+u16 *reg_value;
+
+char last_message[20] = "OK";
+
+RealDSP real_dsp;
+
+// Currently running microcode
+int curUcode = 0, runningUcode = 1;
+
+int dsp_steps = 0;
+
+// When comparing regs, ignore the loop stack registers.
+bool regs_equal(int reg, u16 value1, u16 value2) {
+ if (reg >= DSP_REG_ST0 && reg <= DSP_REG_ST3)
+ return true;
+ else
+ return value1 == value2;
+}
+
+void print_reg_block(int x, int y, int sel, const u16 *regs, const u16 *compare_regs)
+{
+ for (int j = 0; j < 4 ; j++)
+ {
+ for (int i = 0; i < 8 ; i++)
+ {
+ // Do not even display the loop stack registers.
+ const int reg = j * 8 + i;
+ CON_SetColor(sel == reg ? CON_BRIGHT_YELLOW : CON_GREEN);
+ CON_Printf(x + j * 8, i + y, "%02x ", reg);
+ if (j != 1 || i < 4)
+ {
+ u8 color1 = regs_equal(reg, regs[reg], compare_regs[reg]) ? CON_BRIGHT_WHITE : CON_BRIGHT_RED;
+ for (int k = 0; k < 4; k++)
+ {
+ if (sel == reg && k == small_cursor_x && ui_mode == UIM_EDIT_REG)
+ CON_SetColor(CON_BRIGHT_CYAN);
+ else
+ CON_SetColor(color1);
+ CON_Printf(x + 3 + j * 8 + k, i + y, "%01x", (regs[reg] >> ((3 - k) * 4)) & 0xf);
+ }
+ }
+ }
+ }
+ CON_SetColor(CON_WHITE);
+
+ CON_Printf(x+2, y+9, "ACC0: %02x %04x %04x", regs[DSP_REG_ACH0]&0xff, regs[DSP_REG_ACM0], regs[DSP_REG_ACL0]);
+ CON_Printf(x+2, y+10, "ACC1: %02x %04x %04x", regs[DSP_REG_ACH1]&0xff, regs[DSP_REG_ACM1], regs[DSP_REG_ACL1]);
+ CON_Printf(x+2, y+11, "AX0: %04x %04x", regs[DSP_REG_AXH0], regs[DSP_REG_AXL0]);
+ CON_Printf(x+2, y+12, "AX1: %04x %04x", regs[DSP_REG_AXH1], regs[DSP_REG_AXL1]);
+}
+
+void print_regs(int _step, int _dsp_steps)
+{
+ const u16 *regs = _step == 0 ? dspreg_in : dspreg_out[_step - 1];
+ const u16 *regs2 = dspreg_out[_step];
+
+ print_reg_block(0, 2, _step == 0 ? cursor_reg : -1, regs, regs2);
+ print_reg_block(33, 2, -1, regs2, regs);
+
+ CON_SetColor(CON_WHITE);
+ CON_Printf(33, 17, "%i / %i ", _step + 1, _dsp_steps);
+
+ return;
+
+ static int count = 0;
+ int x = 0, y = 16;
+ if (count > 2)
+ CON_Clear();
+ count = 0;
+ CON_SetColor(CON_WHITE);
+ for (int i = 0x0; i < 0xf70 ; i++)
+ {
+ if (dspbufC[i] != mem_dump[i])
+ {
+ CON_Printf(x, y, "%04x=%04x", i, dspbufC[i]);
+ count++;
+ x += 10;
+ if (x >= 60) {
+ x = 0;
+ y++;
+ }
+ }
+ }
+ CON_Printf(4, 25, "%08x", count);
+}
+
+void ui_pad_sel(void)
+{
+#ifdef HW_RVL
+ if (WPAD_ButtonsDown(0) & WPAD_BUTTON_RIGHT)
+ cursor_reg += 8;
+ if (WPAD_ButtonsDown(0) & WPAD_BUTTON_LEFT)
+ cursor_reg -= 8;
+ if (WPAD_ButtonsDown(0) & WPAD_BUTTON_UP)
+ cursor_reg--;
+ if (WPAD_ButtonsDown(0) & WPAD_BUTTON_DOWN)
+ cursor_reg++;
+ cursor_reg &= 0x1f;
+ if (WPAD_ButtonsDown(0) & WPAD_BUTTON_A)
+ {
+ ui_mode = UIM_EDIT_REG;
+ reg_value = &dspreg_in[cursor_reg];
+ }
+#else
+ if (PAD_ButtonsDown(0) & PAD_BUTTON_RIGHT)
+ cursor_reg += 8;
+ if (PAD_ButtonsDown(0) & PAD_BUTTON_LEFT)
+ cursor_reg -= 8;
+ if (PAD_ButtonsDown(0) & PAD_BUTTON_UP)
+ cursor_reg--;
+ if (PAD_ButtonsDown(0) & PAD_BUTTON_DOWN)
+ cursor_reg++;
+ cursor_reg &= 0x1f;
+ if (PAD_ButtonsDown(0) & PAD_BUTTON_A)
+ {
+ ui_mode = UIM_EDIT_REG;
+ reg_value = &dspreg_in[cursor_reg];
+ }
+#endif
+}
+
+void ui_pad_edit_reg(void)
+{
+#ifdef HW_RVL
+ if (WPAD_ButtonsDown(0) & WPAD_BUTTON_RIGHT)
+ small_cursor_x++;
+ if (WPAD_ButtonsDown(0) & WPAD_BUTTON_LEFT)
+ small_cursor_x--;
+ small_cursor_x &= 0x3;
+
+ if (WPAD_ButtonsDown(0) & WPAD_BUTTON_UP)
+ *reg_value += 0x1 << (4 * (3 - small_cursor_x));
+ if (WPAD_ButtonsDown(0) & WPAD_BUTTON_DOWN)
+ *reg_value -= 0x1 << (4 * (3 - small_cursor_x));
+ if (WPAD_ButtonsDown(0) & WPAD_BUTTON_A)
+ ui_mode = UIM_SEL;
+ if (WPAD_ButtonsDown(0) & WPAD_BUTTON_1)
+ *reg_value = 0;
+ if (WPAD_ButtonsDown(0) & WPAD_BUTTON_2)
+ *reg_value = 0xffff;
+#else
+ if (PAD_ButtonsDown(0) & PAD_BUTTON_RIGHT)
+ small_cursor_x++;
+ if (PAD_ButtonsDown(0) & PAD_BUTTON_LEFT)
+ small_cursor_x--;
+ small_cursor_x &= 0x3;
+
+ if (PAD_ButtonsDown(0) & PAD_BUTTON_UP)
+ *reg_value += 0x1 << (4 * (3 - small_cursor_x));
+ if (PAD_ButtonsDown(0) & PAD_BUTTON_DOWN)
+ *reg_value -= 0x1 << (4 * (3 - small_cursor_x));
+ if (PAD_ButtonsDown(0) & PAD_BUTTON_A)
+ ui_mode = UIM_SEL;
+ if (PAD_ButtonsDown(0) & PAD_BUTTON_X)
+ *reg_value = 0;
+ if (PAD_ButtonsDown(0) & PAD_BUTTON_Y)
+ *reg_value = 0xffff;
+#endif
+}
+
+void handle_dsp_mail(void)
+{
+ // Should put a loop around this too.
+ if (DSP_CheckMailFrom())
+ {
+ u32 mail = DSP_ReadMailFrom();
+
+ if (mail == 0x8071feed)
+ {
+ // DSP ready for task. Let's send one.
+ // First, prepare data.
+ for (int n = 0 ; n < 32 ; n++)
+ dspbufC[0x00 + n] = dspreg_in[n];
+ DCFlushRange(dspbufC, 0x2000);
+ // Then send the code.
+ DCFlushRange((void *)dsp_code[curUcode], 0x2000);
+ real_dsp.SendTask((void *)MEM_VIRTUAL_TO_PHYSICAL(dsp_code[curUcode]),
+ 0, 4000, 0x10);
+
+ runningUcode = curUcode + 1;
+ }
+ else if (mail == 0x8888dead)
+ {
+ u16* tmpBuf = (u16 *)MEM_VIRTUAL_TO_PHYSICAL(mem_dump);
+
+ while (DSP_CheckMailTo());
+ DSP_SendMailTo((u32)tmpBuf);
+ while (DSP_CheckMailTo());
+ }
+ else if (mail == 0x8888beef)
+ {
+ while (DSP_CheckMailTo());
+ DSP_SendMailTo((u32)dspbufP);
+ while (DSP_CheckMailTo());
+ }
+ else if (mail == 0x8888feeb)
+ {
+ // We got a stepful of registers.
+ DCInvalidateRange(dspbufC, 0x2000);
+ for (int i = 0 ; i < 32 ; i++)
+ dspreg_out[dsp_steps][i] = dspbufC[0xf80 + i];
+
+ dsp_steps++;
+
+ while (DSP_CheckMailTo());
+ DSP_SendMailTo(0x8000DEAD);
+ while (DSP_CheckMailTo());
+ }
+
+ CON_Printf(2, 1, "UCode: %d/%d %s, Last mail: %08x", runningUcode, NUM_UCODES, UCODE_NAMES[runningUcode - 1], mail);
+ }
+}
+
+void dump_all_ucodes(void)
+{
+ char filename[260] = {0};
+ for(int i = 0; i < NUM_UCODES; i++)
+ {
+ // First, change the microcode
+ dsp_steps = 0;
+ curUcode = i;
+ runningUcode = 0;
+
+ DCInvalidateRange(dspbufC, 0x2000);
+ DCFlushRange(dspbufC, 0x2000);
+
+ real_dsp.Reset();
+ VIDEO_WaitVSync();
+
+ while(runningUcode != (curUcode + 1)) {
+ handle_dsp_mail();
+ VIDEO_WaitVSync();
+ }
+
+ // Then write microcode dump to file
+ sprintf(filename, "sd:/dsp_dump%d.bin", i + 1);
+ FILE *f = fopen(filename, "wb");
+ if (f)
+ {
+ // First write initial regs
+ fwrite(dspreg_in, 1, 32 * 2, f);
+
+ // Then write all the dumps.
+ fwrite(dspreg_out, 1, dsp_steps * 32 * 2, f);
+ fclose(f);
+ strcpy(last_message, "Dump Successful.");
+ }
+ else
+ {
+ strcpy(last_message, "SD Write Error");
+ break;
+ }
+ }
+}
+
+// Shove common, un-dsp-ish init things here
+void InitGeneral()
+{
+ // Initialise the video system
+ VIDEO_Init();
+
+ // This function initialises the attached controllers
+ PAD_Init();
+#ifdef HW_RVL
+ WPAD_Init();
+#endif
+
+ // Obtain the preferred video mode from the system
+ // This will correspond to the settings in the Wii menu
+ rmode = VIDEO_GetPreferredMode(NULL);
+
+ // Allocate memory for the display in the uncached region
+ xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
+
+ // Set up the video registers with the chosen mode
+ VIDEO_Configure(rmode);
+ // Tell the video hardware where our display memory is
+ VIDEO_SetNextFramebuffer(xfb);
+ // Make the display visible
+ VIDEO_SetBlack(FALSE);
+ // Flush the video register changes to the hardware
+ VIDEO_Flush();
+ // Wait for Video setup to complete
+ VIDEO_WaitVSync();
+ if (rmode->viTVMode & VI_NON_INTERLACE)
+ VIDEO_WaitVSync();
+
+ // Initialise the console, required for printf
+ CON_Init(xfb, 20, 64, rmode->fbWidth, rmode->xfbHeight, rmode->fbWidth * VI_DISPLAY_PIX_SZ);
+
+ // Initialize FAT so we can write to SD.
+ fatInit(8, false);
+}
+
+int main()
+{
+ InitGeneral();
+
+ ui_mode = UIM_SEL;
+
+ dspbufP = (u16 *)MEM_VIRTUAL_TO_PHYSICAL(dspbuffer);
+ dspbufC = dspbuffer;
+ dspbufU = (u32 *)(MEM_K0_TO_K1(dspbuffer));
+
+ DCInvalidateRange(dspbuffer, 0x2000);
+ for (int j = 0; j < 0x800; j++)
+ dspbufU[j] = 0xffffffff;
+
+ // Initialize DSP.
+ real_dsp.Init();
+
+
+ int show_step = 0;
+ while (true)
+ {
+ handle_dsp_mail();
+
+ VIDEO_WaitVSync();
+
+ PAD_ScanPads();
+ if (PAD_ButtonsDown(0) & PAD_BUTTON_START)
+ exit(0);
+#ifdef HW_RVL
+ WPAD_ScanPads();
+ if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME)
+ exit(0);
+
+ CON_Printf(2, 18, "Controls:");
+ CON_Printf(4, 19, "+/- to move");
+ CON_Printf(4, 20, "A to edit register, B to start over");
+ CON_Printf(4, 21, "1 to move to next microcode");
+ CON_Printf(4, 22, "2 to dump all microcode results to SD");
+ CON_Printf(4, 23, "Home to exit");
+#else
+ CON_Printf(2, 18, "Controls:");
+ CON_Printf(4, 19, "L/R to move");
+ CON_Printf(4, 21, "A to edit register, B to start over");
+ CON_Printf(4, 20, "Z to move to next microcode");
+ CON_Printf(4, 22, "Start to exit");
+#endif
+
+ print_regs(show_step, dsp_steps);
+
+ CON_Printf(4, 24, last_message);
+
+ switch (ui_mode)
+ {
+ case UIM_SEL:
+ ui_pad_sel();
+ break;
+ case UIM_EDIT_REG:
+ ui_pad_edit_reg();
+ break;
+ case UIM_EDIT_BIN:
+ // ui_pad_edit_bin();
+ break;
+ default:
+ break;
+ }
+ DCFlushRange(xfb, 0x200000);
+
+#ifdef HW_RVL
+ if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_1) || (PAD_ButtonsDown(0) & PAD_TRIGGER_Z))
+#else
+ if (PAD_ButtonsDown(0) & PAD_TRIGGER_Z)
+#endif
+ {
+ curUcode++;
+ if(curUcode == NUM_UCODES)
+ curUcode = 0;
+
+ // Reset step counters since we're in a new ucode.
+ show_step = 0;
+ dsp_steps = 0;
+
+ DCInvalidateRange(dspbufC, 0x2000);
+ for (int n = 0 ; n < 0x2000 ; n++)
+ {
+ // dspbufU[n/2] = 0; dspbufC[n] = 0;
+ }
+ DCFlushRange(dspbufC, 0x2000);
+
+ // Reset the DSP.
+ real_dsp.Reset();
+ strcpy(last_message, "OK");
+
+ // Waiting for video to synchronize (enough time to set our new microcode)
+ VIDEO_WaitVSync();
+ }
+
+ // Use B to start over.
+#ifdef HW_RVL
+ if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_B) || (PAD_ButtonsDown(0) & PAD_BUTTON_B))
+#else
+ if (PAD_ButtonsDown(0) & PAD_BUTTON_B)
+#endif
+ {
+ dsp_steps = 0; // Let's not add the new steps after the original ones. That was just annoying.
+
+ DCInvalidateRange(dspbufC, 0x2000);
+ DCFlushRange(dspbufC, 0x2000);
+
+ // Reset the DSP.
+ real_dsp.Reset();
+ strcpy(last_message, "OK");
+ }
+
+ // Navigate between results using + and - buttons.
+#ifdef HW_RVL
+ if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_PLUS) || (PAD_ButtonsDown(0) & PAD_TRIGGER_R))
+#else
+ if (PAD_ButtonsDown(0) & PAD_TRIGGER_R)
+#endif
+ {
+ show_step++;
+ if (show_step >= dsp_steps)
+ show_step = 0;
+ strcpy(last_message, "OK");
+ }
+#ifdef HW_RVL
+ if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_MINUS) || (PAD_ButtonsDown(0) & PAD_TRIGGER_L))
+#else
+ if (PAD_ButtonsDown(0) & PAD_TRIGGER_L)
+#endif
+ {
+ show_step--;
+ if (show_step < 0)
+ show_step = dsp_steps - 1;
+ strcpy(last_message, "OK");
+ }
+
+#ifdef HW_RVL
+ // Probably could offer to save to sd gecko or something on gc...
+ // The future is web-based reporting ;)
+ if (WPAD_ButtonsDown(0) & WPAD_BUTTON_2)
+ {
+ dump_all_ucodes();
+ }
+#endif
+ }
+
+ // Reset the DSP
+ real_dsp.Reset();
+
+ // Reboot back to Homebrew Channel or whatever started this binary.
+ reboot();
+
+ // Will never reach here, but just to be sure..
+ exit(0);
+ return 0;
+}
diff --git a/Source/DSPSpy/real_dsp.cpp b/Source/DSPSpy/real_dsp.cpp
index f99437c8e4..f4ec7505c0 100644
--- a/Source/DSPSpy/real_dsp.cpp
+++ b/Source/DSPSpy/real_dsp.cpp
@@ -1,68 +1,68 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include <gccore.h>
-#include <ogcsys.h>
-#include <ogc/dsp.h>
-#include <ogc/irq.h>
-#include <ogc/machine/asm.h>
-#include <ogc/machine/processor.h>
-
-#include "dsp_interface.h"
-#include "real_dsp.h"
-
-static vu16* const _dspReg = (u16*)0xCC005000;
-
-// Handler for DSP interrupt.
-static void dsp_irq_handler(u32 nIrq, void *pCtx)
-{
- // Acknowledge interrupt?
- _dspReg[5] = (_dspReg[5] & ~(DSPCR_AIINT|DSPCR_ARINT)) | DSPCR_DSPINT;
-}
-
-void RealDSP::Init()
-{
- _dspReg[5] = (_dspReg[5] & ~(DSPCR_AIINT|DSPCR_ARINT|DSPCR_DSPINT)) | DSPCR_DSPRESET;
- _dspReg[5] = (_dspReg[5] & ~(DSPCR_HALT|DSPCR_AIINT|DSPCR_ARINT|DSPCR_DSPINT));
-
- // This code looks odd - shouldn't we initialize level?
- u32 level;
- _CPU_ISR_Disable(level);
- IRQ_Request(IRQ_DSP_DSP, dsp_irq_handler, NULL);
- _CPU_ISR_Restore(level);
-}
-
-void RealDSP::Reset()
-{
- // Reset the DSP.
- _dspReg[5] = (_dspReg[5] & ~(DSPCR_AIINT|DSPCR_ARINT|DSPCR_DSPINT)) | DSPCR_DSPRESET;
- _dspReg[5] = (_dspReg[5] & ~(DSPCR_HALT|DSPCR_AIINT|DSPCR_ARINT|DSPCR_DSPINT));
- _dspReg[5] |= DSPCR_RES;
- while (_dspReg[5] & DSPCR_RES)
- ;
- _dspReg[9] = 0x63;
-}
-
-u32 RealDSP::CheckMailTo()
-{
- return DSP_CheckMailTo();
-}
-
-void RealDSP::SendMailTo(u32 mail)
-{
- DSP_SendMailTo(mail);
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include <gccore.h>
+#include <ogcsys.h>
+#include <ogc/dsp.h>
+#include <ogc/irq.h>
+#include <ogc/machine/asm.h>
+#include <ogc/machine/processor.h>
+
+#include "dsp_interface.h"
+#include "real_dsp.h"
+
+static vu16* const _dspReg = (u16*)0xCC005000;
+
+// Handler for DSP interrupt.
+static void dsp_irq_handler(u32 nIrq, void *pCtx)
+{
+ // Acknowledge interrupt?
+ _dspReg[5] = (_dspReg[5] & ~(DSPCR_AIINT|DSPCR_ARINT)) | DSPCR_DSPINT;
+}
+
+void RealDSP::Init()
+{
+ _dspReg[5] = (_dspReg[5] & ~(DSPCR_AIINT|DSPCR_ARINT|DSPCR_DSPINT)) | DSPCR_DSPRESET;
+ _dspReg[5] = (_dspReg[5] & ~(DSPCR_HALT|DSPCR_AIINT|DSPCR_ARINT|DSPCR_DSPINT));
+
+ // This code looks odd - shouldn't we initialize level?
+ u32 level;
+ _CPU_ISR_Disable(level);
+ IRQ_Request(IRQ_DSP_DSP, dsp_irq_handler, NULL);
+ _CPU_ISR_Restore(level);
+}
+
+void RealDSP::Reset()
+{
+ // Reset the DSP.
+ _dspReg[5] = (_dspReg[5] & ~(DSPCR_AIINT|DSPCR_ARINT|DSPCR_DSPINT)) | DSPCR_DSPRESET;
+ _dspReg[5] = (_dspReg[5] & ~(DSPCR_HALT|DSPCR_AIINT|DSPCR_ARINT|DSPCR_DSPINT));
+ _dspReg[5] |= DSPCR_RES;
+ while (_dspReg[5] & DSPCR_RES)
+ ;
+ _dspReg[9] = 0x63;
+}
+
+u32 RealDSP::CheckMailTo()
+{
+ return DSP_CheckMailTo();
+}
+
+void RealDSP::SendMailTo(u32 mail)
+{
+ DSP_SendMailTo(mail);
+}
diff --git a/Source/DSPSpy/real_dsp.h b/Source/DSPSpy/real_dsp.h
index 70028385fc..3e766faba6 100644
--- a/Source/DSPSpy/real_dsp.h
+++ b/Source/DSPSpy/real_dsp.h
@@ -1,31 +1,31 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _REAL_DSP_H
-#define _REAL_DSP_H
-
-#include "dsp_interface.h"
-
-class RealDSP : public IDSP {
-public:
- virtual void Init();
- virtual void Reset();
- virtual u32 CheckMailTo();
- virtual void SendMailTo(u32 mail);
-};
-
-#endif // _REAL_DSP_H
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _REAL_DSP_H
+#define _REAL_DSP_H
+
+#include "dsp_interface.h"
+
+class RealDSP : public IDSP {
+public:
+ virtual void Init();
+ virtual void Reset();
+ virtual u32 CheckMailTo();
+ virtual void SendMailTo(u32 mail);
+};
+
+#endif // _REAL_DSP_H
diff --git a/Source/DSPTool/Src/main.cpp b/Source/DSPTool/Src/main.cpp
index d86bf4cced..8fb5321298 100644
--- a/Source/DSPTool/Src/main.cpp
+++ b/Source/DSPTool/Src/main.cpp
@@ -1,403 +1,403 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Common.h"
-#include "FileUtil.h"
-#include "DSPCodeUtil.h"
-
-// Stub out the dsplib host stuff, since this is just a simple cmdline tools.
-u8 DSPHost_ReadHostMemory(u32 addr) { return 0; }
-void DSPHost_WriteHostMemory(u8 value, u32 addr) {}
-bool DSPHost_OnThread() { return false; }
-bool DSPHost_Running() { return true; }
-u32 DSPHost_CodeLoaded(const u8 *ptr, int size) {return 0x1337c0de;}
-void DSPHost_InterruptRequest() {}
-void DSPHost_UpdateDebugger() {}
-
-// This test goes from text ASM to binary to text ASM and once again back to binary.
-// Then the two binaries are compared.
-bool RoundTrip(const std::vector<u16> &code1)
-{
- std::vector<u16> code2;
- std::string text;
- if (!Disassemble(code1, false, text))
- {
- printf("RoundTrip: Disassembly failed.\n");
- return false;
- }
- if (!Assemble(text.c_str(), code2))
- {
- printf("RoundTrip: Assembly failed.\n");
- return false;
- }
- if (!Compare(code1, code2))
- {
- Disassemble(code1, true, text);
- printf("%s", text.c_str());
- }
- return true;
-}
-
-// This test goes from text ASM to binary to text ASM and once again back to binary.
-// Very convenient for testing. Then the two binaries are compared.
-bool SuperTrip(const char *asm_code)
-{
- std::vector<u16> code1, code2;
- std::string text;
- if (!Assemble(asm_code, code1))
- {
- printf("SuperTrip: First assembly failed\n");
- return false;
- }
- printf("First assembly: %i words\n", (int)code1.size());
- if (!Disassemble(code1, false, text))
- {
- printf("SuperTrip: Disassembly failed\n");
- return false;
- }
- else
- {
- printf("Disass:\n");
- printf("%s", text.c_str());
- }
- if (!Assemble(text.c_str(), code2))
- {
- printf("SuperTrip: Second assembly failed\n");
- return false;
- }
- /*
- std::string text2;
- Disassemble(code1, true, &text1);
- Disassemble(code2, true, &text2);
- File::WriteStringToFile(true, text1, "code1.txt");
- File::WriteStringToFile(true, text2, "code2.txt");
- */
- return true;
-}
-
-void RunAsmTests()
-{
- bool fail = false;
-#define CHK(a) if (!SuperTrip(a)) printf("FAIL\n%s\n", a), fail = true;
-
- // Let's start out easy - a trivial instruction..
- CHK(" NOP\n");
-
- // Now let's do several.
- CHK(" NOP\n"
- " NOP\n"
- " NOP\n");
-
- // Turning it up a notch.
- CHK(" SET16\n"
- " SET40\n"
- " CLR15\n"
- " M0\n"
- " M2\n");
-
- // Time to try labels and parameters, and comments.
- CHK("DIRQ_TEST: equ 0xfffb ; DSP Irq Request\n"
- " si @0xfffc, #0x8888\n"
- " si @0xfffd, #0xbeef\n"
- " si @DIRQ_TEST, #0x0001\n");
-
- // Let's see if registers roundtrip. Also try predefined labels.
- CHK(" si @0xfffc, #0x8888\n"
- " si @0xfffd, #0xbeef\n"
- " si @DIRQ, #0x0001\n");
-
- // Let's try some messy extended instructions.
- //CHK(" MULMV'SN $AX0.L, $AX0.H, $ACC0 : @$AR2, $AC1.M\n");
-
- //" ADDAXL'MV $ACC1, $AX1.L : $AX1.H, $AC1.M\n");
- // Let's get brutal. We generate random code bytes and make sure that they can
- // be roundtripped. We don't expect it to always succeed but it'll be sure to generate
-
- // interesting test cases.
- /*
- std::vector<u16> hermes;
- if (!LoadBinary("testdata/hermes.bin", &hermes))
- PanicAlert("Failed to load hermes rom");
- RoundTrip(hermes);
- */
- /*
- std::vector<u16> code;
- std::string text_orig;
- File::ReadFileToString(false, "testdata/dsp_test.S", &text_orig);
- if (!Assemble(text_orig.c_str(), &code))
- {
- printf("SuperTrip: First assembly failed\n");
- return;
- }*/
-
- /*
- {
- std::vector<u16> code;
- code.clear();
- for (int i = 0; i < sizeof(dsp_test)/4; i++)
- {
- code.push_back(dsp_test[i] >> 16);
- code.push_back(dsp_test[i] & 0xFFFF);
- }
-
- SaveBinary(code, "dsp_test2.bin");
- RoundTrip(code);
- }*/
- //if (Compare(code, hermes))
- // printf("Successs\n");
-/*
- {
- std::vector<u16> code;
- std::string text;
- LoadBinary("testdata/dsp_test.bin", &code);
- Disassemble(code, true, &text);
- Assemble(text.c_str(), &code);
- Disassemble(code, true, &text);
- printf("%s", text.c_str());
- }*/
- /*
- puts("Insane Random Code Test\n");
- std::vector<u16> rand_code;
- GenRandomCode(30, &rand_code);
- std::string rand_code_text;
- Disassemble(rand_code, true, &rand_code_text);
- printf("%s", rand_code_text.c_str());
- RoundTrip(rand_code);
-
-
- if (File::ReadFileToString(true, "C:/devkitPro/examples/wii/asndlib/dsptest/dsp_test.ds", &dsp_test))
- SuperTrip(dsp_test.c_str());
-
- //.File::ReadFileToString(true, "C:/devkitPro/trunk/libogc/libasnd/dsp_mixer/dsp_mixer.s", &dsp_test);
- // This is CLOSE to working. Sorry about the local path btw. This is preliminary code.
-*/
-
- std::string dsp_test;
- if (File::ReadFileToString(true, "Testdata/dsp_test.s", dsp_test))
- fail = fail || !SuperTrip(dsp_test.c_str());
- if (!fail)
- printf("All passed!\n");
-}
-
-
-// Usage:
-// Run internal tests:
-// dsptool test
-// Disassemble a file:
-// dsptool -d -o asdf.txt asdf.bin
-// Disassemble a file, output to standard output:
-// dsptool -d asdf.bin
-// Assemble a file:
-// dsptool -o asdf.bin asdf.txt
-// Assemble a file, output header:
-// dsptool -h asdf.h asdf.txt
-
-// So far, all this binary can do is test partially that itself works correctly.
-int main(int argc, const char *argv[])
-{
- if(argc == 1 || (argc == 2 && (!strcmp(argv[1], "--help") || (!strcmp(argv[1], "-?")))))
- {
- printf("USAGE: DSPTool [-?] [--help] [-d] [-m] [-o <FILE>] [-h <FILE>] <DSP ASSEMBLER FILE>\n");
- printf("-? / --help: Prints this message\n");
- printf("-d: Disassemble\n");
- printf("-m: Input file contains a list of files (Header assembly only)\n");
- printf("-s: Print the final size in bytes (only)\n");
- printf("-o <OUTPUT FILE>: Results from stdout redirected to a file\n");
- printf("-h <HEADER FILE>: Output assembly results to a header\n");
- return 0;
- }
-
- if (argc == 2 && !strcmp(argv[1], "test"))
- {
- RunAsmTests();
- return 0;
- }
-
- std::string input_name;
- std::string output_header_name;
- std::string output_name;
-
- bool disassemble = false, compare = false, multiple = false, outputSize = false;
- for (int i = 1; i < argc; i++)
- {
- if (!strcmp(argv[i], "-d"))
- disassemble = true;
- else if (!strcmp(argv[i], "-o"))
- output_name = argv[++i];
- else if (!strcmp(argv[i], "-h"))
- output_header_name = argv[++i];
- else if (!strcmp(argv[i], "-c"))
- compare = true;
- else if (!strcmp(argv[i], "-s"))
- outputSize = true;
- else if (!strcmp(argv[i], "-m"))
- multiple = true;
- else
- {
- if (!input_name.empty())
- {
- printf("ERROR: Can only take one input file.\n");
- return 1;
- }
- input_name = argv[i];
- if (!File::Exists(input_name.c_str()))
- {
- printf("ERROR: Input path does not exist.\n");
- return 1;
- }
- }
- }
-
- if(multiple && (compare || disassemble || !output_name.empty() ||
- input_name.empty())) {
- printf("ERROR: Multiple files can only be used with assembly "
- "and must compile a header file.\n");
- return 1;
- }
-
- if (compare)
- {
- // Two binary inputs, let's diff.
- std::string binary_code;
- std::vector<u16> code1, code2;
- File::ReadFileToString(false, input_name.c_str(), binary_code);
- BinaryStringBEToCode(binary_code, code1);
- File::ReadFileToString(false, output_name.c_str(), binary_code);
- BinaryStringBEToCode(binary_code, code2);
- Compare(code1, code2);
- return 0;
- }
-
- if (disassemble)
- {
- if (input_name.empty())
- {
- printf("Disassemble: Must specify input.\n");
- return 1;
- }
- std::string binary_code;
- std::vector<u16> code;
- File::ReadFileToString(false, input_name.c_str(), binary_code);
- BinaryStringBEToCode(binary_code, code);
- std::string text;
- Disassemble(code, true, text);
- if (!output_name.empty())
- File::WriteStringToFile(true, text, output_name.c_str());
- else
- printf("%s", text.c_str());
- }
- else
- {
- if (input_name.empty())
- {
- printf("Assemble: Must specify input.\n");
- return 1;
- }
- std::string source;
- if (File::ReadFileToString(true, input_name.c_str(), source))
- {
- if(multiple)
- {
- // When specifying a list of files we must compile a header
- // (we can't assemble multiple files to one binary)
- // since we checked it before, we assume output_header_name isn't empty
- int lines;
- std::vector<u16> *codes;
- std::vector<std::string> files;
- std::string header, currentSource;
- size_t lastPos = 0, pos = 0;
-
- source.append("\n");
-
- while((pos = source.find('\n', lastPos)) != std::string::npos)
- {
- std::string temp = source.substr(lastPos, pos - lastPos);
- if(!temp.empty())
- files.push_back(temp);
- lastPos = pos + 1;
- }
-
- lines = (int)files.size();
-
- if(lines == 0)
- {
- printf("ERROR: Must specify at least one file\n");
- return 1;
- }
-
- codes = new std::vector<u16>[lines];
-
- for(int i = 0; i < lines; i++)
- {
- if (!File::ReadFileToString(true, files[i].c_str(), currentSource))
- {
- printf("ERROR reading %s, skipping...\n", files[i].c_str());
- lines--;
- }
- else
- {
- if(!Assemble(currentSource.c_str(), codes[i]))
- {
- printf("Assemble: Assembly of %s failed due to errors\n",
- files[i].c_str());
- lines--;
- }
- if(outputSize)
- printf("%s: %d\n", files[i].c_str(), codes[i].size());
- }
- }
-
-
- CodesToHeader(codes, &files, lines, output_header_name.c_str(), header);
- File::WriteStringToFile(true, header, (output_header_name + ".h").c_str());
-
- delete[] codes;
- }
- else
- {
- std::vector<u16> code;
-
- if(!Assemble(source.c_str(), code)) {
- printf("Assemble: Assembly failed due to errors\n");
- return 1;
- }
-
- if(outputSize)
- printf("%s: %d\n", input_name.c_str(), code.size());
-
- if (!output_name.empty())
- {
- std::string binary_code;
- CodeToBinaryStringBE(code, binary_code);
- File::WriteStringToFile(false, binary_code, output_name.c_str());
- }
- if (!output_header_name.empty())
- {
- std::string header;
- CodeToHeader(code, input_name, output_header_name.c_str(), header);
- File::WriteStringToFile(true, header, (output_header_name + ".h").c_str());
- }
- }
- }
- source.clear();
- }
-
- if(!outputSize)
- printf("Assembly completed successfully!\n");
-
- return 0;
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "Common.h"
+#include "FileUtil.h"
+#include "DSPCodeUtil.h"
+
+// Stub out the dsplib host stuff, since this is just a simple cmdline tools.
+u8 DSPHost_ReadHostMemory(u32 addr) { return 0; }
+void DSPHost_WriteHostMemory(u8 value, u32 addr) {}
+bool DSPHost_OnThread() { return false; }
+bool DSPHost_Running() { return true; }
+u32 DSPHost_CodeLoaded(const u8 *ptr, int size) {return 0x1337c0de;}
+void DSPHost_InterruptRequest() {}
+void DSPHost_UpdateDebugger() {}
+
+// This test goes from text ASM to binary to text ASM and once again back to binary.
+// Then the two binaries are compared.
+bool RoundTrip(const std::vector<u16> &code1)
+{
+ std::vector<u16> code2;
+ std::string text;
+ if (!Disassemble(code1, false, text))
+ {
+ printf("RoundTrip: Disassembly failed.\n");
+ return false;
+ }
+ if (!Assemble(text.c_str(), code2))
+ {
+ printf("RoundTrip: Assembly failed.\n");
+ return false;
+ }
+ if (!Compare(code1, code2))
+ {
+ Disassemble(code1, true, text);
+ printf("%s", text.c_str());
+ }
+ return true;
+}
+
+// This test goes from text ASM to binary to text ASM and once again back to binary.
+// Very convenient for testing. Then the two binaries are compared.
+bool SuperTrip(const char *asm_code)
+{
+ std::vector<u16> code1, code2;
+ std::string text;
+ if (!Assemble(asm_code, code1))
+ {
+ printf("SuperTrip: First assembly failed\n");
+ return false;
+ }
+ printf("First assembly: %i words\n", (int)code1.size());
+ if (!Disassemble(code1, false, text))
+ {
+ printf("SuperTrip: Disassembly failed\n");
+ return false;
+ }
+ else
+ {
+ printf("Disass:\n");
+ printf("%s", text.c_str());
+ }
+ if (!Assemble(text.c_str(), code2))
+ {
+ printf("SuperTrip: Second assembly failed\n");
+ return false;
+ }
+ /*
+ std::string text2;
+ Disassemble(code1, true, &text1);
+ Disassemble(code2, true, &text2);
+ File::WriteStringToFile(true, text1, "code1.txt");
+ File::WriteStringToFile(true, text2, "code2.txt");
+ */
+ return true;
+}
+
+void RunAsmTests()
+{
+ bool fail = false;
+#define CHK(a) if (!SuperTrip(a)) printf("FAIL\n%s\n", a), fail = true;
+
+ // Let's start out easy - a trivial instruction..
+ CHK(" NOP\n");
+
+ // Now let's do several.
+ CHK(" NOP\n"
+ " NOP\n"
+ " NOP\n");
+
+ // Turning it up a notch.
+ CHK(" SET16\n"
+ " SET40\n"
+ " CLR15\n"
+ " M0\n"
+ " M2\n");
+
+ // Time to try labels and parameters, and comments.
+ CHK("DIRQ_TEST: equ 0xfffb ; DSP Irq Request\n"
+ " si @0xfffc, #0x8888\n"
+ " si @0xfffd, #0xbeef\n"
+ " si @DIRQ_TEST, #0x0001\n");
+
+ // Let's see if registers roundtrip. Also try predefined labels.
+ CHK(" si @0xfffc, #0x8888\n"
+ " si @0xfffd, #0xbeef\n"
+ " si @DIRQ, #0x0001\n");
+
+ // Let's try some messy extended instructions.
+ //CHK(" MULMV'SN $AX0.L, $AX0.H, $ACC0 : @$AR2, $AC1.M\n");
+
+ //" ADDAXL'MV $ACC1, $AX1.L : $AX1.H, $AC1.M\n");
+ // Let's get brutal. We generate random code bytes and make sure that they can
+ // be roundtripped. We don't expect it to always succeed but it'll be sure to generate
+
+ // interesting test cases.
+ /*
+ std::vector<u16> hermes;
+ if (!LoadBinary("testdata/hermes.bin", &hermes))
+ PanicAlert("Failed to load hermes rom");
+ RoundTrip(hermes);
+ */
+ /*
+ std::vector<u16> code;
+ std::string text_orig;
+ File::ReadFileToString(false, "testdata/dsp_test.S", &text_orig);
+ if (!Assemble(text_orig.c_str(), &code))
+ {
+ printf("SuperTrip: First assembly failed\n");
+ return;
+ }*/
+
+ /*
+ {
+ std::vector<u16> code;
+ code.clear();
+ for (int i = 0; i < sizeof(dsp_test)/4; i++)
+ {
+ code.push_back(dsp_test[i] >> 16);
+ code.push_back(dsp_test[i] & 0xFFFF);
+ }
+
+ SaveBinary(code, "dsp_test2.bin");
+ RoundTrip(code);
+ }*/
+ //if (Compare(code, hermes))
+ // printf("Successs\n");
+/*
+ {
+ std::vector<u16> code;
+ std::string text;
+ LoadBinary("testdata/dsp_test.bin", &code);
+ Disassemble(code, true, &text);
+ Assemble(text.c_str(), &code);
+ Disassemble(code, true, &text);
+ printf("%s", text.c_str());
+ }*/
+ /*
+ puts("Insane Random Code Test\n");
+ std::vector<u16> rand_code;
+ GenRandomCode(30, &rand_code);
+ std::string rand_code_text;
+ Disassemble(rand_code, true, &rand_code_text);
+ printf("%s", rand_code_text.c_str());
+ RoundTrip(rand_code);
+
+
+ if (File::ReadFileToString(true, "C:/devkitPro/examples/wii/asndlib/dsptest/dsp_test.ds", &dsp_test))
+ SuperTrip(dsp_test.c_str());
+
+ //.File::ReadFileToString(true, "C:/devkitPro/trunk/libogc/libasnd/dsp_mixer/dsp_mixer.s", &dsp_test);
+ // This is CLOSE to working. Sorry about the local path btw. This is preliminary code.
+*/
+
+ std::string dsp_test;
+ if (File::ReadFileToString(true, "Testdata/dsp_test.s", dsp_test))
+ fail = fail || !SuperTrip(dsp_test.c_str());
+ if (!fail)
+ printf("All passed!\n");
+}
+
+
+// Usage:
+// Run internal tests:
+// dsptool test
+// Disassemble a file:
+// dsptool -d -o asdf.txt asdf.bin
+// Disassemble a file, output to standard output:
+// dsptool -d asdf.bin
+// Assemble a file:
+// dsptool -o asdf.bin asdf.txt
+// Assemble a file, output header:
+// dsptool -h asdf.h asdf.txt
+
+// So far, all this binary can do is test partially that itself works correctly.
+int main(int argc, const char *argv[])
+{
+ if(argc == 1 || (argc == 2 && (!strcmp(argv[1], "--help") || (!strcmp(argv[1], "-?")))))
+ {
+ printf("USAGE: DSPTool [-?] [--help] [-d] [-m] [-o <FILE>] [-h <FILE>] <DSP ASSEMBLER FILE>\n");
+ printf("-? / --help: Prints this message\n");
+ printf("-d: Disassemble\n");
+ printf("-m: Input file contains a list of files (Header assembly only)\n");
+ printf("-s: Print the final size in bytes (only)\n");
+ printf("-o <OUTPUT FILE>: Results from stdout redirected to a file\n");
+ printf("-h <HEADER FILE>: Output assembly results to a header\n");
+ return 0;
+ }
+
+ if (argc == 2 && !strcmp(argv[1], "test"))
+ {
+ RunAsmTests();
+ return 0;
+ }
+
+ std::string input_name;
+ std::string output_header_name;
+ std::string output_name;
+
+ bool disassemble = false, compare = false, multiple = false, outputSize = false;
+ for (int i = 1; i < argc; i++)
+ {
+ if (!strcmp(argv[i], "-d"))
+ disassemble = true;
+ else if (!strcmp(argv[i], "-o"))
+ output_name = argv[++i];
+ else if (!strcmp(argv[i], "-h"))
+ output_header_name = argv[++i];
+ else if (!strcmp(argv[i], "-c"))
+ compare = true;
+ else if (!strcmp(argv[i], "-s"))
+ outputSize = true;
+ else if (!strcmp(argv[i], "-m"))
+ multiple = true;
+ else
+ {
+ if (!input_name.empty())
+ {
+ printf("ERROR: Can only take one input file.\n");
+ return 1;
+ }
+ input_name = argv[i];
+ if (!File::Exists(input_name.c_str()))
+ {
+ printf("ERROR: Input path does not exist.\n");
+ return 1;
+ }
+ }
+ }
+
+ if(multiple && (compare || disassemble || !output_name.empty() ||
+ input_name.empty())) {
+ printf("ERROR: Multiple files can only be used with assembly "
+ "and must compile a header file.\n");
+ return 1;
+ }
+
+ if (compare)
+ {
+ // Two binary inputs, let's diff.
+ std::string binary_code;
+ std::vector<u16> code1, code2;
+ File::ReadFileToString(false, input_name.c_str(), binary_code);
+ BinaryStringBEToCode(binary_code, code1);
+ File::ReadFileToString(false, output_name.c_str(), binary_code);
+ BinaryStringBEToCode(binary_code, code2);
+ Compare(code1, code2);
+ return 0;
+ }
+
+ if (disassemble)
+ {
+ if (input_name.empty())
+ {
+ printf("Disassemble: Must specify input.\n");
+ return 1;
+ }
+ std::string binary_code;
+ std::vector<u16> code;
+ File::ReadFileToString(false, input_name.c_str(), binary_code);
+ BinaryStringBEToCode(binary_code, code);
+ std::string text;
+ Disassemble(code, true, text);
+ if (!output_name.empty())
+ File::WriteStringToFile(true, text, output_name.c_str());
+ else
+ printf("%s", text.c_str());
+ }
+ else
+ {
+ if (input_name.empty())
+ {
+ printf("Assemble: Must specify input.\n");
+ return 1;
+ }
+ std::string source;
+ if (File::ReadFileToString(true, input_name.c_str(), source))
+ {
+ if(multiple)
+ {
+ // When specifying a list of files we must compile a header
+ // (we can't assemble multiple files to one binary)
+ // since we checked it before, we assume output_header_name isn't empty
+ int lines;
+ std::vector<u16> *codes;
+ std::vector<std::string> files;
+ std::string header, currentSource;
+ size_t lastPos = 0, pos = 0;
+
+ source.append("\n");
+
+ while((pos = source.find('\n', lastPos)) != std::string::npos)
+ {
+ std::string temp = source.substr(lastPos, pos - lastPos);
+ if(!temp.empty())
+ files.push_back(temp);
+ lastPos = pos + 1;
+ }
+
+ lines = (int)files.size();
+
+ if(lines == 0)
+ {
+ printf("ERROR: Must specify at least one file\n");
+ return 1;
+ }
+
+ codes = new std::vector<u16>[lines];
+
+ for(int i = 0; i < lines; i++)
+ {
+ if (!File::ReadFileToString(true, files[i].c_str(), currentSource))
+ {
+ printf("ERROR reading %s, skipping...\n", files[i].c_str());
+ lines--;
+ }
+ else
+ {
+ if(!Assemble(currentSource.c_str(), codes[i]))
+ {
+ printf("Assemble: Assembly of %s failed due to errors\n",
+ files[i].c_str());
+ lines--;
+ }
+ if(outputSize)
+ printf("%s: %d\n", files[i].c_str(), codes[i].size());
+ }
+ }
+
+
+ CodesToHeader(codes, &files, lines, output_header_name.c_str(), header);
+ File::WriteStringToFile(true, header, (output_header_name + ".h").c_str());
+
+ delete[] codes;
+ }
+ else
+ {
+ std::vector<u16> code;
+
+ if(!Assemble(source.c_str(), code)) {
+ printf("Assemble: Assembly failed due to errors\n");
+ return 1;
+ }
+
+ if(outputSize)
+ printf("%s: %d\n", input_name.c_str(), code.size());
+
+ if (!output_name.empty())
+ {
+ std::string binary_code;
+ CodeToBinaryStringBE(code, binary_code);
+ File::WriteStringToFile(false, binary_code, output_name.c_str());
+ }
+ if (!output_header_name.empty())
+ {
+ std::string header;
+ CodeToHeader(code, input_name, output_header_name.c_str(), header);
+ File::WriteStringToFile(true, header, (output_header_name + ".h").c_str());
+ }
+ }
+ }
+ source.clear();
+ }
+
+ if(!outputSize)
+ printf("Assembly completed successfully!\n");
+
+ return 0;
+}
diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/HLEMixer.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/HLEMixer.cpp
index fdb4f1b2e6..f36e512eec 100644
--- a/Source/Plugins/Plugin_DSP_HLE/Src/HLEMixer.cpp
+++ b/Source/Plugins/Plugin_DSP_HLE/Src/HLEMixer.cpp
@@ -1,42 +1,42 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Config.h" // Local
-#include "Globals.h"
-#include "DSPHandler.h"
-#include "HLEMixer.h"
-
-void HLEMixer::MixUCode(short *samples, int numSamples) {
- // if this was called directly from the HLE, and not by timeout
- if (g_Config.m_EnableHLEAudio && IsHLEReady()) {
- IUCode* pUCode = CDSPHandler::GetInstance().GetUCode();
- if (pUCode != NULL)
- pUCode->MixAdd(samples, numSamples);
- }
-}
-
-void HLEMixer::Premix(short *samples, int numSamples) {
-
- // first get the DTK Music
- // if (g_Config.m_EnableDTKMusic) {
- // g_dspInitialize.pGetAudioStreaming(samples, numSamples);
- // }
-
- MixUCode(samples, numSamples);
-}
-
-
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "Config.h" // Local
+#include "Globals.h"
+#include "DSPHandler.h"
+#include "HLEMixer.h"
+
+void HLEMixer::MixUCode(short *samples, int numSamples) {
+ // if this was called directly from the HLE, and not by timeout
+ if (g_Config.m_EnableHLEAudio && IsHLEReady()) {
+ IUCode* pUCode = CDSPHandler::GetInstance().GetUCode();
+ if (pUCode != NULL)
+ pUCode->MixAdd(samples, numSamples);
+ }
+}
+
+void HLEMixer::Premix(short *samples, int numSamples) {
+
+ // first get the DTK Music
+ // if (g_Config.m_EnableDTKMusic) {
+ // g_dspInitialize.pGetAudioStreaming(samples, numSamples);
+ // }
+
+ MixUCode(samples, numSamples);
+}
+
+
diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_ADPCM.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_ADPCM.cpp
index 2bacf5a4a5..b611a5c7d5 100644
--- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_ADPCM.cpp
+++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_ADPCM.cpp
@@ -1,95 +1,95 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Common.h"
-#include "UCode_Zelda_ADPCM.h"
-
-void AFCdecodebuffer(const s16 *coef, const char *input, signed short *out, short *histp, short *hist2p, int type)
-{
- short nibbles[16];
- short hist = *histp;
- short hist2 = *hist2p;
-
- const char *src = input;
- char *dst = (char*)out;
-
- // First 2 nibbles are ADPCM scale etc.
- short delta = 1 << (((*src) >> 4) & 0xf);
- short idx = (*src) & 0xf;
- src++;
-
- if (type == 9)
- {
- for (int i = 0; i < 16; i = i + 2) {
- int j = (*src & 255) >> 4;
- nibbles[i] = j;
- j = *src & 255 & 15;
- nibbles[i+1] = j;
- src++;
- }
-
- for (int i = 0; i < 16; i = i + 1) {
- if (nibbles[i] >= 8)
- nibbles[i] = nibbles[i] - 16;
- }
- }
- else
- {
- // untested !!! i havnt seen such a sample yet :)
- for (int i = 0; i < 16; i += 4)
- {
- int j = (*src >> 0) & 0x02;
- nibbles[i] = j;
-
- j = (*src >> 2) & 0x02;
- nibbles[i+1] = j;
-
- j = (*src >> 4) & 0x02;
- nibbles[i+2] = j;
-
- j = (*src >> 6) & 0x02;
- nibbles[i+3] = j;
-
- src++;
- }
-
- for (int i = 0; i < 16; i++)
- {
- if (nibbles[i] >= 2)
- nibbles[i] = nibbles[i] - 4;
- }
- }
-
- for (int i = 0; i < 16; i++)
- {
- int sample = (delta * nibbles[i]) << 11;
- sample += ((long)hist * coef[idx * 2]) + ((long)hist2 * coef[idx * 2 + 1]);
- sample = sample >> 11;
- if (sample > 32767) {
- sample = 32767;
- }
- if (sample < -32768) {
- sample = -32768;
- }
- *(short*)dst = (short)sample;
- dst = dst + 2;
- hist2 = hist;
- hist = (short)sample;
- }
- *histp = hist;
- *hist2p = hist2;
-}
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "Common.h"
+#include "UCode_Zelda_ADPCM.h"
+
+void AFCdecodebuffer(const s16 *coef, const char *input, signed short *out, short *histp, short *hist2p, int type)
+{
+ short nibbles[16];
+ short hist = *histp;
+ short hist2 = *hist2p;
+
+ const char *src = input;
+ char *dst = (char*)out;
+
+ // First 2 nibbles are ADPCM scale etc.
+ short delta = 1 << (((*src) >> 4) & 0xf);
+ short idx = (*src) & 0xf;
+ src++;
+
+ if (type == 9)
+ {
+ for (int i = 0; i < 16; i = i + 2) {
+ int j = (*src & 255) >> 4;
+ nibbles[i] = j;
+ j = *src & 255 & 15;
+ nibbles[i+1] = j;
+ src++;
+ }
+
+ for (int i = 0; i < 16; i = i + 1) {
+ if (nibbles[i] >= 8)
+ nibbles[i] = nibbles[i] - 16;
+ }
+ }
+ else
+ {
+ // untested !!! i havnt seen such a sample yet :)
+ for (int i = 0; i < 16; i += 4)
+ {
+ int j = (*src >> 0) & 0x02;
+ nibbles[i] = j;
+
+ j = (*src >> 2) & 0x02;
+ nibbles[i+1] = j;
+
+ j = (*src >> 4) & 0x02;
+ nibbles[i+2] = j;
+
+ j = (*src >> 6) & 0x02;
+ nibbles[i+3] = j;
+
+ src++;
+ }
+
+ for (int i = 0; i < 16; i++)
+ {
+ if (nibbles[i] >= 2)
+ nibbles[i] = nibbles[i] - 4;
+ }
+ }
+
+ for (int i = 0; i < 16; i++)
+ {
+ int sample = (delta * nibbles[i]) << 11;
+ sample += ((long)hist * coef[idx * 2]) + ((long)hist2 * coef[idx * 2 + 1]);
+ sample = sample >> 11;
+ if (sample > 32767) {
+ sample = 32767;
+ }
+ if (sample < -32768) {
+ sample = -32768;
+ }
+ *(short*)dst = (short)sample;
+ dst = dst + 2;
+ hist2 = hist;
+ hist = (short)sample;
+ }
+ *histp = hist;
+ *hist2p = hist2;
+}
diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_ADPCM.h b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_ADPCM.h
index 1839ff4eae..0af424494c 100644
--- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_ADPCM.h
+++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_ADPCM.h
@@ -1,20 +1,20 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Common.h"
-
-void AFCdecodebuffer(const s16 *coef, const char *input, signed short *out, short *histp, short *hist2p, int type);
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "Common.h"
+
+void AFCdecodebuffer(const s16 *coef, const char *input, signed short *out, short *histp, short *hist2p, int type);
diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_Synth.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_Synth.cpp
index 70da655bc0..9fe87f4fb9 100644
--- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_Synth.cpp
+++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_Synth.cpp
@@ -1,106 +1,106 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "../Globals.h"
-#include "UCodes.h"
-#include "UCode_Zelda.h"
-#include "UCode_Zelda_ADPCM.h"
-
-#include "../main.h"
-#include "Mixer.h"
-
-void CUCode_Zelda::RenderSynth_Waveform(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
-{
- float ratioFactor = 32000.0f / (float)soundStream->GetMixer()->GetSampleRate();
- u32 _ratio = (PB.RatioInt << 16);
- s64 ratio = (_ratio * ratioFactor) * 16;
- s64 TrueSamplePosition = (s64)(PB.Length - PB.RemLength) << 16;
- TrueSamplePosition += PB.CurSampleFrac;
-
- int mask = PB.Format ? 3 : 1, shift = PB.Format ? 2 : 1;
-
- u32 pos[2] = {0, 0};
- int i = 0;
-
- if (PB.KeyOff != 0)
- return;
-
- if (PB.NeedsReset)
- {
- PB.RemLength = PB.Length - PB.RestartPos;
- PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
- PB.ReachedEnd = 0;
- }
-
-_lRestart:
- if (PB.ReachedEnd)
- {
- PB.ReachedEnd = 0;
-
- if (PB.RepeatMode == 0)
- {
- PB.KeyOff = 1;
- PB.RemLength = 0;
- PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1) + PB.Length;
- return;
- }
- else
- {
- PB.RestartPos = PB.LoopStartPos;
- PB.RemLength = PB.Length - PB.RestartPos;
- PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
- pos[1] = 0; pos[0] = 0;
- }
- }
-
- while(i < _Size)
- {
- s16 sample = ((pos[1] & mask) == mask) ? 0xc000 : 0x4000;
-
- TrueSamplePosition += (ratio >> 16);
-
- _Buffer[i++] = (s32)sample;
-
- (*(u64*)&pos) += ratio;
- if ((pos[1] + ((PB.CurAddr - PB.StartAddr) >> 1)) >= PB.Length)
- {
- PB.ReachedEnd = 1;
- goto _lRestart;
- }
- }
-
- if (PB.RemLength < pos[1])
- {
- PB.RemLength = 0;
- PB.ReachedEnd = 1;
- }
- else
- PB.RemLength -= pos[1];
-
- PB.CurSampleFrac = TrueSamplePosition & 0xFFFF;
-}
-
-
-void CUCode_Zelda::RenderSynth_Constant(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
-{
- // TODO: Header, footer and cases this synth actually happens
- for (int i = 0; i < _Size; i++)
- _Buffer[i++] = (s32)PB.RatioInt;
-}
-
-
-
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "../Globals.h"
+#include "UCodes.h"
+#include "UCode_Zelda.h"
+#include "UCode_Zelda_ADPCM.h"
+
+#include "../main.h"
+#include "Mixer.h"
+
+void CUCode_Zelda::RenderSynth_Waveform(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
+{
+ float ratioFactor = 32000.0f / (float)soundStream->GetMixer()->GetSampleRate();
+ u32 _ratio = (PB.RatioInt << 16);
+ s64 ratio = (_ratio * ratioFactor) * 16;
+ s64 TrueSamplePosition = (s64)(PB.Length - PB.RemLength) << 16;
+ TrueSamplePosition += PB.CurSampleFrac;
+
+ int mask = PB.Format ? 3 : 1, shift = PB.Format ? 2 : 1;
+
+ u32 pos[2] = {0, 0};
+ int i = 0;
+
+ if (PB.KeyOff != 0)
+ return;
+
+ if (PB.NeedsReset)
+ {
+ PB.RemLength = PB.Length - PB.RestartPos;
+ PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
+ PB.ReachedEnd = 0;
+ }
+
+_lRestart:
+ if (PB.ReachedEnd)
+ {
+ PB.ReachedEnd = 0;
+
+ if (PB.RepeatMode == 0)
+ {
+ PB.KeyOff = 1;
+ PB.RemLength = 0;
+ PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1) + PB.Length;
+ return;
+ }
+ else
+ {
+ PB.RestartPos = PB.LoopStartPos;
+ PB.RemLength = PB.Length - PB.RestartPos;
+ PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
+ pos[1] = 0; pos[0] = 0;
+ }
+ }
+
+ while(i < _Size)
+ {
+ s16 sample = ((pos[1] & mask) == mask) ? 0xc000 : 0x4000;
+
+ TrueSamplePosition += (ratio >> 16);
+
+ _Buffer[i++] = (s32)sample;
+
+ (*(u64*)&pos) += ratio;
+ if ((pos[1] + ((PB.CurAddr - PB.StartAddr) >> 1)) >= PB.Length)
+ {
+ PB.ReachedEnd = 1;
+ goto _lRestart;
+ }
+ }
+
+ if (PB.RemLength < pos[1])
+ {
+ PB.RemLength = 0;
+ PB.ReachedEnd = 1;
+ }
+ else
+ PB.RemLength -= pos[1];
+
+ PB.CurSampleFrac = TrueSamplePosition & 0xFFFF;
+}
+
+
+void CUCode_Zelda::RenderSynth_Constant(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
+{
+ // TODO: Header, footer and cases this synth actually happens
+ for (int i = 0; i < _Size; i++)
+ _Buffer[i++] = (s32)PB.RatioInt;
+}
+
+
+
diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_Voice.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_Voice.cpp
index c7c48682c9..0acb3c9cc4 100644
--- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_Voice.cpp
+++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_Voice.cpp
@@ -1,466 +1,466 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "../Globals.h"
-#include "UCodes.h"
-#include "UCode_Zelda.h"
-#include "UCode_Zelda_ADPCM.h"
-
-#include "../main.h"
-#include "Mixer.h"
-
-void CUCode_Zelda::ReadVoicePB(u32 _Addr, ZeldaVoicePB& PB)
-{
- u16 *memory = (u16*)g_dspInitialize.pGetMemoryPointer(_Addr);
-
- // Perform byteswap
- for (int i = 0; i < (0x180 / 2); i++)
- ((u16*)&PB)[i] = Common::swap16(memory[i]);
-
- PB.RestartPos = (PB.RestartPos << 16) | (PB.RestartPos >> 16);
- PB.CurAddr = (PB.CurAddr << 16) | (PB.CurAddr >> 16);
- PB.RemLength = (PB.RemLength << 16) | (PB.RemLength >> 16);
- PB.LoopStartPos = (PB.LoopStartPos << 16) | (PB.LoopStartPos >> 16);
- PB.Length = (PB.Length << 16) | (PB.Length >> 16);
- PB.StartAddr = (PB.StartAddr << 16) | (PB.StartAddr >> 16);
- PB.UnkAddr = (PB.UnkAddr << 16) | (PB.UnkAddr >> 16);
-}
-
-void CUCode_Zelda::WritebackVoicePB(u32 _Addr, ZeldaVoicePB& PB)
-{
- u16 *memory = (u16*)g_dspInitialize.pGetMemoryPointer(_Addr);
-
- PB.RestartPos = (PB.RestartPos << 16) | (PB.RestartPos >> 16);
- PB.CurAddr = (PB.CurAddr << 16) | (PB.CurAddr >> 16);
- PB.RemLength = (PB.RemLength << 16) | (PB.RemLength >> 16);
-
- // Perform byteswap
- // Only the first 0x100 bytes are written back
- for (int i = 0; i < (0x100 / 2); i++)
- memory[i] = Common::swap16(((u16*)&PB)[i]);
-}
-
-void CUCode_Zelda::RenderVoice_PCM16(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
-{
- float ratioFactor = 32000.0f / (float)soundStream->GetMixer()->GetSampleRate();
- u32 _ratio = (((PB.RatioInt * 80) + PB.CurSampleFrac) << 4) & 0xFFFF0000;
- u64 ratio = (u64)(((_ratio / 80) << 16) * ratioFactor);
-
- u32 pos[2] = {0, 0};
- int i = 0;
-
- if (PB.KeyOff != 0)
- return;
-
- if (PB.NeedsReset)
- {
- PB.RemLength = PB.Length - PB.RestartPos;
- PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
- PB.ReachedEnd = 0;
- }
-
-_lRestart:
- if (PB.ReachedEnd)
- {
- PB.ReachedEnd = 0;
-
- if (PB.RepeatMode == 0)
- {
- PB.KeyOff = 1;
- PB.RemLength = 0;
- PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1) + PB.Length;
- return;
- }
- else
- {
- PB.RestartPos = PB.LoopStartPos;
- PB.RemLength = PB.Length - PB.RestartPos;
- PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
- pos[1] = 0; pos[0] = 0;
- }
- }
-
- s16 *source;
- if (m_CRC == 0xD643001F)
- source = (s16*)(g_dspInitialize.pGetMemoryPointer(m_DMABaseAddr) + PB.CurAddr);
- else
- source = (s16*)(g_dspInitialize.pGetARAMPointer() + PB.CurAddr);
-
- for (; i < _Size;)
- {
- s16 sample = Common::swap16(source[pos[1]]);
-
- _Buffer[i++] = (s32)sample;
-
- (*(u64*)&pos) += ratio;
- if ((pos[1] + ((PB.CurAddr - PB.StartAddr) >> 1)) >= PB.Length)
- {
- PB.ReachedEnd = 1;
- goto _lRestart;
- }
- }
-
- if (PB.RemLength < pos[1])
- {
- PB.RemLength = 0;
- PB.ReachedEnd = 1;
- }
- else
- PB.RemLength -= pos[1];
-
- PB.CurAddr += pos[1] << 1;
- // There should be a position fraction as well.
-}
-
-void CUCode_Zelda::RenderVoice_AFC(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
-{
- float ratioFactor = 32000.0f / (float)soundStream->GetMixer()->GetSampleRate();
- u32 _ratio = (PB.RatioInt << 16);// + PB.RatioFrac;
- s64 ratio = (_ratio * ratioFactor) * 16; // (s64)(((_ratio / 80) << 16) * ratioFactor);
-
- // initialize "decoder" if the sample is played the first time
- if (PB.NeedsReset != 0)
- {
- // This is 0717_ReadOutPBStuff
-
- // increment 4fb
-
- // zelda:
- // perhaps init or "has played before"
- PB.CurBlock = 0x00;
- PB.YN2 = 0x00; // history1
- PB.YN1 = 0x00; // history2
-
- // Length in samples.
- PB.RemLength = PB.Length;
-
- // Copy ARAM addr from r to rw area.
- PB.CurAddr = PB.StartAddr;
- PB.ReachedEnd = 0;
- PB.CurSampleFrac = 0;
- // Looking at Zelda Four Swords
- // WARN_LOG(DSPHLE, "PB -----: %04x", PB.Unk03);
- // WARN_LOG(DSPHLE, "PB Unk03: %04x", PB.Unk03); 0
- // WARN_LOG(DSPHLE, "PB Unk07: %04x", PB.Unk07[0]); 0
-
- /// WARN_LOG(DSPHLE, "PB Unk78: %04x", PB.Unk78);
- // WARN_LOG(DSPHLE, "PB Unk79: %04x", PB.Unk79);
- // WARN_LOG(DSPHLE, "PB Unk31: %04x", PB.Unk31);
- // WARN_LOG(DSPHLE, "PB Unk36: %04x", PB.Unk36[0]);
- // WARN_LOG(DSPHLE, "PB Unk37: %04x", PB.Unk36[1]);
- // WARN_LOG(DSPHLE, "PB Unk3c: %04x", PB.Unk3C[0]);
- // WARN_LOG(DSPHLE, "PB Unk3d: %04x", PB.Unk3C[1]);
- }
-
- if (PB.KeyOff != 0) // 0747 early out... i dunno if this can happen because we filter it above
- return;
-
- // round upwards how many samples we need to copy, 0759
- // u32 frac = NumberOfSamples & 0xF;
- // NumberOfSamples = (NumberOfSamples + 0xf) >> 4; // i think the lower 4 are the fraction
-
- u8 *source;
- u32 ram_mask = 1024 * 1024 * 16 - 1;
- if (m_CRC == 0xD643001F) {
- source = g_dspInitialize.pGetMemoryPointer(m_DMABaseAddr);
- ram_mask = 1024 * 1024 * 64 - 1;
- }
- else
- source = g_dspInitialize.pGetARAMPointer();
-
-restart:
- if (PB.ReachedEnd)
- {
- PB.ReachedEnd = 0;
-
- // HACK: Looping doesn't work.
- if (true || PB.RepeatMode == 0)
- {
- PB.KeyOff = 1;
- PB.RemLength = 0;
- PB.CurAddr = PB.StartAddr + PB.RestartPos + PB.Length;
- return;
- }
- else
- {
- // This needs adjustment. It's not right for AFC, was just copied from PCM16.
- // We should also probably reinitialize YN1 and YN2 with something - but with what?
- PB.RestartPos = PB.LoopStartPos;
- PB.RemLength = PB.Length - PB.RestartPos;
- PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
-// pos[1] = 0; pos[0] = 0;
- }
- }
-
- short outbuf[16] = {0};
-
- u16 prev_yn1 = PB.YN1;
- u16 prev_yn2 = PB.YN2;
- u32 prev_addr = PB.CurAddr;
-
- // Prefill the decode buffer.
- AFCdecodebuffer(m_AFCCoefTable, (char*)(source + (PB.CurAddr & ram_mask)), outbuf, (short*)&PB.YN2, (short*)&PB.YN1, PB.Format);
- PB.CurAddr += 9;
-
- s64 TrueSamplePosition = (s64)(PB.Length - PB.RemLength) << 16;
- TrueSamplePosition += PB.CurSampleFrac;
- s64 delta = ratio >> 16; // 0x100000000ULL;
- int sampleCount = 0;
- while (sampleCount < _Size)
- {
- int SamplePosition = TrueSamplePosition >> 16;
- _Buffer[sampleCount] = outbuf[SamplePosition & 15];
-
- sampleCount++;
- TrueSamplePosition += delta;
-
- int TargetPosition = TrueSamplePosition >> 16;
-
- // Decode forwards...
- while (SamplePosition < TargetPosition)
- {
- SamplePosition++;
- PB.RemLength--;
- if (PB.RemLength == 0)
- {
- PB.ReachedEnd = 1;
- goto restart;
- }
-
- // Need new samples!
- if ((SamplePosition & 15) == 0) {
- prev_yn1 = PB.YN1;
- prev_yn2 = PB.YN2;
- prev_addr = PB.CurAddr;
-
- AFCdecodebuffer(m_AFCCoefTable, (char*)(source + (PB.CurAddr & ram_mask)), outbuf, (short*)&PB.YN2, (short*)&PB.YN1, PB.Format);
- PB.CurAddr += 9;
- }
- }
- }
-
- // Here we should back off to the previous addr/yn1/yn2, since we didn't consume the full last block.
- // We'll have to re-decode it the next time around.
- // if (SamplePosition & 15) {
- PB.YN2 = prev_yn2;
- PB.YN1 = prev_yn1;
- PB.CurAddr = prev_addr;
- // }
-
- PB.NeedsReset = 0;
- PB.CurSampleFrac = TrueSamplePosition & 0xFFFF;
- // write back
- // NumberOfSamples = (NumberOfSamples << 4) | frac; // missing fraction
-
- // i think pTest[0x3a] and pTest[0x3b] got an update after you have decoded some samples...
- // just decrement them with the number of samples you have played
- // and increase the ARAM Offset in pTest[0x38], pTest[0x39]
-
- // end of block (Zelda 03b2)
-}
-
-// Researching what's actually inside the mysterious 0x21 case
-void CUCode_Zelda::RenderVoice_Raw(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
-{
- float ratioFactor = 32000.0f / (float)soundStream->GetMixer()->GetSampleRate();
- u32 _ratio = (PB.RatioInt << 16);// + PB.RatioFrac;
- s64 ratio = (_ratio * ratioFactor) * 16; // (s64)(((_ratio / 80) << 16) * ratioFactor);
-
- if (PB.NeedsReset != 0)
- {
- PB.CurBlock = 0x00;
-
- // Length in samples.
- PB.RemLength = PB.Length;
-
- // Copy ARAM addr from r to rw area.
- PB.CurAddr = PB.StartAddr;
- PB.ReachedEnd = 0;
- PB.CurSampleFrac = 0;
- }
-
- if (PB.KeyOff != 0)
- return;
-
- u8 *source;
- u32 ram_mask = 1024 * 1024 * 16 - 1;
- if (m_CRC == 0xD643001F) {
- source = g_dspInitialize.pGetMemoryPointer(m_DMABaseAddr);
- ram_mask = 1024 * 1024 * 64 - 1;
- }
- else
- source = g_dspInitialize.pGetARAMPointer();
-
-//restart:
- if (PB.ReachedEnd)
- {
- PB.ReachedEnd = 0;
-
- // HACK: Looping doesn't work.
- if (true || PB.RepeatMode == 0)
- {
- PB.KeyOff = 1;
- PB.RemLength = 0;
- PB.CurAddr = PB.StartAddr + PB.RestartPos + PB.Length;
- return;
- }
- else
- {
- // This needs adjustment. It's not right for AFC, was just copied from PCM16.
- // We should also probably reinitialize YN1 and YN2 with something - but with what?
- PB.RestartPos = PB.LoopStartPos;
- PB.RemLength = PB.Length - PB.RestartPos;
- PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
- }
- }
-
-
-
- u32 prev_addr = PB.CurAddr;
-
- // Prefill the decode buffer.
- //AFCdecodebuffer(m_AFCCoefTable, (char*)(source + (PB.CurAddr & ram_mask)), outbuf, (short*)&PB.YN2, (short*)&PB.YN1, PB.Format);
- const char *src = (char *)(source + (PB.CurAddr & ram_mask));
- PB.CurAddr += 9;
-
- s64 TrueSamplePosition = (s64)(PB.Length - PB.RemLength) << 16;
- TrueSamplePosition += PB.CurSampleFrac;
- s64 delta = ratio >> 16; // 0x100000000ULL;
- int sampleCount = 0, realSample = 0;
- while (sampleCount < _Size)
- {
- _Buffer[sampleCount] = src[realSample] | (src[realSample + 1] << 8) | (src[realSample + 2] << 16)
- | (src[realSample + 3] << 24);
-
- //WARN_LOG(DSPHLE, "The sample: %02x", src[sampleCount]);
-
- sampleCount++;
- realSample += 4;
- TrueSamplePosition += delta;
- }
-
- PB.NeedsReset = 0;
- PB.CurSampleFrac = TrueSamplePosition & 0xFFFF;
-}
-
-void CUCode_Zelda::RenderAddVoice(ZeldaVoicePB &PB, s32* _LeftBuffer, s32* _RightBuffer, int _Size)
-{
- //static u16 lastLeft = 0x1FF, lastRight = 0x1FF;
- memset(m_TempBuffer, 0, _Size * sizeof(s32));
-
- if (PB.IsBlank)
- {
- s32 sample = (s32)(s16)PB.FixedSample;
- for (int i = 0; i < _Size; i++)
- m_TempBuffer[i] = sample;
- }
- else
- {
- // XK: Use this to disable music (GREAT for testing)
- //if(PB.SoundType == 0x0d00) {
- // PB.NeedsReset = 0;
- // return;
- //}
- //WARN_LOG(DSPHLE, "Fmt %04x, %04x: %04x %04x",
- // PB.Format, PB.SoundType, PB.Unk29, PB.Unk2a);
- /*WARN_LOG(DSPHLE, "Fmt %04x, %04x: %04x %04x %04x %04x %04x %04x %04x %04x",
- PB.Format, PB.SoundType,
- PB.volumeLeft1, PB.volumeLeft2, PB.volumeRight1, PB.volumeRight2,
- PB.volumeUnknown1_1, PB.volumeUnknown1_2, PB.volumeUnknown2_1,
- PB.volumeUnknown2_2);*/
-
- switch (PB.Format)
- {
- // Synthesized sounds
- case 0x0000: // Example: Magic meter filling up in ZWW
- case 0x0001: // Example: "Denied" sound when trying to pull out a sword
- // indoors in ZWW
- RenderSynth_Waveform(PB, m_TempBuffer, _Size);
- break;
-
- case 0x0006:
- WARN_LOG(DSPHLE, "Synthesizing 0x0006 (constant sound)");
- RenderSynth_Constant(PB, m_TempBuffer, _Size);
- break;
-
- // These are more "synth" formats - square wave, saw wave etc.
- case 0x0002:
- WARN_LOG(DSPHLE, "Synthesizing 0x0002");
- break;
-
-
- // AFC formats
- case 0x0005: // AFC with extra low bitrate (32:5 compression). Not yet seen.
- WARN_LOG(DSPHLE, "5 byte AFC - does it work?");
- case 0x0009: // AFC with normal bitrate (32:9 compression).
-
-
- RenderVoice_AFC(PB, m_TempBuffer, _Size);
- break;
-
- case 0x0010: // PCM16 - normal PCM 16-bit audio.
- RenderVoice_PCM16(PB, m_TempBuffer, _Size);
- break;
-
-
- case 0x0008: // Likely PCM8 - normal PCM 8-bit audio. Used in Mario Kart DD.
- case 0x0020:
- case 0x0021: // Probably raw sound. Important for Zelda WW. Really need to implement - missing it causes hangs.
- WARN_LOG(DSPHLE, "Unimplemented MixAddVoice format in zelda %04x", PB.Format);
-
- // This is what 0x20 and 0x21 do on end of voice
- PB.RemLength = 0;
- PB.KeyOff = 1;
-
- // Caution: Use at your own risk. Sounds awful :)
- //RenderVoice_Raw(PB, m_TempBuffer, _Size);
- break;
-
- default:
- // TODO: Implement general decoder here
- ERROR_LOG(DSPHLE, "Unknown MixAddVoice format in zelda %04x", PB.Format);
- break;
- }
-
- // Necessary for SMG, not for Zelda. Weird.
- PB.NeedsReset = 0;
- }
-
- for (int i = 0; i < _Size; i++)
- {
- /*if(PB.volumeLeft2)
- lastLeft = PB.volumeLeft2;
- if(PB.volumeRight2)
- lastRight = PB.volumeRight2;*/
-
- // TODO: Some noises in Zelda WW (birds, etc) have a volume of 0
- // Really not sure about the masking here, but it seems to kill off some overly loud
- // sounds in Zelda TP. Needs investigation.
- s32 left = _LeftBuffer[i] + (m_TempBuffer[i] * (float)(
- (PB.volumeLeft1 & 0x1FFF) + (PB.volumeLeft2 & 0x1FFF)) * 0.00005);
- s32 right = _RightBuffer[i] + (m_TempBuffer[i] * (float)(
- (PB.volumeRight1 & 0x1FFF) + (PB.volumeRight2 & 0x1FFF)) * 0.00005);
-
- if (left < -32768) left = -32768;
- if (left > 32767) left = 32767;
- _LeftBuffer[i] = left; //(s32)(((float)left * (float)PB.volumeLeft) / 1000.f);
-
- if (right < -32768) right = -32768;
- if (right > 32767) right = 32767;
- _RightBuffer[i] = right; //(s32)(((float)right * (float)PB.volumeRight) / 1000.0f);
- }
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "../Globals.h"
+#include "UCodes.h"
+#include "UCode_Zelda.h"
+#include "UCode_Zelda_ADPCM.h"
+
+#include "../main.h"
+#include "Mixer.h"
+
+void CUCode_Zelda::ReadVoicePB(u32 _Addr, ZeldaVoicePB& PB)
+{
+ u16 *memory = (u16*)g_dspInitialize.pGetMemoryPointer(_Addr);
+
+ // Perform byteswap
+ for (int i = 0; i < (0x180 / 2); i++)
+ ((u16*)&PB)[i] = Common::swap16(memory[i]);
+
+ PB.RestartPos = (PB.RestartPos << 16) | (PB.RestartPos >> 16);
+ PB.CurAddr = (PB.CurAddr << 16) | (PB.CurAddr >> 16);
+ PB.RemLength = (PB.RemLength << 16) | (PB.RemLength >> 16);
+ PB.LoopStartPos = (PB.LoopStartPos << 16) | (PB.LoopStartPos >> 16);
+ PB.Length = (PB.Length << 16) | (PB.Length >> 16);
+ PB.StartAddr = (PB.StartAddr << 16) | (PB.StartAddr >> 16);
+ PB.UnkAddr = (PB.UnkAddr << 16) | (PB.UnkAddr >> 16);
+}
+
+void CUCode_Zelda::WritebackVoicePB(u32 _Addr, ZeldaVoicePB& PB)
+{
+ u16 *memory = (u16*)g_dspInitialize.pGetMemoryPointer(_Addr);
+
+ PB.RestartPos = (PB.RestartPos << 16) | (PB.RestartPos >> 16);
+ PB.CurAddr = (PB.CurAddr << 16) | (PB.CurAddr >> 16);
+ PB.RemLength = (PB.RemLength << 16) | (PB.RemLength >> 16);
+
+ // Perform byteswap
+ // Only the first 0x100 bytes are written back
+ for (int i = 0; i < (0x100 / 2); i++)
+ memory[i] = Common::swap16(((u16*)&PB)[i]);
+}
+
+void CUCode_Zelda::RenderVoice_PCM16(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
+{
+ float ratioFactor = 32000.0f / (float)soundStream->GetMixer()->GetSampleRate();
+ u32 _ratio = (((PB.RatioInt * 80) + PB.CurSampleFrac) << 4) & 0xFFFF0000;
+ u64 ratio = (u64)(((_ratio / 80) << 16) * ratioFactor);
+
+ u32 pos[2] = {0, 0};
+ int i = 0;
+
+ if (PB.KeyOff != 0)
+ return;
+
+ if (PB.NeedsReset)
+ {
+ PB.RemLength = PB.Length - PB.RestartPos;
+ PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
+ PB.ReachedEnd = 0;
+ }
+
+_lRestart:
+ if (PB.ReachedEnd)
+ {
+ PB.ReachedEnd = 0;
+
+ if (PB.RepeatMode == 0)
+ {
+ PB.KeyOff = 1;
+ PB.RemLength = 0;
+ PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1) + PB.Length;
+ return;
+ }
+ else
+ {
+ PB.RestartPos = PB.LoopStartPos;
+ PB.RemLength = PB.Length - PB.RestartPos;
+ PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
+ pos[1] = 0; pos[0] = 0;
+ }
+ }
+
+ s16 *source;
+ if (m_CRC == 0xD643001F)
+ source = (s16*)(g_dspInitialize.pGetMemoryPointer(m_DMABaseAddr) + PB.CurAddr);
+ else
+ source = (s16*)(g_dspInitialize.pGetARAMPointer() + PB.CurAddr);
+
+ for (; i < _Size;)
+ {
+ s16 sample = Common::swap16(source[pos[1]]);
+
+ _Buffer[i++] = (s32)sample;
+
+ (*(u64*)&pos) += ratio;
+ if ((pos[1] + ((PB.CurAddr - PB.StartAddr) >> 1)) >= PB.Length)
+ {
+ PB.ReachedEnd = 1;
+ goto _lRestart;
+ }
+ }
+
+ if (PB.RemLength < pos[1])
+ {
+ PB.RemLength = 0;
+ PB.ReachedEnd = 1;
+ }
+ else
+ PB.RemLength -= pos[1];
+
+ PB.CurAddr += pos[1] << 1;
+ // There should be a position fraction as well.
+}
+
+void CUCode_Zelda::RenderVoice_AFC(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
+{
+ float ratioFactor = 32000.0f / (float)soundStream->GetMixer()->GetSampleRate();
+ u32 _ratio = (PB.RatioInt << 16);// + PB.RatioFrac;
+ s64 ratio = (_ratio * ratioFactor) * 16; // (s64)(((_ratio / 80) << 16) * ratioFactor);
+
+ // initialize "decoder" if the sample is played the first time
+ if (PB.NeedsReset != 0)
+ {
+ // This is 0717_ReadOutPBStuff
+
+ // increment 4fb
+
+ // zelda:
+ // perhaps init or "has played before"
+ PB.CurBlock = 0x00;
+ PB.YN2 = 0x00; // history1
+ PB.YN1 = 0x00; // history2
+
+ // Length in samples.
+ PB.RemLength = PB.Length;
+
+ // Copy ARAM addr from r to rw area.
+ PB.CurAddr = PB.StartAddr;
+ PB.ReachedEnd = 0;
+ PB.CurSampleFrac = 0;
+ // Looking at Zelda Four Swords
+ // WARN_LOG(DSPHLE, "PB -----: %04x", PB.Unk03);
+ // WARN_LOG(DSPHLE, "PB Unk03: %04x", PB.Unk03); 0
+ // WARN_LOG(DSPHLE, "PB Unk07: %04x", PB.Unk07[0]); 0
+
+ /// WARN_LOG(DSPHLE, "PB Unk78: %04x", PB.Unk78);
+ // WARN_LOG(DSPHLE, "PB Unk79: %04x", PB.Unk79);
+ // WARN_LOG(DSPHLE, "PB Unk31: %04x", PB.Unk31);
+ // WARN_LOG(DSPHLE, "PB Unk36: %04x", PB.Unk36[0]);
+ // WARN_LOG(DSPHLE, "PB Unk37: %04x", PB.Unk36[1]);
+ // WARN_LOG(DSPHLE, "PB Unk3c: %04x", PB.Unk3C[0]);
+ // WARN_LOG(DSPHLE, "PB Unk3d: %04x", PB.Unk3C[1]);
+ }
+
+ if (PB.KeyOff != 0) // 0747 early out... i dunno if this can happen because we filter it above
+ return;
+
+ // round upwards how many samples we need to copy, 0759
+ // u32 frac = NumberOfSamples & 0xF;
+ // NumberOfSamples = (NumberOfSamples + 0xf) >> 4; // i think the lower 4 are the fraction
+
+ u8 *source;
+ u32 ram_mask = 1024 * 1024 * 16 - 1;
+ if (m_CRC == 0xD643001F) {
+ source = g_dspInitialize.pGetMemoryPointer(m_DMABaseAddr);
+ ram_mask = 1024 * 1024 * 64 - 1;
+ }
+ else
+ source = g_dspInitialize.pGetARAMPointer();
+
+restart:
+ if (PB.ReachedEnd)
+ {
+ PB.ReachedEnd = 0;
+
+ // HACK: Looping doesn't work.
+ if (true || PB.RepeatMode == 0)
+ {
+ PB.KeyOff = 1;
+ PB.RemLength = 0;
+ PB.CurAddr = PB.StartAddr + PB.RestartPos + PB.Length;
+ return;
+ }
+ else
+ {
+ // This needs adjustment. It's not right for AFC, was just copied from PCM16.
+ // We should also probably reinitialize YN1 and YN2 with something - but with what?
+ PB.RestartPos = PB.LoopStartPos;
+ PB.RemLength = PB.Length - PB.RestartPos;
+ PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
+// pos[1] = 0; pos[0] = 0;
+ }
+ }
+
+ short outbuf[16] = {0};
+
+ u16 prev_yn1 = PB.YN1;
+ u16 prev_yn2 = PB.YN2;
+ u32 prev_addr = PB.CurAddr;
+
+ // Prefill the decode buffer.
+ AFCdecodebuffer(m_AFCCoefTable, (char*)(source + (PB.CurAddr & ram_mask)), outbuf, (short*)&PB.YN2, (short*)&PB.YN1, PB.Format);
+ PB.CurAddr += 9;
+
+ s64 TrueSamplePosition = (s64)(PB.Length - PB.RemLength) << 16;
+ TrueSamplePosition += PB.CurSampleFrac;
+ s64 delta = ratio >> 16; // 0x100000000ULL;
+ int sampleCount = 0;
+ while (sampleCount < _Size)
+ {
+ int SamplePosition = TrueSamplePosition >> 16;
+ _Buffer[sampleCount] = outbuf[SamplePosition & 15];
+
+ sampleCount++;
+ TrueSamplePosition += delta;
+
+ int TargetPosition = TrueSamplePosition >> 16;
+
+ // Decode forwards...
+ while (SamplePosition < TargetPosition)
+ {
+ SamplePosition++;
+ PB.RemLength--;
+ if (PB.RemLength == 0)
+ {
+ PB.ReachedEnd = 1;
+ goto restart;
+ }
+
+ // Need new samples!
+ if ((SamplePosition & 15) == 0) {
+ prev_yn1 = PB.YN1;
+ prev_yn2 = PB.YN2;
+ prev_addr = PB.CurAddr;
+
+ AFCdecodebuffer(m_AFCCoefTable, (char*)(source + (PB.CurAddr & ram_mask)), outbuf, (short*)&PB.YN2, (short*)&PB.YN1, PB.Format);
+ PB.CurAddr += 9;
+ }
+ }
+ }
+
+ // Here we should back off to the previous addr/yn1/yn2, since we didn't consume the full last block.
+ // We'll have to re-decode it the next time around.
+ // if (SamplePosition & 15) {
+ PB.YN2 = prev_yn2;
+ PB.YN1 = prev_yn1;
+ PB.CurAddr = prev_addr;
+ // }
+
+ PB.NeedsReset = 0;
+ PB.CurSampleFrac = TrueSamplePosition & 0xFFFF;
+ // write back
+ // NumberOfSamples = (NumberOfSamples << 4) | frac; // missing fraction
+
+ // i think pTest[0x3a] and pTest[0x3b] got an update after you have decoded some samples...
+ // just decrement them with the number of samples you have played
+ // and increase the ARAM Offset in pTest[0x38], pTest[0x39]
+
+ // end of block (Zelda 03b2)
+}
+
+// Researching what's actually inside the mysterious 0x21 case
+void CUCode_Zelda::RenderVoice_Raw(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
+{
+ float ratioFactor = 32000.0f / (float)soundStream->GetMixer()->GetSampleRate();
+ u32 _ratio = (PB.RatioInt << 16);// + PB.RatioFrac;
+ s64 ratio = (_ratio * ratioFactor) * 16; // (s64)(((_ratio / 80) << 16) * ratioFactor);
+
+ if (PB.NeedsReset != 0)
+ {
+ PB.CurBlock = 0x00;
+
+ // Length in samples.
+ PB.RemLength = PB.Length;
+
+ // Copy ARAM addr from r to rw area.
+ PB.CurAddr = PB.StartAddr;
+ PB.ReachedEnd = 0;
+ PB.CurSampleFrac = 0;
+ }
+
+ if (PB.KeyOff != 0)
+ return;
+
+ u8 *source;
+ u32 ram_mask = 1024 * 1024 * 16 - 1;
+ if (m_CRC == 0xD643001F) {
+ source = g_dspInitialize.pGetMemoryPointer(m_DMABaseAddr);
+ ram_mask = 1024 * 1024 * 64 - 1;
+ }
+ else
+ source = g_dspInitialize.pGetARAMPointer();
+
+//restart:
+ if (PB.ReachedEnd)
+ {
+ PB.ReachedEnd = 0;
+
+ // HACK: Looping doesn't work.
+ if (true || PB.RepeatMode == 0)
+ {
+ PB.KeyOff = 1;
+ PB.RemLength = 0;
+ PB.CurAddr = PB.StartAddr + PB.RestartPos + PB.Length;
+ return;
+ }
+ else
+ {
+ // This needs adjustment. It's not right for AFC, was just copied from PCM16.
+ // We should also probably reinitialize YN1 and YN2 with something - but with what?
+ PB.RestartPos = PB.LoopStartPos;
+ PB.RemLength = PB.Length - PB.RestartPos;
+ PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
+ }
+ }
+
+
+
+ u32 prev_addr = PB.CurAddr;
+
+ // Prefill the decode buffer.
+ //AFCdecodebuffer(m_AFCCoefTable, (char*)(source + (PB.CurAddr & ram_mask)), outbuf, (short*)&PB.YN2, (short*)&PB.YN1, PB.Format);
+ const char *src = (char *)(source + (PB.CurAddr & ram_mask));
+ PB.CurAddr += 9;
+
+ s64 TrueSamplePosition = (s64)(PB.Length - PB.RemLength) << 16;
+ TrueSamplePosition += PB.CurSampleFrac;
+ s64 delta = ratio >> 16; // 0x100000000ULL;
+ int sampleCount = 0, realSample = 0;
+ while (sampleCount < _Size)
+ {
+ _Buffer[sampleCount] = src[realSample] | (src[realSample + 1] << 8) | (src[realSample + 2] << 16)
+ | (src[realSample + 3] << 24);
+
+ //WARN_LOG(DSPHLE, "The sample: %02x", src[sampleCount]);
+
+ sampleCount++;
+ realSample += 4;
+ TrueSamplePosition += delta;
+ }
+
+ PB.NeedsReset = 0;
+ PB.CurSampleFrac = TrueSamplePosition & 0xFFFF;
+}
+
+void CUCode_Zelda::RenderAddVoice(ZeldaVoicePB &PB, s32* _LeftBuffer, s32* _RightBuffer, int _Size)
+{
+ //static u16 lastLeft = 0x1FF, lastRight = 0x1FF;
+ memset(m_TempBuffer, 0, _Size * sizeof(s32));
+
+ if (PB.IsBlank)
+ {
+ s32 sample = (s32)(s16)PB.FixedSample;
+ for (int i = 0; i < _Size; i++)
+ m_TempBuffer[i] = sample;
+ }
+ else
+ {
+ // XK: Use this to disable music (GREAT for testing)
+ //if(PB.SoundType == 0x0d00) {
+ // PB.NeedsReset = 0;
+ // return;
+ //}
+ //WARN_LOG(DSPHLE, "Fmt %04x, %04x: %04x %04x",
+ // PB.Format, PB.SoundType, PB.Unk29, PB.Unk2a);
+ /*WARN_LOG(DSPHLE, "Fmt %04x, %04x: %04x %04x %04x %04x %04x %04x %04x %04x",
+ PB.Format, PB.SoundType,
+ PB.volumeLeft1, PB.volumeLeft2, PB.volumeRight1, PB.volumeRight2,
+ PB.volumeUnknown1_1, PB.volumeUnknown1_2, PB.volumeUnknown2_1,
+ PB.volumeUnknown2_2);*/
+
+ switch (PB.Format)
+ {
+ // Synthesized sounds
+ case 0x0000: // Example: Magic meter filling up in ZWW
+ case 0x0001: // Example: "Denied" sound when trying to pull out a sword
+ // indoors in ZWW
+ RenderSynth_Waveform(PB, m_TempBuffer, _Size);
+ break;
+
+ case 0x0006:
+ WARN_LOG(DSPHLE, "Synthesizing 0x0006 (constant sound)");
+ RenderSynth_Constant(PB, m_TempBuffer, _Size);
+ break;
+
+ // These are more "synth" formats - square wave, saw wave etc.
+ case 0x0002:
+ WARN_LOG(DSPHLE, "Synthesizing 0x0002");
+ break;
+
+
+ // AFC formats
+ case 0x0005: // AFC with extra low bitrate (32:5 compression). Not yet seen.
+ WARN_LOG(DSPHLE, "5 byte AFC - does it work?");
+ case 0x0009: // AFC with normal bitrate (32:9 compression).
+
+
+ RenderVoice_AFC(PB, m_TempBuffer, _Size);
+ break;
+
+ case 0x0010: // PCM16 - normal PCM 16-bit audio.
+ RenderVoice_PCM16(PB, m_TempBuffer, _Size);
+ break;
+
+
+ case 0x0008: // Likely PCM8 - normal PCM 8-bit audio. Used in Mario Kart DD.
+ case 0x0020:
+ case 0x0021: // Probably raw sound. Important for Zelda WW. Really need to implement - missing it causes hangs.
+ WARN_LOG(DSPHLE, "Unimplemented MixAddVoice format in zelda %04x", PB.Format);
+
+ // This is what 0x20 and 0x21 do on end of voice
+ PB.RemLength = 0;
+ PB.KeyOff = 1;
+
+ // Caution: Use at your own risk. Sounds awful :)
+ //RenderVoice_Raw(PB, m_TempBuffer, _Size);
+ break;
+
+ default:
+ // TODO: Implement general decoder here
+ ERROR_LOG(DSPHLE, "Unknown MixAddVoice format in zelda %04x", PB.Format);
+ break;
+ }
+
+ // Necessary for SMG, not for Zelda. Weird.
+ PB.NeedsReset = 0;
+ }
+
+ for (int i = 0; i < _Size; i++)
+ {
+ /*if(PB.volumeLeft2)
+ lastLeft = PB.volumeLeft2;
+ if(PB.volumeRight2)
+ lastRight = PB.volumeRight2;*/
+
+ // TODO: Some noises in Zelda WW (birds, etc) have a volume of 0
+ // Really not sure about the masking here, but it seems to kill off some overly loud
+ // sounds in Zelda TP. Needs investigation.
+ s32 left = _LeftBuffer[i] + (m_TempBuffer[i] * (float)(
+ (PB.volumeLeft1 & 0x1FFF) + (PB.volumeLeft2 & 0x1FFF)) * 0.00005);
+ s32 right = _RightBuffer[i] + (m_TempBuffer[i] * (float)(
+ (PB.volumeRight1 & 0x1FFF) + (PB.volumeRight2 & 0x1FFF)) * 0.00005);
+
+ if (left < -32768) left = -32768;
+ if (left > 32767) left = 32767;
+ _LeftBuffer[i] = left; //(s32)(((float)left * (float)PB.volumeLeft) / 1000.f);
+
+ if (right < -32768) right = -32768;
+ if (right > 32767) right = 32767;
+ _RightBuffer[i] = right; //(s32)(((float)right * (float)PB.volumeRight) / 1000.0f);
+ }
+}
diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/DSPDebugInterface.cpp b/Source/Plugins/Plugin_DSP_LLE/Src/DSPDebugInterface.cpp
index 79fbd6fa9f..8c34fafd45 100644
--- a/Source/Plugins/Plugin_DSP_LLE/Src/DSPDebugInterface.cpp
+++ b/Source/Plugins/Plugin_DSP_LLE/Src/DSPDebugInterface.cpp
@@ -1,179 +1,179 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "DSPDebugInterface.h"
-
-#include "DSPCore.h"
-#include "disassemble.h"
-
-#include "DSPSymbols.h"
-#include "DSPMemoryMap.h"
-
-void DSPDebugInterface::disasm(unsigned int address, char *dest, int max_size)
-{
- // we'll treat addresses as line numbers.
- strncpy(dest, DSPSymbols::GetLineText(address), max_size);
- dest[max_size-1] = 0;
-}
-
-void DSPDebugInterface::getRawMemoryString(int memory, unsigned int address, char *dest, int max_size)
-{
- switch (memory) {
- case 0: // IMEM
- switch (address >> 12) {
- case 0:
- case 0x8:
- sprintf(dest, "%04x", dsp_imem_read(address));
- break;
- default:
- sprintf(dest, "----");
- break;
- }
- break;
- case 1: // DMEM
- switch (address >> 12) {
- case 0:
- case 1:
- sprintf(dest, "%04x", dsp_dmem_read(address));
- break;
- default:
- sprintf(dest, "----");
- break;
- }
- break;
- }
-}
-
-unsigned int DSPDebugInterface::readMemory(unsigned int address)
-{
- return 0; //Memory::ReadUnchecked_U32(address);
-}
-
-unsigned int DSPDebugInterface::readInstruction(unsigned int address)
-{
- return 0; //Memory::Read_Instruction(address);
-}
-
-bool DSPDebugInterface::isAlive()
-{
- return true; //Core::GetState() != Core::CORE_UNINITIALIZED;
-}
-
-bool DSPDebugInterface::isBreakpoint(unsigned int address)
-{
- int real_addr = DSPSymbols::Line2Addr(address);
- if (real_addr >= 0)
- return dsp_breakpoints.IsAddressBreakPoint(real_addr);
- else
- return false;
-}
-
-void DSPDebugInterface::setBreakpoint(unsigned int address)
-{
- int real_addr = DSPSymbols::Line2Addr(address);
- if (real_addr >= 0) {
- if (dsp_breakpoints.Add(real_addr))
- ;
- }
-}
-
-void DSPDebugInterface::clearBreakpoint(unsigned int address)
-{
- int real_addr = DSPSymbols::Line2Addr(address);
- if (real_addr >= 0) {
- if (dsp_breakpoints.Remove(real_addr))
- ;
- }
-}
-
-void DSPDebugInterface::clearAllBreakpoints() {
- dsp_breakpoints.Clear();
-}
-
-void DSPDebugInterface::toggleBreakpoint(unsigned int address)
-{
- int real_addr = DSPSymbols::Line2Addr(address);
- if (real_addr >= 0) {
- if (dsp_breakpoints.IsAddressBreakPoint(real_addr))
- dsp_breakpoints.Remove(real_addr);
- else
- dsp_breakpoints.Add(real_addr);
- }
-}
-
-void DSPDebugInterface::insertBLR(unsigned int address)
-{
- PanicAlert("insertBLR functionality not supported in DSP module.");
-}
-
-// =======================================================
-// Separate the blocks with colors.
-// -------------
-int DSPDebugInterface::getColor(unsigned int address)
-{
- static const int colors[6] =
- {
- 0xd0FFFF, // light cyan
- 0xFFd0d0, // light red
- 0xd8d8FF, // light blue
- 0xFFd0FF, // light purple
- 0xd0FFd0, // light green
- 0xFFFFd0, // light yellow
- };
-
- // Scan backwards so we don't miss it. Hm, actually, let's not - it looks pretty good.
- int addr = -1;
- for (int i = 0; i < 1; i++)
- {
- addr = DSPSymbols::Line2Addr(address - i);
- if (addr >= 0)
- break;
- }
- if (addr == -1)
- return 0xFFFFFF;
-
- Symbol *symbol = DSPSymbols::g_dsp_symbol_db.GetSymbolFromAddr(addr);
- if (!symbol)
- return 0xFFFFFF;
- if (symbol->type != Symbol::SYMBOL_FUNCTION)
- return 0xEEEEFF;
- return colors[symbol->index % 6];
-}
-// =============
-
-
-std::string DSPDebugInterface::getDescription(unsigned int address)
-{
- return ""; // g_symbolDB.GetDescription(address);
-}
-
-unsigned int DSPDebugInterface::getPC()
-{
- return DSPSymbols::Addr2Line(g_dsp.pc);
-}
-
-void DSPDebugInterface::setPC(unsigned int address)
-{
- int new_pc = DSPSymbols::Line2Addr(address);
- if (new_pc > 0)
- g_dsp.pc = new_pc;
-}
-
-void DSPDebugInterface::runToBreakpoint()
-{
-
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "DSPDebugInterface.h"
+
+#include "DSPCore.h"
+#include "disassemble.h"
+
+#include "DSPSymbols.h"
+#include "DSPMemoryMap.h"
+
+void DSPDebugInterface::disasm(unsigned int address, char *dest, int max_size)
+{
+ // we'll treat addresses as line numbers.
+ strncpy(dest, DSPSymbols::GetLineText(address), max_size);
+ dest[max_size-1] = 0;
+}
+
+void DSPDebugInterface::getRawMemoryString(int memory, unsigned int address, char *dest, int max_size)
+{
+ switch (memory) {
+ case 0: // IMEM
+ switch (address >> 12) {
+ case 0:
+ case 0x8:
+ sprintf(dest, "%04x", dsp_imem_read(address));
+ break;
+ default:
+ sprintf(dest, "----");
+ break;
+ }
+ break;
+ case 1: // DMEM
+ switch (address >> 12) {
+ case 0:
+ case 1:
+ sprintf(dest, "%04x", dsp_dmem_read(address));
+ break;
+ default:
+ sprintf(dest, "----");
+ break;
+ }
+ break;
+ }
+}
+
+unsigned int DSPDebugInterface::readMemory(unsigned int address)
+{
+ return 0; //Memory::ReadUnchecked_U32(address);
+}
+
+unsigned int DSPDebugInterface::readInstruction(unsigned int address)
+{
+ return 0; //Memory::Read_Instruction(address);
+}
+
+bool DSPDebugInterface::isAlive()
+{
+ return true; //Core::GetState() != Core::CORE_UNINITIALIZED;
+}
+
+bool DSPDebugInterface::isBreakpoint(unsigned int address)
+{
+ int real_addr = DSPSymbols::Line2Addr(address);
+ if (real_addr >= 0)
+ return dsp_breakpoints.IsAddressBreakPoint(real_addr);
+ else
+ return false;
+}
+
+void DSPDebugInterface::setBreakpoint(unsigned int address)
+{
+ int real_addr = DSPSymbols::Line2Addr(address);
+ if (real_addr >= 0) {
+ if (dsp_breakpoints.Add(real_addr))
+ ;
+ }
+}
+
+void DSPDebugInterface::clearBreakpoint(unsigned int address)
+{
+ int real_addr = DSPSymbols::Line2Addr(address);
+ if (real_addr >= 0) {
+ if (dsp_breakpoints.Remove(real_addr))
+ ;
+ }
+}
+
+void DSPDebugInterface::clearAllBreakpoints() {
+ dsp_breakpoints.Clear();
+}
+
+void DSPDebugInterface::toggleBreakpoint(unsigned int address)
+{
+ int real_addr = DSPSymbols::Line2Addr(address);
+ if (real_addr >= 0) {
+ if (dsp_breakpoints.IsAddressBreakPoint(real_addr))
+ dsp_breakpoints.Remove(real_addr);
+ else
+ dsp_breakpoints.Add(real_addr);
+ }
+}
+
+void DSPDebugInterface::insertBLR(unsigned int address)
+{
+ PanicAlert("insertBLR functionality not supported in DSP module.");
+}
+
+// =======================================================
+// Separate the blocks with colors.
+// -------------
+int DSPDebugInterface::getColor(unsigned int address)
+{
+ static const int colors[6] =
+ {
+ 0xd0FFFF, // light cyan
+ 0xFFd0d0, // light red
+ 0xd8d8FF, // light blue
+ 0xFFd0FF, // light purple
+ 0xd0FFd0, // light green
+ 0xFFFFd0, // light yellow
+ };
+
+ // Scan backwards so we don't miss it. Hm, actually, let's not - it looks pretty good.
+ int addr = -1;
+ for (int i = 0; i < 1; i++)
+ {
+ addr = DSPSymbols::Line2Addr(address - i);
+ if (addr >= 0)
+ break;
+ }
+ if (addr == -1)
+ return 0xFFFFFF;
+
+ Symbol *symbol = DSPSymbols::g_dsp_symbol_db.GetSymbolFromAddr(addr);
+ if (!symbol)
+ return 0xFFFFFF;
+ if (symbol->type != Symbol::SYMBOL_FUNCTION)
+ return 0xEEEEFF;
+ return colors[symbol->index % 6];
+}
+// =============
+
+
+std::string DSPDebugInterface::getDescription(unsigned int address)
+{
+ return ""; // g_symbolDB.GetDescription(address);
+}
+
+unsigned int DSPDebugInterface::getPC()
+{
+ return DSPSymbols::Addr2Line(g_dsp.pc);
+}
+
+void DSPDebugInterface::setPC(unsigned int address)
+{
+ int new_pc = DSPSymbols::Line2Addr(address);
+ if (new_pc > 0)
+ g_dsp.pc = new_pc;
+}
+
+void DSPDebugInterface::runToBreakpoint()
+{
+
+}
diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/DSPDebugInterface.h b/Source/Plugins/Plugin_DSP_LLE/Src/DSPDebugInterface.h
index 79d0220148..4e2d9a2988 100644
--- a/Source/Plugins/Plugin_DSP_LLE/Src/DSPDebugInterface.h
+++ b/Source/Plugins/Plugin_DSP_LLE/Src/DSPDebugInterface.h
@@ -1,33 +1,33 @@
-#ifndef _DSPDEBUGINTERFACE_H
-#define _DSPDEBUGINTERFACE_H
-
-#include <string>
-
-#include "DebugInterface.h"
-#include "Common.h"
-
-class DSPDebugInterface : public DebugInterface
-{
-public:
- DSPDebugInterface(){}
- virtual void disasm(unsigned int address, char *dest, int max_size);
- virtual void getRawMemoryString(int memory, unsigned int address, char *dest, int max_size);
- virtual int getInstructionSize(int instruction) {return 1;}
- virtual bool isAlive();
- virtual bool isBreakpoint(unsigned int address);
- virtual void setBreakpoint(unsigned int address);
- virtual void clearBreakpoint(unsigned int address);
- virtual void clearAllBreakpoints();
- virtual void toggleBreakpoint(unsigned int address);
- virtual unsigned int readMemory(unsigned int address);
- virtual unsigned int readInstruction(unsigned int address);
- virtual unsigned int getPC();
- virtual void setPC(unsigned int address);
- virtual void step() {}
- virtual void runToBreakpoint();
- virtual void insertBLR(unsigned int address);
- virtual int getColor(unsigned int address);
- virtual std::string getDescription(unsigned int address);
-};
-
-#endif // _DSPDEBUGINTERFACE_H
+#ifndef _DSPDEBUGINTERFACE_H
+#define _DSPDEBUGINTERFACE_H
+
+#include <string>
+
+#include "DebugInterface.h"
+#include "Common.h"
+
+class DSPDebugInterface : public DebugInterface
+{
+public:
+ DSPDebugInterface(){}
+ virtual void disasm(unsigned int address, char *dest, int max_size);
+ virtual void getRawMemoryString(int memory, unsigned int address, char *dest, int max_size);
+ virtual int getInstructionSize(int instruction) {return 1;}
+ virtual bool isAlive();
+ virtual bool isBreakpoint(unsigned int address);
+ virtual void setBreakpoint(unsigned int address);
+ virtual void clearBreakpoint(unsigned int address);
+ virtual void clearAllBreakpoints();
+ virtual void toggleBreakpoint(unsigned int address);
+ virtual unsigned int readMemory(unsigned int address);
+ virtual unsigned int readInstruction(unsigned int address);
+ virtual unsigned int getPC();
+ virtual void setPC(unsigned int address);
+ virtual void step() {}
+ virtual void runToBreakpoint();
+ virtual void insertBLR(unsigned int address);
+ virtual int getColor(unsigned int address);
+ virtual std::string getDescription(unsigned int address);
+};
+
+#endif // _DSPDEBUGINTERFACE_H
diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/DSPHost.cpp b/Source/Plugins/Plugin_DSP_LLE/Src/DSPHost.cpp
index 5681564968..2fea1884b0 100644
--- a/Source/Plugins/Plugin_DSP_LLE/Src/DSPHost.cpp
+++ b/Source/Plugins/Plugin_DSP_LLE/Src/DSPHost.cpp
@@ -1,115 +1,115 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Common.h"
-#include "DSPHost.h"
-#include "DSPSymbols.h"
-#include "Tools.h"
-#include "pluginspecs_dsp.h"
-
-extern DSPInitialize g_dspInitialize;
-
-#if defined(HAVE_WX) && HAVE_WX
-
-#include "DSPConfigDlgLLE.h"
-#include "Debugger/Debugger.h" // For the DSPDebuggerLLE class
-extern DSPDebuggerLLE* m_DebuggerFrame;
-
-#endif
-
-// The user of the DSPCore library must supply a few functions so that the
-// emulation core can access the environment it runs in. If the emulation
-// core isn't used, for example in an asm/disasm tool, then most of these
-// can be stubbed out.
-
-u8 DSPHost_ReadHostMemory(u32 addr)
-{
- return g_dspInitialize.pARAM_Read_U8(addr);
-}
-
-void DSPHost_WriteHostMemory(u8 value, u32 addr)
-{
- g_dspInitialize.pARAM_Write_U8(value, addr);
-}
-
-bool DSPHost_OnThread()
-{
- return g_dspInitialize.bOnThread;
-}
-
-bool DSPHost_Running()
-{
- return !(*g_dspInitialize.pEmulatorState);
-}
-
-void DSPHost_InterruptRequest()
-{
-#ifdef DEBUG_EXP
- NOTICE_LOG(DSPLLE, "Firing an interrupt on the PPC ASAP");
-#endif
- // Fire an interrupt on the PPC ASAP.
- g_dspInitialize.pGenerateDSPInterrupt();
-}
-
-u32 DSPHost_CodeLoaded(const u8 *ptr, int size)
-{
- u32 crc = GenerateCRC(ptr, size);
- DumpDSPCode(ptr, size, crc);
-
- // this crc is comparable with the HLE plugin
- u32 ector_crc = 0;
- for (int i = 0; i < size; i++)
- {
- ector_crc ^= ptr[i];
- //let's rol
- ector_crc = (ector_crc << 3) | (ector_crc >> 29);
- }
-
- DSPSymbols::Clear();
-
- // Auto load text file - if none just disassemble.
-
- // TODO: Don't hardcode for Zelda.
- NOTICE_LOG(DSPLLE, "CRC: %08x", ector_crc);
-
- DSPSymbols::Clear();
- bool success = false;
- switch (ector_crc)
- {
- case 0x86840740: success = DSPSymbols::ReadAnnotatedAssembly("../../docs/DSP/DSP_UC_Zelda.txt"); break;
- case 0x42f64ac4: success = DSPSymbols::ReadAnnotatedAssembly("../../docs/DSP/DSP_UC_Luigi.txt"); break;
- case 0x4e8a8b21: success = DSPSymbols::ReadAnnotatedAssembly("../../docs/DSP/DSP_UC_AX1.txt"); break;
- default: success = false; break;
- }
-
- if (!success) {
- DSPSymbols::AutoDisassembly(0x0, 0x1000);
- }
-
- // Always add the ROM.
- DSPSymbols::AutoDisassembly(0x8000, 0x9000);
-
- if (m_DebuggerFrame)
- m_DebuggerFrame->Refresh();
- return crc;
-}
-
-void DSPHost_UpdateDebugger()
-{
- if (m_DebuggerFrame)
- m_DebuggerFrame->Refresh();
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "Common.h"
+#include "DSPHost.h"
+#include "DSPSymbols.h"
+#include "Tools.h"
+#include "pluginspecs_dsp.h"
+
+extern DSPInitialize g_dspInitialize;
+
+#if defined(HAVE_WX) && HAVE_WX
+
+#include "DSPConfigDlgLLE.h"
+#include "Debugger/Debugger.h" // For the DSPDebuggerLLE class
+extern DSPDebuggerLLE* m_DebuggerFrame;
+
+#endif
+
+// The user of the DSPCore library must supply a few functions so that the
+// emulation core can access the environment it runs in. If the emulation
+// core isn't used, for example in an asm/disasm tool, then most of these
+// can be stubbed out.
+
+u8 DSPHost_ReadHostMemory(u32 addr)
+{
+ return g_dspInitialize.pARAM_Read_U8(addr);
+}
+
+void DSPHost_WriteHostMemory(u8 value, u32 addr)
+{
+ g_dspInitialize.pARAM_Write_U8(value, addr);
+}
+
+bool DSPHost_OnThread()
+{
+ return g_dspInitialize.bOnThread;
+}
+
+bool DSPHost_Running()
+{
+ return !(*g_dspInitialize.pEmulatorState);
+}
+
+void DSPHost_InterruptRequest()
+{
+#ifdef DEBUG_EXP
+ NOTICE_LOG(DSPLLE, "Firing an interrupt on the PPC ASAP");
+#endif
+ // Fire an interrupt on the PPC ASAP.
+ g_dspInitialize.pGenerateDSPInterrupt();
+}
+
+u32 DSPHost_CodeLoaded(const u8 *ptr, int size)
+{
+ u32 crc = GenerateCRC(ptr, size);
+ DumpDSPCode(ptr, size, crc);
+
+ // this crc is comparable with the HLE plugin
+ u32 ector_crc = 0;
+ for (int i = 0; i < size; i++)
+ {
+ ector_crc ^= ptr[i];
+ //let's rol
+ ector_crc = (ector_crc << 3) | (ector_crc >> 29);
+ }
+
+ DSPSymbols::Clear();
+
+ // Auto load text file - if none just disassemble.
+
+ // TODO: Don't hardcode for Zelda.
+ NOTICE_LOG(DSPLLE, "CRC: %08x", ector_crc);
+
+ DSPSymbols::Clear();
+ bool success = false;
+ switch (ector_crc)
+ {
+ case 0x86840740: success = DSPSymbols::ReadAnnotatedAssembly("../../docs/DSP/DSP_UC_Zelda.txt"); break;
+ case 0x42f64ac4: success = DSPSymbols::ReadAnnotatedAssembly("../../docs/DSP/DSP_UC_Luigi.txt"); break;
+ case 0x4e8a8b21: success = DSPSymbols::ReadAnnotatedAssembly("../../docs/DSP/DSP_UC_AX1.txt"); break;
+ default: success = false; break;
+ }
+
+ if (!success) {
+ DSPSymbols::AutoDisassembly(0x0, 0x1000);
+ }
+
+ // Always add the ROM.
+ DSPSymbols::AutoDisassembly(0x8000, 0x9000);
+
+ if (m_DebuggerFrame)
+ m_DebuggerFrame->Refresh();
+ return crc;
+}
+
+void DSPHost_UpdateDebugger()
+{
+ if (m_DebuggerFrame)
+ m_DebuggerFrame->Refresh();
+}
diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/DSPSymbols.cpp b/Source/Plugins/Plugin_DSP_LLE/Src/DSPSymbols.cpp
index 7777d8df3f..4e72b54d34 100644
--- a/Source/Plugins/Plugin_DSP_LLE/Src/DSPSymbols.cpp
+++ b/Source/Plugins/Plugin_DSP_LLE/Src/DSPSymbols.cpp
@@ -1,287 +1,287 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include <iostream> // I hope this doesn't break anything
-#include <stdio.h>
-#include <stdarg.h>
-
-#include <list>
-#include <map>
-#include <string>
-
-#include "Common.h"
-#include "StringUtil.h"
-
-#include "DSPCore.h"
-#include "DSPSymbols.h"
-#include "disassemble.h"
-
-namespace DSPSymbols {
-
-DSPSymbolDB g_dsp_symbol_db;
-
-std::map<u16, int> addr_to_line;
-std::map<int, u16> line_to_addr;
-std::map<int, const char *> line_to_symbol;
-std::vector<std::string> lines;
-int line_counter = 0;
-
-int Addr2Line(u16 address) // -1 for not found
-{
- std::map<u16, int>::iterator iter = addr_to_line.find(address);
- if (iter != addr_to_line.end())
- return iter->second;
- else
- return -1;
-}
-
-int Line2Addr(int line) // -1 for not found
-{
- std::map<int, u16>::iterator iter = line_to_addr.find(line);
- if (iter != line_to_addr.end())
- return iter->second;
- else
- return -1;
-}
-
-const char *GetLineText(int line)
-{
- if (line > 0 && line < (int)lines.size())
- {
- return lines[line].c_str();
- }
- else
- return "----";
-}
-
-Symbol *DSPSymbolDB::GetSymbolFromAddr(u32 addr)
-{
- XFuncMap::iterator it = functions.find(addr);
- if (it != functions.end())
- return &it->second;
- else
- {
- for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++)
- {
- if (addr >= iter->second.address && addr < iter->second.address + iter->second.size)
- return &iter->second;
- }
- }
- return 0;
-}
-
-// lower case only
-bool IsHexDigit(char c) {
- switch (c) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case 'a':
- case 'b':
- case 'c':
- case 'd':
- case 'e':
- case 'f':
- return true;
- default:
- return false;
- }
-}
-
-bool IsAlpha(char c) {
- return (c >= 'A' && c <= 'Z') ||
- (c >= 'a' && c <= 'z');
-}
-
-void DisasssembleRange(u16 start, u16 end)
-{
-
-}
-
-bool ReadAnnotatedAssembly(const char *filename)
-{
- FILE *f = fopen(filename, "r");
- if (!f) {
- ERROR_LOG(DSPLLE, "Bah! ReadAnnotatedAssembly couldn't find the file %s", filename);
- return false;
- }
- char line[512];
-
- int last_addr = 0;
-
- lines.reserve(3000);
-
- // Symbol generation
- int brace_count = 0;
- bool symbol_in_progress = false;
-
- int symbol_count = 0;
- Symbol current_symbol;
-
- while (fgets(line, 512, f))
- {
- // Scan string for the first 4-digit hex string.
- size_t len = strlen(line);
- int first_hex = -1;
- bool hex_found = false;
- for (unsigned int i = 0; i < strlen(line); i++)
- {
- const char c = line[i];
- if (IsHexDigit(c))
- {
- if (first_hex == -1)
- {
- first_hex = i;
- }
- else
- {
- // Remove hex notation
- if (i == first_hex + 3 &&
- (first_hex == 0 || line[first_hex - 1] != 'x') &&
- (i >= len - 1 || line[i + 1] == ' '))
- {
- hex_found = true;
- break;
- }
- }
- } else {
- if (i - first_hex < 3)
- {
- first_hex = -1;
- }
- if (IsAlpha(c))
- break;
- }
- }
-
- // Scan for function starts
- if (!memcmp(line, "void", 4)) {
- char temp[256];
- for (int i = 6; i < len; i++) {
- if (line[i] == '(') {
- // Yep, got one.
- memcpy(temp, line + 5, i - 5);
- temp[i - 5] = 0;
-
- // Mark symbol so the next hex sets the address
- current_symbol.name = temp;
- current_symbol.address = 0xFFFF;
- current_symbol.index = symbol_count++;
- symbol_in_progress = true;
-
- // Reset brace count.
- brace_count = 0;
- }
- }
- }
-
- // Scan for braces
- for (int i = 0; i < (int)len; i++) {
- if (line[i] == '{')
- brace_count++;
- if (line[i] == '}')
- {
- brace_count--;
- if (brace_count == 0 && symbol_in_progress) {
- // Commit this symbol.
- current_symbol.size = last_addr - current_symbol.address + 1;
- g_dsp_symbol_db.AddCompleteSymbol(current_symbol);
- current_symbol.address = 0xFFFF;
- symbol_in_progress = false;
- }
- }
- }
-
- if (hex_found)
- {
- int hex = 0;
- sscanf(line + first_hex, "%04x", &hex);
-
- // Sanity check
- if (hex > last_addr + 3 || hex < last_addr - 3) {
- static int errors = 0;
- ERROR_LOG(DSPLLE, "Got Insane Hex Digit %04x (%04x) from %s", hex, last_addr, line);
- errors++;
- if (errors > 10)
- {
- fclose(f);
- return false;
- }
- }
- else
- {
- // if (line_counter >= 200 && line_counter <= 220)
- // NOTICE_LOG(DSPLLE, "Got Hex Digit %04x from %s, line %i", hex, line, line_counter);
- if (symbol_in_progress && current_symbol.address == 0xFFFF)
- current_symbol.address = hex;
-
- line_to_addr[line_counter] = hex;
- addr_to_line[hex] = line_counter;
- last_addr = hex;
- }
- }
-
- lines.push_back(TabsToSpaces(4, line));
- line_counter++;
- }
- fclose(f);
- return true;
-}
-
-void AutoDisassembly(u16 start_addr, u16 end_addr)
-{
- AssemblerSettings settings;
- settings.show_pc = true;
- settings.show_hex = true;
- DSPDisassembler disasm(settings);
-
- u16 addr = start_addr;
- const u16 *ptr = (start_addr >> 15) ? g_dsp.irom : g_dsp.iram;
- while (addr < end_addr)
- {
- line_to_addr[line_counter] = addr;
- addr_to_line[addr] = line_counter;
-
- std::string buf;
- if (!disasm.DisOpcode(ptr, 0, 2, &addr, buf))
- {
- ERROR_LOG(DSPLLE, "disasm failed at %04x", addr);
- break;
- }
-
- //NOTICE_LOG(DSPLLE, "added %04x %i %s", addr, line_counter, buf.c_str());
- lines.push_back(buf);
- line_counter++;
- }
-}
-
-void Clear()
-{
- addr_to_line.clear();
- line_to_addr.clear();
- lines.clear();
- line_counter = 0;
-}
-
-} // namespace DSPSymbols
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include <iostream> // I hope this doesn't break anything
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <list>
+#include <map>
+#include <string>
+
+#include "Common.h"
+#include "StringUtil.h"
+
+#include "DSPCore.h"
+#include "DSPSymbols.h"
+#include "disassemble.h"
+
+namespace DSPSymbols {
+
+DSPSymbolDB g_dsp_symbol_db;
+
+std::map<u16, int> addr_to_line;
+std::map<int, u16> line_to_addr;
+std::map<int, const char *> line_to_symbol;
+std::vector<std::string> lines;
+int line_counter = 0;
+
+int Addr2Line(u16 address) // -1 for not found
+{
+ std::map<u16, int>::iterator iter = addr_to_line.find(address);
+ if (iter != addr_to_line.end())
+ return iter->second;
+ else
+ return -1;
+}
+
+int Line2Addr(int line) // -1 for not found
+{
+ std::map<int, u16>::iterator iter = line_to_addr.find(line);
+ if (iter != line_to_addr.end())
+ return iter->second;
+ else
+ return -1;
+}
+
+const char *GetLineText(int line)
+{
+ if (line > 0 && line < (int)lines.size())
+ {
+ return lines[line].c_str();
+ }
+ else
+ return "----";
+}
+
+Symbol *DSPSymbolDB::GetSymbolFromAddr(u32 addr)
+{
+ XFuncMap::iterator it = functions.find(addr);
+ if (it != functions.end())
+ return &it->second;
+ else
+ {
+ for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++)
+ {
+ if (addr >= iter->second.address && addr < iter->second.address + iter->second.size)
+ return &iter->second;
+ }
+ }
+ return 0;
+}
+
+// lower case only
+bool IsHexDigit(char c) {
+ switch (c) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsAlpha(char c) {
+ return (c >= 'A' && c <= 'Z') ||
+ (c >= 'a' && c <= 'z');
+}
+
+void DisasssembleRange(u16 start, u16 end)
+{
+
+}
+
+bool ReadAnnotatedAssembly(const char *filename)
+{
+ FILE *f = fopen(filename, "r");
+ if (!f) {
+ ERROR_LOG(DSPLLE, "Bah! ReadAnnotatedAssembly couldn't find the file %s", filename);
+ return false;
+ }
+ char line[512];
+
+ int last_addr = 0;
+
+ lines.reserve(3000);
+
+ // Symbol generation
+ int brace_count = 0;
+ bool symbol_in_progress = false;
+
+ int symbol_count = 0;
+ Symbol current_symbol;
+
+ while (fgets(line, 512, f))
+ {
+ // Scan string for the first 4-digit hex string.
+ size_t len = strlen(line);
+ int first_hex = -1;
+ bool hex_found = false;
+ for (unsigned int i = 0; i < strlen(line); i++)
+ {
+ const char c = line[i];
+ if (IsHexDigit(c))
+ {
+ if (first_hex == -1)
+ {
+ first_hex = i;
+ }
+ else
+ {
+ // Remove hex notation
+ if (i == first_hex + 3 &&
+ (first_hex == 0 || line[first_hex - 1] != 'x') &&
+ (i >= len - 1 || line[i + 1] == ' '))
+ {
+ hex_found = true;
+ break;
+ }
+ }
+ } else {
+ if (i - first_hex < 3)
+ {
+ first_hex = -1;
+ }
+ if (IsAlpha(c))
+ break;
+ }
+ }
+
+ // Scan for function starts
+ if (!memcmp(line, "void", 4)) {
+ char temp[256];
+ for (int i = 6; i < len; i++) {
+ if (line[i] == '(') {
+ // Yep, got one.
+ memcpy(temp, line + 5, i - 5);
+ temp[i - 5] = 0;
+
+ // Mark symbol so the next hex sets the address
+ current_symbol.name = temp;
+ current_symbol.address = 0xFFFF;
+ current_symbol.index = symbol_count++;
+ symbol_in_progress = true;
+
+ // Reset brace count.
+ brace_count = 0;
+ }
+ }
+ }
+
+ // Scan for braces
+ for (int i = 0; i < (int)len; i++) {
+ if (line[i] == '{')
+ brace_count++;
+ if (line[i] == '}')
+ {
+ brace_count--;
+ if (brace_count == 0 && symbol_in_progress) {
+ // Commit this symbol.
+ current_symbol.size = last_addr - current_symbol.address + 1;
+ g_dsp_symbol_db.AddCompleteSymbol(current_symbol);
+ current_symbol.address = 0xFFFF;
+ symbol_in_progress = false;
+ }
+ }
+ }
+
+ if (hex_found)
+ {
+ int hex = 0;
+ sscanf(line + first_hex, "%04x", &hex);
+
+ // Sanity check
+ if (hex > last_addr + 3 || hex < last_addr - 3) {
+ static int errors = 0;
+ ERROR_LOG(DSPLLE, "Got Insane Hex Digit %04x (%04x) from %s", hex, last_addr, line);
+ errors++;
+ if (errors > 10)
+ {
+ fclose(f);
+ return false;
+ }
+ }
+ else
+ {
+ // if (line_counter >= 200 && line_counter <= 220)
+ // NOTICE_LOG(DSPLLE, "Got Hex Digit %04x from %s, line %i", hex, line, line_counter);
+ if (symbol_in_progress && current_symbol.address == 0xFFFF)
+ current_symbol.address = hex;
+
+ line_to_addr[line_counter] = hex;
+ addr_to_line[hex] = line_counter;
+ last_addr = hex;
+ }
+ }
+
+ lines.push_back(TabsToSpaces(4, line));
+ line_counter++;
+ }
+ fclose(f);
+ return true;
+}
+
+void AutoDisassembly(u16 start_addr, u16 end_addr)
+{
+ AssemblerSettings settings;
+ settings.show_pc = true;
+ settings.show_hex = true;
+ DSPDisassembler disasm(settings);
+
+ u16 addr = start_addr;
+ const u16 *ptr = (start_addr >> 15) ? g_dsp.irom : g_dsp.iram;
+ while (addr < end_addr)
+ {
+ line_to_addr[line_counter] = addr;
+ addr_to_line[addr] = line_counter;
+
+ std::string buf;
+ if (!disasm.DisOpcode(ptr, 0, 2, &addr, buf))
+ {
+ ERROR_LOG(DSPLLE, "disasm failed at %04x", addr);
+ break;
+ }
+
+ //NOTICE_LOG(DSPLLE, "added %04x %i %s", addr, line_counter, buf.c_str());
+ lines.push_back(buf);
+ line_counter++;
+ }
+}
+
+void Clear()
+{
+ addr_to_line.clear();
+ line_to_addr.clear();
+ lines.clear();
+ line_counter = 0;
+}
+
+} // namespace DSPSymbols
diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/DSPSymbols.h b/Source/Plugins/Plugin_DSP_LLE/Src/DSPSymbols.h
index ab91646b5d..6a63aa5a10 100644
--- a/Source/Plugins/Plugin_DSP_LLE/Src/DSPSymbols.h
+++ b/Source/Plugins/Plugin_DSP_LLE/Src/DSPSymbols.h
@@ -1,54 +1,54 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _DSPSYMBOLS_H
-#define _DSPSYMBOLS_H
-
-#include "Common.h"
-#include "SymbolDB.h"
-#include "AudioCommon.h"
-
-#include <stdio.h>
-
-namespace DSPSymbols {
-
-class DSPSymbolDB : public SymbolDB
-{
-public:
- DSPSymbolDB() {}
- ~DSPSymbolDB() {}
-
- Symbol *GetSymbolFromAddr(u32 addr);
-
-};
-
-extern DSPSymbolDB g_dsp_symbol_db;
-
-bool ReadAnnotatedAssembly(const char *filename);
-void AutoDisassembly(u16 start_addr, u16 end_addr);
-
-void Clear();
-
-int Addr2Line(u16 address);
-int Line2Addr(int line); // -1 for not found
-
-const char *GetLineText(int line);
-
-} // namespace DSPSymbols
-
-#endif
-
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _DSPSYMBOLS_H
+#define _DSPSYMBOLS_H
+
+#include "Common.h"
+#include "SymbolDB.h"
+#include "AudioCommon.h"
+
+#include <stdio.h>
+
+namespace DSPSymbols {
+
+class DSPSymbolDB : public SymbolDB
+{
+public:
+ DSPSymbolDB() {}
+ ~DSPSymbolDB() {}
+
+ Symbol *GetSymbolFromAddr(u32 addr);
+
+};
+
+extern DSPSymbolDB g_dsp_symbol_db;
+
+bool ReadAnnotatedAssembly(const char *filename);
+void AutoDisassembly(u16 start_addr, u16 end_addr);
+
+void Clear();
+
+int Addr2Line(u16 address);
+int Line2Addr(int line); // -1 for not found
+
+const char *GetLineText(int line);
+
+} // namespace DSPSymbols
+
+#endif
+
diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/Debugger/Debugger.cpp b/Source/Plugins/Plugin_DSP_LLE/Src/Debugger/Debugger.cpp
index d0c3c6ca18..32328ec9c7 100644
--- a/Source/Plugins/Plugin_DSP_LLE/Src/Debugger/Debugger.cpp
+++ b/Source/Plugins/Plugin_DSP_LLE/Src/Debugger/Debugger.cpp
@@ -1,228 +1,228 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Common.h" // Common
-#include <iostream> // System
-#include <fstream>
-#include <sstream>
-
-#include "Debugger.h"
-#include "DSPRegisterView.h"
-#include "CodeView.h"
-#include "../DSPSymbols.h"
-
-// Event table and class
-BEGIN_EVENT_TABLE(DSPDebuggerLLE, wxFrame)
- EVT_CLOSE(DSPDebuggerLLE::OnClose)
-
- EVT_MENU_RANGE(ID_RUNTOOL, ID_STEPTOOL, DSPDebuggerLLE::OnChangeState)
- EVT_MENU(ID_SHOWPCTOOL, DSPDebuggerLLE::OnShowPC)
- EVT_TEXT(ID_ADDRBOX, DSPDebuggerLLE::OnAddrBoxChange)
- EVT_LISTBOX(ID_SYMBOLLIST, DSPDebuggerLLE::OnSymbolListChange)
-END_EVENT_TABLE()
-
-DSPDebuggerLLE::DSPDebuggerLLE(wxWindow *parent, wxWindowID id, const wxString &title,
- const wxPoint &position, const wxSize& size, long style)
- : wxFrame(parent, id, title, position, size, style)
- , m_CachedStepCounter(-1)
-{
- CreateGUIControls();
-}
-
-DSPDebuggerLLE::~DSPDebuggerLLE()
-{
-}
-
-void DSPDebuggerLLE::CreateGUIControls()
-{
- // Basic settings
- SetSize(700, 800);
- this->SetSizeHints(700, 800);
- this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
-
- m_Toolbar = CreateToolBar(wxTB_NODIVIDER|wxTB_NOICONS|wxTB_HORZ_TEXT|wxTB_DOCKABLE, ID_TOOLBAR);
- m_Toolbar->AddTool(ID_RUNTOOL, wxT("Run"), wxNullBitmap, wxEmptyString, wxITEM_NORMAL);
- m_Toolbar->AddTool(ID_STEPTOOL, wxT("Step"), wxNullBitmap, wxT("Step Code "), wxITEM_NORMAL);
- m_Toolbar->AddTool(ID_SHOWPCTOOL, wxT("Show Pc"), wxNullBitmap, wxT("Show where PC is"), wxITEM_NORMAL);
- m_Toolbar->AddTool(ID_JUMPTOTOOL, wxT("Jump"), wxNullBitmap, wxT("Jump to a specific Address"), wxITEM_NORMAL);
- m_Toolbar->AddSeparator();
-
- m_Toolbar->AddControl(new wxTextCtrl(m_Toolbar, ID_ADDRBOX, _T("")));
-
- m_Toolbar->Realize();
-
- wxBoxSizer* sMain = new wxBoxSizer(wxHORIZONTAL);
- wxBoxSizer* sizerLeft = new wxBoxSizer(wxVERTICAL);
- sizerLeft->Add(m_SymbolList = new wxListBox(this, ID_SYMBOLLIST, wxDefaultPosition, wxSize(140, 100), 0, NULL, wxLB_SORT),
- 1, wxEXPAND);
-
- m_CodeView = new CCodeView(&debug_interface, &DSPSymbols::g_dsp_symbol_db, this, ID_CODEVIEW);
- m_CodeView->SetPlain();
-
- sMain->Add(sizerLeft, 0, wxEXPAND, 0);
-
- sMain->Add(m_CodeView, 4, wxEXPAND, 0);
-
- wxStaticLine* m_staticline = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL);
- sMain->Add(m_staticline, 0, wxEXPAND|wxALL, 0);
-
- m_Regs = new DSPRegisterView(this, ID_DSP_REGS);
- sMain->Add(m_Regs, 0, wxEXPAND|wxALL, 5);
-
- this->SetSizer(sMain);
- this->Layout();
-
- UpdateState();
-}
-
-void DSPDebuggerLLE::OnClose(wxCloseEvent& event)
-{
- Hide();
-}
-
-void DSPDebuggerLLE::OnChangeState(wxCommandEvent& event)
-{
- switch (event.GetId())
- {
- case ID_RUNTOOL:
- if (DSPCore_GetState() == DSPCORE_RUNNING)
- DSPCore_SetState(DSPCORE_STEPPING);
- else
- DSPCore_SetState(DSPCORE_RUNNING);
- break;
-
- case ID_STEPTOOL:
- if (DSPCore_GetState() == DSPCORE_STEPPING)
- DSPCore_Step();
- break;
-
- case ID_SHOWPCTOOL:
- FocusOnPC();
- break;
- }
-
- UpdateState();
-}
-
-void DSPDebuggerLLE::OnShowPC(wxCommandEvent& event)
-{
- Refresh();
- FocusOnPC();
-}
-
-void DSPDebuggerLLE::Refresh()
-{
- UpdateSymbolMap();
- UpdateDisAsmListView();
- UpdateRegisterFlags();
- UpdateState();
-}
-
-void DSPDebuggerLLE::FocusOnPC()
-{
- JumpToAddress(g_dsp.pc);
-}
-
-void DSPDebuggerLLE::UpdateState()
-{
- if (DSPCore_GetState() == DSPCORE_RUNNING) {
- m_Toolbar->FindById(ID_RUNTOOL)->SetLabel(wxT("Pause"));
- m_Toolbar->FindById(ID_STEPTOOL)->Enable(false);
- }
- else {
- m_Toolbar->FindById(ID_RUNTOOL)->SetLabel(wxT("Run"));
- m_Toolbar->FindById(ID_STEPTOOL)->Enable(true);
- }
- m_Toolbar->Realize();
-}
-
-void DSPDebuggerLLE::UpdateDisAsmListView()
-{
- if (m_CachedStepCounter == g_dsp.step_counter)
- return;
-
- // show PC
- FocusOnPC();
- m_CachedStepCounter = g_dsp.step_counter;
- m_Regs->Update();
-}
-
-void DSPDebuggerLLE::UpdateSymbolMap()
-{
- if (g_dsp.dram == NULL)
- return;
-
- m_SymbolList->Freeze(); // HyperIris: wx style fast filling
- m_SymbolList->Clear();
- for (SymbolDB::XFuncMap::iterator iter = DSPSymbols::g_dsp_symbol_db.GetIterator();
- iter != DSPSymbols::g_dsp_symbol_db.End(); iter++)
- {
- int idx = m_SymbolList->Append(wxString::FromAscii(iter->second.name.c_str()));
- m_SymbolList->SetClientData(idx, (void*)&iter->second);
- }
- m_SymbolList->Thaw();
-}
-
-void DSPDebuggerLLE::OnSymbolListChange(wxCommandEvent& event)
-{
- int index = m_SymbolList->GetSelection();
- if (index >= 0) {
- Symbol* pSymbol = static_cast<Symbol *>(m_SymbolList->GetClientData(index));
- if (pSymbol != NULL)
- {
- if (pSymbol->type == Symbol::SYMBOL_FUNCTION)
- {
- JumpToAddress(pSymbol->address);
- }
- }
- }
-}
-
-void DSPDebuggerLLE::UpdateRegisterFlags()
-{
-
-}
-
-void DSPDebuggerLLE::OnAddrBoxChange(wxCommandEvent& event)
-{
- wxTextCtrl* pAddrCtrl = (wxTextCtrl*)GetToolBar()->FindControl(ID_ADDRBOX);
- wxString txt = pAddrCtrl->GetValue();
-
- std::string text(txt.mb_str());
- text = StripSpaces(text);
- if (text.size())
- {
- u32 addr;
- sscanf(text.c_str(), "%04x", &addr);
- if (JumpToAddress(addr))
- pAddrCtrl->SetBackgroundColour(*wxWHITE);
- else
- pAddrCtrl->SetBackgroundColour(*wxRED);
- }
- event.Skip(1);
-}
-
-bool DSPDebuggerLLE::JumpToAddress(u16 addr)
-{
- int new_line = DSPSymbols::Addr2Line(addr);
- if (new_line >= 0) {
- m_CodeView->Center(new_line);
- return true;
- } else {
- return false;
- }
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "Common.h" // Common
+#include <iostream> // System
+#include <fstream>
+#include <sstream>
+
+#include "Debugger.h"
+#include "DSPRegisterView.h"
+#include "CodeView.h"
+#include "../DSPSymbols.h"
+
+// Event table and class
+BEGIN_EVENT_TABLE(DSPDebuggerLLE, wxFrame)
+ EVT_CLOSE(DSPDebuggerLLE::OnClose)
+
+ EVT_MENU_RANGE(ID_RUNTOOL, ID_STEPTOOL, DSPDebuggerLLE::OnChangeState)
+ EVT_MENU(ID_SHOWPCTOOL, DSPDebuggerLLE::OnShowPC)
+ EVT_TEXT(ID_ADDRBOX, DSPDebuggerLLE::OnAddrBoxChange)
+ EVT_LISTBOX(ID_SYMBOLLIST, DSPDebuggerLLE::OnSymbolListChange)
+END_EVENT_TABLE()
+
+DSPDebuggerLLE::DSPDebuggerLLE(wxWindow *parent, wxWindowID id, const wxString &title,
+ const wxPoint &position, const wxSize& size, long style)
+ : wxFrame(parent, id, title, position, size, style)
+ , m_CachedStepCounter(-1)
+{
+ CreateGUIControls();
+}
+
+DSPDebuggerLLE::~DSPDebuggerLLE()
+{
+}
+
+void DSPDebuggerLLE::CreateGUIControls()
+{
+ // Basic settings
+ SetSize(700, 800);
+ this->SetSizeHints(700, 800);
+ this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
+
+ m_Toolbar = CreateToolBar(wxTB_NODIVIDER|wxTB_NOICONS|wxTB_HORZ_TEXT|wxTB_DOCKABLE, ID_TOOLBAR);
+ m_Toolbar->AddTool(ID_RUNTOOL, wxT("Run"), wxNullBitmap, wxEmptyString, wxITEM_NORMAL);
+ m_Toolbar->AddTool(ID_STEPTOOL, wxT("Step"), wxNullBitmap, wxT("Step Code "), wxITEM_NORMAL);
+ m_Toolbar->AddTool(ID_SHOWPCTOOL, wxT("Show Pc"), wxNullBitmap, wxT("Show where PC is"), wxITEM_NORMAL);
+ m_Toolbar->AddTool(ID_JUMPTOTOOL, wxT("Jump"), wxNullBitmap, wxT("Jump to a specific Address"), wxITEM_NORMAL);
+ m_Toolbar->AddSeparator();
+
+ m_Toolbar->AddControl(new wxTextCtrl(m_Toolbar, ID_ADDRBOX, _T("")));
+
+ m_Toolbar->Realize();
+
+ wxBoxSizer* sMain = new wxBoxSizer(wxHORIZONTAL);
+ wxBoxSizer* sizerLeft = new wxBoxSizer(wxVERTICAL);
+ sizerLeft->Add(m_SymbolList = new wxListBox(this, ID_SYMBOLLIST, wxDefaultPosition, wxSize(140, 100), 0, NULL, wxLB_SORT),
+ 1, wxEXPAND);
+
+ m_CodeView = new CCodeView(&debug_interface, &DSPSymbols::g_dsp_symbol_db, this, ID_CODEVIEW);
+ m_CodeView->SetPlain();
+
+ sMain->Add(sizerLeft, 0, wxEXPAND, 0);
+
+ sMain->Add(m_CodeView, 4, wxEXPAND, 0);
+
+ wxStaticLine* m_staticline = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL);
+ sMain->Add(m_staticline, 0, wxEXPAND|wxALL, 0);
+
+ m_Regs = new DSPRegisterView(this, ID_DSP_REGS);
+ sMain->Add(m_Regs, 0, wxEXPAND|wxALL, 5);
+
+ this->SetSizer(sMain);
+ this->Layout();
+
+ UpdateState();
+}
+
+void DSPDebuggerLLE::OnClose(wxCloseEvent& event)
+{
+ Hide();
+}
+
+void DSPDebuggerLLE::OnChangeState(wxCommandEvent& event)
+{
+ switch (event.GetId())
+ {
+ case ID_RUNTOOL:
+ if (DSPCore_GetState() == DSPCORE_RUNNING)
+ DSPCore_SetState(DSPCORE_STEPPING);
+ else
+ DSPCore_SetState(DSPCORE_RUNNING);
+ break;
+
+ case ID_STEPTOOL:
+ if (DSPCore_GetState() == DSPCORE_STEPPING)
+ DSPCore_Step();
+ break;
+
+ case ID_SHOWPCTOOL:
+ FocusOnPC();
+ break;
+ }
+
+ UpdateState();
+}
+
+void DSPDebuggerLLE::OnShowPC(wxCommandEvent& event)
+{
+ Refresh();
+ FocusOnPC();
+}
+
+void DSPDebuggerLLE::Refresh()
+{
+ UpdateSymbolMap();
+ UpdateDisAsmListView();
+ UpdateRegisterFlags();
+ UpdateState();
+}
+
+void DSPDebuggerLLE::FocusOnPC()
+{
+ JumpToAddress(g_dsp.pc);
+}
+
+void DSPDebuggerLLE::UpdateState()
+{
+ if (DSPCore_GetState() == DSPCORE_RUNNING) {
+ m_Toolbar->FindById(ID_RUNTOOL)->SetLabel(wxT("Pause"));
+ m_Toolbar->FindById(ID_STEPTOOL)->Enable(false);
+ }
+ else {
+ m_Toolbar->FindById(ID_RUNTOOL)->SetLabel(wxT("Run"));
+ m_Toolbar->FindById(ID_STEPTOOL)->Enable(true);
+ }
+ m_Toolbar->Realize();
+}
+
+void DSPDebuggerLLE::UpdateDisAsmListView()
+{
+ if (m_CachedStepCounter == g_dsp.step_counter)
+ return;
+
+ // show PC
+ FocusOnPC();
+ m_CachedStepCounter = g_dsp.step_counter;
+ m_Regs->Update();
+}
+
+void DSPDebuggerLLE::UpdateSymbolMap()
+{
+ if (g_dsp.dram == NULL)
+ return;
+
+ m_SymbolList->Freeze(); // HyperIris: wx style fast filling
+ m_SymbolList->Clear();
+ for (SymbolDB::XFuncMap::iterator iter = DSPSymbols::g_dsp_symbol_db.GetIterator();
+ iter != DSPSymbols::g_dsp_symbol_db.End(); iter++)
+ {
+ int idx = m_SymbolList->Append(wxString::FromAscii(iter->second.name.c_str()));
+ m_SymbolList->SetClientData(idx, (void*)&iter->second);
+ }
+ m_SymbolList->Thaw();
+}
+
+void DSPDebuggerLLE::OnSymbolListChange(wxCommandEvent& event)
+{
+ int index = m_SymbolList->GetSelection();
+ if (index >= 0) {
+ Symbol* pSymbol = static_cast<Symbol *>(m_SymbolList->GetClientData(index));
+ if (pSymbol != NULL)
+ {
+ if (pSymbol->type == Symbol::SYMBOL_FUNCTION)
+ {
+ JumpToAddress(pSymbol->address);
+ }
+ }
+ }
+}
+
+void DSPDebuggerLLE::UpdateRegisterFlags()
+{
+
+}
+
+void DSPDebuggerLLE::OnAddrBoxChange(wxCommandEvent& event)
+{
+ wxTextCtrl* pAddrCtrl = (wxTextCtrl*)GetToolBar()->FindControl(ID_ADDRBOX);
+ wxString txt = pAddrCtrl->GetValue();
+
+ std::string text(txt.mb_str());
+ text = StripSpaces(text);
+ if (text.size())
+ {
+ u32 addr;
+ sscanf(text.c_str(), "%04x", &addr);
+ if (JumpToAddress(addr))
+ pAddrCtrl->SetBackgroundColour(*wxWHITE);
+ else
+ pAddrCtrl->SetBackgroundColour(*wxRED);
+ }
+ event.Skip(1);
+}
+
+bool DSPDebuggerLLE::JumpToAddress(u16 addr)
+{
+ int new_line = DSPSymbols::Addr2Line(addr);
+ if (new_line >= 0) {
+ m_CodeView->Center(new_line);
+ return true;
+ } else {
+ return false;
+ }
+}
diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/Debugger/Debugger.h b/Source/Plugins/Plugin_DSP_LLE/Src/Debugger/Debugger.h
index f68ca8b020..5d44b16199 100644
--- a/Source/Plugins/Plugin_DSP_LLE/Src/Debugger/Debugger.h
+++ b/Source/Plugins/Plugin_DSP_LLE/Src/Debugger/Debugger.h
@@ -1,126 +1,126 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _DSP_DEBUGGER_LLE_H
-#define _DSP_DEBUGGER_LLE_H
-
-// general things
-#include <iostream>
-#include <vector>
-#include <list>
-#include <map>
-#include <algorithm>
-
-#include <wx/wx.h>
-#include <wx/frame.h>
-#include <wx/button.h>
-#include <wx/stattext.h>
-#include <wx/statbox.h>
-#include <wx/sizer.h>
-#include <wx/listctrl.h>
-#include <wx/statline.h>
-
-#include "disassemble.h"
-#include "DSPInterpreter.h"
-#include "DSPMemoryMap.h"
-#include "../DSPDebugInterface.h"
-
-class DSPRegisterView;
-class CCodeView;
-
-class DSPDebuggerLLE : public wxFrame
-{
-public:
- DSPDebuggerLLE(wxWindow *parent,
- wxWindowID id = wxID_ANY,
- const wxString &title = wxT("DSP LLE Debugger"),
- const wxPoint& pos = wxDefaultPosition,
- const wxSize& size = wxDefaultSize,
- long style = wxDEFAULT_FRAME_STYLE);
-
- virtual ~DSPDebuggerLLE();
-
- void Refresh();
-
-private:
- DECLARE_EVENT_TABLE();
-
- enum
- {
- // Toolbar
- ID_TOOLBAR = 1000,
- ID_RUNTOOL,
- ID_STEPTOOL,
- ID_SHOWPCTOOL,
- ID_ADDRBOX,
- ID_JUMPTOTOOL,
- ID_DISASMDUMPTOOL,
- ID_CHECK_ASSERTINT,
- ID_CHECK_HALT,
- ID_CHECK_INIT,
- ID_SYMBOLLIST,
-
- // Code view
- ID_CODEVIEW,
-
- // Register View
- ID_DSP_REGS,
- };
-
- // Disasm listctrl columns
- enum
- {
- COLUMN_BP,
- COLUMN_FUNCTION,
- COLUMN_ADDRESS,
- COLUMN_MNEMONIC,
- COLUMN_OPCODE,
- COLUMN_EXT,
- COLUMN_PARAM,
- };
-
- DSPDebugInterface debug_interface;
- u64 m_CachedStepCounter;
-
- // GUI updaters
- void UpdateDisAsmListView();
- void UpdateRegisterFlags();
- void UpdateSymbolMap();
- void UpdateState();
-
- // GUI items
- wxToolBar* m_Toolbar;
- CCodeView* m_CodeView;
- DSPRegisterView* m_Regs;
- wxListBox* m_SymbolList;
-
- void OnClose(wxCloseEvent& event);
- void OnChangeState(wxCommandEvent& event);
- void OnShowPC(wxCommandEvent& event);
- void OnRightClick(wxListEvent& event);
- void OnDoubleClick(wxListEvent& event);
- void OnAddrBoxChange(wxCommandEvent& event);
- void OnSymbolListChange(wxCommandEvent& event);
-
- bool JumpToAddress(u16 addr);
-
- void CreateGUIControls();
- void FocusOnPC();
- void UnselectAll();
-};
-
-#endif //_DSP_DEBUGGER_LLE_H
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _DSP_DEBUGGER_LLE_H
+#define _DSP_DEBUGGER_LLE_H
+
+// general things
+#include <iostream>
+#include <vector>
+#include <list>
+#include <map>
+#include <algorithm>
+
+#include <wx/wx.h>
+#include <wx/frame.h>
+#include <wx/button.h>
+#include <wx/stattext.h>
+#include <wx/statbox.h>
+#include <wx/sizer.h>
+#include <wx/listctrl.h>
+#include <wx/statline.h>
+
+#include "disassemble.h"
+#include "DSPInterpreter.h"
+#include "DSPMemoryMap.h"
+#include "../DSPDebugInterface.h"
+
+class DSPRegisterView;
+class CCodeView;
+
+class DSPDebuggerLLE : public wxFrame
+{
+public:
+ DSPDebuggerLLE(wxWindow *parent,
+ wxWindowID id = wxID_ANY,
+ const wxString &title = wxT("DSP LLE Debugger"),
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxDEFAULT_FRAME_STYLE);
+
+ virtual ~DSPDebuggerLLE();
+
+ void Refresh();
+
+private:
+ DECLARE_EVENT_TABLE();
+
+ enum
+ {
+ // Toolbar
+ ID_TOOLBAR = 1000,
+ ID_RUNTOOL,
+ ID_STEPTOOL,
+ ID_SHOWPCTOOL,
+ ID_ADDRBOX,
+ ID_JUMPTOTOOL,
+ ID_DISASMDUMPTOOL,
+ ID_CHECK_ASSERTINT,
+ ID_CHECK_HALT,
+ ID_CHECK_INIT,
+ ID_SYMBOLLIST,
+
+ // Code view
+ ID_CODEVIEW,
+
+ // Register View
+ ID_DSP_REGS,
+ };
+
+ // Disasm listctrl columns
+ enum
+ {
+ COLUMN_BP,
+ COLUMN_FUNCTION,
+ COLUMN_ADDRESS,
+ COLUMN_MNEMONIC,
+ COLUMN_OPCODE,
+ COLUMN_EXT,
+ COLUMN_PARAM,
+ };
+
+ DSPDebugInterface debug_interface;
+ u64 m_CachedStepCounter;
+
+ // GUI updaters
+ void UpdateDisAsmListView();
+ void UpdateRegisterFlags();
+ void UpdateSymbolMap();
+ void UpdateState();
+
+ // GUI items
+ wxToolBar* m_Toolbar;
+ CCodeView* m_CodeView;
+ DSPRegisterView* m_Regs;
+ wxListBox* m_SymbolList;
+
+ void OnClose(wxCloseEvent& event);
+ void OnChangeState(wxCommandEvent& event);
+ void OnShowPC(wxCommandEvent& event);
+ void OnRightClick(wxListEvent& event);
+ void OnDoubleClick(wxListEvent& event);
+ void OnAddrBoxChange(wxCommandEvent& event);
+ void OnSymbolListChange(wxCommandEvent& event);
+
+ bool JumpToAddress(u16 addr);
+
+ void CreateGUIControls();
+ void FocusOnPC();
+ void UnselectAll();
+};
+
+#endif //_DSP_DEBUGGER_LLE_H
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp b/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp
index 8107c28c0f..876efd0d5f 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp
@@ -1,336 +1,336 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "BPFunctions.h"
-#include "D3DBase.h"
-#include "Config.h"
-#include "Common.h"
-#include "TextureCache.h"
-#include "VertexManager.h"
-#include "VertexShaderManager.h"
-#include "Utils.h"
-
-
-bool textureChanged[8];
-
-const bool renderFog = false;
-
-using namespace D3D;
-
-// State translation lookup tables
-static const D3DBLEND d3dSrcFactors[8] =
-{
- D3DBLEND_ZERO,
- D3DBLEND_ONE,
- D3DBLEND_DESTCOLOR,
- D3DBLEND_INVDESTCOLOR,
- D3DBLEND_SRCALPHA,
- D3DBLEND_INVSRCALPHA,
- D3DBLEND_DESTALPHA,
- D3DBLEND_INVDESTALPHA
-};
-
-static const D3DBLEND d3dDestFactors[8] =
-{
- D3DBLEND_ZERO,
- D3DBLEND_ONE,
- D3DBLEND_SRCCOLOR,
- D3DBLEND_INVSRCCOLOR,
- D3DBLEND_SRCALPHA,
- D3DBLEND_INVSRCALPHA,
- D3DBLEND_DESTALPHA,
- D3DBLEND_INVDESTALPHA
-};
-
-static const D3DCULL d3dCullModes[4] =
-{
- D3DCULL_NONE,
- D3DCULL_CCW,
- D3DCULL_CW,
- D3DCULL_CCW
-};
-
-static const D3DCMPFUNC d3dCmpFuncs[8] =
-{
- D3DCMP_NEVER,
- D3DCMP_LESS,
- D3DCMP_EQUAL,
- D3DCMP_LESSEQUAL,
- D3DCMP_GREATER,
- D3DCMP_NOTEQUAL,
- D3DCMP_GREATEREQUAL,
- D3DCMP_ALWAYS
-};
-
-static const D3DTEXTUREFILTERTYPE d3dMipFilters[4] =
-{
- D3DTEXF_NONE,
- D3DTEXF_POINT,
- D3DTEXF_ANISOTROPIC,
- D3DTEXF_LINEAR, //reserved
-};
-
-static const D3DTEXTUREADDRESS d3dClamps[4] =
-{
- D3DTADDRESS_CLAMP,
- D3DTADDRESS_WRAP,
- D3DTADDRESS_MIRROR,
- D3DTADDRESS_WRAP //reserved
-};
-
-namespace BPFunctions
-{
-
-void FlushPipeline()
-{
- VertexManager::Flush();
-}
-
-void SetGenerationMode(const Bypass &bp)
-{
- // dev->SetRenderState(D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode]);
- Renderer::SetRenderState(D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode]);
-
- if (bpmem.genMode.cullmode == 3)
- {
- // dev->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
- Renderer::SetRenderState(D3DRS_COLORWRITEENABLE, 0);
- }
- else
- {
- DWORD write = 0;
- if (bpmem.blendmode.alphaupdate)
- write = D3DCOLORWRITEENABLE_ALPHA;
- if (bpmem.blendmode.colorupdate)
- write |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE;
-
- // dev->SetRenderState(D3DRS_COLORWRITEENABLE, write);
- Renderer::SetRenderState(D3DRS_COLORWRITEENABLE, write);
- }
-}
-
-void SetScissor(const Bypass &bp)
-{
- Renderer::SetScissorRect();
-}
-void SetLineWidth(const Bypass &bp)
-{
- // We can't change line width in D3D unless we use ID3DXLine
- float psize = float(bpmem.lineptwidth.pointsize) * 6.0f;
- Renderer::SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&psize));
-}
-void SetDepthMode(const Bypass &bp)
-{
- if (bpmem.zmode.testenable)
- {
- // dev->SetRenderState(D3DRS_ZENABLE, TRUE);
- // dev->SetRenderState(D3DRS_ZWRITEENABLE, bpmem.zmode.updateenable);
- // dev->SetRenderState(D3DRS_ZFUNC,d3dCmpFuncs[bpmem.zmode.func]);
-
- Renderer::SetRenderState(D3DRS_ZENABLE, TRUE);
- Renderer::SetRenderState(D3DRS_ZWRITEENABLE, bpmem.zmode.updateenable);
- Renderer::SetRenderState(D3DRS_ZFUNC, d3dCmpFuncs[bpmem.zmode.func]);
- }
- else
- {
- // if the test is disabled write is disabled too
- // dev->SetRenderState(D3DRS_ZENABLE, FALSE);
- // dev->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
-
- Renderer::SetRenderState(D3DRS_ZENABLE, FALSE);
- Renderer::SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
- }
-
- //if (!bpmem.zmode.updateenable)
- // Renderer::SetRenderMode(Renderer::RM_Normal);
-
-}
-void SetBlendMode(const Bypass &bp)
-{
- if (bp.changes & 1)
- Renderer::SetRenderState(D3DRS_ALPHABLENDENABLE, bpmem.blendmode.blendenable);
-
- D3DBLEND src = d3dSrcFactors[bpmem.blendmode.srcfactor];
- D3DBLEND dst = d3dDestFactors[bpmem.blendmode.dstfactor];
-
- if (bp.changes & 0x700)
- Renderer::SetRenderState(D3DRS_SRCBLEND, src);
-
- if (bp.changes & 0xE0) {
- if (!bpmem.blendmode.subtract)
- {
- Renderer::SetRenderState(D3DRS_DESTBLEND, dst);
- }
- else
- {
- Renderer::SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
- }
- }
- if (bp.changes & 0x800)
- {
- if (bpmem.blendmode.subtract)
- {
- Renderer::SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
- Renderer::SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
- }
- else
- {
- Renderer::SetRenderState(D3DRS_SRCBLEND, src);
- Renderer::SetRenderState(D3DRS_DESTBLEND, dst);
- }
-
- Renderer::SetRenderState(D3DRS_BLENDOP, bpmem.blendmode.subtract ? D3DBLENDOP_SUBTRACT : D3DBLENDOP_ADD);
- }
-}
-void SetDitherMode(const Bypass &bp)
-{
- Renderer::SetRenderState(D3DRS_DITHERENABLE,bpmem.blendmode.dither);
-}
-void SetLogicOpMode(const Bypass &bp)
-{
- // Logic op blending. D3D can't do this but can fake some modes.
-}
-void SetColorMask(const Bypass &bp)
-{
- DWORD write = 0;
- if (bpmem.blendmode.alphaupdate)
- write = D3DCOLORWRITEENABLE_ALPHA;
- if (bpmem.blendmode.colorupdate)
- write |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE;
-
- Renderer::SetRenderState(D3DRS_COLORWRITEENABLE, write);
-}
-float GetRendererTargetScaleX()
-{
- return Renderer::GetXScale();
-}
-float GetRendererTargetScaleY()
-{
- return Renderer::GetYScale();
-}
-void CopyEFB(const Bypass &bp, const TRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const bool &scaleByHalf)
-{
- RECT rec = { rc.left, rc.top, rc.right, rc.bottom };
- TextureCache::CopyEFBToRenderTarget(bpmem.copyTexDest<<5, &rec);
-}
-
-void RenderToXFB(const Bypass &bp, const TRectangle &multirc, const float &yScale, const float &xfbLines, u32 xfbAddr, const u32 &dstWidth, const u32 &dstHeight)
-{
- Renderer::SwapBuffers();
- PRIM_LOG("Renderer::SwapBuffers()");
- g_VideoInitialize.pCopiedToXFB();
-}
-void ClearScreen(const Bypass &bp, const TRectangle &multirc)
-{
- // it seems that the GC is able to alpha blend on color-fill
- // we cant do that so if alpha is != 255 we skip it
-
- VertexShaderManager::SetViewportChanged();
-
- // Since clear operations use the source rectangle, we have to do
- // regular renders
- DWORD clearflags = 0;
- D3DCOLOR col = 0;
- float clearZ = 0;
-
- if (bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate)
- {
- if (bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate)
- col = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
- // clearflags |= D3DCLEAR_TARGET; set to break animal crossing :p
- }
-
- // clear z-buffer
- if (bpmem.zmode.updateenable)
- {
- clearZ = (float)(bpmem.clearZValue & 0xFFFFFF) / float(0xFFFFFF);
- if (clearZ > 1.0f) clearZ = 1.0f;
- if (clearZ < 0.0f) clearZ = 0.0f;
- clearflags |= D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL;
- }
-
- D3D::dev->Clear(0, NULL, clearflags, col, clearZ, 0);
-}
-
-void RestoreRenderState(const Bypass &bp)
-{
- //Renderer::SetRenderMode(Renderer::RM_Normal);
-}
-
-bool GetConfig(const int &type)
-{
- switch (type)
- {
- case CONFIG_ISWII:
- return g_VideoInitialize.bWii;
- case CONFIG_DISABLEFOG:
- return false;
- case CONFIG_SHOWEFBREGIONS:
- return false;
- default:
- PanicAlert("GetConfig Error: Unknown Config Type!");
- return false;
- }
-}
-u8 *GetPointer(const u32 &address)
-{
- return g_VideoInitialize.pGetMemoryPointer(address);
-}
-void SetSamplerState(const Bypass &bp)
-{
- FourTexUnits &tex = bpmem.tex[(bp.address & 0xE0) == 0xA0];
- int stage = (bp.address & 3);//(addr>>4)&2;
- TexMode0 &tm0 = tex.texMode0[stage];
-
- D3DTEXTUREFILTERTYPE min, mag, mip;
- if (g_Config.bForceFiltering)
- {
- min = mag = mip = D3DTEXF_LINEAR;
- }
- else
- {
- min = (tm0.min_filter & 4) ? D3DTEXF_LINEAR : D3DTEXF_POINT;
- mag = tm0.mag_filter ? D3DTEXF_LINEAR : D3DTEXF_POINT;
- mip = d3dMipFilters[tm0.min_filter & 3];
- }
- if ((bp.address & 0xE0) == 0xA0)
- stage += 4;
-
- if (g_Config.bForceMaxAniso)
- {
- mag = D3DTEXF_ANISOTROPIC;
- mip = D3DTEXF_ANISOTROPIC;
- min = D3DTEXF_ANISOTROPIC;
- }
- dev->SetSamplerState(stage, D3DSAMP_MINFILTER, min);
- dev->SetSamplerState(stage, D3DSAMP_MAGFILTER, mag);
- dev->SetSamplerState(stage, D3DSAMP_MIPFILTER, mip);
-
- dev->SetSamplerState(stage, D3DSAMP_MAXANISOTROPY, 16);
- dev->SetSamplerState(stage, D3DSAMP_ADDRESSU, d3dClamps[tm0.wrap_s]);
- dev->SetSamplerState(stage, D3DSAMP_ADDRESSV, d3dClamps[tm0.wrap_t]);
- //wip
- //dev->SetSamplerState(stage,D3DSAMP_MIPMAPLODBIAS,tm0.lod_bias/4.0f);
- //char temp[256];
- //sprintf(temp,"lod %f",tm0.lod_bias/4.0f);
- //g_VideoInitialize.pLog(temp);
-}
-void SetInterlacingMode(const Bypass &bp)
-{
- // TODO
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "BPFunctions.h"
+#include "D3DBase.h"
+#include "Config.h"
+#include "Common.h"
+#include "TextureCache.h"
+#include "VertexManager.h"
+#include "VertexShaderManager.h"
+#include "Utils.h"
+
+
+bool textureChanged[8];
+
+const bool renderFog = false;
+
+using namespace D3D;
+
+// State translation lookup tables
+static const D3DBLEND d3dSrcFactors[8] =
+{
+ D3DBLEND_ZERO,
+ D3DBLEND_ONE,
+ D3DBLEND_DESTCOLOR,
+ D3DBLEND_INVDESTCOLOR,
+ D3DBLEND_SRCALPHA,
+ D3DBLEND_INVSRCALPHA,
+ D3DBLEND_DESTALPHA,
+ D3DBLEND_INVDESTALPHA
+};
+
+static const D3DBLEND d3dDestFactors[8] =
+{
+ D3DBLEND_ZERO,
+ D3DBLEND_ONE,
+ D3DBLEND_SRCCOLOR,
+ D3DBLEND_INVSRCCOLOR,
+ D3DBLEND_SRCALPHA,
+ D3DBLEND_INVSRCALPHA,
+ D3DBLEND_DESTALPHA,
+ D3DBLEND_INVDESTALPHA
+};
+
+static const D3DCULL d3dCullModes[4] =
+{
+ D3DCULL_NONE,
+ D3DCULL_CCW,
+ D3DCULL_CW,
+ D3DCULL_CCW
+};
+
+static const D3DCMPFUNC d3dCmpFuncs[8] =
+{
+ D3DCMP_NEVER,
+ D3DCMP_LESS,
+ D3DCMP_EQUAL,
+ D3DCMP_LESSEQUAL,
+ D3DCMP_GREATER,
+ D3DCMP_NOTEQUAL,
+ D3DCMP_GREATEREQUAL,
+ D3DCMP_ALWAYS
+};
+
+static const D3DTEXTUREFILTERTYPE d3dMipFilters[4] =
+{
+ D3DTEXF_NONE,
+ D3DTEXF_POINT,
+ D3DTEXF_ANISOTROPIC,
+ D3DTEXF_LINEAR, //reserved
+};
+
+static const D3DTEXTUREADDRESS d3dClamps[4] =
+{
+ D3DTADDRESS_CLAMP,
+ D3DTADDRESS_WRAP,
+ D3DTADDRESS_MIRROR,
+ D3DTADDRESS_WRAP //reserved
+};
+
+namespace BPFunctions
+{
+
+void FlushPipeline()
+{
+ VertexManager::Flush();
+}
+
+void SetGenerationMode(const Bypass &bp)
+{
+ // dev->SetRenderState(D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode]);
+ Renderer::SetRenderState(D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode]);
+
+ if (bpmem.genMode.cullmode == 3)
+ {
+ // dev->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
+ Renderer::SetRenderState(D3DRS_COLORWRITEENABLE, 0);
+ }
+ else
+ {
+ DWORD write = 0;
+ if (bpmem.blendmode.alphaupdate)
+ write = D3DCOLORWRITEENABLE_ALPHA;
+ if (bpmem.blendmode.colorupdate)
+ write |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE;
+
+ // dev->SetRenderState(D3DRS_COLORWRITEENABLE, write);
+ Renderer::SetRenderState(D3DRS_COLORWRITEENABLE, write);
+ }
+}
+
+void SetScissor(const Bypass &bp)
+{
+ Renderer::SetScissorRect();
+}
+void SetLineWidth(const Bypass &bp)
+{
+ // We can't change line width in D3D unless we use ID3DXLine
+ float psize = float(bpmem.lineptwidth.pointsize) * 6.0f;
+ Renderer::SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&psize));
+}
+void SetDepthMode(const Bypass &bp)
+{
+ if (bpmem.zmode.testenable)
+ {
+ // dev->SetRenderState(D3DRS_ZENABLE, TRUE);
+ // dev->SetRenderState(D3DRS_ZWRITEENABLE, bpmem.zmode.updateenable);
+ // dev->SetRenderState(D3DRS_ZFUNC,d3dCmpFuncs[bpmem.zmode.func]);
+
+ Renderer::SetRenderState(D3DRS_ZENABLE, TRUE);
+ Renderer::SetRenderState(D3DRS_ZWRITEENABLE, bpmem.zmode.updateenable);
+ Renderer::SetRenderState(D3DRS_ZFUNC, d3dCmpFuncs[bpmem.zmode.func]);
+ }
+ else
+ {
+ // if the test is disabled write is disabled too
+ // dev->SetRenderState(D3DRS_ZENABLE, FALSE);
+ // dev->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+
+ Renderer::SetRenderState(D3DRS_ZENABLE, FALSE);
+ Renderer::SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+ }
+
+ //if (!bpmem.zmode.updateenable)
+ // Renderer::SetRenderMode(Renderer::RM_Normal);
+
+}
+void SetBlendMode(const Bypass &bp)
+{
+ if (bp.changes & 1)
+ Renderer::SetRenderState(D3DRS_ALPHABLENDENABLE, bpmem.blendmode.blendenable);
+
+ D3DBLEND src = d3dSrcFactors[bpmem.blendmode.srcfactor];
+ D3DBLEND dst = d3dDestFactors[bpmem.blendmode.dstfactor];
+
+ if (bp.changes & 0x700)
+ Renderer::SetRenderState(D3DRS_SRCBLEND, src);
+
+ if (bp.changes & 0xE0) {
+ if (!bpmem.blendmode.subtract)
+ {
+ Renderer::SetRenderState(D3DRS_DESTBLEND, dst);
+ }
+ else
+ {
+ Renderer::SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
+ }
+ }
+ if (bp.changes & 0x800)
+ {
+ if (bpmem.blendmode.subtract)
+ {
+ Renderer::SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
+ Renderer::SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
+ }
+ else
+ {
+ Renderer::SetRenderState(D3DRS_SRCBLEND, src);
+ Renderer::SetRenderState(D3DRS_DESTBLEND, dst);
+ }
+
+ Renderer::SetRenderState(D3DRS_BLENDOP, bpmem.blendmode.subtract ? D3DBLENDOP_SUBTRACT : D3DBLENDOP_ADD);
+ }
+}
+void SetDitherMode(const Bypass &bp)
+{
+ Renderer::SetRenderState(D3DRS_DITHERENABLE,bpmem.blendmode.dither);
+}
+void SetLogicOpMode(const Bypass &bp)
+{
+ // Logic op blending. D3D can't do this but can fake some modes.
+}
+void SetColorMask(const Bypass &bp)
+{
+ DWORD write = 0;
+ if (bpmem.blendmode.alphaupdate)
+ write = D3DCOLORWRITEENABLE_ALPHA;
+ if (bpmem.blendmode.colorupdate)
+ write |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE;
+
+ Renderer::SetRenderState(D3DRS_COLORWRITEENABLE, write);
+}
+float GetRendererTargetScaleX()
+{
+ return Renderer::GetXScale();
+}
+float GetRendererTargetScaleY()
+{
+ return Renderer::GetYScale();
+}
+void CopyEFB(const Bypass &bp, const TRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const bool &scaleByHalf)
+{
+ RECT rec = { rc.left, rc.top, rc.right, rc.bottom };
+ TextureCache::CopyEFBToRenderTarget(bpmem.copyTexDest<<5, &rec);
+}
+
+void RenderToXFB(const Bypass &bp, const TRectangle &multirc, const float &yScale, const float &xfbLines, u32 xfbAddr, const u32 &dstWidth, const u32 &dstHeight)
+{
+ Renderer::SwapBuffers();
+ PRIM_LOG("Renderer::SwapBuffers()");
+ g_VideoInitialize.pCopiedToXFB();
+}
+void ClearScreen(const Bypass &bp, const TRectangle &multirc)
+{
+ // it seems that the GC is able to alpha blend on color-fill
+ // we cant do that so if alpha is != 255 we skip it
+
+ VertexShaderManager::SetViewportChanged();
+
+ // Since clear operations use the source rectangle, we have to do
+ // regular renders
+ DWORD clearflags = 0;
+ D3DCOLOR col = 0;
+ float clearZ = 0;
+
+ if (bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate)
+ {
+ if (bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate)
+ col = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
+ // clearflags |= D3DCLEAR_TARGET; set to break animal crossing :p
+ }
+
+ // clear z-buffer
+ if (bpmem.zmode.updateenable)
+ {
+ clearZ = (float)(bpmem.clearZValue & 0xFFFFFF) / float(0xFFFFFF);
+ if (clearZ > 1.0f) clearZ = 1.0f;
+ if (clearZ < 0.0f) clearZ = 0.0f;
+ clearflags |= D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL;
+ }
+
+ D3D::dev->Clear(0, NULL, clearflags, col, clearZ, 0);
+}
+
+void RestoreRenderState(const Bypass &bp)
+{
+ //Renderer::SetRenderMode(Renderer::RM_Normal);
+}
+
+bool GetConfig(const int &type)
+{
+ switch (type)
+ {
+ case CONFIG_ISWII:
+ return g_VideoInitialize.bWii;
+ case CONFIG_DISABLEFOG:
+ return false;
+ case CONFIG_SHOWEFBREGIONS:
+ return false;
+ default:
+ PanicAlert("GetConfig Error: Unknown Config Type!");
+ return false;
+ }
+}
+u8 *GetPointer(const u32 &address)
+{
+ return g_VideoInitialize.pGetMemoryPointer(address);
+}
+void SetSamplerState(const Bypass &bp)
+{
+ FourTexUnits &tex = bpmem.tex[(bp.address & 0xE0) == 0xA0];
+ int stage = (bp.address & 3);//(addr>>4)&2;
+ TexMode0 &tm0 = tex.texMode0[stage];
+
+ D3DTEXTUREFILTERTYPE min, mag, mip;
+ if (g_Config.bForceFiltering)
+ {
+ min = mag = mip = D3DTEXF_LINEAR;
+ }
+ else
+ {
+ min = (tm0.min_filter & 4) ? D3DTEXF_LINEAR : D3DTEXF_POINT;
+ mag = tm0.mag_filter ? D3DTEXF_LINEAR : D3DTEXF_POINT;
+ mip = d3dMipFilters[tm0.min_filter & 3];
+ }
+ if ((bp.address & 0xE0) == 0xA0)
+ stage += 4;
+
+ if (g_Config.bForceMaxAniso)
+ {
+ mag = D3DTEXF_ANISOTROPIC;
+ mip = D3DTEXF_ANISOTROPIC;
+ min = D3DTEXF_ANISOTROPIC;
+ }
+ dev->SetSamplerState(stage, D3DSAMP_MINFILTER, min);
+ dev->SetSamplerState(stage, D3DSAMP_MAGFILTER, mag);
+ dev->SetSamplerState(stage, D3DSAMP_MIPFILTER, mip);
+
+ dev->SetSamplerState(stage, D3DSAMP_MAXANISOTROPY, 16);
+ dev->SetSamplerState(stage, D3DSAMP_ADDRESSU, d3dClamps[tm0.wrap_s]);
+ dev->SetSamplerState(stage, D3DSAMP_ADDRESSV, d3dClamps[tm0.wrap_t]);
+ //wip
+ //dev->SetSamplerState(stage,D3DSAMP_MIPMAPLODBIAS,tm0.lod_bias/4.0f);
+ //char temp[256];
+ //sprintf(temp,"lod %f",tm0.lod_bias/4.0f);
+ //g_VideoInitialize.pLog(temp);
+}
+void SetInterlacingMode(const Bypass &bp)
+{
+ // TODO
+}
}; \ No newline at end of file
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp b/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp
index 1fe8da65ed..97b13beda5 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp
@@ -1,212 +1,212 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "BPFunctions.h"
-#include "Globals.h"
-#include "Profiler.h"
-#include "Config.h"
-#include "VertexManager.h"
-#include "Render.h"
-#include "TextureMngr.h"
-#include "TextureConverter.h"
-#include "VertexShaderManager.h"
-#include "XFB.h"
-#include "main.h"
-
-namespace BPFunctions
-{
-// ----------------------------------------------
-// State translation lookup tables
-// Reference: Yet Another Gamecube Documentation
-// ----------------------------------------------
-
-static const GLenum glCmpFuncs[8] = {
- GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, GL_ALWAYS
-};
-
-static const GLenum glLogicOpCodes[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
-};
-
-void FlushPipeline()
-{
- VertexManager::Flush();
-}
-void SetGenerationMode(const Bypass &bp)
-{
- // none, ccw, cw, ccw
- if (bpmem.genMode.cullmode > 0)
- {
- glEnable(GL_CULL_FACE);
- glFrontFace(bpmem.genMode.cullmode == 2 ? GL_CCW : GL_CW);
- }
- else
- glDisable(GL_CULL_FACE);
-}
-
-
-void SetScissor(const Bypass &bp)
-{
- if (!Renderer::SetScissorRect())
- if (bp.address == BPMEM_SCISSORBR)
- ERROR_LOG(VIDEO, "bad scissor!");
-}
-void SetLineWidth(const Bypass &bp)
-{
- float fratio = xfregs.rawViewport[0] != 0 ? ((float)Renderer::GetTargetWidth() / EFB_WIDTH) : 1.0f;
- if (bpmem.lineptwidth.linesize > 0)
- glLineWidth((float)bpmem.lineptwidth.linesize * fratio / 6.0f); // scale by ratio of widths
- if (bpmem.lineptwidth.pointsize > 0)
- glPointSize((float)bpmem.lineptwidth.pointsize * fratio / 6.0f);
-}
-void SetDepthMode(const Bypass &bp)
-{
- if (bpmem.zmode.testenable)
- {
- glEnable(GL_DEPTH_TEST);
- glDepthMask(bpmem.zmode.updateenable ? GL_TRUE : GL_FALSE);
- glDepthFunc(glCmpFuncs[bpmem.zmode.func]);
- }
- else
- {
- // if the test is disabled write is disabled too
- glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
- }
-}
-void SetBlendMode(const Bypass &bp)
-{
- Renderer::SetBlendMode(false);
-}
-void SetDitherMode(const Bypass &bp)
-{
- if (bpmem.blendmode.dither)
- glEnable(GL_DITHER);
- else
- glDisable(GL_DITHER);
-}
-void SetLogicOpMode(const Bypass &bp)
-{
- if (bpmem.blendmode.logicopenable)
- {
- glEnable(GL_COLOR_LOGIC_OP);
- glLogicOp(glLogicOpCodes[bpmem.blendmode.logicmode]);
- }
- else
- glDisable(GL_COLOR_LOGIC_OP);
-}
-void SetColorMask(const Bypass &bp)
-{
- Renderer::SetColorMask();
-}
-float GetRendererTargetScaleX()
-{
- return Renderer::GetTargetScaleX();
-}
-float GetRendererTargetScaleY()
-{
- return Renderer::GetTargetScaleY();
-}
-void CopyEFB(const Bypass &bp, const TRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const bool &scaleByHalf)
-{
- // bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format)
- if (!g_Config.bEFBCopyDisable)
- if (g_Config.bCopyEFBToRAM) // To RAM
- TextureConverter::EncodeToRam(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
- else // To OGL Texture
- TextureMngr::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
-}
-
-void RenderToXFB(const Bypass &bp, const TRectangle &multirc, const float &yScale, const float &xfbLines, u32 xfbAddr, const u32 &dstWidth, const u32 &dstHeight)
-{
- Renderer::RenderToXFB(xfbAddr, dstWidth, dstHeight, multirc);
-}
-void ClearScreen(const Bypass &bp, const TRectangle &multirc)
-{
- // Update the view port for clearing the picture
- glViewport(0, 0, Renderer::GetTargetWidth(), Renderer::GetTargetHeight());
-
- // Always set the scissor in case it was set by the game and has not been reset
- glScissor(multirc.left, (Renderer::GetTargetHeight() - multirc.bottom),
- (multirc.right - multirc.left), (multirc.bottom - multirc.top));
- // ---------------------------
-
- VertexShaderManager::SetViewportChanged();
-
- // Since clear operations use the source rectangle, we have to do
- // regular renders (glClear clears the entire buffer)
- if (bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate || bpmem.zmode.updateenable)
- {
- GLbitfield bits = 0;
- if (bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate)
- {
- u32 clearColor = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
-
- // Alpha may or may not be present depending on the EFB pixel format.
- GLclampf clearAlpha = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24) ?
- ((clearColor>>24) & 0xff)*(1/255.0f) : 1.0f;
-
- glClearColor(((clearColor>>16) & 0xff)*(1/255.0f),
- ((clearColor>>8 ) & 0xff)*(1/255.0f),
- ((clearColor>>0 ) & 0xff)*(1/255.0f),
- clearAlpha);
- bits |= GL_COLOR_BUFFER_BIT;
- }
- if (bpmem.zmode.updateenable)
- {
- glClearDepth((float)(bpmem.clearZValue & 0xFFFFFF) / float(0xFFFFFF));
- bits |= GL_DEPTH_BUFFER_BIT;
- }
- glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
- glClear(bits);
- }
-}
-
-void RestoreRenderState(const Bypass &bp)
-{
- Renderer::RestoreGLState();
-}
-
-bool GetConfig(const int &type)
-{
- switch (type)
- {
- case CONFIG_ISWII:
- return g_VideoInitialize.bWii;
- case CONFIG_DISABLEFOG:
- return g_Config.bDisableFog;
- case CONFIG_SHOWEFBREGIONS:
- return g_Config.bShowEFBCopyRegions;
- default:
- PanicAlert("GetConfig Error: Unknown Config Type!");
- return false;
- }
-}
-u8 *GetPointer(const u32 &address)
-{
- return g_VideoInitialize.pGetMemoryPointer(address);
-}
-void SetSamplerState(const Bypass &bp)
-{
- // TODO
-}
-void SetInterlacingMode(const Bypass &bp)
-{
- // TODO
-}
-};
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "BPFunctions.h"
+#include "Globals.h"
+#include "Profiler.h"
+#include "Config.h"
+#include "VertexManager.h"
+#include "Render.h"
+#include "TextureMngr.h"
+#include "TextureConverter.h"
+#include "VertexShaderManager.h"
+#include "XFB.h"
+#include "main.h"
+
+namespace BPFunctions
+{
+// ----------------------------------------------
+// State translation lookup tables
+// Reference: Yet Another Gamecube Documentation
+// ----------------------------------------------
+
+static const GLenum glCmpFuncs[8] = {
+ GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, GL_ALWAYS
+};
+
+static const GLenum glLogicOpCodes[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
+};
+
+void FlushPipeline()
+{
+ VertexManager::Flush();
+}
+void SetGenerationMode(const Bypass &bp)
+{
+ // none, ccw, cw, ccw
+ if (bpmem.genMode.cullmode > 0)
+ {
+ glEnable(GL_CULL_FACE);
+ glFrontFace(bpmem.genMode.cullmode == 2 ? GL_CCW : GL_CW);
+ }
+ else
+ glDisable(GL_CULL_FACE);
+}
+
+
+void SetScissor(const Bypass &bp)
+{
+ if (!Renderer::SetScissorRect())
+ if (bp.address == BPMEM_SCISSORBR)
+ ERROR_LOG(VIDEO, "bad scissor!");
+}
+void SetLineWidth(const Bypass &bp)
+{
+ float fratio = xfregs.rawViewport[0] != 0 ? ((float)Renderer::GetTargetWidth() / EFB_WIDTH) : 1.0f;
+ if (bpmem.lineptwidth.linesize > 0)
+ glLineWidth((float)bpmem.lineptwidth.linesize * fratio / 6.0f); // scale by ratio of widths
+ if (bpmem.lineptwidth.pointsize > 0)
+ glPointSize((float)bpmem.lineptwidth.pointsize * fratio / 6.0f);
+}
+void SetDepthMode(const Bypass &bp)
+{
+ if (bpmem.zmode.testenable)
+ {
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(bpmem.zmode.updateenable ? GL_TRUE : GL_FALSE);
+ glDepthFunc(glCmpFuncs[bpmem.zmode.func]);
+ }
+ else
+ {
+ // if the test is disabled write is disabled too
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+ }
+}
+void SetBlendMode(const Bypass &bp)
+{
+ Renderer::SetBlendMode(false);
+}
+void SetDitherMode(const Bypass &bp)
+{
+ if (bpmem.blendmode.dither)
+ glEnable(GL_DITHER);
+ else
+ glDisable(GL_DITHER);
+}
+void SetLogicOpMode(const Bypass &bp)
+{
+ if (bpmem.blendmode.logicopenable)
+ {
+ glEnable(GL_COLOR_LOGIC_OP);
+ glLogicOp(glLogicOpCodes[bpmem.blendmode.logicmode]);
+ }
+ else
+ glDisable(GL_COLOR_LOGIC_OP);
+}
+void SetColorMask(const Bypass &bp)
+{
+ Renderer::SetColorMask();
+}
+float GetRendererTargetScaleX()
+{
+ return Renderer::GetTargetScaleX();
+}
+float GetRendererTargetScaleY()
+{
+ return Renderer::GetTargetScaleY();
+}
+void CopyEFB(const Bypass &bp, const TRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const bool &scaleByHalf)
+{
+ // bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format)
+ if (!g_Config.bEFBCopyDisable)
+ if (g_Config.bCopyEFBToRAM) // To RAM
+ TextureConverter::EncodeToRam(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
+ else // To OGL Texture
+ TextureMngr::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
+}
+
+void RenderToXFB(const Bypass &bp, const TRectangle &multirc, const float &yScale, const float &xfbLines, u32 xfbAddr, const u32 &dstWidth, const u32 &dstHeight)
+{
+ Renderer::RenderToXFB(xfbAddr, dstWidth, dstHeight, multirc);
+}
+void ClearScreen(const Bypass &bp, const TRectangle &multirc)
+{
+ // Update the view port for clearing the picture
+ glViewport(0, 0, Renderer::GetTargetWidth(), Renderer::GetTargetHeight());
+
+ // Always set the scissor in case it was set by the game and has not been reset
+ glScissor(multirc.left, (Renderer::GetTargetHeight() - multirc.bottom),
+ (multirc.right - multirc.left), (multirc.bottom - multirc.top));
+ // ---------------------------
+
+ VertexShaderManager::SetViewportChanged();
+
+ // Since clear operations use the source rectangle, we have to do
+ // regular renders (glClear clears the entire buffer)
+ if (bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate || bpmem.zmode.updateenable)
+ {
+ GLbitfield bits = 0;
+ if (bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate)
+ {
+ u32 clearColor = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
+
+ // Alpha may or may not be present depending on the EFB pixel format.
+ GLclampf clearAlpha = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24) ?
+ ((clearColor>>24) & 0xff)*(1/255.0f) : 1.0f;
+
+ glClearColor(((clearColor>>16) & 0xff)*(1/255.0f),
+ ((clearColor>>8 ) & 0xff)*(1/255.0f),
+ ((clearColor>>0 ) & 0xff)*(1/255.0f),
+ clearAlpha);
+ bits |= GL_COLOR_BUFFER_BIT;
+ }
+ if (bpmem.zmode.updateenable)
+ {
+ glClearDepth((float)(bpmem.clearZValue & 0xFFFFFF) / float(0xFFFFFF));
+ bits |= GL_DEPTH_BUFFER_BIT;
+ }
+ glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+ glClear(bits);
+ }
+}
+
+void RestoreRenderState(const Bypass &bp)
+{
+ Renderer::RestoreGLState();
+}
+
+bool GetConfig(const int &type)
+{
+ switch (type)
+ {
+ case CONFIG_ISWII:
+ return g_VideoInitialize.bWii;
+ case CONFIG_DISABLEFOG:
+ return g_Config.bDisableFog;
+ case CONFIG_SHOWEFBREGIONS:
+ return g_Config.bShowEFBCopyRegions;
+ default:
+ PanicAlert("GetConfig Error: Unknown Config Type!");
+ return false;
+ }
+}
+u8 *GetPointer(const u32 &address)
+{
+ return g_VideoInitialize.pGetMemoryPointer(address);
+}
+void SetSamplerState(const Bypass &bp)
+{
+ // TODO
+}
+void SetInterlacingMode(const Bypass &bp)
+{
+ // TODO
+}
+};
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp
index 76038be2c9..f7670b00cc 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp
@@ -1,451 +1,451 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Globals.h"
-#include "FramebufferManager.h"
-
-#include "TextureConverter.h"
-#include "XFB.h"
-
-extern bool s_bHaveFramebufferBlit; // comes from Render.cpp
-
-void FramebufferManager::Init(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples)
-{
- m_targetWidth = targetWidth;
- m_targetHeight = targetHeight;
- m_msaaSamples = msaaSamples;
- m_msaaCoverageSamples = msaaCoverageSamples;
-
- // The EFB can be set to different pixel formats by the game through the
- // BPMEM_ZCOMPARE register (which should probably have a different name).
- // They are:
- // - 24-bit RGB (8-bit components) with 24-bit Z
- // - 24-bit RGBA (6-bit components) with 24-bit Z
- // - Multisampled 16-bit RGB (5-6-5 format) with 16-bit Z
- // We only use one EFB format here: 32-bit ARGB with 24-bit Z.
- // Multisampling depends on user settings.
- // The distinction becomes important for certain operations, i.e. the
- // alpha channel should be ignored if the EFB does not have one.
-
- // Create EFB target.
-
- glGenFramebuffersEXT(1, &m_efbFramebuffer);
-
- if (m_msaaSamples <= 1)
- {
- // EFB targets will be textures in non-MSAA mode.
-
- GLuint glObj[2];
- glGenTextures(2, glObj);
- m_efbColor = glObj[0];
- m_efbDepth = glObj[1];
-
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_efbColor);
- glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_efbDepth);
- glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
-
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
-
- // Bind target textures to the EFB framebuffer.
-
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
-
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_efbColor, 0);
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, m_efbDepth, 0);
-
- GL_REPORT_FBO_ERROR();
- }
- else
- {
- // EFB targets will be renderbuffers in MSAA mode (required by OpenGL).
- // Resolve targets will be created to transfer EFB to RAM textures.
- // XFB framebuffer will be created to transfer EFB to XFB texture.
-
- // Create EFB target renderbuffers.
-
- GLuint glObj[2];
- glGenRenderbuffersEXT(2, glObj);
- m_efbColor = glObj[0];
- m_efbDepth = glObj[1];
-
- glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_efbColor);
- if (m_msaaCoverageSamples)
- glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, m_msaaCoverageSamples, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight);
- else
- glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight);
-
- glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_efbDepth);
- if (m_msaaCoverageSamples)
- glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, m_msaaCoverageSamples, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight);
- else
- glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight);
-
- glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
-
- // Bind target renderbuffers to EFB framebuffer.
-
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
-
- glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_efbColor);
- glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_efbDepth);
-
- GL_REPORT_FBO_ERROR();
-
- // Create resolved targets for transferring multisampled EFB to texture.
-
- glGenFramebuffersEXT(1, &m_resolvedFramebuffer);
-
- glGenTextures(2, glObj);
- m_resolvedColorTexture = glObj[0];
- m_resolvedDepthTexture = glObj[1];
-
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_resolvedColorTexture);
- glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_resolvedDepthTexture);
- glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
-
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
-
- // Bind resolved textures to resolved framebuffer.
-
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_resolvedFramebuffer);
-
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_resolvedColorTexture, 0);
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, m_resolvedDepthTexture, 0);
-
- GL_REPORT_FBO_ERROR();
-
- // Return to EFB framebuffer.
-
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
- }
-
- // Create XFB framebuffer; targets will be created elsewhere.
-
- glGenFramebuffersEXT(1, &m_xfbFramebuffer);
-
- // EFB framebuffer is currently bound.
-}
-
-void FramebufferManager::Shutdown()
-{
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
-
- GLuint glObj[3];
-
- // Note: OpenGL deletion functions silently ignore parameters of "0".
-
- glObj[0] = m_efbFramebuffer;
- glObj[1] = m_resolvedFramebuffer;
- glObj[2] = m_xfbFramebuffer;
- glDeleteFramebuffersEXT(3, glObj);
- m_efbFramebuffer = 0;
- m_xfbFramebuffer = 0;
-
- glObj[0] = m_resolvedColorTexture;
- glObj[1] = m_resolvedDepthTexture;
- glObj[2] = m_realXFBSource.texture;
- glDeleteTextures(3, glObj);
- m_resolvedColorTexture = 0;
- m_resolvedDepthTexture = 0;
- m_realXFBSource.texture = 0;
-
- glObj[0] = m_efbColor;
- glObj[1] = m_efbDepth;
- if (m_msaaSamples <= 1)
- glDeleteTextures(2, glObj);
- else
- glDeleteRenderbuffersEXT(2, glObj);
- m_efbColor = 0;
- m_efbDepth = 0;
-
- for (VirtualXFBListType::iterator it = m_virtualXFBList.begin(); it != m_virtualXFBList.end(); ++it)
- {
- glDeleteTextures(1, &it->xfbSource.texture);
- }
- m_virtualXFBList.clear();
-}
-
-void FramebufferManager::CopyToXFB(u32 xfbAddr, u32 dstWidth, u32 dstHeight, const TRectangle& sourceRc)
-{
- if (g_Config.bUseXFB)
- copyToRealXFB(xfbAddr, dstWidth, dstHeight, sourceRc);
- else
- copyToVirtualXFB(xfbAddr, dstWidth, dstHeight, sourceRc);
-}
-
-const XFBSource* FramebufferManager::GetXFBSource(u32 xfbAddr, u32 srcWidth, u32 srcHeight)
-{
- if (g_Config.bUseXFB)
- return getRealXFBSource(xfbAddr, srcWidth, srcHeight);
- else
- return getVirtualXFBSource(xfbAddr, srcWidth, srcHeight);
-}
-
-GLuint FramebufferManager::GetEFBColorTexture(const TRectangle& sourceRc) const
-{
- if (m_msaaSamples <= 1)
- {
- return m_efbColor;
- }
- else
- {
- // Transfer the EFB to a resolved texture. EXT_framebuffer_blit is
- // required.
-
- // Flip source rectangle upside-down for OpenGL.
- TRectangle glRect;
- sourceRc.FlipYPosition(m_targetHeight, &glRect);
- glRect.Clamp(0, 0, m_targetWidth, m_targetHeight);
-
- // Resolve.
- glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_efbFramebuffer);
- glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_resolvedFramebuffer);
- glBlitFramebufferEXT(
- glRect.left, glRect.top, glRect.right, glRect.bottom,
- glRect.left, glRect.top, glRect.right, glRect.bottom,
- GL_COLOR_BUFFER_BIT, GL_NEAREST
- );
-
- // Return to EFB.
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
-
- return m_resolvedColorTexture;
- }
-}
-
-GLuint FramebufferManager::GetEFBDepthTexture(const TRectangle& sourceRc) const
-{
- if (m_msaaSamples <= 1)
- {
- return m_efbDepth;
- }
- else
- {
- // Transfer the EFB to a resolved texture. EXT_framebuffer_blit is
- // required.
-
- // Flip source rectangle upside-down for OpenGL.
- TRectangle glRect;
- sourceRc.FlipYPosition(m_targetHeight, &glRect);
- glRect.Clamp(0, 0, m_targetWidth, m_targetHeight);
-
- // Resolve.
- glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_efbFramebuffer);
- glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_resolvedFramebuffer);
- glBlitFramebufferEXT(
- glRect.left, glRect.top, glRect.right, glRect.bottom,
- glRect.left, glRect.top, glRect.right, glRect.bottom,
- GL_DEPTH_BUFFER_BIT, GL_NEAREST
- );
-
- // Return to EFB.
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
-
- return m_resolvedDepthTexture;
- }
-}
-
-FramebufferManager::VirtualXFBListType::iterator
-FramebufferManager::findVirtualXFB(u32 xfbAddr, u32 width, u32 height)
-{
- u32 srcLower = xfbAddr;
- u32 srcUpper = xfbAddr + 2 * width * height;
-
- VirtualXFBListType::iterator it;
- for (it = m_virtualXFBList.begin(); it != m_virtualXFBList.end(); ++it)
- {
- u32 dstLower = it->xfbAddr;
- u32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight;
-
- if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper))
- return it;
- }
-
- // That address is not in the Virtual XFB list.
- return m_virtualXFBList.end();
-}
-
-void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 dstWidth, u32 dstHeight, const TRectangle& sourceRc)
-{
- u8* pXFB = Memory_GetPtr(xfbAddr);
- if (!pXFB)
- {
- WARN_LOG(VIDEO, "Tried to copy to invalid XFB address");
- return;
- }
-
- XFB_Write(pXFB, sourceRc, dstWidth, dstHeight);
-}
-
-void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 dstWidth, u32 dstHeight, const TRectangle& sourceRc)
-{
- GLuint xfbTexture;
-
- VirtualXFBListType::iterator it = findVirtualXFB(xfbAddr, dstWidth, dstHeight);
-
- if (it != m_virtualXFBList.end())
- {
- // Overwrite an existing Virtual XFB.
-
- it->xfbAddr = xfbAddr;
- it->xfbWidth = dstWidth;
- it->xfbHeight = dstHeight;
-
- it->xfbSource.texWidth = m_targetWidth;
- it->xfbSource.texHeight = m_targetHeight;
- it->xfbSource.sourceRc = sourceRc;
-
- xfbTexture = it->xfbSource.texture;
-
- // Move this Virtual XFB to the front of the list.
- m_virtualXFBList.splice(m_virtualXFBList.begin(), m_virtualXFBList, it);
- }
- else
- {
- // Create a new Virtual XFB and place it at the front of the list.
-
- glGenTextures(1, &xfbTexture);
-
-#if 0 // XXX: Some video drivers don't handle glCopyTexImage2D correctly, so use EXT_framebuffer_blit whenever possible.
- if (m_msaaSamples > 1)
-#else
- if (s_bHaveFramebufferBlit)
-#endif
- {
- // In MSAA mode, allocate the texture image here. In non-MSAA mode,
- // the image will be allocated by glCopyTexImage2D (later).
-
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, xfbTexture);
- glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, m_targetWidth, m_targetHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
-
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
- }
-
- VirtualXFB newVirt;
-
- newVirt.xfbAddr = xfbAddr;
- newVirt.xfbWidth = dstWidth;
- newVirt.xfbHeight = dstHeight;
-
- newVirt.xfbSource.texture = xfbTexture;
- newVirt.xfbSource.texWidth = m_targetWidth;
- newVirt.xfbSource.texHeight = m_targetHeight;
- newVirt.xfbSource.sourceRc = sourceRc;
-
- // Add the new Virtual XFB to the list
-
- if (m_virtualXFBList.size() >= MAX_VIRTUAL_XFB)
- {
- // List overflowed; delete the oldest.
- glDeleteTextures(1, &m_virtualXFBList.back().xfbSource.texture);
- m_virtualXFBList.pop_back();
- }
-
- m_virtualXFBList.push_front(newVirt);
- }
-
- // Copy EFB to XFB texture
-
-#if 0
- if (m_msaaSamples <= 1)
-#else
- if (!s_bHaveFramebufferBlit)
-#endif
- {
- // Just copy the EFB directly.
-
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
-
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, xfbTexture);
- glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, 0, 0, m_targetWidth, m_targetHeight, 0);
-
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
- }
- else
- {
- // OpenGL cannot copy directly from a multisampled framebuffer, so use
- // EXT_framebuffer_blit.
-
- glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_efbFramebuffer);
- glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_xfbFramebuffer);
-
- // Bind texture.
- glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, xfbTexture, 0);
- GL_REPORT_FBO_ERROR();
-
- glBlitFramebufferEXT(
- 0, 0, m_targetWidth, m_targetHeight,
- 0, 0, m_targetWidth, m_targetHeight,
- GL_COLOR_BUFFER_BIT, GL_NEAREST
- );
-
- // Unbind texture.
- glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
-
- // Return to EFB.
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
- }
-}
-
-const XFBSource* FramebufferManager::getRealXFBSource(u32 xfbAddr, u32 srcWidth, u32 srcHeight)
-{
- m_realXFBSource.texWidth = XFB_WIDTH;
- m_realXFBSource.texHeight = XFB_HEIGHT;
-
- m_realXFBSource.sourceRc.left = 0;
- m_realXFBSource.sourceRc.top = 0;
- m_realXFBSource.sourceRc.right = srcWidth;
- m_realXFBSource.sourceRc.bottom = srcHeight;
-
- if (!m_realXFBSource.texture)
- {
- glGenTextures(1, &m_realXFBSource.texture);
-
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_realXFBSource.texture);
- glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, XFB_WIDTH, XFB_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
-
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
- }
-
- // Decode YUYV data from GameCube RAM
- TextureConverter::DecodeToTexture(xfbAddr, srcWidth, srcHeight, m_realXFBSource.texture);
-
- return &m_realXFBSource;
-}
-
-const XFBSource* FramebufferManager::getVirtualXFBSource(u32 xfbAddr, u32 srcWidth, u32 srcHeight)
-{
- if (m_virtualXFBList.size() == 0)
- {
- // No Virtual XFBs available.
- return NULL;
- }
-
- VirtualXFBListType::iterator it = findVirtualXFB(xfbAddr, srcWidth, srcHeight);
- if (it == m_virtualXFBList.end())
- {
- // Virtual XFB is not in the list, so return the most recently rendered
- // one.
- it = m_virtualXFBList.begin();
- }
-
- return &it->xfbSource;
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "Globals.h"
+#include "FramebufferManager.h"
+
+#include "TextureConverter.h"
+#include "XFB.h"
+
+extern bool s_bHaveFramebufferBlit; // comes from Render.cpp
+
+void FramebufferManager::Init(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples)
+{
+ m_targetWidth = targetWidth;
+ m_targetHeight = targetHeight;
+ m_msaaSamples = msaaSamples;
+ m_msaaCoverageSamples = msaaCoverageSamples;
+
+ // The EFB can be set to different pixel formats by the game through the
+ // BPMEM_ZCOMPARE register (which should probably have a different name).
+ // They are:
+ // - 24-bit RGB (8-bit components) with 24-bit Z
+ // - 24-bit RGBA (6-bit components) with 24-bit Z
+ // - Multisampled 16-bit RGB (5-6-5 format) with 16-bit Z
+ // We only use one EFB format here: 32-bit ARGB with 24-bit Z.
+ // Multisampling depends on user settings.
+ // The distinction becomes important for certain operations, i.e. the
+ // alpha channel should be ignored if the EFB does not have one.
+
+ // Create EFB target.
+
+ glGenFramebuffersEXT(1, &m_efbFramebuffer);
+
+ if (m_msaaSamples <= 1)
+ {
+ // EFB targets will be textures in non-MSAA mode.
+
+ GLuint glObj[2];
+ glGenTextures(2, glObj);
+ m_efbColor = glObj[0];
+ m_efbDepth = glObj[1];
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_efbColor);
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_efbDepth);
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
+
+ // Bind target textures to the EFB framebuffer.
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
+
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_efbColor, 0);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, m_efbDepth, 0);
+
+ GL_REPORT_FBO_ERROR();
+ }
+ else
+ {
+ // EFB targets will be renderbuffers in MSAA mode (required by OpenGL).
+ // Resolve targets will be created to transfer EFB to RAM textures.
+ // XFB framebuffer will be created to transfer EFB to XFB texture.
+
+ // Create EFB target renderbuffers.
+
+ GLuint glObj[2];
+ glGenRenderbuffersEXT(2, glObj);
+ m_efbColor = glObj[0];
+ m_efbDepth = glObj[1];
+
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_efbColor);
+ if (m_msaaCoverageSamples)
+ glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, m_msaaCoverageSamples, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight);
+ else
+ glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight);
+
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_efbDepth);
+ if (m_msaaCoverageSamples)
+ glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, m_msaaCoverageSamples, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight);
+ else
+ glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight);
+
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+
+ // Bind target renderbuffers to EFB framebuffer.
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
+
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_efbColor);
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_efbDepth);
+
+ GL_REPORT_FBO_ERROR();
+
+ // Create resolved targets for transferring multisampled EFB to texture.
+
+ glGenFramebuffersEXT(1, &m_resolvedFramebuffer);
+
+ glGenTextures(2, glObj);
+ m_resolvedColorTexture = glObj[0];
+ m_resolvedDepthTexture = glObj[1];
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_resolvedColorTexture);
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_resolvedDepthTexture);
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
+
+ // Bind resolved textures to resolved framebuffer.
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_resolvedFramebuffer);
+
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_resolvedColorTexture, 0);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, m_resolvedDepthTexture, 0);
+
+ GL_REPORT_FBO_ERROR();
+
+ // Return to EFB framebuffer.
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
+ }
+
+ // Create XFB framebuffer; targets will be created elsewhere.
+
+ glGenFramebuffersEXT(1, &m_xfbFramebuffer);
+
+ // EFB framebuffer is currently bound.
+}
+
+void FramebufferManager::Shutdown()
+{
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+ GLuint glObj[3];
+
+ // Note: OpenGL deletion functions silently ignore parameters of "0".
+
+ glObj[0] = m_efbFramebuffer;
+ glObj[1] = m_resolvedFramebuffer;
+ glObj[2] = m_xfbFramebuffer;
+ glDeleteFramebuffersEXT(3, glObj);
+ m_efbFramebuffer = 0;
+ m_xfbFramebuffer = 0;
+
+ glObj[0] = m_resolvedColorTexture;
+ glObj[1] = m_resolvedDepthTexture;
+ glObj[2] = m_realXFBSource.texture;
+ glDeleteTextures(3, glObj);
+ m_resolvedColorTexture = 0;
+ m_resolvedDepthTexture = 0;
+ m_realXFBSource.texture = 0;
+
+ glObj[0] = m_efbColor;
+ glObj[1] = m_efbDepth;
+ if (m_msaaSamples <= 1)
+ glDeleteTextures(2, glObj);
+ else
+ glDeleteRenderbuffersEXT(2, glObj);
+ m_efbColor = 0;
+ m_efbDepth = 0;
+
+ for (VirtualXFBListType::iterator it = m_virtualXFBList.begin(); it != m_virtualXFBList.end(); ++it)
+ {
+ glDeleteTextures(1, &it->xfbSource.texture);
+ }
+ m_virtualXFBList.clear();
+}
+
+void FramebufferManager::CopyToXFB(u32 xfbAddr, u32 dstWidth, u32 dstHeight, const TRectangle& sourceRc)
+{
+ if (g_Config.bUseXFB)
+ copyToRealXFB(xfbAddr, dstWidth, dstHeight, sourceRc);
+ else
+ copyToVirtualXFB(xfbAddr, dstWidth, dstHeight, sourceRc);
+}
+
+const XFBSource* FramebufferManager::GetXFBSource(u32 xfbAddr, u32 srcWidth, u32 srcHeight)
+{
+ if (g_Config.bUseXFB)
+ return getRealXFBSource(xfbAddr, srcWidth, srcHeight);
+ else
+ return getVirtualXFBSource(xfbAddr, srcWidth, srcHeight);
+}
+
+GLuint FramebufferManager::GetEFBColorTexture(const TRectangle& sourceRc) const
+{
+ if (m_msaaSamples <= 1)
+ {
+ return m_efbColor;
+ }
+ else
+ {
+ // Transfer the EFB to a resolved texture. EXT_framebuffer_blit is
+ // required.
+
+ // Flip source rectangle upside-down for OpenGL.
+ TRectangle glRect;
+ sourceRc.FlipYPosition(m_targetHeight, &glRect);
+ glRect.Clamp(0, 0, m_targetWidth, m_targetHeight);
+
+ // Resolve.
+ glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_efbFramebuffer);
+ glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_resolvedFramebuffer);
+ glBlitFramebufferEXT(
+ glRect.left, glRect.top, glRect.right, glRect.bottom,
+ glRect.left, glRect.top, glRect.right, glRect.bottom,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST
+ );
+
+ // Return to EFB.
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
+
+ return m_resolvedColorTexture;
+ }
+}
+
+GLuint FramebufferManager::GetEFBDepthTexture(const TRectangle& sourceRc) const
+{
+ if (m_msaaSamples <= 1)
+ {
+ return m_efbDepth;
+ }
+ else
+ {
+ // Transfer the EFB to a resolved texture. EXT_framebuffer_blit is
+ // required.
+
+ // Flip source rectangle upside-down for OpenGL.
+ TRectangle glRect;
+ sourceRc.FlipYPosition(m_targetHeight, &glRect);
+ glRect.Clamp(0, 0, m_targetWidth, m_targetHeight);
+
+ // Resolve.
+ glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_efbFramebuffer);
+ glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_resolvedFramebuffer);
+ glBlitFramebufferEXT(
+ glRect.left, glRect.top, glRect.right, glRect.bottom,
+ glRect.left, glRect.top, glRect.right, glRect.bottom,
+ GL_DEPTH_BUFFER_BIT, GL_NEAREST
+ );
+
+ // Return to EFB.
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
+
+ return m_resolvedDepthTexture;
+ }
+}
+
+FramebufferManager::VirtualXFBListType::iterator
+FramebufferManager::findVirtualXFB(u32 xfbAddr, u32 width, u32 height)
+{
+ u32 srcLower = xfbAddr;
+ u32 srcUpper = xfbAddr + 2 * width * height;
+
+ VirtualXFBListType::iterator it;
+ for (it = m_virtualXFBList.begin(); it != m_virtualXFBList.end(); ++it)
+ {
+ u32 dstLower = it->xfbAddr;
+ u32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight;
+
+ if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper))
+ return it;
+ }
+
+ // That address is not in the Virtual XFB list.
+ return m_virtualXFBList.end();
+}
+
+void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 dstWidth, u32 dstHeight, const TRectangle& sourceRc)
+{
+ u8* pXFB = Memory_GetPtr(xfbAddr);
+ if (!pXFB)
+ {
+ WARN_LOG(VIDEO, "Tried to copy to invalid XFB address");
+ return;
+ }
+
+ XFB_Write(pXFB, sourceRc, dstWidth, dstHeight);
+}
+
+void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 dstWidth, u32 dstHeight, const TRectangle& sourceRc)
+{
+ GLuint xfbTexture;
+
+ VirtualXFBListType::iterator it = findVirtualXFB(xfbAddr, dstWidth, dstHeight);
+
+ if (it != m_virtualXFBList.end())
+ {
+ // Overwrite an existing Virtual XFB.
+
+ it->xfbAddr = xfbAddr;
+ it->xfbWidth = dstWidth;
+ it->xfbHeight = dstHeight;
+
+ it->xfbSource.texWidth = m_targetWidth;
+ it->xfbSource.texHeight = m_targetHeight;
+ it->xfbSource.sourceRc = sourceRc;
+
+ xfbTexture = it->xfbSource.texture;
+
+ // Move this Virtual XFB to the front of the list.
+ m_virtualXFBList.splice(m_virtualXFBList.begin(), m_virtualXFBList, it);
+ }
+ else
+ {
+ // Create a new Virtual XFB and place it at the front of the list.
+
+ glGenTextures(1, &xfbTexture);
+
+#if 0 // XXX: Some video drivers don't handle glCopyTexImage2D correctly, so use EXT_framebuffer_blit whenever possible.
+ if (m_msaaSamples > 1)
+#else
+ if (s_bHaveFramebufferBlit)
+#endif
+ {
+ // In MSAA mode, allocate the texture image here. In non-MSAA mode,
+ // the image will be allocated by glCopyTexImage2D (later).
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, xfbTexture);
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, m_targetWidth, m_targetHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
+ }
+
+ VirtualXFB newVirt;
+
+ newVirt.xfbAddr = xfbAddr;
+ newVirt.xfbWidth = dstWidth;
+ newVirt.xfbHeight = dstHeight;
+
+ newVirt.xfbSource.texture = xfbTexture;
+ newVirt.xfbSource.texWidth = m_targetWidth;
+ newVirt.xfbSource.texHeight = m_targetHeight;
+ newVirt.xfbSource.sourceRc = sourceRc;
+
+ // Add the new Virtual XFB to the list
+
+ if (m_virtualXFBList.size() >= MAX_VIRTUAL_XFB)
+ {
+ // List overflowed; delete the oldest.
+ glDeleteTextures(1, &m_virtualXFBList.back().xfbSource.texture);
+ m_virtualXFBList.pop_back();
+ }
+
+ m_virtualXFBList.push_front(newVirt);
+ }
+
+ // Copy EFB to XFB texture
+
+#if 0
+ if (m_msaaSamples <= 1)
+#else
+ if (!s_bHaveFramebufferBlit)
+#endif
+ {
+ // Just copy the EFB directly.
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, xfbTexture);
+ glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, 0, 0, m_targetWidth, m_targetHeight, 0);
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
+ }
+ else
+ {
+ // OpenGL cannot copy directly from a multisampled framebuffer, so use
+ // EXT_framebuffer_blit.
+
+ glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_efbFramebuffer);
+ glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_xfbFramebuffer);
+
+ // Bind texture.
+ glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, xfbTexture, 0);
+ GL_REPORT_FBO_ERROR();
+
+ glBlitFramebufferEXT(
+ 0, 0, m_targetWidth, m_targetHeight,
+ 0, 0, m_targetWidth, m_targetHeight,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST
+ );
+
+ // Unbind texture.
+ glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
+
+ // Return to EFB.
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
+ }
+}
+
+const XFBSource* FramebufferManager::getRealXFBSource(u32 xfbAddr, u32 srcWidth, u32 srcHeight)
+{
+ m_realXFBSource.texWidth = XFB_WIDTH;
+ m_realXFBSource.texHeight = XFB_HEIGHT;
+
+ m_realXFBSource.sourceRc.left = 0;
+ m_realXFBSource.sourceRc.top = 0;
+ m_realXFBSource.sourceRc.right = srcWidth;
+ m_realXFBSource.sourceRc.bottom = srcHeight;
+
+ if (!m_realXFBSource.texture)
+ {
+ glGenTextures(1, &m_realXFBSource.texture);
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_realXFBSource.texture);
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, XFB_WIDTH, XFB_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
+ }
+
+ // Decode YUYV data from GameCube RAM
+ TextureConverter::DecodeToTexture(xfbAddr, srcWidth, srcHeight, m_realXFBSource.texture);
+
+ return &m_realXFBSource;
+}
+
+const XFBSource* FramebufferManager::getVirtualXFBSource(u32 xfbAddr, u32 srcWidth, u32 srcHeight)
+{
+ if (m_virtualXFBList.size() == 0)
+ {
+ // No Virtual XFBs available.
+ return NULL;
+ }
+
+ VirtualXFBListType::iterator it = findVirtualXFB(xfbAddr, srcWidth, srcHeight);
+ if (it == m_virtualXFBList.end())
+ {
+ // Virtual XFB is not in the list, so return the most recently rendered
+ // one.
+ it = m_virtualXFBList.begin();
+ }
+
+ return &it->xfbSource;
+}
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.h b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.h
index 1ec6314a6e..02f38d63f0 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.h
+++ b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.h
@@ -1,152 +1,152 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _FRAMEBUFFERMANAGER_H_
-#define _FRAMEBUFFERMANAGER_H_
-
-#include <list>
-#include "GLUtil.h"
-
-// On the GameCube, the game sends a request for the graphics processor to
-// transfer its internal EFB (Embedded Framebuffer) to an area in GameCube RAM
-// called the XFB (External Framebuffer). The size and location of the XFB is
-// decided at the time of the copy, and the format is always YUYV. The video
-// interface is given a pointer to the XFB, which will be decoded and
-// displayed on the TV.
-//
-// There are two ways for Dolphin to emulate this:
-//
-// Real XFB mode:
-//
-// Dolphin will behave like the GameCube and encode the EFB to
-// a portion of GameCube RAM. The emulated video interface will decode the data
-// for output to the screen.
-//
-// Advantages: Behaves exactly like the GameCube.
-// Disadvantages: Resolution will be limited.
-//
-// Virtual XFB mode:
-//
-// When a request is made to copy the EFB to an XFB, Dolphin
-// will remember the RAM location and size of the XFB in a Virtual XFB list.
-// The video interface will look up the XFB in the list and use the enhanced
-// data stored there, if available.
-//
-// Advantages: Enables high resolution graphics, better than real hardware.
-// Disadvantages: If the GameCube CPU writes directly to the XFB (which is
-// possible but uncommon), the Virtual XFB will not capture this information.
-
-// There may be multiple XFBs in GameCube RAM. This is the maximum number to
-// virtualize.
-const int MAX_VIRTUAL_XFB = 4;
-
-inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
-{
- return (
- (aLower >= bLower && aLower < bUpper) ||
- (aUpper >= bLower && aUpper < bUpper) ||
- (bLower >= aLower && bLower < aUpper) ||
- (bUpper >= aLower && bUpper < aUpper)
- );
-}
-
-struct XFBSource
-{
- XFBSource() :
- texture(0)
- {}
-
- GLuint texture;
- int texWidth;
- int texHeight;
-
- TRectangle sourceRc;
-};
-
-class FramebufferManager
-{
-
-public:
-
- FramebufferManager() :
- m_efbFramebuffer(0),
- m_efbColor(0),
- m_efbDepth(0),
- m_resolvedFramebuffer(0),
- m_resolvedColorTexture(0),
- m_resolvedDepthTexture(0),
- m_xfbFramebuffer(0)
- {}
-
- void Init(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples);
- void Shutdown();
-
- // sourceRc is in GL target coordinates, not GameCube EFB coordinates!
- // TODO: Clean that up.
- void CopyToXFB(u32 xfbAddr, u32 dstWidth, u32 dstHeight, const TRectangle& sourceRc);
-
- const XFBSource* GetXFBSource(u32 xfbAddr, u32 srcWidth, u32 srcHeight);
-
- // To get the EFB in texture form, these functions may have to transfer
- // the EFB to a resolved texture first.
- GLuint GetEFBColorTexture(const TRectangle& sourceRc) const;
- GLuint GetEFBDepthTexture(const TRectangle& sourceRc) const;
-
- GLuint GetEFBFramebuffer() const { return m_efbFramebuffer; }
-
-private:
-
- struct VirtualXFB
- {
- // Address and size in GameCube RAM
- u32 xfbAddr;
- u32 xfbWidth;
- u32 xfbHeight;
-
- XFBSource xfbSource;
- };
-
- typedef std::list<VirtualXFB> VirtualXFBListType;
-
- VirtualXFBListType::iterator findVirtualXFB(u32 xfbAddr, u32 width, u32 height);
-
- void copyToRealXFB(u32 xfbAddr, u32 dstWidth, u32 dstHeight, const TRectangle& sourceRc);
- void copyToVirtualXFB(u32 xfbAddr, u32 dstWidth, u32 dstHeight, const TRectangle& sourceRc);
- const XFBSource* getRealXFBSource(u32 xfbAddr, u32 srcWidth, u32 srcHeight);
- const XFBSource* getVirtualXFBSource(u32 xfbAddr, u32 srcWidth, u32 srcHeight);
-
- int m_targetWidth;
- int m_targetHeight;
- int m_msaaSamples;
- int m_msaaCoverageSamples;
-
- GLuint m_efbFramebuffer;
- GLuint m_efbColor; // Renderbuffer in MSAA mode; Texture otherwise
- GLuint m_efbDepth; // Renderbuffer in MSAA mode; Texture otherwise
-
- // Only used in MSAA mode.
- GLuint m_resolvedFramebuffer;
- GLuint m_resolvedColorTexture;
- GLuint m_resolvedDepthTexture;
-
- GLuint m_xfbFramebuffer; // Only used in MSAA mode
- XFBSource m_realXFBSource; // Only used in Real XFB mode
- VirtualXFBListType m_virtualXFBList; // Only used in Virtual XFB mode
-
-};
-
-#endif
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _FRAMEBUFFERMANAGER_H_
+#define _FRAMEBUFFERMANAGER_H_
+
+#include <list>
+#include "GLUtil.h"
+
+// On the GameCube, the game sends a request for the graphics processor to
+// transfer its internal EFB (Embedded Framebuffer) to an area in GameCube RAM
+// called the XFB (External Framebuffer). The size and location of the XFB is
+// decided at the time of the copy, and the format is always YUYV. The video
+// interface is given a pointer to the XFB, which will be decoded and
+// displayed on the TV.
+//
+// There are two ways for Dolphin to emulate this:
+//
+// Real XFB mode:
+//
+// Dolphin will behave like the GameCube and encode the EFB to
+// a portion of GameCube RAM. The emulated video interface will decode the data
+// for output to the screen.
+//
+// Advantages: Behaves exactly like the GameCube.
+// Disadvantages: Resolution will be limited.
+//
+// Virtual XFB mode:
+//
+// When a request is made to copy the EFB to an XFB, Dolphin
+// will remember the RAM location and size of the XFB in a Virtual XFB list.
+// The video interface will look up the XFB in the list and use the enhanced
+// data stored there, if available.
+//
+// Advantages: Enables high resolution graphics, better than real hardware.
+// Disadvantages: If the GameCube CPU writes directly to the XFB (which is
+// possible but uncommon), the Virtual XFB will not capture this information.
+
+// There may be multiple XFBs in GameCube RAM. This is the maximum number to
+// virtualize.
+const int MAX_VIRTUAL_XFB = 4;
+
+inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
+{
+ return (
+ (aLower >= bLower && aLower < bUpper) ||
+ (aUpper >= bLower && aUpper < bUpper) ||
+ (bLower >= aLower && bLower < aUpper) ||
+ (bUpper >= aLower && bUpper < aUpper)
+ );
+}
+
+struct XFBSource
+{
+ XFBSource() :
+ texture(0)
+ {}
+
+ GLuint texture;
+ int texWidth;
+ int texHeight;
+
+ TRectangle sourceRc;
+};
+
+class FramebufferManager
+{
+
+public:
+
+ FramebufferManager() :
+ m_efbFramebuffer(0),
+ m_efbColor(0),
+ m_efbDepth(0),
+ m_resolvedFramebuffer(0),
+ m_resolvedColorTexture(0),
+ m_resolvedDepthTexture(0),
+ m_xfbFramebuffer(0)
+ {}
+
+ void Init(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples);
+ void Shutdown();
+
+ // sourceRc is in GL target coordinates, not GameCube EFB coordinates!
+ // TODO: Clean that up.
+ void CopyToXFB(u32 xfbAddr, u32 dstWidth, u32 dstHeight, const TRectangle& sourceRc);
+
+ const XFBSource* GetXFBSource(u32 xfbAddr, u32 srcWidth, u32 srcHeight);
+
+ // To get the EFB in texture form, these functions may have to transfer
+ // the EFB to a resolved texture first.
+ GLuint GetEFBColorTexture(const TRectangle& sourceRc) const;
+ GLuint GetEFBDepthTexture(const TRectangle& sourceRc) const;
+
+ GLuint GetEFBFramebuffer() const { return m_efbFramebuffer; }
+
+private:
+
+ struct VirtualXFB
+ {
+ // Address and size in GameCube RAM
+ u32 xfbAddr;
+ u32 xfbWidth;
+ u32 xfbHeight;
+
+ XFBSource xfbSource;
+ };
+
+ typedef std::list<VirtualXFB> VirtualXFBListType;
+
+ VirtualXFBListType::iterator findVirtualXFB(u32 xfbAddr, u32 width, u32 height);
+
+ void copyToRealXFB(u32 xfbAddr, u32 dstWidth, u32 dstHeight, const TRectangle& sourceRc);
+ void copyToVirtualXFB(u32 xfbAddr, u32 dstWidth, u32 dstHeight, const TRectangle& sourceRc);
+ const XFBSource* getRealXFBSource(u32 xfbAddr, u32 srcWidth, u32 srcHeight);
+ const XFBSource* getVirtualXFBSource(u32 xfbAddr, u32 srcWidth, u32 srcHeight);
+
+ int m_targetWidth;
+ int m_targetHeight;
+ int m_msaaSamples;
+ int m_msaaCoverageSamples;
+
+ GLuint m_efbFramebuffer;
+ GLuint m_efbColor; // Renderbuffer in MSAA mode; Texture otherwise
+ GLuint m_efbDepth; // Renderbuffer in MSAA mode; Texture otherwise
+
+ // Only used in MSAA mode.
+ GLuint m_resolvedFramebuffer;
+ GLuint m_resolvedColorTexture;
+ GLuint m_resolvedDepthTexture;
+
+ GLuint m_xfbFramebuffer; // Only used in MSAA mode
+ XFBSource m_realXFBSource; // Only used in Real XFB mode
+ VirtualXFBListType m_virtualXFBList; // Only used in Virtual XFB mode
+
+};
+
+#endif
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PostProcessing.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PostProcessing.cpp
index ccd6d80ba0..a97ea95130 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/PostProcessing.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/PostProcessing.cpp
@@ -1,89 +1,89 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "VideoCommon.h"
-#include "FileUtil.h"
-#include "Config.h"
-#include "GLUtil.h"
-#include "PostProcessing.h"
-#include "PixelShaderCache.h"
-
-namespace PostProcessing
-{
-
-static std::string s_currentShader;
-static FRAGMENTSHADER s_shader;
-
-void Init()
-{
- s_currentShader = "";
-}
-
-void Shutdown()
-{
- s_shader.Destroy();
-}
-
-void ReloadShader()
-{
- s_currentShader = "";
-}
-
-bool ApplyShader()
-{
- if (s_currentShader != "User/Shaders/" + g_Config.sPostProcessingShader + ".txt")
- {
- // Set immediately to prevent endless recompiles on failure.
- if (!g_Config.sPostProcessingShader.empty())
- s_currentShader = "User/Shaders/" + g_Config.sPostProcessingShader + ".txt";
- else
- s_currentShader.clear();
-
- s_shader.Destroy();
-
- if (!s_currentShader.empty())
- {
- std::string code;
- if (File::ReadFileToString(true, s_currentShader.c_str(), code))
- {
- if (!PixelShaderCache::CompilePixelShader(s_shader, code.c_str()))
- {
- ERROR_LOG(VIDEO, "Failed to compile post-processing shader %s", s_currentShader.c_str());
- }
- }
- else
- {
- ERROR_LOG(VIDEO, "Failed to load post-processing shader %s - does not exist?", s_currentShader.c_str());
- }
- }
- }
-
- if (s_shader.glprogid != 0)
- {
- glEnable(GL_FRAGMENT_PROGRAM_ARB);
- glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, s_shader.glprogid);
- return true;
- }
- else
- {
- glDisable(GL_FRAGMENT_PROGRAM_ARB);
- glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0);
- return false;
- }
-}
-
-} // namespace
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "VideoCommon.h"
+#include "FileUtil.h"
+#include "Config.h"
+#include "GLUtil.h"
+#include "PostProcessing.h"
+#include "PixelShaderCache.h"
+
+namespace PostProcessing
+{
+
+static std::string s_currentShader;
+static FRAGMENTSHADER s_shader;
+
+void Init()
+{
+ s_currentShader = "";
+}
+
+void Shutdown()
+{
+ s_shader.Destroy();
+}
+
+void ReloadShader()
+{
+ s_currentShader = "";
+}
+
+bool ApplyShader()
+{
+ if (s_currentShader != "User/Shaders/" + g_Config.sPostProcessingShader + ".txt")
+ {
+ // Set immediately to prevent endless recompiles on failure.
+ if (!g_Config.sPostProcessingShader.empty())
+ s_currentShader = "User/Shaders/" + g_Config.sPostProcessingShader + ".txt";
+ else
+ s_currentShader.clear();
+
+ s_shader.Destroy();
+
+ if (!s_currentShader.empty())
+ {
+ std::string code;
+ if (File::ReadFileToString(true, s_currentShader.c_str(), code))
+ {
+ if (!PixelShaderCache::CompilePixelShader(s_shader, code.c_str()))
+ {
+ ERROR_LOG(VIDEO, "Failed to compile post-processing shader %s", s_currentShader.c_str());
+ }
+ }
+ else
+ {
+ ERROR_LOG(VIDEO, "Failed to load post-processing shader %s - does not exist?", s_currentShader.c_str());
+ }
+ }
+ }
+
+ if (s_shader.glprogid != 0)
+ {
+ glEnable(GL_FRAGMENT_PROGRAM_ARB);
+ glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, s_shader.glprogid);
+ return true;
+ }
+ else
+ {
+ glDisable(GL_FRAGMENT_PROGRAM_ARB);
+ glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0);
+ return false;
+ }
+}
+
+} // namespace
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PostProcessing.h b/Source/Plugins/Plugin_VideoOGL/Src/PostProcessing.h
index 3666750f02..5b168cfd8b 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/PostProcessing.h
+++ b/Source/Plugins/Plugin_VideoOGL/Src/PostProcessing.h
@@ -1,36 +1,36 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _POSTPROCESSING_H_
-#define _POSTPROCESSING_H_
-
-#include "VideoCommon.h"
-#include "GLUtil.h"
-
-namespace PostProcessing
-{
-
-void Init();
-void Shutdown();
-
-void ReloadShader();
-// Returns false if no shader was applied.
-bool ApplyShader();
-
-} // namespace
-
-#endif // _POSTPROCESSING_H_
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _POSTPROCESSING_H_
+#define _POSTPROCESSING_H_
+
+#include "VideoCommon.h"
+#include "GLUtil.h"
+
+namespace PostProcessing
+{
+
+void Init();
+void Shutdown();
+
+void ReloadShader();
+// Returns false if no shader was applied.
+bool ApplyShader();
+
+} // namespace
+
+#endif // _POSTPROCESSING_H_
diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/Images/njoy.xpm b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/Images/njoy.xpm
index 2214139485..746e6569c7 100644
--- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/Images/njoy.xpm
+++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/Images/njoy.xpm
@@ -1,4028 +1,4028 @@
-/* XPM */
-static const char *AboutBox_WxStaticBitmap1_XPM[]={
-/* AboutBox_WxStaticBitmap1 */
-"200 60 3963 2",
-" c None",
-" 0 c #98CAFD",
-" 1 c #99CBFC",
-" 2 c #97C9FC",
-" 3 c #96C8F9",
-" 4 c #95C7F8",
-" 5 c #94C6F7",
-" 6 c #93C5F6",
-" 7 c #92C2F2",
-" 8 c #91C1F1",
-" 9 c #91C0EC",
-" a c #8DBCE8",
-" b c #8BB6E3",
-" c c #81ACD9",
-" d c #707CA6",
-" e c #B1BDE7",
-" f c #BCCAEF",
-" g c #526085",
-" h c #6E98C2",
-" i c #8BB5DF",
-" j c #90C0F0",
-" k c #93C5F8",
-" l c #94C6F9",
-" m c #97C9FA",
-" n c #99CBFE",
-" o c #9ACAFB",
-" p c #9ACCFD",
-" q c #9ACCFF",
-" r c #92C4F5",
-" s c #8EBDE9",
-" t c #8CB7E4",
-" u c #79A4D1",
-" v c #6F7BA5",
-" w c #D7E3FF",
-" x c #8E9CC1",
-" y c #58668B",
-" z c #6B95BF",
-" A c #8AB4DE",
-" B c #95C5F5",
-" C c #95C7FA",
-" D c #9BCDFE",
-" E c #9BCDFF",
-" F c #9CCCFD",
-" G c #A0D1FC",
-" H c #A1D0FC",
-" I c #A0D0FE",
-" J c #9FCFFD",
-" K c #9FCEFA",
-" L c #9ECDF9",
-" M c #9CCBF5",
-" N c #9BCAF4",
-" O c #9AC7F1",
-" P c #97C4EE",
-" Q c #94BFE9",
-" R c #93BEE8",
-" S c #91BBE3",
-" T c #8BB5DD",
-" U c #8EA2D5",
-" V c #6F83B6",
-" W c #B7BDDF",
-" X c #BDC3E5",
-" Y c #556B90",
-" Z c #61779C",
-" & c #779FC2",
-"0 c #91B9DC",
-"00 c #97C4ED",
-"01 c #9AC7F0",
-"02 c #9DC9F6",
-"03 c #A0CCF9",
-"04 c #9ECFFA",
-"05 c #9FD0FB",
-"06 c #A0D1FA",
-"07 c #A1D0FE",
-"08 c #A2D3FE",
-"09 c #A3D2FE",
-"0a c #A1D1FF",
-"0b c #9DCCF6",
-"0c c #9AC9F3",
-"0d c #96C3ED",
-"0e c #91BCE6",
-"0f c #89B3DB",
-"0g c #78A2CA",
-"0h c #7488BB",
-"0i c #99ADE0",
-"0j c #C7CDEF",
-"0k c #6D7395",
-"0l c #546A8F",
-"0m c #748AAF",
-"0n c #85ADD0",
-"0o c #96BEE1",
-"0p c #99C6EF",
-"0q c #9BC8F1",
-"0r c #A1CDFA",
-"0s c #A1D2FD",
-"0t c #A2D3FC",
-"0u c #A3D2FF",
-"0v c #A6D6FC",
-"0w c #A8D5FC",
-"0x c #A7D4FB",
-"0y c #A6D3FA",
-"0z c #A5D2F9",
-"0A c #A4D0F7",
-"0B c #A2CEF5",
-"0C c #A0CCF1",
-"0D c #9DC9EE",
-"0E c #9CC4E8",
-"0F c #99C1E5",
-"0G c #99BDE1",
-"0H c #89ADD1",
-"0I c #8094C6",
-"0J c #798DBF",
-"0K c #9EAAD4",
-"0L c #AFBBE5",
-"0M c #617598",
-"0N c #53678A",
-"0O c #6689A7",
-"0P c #80A3C1",
-"0Q c #8FBADD",
-"0R c #99C4E7",
-"0S c #9CC8ED",
-"0T c #9FCBF0",
-"0U c #A2CFF6",
-"0V c #A3D0F7",
-"0W c #A8D5FE",
-"0X c #A5D5FB",
-"0Y c #A9D5FC",
-"0Z c #A8D8FE",
-"0& c #AAD7FE",
-"1 c #A9D6FD",
-"10 c #85A9CD",
-"11 c #7094B8",
-"12 c #7F93C5",
-"13 c #97ABDD",
-"14 c #9DA9D3",
-"15 c #64709A",
-"16 c #54688B",
-"17 c #7185A8",
-"18 c #7FA2C0",
-"19 c #94B7D5",
-"1a c #98C3E6",
-"1b c #9DC8EB",
-"1c c #A2CEF3",
-"1d c #AAD7FF",
-"1e c #A7D7FD",
-"1f c #ABD7FE",
-"1g c #AED9FB",
-"1h c #AED9FC",
-"1i c #ADD8FA",
-"1j c #ACD7FA",
-"1k c #ABD6F9",
-"1l c #AAD5F7",
-"1m c #A7D2F4",
-"1n c #A7D0F0",
-"1o c #A5CEEE",
-"1p c #A2C9E8",
-"1q c #9FC6E5",
-"1r c #9DBAE2",
-"1s c #84A1C9",
-"1t c #7586BC",
-"1u c #899AD0",
-"1v c #95A3D2",
-"1w c #8593C2",
-"1x c #586D8A",
-"1y c #5A6F8C",
-"1z c #6B8BA4",
-"1A c #82A2BB",
-"1B c #91B8D7",
-"1C c #9AC1E0",
-"1D c #9EC7E7",
-"1E c #A1CAEA",
-"1F c #A8D3F5",
-"1G c #ABD6F8",
-"1H c #ACD7F9",
-"1I c #ADD8FB",
-"1J c #B0D8FB",
-"1K c #AED8FE",
-"1L c #707D86",
-"1M c #3D4A53",
-"1N c #798B99",
-"1O c #B6C8D6",
-"1P c #B8D6EE",
-"1Q c #B1D8F9",
-"1R c #AFDAFC",
-"1S c #B1DCFE",
-"1T c #B1DCFF",
-"1U c #B0DBFD",
-"1V c #AFDAFD",
-"1W c #A6CFEF",
-"1X c #A3CCEC",
-"1Y c #A0C7E6",
-"1Z c #96BDDC",
-"1& c #86A3CB",
-"2 c #83A0C8",
-"20 c #8C9DD3",
-"21 c #8A9BD1",
-"22 c #7280AF",
-"23 c #5A6897",
-"24 c #647996",
-"25 c #7B90AD",
-"26 c #89A9C2",
-"27 c #9ABAD3",
-"28 c #9CC3E2",
-"29 c #A1C8E7",
-"2a c #A2CBEB",
-"2b c #A9D2F2",
-"2c c #B0DBFE",
-"2d c #B3DBFE",
-"2e c #B1DBFF",
-"2f c #2D3A43",
-"2g c #606D76",
-"2h c #3F515F",
-"2i c #000F1D",
-"2j c #1E3C54",
-"2k c #537189",
-"2l c #7DA4C5",
-"2m c #AED5F6",
-"2n c #B6DFFB",
-"2o c #B6DFFD",
-"2p c #B5DEFA",
-"2q c #B4DDF9",
-"2r c #B4DBFC",
-"2s c #AED5F2",
-"2t c #AAD1EE",
-"2u c #A8CDE8",
-"2v c #A4C9E4",
-"2w c #9BB4DD",
-"2x c #849DC6",
-"2y c #8C9CD8",
-"2z c #93A3DF",
-"2A c #8497BF",
-"2B c #6679A1",
-"2C c #5C758B",
-"2D c #6F889E",
-"2E c #7C9FB5",
-"2F c #8FB2C8",
-"2G c #9ABED8",
-"2H c #A2C6E0",
-"2I c #A4C9E3",
-"2J c #A7CCE6",
-"2K c #A8D0EA",
-"2L c #A9D1EB",
-"2M c #ABD3ED",
-"2N c #ADD5EF",
-"2O c #B0D7F4",
-"2P c #B0D9F5",
-"2Q c #B2DBF7",
-"2R c #B3DAF9",
-"2S c #B7E0FE",
-"2T c #B7DEFB",
-"2U c #B6DFFF",
-"2V c #B7E0FF",
-"2W c #3D4547",
-"2X c #A5ADAF",
-"2Y c #F8F8F6",
-"2Z c #F1F1EF",
-"2& c #B8B8B8",
-"3 c #797979",
-"30 c #3E3E3E",
-"31 c #090909",
-"32 c #272F32",
-"33 c #50585B",
-"34 c #788691",
-"35 c #A8B6C1",
-"36 c #C1DCED",
-"37 c #B9DEF9",
-"38 c #B7DEFD",
-"39 c #B8E1FD",
-"3a c #B8E1FF",
-"3b c #B7E0FC",
-"3c c #B5DCFD",
-"3d c #B2D9FA",
-"3e c #A6CBE6",
-"3f c #9ABFDA",
-"3g c #859EC7",
-"3h c #8BA4CD",
-"3i c #98A8E4",
-"3j c #8191CD",
-"3k c #60739B",
-"3l c #63769E",
-"3m c #7891A7",
-"3n c #8CA5BB",
-"3o c #95B8CE",
-"3p c #9EC1D7",
-"3q c #A3C7E1",
-"3r c #A6CAE4",
-"3s c #A9CEE8",
-"3t c #AAD2EC",
-"3u c #ACD4EE",
-"3v c #B1DAF6",
-"3w c #B4DBFA",
-"3x c #B8DFFC",
-"3y c #BAE1FE",
-"3z c #464E50",
-"3A c #9EA6A8",
-"3B c #FDFDFB",
-"3C c #FCFCFA",
-"3D c #FDFDFD",
-"3E c #F9F9F9",
-"3F c #C5CDD0",
-"3G c #929A9D",
-"3H c #56646F",
-"3I c #192732",
-"3J c #052031",
-"3K c #405B6C",
-"3L c #779CB7",
-"3M c #BCE1FC",
-"3N c #B9E0FF",
-"3O c #B8DFFE",
-"3P c #BCE5FB",
-"3Q c #BCE4FD",
-"3R c #BBE5FD",
-"3S c #BEE4FB",
-"3T c #BBE4FA",
-"3U c #B9E2F8",
-"3V c #B8DEF5",
-"3W c #B5DBF2",
-"3X c #B1D5EB",
-"3Y c #ABCFE5",
-"3Z c #A4C0E7",
-"3& c #88A4CB",
-"4 c #91A4DF",
-"40 c #A1B4EF",
-"41 c #8391B6",
-"42 c #637196",
-"43 c #647F90",
-"44 c #7D98A9",
-"45 c #8FAFC4",
-"46 c #9BBBD0",
-"47 c #A1C4D8",
-"48 c #A6C9DD",
-"49 c #A8CBE1",
-"4a c #AACDE3",
-"4b c #ABD1E6",
-"4c c #ADD3E8",
-"4d c #AED3E6",
-"4e c #B0D5E8",
-"4f c #B1D5ED",
-"4g c #B2D6EE",
-"4h c #B3D7EF",
-"4i c #B5D9F1",
-"4j c #B6DCF3",
-"4k c #B8DEF3",
-"4l c #B9DFF4",
-"4m c #BBE0FA",
-"4n c #BCE1FB",
-"4o c #BAE3F9",
-"4p c #BEE3FD",
-"4q c #4B5356",
-"4r c #9DA5A8",
-"4s c #FEFFFF",
-"4t c #FDFFFE",
-"4u c #FFFFFF",
-"4v c #FEFEFE",
-"4w c #DFDFE1",
-"4x c #969698",
-"4y c #454545",
-"4z c #030303",
-"4A c #526875",
-"4B c #C8DEEB",
-"4C c #BBE3FC",
-"4D c #BEE7FD",
-"4E c #BEE6FF",
-"4F c #BDE7FF",
-"4G c #C0E6FD",
-"4H c #BAE0F7",
-"4I c #B2D6EC",
-"4J c #A9CDE3",
-"4K c #97B3DA",
-"4L c #8CA8CF",
-"4M c #AABDF8",
-"4N c #899CD7",
-"4O c #627095",
-"4P c #6A789D",
-"4Q c #93AEBF",
-"4R c #A1C1D6",
-"4S c #A3C6DA",
-"4T c #A7CAE0",
-"4U c #A9CCE2",
-"4V c #A8CCE2",
-"4W c #A9CFE4",
-"4X c #AAD0E5",
-"4Y c #ACD1E4",
-"4Z c #AED2EA",
-"4& c #ADD1E9",
-"5 c #AFD3EB",
-"50 c #B3D9F0",
-"51 c #B4DAF1",
-"52 c #B5DBF0",
-"53 c #BFE5FC",
-"54 c #BDE6FC",
-"55 c #C0E5FF",
-"56 c #495154",
-"57 c #9EA6A9",
-"58 c #FCFEFD",
-"59 c #FEFEFF",
-"5a c #E7E7E7",
-"5b c #182E3B",
-"5c c #8197A4",
-"5d c #BDE5FE",
-"5e c #C2E8FD",
-"5f c #C3E7FF",
-"5g c #C3E9FE",
-"5h c #C2E6FE",
-"5i c #C1E5FB",
-"5j c #BEE2F8",
-"5k c #BCDFF5",
-"5l c #B7DAF0",
-"5m c #B4D4EB",
-"5n c #A6C6DD",
-"5o c #90A5DE",
-"5p c #A5BAF3",
-"5q c #A4B6E4",
-"5r c #6577A5",
-"5s c #647786",
-"5t c #8093A2",
-"5u c #8DAABA",
-"5v c #9CB9C9",
-"5w c #9FBED0",
-"5x c #A2C1D3",
-"5y c #A5C6D9",
-"5z c #A6C7DA",
-"5A c #A9CADD",
-"5B c #A8C9DC",
-"5C c #AAC9DE",
-"5D c #ABCADF",
-"5E c #AEC7E6",
-"5F c #ADC8E6",
-"5G c #AEC9E7",
-"5H c #ADCCE0",
-"5I c #B0CFE3",
-"5J c #B2D2E7",
-"5K c #B6D6EB",
-"5L c #B5DAEC",
-"5M c #B8DDEF",
-"5N c #B9DDF3",
-"5O c #BCE0F6",
-"5P c #C1E5FD",
-"5Q c #C2E8FB",
-"5R c #C1E7FC",
-"5S c #C4E8FF",
-"5T c #454A4E",
-"5U c #A9AEB2",
-"5V c #E9E9E9",
-"5W c #000D1A",
-"5X c #C4DAE7",
-"5Y c #C4E6FF",
-"5Z c #C3E5FE",
-"5& c #C0E4FC",
-"6 c #BFE3F9",
-"60 c #BADDF3",
-"61 c #B5D8EE",
-"62 c #B1D1E8",
-"63 c #96B6CD",
-"64 c #94A9E2",
-"65 c #BDD2FF",
-"66 c #8092C0",
-"67 c #5E709E",
-"68 c #728594",
-"69 c #8C9FAE",
-"6a c #92AFBF",
-"6b c #99B6C6",
-"6c c #9AB9CB",
-"6d c #9CBBCD",
-"6e c #9EBFD2",
-"6f c #9FC0D3",
-"6g c #9DBED1",
-"6h c #96B5CA",
-"6i c #89A8BD",
-"6j c #7891B0",
-"6k c #6E87A6",
-"6l c #6E89A7",
-"6m c #809BB9",
-"6n c #94B3C7",
-"6o c #A3C2D6",
-"6p c #A8C8DD",
-"6q c #ADCDE2",
-"6r c #AED3E5",
-"6s c #B1D6E8",
-"6t c #B4D8EE",
-"6u c #B7DBF1",
-"6v c #BADEF4",
-"6w c #BEE2FA",
-"6x c #C0E6FB",
-"6y c #C1E7FA",
-"6z c #C2E6FF",
-"6A c #393E42",
-"6B c #B6BBBF",
-"6C c #8D8D8D",
-"6D c #415764",
-"6E c #CDE3F0",
-"6F c #C2E4FD",
-"6G c #BCE6FE",
-"6H c #BCE2F9",
-"6I c #B9DFF6",
-"6J c #B7DBF3",
-"6K c #AFCDF3",
-"6L c #91AFD5",
-"6M c #A9BEEB",
-"6N c #BED3FF",
-"6O c #687B9C",
-"6P c #627596",
-"6Q c #7792A5",
-"6R c #8AA5B8",
-"6S c #90ADBF",
-"6T c #93B0C2",
-"6U c #96B3C5",
-"6V c #98B5C7",
-"6W c #98B7CB",
-"6X c #97B6CA",
-"6Y c #98B0D2",
-"6Z c #93ABCD",
-"6& c #8A9FD6",
-"7 c #768BC2",
-"70 c #6E7CBD",
-"71 c #6F7DBE",
-"72 c #6E7BAF",
-"73 c #6D77B2",
-"74 c #6B75B0",
-"75 c #6D7FAF",
-"76 c #8496C6",
-"77 c #9BBACF",
-"78 c #A4C3D8",
-"79 c #A6CBDE",
-"7a c #ABD0E3",
-"7b c #AED2E8",
-"7c c #B7DDF4",
-"7d c #BDE2FC",
-"7e c #BCE5F9",
-"7f c #BDE6FA",
-"7g c #BEE7FB",
-"7h c #BFE7FF",
-"7i c #292D2E",
-"7j c #CBCFD0",
-"7k c #FDFEFF",
-"7l c #2B2C2E",
-"7m c #82A8BD",
-"7n c #B9E3FB",
-"7o c #B8E2FA",
-"7p c #B4D8F0",
-"7q c #AAC8EE",
-"7r c #86A4CA",
-"7s c #ABC0ED",
-"7t c #677A9B",
-"7u c #657899",
-"7v c #7994A7",
-"7w c #87A2B5",
-"7x c #8AA7B9",
-"7y c #8CA9BB",
-"7z c #8EABBD",
-"7A c #8DAABC",
-"7B c #88A7BB",
-"7C c #87A6BA",
-"7D c #8098BA",
-"7E c #7189AB",
-"7F c #6D82B9",
-"7G c #6F84BB",
-"7H c #7785C6",
-"7I c #8A98D9",
-"7J c #ADBAEE",
-"7K c #C4D1FF",
-"7L c #B6C0FB",
-"7M c #838DC8",
-"7N c #6779A9",
-"7O c #6678A8",
-"7P c #7493A8",
-"7Q c #91B0C5",
-"7R c #9CC1D4",
-"7S c #A1C6D9",
-"7T c #A6CAE0",
-"7U c #ACD0E6",
-"7V c #AFD5EC",
-"7W c #B7DCF6",
-"7X c #B9DEF8",
-"7Y c #B9E2F6",
-"7Z c #BAE3F7",
-"7& c #BBE4F8",
-"8 c #111516",
-"80 c #E4E8E9",
-"81 c #C9CACC",
-"82 c #202123",
-"83 c #BEE4F9",
-"84 c #BAE4FD",
-"85 c #BAE3FF",
-"86 c #B8E4FD",
-"87 c #B9E3FC",
-"88 c #B8E2FB",
-"89 c #B4DCF6",
-"8a c #B1D9F3",
-"8b c #AED3ED",
-"8c c #A4C6E2",
-"8d c #85A7C3",
-"8e c #A0B4E9",
-"8f c #C1D5FF",
-"8g c #8594CB",
-"8h c #5D6CA3",
-"8i c #6779A1",
-"8j c #7385AD",
-"8k c #7990AF",
-"8l c #8097B6",
-"8m c #7D92BD",
-"8n c #798BCB",
-"8o c #7183C3",
-"8p c #7584BD",
-"8q c #7D8CC5",
-"8r c #909DBD",
-"8s c #B0BDDD",
-"8t c #D4E0EE",
-"8u c #E9F5FF",
-"8v c #EDF8FE",
-"8w c #EEF9FF",
-"8x c #EFF7FF",
-"8y c #D9E1EC",
-"8z c #939FC9",
-"8A c #6372AB",
-"8B c #7483BC",
-"8C c #8DACC1",
-"8D c #9AB9CE",
-"8E c #A0C2DB",
-"8F c #A7C9E2",
-"8G c #A9CFE6",
-"8H c #AED4EB",
-"8I c #B1D9F2",
-"8J c #B3DBF4",
-"8K c #B5DFF8",
-"8L c #B7E1FA",
-"8M c #B9E2FE",
-"8N c #BAE4FC",
-"8O c #5B6972",
-"8P c #64727B",
-"8Q c #BBE5FE",
-"8R c #BBE3FD",
-"8S c #BBE4FF",
-"8T c #B7E3FC",
-"8U c #B9E2FF",
-"8V c #B6E0F9",
-"8W c #AACFE9",
-"8X c #9FC1DD",
-"8Y c #87A9C5",
-"8Z c #8195CA",
-"8& c #A7BBF0",
-"9 c #8998CF",
-"90 c #7382B9",
-"91 c #6E80A8",
-"92 c #63759D",
-"93 c #5F7695",
-"94 c #7188A7",
-"95 c #758AB5",
-"96 c #7388B3",
-"97 c #788ACA",
-"98 c #8092D2",
-"99 c #99A8E1",
-"9a c #C2D1FF",
-"9b c #DEEBFF",
-"9c c #E4F1FF",
-"9d c #E7F3FF",
-"9e c #F0F8FF",
-"9f c #DDE9FF",
-"9g c #A2AED8",
-"9h c #6C7BB4",
-"9i c #6170A9",
-"9j c #68879C",
-"9k c #88A7BC",
-"9l c #95B7D0",
-"9m c #9EC0D9",
-"9n c #A3C9E0",
-"9o c #ACD4ED",
-"9p c #B0D8F1",
-"9q c #B2DCF5",
-"9r c #B4DEF7",
-"9s c #BAE2FB",
-"9t c #90B8D1",
-"9u c #2D2D2D",
-"9v c #F4F4F4",
-"9w c #03111A",
-"9x c #B1BFC8",
-"9y c #B9E1FB",
-"9z c #BAE2FC",
-"9A c #B5E1FC",
-"9B c #B5E1FE",
-"9C c #B4E0FD",
-"9D c #ADD4F1",
-"9E c #A9D0ED",
-"9F c #A5CAE7",
-"9G c #9FC4E1",
-"9H c #9ABCD8",
-"9I c #88AAC6",
-"9J c #7A8DD1",
-"9K c #7B8ED2",
-"9L c #8B9FD2",
-"9M c #9DB1E4",
-"9N c #97A9E7",
-"9O c #7B8DCB",
-"9P c #6B7CC1",
-"9Q c #7384C9",
-"9R c #8191C4",
-"9S c #8B9BCE",
-"9T c #ABBBD5",
-"9U c #CADAF4",
-"9V c #DBEAFF",
-"9W c #DAE9FF",
-"9X c #D2E0FF",
-"9Y c #D4E2FF",
-"9Z c #E3F0FF",
-"9& c #E8F5FF",
-"a c #EDF7FF",
-"a0 c #EDFAFF",
-"a1 c #F0F9FE",
-"a2 c #EDF6FB",
-"a3 c #A6AFD6",
-"a4 c #717AA1",
-"a5 c #5E6EA2",
-"a6 c #6B7BAF",
-"a7 c #85A5BC",
-"a8 c #98B8CF",
-"a9 c #9DC3D8",
-"aa c #A4CADF",
-"ab c #A8CFEC",
-"ac c #ACD3F0",
-"ad c #AFD8F4",
-"ae c #B4DDFB",
-"af c #B3DFFC",
-"ag c #B6E2FD",
-"ah c #BADFF9",
-"ai c #B4E0FB",
-"aj c #B5E1FA",
-"ak c #B5E0FF",
-"al c #BEDEF5",
-"am c #7090A7",
-"an c #595959",
-"ao c #9E9E9E",
-"ap c #28485D",
-"aq c #BEDEF3",
-"ar c #B6E2FF",
-"as c #B3DFFA",
-"at c #B2DEFB",
-"au c #B1DDFA",
-"av c #AED7F3",
-"aw c #AAD3EF",
-"ax c #A7CEEB",
-"ay c #A2C9E6",
-"az c #98BDDA",
-"aA c #93B5D1",
-"aB c #84A6C2",
-"aC c #8194D8",
-"aD c #95A8EC",
-"aE c #B4C8FB",
-"aF c #ABBFF2",
-"aG c #90A2E0",
-"aH c #7C8ECC",
-"aI c #7F90D5",
-"aJ c #91A2E7",
-"aK c #B0C0F3",
-"aL c #CDDDFF",
-"aM c #DEEEFF",
-"aN c #D8E8FF",
-"aO c #CDDCFD",
-"aP c #BECDEE",
-"aQ c #AFBDEC",
-"aR c #A9B7E6",
-"aS c #CFDCED",
-"aT c #ECF6FF",
-"aU c #E7F1FA",
-"aV c #E2EFF7",
-"aW c #ECF5FA",
-"aX c #F1FAFF",
-"aY c #EAF3FF",
-"aZ c #6777AB",
-"a& c #5D6DA1",
-"b c #608097",
-"b0 c #82A2B9",
-"b1 c #92B8CD",
-"b2 c #A1C8E5",
-"b3 c #A6CDEA",
-"b4 c #A9D2EE",
-"b5 c #AFD8F6",
-"b6 c #B0D9F7",
-"b7 c #ABD7F2",
-"b8 c #83A8C2",
-"b9 c #90B5CF",
-"ba c #B4E0F9",
-"bb c #B4DFFF",
-"bc c #45657C",
-"bd c #8A8A8A",
-"be c #3A3A3A",
-"bf c #7595AA",
-"bg c #BDDDF2",
-"bh c #B1E0FE",
-"bi c #B2DFFE",
-"bj c #B1DEFD",
-"bk c #B0DDFC",
-"bl c #AFDCFB",
-"bm c #ADDAF9",
-"bn c #ABD8F5",
-"bo c #AAD7F4",
-"bp c #A8D4F1",
-"bq c #A3CFEC",
-"br c #A2CAE4",
-"bs c #9CC4DE",
-"bt c #99BED8",
-"bu c #91B6D0",
-"bv c #8FACD8",
-"bw c #7F9CC8",
-"bx c #8599DE",
-"by c #9BAFF4",
-"bz c #8FA2E4",
-"bA c #7E91D3",
-"bB c #8698C8",
-"bC c #99ABDB",
-"bD c #B4C4DD",
-"bE c #D0E0F9",
-"bF c #DEEEFD",
-"bG c #DFEFFE",
-"bH c #DEEFFF",
-"bI c #C5D6F4",
-"bJ c #B5B6FF",
-"bK c #9E9FFF",
-"bL c #7F83FE",
-"bM c #7C80FB",
-"bN c #BFCDE8",
-"bO c #E2F0FF",
-"bP c #C9F5E6",
-"bQ c #BBE7D8",
-"bR c #98EAA8",
-"bS c #8DDF9D",
-"bT c #C4E4D9",
-"bU c #E0FFF5",
-"bV c #F3FBFE",
-"bW c #EFF7FA",
-"bX c #A5ADD1",
-"bY c #6E769A",
-"bZ c #5D6B9C",
-"b& c #6B79AA",
-"c c #83A7BD",
-"c0 c #96BAD0",
-"c1 c #9BC2DF",
-"c2 c #A3CFEA",
-"c3 c #A6D2ED",
-"c4 c #AAD6F3",
-"c5 c #ACD8F5",
-"c6 c #AEDBFC",
-"c7 c #B0DDFE",
-"c8 c #BDDCF1",
-"c9 c #C4DAE8",
-"ca c #9CB2C0",
-"cb c #7A848E",
-"cc c #4F5963",
-"cd c #25292A",
-"ce c #080C0D",
-"cf c #343537",
-"cg c #000103",
-"ch c #B2DFFF",
-"ci c #B9DDF7",
-"cj c #B6DDFA",
-"ck c #B0DFFD",
-"cl c #B2DFFC",
-"cm c #B3DEFE",
-"cn c #B1E0FC",
-"co c #C1DBEC",
-"cp c #1C3647",
-"cq c #C2C2C2",
-"cr c #CBD0D6",
-"cs c #000208",
-"ct c #B9DDF5",
-"cu c #C5DBE9",
-"cv c #9AB0BE",
-"cw c #6F7A80",
-"cx c #49545A",
-"cy c #383D41",
-"cz c #34393D",
-"cA c #3E474E",
-"cB c #5B646B",
-"cC c #889EAC",
-"cD c #C0DBEE",
-"cE c #BFDAED",
-"cF c #86A0B1",
-"cG c #A1B3C1",
-"cH c #9FB1BF",
-"cI c #BBD2E0",
-"cJ c #C3DAE8",
-"cK c #C0DCEA",
-"cL c #C1DDEB",
-"cM c #B1DFFF",
-"cN c #AFDEFC",
-"cO c #ACD9F8",
-"cP c #AAD7F6",
-"cQ c #A7D4F1",
-"cR c #A5D2EF",
-"cS c #A1CDEA",
-"cT c #9ECAE7",
-"cU c #9BC3DD",
-"cV c #95BDD7",
-"cW c #92B7D1",
-"cX c #8BB0CA",
-"cY c #7794C0",
-"cZ c #7D9AC6",
-"c& c #7E92D7",
-"d c #8497D9",
-"d0 c #9AADEF",
-"d1 c #B5C7F7",
-"d2 c #CEE0FF",
-"d3 c #DDEDFF",
-"d4 c #DBECFF",
-"d5 c #C1D2F0",
-"d6 c #898AF4",
-"d7 c #7273DD",
-"d8 c #696DE8",
-"d9 c #9498FF",
-"da c #D7E5FF",
-"db c #D9E7FF",
-"dc c #B1DDCE",
-"dd c #9FCBBC",
-"de c #73C583",
-"df c #59AB69",
-"dg c #A7C7BC",
-"dh c #DDFDF2",
-"di c #F4FCFF",
-"dj c #E8F0FF",
-"dk c #A6AED2",
-"dl c #6270A1",
-"dm c #5A6899",
-"dn c #5E8298",
-"do c #89ADC3",
-"dp c #93BAD7",
-"dq c #9ECAE5",
-"dr c #A2CEE9",
-"ds c #A7D3F0",
-"dt c #ACD9FA",
-"du c #8CB8D5",
-"dv c #58778C",
-"dw c #214055",
-"dx c #000816",
-"dy c #1F3543",
-"dz c #5C6670",
-"dA c #929CA6",
-"dB c #CED2D3",
-"dC c #F8FCFD",
-"dD c #B8B9BB",
-"dE c #333436",
-"dF c #B1DEFF",
-"dG c #A6D3F4",
-"dH c #7A9EB8",
-"dI c #557993",
-"dJ c #44677D",
-"dK c #4A6D83",
-"dL c #678EAB",
-"dM c #B1DEFB",
-"dN c #B2DDFD",
-"dO c #AFDEFA",
-"dP c #B0DFFB",
-"dQ c #B5CFE0",
-"dR c #000F20",
-"dS c #F8F8F8",
-"dT c #5D6268",
-"dU c #666B71",
-"dV c #84A8C0",
-"dW c #3F637B",
-"dX c #091F2D",
-"dY c #1C3240",
-"dZ c #667177",
-"d& c #98A3A9",
-"e c #B8BDC1",
-"e0 c #BBC0C4",
-"e1 c #AAB3BA",
-"e2 c #7E878E",
-"e3 c #263C4A",
-"e4 c #192F3D",
-"e5 c #7AA6C1",
-"e6 c #B2DEF9",
-"e7 c #7FAACA",
-"e8 c #425D70",
-"e9 c #000A1D",
-"ea c #062031",
-"eb c #5A7485",
-"ec c #90BDDC",
-"ed c #000B19",
-"ee c #0C1E2C",
-"ef c #001422",
-"eg c #000917",
-"eh c #001220",
-"ei c #031F2D",
-"ej c #719DB8",
-"ek c #B0DEFF",
-"el c #AFDDFE",
-"em c #AEDCFD",
-"en c #AEDCFF",
-"eo c #AEDCFE",
-"ep c #ACDDFD",
-"eq c #ABDCFC",
-"er c #ACDAFC",
-"es c #AAD8F9",
-"et c #A8D6F7",
-"eu c #A8D5F6",
-"ev c #A5D2F3",
-"ew c #A2CFEE",
-"ex c #9FCCEB",
-"ey c #9FC8E6",
-"ez c #99C2E0",
-"eA c #96BBD8",
-"eB c #90B5D2",
-"eC c #839ECB",
-"eD c #6984B1",
-"eE c #798ED1",
-"eF c #7C91D4",
-"eG c #8698CA",
-"eH c #9EB0E2",
-"eI c #B9CAE4",
-"eJ c #CFE0FA",
-"eK c #DAEBFD",
-"eL c #DBECFE",
-"eM c #E0F0FF",
-"eN c #E1F1FF",
-"eO c #E2EEFF",
-"eP c #D7E3F9",
-"eQ c #AFB6ED",
-"eR c #9EA5DC",
-"eS c #B6BFDC",
-"eT c #D7E0FD",
-"eU c #E3F6FD",
-"eV c #CEE1E8",
-"eW c #88DA92",
-"eX c #69BB73",
-"eY c #43A945",
-"eZ c #44AA46",
-"e& c #BCD4C7",
-"f c #E7FFF2",
-"f0 c #F6FBFF",
-"f1 c #F7FCFF",
-"f2 c #E9EEF2",
-"f3 c #9AA1CD",
-"f4 c #646B97",
-"f5 c #546590",
-"f6 c #7182AD",
-"f7 c #8AAFCA",
-"f8 c #94B9D4",
-"f9 c #97C3E0",
-"fa c #A1CEEF",
-"fb c #A7D5F6",
-"fc c #A9D7F8",
-"fd c #ADDBFD",
-"fe c #ADDBFC",
-"ff c #C3D6E5",
-"fg c #6F8291",
-"fh c #2A2E31",
-"fi c #1D2124",
-"fj c #707070",
-"fk c #B6B6B6",
-"fl c #F0F0F0",
-"fm c #FCFCFC",
-"fn c #FBFDFC",
-"fo c #FAFCFB",
-"fp c #FBFBFD",
-"fq c #72797F",
-"fr c #5E656B",
-"fs c #3D4144",
-"ft c #060A0D",
-"fu c #474747",
-"fv c #747474",
-"fw c #858585",
-"fx c #535353",
-"fy c #050505",
-"fz c #59707E",
-"fA c #C0D7E5",
-"fB c #AFDBFE",
-"fC c #85939C",
-"fD c #3A4851",
-"fE c #FBFBFB",
-"fF c #FBFCFE",
-"fG c #FCFDFF",
-"fH c #FCFCFE",
-"fI c #E1E1E1",
-"fJ c #000C1E",
-"fK c #AAC7D9",
-"fL c #B6DAF4",
-"fM c #B5D9F3",
-"fN c #848E98",
-"fO c #2B353F",
-"fP c #252525",
-"fQ c #868686",
-"fR c #DADCDB",
-"fS c #AFAFAF",
-"fT c #071017",
-"fU c #868F96",
-"fV c #AFDCFD",
-"fW c #ACDDFE",
-"fX c #B3DAF7",
-"fY c #B4DBF8",
-"fZ c #B1C3CF",
-"f& c #647682",
-"g c #262729",
-"g0 c #2A2B2D",
-"g1 c #898B8A",
-"g2 c #E4E6E5",
-"g3 c #7A848D",
-"g4 c #5B656E",
-"g5 c #C3D6E4",
-"g6 c #263947",
-"g7 c #919191",
-"g8 c #EBEFF2",
-"g9 c #262A2D",
-"ga c #5C83A2",
-"gb c #ACDAFB",
-"gc c #ACDAFE",
-"gd c #A9DAFA",
-"ge c #A8D9F9",
-"gf c #A8D6F8",
-"gg c #A7D5F7",
-"gh c #A6D4F5",
-"gi c #A3D1F2",
-"gj c #A2CFF0",
-"gk c #9FCCED",
-"gl c #9BC8E7",
-"gm c #97C4E3",
-"gn c #96BFDD",
-"go c #90B9D7",
-"gp c #89AECB",
-"gq c #6D92AF",
-"gr c #7691BE",
-"gs c #7B96C3",
-"gt c #7E93D6",
-"gu c #94A9EC",
-"gv c #B7C9FB",
-"gw c #CADCFF",
-"gx c #D7E8FF",
-"gy c #D9EAFF",
-"gz c #DCEDFF",
-"gA c #DFEFFF",
-"gB c #D9E9F9",
-"gC c #D6E2F8",
-"gD c #DBE2FF",
-"gE c #DDE4FF",
-"gF c #EBF4FF",
-"gG c #E9F2FF",
-"gH c #E4F7FE",
-"gI c #D8EBF2",
-"gJ c #95E79F",
-"gK c #74C67E",
-"gL c #67CD69",
-"gM c #87ED89",
-"gN c #E0F8EB",
-"gO c #EBFFF6",
-"gP c #F8FDFF",
-"gQ c #D7DEFF",
-"gR c #8990BC",
-"gS c #586994",
-"gT c #7196B1",
-"gU c #8CB1CC",
-"gV c #91BDDA",
-"gW c #9CC9EA",
-"gX c #A4D2F3",
-"gY c #A9D7F9",
-"gZ c #AAD8FA",
-"g& c #ABD9FA",
-"h c #A1CFF0",
-"h0 c #132635",
-"h1 c #3B4E5D",
-"h2 c #B9BDC0",
-"h3 c #F6FAFD",
-"h4 c #F8FAF9",
-"h5 c #F9FBFA",
-"h6 c #F9F9FB",
-"h7 c #343B41",
-"h8 c #3B4248",
-"h9 c #A3A7AA",
-"ha c #EEF2F5",
-"hb c #FAFAFA",
-"hc c #DBDBDB",
-"hd c #324957",
-"he c #ADD9FC",
-"hf c #4F5D66",
-"hg c #829099",
-"hh c #F9FAFC",
-"hi c #FAFAFC",
-"hj c #6C6C6C",
-"hk c #436072",
-"hl c #BAD7E9",
-"hm c #84A8C2",
-"hn c #1B3F59",
-"ho c #A8B2BC",
-"hp c #BBC4CB",
-"hq c #000910",
-"hr c #8CB9DA",
-"hs c #ADDAFB",
-"ht c #AADBFC",
-"hu c #A9DAFB",
-"hv c #8CB3D0",
-"hw c #5E85A2",
-"hx c #00111D",
-"hy c #576975",
-"hz c #C4C5C7",
-"hA c #828C95",
-"hB c #545E67",
-"hC c #536674",
-"hD c #415462",
-"hE c #606467",
-"hF c #44484B",
-"hG c #B1D8F7",
-"hH c #AADBFB",
-"hI c #A8DAFD",
-"hJ c #A9D9FF",
-"hK c #A8DAFF",
-"hL c #A7D7FB",
-"hM c #A5D5F9",
-"hN c #A4D2F6",
-"hO c #A2D0F2",
-"hP c #9FCDEF",
-"hQ c #99C6E7",
-"hR c #98C1DF",
-"hS c #93BCDA",
-"hT c #90AFDD",
-"hU c #7B9AC8",
-"hV c #788DCE",
-"hW c #7F94D5",
-"hX c #8295CD",
-"hY c #96A9E1",
-"hZ c #B2C7E6",
-"h& c #C5DAF9",
-"i c #D7E9FF",
-"i0 c #D8EAFF",
-"i1 c #DBEBFB",
-"i2 c #DDEDFD",
-"i3 c #DDEEFF",
-"i4 c #DDF0FF",
-"i5 c #F2DAD6",
-"i6 c #E9D1CD",
-"i7 c #FFB781",
-"i8 c #FFAA74",
-"i9 c #D9AB94",
-"ia c #FFE1CA",
-"ib c #E5F5FF",
-"ic c #E5E8DD",
-"id c #E2E5DA",
-"ie c #D5E5D8",
-"if c #D4E4D7",
-"ig c #DCEAEA",
-"ih c #EAF8F8",
-"ii c #FAFFFF",
-"ij c #F7FAFF",
-"ik c #CCCFD8",
-"il c #727CAF",
-"im c #586295",
-"in c #5C7496",
-"io c #839BBD",
-"ip c #8BB4D2",
-"iq c #94BDDB",
-"ir c #A3CFF2",
-"is c #A5D1F4",
-"it c #A7D9FC",
-"iu c #A9DBFE",
-"iv c #A9D9FD",
-"iw c #8FBFE3",
-"ix c #1A1A1A",
-"iy c #F7F8FA",
-"iz c #F6F8F7",
-"iA c #F7F9F8",
-"iB c #F7F7F7",
-"iC c #CDCDCD",
-"iD c #E1E6E9",
-"iE c #84898C",
-"iF c #304352",
-"iG c #112433",
-"iH c #26353C",
-"iI c #85949B",
-"iJ c #F5F5F5",
-"iK c #F6F6F6",
-"iL c #F3F3F3",
-"iM c #545454",
-"iN c #3B5669",
-"iO c #BAD5E8",
-"iP c #AADAFF",
-"iQ c #ACD7F7",
-"iR c #A6D1F1",
-"iS c #DDDDDD",
-"iT c #F9F7F8",
-"iU c #F8F8FA",
-"iV c #F7F7F9",
-"iW c #D8DDE1",
-"iX c #03080C",
-"iY c #91BFE1",
-"iZ c #ABD9FB",
-"i& c #BED3E4",
-"j c #526778",
-"j0 c #171717",
-"j1 c #F7F5F6",
-"j2 c #E6E6E8",
-"j3 c #8D97A0",
-"j4 c #505A63",
-"j5 c #32434D",
-"j6 c #54656F",
-"j7 c #C4C4C4",
-"j8 c #838584",
-"j9 c #304C61",
-"ja c #B8D4E9",
-"jb c #B8D7EC",
-"jc c #B7D6EB",
-"jd c #828F97",
-"je c #334048",
-"jf c #1B191A",
-"jg c #8A8889",
-"jh c #EBEBEB",
-"ji c #899299",
-"jj c #4E575E",
-"jk c #B7D5ED",
-"jl c #7391A9",
-"jm c #202020",
-"jn c #E6E6E6",
-"jo c #0A2D49",
-"jp c #AACDE9",
-"jq c #A7D9FE",
-"jr c #A6D8FD",
-"js c #A4D4F8",
-"jt c #A2D2F6",
-"ju c #A3D1F5",
-"jv c #9FCDF1",
-"jw c #9DCBED",
-"jx c #98C6E8",
-"jy c #95C2E3",
-"jz c #90BDDE",
-"jA c #8DB6D4",
-"jB c #78A1BF",
-"jC c #7897C5",
-"jD c #7D9CCA",
-"jE c #8EA3E4",
-"jF c #ADC0F8",
-"jG c #C2D5FF",
-"jH c #D1E6FF",
-"jI c #D4E9FF",
-"jJ c #DCECFC",
-"jK c #DCEFFF",
-"jL c #D7EAFB",
-"jM c #E2CAC6",
-"jN c #D0B8B4",
-"jO c #ED9660",
-"jP c #D8814B",
-"jQ c #B4866F",
-"jR c #FFE4CD",
-"jS c #DAEAF9",
-"jT c #DBEBFA",
-"jU c #E9ECE1",
-"jV c #DFE2D7",
-"jW c #E2F2E5",
-"jX c #EDFBFB",
-"jY c #EEFCFC",
-"jZ c #FBFEFF",
-"j& c #F1F4FD",
-"k c #ABB5E8",
-"k0 c #606A9D",
-"k1 c #50688A",
-"k2 c #677FA1",
-"k3 c #80A9C7",
-"k4 c #8CB5D3",
-"k5 c #93BEE1",
-"k6 c #9FCBEE",
-"k7 c #A2CEF1",
-"k8 c #A3D3F9",
-"k9 c #A6D8FB",
-"ka c #020202",
-"kb c #F1F1F1",
-"kc c #F3F4F6",
-"kd c #F3F5F4",
-"ke c #F4F6F5",
-"kf c #EFEFEF",
-"kg c #0A0F12",
-"kh c #474C4F",
-"ki c #7E91A0",
-"kj c #A3B6C5",
-"kk c #8A99A0",
-"kl c #29383F",
-"km c #575757",
-"kn c #F2F2F2",
-"ko c #E8E8E8",
-"kp c #062134",
-"kq c #86A1B4",
-"kr c #507B9B",
-"ks c #F5F3F4",
-"kt c #F3F3F5",
-"ku c #F4F4F6",
-"kv c #595E62",
-"kw c #5A5F63",
-"kx c #A1CFF1",
-"ky c #2C4152",
-"kz c #394E5F",
-"kA c #F4F2F3",
-"kB c #727274",
-"kC c #0A0A0C",
-"kD c #3D4750",
-"kE c #757F88",
-"kF c #8899A3",
-"kG c #61727C",
-"kH c #000000",
-"kI c #989898",
-"kJ c #F2F4F3",
-"kK c #E7E9E8",
-"kL c #001227",
-"kM c #A3BFD4",
-"kN c #A8D8FC",
-"kO c #98C8EC",
-"kP c #57768B",
-"kQ c #00081D",
-"kR c #323F47",
-"kS c #98A5AD",
-"kT c #F0EEEF",
-"kU c #9099A0",
-"kV c #475057",
-"kW c #9BB9D1",
-"kX c #000A22",
-"kY c #BEBEBE",
-"kZ c #AAAAAA",
-"k& c #8EB1CD",
-"l c #B2D5F1",
-"l0 c #A8D8FF",
-"l1 c #A3D7FC",
-"l2 c #A5D6FE",
-"l3 c #A2D6FB",
-"l4 c #A3D4FC",
-"l5 c #A2D3FB",
-"l6 c #A0D2F7",
-"l7 c #9FD1F6",
-"l8 c #9DCDF3",
-"l9 c #99C9EF",
-"la c #97C5E7",
-"lb c #92C0E2",
-"lc c #91B7DC",
-"ld c #85ABD0",
-"le c #7B94D4",
-"lf c #738CCC",
-"lg c #8196D7",
-"lh c #889DDE",
-"li c #A3BAE4",
-"lj c #BBD2FC",
-"lk c #CEE2FD",
-"ll c #D0E4FF",
-"lm c #D1E3F9",
-"ln c #D3E5FB",
-"lo c #D6E8FF",
-"lp c #D9EBFF",
-"lq c #DBEDFF",
-"lr c #D7E8FA",
-"ls c #F5AD87",
-"lt c #D18963",
-"lu c #DE7130",
-"lv c #D86B2A",
-"lw c #C8BBB5",
-"lx c #F8EBE5",
-"ly c #EFE5A8",
-"lz c #F6ECAF",
-"lA c #FFE545",
-"lB c #FFD939",
-"lC c #E4D793",
-"lD c #FBEEAA",
-"lE c #F1F9FC",
-"lF c #F9FFFF",
-"lG c #FBFFFF",
-"lH c #E1E6F9",
-"lI c #959AAD",
-"lJ c #576397",
-"lK c #596599",
-"lL c #6F92AE",
-"lM c #89ACC8",
-"lN c #8DB9DC",
-"lO c #93BFE2",
-"lP c #9CCCF0",
-"lQ c #A0D1F9",
-"lR c #A1D5FA",
-"lS c #A3D7FE",
-"lT c #A4D8FD",
-"lU c #0E1215",
-"lV c #D6DADD",
-"lW c #F2F2F4",
-"lX c #E0E0E0",
-"lY c #243B4D",
-"lZ c #283F51",
-"l& c #80B0D4",
-"m c #A6D6FA",
-"m0 c #A4D5FD",
-"m1 c #25323B",
-"m2 c #86939C",
-"m3 c #7B8489",
-"m4 c #4A5358",
-"m5 c #A2D8FC",
-"m6 c #A5D6FF",
-"m7 c #BED1DF",
-"m8 c #000513",
-"m9 c #C5C7C6",
-"ma c #F1F3F2",
-"mb c #C5C5C5",
-"mc c #000821",
-"md c #A5C5DE",
-"me c #B4C7D5",
-"mf c #213442",
-"mg c #F0F2F1",
-"mh c #F1F1F3",
-"mi c #BDC4CA",
-"mj c #1C2329",
-"mk c #2B5472",
-"ml c #8EB7D5",
-"mm c #8EA8BF",
-"mn c #000F26",
-"mo c #E0DEDF",
-"mp c #F2F0F1",
-"mq c #404D56",
-"mr c #7A8790",
-"ms c #5E6367",
-"mt c #050A0E",
-"mu c #5F5F5F",
-"mv c #C6C6C6",
-"mw c #959EA5",
-"mx c #404950",
-"my c #A9D6F7",
-"mz c #AAD7F8",
-"mA c #383C3F",
-"mB c #7F8386",
-"mC c #BDBFBE",
-"mD c #001026",
-"mE c #7D99AF",
-"mF c #A0D4F9",
-"mG c #A1D2FA",
-"mH c #9FD0F8",
-"mI c #9ED0F5",
-"mJ c #9BCDF2",
-"mK c #95C5EB",
-"mL c #8BB9DB",
-"mM c #7CA2C7",
-"mN c #749ABF",
-"mO c #829BDB",
-"mP c #819ADA",
-"mQ c #96ABEC",
-"mR c #B7CCFF",
-"mS c #C3DAFF",
-"mT c #B4CBF5",
-"mU c #99ADC8",
-"mV c #8397B2",
-"mW c #788AA0",
-"mX c #8597AD",
-"mY c #99ABC3",
-"mZ c #C5D7EF",
-"m& c #D7E9FD",
-"n c #FFCEA8",
-"n0 c #F6AE88",
-"n1 c #FFA362",
-"n2 c #FFBF7E",
-"n3 c #F7EAE4",
-"n4 c #F5E8E2",
-"n5 c #EDE3A6",
-"n6 c #E5DB9E",
-"n7 c #FAD030",
-"n8 c #F6CC2C",
-"n9 c #EEE19D",
-"na c #FFFAB6",
-"nb c #F2FAFD",
-"nc c #C3C8DB",
-"nd c #6C78AC",
-"ne c #527591",
-"nf c #7B9EBA",
-"ng c #86B2D5",
-"nh c #8FBBDE",
-"ni c #94C4E8",
-"nj c #99C9ED",
-"nk c #9ECFF7",
-"nl c #A2D6FD",
-"nm c #222629",
-"nn c #BDC1C4",
-"no c #EFEFF1",
-"np c #EEEEEE",
-"nq c #515151",
-"nr c #566D7F",
-"ns c #B9D0E2",
-"nt c #95A2AB",
-"nu c #26333C",
-"nv c #EDEDED",
-"nw c #BEC7CC",
-"nx c #161F24",
-"ny c #A1D7FB",
-"nz c #A3D4FD",
-"nA c #A4D5FE",
-"nB c #647785",
-"nC c #3E515F",
-"nD c #EEF0EF",
-"nE c #EDEFEE",
-"nF c #F0F0F2",
-"nG c #5A7A93",
-"nH c #B1D1EA",
-"nI c #2B3E4C",
-"nJ c #5B6E7C",
-"nK c #A8A8AA",
-"nL c #030A10",
-"nM c #757C82",
-"nN c #ABD4F2",
-"nO c #B5CFE6",
-"nP c #2F4960",
-"nQ c #9A9899",
-"nR c #EFEDEE",
-"nS c #6B7881",
-"nT c #48555E",
-"nU c #3A3F43",
-"nV c #DBE0E4",
-"nW c #EEEEF0",
-"nX c #9BA4AB",
-"nY c #3A434A",
-"nZ c #426F90",
-"n& c #414548",
-"o c #E8ECEF",
-"o0 c #CDCFCE",
-"o1 c #131514",
-"o2 c #6B879D",
-"o3 c #B5D1E7",
-"o4 c #9FD4FC",
-"o5 c #9FD4FE",
-"o6 c #9ED3FD",
-"o7 c #9FD3FB",
-"o8 c #9ED2FA",
-"o9 c #9CD0F8",
-"oa c #9BCFF7",
-"ob c #9BCCF4",
-"oc c #97C8F0",
-"od c #8FBFE5",
-"oe c #8EB4E5",
-"of c #81A7D8",
-"og c #7D91DA",
-"oh c #8599E2",
-"oi c #8EA5D7",
-"oj c #ABC2F4",
-"ok c #C5D9F4",
-"ol c #AFC3DE",
-"om c #8B9096",
-"on c #858A90",
-"oo c #A8A7AC",
-"op c #B7B6BB",
-"oq c #C3C5C4",
-"or c #A3A5A4",
-"os c #8F9092",
-"ot c #737476",
-"ou c #A3AFBF",
-"ov c #D7E3F3",
-"ow c #DDECFF",
-"ox c #DEEDFF",
-"oy c #E3EFFD",
-"oz c #E1EDFB",
-"oA c #E3EDF7",
-"oB c #E7F1FB",
-"oC c #E6F2FE",
-"oD c #E9EBD6",
-"oE c #E0E2CD",
-"oF c #E8E0B9",
-"oG c #F4ECC5",
-"oH c #EFF7F9",
-"oI c #F2FAFC",
-"oJ c #F3FAFF",
-"oK c #F9FEFF",
-"oL c #FAFEFD",
-"oM c #FBFFFE",
-"oN c #F2F3F5",
-"oO c #A3A7D4",
-"oP c #626693",
-"oQ c #51678E",
-"oR c #6C82A9",
-"oS c #7EA9CB",
-"oT c #8BB6D8",
-"oU c #90C0E6",
-"oV c #98CCF4",
-"oW c #9ACEF6",
-"oX c #9DD1F9",
-"oY c #A0D3FE",
-"oZ c #9FD2FD",
-"o& c #303B41",
-"p c #A0ABB1",
-"p0 c #EAEAEA",
-"p1 c #A9B2B7",
-"p2 c #000308",
-"p3 c #9ED3FB",
-"p4 c #9FD5FB",
-"p5 c #99AEBF",
-"p6 c #132839",
-"p7 c #E7E5E6",
-"p8 c #040203",
-"p9 c #A0D4FC",
-"pa c #9FD2FF",
-"pb c #A5D3F5",
-"pc c #C3C3C3",
-"pd c #E9EBEA",
-"pe c #EAECEB",
-"pf c #EBEBED",
-"pg c #EAEAEC",
-"ph c #87949D",
-"pi c #24313A",
-"pj c #B3CFE5",
-"pk c #476379",
-"pl c #484848",
-"pm c #A1AAB1",
-"pn c #00060D",
-"po c #6B9BC3",
-"pp c #A3D3FB",
-"pq c #AAD1F0",
-"pr c #446B8A",
-"ps c #777777",
-"pt c #76838C",
-"pu c #4C5962",
-"pv c #090E12",
-"pw c #D3D8DC",
-"px c #ECECEC",
-"py c #A1A8AE",
-"pz c #333A40",
-"pA c #858F98",
-"pB c #101A23",
-"pC c #D8D8D8",
-"pD c #D6D6D6",
-"pE c #0C273C",
-"pF c #5B768B",
-"pG c #A1D4FF",
-"pH c #9DD2FC",
-"pI c #98C9F1",
-"pJ c #94C5ED",
-"pK c #91C1E7",
-"pL c #8BBBE1",
-"pM c #83A9DA",
-"pN c #7DA3D4",
-"pO c #879BE4",
-"pP c #97ABF4",
-"pQ c #BBD2FF",
-"pR c #9BAFCA",
-"pS c #7B8FAA",
-"pT c #B1B6BC",
-"pU c #C3C8CE",
-"pV c #CCCBD0",
-"pW c #CAC9CE",
-"pX c #C1C3C2",
-"pY c #B9BBBA",
-"pZ c #AEAFB1",
-"p& c #9C9D9F",
-"q c #778393",
-"q0 c #A8B4C4",
-"q1 c #DCEBFE",
-"q2 c #E4F0FE",
-"q3 c #E5F1FF",
-"q4 c #E8F2FC",
-"q5 c #E8F4FF",
-"q6 c #F4F6E1",
-"q7 c #F6F8E3",
-"q8 c #FFF8D1",
-"q9 c #F0F8FA",
-"qa c #F1F8FE",
-"qb c #F2F9FF",
-"qc c #F5FDFF",
-"qd c #D1D5FF",
-"qe c #8084B1",
-"qf c #546A91",
-"qg c #729DBF",
-"qh c #85B0D2",
-"qi c #8CBCE2",
-"qj c #92C2E8",
-"qk c #95C9F1",
-"ql c #9ED1FC",
-"qm c #3E494F",
-"qn c #8C979D",
-"qo c #343D42",
-"qp c #737C81",
-"qq c #9ED4FA",
-"qr c #8DA2B3",
-"qs c #1F3445",
-"qt c #E8E6E7",
-"qu c #141213",
-"qv c #8BBFE7",
-"qw c #9DD2FA",
-"qx c #A4D2F4",
-"qy c #3E6C8E",
-"qz c #585858",
-"qA c #E6E8E7",
-"qB c #E7E7E9",
-"qC c #CECED0",
-"qD c #05121B",
-"qE c #8D9AA3",
-"qF c #809CB2",
-"qG c #00192F",
-"qH c #D4D4D4",
-"qI c #D2D2D2",
-"qJ c #091219",
-"qK c #879097",
-"qL c #A2D2FA",
-"qM c #A9D0EF",
-"qN c #456C8B",
-"qO c #757575",
-"qP c #65727B",
-"qQ c #58656E",
-"qR c #51565A",
-"qS c #A4ABB1",
-"qT c #2E353B",
-"qU c #8ABFE7",
-"qV c #0F1922",
-"qW c #A6B0B9",
-"qX c #313131",
-"qY c #4A657A",
-"qZ c #B3CEE3",
-"q& c #9BD1FD",
-"r c #9BD1FF",
-"r0 c #9AD0FE",
-"r1 c #99D0F9",
-"r2 c #97CEF7",
-"r3 c #97CCF8",
-"r4 c #94C9F5",
-"r5 c #91C4EF",
-"r6 c #8EC1EC",
-"r7 c #8DBDE5",
-"r8 c #86B6DE",
-"r9 c #869DE9",
-"ra c #879EEA",
-"rb c #9BB7E6",
-"rc c #BFDBFF",
-"rd c #C7DFFB",
-"re c #9CB4D0",
-"rf c #96979B",
-"rg c #CBCCD0",
-"rh c #D0D0D0",
-"ri c #BBBBBB",
-"rj c #BFBFBF",
-"rk c #B7B7B5",
-"rl c #ACACAA",
-"rm c #929292",
-"rn c #7E7E7E",
-"ro c #85868A",
-"rp c #949599",
-"rq c #D8E5F6",
-"rr c #E1EEFF",
-"rs c #E4F0FC",
-"rt c #EAF4FF",
-"ru c #E9F6FF",
-"rv c #EAF7FF",
-"rw c #EBF8FF",
-"rx c #DCF0FF",
-"ry c #D3E7FF",
-"rz c #D5E7FF",
-"rA c #E1F3FF",
-"rB c #F0FAFF",
-"rC c #F3FDFF",
-"rD c #FAFCFF",
-"rE c #B1B3BF",
-"rF c #616CA2",
-"rG c #576298",
-"rH c #6185A5",
-"rI c #81A5C5",
-"rJ c #87B8E0",
-"rK c #8DBEE6",
-"rL c #92C5F0",
-"rM c #95C8F3",
-"rN c #96CCF8",
-"rO c #98CEFA",
-"rP c #47515B",
-"rQ c #7D8791",
-"rR c #E5E5E5",
-"rS c #BDBDBD",
-"rT c #000924",
-"rU c #ABCDE8",
-"rV c #9AD0FC",
-"rW c #9CD2FE",
-"rX c #6C7680",
-"rY c #505A64",
-"rZ c #E4E4E4",
-"r& c #161616",
-"s c #84B9E3",
-"s0 c #9CD1F9",
-"s1 c #A4CFF1",
-"s2 c #ABCEEC",
-"s3 c #AACDEB",
-"s4 c #9CD1FB",
-"s5 c #9FAFBE",
-"s6 c #000C1B",
-"s7 c #CBCBCD",
-"s8 c #E5E5E7",
-"s9 c #E0E4E7",
-"sa c #3B3F42",
-"sb c #3B698D",
-"sc c #A1CFF3",
-"sd c #373B3E",
-"se c #868A8D",
-"sf c #616161",
-"sg c #346286",
-"sh c #A2D0F4",
-"si c #9CD0FF",
-"sj c #9BCFFE",
-"sk c #AECCE6",
-"sl c #2C4A64",
-"sm c #34495A",
-"sn c #6E8394",
-"so c #98BBD7",
-"sp c #000723",
-"sq c #B2B2B0",
-"sr c #E5E5E3",
-"ss c #E5E3E4",
-"st c #E6E4E5",
-"su c #AAAFB5",
-"sv c #2C3137",
-"sw c #B3CCE0",
-"sx c #2A4357",
-"sy c #E1E1E3",
-"sz c #334A5C",
-"sA c #3B5264",
-"sB c #99CFFD",
-"sC c #98CFF8",
-"sD c #95CCF5",
-"sE c #96CBF7",
-"sF c #92C7F3",
-"sG c #90C3EE",
-"sH c #8CBFEA",
-"sI c #8ABAE2",
-"sJ c #83B3DB",
-"sK c #859CE8",
-"sL c #91A8F4",
-"sM c #B3CFFE",
-"sN c #B4CCE8",
-"sO c #829AB6",
-"sP c #AFB0B4",
-"sQ c #DADBDF",
-"sR c #C8C8C8",
-"sS c #B4B4B4",
-"sT c #AAAAA8",
-"sU c #A0A09E",
-"sV c #949494",
-"sW c #838383",
-"sX c #828387",
-"sY c #9D9EA2",
-"sZ c #D5E2F3",
-"s& c #E0EDFE",
-"t c #E5F1FD",
-"t0 c #E8F5FE",
-"t1 c #E7F4FD",
-"t2 c #E0EDFD",
-"t3 c #D8E5F5",
-"t4 c #CEE2FA",
-"t5 c #CFE3FB",
-"t6 c #D3E5FD",
-"t7 c #D2E4FC",
-"t8 c #E2ECF5",
-"t9 c #EFF9FF",
-"ta c #FBFDFF",
-"tb c #E2E4F0",
-"tc c #7F8AC0",
-"td c #586399",
-"te c #4B6F8F",
-"tf c #769ABA",
-"tg c #83B4DC",
-"th c #8ABBE3",
-"ti c #8FC2ED",
-"tj c #93C6F1",
-"tk c #94CAF6",
-"tl c #98CEFC",
-"tm c #99CFFB",
-"tn c #747E88",
-"to c #E2E2E2",
-"tp c #666666",
-"tq c #41637E",
-"tr c #A9CBE6",
-"ts c #29333D",
-"tt c #96A0AA",
-"tu c #0A0A0A",
-"tv c #8CC1EB",
-"tw c #9BD0FA",
-"tx c #9BD0F8",
-"ty c #7DB2DA",
-"tz c #5C87A9",
-"tA c #356082",
-"tB c #234664",
-"tC c #315472",
-"tD c #7DB2DC",
-"tE c #9ACFF9",
-"tF c #3E4E5D",
-"tG c #647483",
-"tH c #717578",
-"tI c #303437",
-"tJ c #81AFD3",
-"tK c #0F1316",
-"tL c #D7DBDE",
-"tM c #DADADA",
-"tN c #0D0D0D",
-"tO c #88B6DA",
-"tP c #A7C5DF",
-"tQ c #000923",
-"tR c #CBCBCB",
-"tS c #000D1E",
-"tT c #9EB3C4",
-"tU c #A8CBE7",
-"tV c #5E819D",
-"tW c #20201E",
-"tX c #D5D5D3",
-"tY c #E1DFE0",
-"tZ c #272C32",
-"t& c #556E82",
-"u c #253E52",
-"u0 c #5C5C5E",
-"u1 c #294052",
-"u2 c #B2C9DB",
-"u3 c #95CFFD",
-"u4 c #95CDFE",
-"u5 c #94CCFD",
-"u6 c #92CAFB",
-"u7 c #92C8F6",
-"u8 c #8EC4F2",
-"u9 c #8DC2EE",
-"ua c #88BDE9",
-"ub c #85B6DF",
-"uc c #7FB0D9",
-"ud c #839DE8",
-"ue c #8FA9F4",
-"uf c #B0D1FA",
-"ug c #B9DAFF",
-"uh c #AEBAC8",
-"ui c #8894A2",
-"uj c #C4C4C6",
-"uk c #BBBBBD",
-"ul c #B1B1B1",
-"um c #A8A8A8",
-"un c #9E9EA0",
-"uo c #939395",
-"up c #898989",
-"uq c #808080",
-"ur c #7E7F83",
-"us c #A8A9AD",
-"ut c #DDEAFA",
-"uu c #E1EEFE",
-"uv c #E4F2FF",
-"uw c #E5F3FF",
-"ux c #E6F4FF",
-"uy c #E3F4FF",
-"uz c #E1F2FF",
-"uA c #D5EDFF",
-"uB c #CDE5FF",
-"uC c #C7E0FF",
-"uD c #C8E1FF",
-"uE c #C9E0FF",
-"uF c #C8DFFF",
-"uG c #C3D3FF",
-"uH c #B2C2F3",
-"uI c #AAB8E7",
-"uJ c #C8D6FF",
-"uK c #F4FDFF",
-"uL c #FCFFFF",
-"uM c #F9FCFF",
-"uN c #A0ABD9",
-"uO c #616C9A",
-"uP c #4E678F",
-"uQ c #6C85AD",
-"uR c #7BACD4",
-"uS c #8BC0EC",
-"uT c #8FC4F0",
-"uU c #8FC8F5",
-"uV c #91CAF7",
-"uW c #94CCFB",
-"uX c #96CEFF",
-"uY c #94CEFE",
-"uZ c #95CFFF",
-"u& c #505C68",
-"v c #6B7783",
-"v0 c #DCDCDC",
-"v1 c #DEDCDD",
-"v2 c #DADBDD",
-"v3 c #1A1B1D",
-"v4 c #72A8D6",
-"v5 c #A1CCEF",
-"v6 c #6E99BC",
-"v7 c #D9D9D9",
-"v8 c #CFD0D4",
-"v9 c #010206",
-"va c #96CEFD",
-"vb c #95CDFC",
-"vc c #AFC8DE",
-"vd c #597288",
-"ve c #1F2324",
-"vf c #171B1C",
-"vg c #4E4E4E",
-"vh c #7A7A7A",
-"vi c #969696",
-"vj c #606060",
-"vk c #0B2A46",
-"vl c #A9C8E4",
-"vm c #A5C9E9",
-"vn c #698DAD",
-"vo c #1C1C1C",
-"vp c #DCDCDE",
-"vq c #DDDDDF",
-"vr c #9D9D9D",
-"vs c #000828",
-"vt c #8AAECE",
-"vu c #A4CBEC",
-"vv c #446B8C",
-"vw c #9FA6B0",
-"vx c #2B323C",
-"vy c #97CDF9",
-"vz c #5D646A",
-"vA c #4A5157",
-"vB c #828284",
-"vC c #1B4367",
-"vD c #A3CBEF",
-"vE c #94CEFC",
-"vF c #3A5065",
-"vG c #374D62",
-"vH c #DEDEDE",
-"vI c #DBDDDC",
-"vJ c #252C32",
-"vK c #76A2C5",
-"vL c #0E0E10",
-"vM c #C3C3C5",
-"vN c #687888",
-"vO c #1B2B3B",
-"vP c #8DC5F4",
-"vQ c #98CDFF",
-"vR c #96D0FE",
-"vS c #97CFFF",
-"vT c #93CDFB",
-"vU c #93CBFC",
-"vV c #91C9FA",
-"vW c #90C8F9",
-"vX c #90C6F4",
-"vY c #8DC3F1",
-"vZ c #8ABFEB",
-"v& c #85BAE6",
-"w c #83B4DD",
-"w0 c #7CADD6",
-"w1 c #87A1EC",
-"w2 c #AFD0F9",
-"w3 c #85919F",
-"w4 c #BABABA",
-"w5 c #B4B4B6",
-"w6 c #AFAFB1",
-"w7 c #A5A5A5",
-"w8 c #9B9B9B",
-"w9 c #8F8F91",
-"wa c #7D7D7D",
-"wb c #787878",
-"wc c #8C8D91",
-"wd c #C6C7CB",
-"we c #E2F0FD",
-"wf c #D2E3F5",
-"wg c #C6DEF8",
-"wh c #C5DEFD",
-"wi c #C6DFFE",
-"wj c #BED5F7",
-"wk c #ABC2E4",
-"wl c #8C9CCD",
-"wm c #6979AA",
-"wn c #5F6D9C",
-"wo c #8492C1",
-"wp c #BFC8D7",
-"wq c #E6EFFE",
-"wr c #F7FBFC",
-"ws c #FAFEFF",
-"wt c #FAFDFF",
-"wu c #F0F3FA",
-"wv c #C3CEFC",
-"ww c #737EAC",
-"wx c #506991",
-"wy c #5A739B",
-"wz c #73A4CC",
-"wA c #85B6DE",
-"wB c #87BCE8",
-"wC c #8CC5F2",
-"wD c #91C9F8",
-"wE c #92CAF9",
-"wF c #92CCFA",
-"wG c #93CDFD",
-"wH c #4E5A66",
-"wI c #D7D7D7",
-"wJ c #D9D7D8",
-"wK c #D8D6D7",
-"wL c #AFB0B2",
-"wM c #1B1C1E",
-"wN c #96CCFA",
-"wO c #A0CBEE",
-"wP c #0C375A",
-"wQ c #8F8F8F",
-"wR c #A9AAAE",
-"wS c #232428",
-"wT c #84BCEB",
-"wU c #1E374D",
-"wV c #263F55",
-"wW c #A3A7A8",
-"wX c #D5D9DA",
-"wY c #B2B2B2",
-"wZ c #001531",
-"w& c #A8C7E3",
-"x c #94B8D8",
-"x0 c #A1A1A1",
-"x1 c #D7D7D9",
-"x2 c #D8D8DA",
-"x3 c #0C0C0C",
-"x4 c #6B8FAF",
-"x5 c #A4C8E8",
-"x6 c #A2C9EA",
-"x7 c #0A3152",
-"x8 c #A2A2A2",
-"x9 c #787F89",
-"xa c #4C535D",
-"xb c #92CCFC",
-"xc c #95CBF7",
-"xd c #6AA0CC",
-"xe c #060D13",
-"xf c #BAC1C7",
-"xg c #18181A",
-"xh c #6C94B8",
-"xi c #A0C8EC",
-"xj c #AFC5DA",
-"xk c #1C3247",
-"xl c #686868",
-"xm c #D7D9D8",
-"xn c #D6D8D7",
-"xo c #9AA1A7",
-"xp c #2B3238",
-"xq c #9ECAED",
-"xr c #083457",
-"xs c #8B8B8D",
-"xt c #8D8D8F",
-"xu c #081828",
-"xv c #99A9B9",
-"xw c #96CBFD",
-"xx c #90CDFC",
-"xy c #91CBFD",
-"xz c #90CAFC",
-"xA c #8FC9F9",
-"xB c #8DC7F7",
-"xC c #8CC4F5",
-"xD c #89C1F2",
-"xE c #87BDEB",
-"xF c #82B8E6",
-"xG c #80B1DC",
-"xH c #7AABD6",
-"xI c #8298E4",
-"xJ c #899FEB",
-"xK c #ABCBFA",
-"xL c #B6D6FF",
-"xM c #B5C5D5",
-"xN c #8696A6",
-"xO c #A0A0A0",
-"xP c #A6A6A6",
-"xQ c #999999",
-"xR c #7B797A",
-"xS c #6B696A",
-"xT c #767678",
-"xU c #878789",
-"xV c #B2BCC5",
-"xW c #E1EBF4",
-"xX c #DEEEFE",
-"xY c #DFF1FF",
-"xZ c #D2EBFF",
-"x& c #CBE4FF",
-"y c #C1DDFF",
-"y0 c #C3DDFF",
-"y1 c #BCD0FF",
-"y2 c #A8BCEF",
-"y3 c #8E9DD8",
-"y4 c #6D7CB7",
-"y5 c #5C6D99",
-"y6 c #4E5F8B",
-"y7 c #506290",
-"y8 c #596B99",
-"y9 c #717DB7",
-"ya c #A7B3ED",
-"yb c #D6E4FF",
-"yc c #E8F6FF",
-"yd c #F2FCFF",
-"ye c #F0FCFF",
-"yf c #EEFAFF",
-"yg c #E1F4FF",
-"yh c #D9ECFD",
-"yi c #D5E4FF",
-"yj c #7D8CB3",
-"yk c #556795",
-"yl c #546694",
-"ym c #6B9CC4",
-"yn c #81B2DA",
-"yo c #84BAE9",
-"yp c #89BFEE",
-"yq c #8AC2F3",
-"yr c #8EC6F7",
-"ys c #8EC8FA",
-"yt c #8FC9FB",
-"yu c #8FCCFB",
-"yv c #92CCFE",
-"yw c #8FCDFC",
-"yx c #8ECCFB",
-"yy c #49565F",
-"yz c #6E7B84",
-"yA c #D3D3D3",
-"yB c #435362",
-"yC c #93CBFA",
-"yD c #5F686D",
-"yE c #353E43",
-"yF c #6D7B88",
-"yG c #404E5B",
-"yH c #AAC6DC",
-"yI c #1B374D",
-"yJ c #646464",
-"yK c #D3D3D5",
-"yL c #A7A7A9",
-"yM c #98999D",
-"yN c #CECFD3",
-"yO c #CDD1D4",
-"yP c #4B4F52",
-"yQ c #295071",
-"yR c #A1C8E9",
-"yS c #34393C",
-"yT c #676C6F",
-"yU c #D5D3D4",
-"yV c #B9B7B8",
-"yW c #001C35",
-"yX c #9FBBD0",
-"yY c #000B20",
-"yZ c #CECECE",
-"y& c #6F7983",
-"z c #8FCCF9",
-"z0 c #90CDFA",
-"z1 c #9AACBA",
-"z2 c #8F9190",
-"z3 c #D2D4D3",
-"z4 c #526574",
-"z5 c #314453",
-"z6 c #8FCDFE",
-"z7 c #8ECCFD",
-"z8 c #7CB6E6",
-"z9 c #102131",
-"za c #647585",
-"zb c #D4D4D6",
-"zc c #D5D5D5",
-"zd c #303940",
-"ze c #585F65",
-"zf c #3C4349",
-"zg c #9AA4AD",
-"zh c #00060F",
-"zi c #659DCC",
-"zj c #92CBFF",
-"zk c #8ECBFA",
-"zl c #8BC5F5",
-"zm c #8BC3F4",
-"zn c #87BFF0",
-"zo c #84BAE8",
-"zp c #80B6E4",
-"zq c #7FB0DB",
-"zr c #78A9D4",
-"zs c #8096E2",
-"zt c #879DE9",
-"zu c #A3C3F2",
-"zv c #B4D4FF",
-"zw c #CBDBEB",
-"zx c #A1B1C1",
-"zy c #959595",
-"zz c #747273",
-"zA c #787677",
-"zB c #DEE8F1",
-"zC c #E4EEF7",
-"zD c #DAEAFA",
-"zE c #CDDFF7",
-"zF c #C1DAF9",
-"zG c #BEDAFF",
-"zH c #BAD4F7",
-"zI c #A4BEE1",
-"zJ c #8CA0D3",
-"zK c #6E82B5",
-"zL c #5D6CA7",
-"zM c #51609B",
-"zN c #445581",
-"zO c #475987",
-"zP c #4B5D8B",
-"zQ c #58649E",
-"zR c #6470AA",
-"zS c #99A7C2",
-"zT c #C5D3EE",
-"zU c #E2ECF6",
-"zV c #E1EDF9",
-"zW c #DDE9F5",
-"zX c #D6E9FA",
-"zY c #CAD9FF",
-"zZ c #7584AB",
-"z& c #536593",
-"A c #699AC2",
-"A0 c #83B9E8",
-"A1 c #87BDEC",
-"A2 c #8BC5F7",
-"A3 c #8DC7F9",
-"A4 c #8DCAF9",
-"A5 c #8DCBFA",
-"A6 c #3F4C55",
-"A7 c #75828B",
-"A8 c #CFCFCF",
-"A9 c #283847",
-"Aa c #758594",
-"Ab c #6BA3D2",
-"Ac c #060F14",
-"Ad c #B0B9BE",
-"Ae c #354350",
-"Af c #6E7C89",
-"Ag c #637F95",
-"Ah c #1A364C",
-"Ai c #979799",
-"Aj c #030305",
-"Ak c #030408",
-"Al c #03070A",
-"Am c #282C2F",
-"An c #8AB1D2",
-"Ao c #214869",
-"Ap c #4B5053",
-"Aq c #C9CED1",
-"Ar c #B7B5B6",
-"As c #4E6E87",
-"At c #A4C4DD",
-"Au c #819DB2",
-"Av c #0D293E",
-"Aw c #828C96",
-"Ax c #37414B",
-"Ay c #8ECBF8",
-"Az c #90C8F7",
-"AA c #75ADDC",
-"AB c #132533",
-"AC c #697B89",
-"AD c #969897",
-"AE c #001221",
-"AF c #98ABBA",
-"AG c #8CCAFB",
-"AH c #8DCBFC",
-"AI c #90CAFA",
-"AJ c #93A4B4",
-"AK c #6C6C6E",
-"AL c #848D94",
-"AM c #363F46",
-"AN c #0B1218",
-"AO c #B5BCC2",
-"AP c #08121B",
-"AQ c #747E87",
-"AR c #90C9FE",
-"AS c #8DCBFE",
-"AT c #8CCAFD",
-"AU c #8BC8FE",
-"AV c #8AC7FD",
-"AW c #89C6FC",
-"AX c #87C4FA",
-"AY c #86C2F4",
-"AZ c #82BEF0",
-"A& c #82BAE9",
-"B c #7DB5E4",
-"B0 c #7AAEDD",
-"B1 c #74A8D7",
-"B2 c #7B96DD",
-"B3 c #839EE5",
-"B4 c #9DBCF2",
-"B5 c #B3D2FF",
-"B6 c #C4D8F3",
-"B7 c #AFB8C7",
-"B8 c #A0A9B8",
-"B9 c #9CA1A5",
-"Ba c #909599",
-"Bb c #8D9095",
-"Bc c #93969B",
-"Bd c #99A2A7",
-"Be c #B4BDC2",
-"Bf c #CDDAEA",
-"Bg c #DFECFC",
-"Bh c #DAEFFF",
-"Bi c #D3ECFF",
-"Bj c #CDE6FF",
-"Bk c #C4E2FF",
-"Bl c #BEDCFF",
-"Bm c #B8D8FF",
-"Bn c #BAD7FF",
-"Bo c #BACFFF",
-"Bp c #A2B7EE",
-"Bq c #8E9CD9",
-"Br c #7381BE",
-"Bs c #6072A0",
-"Bt c #526492",
-"Bu c #3E5B7B",
-"Bv c #3F5C7C",
-"Bw c #4E7596",
-"Bx c #547C9F",
-"By c #4D7598",
-"Bz c #476089",
-"BA c #506992",
-"BB c #5C68A2",
-"BC c #838FC9",
-"BD c #ADBEEA",
-"BE c #CCDDFF",
-"BF c #D2E5FF",
-"BG c #D1E4FF",
-"BH c #CCDFFF",
-"BI c #9EA9E1",
-"BJ c #6570A8",
-"BK c #4B648C",
-"BL c #679CC6",
-"BM c #7DBAE9",
-"BN c #81BEED",
-"BO c #87C1F3",
-"BP c #89C3F5",
-"BQ c #89C5FB",
-"BR c #8AC6FC",
-"BS c #8CC9FF",
-"BT c #323941",
-"BU c #888F97",
-"BV c #CACACC",
-"BW c #CACACA",
-"BX c #C9C9C9",
-"BY c #C0C0C0",
-"BZ c #000A29",
-"B& c #97B8D7",
-"C c #8DC9FF",
-"C0 c #A8C2D9",
-"C1 c #142E45",
-"C2 c #828483",
-"C3 c #C9CBCA",
-"C4 c #C8CAC9",
-"C5 c #C7C9C8",
-"C6 c #000F2B",
-"C7 c #90B2CE",
-"C8 c #394249",
-"C9 c #778087",
-"Ca c #223343",
-"Cb c #728393",
-"Cc c #94C7F2",
-"Cd c #83B6E1",
-"Ce c #8BAAC7",
-"Cf c #83A2BF",
-"Cg c #292C31",
-"Ch c #4E5156",
-"Ci c #C7C7C7",
-"Cj c #C9C9CB",
-"Ck c #ABABAB",
-"Cl c #001F3B",
-"Cm c #496884",
-"Cn c #8BC9FC",
-"Co c #7B95A6",
-"Cp c #183243",
-"Cq c #B4B5B7",
-"Cr c #0E0F11",
-"Cs c #91C7F5",
-"Ct c #00040E",
-"Cu c #78797B",
-"Cv c #C8C9CB",
-"Cw c #A2ABB2",
-"Cx c #060F16",
-"Cy c #568EBF",
-"Cz c #8FC7F8",
-"CA c #8DC9FB",
-"CB c #74B0E2",
-"CC c #122335",
-"CD c #5D6E80",
-"CE c #7C8083",
-"CF c #25292C",
-"CG c #858688",
-"CH c #B8BDC3",
-"CI c #1C2127",
-"CJ c #3B719F",
-"CK c #8DC9FD",
-"CL c #88C5FB",
-"CM c #80B8E7",
-"CN c #7BAFDE",
-"CO c #7792D9",
-"CP c #819CE3",
-"CQ c #94B3E9",
-"CR c #B2D1FF",
-"CS c #CBDFFA",
-"CT c #D1E5FF",
-"CU c #D8E1F0",
-"CV c #CDD6E5",
-"CW c #C8CDD1",
-"CX c #C3C8CC",
-"CY c #C6C9CE",
-"CZ c #CFD2D7",
-"C& c #D5DEE3",
-"D c #E2EBF0",
-"D0 c #DEEBFB",
-"D1 c #D2E7FA",
-"D2 c #CDE2F5",
-"D3 c #C3DCFA",
-"D4 c #BED7F5",
-"D5 c #B7D5F9",
-"D6 c #B6D6FD",
-"D7 c #B7D7FE",
-"D8 c #AFCCF6",
-"D9 c #9FBCE6",
-"Da c #7287BE",
-"Db c #6472AF",
-"Dc c #54629F",
-"Dd c #455785",
-"De c #465886",
-"Df c #4D6A8A",
-"Dg c #5A7797",
-"Dh c #5F86A7",
-"Di c #668DAE",
-"Dj c #6991B4",
-"Dk c #668EB1",
-"Dl c #657EA7",
-"Dm c #4A638C",
-"Dn c #54609A",
-"Do c #6C7DA9",
-"Dp c #95A6D2",
-"Dq c #ADC0E0",
-"Dr c #B0C3E3",
-"Ds c #AABDDE",
-"Dt c #92A5C6",
-"Du c #6B76AE",
-"Dv c #57629A",
-"Dw c #455E86",
-"Dx c #5D769E",
-"Dy c #6DA2CC",
-"Dz c #7FB4DE",
-"DA c #7EBBEA",
-"DB c #86C0F2",
-"DC c #1E252D",
-"DD c #99A0A8",
-"DE c #153655",
-"DF c #A1C2E1",
-"DG c #8BC9FA",
-"DH c #8CC8FE",
-"DI c #8AC8FB",
-"DJ c #486279",
-"DK c #2B455C",
-"DL c #C4C6C5",
-"DM c #C2C4C3",
-"DN c #153753",
-"DO c #A1C3DF",
-"DP c #1F282F",
-"DQ c #929BA2",
-"DR c #304151",
-"DS c #4C5D6D",
-"DT c #6598C3",
-"DU c #477AA5",
-"DV c #2C4B68",
-"DW c #00112E",
-"DX c #75787D",
-"DY c #C0C3C8",
-"DZ c #C5C5C7",
-"D& c #909090",
-"E c #0E0E0E",
-"E0 c #4E6D89",
-"E1 c #A3C2DE",
-"E2 c #89A3B4",
-"E3 c #031D2E",
-"E4 c #C3C4C6",
-"E5 c #303133",
-"E6 c #4F87B6",
-"E7 c #8EC6F5",
-"E8 c #366C9A",
-"E9 c #06101A",
-"Ea c #858F99",
-"Eb c #C2C3C5",
-"Ec c #A6A7A9",
-"Ed c #0E171E",
-"Ee c #636C73",
-"Ef c #8CC8FA",
-"Eg c #93A4B6",
-"Eh c #091A2C",
-"Ei c #707477",
-"Ej c #BFC0C2",
-"Ek c #31363C",
-"El c #4C5157",
-"Em c #8CC8FC",
-"En c #85C6FC",
-"Eo c #86C5FB",
-"Ep c #85C4FA",
-"Eq c #84C3F9",
-"Er c #84C0F6",
-"Es c #81BDF3",
-"Et c #7CB8EC",
-"Eu c #79B5E9",
-"Ev c #77AFE0",
-"Ew c #70A8D9",
-"Ex c #7594D4",
-"Ey c #7D9CDC",
-"Ez c #8CAAE6",
-"EA c #B1CFFF",
-"EB c #C6DFFD",
-"EC c #CCE5FF",
-"ED c #D0E6FE",
-"EE c #D2E8FF",
-"EF c #D5EAFF",
-"EG c #D7ECFF",
-"EH c #D8EAFE",
-"EI c #D3EBFF",
-"EJ c #CAE2FE",
-"EK c #B7D9FF",
-"EL c #B3D5FF",
-"EM c #B0D2FF",
-"EN c #B1D3FF",
-"EO c #B4D3FF",
-"EP c #AEC3FF",
-"EQ c #95AAE9",
-"ER c #8496D6",
-"ES c #7587C7",
-"ET c #667AAC",
-"EU c #596D9F",
-"EV c #3E5F80",
-"EW c #3C5D7E",
-"EX c #436E91",
-"EY c #517C9F",
-"EZ c #5889B2",
-"E& c #6394BD",
-"F c #659AC6",
-"F0 c #699ECA",
-"F1 c #689DC9",
-"F2 c #6497C2",
-"F3 c #5C8FBA",
-"F4 c #4D739A",
-"F5 c #41678E",
-"F6 c #536498",
-"F7 c #5C6DA1",
-"F8 c #6B7AB1",
-"F9 c #6E7DB4",
-"Fa c #6979AD",
-"Fb c #5B6B9F",
-"Fc c #4F658C",
-"Fd c #435980",
-"Fe c #436F96",
-"Ff c #618DB4",
-"Fg c #6FA9DB",
-"Fh c #7BB5E7",
-"Fi c #7CB9EF",
-"Fj c #7FBCF2",
-"Fk c #7FC0F6",
-"Fl c #82C3F9",
-"Fm c #84C5FB",
-"Fn c #87C6FC",
-"Fo c #87C5F8",
-"Fp c #88C6F9",
-"Fq c #010101",
-"Fr c #B3B3B3",
-"Fs c #505050",
-"Ft c #366A99",
-"Fu c #8FC3F2",
-"Fv c #86C7FD",
-"Fw c #8BC3F2",
-"Fx c #7AB2E1",
-"Fy c #050706",
-"Fz c #A7A9A8",
-"FA c #373737",
-"FB c #407AAA",
-"FC c #1C252C",
-"FD c #8A939A",
-"FE c #BCBEBD",
-"FF c #5B5B5B",
-"FG c #3B3B3B",
-"FH c #4F4F4F",
-"FI c #B0B0B0",
-"FJ c #BEBEC0",
-"FK c #BDBDBF",
-"FL c #B5BAC0",
-"FM c #575C62",
-"FN c #000A2C",
-"FO c #5A85A7",
-"FP c #001438",
-"FQ c #A2A2A4",
-"FR c #BEBEBC",
-"FS c #91918F",
-"FT c #00040D",
-"FU c #77818A",
-"FV c #7C8FA0",
-"FW c #4E6172",
-"FX c #17181A",
-"FY c #3F4042",
-"FZ c #839099",
-"F& c #3870A1",
-"G c #85C7FB",
-"G0 c #88C5FC",
-"G1 c #89C6FD",
-"G2 c #619FD2",
-"G3 c #88929B",
-"G4 c #BEBCBD",
-"G5 c #BFBDBE",
-"G6 c #AEAEAE",
-"G7 c #0D426E",
-"G8 c #85C6FE",
-"G9 c #82C1F7",
-"Ga c #83BFF5",
-"Gb c #80BCF2",
-"Gc c #71A9DA",
-"Gd c #6A89C9",
-"Ge c #7B9ADA",
-"Gf c #86A4E0",
-"Gg c #ABC9FF",
-"Gh c #C1DAF8",
-"Gi c #CFE5FD",
-"Gj c #D1E7FF",
-"Gk c #D3E8FD",
-"Gl c #D8E9FD",
-"Gm c #D7E8FC",
-"Gn c #D2EAFF",
-"Go c #C0D8F4",
-"Gp c #AED0FD",
-"Gq c #AFD1FF",
-"Gr c #ADCFFD",
-"Gs c #9FBEED",
-"Gt c #87A6D5",
-"Gu c #7E93D2",
-"Gv c #6E83C2",
-"Gw c #6779B9",
-"Gx c #596BAB",
-"Gy c #465A8C",
-"Gz c #435789",
-"GA c #496A8B",
-"GB c #58799A",
-"GC c #608BAE",
-"GD c #6A95B8",
-"GE c #6B9CC5",
-"GF c #6FA0C9",
-"GG c #71A6D2",
-"GH c #70A5D1",
-"GI c #6EA1CC",
-"GJ c #6B9EC9",
-"GK c #6F95BC",
-"GL c #5D83AA",
-"GM c #526397",
-"GN c #516296",
-"GO c #516097",
-"GP c #505F96",
-"GQ c #506094",
-"GR c #48588C",
-"GS c #455B82",
-"GT c #5C88AF",
-"GU c #739FC6",
-"GV c #76B0E2",
-"GW c #7DB7E9",
-"GX c #7DBAF0",
-"GY c #80BDF3",
-"GZ c #80C1F7",
-"G& c #66A4D7",
-"H c #B9B9B9",
-"H0 c #B7B9B8",
-"H1 c #B7B7B7",
-"H2 c #669AC9",
-"H3 c #8EC2F1",
-"H4 c #28608F",
-"H5 c #505251",
-"H6 c #86C0F0",
-"H7 c #8AC4F4",
-"H8 c #384148",
-"H9 c #626B72",
-"Ha c #B6B8B7",
-"Hb c #B9B9BB",
-"Hc c #B8B8BA",
-"Hd c #878787",
-"He c #191E24",
-"Hf c #353A40",
-"Hg c #7DA8CA",
-"Hh c #96C1E3",
-"Hi c #83C4FA",
-"Hj c #98C0E4",
-"Hk c #325A7E",
-"Hl c #404042",
-"Hm c #B8B8B6",
-"Hn c #7E8891",
-"Ho c #313B44",
-"Hp c #233647",
-"Hq c #495C6D",
-"Hr c #999A9C",
-"Hs c #B7B8BA",
-"Ht c #555555",
-"Hu c #00050E",
-"Hv c #6D7A83",
-"Hw c #83C5F9",
-"Hx c #84C6FA",
-"Hy c #87C4FB",
-"Hz c #86C4F7",
-"HA c #727C85",
-"HB c #0A141D",
-"HC c #B5B5B5",
-"HD c #81B6E2",
-"HE c #84C5FD",
-"HF c #81C4F9",
-"HG c #82C3FB",
-"HH c #81C2FA",
-"HI c #7FC2F9",
-"HJ c #7CBFF6",
-"HK c #80BFF5",
-"HL c #7DBCF2",
-"HM c #77B4EA",
-"HN c #75AFE1",
-"HO c #6A91CA",
-"HP c #7198D1",
-"HQ c #83A0E2",
-"HR c #A4C1FF",
-"HS c #BBD8FA",
-"HT c #C9E6FF",
-"HU c #D1E5FE",
-"HV c #D2E6FF",
-"HW c #D9EAFE",
-"HX c #DAEBFF",
-"HY c #BBD4F3",
-"HZ c #AECDFF",
-"H& c #A8C7FD",
-"I c #9AADF1",
-"I0 c #8699DD",
-"I1 c #788AC8",
-"I2 c #6D7FBD",
-"I3 c #657AA9",
-"I4 c #526796",
-"I5 c #3A5D7D",
-"I6 c #3E6181",
-"I7 c #517DA4",
-"I8 c #578CB8",
-"I9 c #6297C3",
-"Ia c #68A0D1",
-"Ib c #6DA5D6",
-"Ic c #70AADC",
-"Id c #72ACDE",
-"Ie c #71ADE1",
-"If c #71ADDF",
-"Ig c #6DA5D4",
-"Ih c #69A1D0",
-"Ii c #6095C1",
-"Ij c #5186B2",
-"Ik c #4B789F",
-"Il c #46739A",
-"Im c #5083AE",
-"In c #5D90BB",
-"Io c #67A0D5",
-"Ip c #72ABE0",
-"Iq c #7AB7ED",
-"Ir c #7CBBF1",
-"Is c #7EBDF3",
-"It c #7EBFF7",
-"Iu c #7FC0F8",
-"Iv c #80C1F9",
-"Iw c #81C4FB",
-"Ix c #92BFE6",
-"Iy c #3E6B92",
-"Iz c #484A49",
-"IA c #B1B3B2",
-"IB c #B0B2B1",
-"IC c #949BA1",
-"ID c #9DBBD5",
-"IE c #ACB0AF",
-"IF c #9CA09F",
-"IG c #888F95",
-"IH c #798086",
-"II c #13334C",
-"IJ c #476780",
-"IK c #001C38",
-"IL c #A3A3A3",
-"IM c #B3B1B4",
-"IN c #888888",
-"IO c #001C32",
-"IP c #407CAE",
-"IQ c #85C1F3",
-"IR c #7BBCF4",
-"IS c #000515",
-"IT c #4D5E6E",
-"IU c #AAAFB2",
-"IV c #696E71",
-"IW c #20425E",
-"IX c #6CABE1",
-"IY c #81C2F8",
-"IZ c #84C2FB",
-"I& c #83C1FA",
-"J c #88C2F2",
-"J0 c #255F8F",
-"J1 c #323637",
-"J2 c #AEB2B3",
-"J3 c #000F30",
-"J4 c #6E95B6",
-"J5 c #83C4FC",
-"J6 c #7FC4FB",
-"J7 c #7FC2F7",
-"J8 c #7EC1F8",
-"J9 c #7DC0F7",
-"Ja c #7FBEF4",
-"Jb c #7BB8EE",
-"Jc c #78B5EB",
-"Jd c #6E95CE",
-"Je c #6D94CD",
-"Jf c #7F9CDE",
-"Jg c #99B6F8",
-"Jh c #B8D5F7",
-"Ji c #C7E4FF",
-"Jj c #D1EAFF",
-"Jk c #B7D0EF",
-"Jl c #7897CD",
-"Jm c #7487CB",
-"Jn c #6D80C4",
-"Jo c #6072B0",
-"Jp c #4C5E9C",
-"Jq c #3D5281",
-"Jr c #445988",
-"Js c #4A6D8D",
-"Jt c #597C9C",
-"Ju c #5E8AB1",
-"Jv c #6A96BD",
-"Jw c #6A9FCB",
-"Jx c #6FA4D0",
-"Jy c #73ABDC",
-"Jz c #74AEE0",
-"JA c #77B1E3",
-"JB c #76B2E6",
-"JC c #76B2E4",
-"JD c #75B1E3",
-"JE c #74ACDB",
-"JF c #72AAD9",
-"JG c #6CA1CD",
-"JH c #6C99C0",
-"JI c #6996BD",
-"JJ c #6895BC",
-"JK c #6A97BE",
-"JL c #6A9DC8",
-"JM c #71A4CF",
-"JN c #77B0E5",
-"JO c #90BDE4",
-"JP c #002B52",
-"JQ c #818382",
-"JR c #AAACAB",
-"JS c #A9ABAA",
-"JT c #60676D",
-"JU c #7694AE",
-"JV c #000D27",
-"JW c #1F1F1F",
-"JX c #0F0F0F",
-"JY c #000201",
-"JZ c #090D0C",
-"J& c #171E24",
-"K c #282F35",
-"K0 c #25455E",
-"K1 c #9BBBD4",
-"K2 c #30536F",
-"K3 c #151515",
-"K4 c #6A6A6A",
-"K5 c #9A9A9A",
-"K6 c #ACAAAD",
-"K7 c #9E9C9F",
-"K8 c #232323",
-"K9 c #4E6A80",
-"Ka c #9EBAD0",
-"Kb c #84C0F2",
-"Kc c #8C9DAD",
-"Kd c #152636",
-"Ke c #333333",
-"Kf c #ABADAC",
-"Kg c #0F1417",
-"Kh c #2A2F32",
-"Ki c #6385A1",
-"Kj c #99BBD7",
-"Kk c #83C2F8",
-"Kl c #82C0F9",
-"Km c #85BFEF",
-"Kn c #202425",
-"Ko c #6D7172",
-"Kp c #A4A4A4",
-"Kq c #1D1D1D",
-"Kr c #4B7293",
-"Ks c #96BDDE",
-"Kt c #7DC2F9",
-"Ku c #7AC1F9",
-"Kv c #7BC0FB",
-"Kw c #79BEF9",
-"Kx c #7BC0F9",
-"Ky c #79BEF7",
-"Kz c #7ABCF6",
-"KA c #78BAF4",
-"KB c #76B9EE",
-"KC c #72B5EA",
-"KD c #71B0E5",
-"KE c #6BAADF",
-"KF c #689ACD",
-"KG c #6193C6",
-"KH c #8197E0",
-"KI c #94AAF3",
-"KJ c #B5D2FA",
-"KK c #C2DFFF",
-"KL c #D4E9FE",
-"KM c #D6EBFF",
-"KN c #CFE9FF",
-"KO c #AFC9EE",
-"KP c #889BDD",
-"KQ c #6B7EC0",
-"KR c #5C739C",
-"KS c #445B84",
-"KT c #335777",
-"KU c #3B5F7F",
-"KV c #3F7098",
-"KW c #4D7EA6",
-"KX c #558BB9",
-"KY c #6096C4",
-"KZ c #649ECE",
-"K& c #69A3D3",
-"L c #6AA9DC",
-"L0 c #6BAADD",
-"L1 c #6FAEE4",
-"L2 c #71B0E6",
-"L3 c #71B2E8",
-"L4 c #74B5EB",
-"L5 c #75B6EE",
-"L6 c #73B6ED",
-"L7 c #74B7EE",
-"L8 c #74B5ED",
-"L9 c #72B3EB",
-"La c #70B1E7",
-"Lb c #6FB0E6",
-"Lc c #6FAEE3",
-"Ld c #6CABE0",
-"Le c #6AA7DD",
-"Lf c #6BA8DE",
-"Lg c #70AFE4",
-"Lh c #74B3E9",
-"Li c #74B6F0",
-"Lj c #76B8F2",
-"Lk c #77B9F3",
-"Ll c #78BFF7",
-"Lm c #79C0F8",
-"Ln c #7ABFFA",
-"Lo c #7AC1F7",
-"Lp c #64839F",
-"Lq c #001632",
-"Lr c #68707B",
-"Ls c #656D78",
-"Lt c #576572",
-"Lu c #485663",
-"Lv c #2C4355",
-"Lw c #102739",
-"Lx c #001034",
-"Ly c #4D7B9F",
-"Lz c #7DBFF3",
-"LA c #4587BB",
-"LB c #5897CC",
-"LC c #69A8DD",
-"LD c #74B9F2",
-"LE c #4A7FA9",
-"LF c #063B65",
-"LG c #000F29",
-"LH c #00102A",
-"LI c #001A30",
-"LJ c #08243A",
-"LK c #052137",
-"LL c #000C26",
-"LM c #00284B",
-"LN c #123E61",
-"LO c #4483B8",
-"LP c #80BFF4",
-"LQ c #7ABFF8",
-"LR c #7AC0FB",
-"LS c #78BDF6",
-"LT c #336183",
-"LU c #081D30",
-"LV c #33485B",
-"LW c #616870",
-"LX c #747B83",
-"LY c #737C83",
-"LZ c #384F5F",
-"L& c #0B2232",
-"M c #00082B",
-"M0 c #20486B",
-"M1 c #67ACE3",
-"M2 c #7BC0F7",
-"M3 c #79C2F9",
-"M4 c #78C1F8",
-"M5 c #82BEF2",
-"M6 c #272A2F",
-"M7 c #64676C",
-"M8 c #3C5162",
-"M9 c #7BBFFC",
-"Ma c #73B6EB",
-"Mb c #73B2E7",
-"Mc c #6C9ED1",
-"Md c #6092C5",
-"Me c #7E94DD",
-"Mf c #8CA2EB",
-"Mg c #B3D0F8",
-"Mh c #BFDCFF",
-"Mi c #DAECFF",
-"Mj c #D0EAFF",
-"Mk c #AAC4E9",
-"Ml c #7D90D2",
-"Mm c #576AAC",
-"Mn c #395079",
-"Mo c #425982",
-"Mp c #486C8C",
-"Mq c #567A9A",
-"Mr c #598AB2",
-"Ms c #6394BC",
-"Mt c #659BC9",
-"Mu c #6AA0CE",
-"Mv c #6BA5D5",
-"Mw c #6FA9D9",
-"Mx c #6EADE0",
-"My c #70AFE2",
-"Mz c #73B2E8",
-"MA c #75B6EC",
-"MB c #76B7ED",
-"MC c #77B8F0",
-"MD c #75B8EF",
-"ME c #76B9F0",
-"MF c #76B7EF",
-"MG c #73B4EA",
-"MH c #72B3E9",
-"MI c #72B1E6",
-"MJ c #6FAEE1",
-"MK c #70ADE3",
-"ML c #71AEE4",
-"MM c #77B6EC",
-"MN c #79BBF5",
-"MO c #7BC2F8",
-"MP c #85A4C0",
-"MQ c #153450",
-"MR c #272F3A",
-"MS c #2F3742",
-"MT c #364451",
-"MU c #44525F",
-"MV c #546B7D",
-"MW c #71889A",
-"MX c #80AED2",
-"MY c #8EBCE0",
-"MZ c #7EC0F4",
-"M& c #88BDE7",
-"N c #96BAD4",
-"N0 c #85A9C3",
-"N1 c #7B97AD",
-"N2 c #7793A9",
-"N3 c #7894AA",
-"N4 c #87ABC5",
-"N5 c #97BBD5",
-"N6 c #7FBEF3",
-"N7 c #8EBCDE",
-"N8 c #74899C",
-"N9 c #495E71",
-"Na c #313840",
-"Nb c #1D242C",
-"Nc c #1D262D",
-"Nd c #2F383F",
-"Ne c #435A6A",
-"Nf c #6D8494",
-"Ng c #92BADD",
-"Nh c #7ABFF6",
-"Ni c #205C90",
-"Nj c #2E3136",
-"Nk c #979A9F",
-"Nl c #000617",
-"Nm c #889DAE",
-"Nn c #76BEF9",
-"No c #77BFFA",
-"Np c #75BDF8",
-"Nq c #76BAF7",
-"Nr c #74B8F5",
-"Ns c #72B9F1",
-"Nt c #6FB6EE",
-"Nu c #6EB1E8",
-"Nv c #69ACE3",
-"Nw c #68A2D2",
-"Nx c #4F89B9",
-"Ny c #798FD8",
-"Nz c #869CE5",
-"NA c #A3C3F4",
-"NB c #D6E8FE",
-"NC c #D9E9FF",
-"ND c #CEEAFF",
-"NE c #A7C3EA",
-"NF c #7B8FCE",
-"NG c #586CAB",
-"NH c #365C80",
-"NI c #486E92",
-"NJ c #4F84B0",
-"NK c #598EBA",
-"NL c #5C98CA",
-"NM c #619DCF",
-"NN c #63A2D7",
-"NO c #66A5DA",
-"NP c #67AADF",
-"NQ c #6AADE2",
-"NR c #6CB1E8",
-"NS c #6EB3EA",
-"NT c #70B5EE",
-"NU c #71B6EF",
-"NV c #71B9F4",
-"NW c #72BAF5",
-"NX c #73B9F5",
-"NY c #74BAF6",
-"NZ c #73BBF5",
-"N& c #72BAF4",
-"O c #74B9F4",
-"O0 c #73B8F3",
-"O1 c #71B8F0",
-"O2 c #70B7EF",
-"O3 c #6EB3EC",
-"O4 c #6CB3E9",
-"O5 c #6CB1EA",
-"O6 c #6DB2EB",
-"O7 c #6FB4ED",
-"O8 c #73BBF6",
-"O9 c #75BBF7",
-"Oa c #76BDFB",
-"Ob c #77BDF9",
-"Oc c #75BDF7",
-"Od c #76BEF8",
-"Oe c #73BEF8",
-"Of c #74BFF9",
-"Og c #77A5C7",
-"Oh c #4E5B64",
-"Oi c #1C2932",
-"Oj c #0A1117",
-"Ok c #2A3137",
-"Ol c #5E87A7",
-"Om c #8FB8D8",
-"On c #7ABBF3",
-"Oo c #5F6972",
-"Op c #0E1821",
-"Oq c #939393",
-"Or c #6F7982",
-"Os c #000912",
-"Ot c #4B8CC2",
-"Ou c #7ABBF1",
-"Ov c #74BCF7",
-"Ow c #75B9F6",
-"Ox c #73B7F4",
-"Oy c #6DB4EC",
-"Oz c #538DBD",
-"OA c #7288D1",
-"OB c #8298E1",
-"OC c #99B9EA",
-"OD c #B5D5FF",
-"OE c #CFE3FC",
-"OF c #D4E8FF",
-"OG c #C6E2FF",
-"OH c #A6C2E9",
-"OI c #768AC9",
-"OJ c #576BAA",
-"OK c #395F83",
-"OL c #50769A",
-"OM c #558AB6",
-"ON c #5E93BF",
-"OO c #5F9BCD",
-"OP c #64A0D2",
-"OQ c #6DB0E5",
-"OR c #6DB2E9",
-"OS c #70B8F3",
-"OT c #72B8F4",
-"OU c #71B9F3",
-"OV c #72B7F2",
-"OW c #6DB4EA",
-"OX c #74BBF9",
-"OY c #74BCF6",
-"OZ c #72BDF7",
-"O& c #4A789A",
-"P c #001133",
-"P0 c #323F48",
-"P1 c #767D83",
-"P2 c #51585E",
-"P3 c #001434",
-"P4 c #3E6787",
-"P5 c #79BAF2",
-"P6 c #3E7FB7",
-"P7 c #030D16",
-"P8 c #6D7780",
-"P9 c #061019",
-"Pa c #626C75",
-"Pb c #78B9EF",
-"Pc c #6DBCF7",
-"Pd c #70BAF9",
-"Pe c #6FBBF7",
-"Pf c #6FB9F8",
-"Pg c #6EB8F7",
-"Ph c #6DB7F4",
-"Pi c #6AB4F1",
-"Pj c #6AB0EB",
-"Pk c #62A8E3",
-"Pl c #64A3D6",
-"Pm c #5594C7",
-"Pn c #6685C6",
-"Po c #7897D8",
-"Pp c #8FACE6",
-"Pq c #B2CFFF",
-"Pr c #D1E9FF",
-"Ps c #C3E3FF",
-"Pt c #A0C0E9",
-"Pu c #7080BC",
-"Pv c #4E5E9A",
-"Pw c #356289",
-"Px c #4F7CA3",
-"Py c #538FC1",
-"Pz c #5FA0D8",
-"PA c #63A4DC",
-"PB c #63ACE3",
-"PC c #66AFE6",
-"PD c #6AB0EE",
-"PE c #6BB1EF",
-"PF c #6AB5EF",
-"PG c #6BB6F0",
-"PH c #6CB6F3",
-"PI c #6EB8F5",
-"PJ c #6EBAF6",
-"PK c #6AB6F0",
-"PL c #69B5EF",
-"PM c #6CB3F1",
-"PN c #6CB6F5",
-"PO c #6DB7F6",
-"PP c #6FB9F6",
-"PQ c #70BCF8",
-"PR c #72B9F9",
-"PS c #71BBF8",
-"PT c #71BBFA",
-"PU c #6EBAF4",
-"PV c #70BAF7",
-"PW c #71B8F8",
-"PX c #76B8EC",
-"PY c #6DAFE3",
-"PZ c #656565",
-"P& c #6D6D6D",
-"Q c #7F7F7F",
-"Q0 c #6A6E6F",
-"Q1 c #000405",
-"Q2 c #6C7A87",
-"Q3 c #000A17",
-"Q4 c #646665",
-"Q5 c #7E807F",
-"Q6 c #6E777E",
-"Q7 c #0C151C",
-"Q8 c #25689D",
-"Q9 c #75B8ED",
-"Qa c #6FBBF9",
-"Qb c #6BBAF5",
-"Qc c #6DB9F5",
-"Qd c #69B3F0",
-"Qe c #65ABE6",
-"Qf c #5998CB",
-"Qg c #5E7DBE",
-"Qh c #7392D3",
-"Qi c #86A3DD",
-"Qj c #AAC7FF",
-"Qk c #C4DCF8",
-"Ql c #D0E8FF",
-"Qm c #BEDEFF",
-"Qn c #9FBFE8",
-"Qo c #6F7FBB",
-"Qp c #4B5B97",
-"Qq c #38658C",
-"Qr c #5380A7",
-"Qs c #5692C4",
-"Qt c #5E9ACC",
-"Qu c #61A2DA",
-"Qv c #66A7DF",
-"Qw c #64ADE4",
-"Qx c #67B0E7",
-"Qy c #6CB2F0",
-"Qz c #6CB7F1",
-"QA c #6BB5F2",
-"QB c #6CB8F4",
-"QC c #6BB7F1",
-"QD c #6DB4F2",
-"QE c #6FB6F4",
-"QF c #70B7F7",
-"QG c #6DB9F3",
-"QH c #6AB9F4",
-"QI c #75B7EB",
-"QJ c #1F6195",
-"QK c #2F2F2F",
-"QL c #303030",
-"QM c #505455",
-"QN c #15191A",
-"QO c #515F6C",
-"QP c #757776",
-"QQ c #6F7170",
-"QR c #111A21",
-"QS c #464F56",
-"QT c #74B7EC",
-"QU c #6DB9F7",
-"QV c #6CB8F6",
-"QW c #69AFEB",
-"QX c #65ABE7",
-"QY c #62A5DC",
-"QZ c #599CD3",
-"Q& c #537AB3",
-"R c #668DC6",
-"R0 c #829BDE",
-"R1 c #A1BAFD",
-"R2 c #BED8FB",
-"R3 c #CCE6FF",
-"R4 c #98B8EB",
-"R5 c #6C7FB9",
-"R6 c #465993",
-"R7 c #396A93",
-"R8 c #5485AE",
-"R9 c #5F9ED1",
-"Ra c #62A4E0",
-"Rb c #67A9E5",
-"Rc c #64AEEB",
-"Rd c #67B1EE",
-"Re c #6BB7F5",
-"Rf c #6DB8F9",
-"Rg c #6BB9F7",
-"Rh c #8CB0D0",
-"Ri c #001838",
-"Rj c #626463",
-"Rk c #090A0C",
-"Rl c #636466",
-"Rm c #64696F",
-"Rn c #3F444A",
-"Ro c #040605",
-"Rp c #080A09",
-"Rq c #5E5E5E",
-"Rr c #767676",
-"Rs c #6A7378",
-"Rt c #141D22",
-"Ru c #13548A",
-"Rv c #6EBAF8",
-"Rw c #66ACE8",
-"Rx c #63A6DD",
-"Ry c #5DA0D7",
-"Rz c #5D84BD",
-"RA c #5F86BF",
-"RB c #7B94D7",
-"RC c #95AEF1",
-"RD c #B8D2F5",
-"RE c #C8E2FF",
-"RF c #B0D0FF",
-"RG c #90B0E3",
-"RH c #687BB5",
-"RI c #3C6D96",
-"RJ c #5788B1",
-"RK c #5A99CC",
-"RL c #61A0D3",
-"RM c #65A7E3",
-"RN c #69ABE7",
-"RO c #66B0ED",
-"RP c #7498B8",
-"RQ c #001232",
-"RR c #767877",
-"RS c #101113",
-"RT c #0F1012",
-"RU c #01060C",
-"RV c #2D3238",
-"RW c #0F1110",
-"RX c #636564",
-"RY c #6E6E6E",
-"RZ c #121B20",
-"R& c #3E474C",
-"S c #6BB1ED",
-"S0 c #67ADE9",
-"S1 c #65A8DF",
-"S2 c #5EA1D8",
-"S3 c #5E92C4",
-"S4 c #497DAF",
-"S5 c #768DD3",
-"S6 c #8AA1E7",
-"S7 c #AAC9F7",
-"S8 c #BEDDFF",
-"S9 c #D6EAFF",
-"Sa c #D5EBFF",
-"Sb c #D6ECFF",
-"Sc c #CDEAFF",
-"Sd c #ACC9FF",
-"Se c #8BA8E2",
-"Sf c #657AAF",
-"Sg c #455A8F",
-"Sh c #4073A0",
-"Si c #588BB8",
-"Sj c #599AD0",
-"Sk c #62A3D9",
-"Sl c #65A9E6",
-"Sm c #69ADEA",
-"Sn c #69B3F2",
-"So c #6AB4F3",
-"Sp c #7296B6",
-"Sq c #000F2F",
-"Sr c #606062",
-"Ss c #171719",
-"St c #0C0C0E",
-"Su c #343436",
-"Sv c #6F6F6F",
-"Sw c #636C75",
-"Sx c #0D161F",
-"Sy c #19588E",
-"Sz c #68AEEA",
-"SA c #66A9E0",
-"SB c #60A3DA",
-"SC c #6397C9",
-"SD c #6D84CA",
-"SE c #8198DE",
-"SF c #9CBBE9",
-"SG c #B7D6FF",
-"SH c #D0E4FC",
-"SI c #D5E9FF",
-"SJ c #D1E7FE",
-"SK c #CBE1F8",
-"SL c #BCD9FB",
-"SM c #B3D0F2",
-"SN c #A9C6FF",
-"SO c #819ED8",
-"SP c #6176AB",
-"SQ c #4275A2",
-"SR c #5A8DBA",
-"SS c #5C9DD3",
-"ST c #63A4DA",
-"SU c #66AAE7",
-"SV c #6AAEEB",
-"SW c #6BB5F4",
-"SX c #002444",
-"SY c #4A4A4A",
-"SZ c #777779",
-"S& c #78787A",
-"T c #050E17",
-"T0 c #4E5760",
-"T1 c #76B5EB",
-"T2 c #68AEEC",
-"T3 c #61A3DF",
-"T4 c #609CD2",
-"T5 c #508CC2",
-"T6 c #6080BD",
-"T7 c #7090CD",
-"T8 c #90AAE7",
-"T9 c #AFC9FF",
-"Ta c #B7D8FF",
-"Tb c #B3D8FF",
-"Tc c #AED3FF",
-"Td c #A9CDFD",
-"Te c #ABC3FF",
-"Tf c #7C94D2",
-"Tg c #5A74A5",
-"Th c #435D8E",
-"Ti c #457AAC",
-"Tj c #5B90C2",
-"Tk c #5E9FD7",
-"Tl c #64A5DD",
-"Tm c #67ABE8",
-"Tn c #6BB2F2",
-"To c #6DB4F4",
-"Tp c #6FB6F6",
-"Tq c #70B4F1",
-"Tr c #4589C6",
-"Ts c #000419",
-"Tt c #23394E",
-"Tu c #616264",
-"Tv c #727375",
-"Tw c #474C52",
-"Tx c #04223C",
-"Ty c #000721",
-"Tz c #3375AF",
-"TA c #73B5EF",
-"TB c #6DB3F1",
-"TC c #69AFED",
-"TD c #63A5E1",
-"TE c #629ED4",
-"TF c #5A96CC",
-"TG c #5676B3",
-"TH c #6A8AC7",
-"TI c #7F99D6",
-"TJ c #9FB9F6",
-"TK c #ADCEF9",
-"TL c #AACFFB",
-"TM c #AACEFE",
-"TN c #A8CCFC",
-"TO c #95ADEB",
-"TP c #6D85C3",
-"TQ c #516B9C",
-"TR c #466091",
-"TS c #4C81B3",
-"TT c #6095C7",
-"TU c #65A6DE",
-"TV c #6CB3F3",
-"TW c #71B5F2",
-"TX c #7C92A7",
-"TY c #30465B",
-"TZ c #000002",
-"T& c #050A10",
-"U c #2A2F35",
-"U0 c #4E6C86",
-"U1 c #90AEC8",
-"U2 c #72B4EE",
-"U3 c #6FB6F8",
-"U4 c #6DB7F8",
-"U5 c #6EB5F7",
-"U6 c #6CB3F5",
-"U7 c #6CB1F2",
-"U8 c #6AAFF0",
-"U9 c #63A7E4",
-"Ua c #60A1D7",
-"Ub c #5B9CD2",
-"Uc c #588ABF",
-"Ud c #5082B7",
-"Ue c #788BD0",
-"Uf c #8699DE",
-"Ug c #9EB8F5",
-"Uh c #AECBFF",
-"Ui c #A1B8FB",
-"Uj c #869DE0",
-"Uk c #687AB8",
-"Ul c #3F668F",
-"Um c #456C95",
-"Un c #4E8AC0",
-"Uo c #5E9AD0",
-"Up c #60A2DE",
-"Uq c #68ACEB",
-"Ur c #6BAFEE",
-"Us c #6FB4F5",
-"Ut c #6EB5F5",
-"Uu c #70B7F9",
-"Uv c #6CB6F7",
-"Uw c #6DB4F6",
-"Ux c #64A8E5",
-"Uy c #5FA0D6",
-"Uz c #6294C9",
-"UA c #4F81B6",
-"UB c #687BC0",
-"UC c #7588CD",
-"UD c #7A94D1",
-"UE c #829CD9",
-"UF c #829FD9",
-"UG c #7A97D1",
-"UH c #768DD0",
-"UI c #6B82C5",
-"UJ c #6476B4",
-"UK c #495B99",
-"UL c #3B628B",
-"UM c #5279A2",
-"UN c #5793C9",
-"UO c #639FD5",
-"UP c #64A6E2",
-"UQ c #66A8E4",
-"UR c #69ADEC",
-"US c #6EB3F4",
-"UT c #70B5F8",
-"UU c #6FB4F7",
-"UV c #6FB2F6",
-"UW c #6DB0F4",
-"UX c #6BAFF0",
-"UY c #67ABEC",
-"UZ c #67A7E5",
-"U& c #63A3E1",
-"V c #619ED7",
-"V0 c #5895CE",
-"V1 c #507EB2",
-"V2 c #4E7CB0",
-"V3 c #6683BB",
-"V4 c #6D8AC2",
-"V5 c #6E87BF",
-"V6 c #6D86BE",
-"V7 c #5F7EAD",
-"V8 c #496897",
-"V9 c #365F8B",
-"Va c #3F6894",
-"Vb c #467DB3",
-"Vc c #578EC4",
-"Vd c #5E9CD9",
-"Ve c #65A3E0",
-"Vf c #66A7E7",
-"Vg c #69AAEA",
-"Vh c #6DB1F2",
-"Vi c #6DB2F5",
-"Vj c #71B4F8",
-"Vk c #71B5F6",
-"Vl c #70B5F6",
-"Vm c #70B5FA",
-"Vn c #6EB3F6",
-"Vo c #6EB1F5",
-"Vp c #69ADEE",
-"Vq c #69A9E7",
-"Vr c #66A6E4",
-"Vs c #66A3DC",
-"Vt c #6593C7",
-"Vu c #5583B7",
-"Vv c #4D6AA2",
-"Vw c #415E96",
-"Vx c #405991",
-"Vy c #3E5D8C",
-"Vz c #486796",
-"VA c #4C75A1",
-"VB c #5B84B0",
-"VC c #5D94CA",
-"VD c #649BD1",
-"VE c #64A2DF",
-"VF c #68A6E3",
-"VG c #68A9E9",
-"VH c #6BACEC",
-"VI c #70B3F7",
-"VJ c #70B4F5",
-"VK c #6FB4F9",
-"VL c #70B2E6",
-"VM c #6EB0E4",
-"VN c #6EADE2",
-"VO c #6AAADA",
-"VP c #67A7D7",
-"VQ c #65A2D1",
-"VR c #619ECD",
-"VS c #5C95C2",
-"VT c #548DBA",
-"VU c #5287B3",
-"VV c #5288B4",
-"VW c #578DB9",
-"VX c #5D97C5",
-"VY c #639DCB",
-"VZ c #64A2D1",
-"V& c #68A6D5",
-"W c #69A7DA",
-"W0 c #6CAADD",
-"W1 c #71B4E9",
-"W2 c #72B5EC",
-"W3 c #627ED4",
-"W4 c #627ED5",
-"W5 c #617ED5",
-"W6 c #637ED3",
-"W7 c #647ED2",
-"W8 c #657ED1",
-"W9 c #667ED0",
-"Wa c #687FCE",
-"Wb c #687FCD",
-"Wc c #697FCC",
-"Wd c #6B7FCA",
-"We c #6D80C9",
-"Wf c #6E80C8",
-"Wg c #6E80C7",
-"Wh c #7180C4",
-"Wi c #7280C3",
-"Wj c #7481C1",
-"Wk c #7681BF",
-"Wl c #7781BD",
-"Wm c #7A81BB",
-"Wn c #7B82BA",
-"Wo c #7D82B8",
-"Wp c #7E82B6",
-"Wq c #8182B3",
-"Wr c #8283B2",
-"Ws c #8483B0",
-"Wt c #8683AE",
-"Wu c #8983AB",
-"Wv c #8B84A9",
-"Ww c #8D84A6",
-"Wx c #8E85A4",
-"Wy c #9185A2",
-"Wz c #9385A0",
-"WA c #95859D",
-"WB c #97869B",
-"WC c #998699",
-"WD c #9B8697",
-"WE c #9D8794",
-"WF c #A18790",
-"WG c #A2888F",
-"WH c #A3888D",
-"WI c #A6888B",
-"WJ c #A88889",
-"WK c #AA8987",
-"WL c #AC8984",
-"WM c #AE8981",
-"WN c #B18A7F",
-"WO c #B38A7D",
-"WP c #B58A7B",
-"WQ c #B88B78",
-"WR c #BA8B76",
-"WS c #BB8B74",
-"WT c #BE8B71",
-"WU c #C08C6F",
-"WV c #C18C6E",
-"WW c #C48D6B",
-"WX c #C58D69",
-"WY c #C88E67",
-"WZ c #CA8E64",
-"W& c #CC8E62",
-"X c #CE8E60",
-"X0 c #CF8E5E",
-"X1 c #D18F5C",
-"X2 c #D48F59",
-"X3 c #D68F57",
-"X4 c #D79057",
-"X5 c #D89055",
-"X6 c #DC9052",
-"X7 c #DC9051",
-"X8 c #DE914F",
-"X9 c #DF914E",
-"Xa c #E1914C",
-"Xb c #E2924B",
-"Xc c #E49248",
-"Xd c #E59247",
-"Xe c #E79245",
-"Xf c #E89245",
-"Xg c #EA9342",
-"Xh c #EB9342",
-"Xi c #EC9341",
-"Xj c #ED943F",
-"Xk c #EE943E",
-"Xl c #EF943D",
-"Xm c #F0943D",
-"Xn c #F1943B",
-"Xo c #F2943B",
-"Xp c #F2943A",
-"Xq c #F39539",
-"Xr c #F49539",
-"Xs c #F59539",
-"Xt c #F69537",
-"Xu c #F69637",
-"Xv c #F79637",
-"Xw c #F69638",
-"Xx c #F69639",
-"Xy c #F59639",
-"Xz c #F4963A",
-"XA c #F4963B",
-"XB c #F3953C",
-"XC c #F2953C",
-"XD c #F2963D",
-"XE c #F1963F",
-"XF c #EF9641",
-"XG c #EE9642",
-"XH c #ED9643",
-"XI c #EC9645",
-"XJ c #EA9647",
-"XK c #EA9648",
-"XL c #E99649",
-"XM c #E8954B",
-"XN c #E6954D",
-"XO c #E5954E",
-"XP c #E3944F",
-"XQ c #E29551",
-"XR c #E19553",
-"XS c #DF9556",
-"XT c #DD9558",
-"XU c #DB955A",
-"XV c #DA955C",
-"XW c #D8955E",
-"XX c #D69560",
-"XY c #D59562",
-"XZ c #D49464",
-"X& c #D29466",
-"Y c #D09468",
-"Y0 c #CE946B",
-"Y1 c #CC936D",
-"Y2 c #CA936F",
-"Y3 c #C89371",
-"Y4 c #C69374",
-"Y5 c #C49377",
-"Y6 c #C39379",
-"Y7 c #C0937C",
-"Y8 c #BE937E",
-"Y9 c #BC9281",
-"Ya c #BB9282",
-"Yb c #B89285",
-"Yc c #B79286",
-"Yd c #B49289",
-"Ye c #B3928C",
-"Yf c #B1918F",
-"Yg c #AF9191",
-"Yh c #AC9194",
-"Yi c #AA9196",
-"Yj c #A99198",
-"Yk c #A7919A",
-"Yl c #A5919D",
-"Ym c #A290A0",
-"Yn c #A190A2",
-"Yo c #9F90A4",
-"Yp c #9D90A7",
-"Yq c #9B90A9",
-"Yr c #998FAB",
-"Ys c #978FAD",
-"Yt c #958FAF",
-"Yu c #938FB2",
-"Yv c #928FB3",
-"Yw c #8F8FB8",
-"Yx c #8E8FB8",
-"Yy c #8C8EBB",
-"Yz c #8A8EBD",
-"YA c #888EBF",
-"YB c #888EC0",
-"YC c #868EC3",
-"YD c #838EC6",
-"YE c #828EC7",
-"YF c #808EC9",
-"YG c #7E8DCB",
-"YH c #7D8DCD",
-"YI c #7C8DCF",
-"YJ c #7A8DD0",
-"YK c #788DD2",
-"YL c #778DD4",
-"YM c #768DD5",
-"YN c #758CD7",
-"YO c #748CD8",
-"YP c #738CDA",
-"YQ c #718CDC",
-"YR c #6F8CDE",
-"YS c #6F8CDF",
-"YT c #6D8CE0",
-"YU c #6B8CE3",
-"YV c #6B8CE4",
-" 0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 3 4 5 6 7 8 9 a b c d e f g h i j 7 k l 3 m 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 n n 1 0 0 n 0 o o 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
-" p p q q p p q q p p q q p p q q p p q q p p q q p p n 0 3 5 r 8 j s a t u v w x y z A 7 B C 2 1 q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p D q q p D q E F F q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q",
-" G G H H G G H H G G H H G G H H G G H H G G H H I J K L M N O P Q R S T U V W X Y Z &0 000102030405 H H0606 H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H H H H H G G H H G G H H05 G H H G G H H G G H H G G H H G G0707 G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H",
-"0808090908080909080809090808090908080909080809090a I L L0b0c O0d Q0e0f0g0h0i0j0k0l0m0n0o0p0q030r G0s09090t0t0909080809090808090908080909080809090808090908080909080809090808090908080909080809090808090908080909080809090808090909090909080809090808090908080909080809090s0809090808090908080u0u0808090908080909080809090808090908080909080809090808090908080909080809090808090908080909080809090808090908080909",
-"0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0x0y0z0A0B0C0D0E0F0G0H0I0J0K0L0M0N0O0P0Q0R0S0T0U0V0y0x0w0w0v0v0W0W0v0v0w0w0v0v0W0W0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0x0X0X0x0x0v0v0w0x0X0X0v0v0v0v0Y0Y0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w",
-"0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z1 0w0w0y0A0B0C0S0E0F101112131415161718191a1b0T1c0z0y0w1 0&0&0Z0Z1d1d0Z0Z0&0&0Z0Z1d1d0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&1e0Z0&0&0Z0Z0&1 0Z0Z0&0&0Z0Z0Z0Z0Z0Z1f1f0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&",
-"1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1i1j1k1l1m1n1o1p1q1r1s1t1u1v1w1x1y1z1A1B1C1D1E1o1n1F1l1G1H1I1h1g1g1h1h1g1g1h1h1J1J1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1K1K1g1g1h1h1L1M1N1O1P1P1Q1Q1g1R1h1h1g1g1K1K1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h",
-"1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1U1V1I1G1m1W1X1Y1Z1&2 202122232425262728292a1o1n2b1l1G1i1g1V2c1U1S1T1T1S1S1T1T2d2d1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S2e2e1S1S1T1T2f2g2h2i2j2k2l2m1U1S1T1T1S1S2e2e1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T",
-"2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2p2q2r1Q2s2t2u2v2w2x2y2z2A2B2C2D2E2F2G2H2I2J2K2L2M2N2O2O2P2Q2R2R2q2p2o2S2T2T2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2p2n2U2V2W2X2Y2Z2&3 303132333435363637372n2n38382n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o",
-"39393a3a39393a3a39393a3a39393a3a39393a3a3b2n3c3d2s2t3e3f3g3h3i3j3k3l3m3n3o3p3q3r2J3s2L3t3u2N2s2O2P3v3w3w2q2p2o2S3x3y3a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a3b393a3a3z3A3B3C3D3D3D3E3F3G3H3I3J3K3L3M39393N3O39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a",
-"3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3T3U3V3W3X3Y3Z3&4 404142434445464748494a3Y3Y4b4c4d4e4f4g4h4i3W4j4k4l4m4n3T4o3Q3Q3S3S3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3T3P4p4p4q4r4s4t4u4v4v4v4s4s4v4u4w4x4y4z4A4B4C4C3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R",
-"4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E3Q3P4o4H3W4I4J4K4L4M4N4O4P444Q464R4S484T4U4V4J4W4X4Y4Y4Z4&5 4f5051524l4m4n3T3P3Q4E534G4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4E4E5454555556574s584v4v4v4u4t4t4v4v59594u5a5b5c5d5d4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F",
-"5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5g5e5f5h5i5j5k5l5m5n5o5p5q5r5s5t5u5v5w5x5y5z5A5B5A5A5C5D5E5E5F5G5H5I5J5K5L5M5N5O5j5j5P5h5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5Q5Q5f5f5e5e5f5f5R5e5f5S5T5U4u3D4v4v4v4v4u594v4v4v4v4u5V5W5X5Y5Z5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f",
-"5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5&6 5O606162636465666768696a6b6c6d6e6f6f6f6e6g6h6i6j6k6l6m6n6o6p6q6r6s6t6u6v5O6w5&6x5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h6y6y6z6z5R5R5h5h6x5R5f5h6A6B4u4v4u4u4u4u4u4u4u4u4v4v4u6C6D6E5Z6F5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h",
-"4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D6G3R6H6I6J4f6K6L6M6N6O6P6Q6R6S6T6U6V6W6X6Y6Z6&7 70717272737475767778797a7b4I517c4m7d7e7f4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4E4E4E4E7f7g4E7h7i7j4v4v4u4u4u4u4u4u4s4s4v4v7k7l7m5R7h5d4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E",
-"3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3T7n7o3V4j7p4Z7q7r7s6N7t7u7v7w7x7y7z7A7B7C7D7E7F7G7H7I7J7K7L7M7N7O7P7Q7R7S7T7U7V517W7X7Y7Z4C3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3Q3Q3Q3Q7&7&3Q3Q8 804v4v4u4u4u4u4u4u4s4s4v4u818283833Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q",
-"8484858586868585848485858484858587883b2p898a8b3s8c8d8e8f8g8h8i8j8k8l8m8m8n8o8p8q8r8s8t8u8v8w8x8y8z v8A8B8C8D8E8F8G8H8I8J8K8L8M8M8484858586868585848485858N7n858584848484878485858M8M858M8N8N858584848585848485858686858584848585868685858484858587844C8I313D4u4v4u4u4u4u4u4u4u4u4u4v8O8P8Q8485858R8R858M8487858M8484858M8484858M8R8R858584848585848Q85858487858S84848585848485858585858584848585858585858N8N858M",
-"87878M8M8T8T8M8M87888M8M87878U3a888V2p2Q8a3u8W2I8X8Y8Z8&9 909192939495969798999a9b9c9d8u8v8v9e9e9f9g9h9i9j9k9l9m9n8G9o9p9q9r2n3988878M8M8T8T8M8M87878M8M7n7n8U8U8888878787878M8M8M8M8M8M7n7o393988888M8M87878M8M8T8T8M8M87878M8M8T8T8M8M87878M8M88879s9t9u4u4u4v4u4u4u4u4u4u4u4u4u9v9w9x87878M8M9y9y393987878M8M88878M8M87878M399z9z8M8M87878M8M87888M8587888M8M87878M8M87878M8M8M8M8M8M8787858M8M8M8M397n7n8M8M",
-"9A9A9B9B9A9A2S2S9A9A9B9B9A9A9C9C2p2q2Q2P9D9E9F9G9H9I9J9K9L9M9N9O9P9Q9R9S9T9U9V9W9X9Y9Z9&a a a0a0a1a2a3a4a5a6a7a8a9aaabacad3vaeaeaf9C9B9B9A9A9B9B9A9A9B9B9Aag9B9B9A9A9B9B9A9A9B9B9A9Aahah9A9A9B9B9Aai9B9Bajaj9B9B9A9Aakak9A9A9B9B9A9A9B9B9A9A9B9Bai9Aalaman4u4u4v4u4u4u4u4u4u4s4s4uaoapaqai9A9B9B9A9A9B9B9A9A9B9Bai9Aar9B9A9A9A9A3b3b9B9B9A9A9B9B9A9A9A9A9A9A9B9C9A9A9B9B9A9A9B9B9B9B9B9B9Aai9B9C9A9A9B9B9A9A2S3a",
-"aiai9C9Caiai2o2oaias9C9Caiasatau3v2Pavawaxay9GazaAaBaCaDaEaFaGaHaIaJaKaLaMaNaOaPaQaRaS9&aTaUaVaVaWaXaYa3aZa&b b0b1a9b2b3b4avb5b6ataf9C9C9Aai9C9Caiai9Cafaias9C9C9Aai9B9Caiai9C9Basb7b8b99Aai9C9Caiai9C9Cbaba9C9Caiaibbbbaiai9C9Caiai9C9Caiai9C9Casasalbcbd4u4v4v4u4u4u4u4u4u4s4s4vbebfbgaiaiafafai9A9C9B9Aai9C9Caiai9C9Caiaiaiai2n2p9C9Casai9C9Caiaiaiasaiai9C9Caiai9C9Caiai9C9C9C9C9C9Caiai9C9Caiaiaf9Caiai2o2o",
-"bhbhbibibhbhbibibhbhbibibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb&c c0c1ayc2c3c4c5c6c7bjbjbhbhbibjbhbhbibibhbhbjbiafafc8c8c9cacbcccdcecfcgchchcici60602Tcjckbhbibibhbhchchbhbhbibibhbhclclbhbhcmcmcncncocpcq4u4u594v4u4u4u4s4s4u4ucrcscmcmbjbibibictctcucvcwcxcyczcAcBcCc9asasafafbhbhbibibhbhbibibibicmcmcDcEcFcobhbhbibibhbhbibibibjcGcHcIcJcKcLasasbibicMcMclcl",
-"ckckbjbjckckbjbjcNckbkbkblbmcOcPcQcRcScTcUcVcWcXcYcZc&c&d d0d1d2d3aMbGbGd4d5d6d7d8d9dadbdcdddedfdgdhbVdidjdkdldmdndodpc1dqdrdsc4dtc6bkbkckckbjbjckckbjbjckckbjbjaududvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdL9EckckbjbjckckdFdFckckbjbjckckdMdMckckdNdNdOdPdQdRdS4u4u594u4u4u4u4s4s4u4udTdUdNdNbkbjbjbjdVdWdXdYdZd&e e0e1e2e3e4e5e6atauckckbjbjckcNbjbkbkbkdNe7e8e9eaebckckbjbjckckbjbjbkecedeeefegeheieje6bjbjekeldMcl",
-"ememenenememeoeoepeqerereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLbHbHeMeNeOePeQeReSeTeUeVeWeXeYeZe&f f0f1f1f2f3f4f5f6f7f8f9cTfaevfbfcerfdememeoeoemfeeoeoememfffgfhfifjfkflfmfnfofpfpfqfrfsftfufv6CfwfxfyfzfAeoeoememfBfBememeoeoememeoeoememeoeoememfCfDfmfmfmfEfmfmfFfGfHfHfmfIfJfKfdeofLfMfNfOfPfQfRfnfofofmfEfEfEfEfSfTfUfVc6ememfWfWememfXfYfZf&g g0g1g2g3g4ememememfVfVeoeog5g6g73Efmfmg8g9ga2Reoeoepepeoeo",
-"gbgbgcgcgbgberergdgegfggghgigjgkglgmgngogpgqgrgsgtgugvgwgxgygzgzbHbHgAgBgCgCgDgEgFgGgHgIgJgKgLgMgNgOf0f1gPf0gQgRgSgSgTgUgVf9gWfagXghgYgZgbgberergbgbererg&h h0h1h2h33E3E3E3Eh4h5h6h6h7h8h9ha3E3E3E3Ehbhchdhderergbgbhehegbgberergbgberergbgbererg&gbhfhghbfEhb3EfEhbhhhhfphifEhjhkhlererhmhnfOhodS3Eh4h5h4h43E3Ehbhb3E3Ehphqhrhsgbgbhthug&gbhvhwhxhyhzhhh4h4hAhBgbgbgbgbhshsererhChD3E3E3E3EhEhFhGhGererhHgderer",
-"hIhIhJhJhKhK0Z0ZhLhMhNhNhOhPgWhQhRhShThUhVhWhXhYhZh&i i0i1i2eLi3i4i4i5i6i7i8i9iaibeMicidieifigihbVdif1gPiigPijikiliminioipiq0R1biris0X1eithIhJhJiuhIhJhJiviwixdSdS3EiyiyiziAdSdSdSiBiCiBiDiEiFiGiHiIiJiKiLiMiNiOhIhIhJ0ZhIhIhJhJhIhIhJhJhIhIhJiPiQiR4ziSdSdSiB3EiTiTdSdSiUiViWiXiYiZi&j j0aoj1iTdSiBiKiBiVj2j3j4j5j6j7iKizj8j9jaivivjbjcjdjejfjgjhdSiViViViUjijjithIhJiPhIitjkjljmjniziziB6CjojphIhIhJhJhIhIhJhJ",
-"itit0Z0Zjqjr1e0vjsjtjujvjwjxjyjzjAjBjCjDhWjEjFjGjHjIi i0i1jJgzi3jKjLjMjNjOjPjQjRjSjTjUjVifjWjXjYbVdif1gPiiiijZj&k k0k1k2k3k4k51ak6k7k80Xk9it0Z0Zitit0Z0ZhLjskakb9v9vkckckdke9v9viLiLkffwkgkhkikjkkklkmkniLkokpkqitit0Z0Zitit0Z0ZhIit0Z0Zitit0Z0ZiQkriM9v9v9v9v9vksks9viLktkukvkwgZkxkykzfI9vkskA9viLiL5VkBkCkDkEkFkGkHkIkJkKkLkMkNkOkPkQkRkSkTksiJ9vkuktktktkUkVitit0Z0Zitk9kWkXkYiLkJkdkZkak&l ititl0l0itit0Z0Z",
-"l1l1l2l2l3l3l4l5l6l7l8l9lalblcldlelflglhliljlklllmlnloi0lplqgzi3bHlrlsltlulvlwlxlylzlAlBlClDlEbVbVdif1gPlFiilGlGlHlIlJlKlLlMlNlOkOlPlQl5lRl3lSlSlTl1l2l2l1l1lUlViLknknkblWlWiLknfllXlYlZl&m m0m0l1l1m1m2kbkbm3m4lTl1l2m0l1l1l2l2m5m5l2l2l1l1m6m6m7m8m9maknkbktktknknkbknknmbmcmdmemfhjflmgmalWmhmhmhmimjmkmll2l2l1l1mmmnmompmqmrmsmtmumvknknlWlWiLknkbkbkbkbmwmxl1l1l2l2mymzmAmBkbkbmamCmDmEl2l2l1l1l2l2l1l1l2l2",
-"l3l3m0l4lRmFmGmHmImJl9mKlbmLmMmNmOmPmQmRmSmTmUmVmWmXmYmZm&lqgzi3bHgzn n0n1n2n3n4n5n6n7n8n9nanbbVbVdif1f1lFiilGlGf0ncndlJnenfngnhninjnkmHmFlRnlnll1l3m0m0lRl3nmnnkfkfkfkfnonokfnpkfnqnrnsjshMm0l4lRlRntnukfnvnwnxl3l3m0l4lRl3l4m0nynyl4m0lRl3nznAnBnCnDnEkfkfnonFkfkfkfkfnpbenGnHnInJnpnpnEnDnonononKnLnMnNnNm0l4l3lRnOnPnQnRnSnTnUnVnvnvnpkfnWnoflkfkfnpnpnpnXnYl3l3m0l4eunZn&o npnpo0o1o2o3l4m0l3l3m0m0l3l3m0m0",
-"o4o4o5o6o7o8o9oaobocmKodoeofogohoiojokolomonooopoqorosotouovowoxbGeMoyozoAoBoCoCoDoEoFoGoHoIoJoJdidigPoKoLoMfG7k7koNoOoPoQoRoSoToUmKoVoWoXo8oYoZo4o4oYoZo6o5o&p jhjhjhp0jhjhjhp0p1p2oYoZp3o4oYoYp4p4p5p6jhp0p7p8oap9oYoYp9o7oYoYo4o4papao4o4pbjw4zpcp0jhpdpepepejhp0pfpgphpipjpkpl5Vp0p0jhjhp0p0pmpnpoppo4o40808o4o4pqprpsp0ptpupvpwp0p0jhp0p0jhpxjhjhp0p0jhpypzp3o4o4o4pApBpC5Vp0pDpEpFo4p3oZpGp4p4oYoYo4o4oYoY",
-"p3p3o6pHoXo9oWoVpIpJpKpLpMpNpOpPpQmSpRpSpTpUpVpWpXpYpZp&q q0q1oxbGeMq2q3q4oB9dq5q6q7q8q8q9q9qaqbdiqcgPoKoLoM7k4s4s4sqdqeoQqfqgqhqiqjqkoVoaoXqloZp3p3oZoZo6pHqmqn5a5ako5a5a5a5a5aqoqpoZoZp3p3oZoZqqqqqrqsjnjnqtquqvo7oZoZo8o7oZqlp3p3papap3qwqxqyqz5ajn5aqAqAqAqA5a5aqBqCqDqEqFqGqH5a5ajnjn5a5aqIqJqKqLqLp3qw0s0sp3p3qMqNqOjnqPqQqRkwjnjn5a5ajn5ako5ajn5ajn5aqSqTp3p3p3qUqVqW5ajniSqXqYqZp3p3oZoZqqqqoZoZp3p3oZoZ",
-"q&q&r r0r1r2r3r4r5r6r7r8r9rarbrcrdrerfrgrhrikYrjrkrlrmrnrorprqrreMeMrsoCoC9drtrtrurvrw9&rxryrzrArBrCgPoKiiii4t4s4v4vrDrErFrGrHrIrJrKrLrMrNrOr0r0q&q&r r0q&q&rPrQrRrRrRrRrRrRrRrSrTrUr0r q&rVr0r q&rWrXrYrZrRrRr&s pHr r s0s0s1s1s2s3s4s4q&q&s5s6s7s8rRrRrZrRrRrRrRrZs9sasbscsdserZrRrRrRrRrZrRsfsgshr0r q&rVsisjq&q&skslrmrRsmsnsospsqsrrRrRrRrRrRjnrRrZssstsusvq&q&swsxqOrZs8syszsAr r0q&q&r r0q&q&r r q&q&r r ",
-"rVrVsBsBsCsDsEsFsGsHsIsJsKsLsMrcsNsOsPsQrhsRrSsSsTsUsVsWsXsYsZs&eMeNt oCoC9drtrtt0t1t2t3t4t5t6t7t8t9f1oKiiii4t4s4v4vtatbtctdtetftgthtitjtkrNtlsBrVrVr0sBtmrVcctnfIfItofIfIfIfItptqtrr0r0rVtmr0r0rVq&tsttlXlXtotutvtwr0r0txtytztAtBtCtDtErVrVtFtGsysyfIfIlXfIfIfIlXfItHtIsctJtKtLfIfIfIfIfIfItMtNtOscsBsBtmrVsjsjtmrVtPtQtRpDtStTtUtVtWtXfIfItofItofIfIlXtYtYsutZrVrVt&u iSlXsyu0u1u2sBsBrVrVr0r0rVrVr0r0rVrVr0r0",
-"u3u3u4u5u5u6u7u8u9uaubucudueufuguhuipciCujukulumunuoupuqurusutuueMeNuvuwuwuxuyuzuAuBuCuDuEuFuGuHuIuJgFuKlGlG584t4s4tuLuMuNuOuPuQuRrJuSuTuUuVuWuWu3u3uXuXuYuZu&v iSiSiSv0v1v1v2v3v4sBuXu4u3u3uXuXv5v6jmv7v0v0v8v9vavbvcvdvevfvgvhvivjvkvlvmvnvoqHvpvqiSiSiSiSiSiSiSvrvsvtvuvvvjv0iSiSiSv0v0v0vwvxuZuZuXuXu3u3uXuXvyrOvzvAvqvBvCvDvEu3vFvGhcv0vqvqvHiSvIvIv0v0qSvJk6vKvLvMvpvpvNvOvPvavQvQvRu3vSuXu3u3uXuXu3u3uXuX",
-"vTvTvUu6vVvWvXvYvZv&w w0udw1w2uguhw32&w4w5w6w7w8w9vBwawbwcwd9cuueNeNuwuxuwwegzwfwgwgwhwiwjwkwlwmwnwowpwqwrws584s4t4twtwuwvwwwxwywzwAwBuSwCuUwDwEwFvTvUu5wGwGwHv pCpCpCwIwJwKwLwMwNwNu5vUvTvTu5u5wOwPwQwIwIwIwRwSuWwTwUwVwWwXwIwIpDwYwZw&x vsx0pCx1x2pCpCpCpCpCwIulx3x4x5x6x7x8wIpCpCpCwIpDpCx9xawGxbu5u5vTvEu5u5xcxdxexfqCxgxhxiwFvTxjxkxlpCx1x1pCpCxmxnwIwIxoxpxqxrxsx1x1xtxuxvuWuWxwxwvTvTu5u5vTvTu5u5vTvTu5u5",
-"xxxxxyxzxAxBxCxDxExFxGxHxIxJxKxLxMxNxOw7xPx8xQwQxRxSxTxUxVxWxXgAeMeNxYlqxZx&y y y0y0y1y2y3y4y5y6y7y8y9yaybycydydyeyfygyhyiyjykylymynyoypyqyrysytyuxxyvyvywyxyyyzqHqHqHyAyAqHtGyBxxxxxxxxxxxxyCyCyDyEyAyAyAyAyFyGyHyIyJqIyKyLyMyNyOyPyQyRySyTyAyAqHqHqHqHqHqHyUyVyWnGxyxyyXyYyZqHqHqHqHyAyAqHy&ccz z0yvyvxxxxyCyCz1eez2z3z4z5yvyvz6z7xbz8z9zazbyKqHzcqHyAyAyAkUzdzezfqHqHzgzhziwExbxbzjzjxxxxyvyvxxxxyvyvxxxxyvyv",
-"zkzkytysxBzlzmznzozpzqzrzsztzuzvzwzxzyx0xOzy6CuqzzzA4xujzBzCgAgAi2zDt7zEzFzFzGrczHzIzJzKzLzMzNzNzOzPzQzRzSzTzUoAzVzWzXzXzYzZz&y7A ynA0A1yqxCA2A3A4zkxzxzA5A5A6A7A8A8A8yZyZA8A9AazkzkzkyuzkzkwDAbAcAdyZyZA8yZAeAfAgAhyZyZAiAjwSAkAlAmAnAoApAqiCA8A8A8A8A8yZA8ArjfAsAtytxzAuAvyZyZA8A8A8A8yZyZAwAxAyAyytytA4A4AzAAABACo0ADAEAFytytAGAHAIAIAJz9AKqCA8A8A8yZyZyZALAMANAOiCwYAPAQAzwDAIAIARARyuzkxzxzzkzkxzxzzkzkxzxz",
-"ASATAUAVAWAXAYAZA&B B0B1B2B3B4B5lkB6B7B8B9BaBbBcBdBeBfBgBhBhBiBjBkBlBmBmBnBnBoBpBqBrBsBtBuBvvvBwBxByBzBABBBCBDBEBFBGBFBHBIBJBKwxBLtDBMBNBOBPBQBRAUBSBSBSATATBTBUBVBVBWBWBXBYBZB&AHAGC C ATATC0C1C2C3C4C5BXcqC6C7C8C9BWBXCaCbCcCdCeCfCgChCiBXBXBWs7CjBXBXBXCkClCmASCnAUBSCoCpC4C3tRBWBWBXBWBXCqCrAzAzBSAUCsu7fNCtCuCvCwCxCyCzBSBSATATBSAUCACBCCCDBWBWBXBXBXBXCECFCGCvCHCICJCsAUBSATATCKCKASATBSBSATATBSBSATATBSBS",
-"CnCnAVAWCLAXAYAZCMB CNB1COCPCQCRCSCTCUCVCWCXCYCZC&D uuD0D1D2D3D4D5D5D6D7D8D96&DaDbDcDdDeDfDgDhDiDjDkDlDmDnzQDoDpDqDrDsDtDuDvDwDxDyDzDABNDBBPBQBRAUAUAUAUCnCnDCDDujujpcj7j7upDEDFDGDGDHDHDICnDJDKDLoqDMoqpcfwDNDODPDQj7pcDRDSDTDUDVDWDXDYj7j7j7mbDZujj7j7D&E E0E1CnCnAVAUE2E3DMDMmbj7j7pcj7j7E4E5E6E7AUAUCsE8E9EaEbEcEdEeCzvWAVAUCnCnAVAUEfEfEgEhvhj7j7pcpcpcEifsEbEjEkElCsCsAUAUDICnEmEmCnCnAUAUCnCnAUAUCnCnAUAU",
-"EnEnEoEpEpEqErEsEtEuEvEwExEyEzEAEBECEDEEEFEGgzd4lpEHEIEJEKELEMENEOB5EPEQERESETEUEVEWEXEYEZE&F F0F0F1F2F3F4F5F6F7F8F9FaFbFcFdFeFfFgFhFiFjFkFlEpEpFmEnFnEoFoFpFqFrrjkYmCmCkYFsFtFuFvEnFnFnFwFxFyFzkYrSkYkYkYFAFBzlFCFDFEFEulFFFGFHpsFIkYrSmCFEFJFKkYkYFLFMFNFOFnEoEnEnFnFn0FFPFQFJkYrjkYkYrSkYFRFSFTFUFVFWFXFYkZrSFZqDF&xCFmEnFnFnG G G0G1EnEnFoG2zhG3rSkYG4G5psG6kYfxG7uTFmEnFnFnG8G8FnFnEnEnFnFnEnEnFnFnEnEnFnFn",
-"FmFmEoEpEqG9GaGbEtEuEvGcGdGeGfGgGhx&GiGjGkGkGlGmEHEHGnGoGpGpGqGrGsGtGuGvGwGxGyGzGAGBGCGDGEGFGGGHGGGHGIGJGKGLGMGNGOGPGQGRGSqfGTGUGVGWGXGYFkGZEqEpFmFmEoEoFoG&ix2&H 2&H0H0H1ixH2H3FmFmEoEoFwH4H5H02&H12&2&kIkHH6H7H8H9HaHaH1H12&H12&2&2&2&H0H0HbHc2&HdHeHfHgHhEpEoHiFmEoEoHjHkHlHc2&2&2&H12&H1HmHmHnHoHpHqHrHsFIHtHuHvzmyqHiFmEoEoHwHxHyHyFmFmFoHzHAHBum2&yVyVHC2&fvFqHDu9HiFmEoEoHEHEEoEoFmFmEoEoFmFmEoEoFmFmEoEo",
-"HFHFHGHHHIHJHKHLFiHMHNFgHOHPHQHRHSHTHUHVrzloi i0HWHXxZHYHZH&I I0I1I2I3I4I5I6FeI7I8I9IaIbIcIdIeIeIfIfIdFgIgIhIiIjIkIlIlIkImInIoIpHMIqIrIsItIuIvHHIwIwHGHHIxIyIzIAIBIBIBIAICcsHGHHIwIwHGHGIDtQaoulIEIFIGIHIIIJHGHHtVIKILulwYwYIAIAwYwYIMIMwYulwYINyIIOIPIQIwIwHGHGIwIwHGHGHGIRISITFIulIBIBwYwYululwYwYulwYIUIVIKIWIXEqHGHGIwIwHFHFIwIwHiIYIwIwIZI&J J0J1J2wYulwYrmJ3J4HGHGIwIwHGJ5J6J6HGHGIwIwHGHGIwIwHGHGIwIwHGHG",
-"J7J7IvIuJ8J9JaHLJbJcGVFgJdJeJfJgJhJiHVHVrzloi i0HWHXJjJkCQJlJmJnJoJpJqJrJsJtJuJvJwJxEwJyJzJAJBJBJCJDJAJzJEJFGGJGJHJIJJJKJLJMIpJNJcIqIrJaItIuIuIvHIHIIvIvJOJPJQJRJSJRJRJRJTh8IvIvHIHIIvIvJUJVJWJXJYJZJ&K K0K1IvIvsoK2K3K4K5CkJRJSCkkZK6K7fwyJK8kHK9KaKbKbJ8HIIvIvHIHIIvIvIuIvKcKdKeupKfJRkZkZkZkZCkCkD&HtKgKhKiKjG9KkIvIvHIHIJ7J7HIHIGZGZHIHIKlKlKmKmKnKoCkkZKpKqKrKsIvHHHIHIIvIvKtKtIvIvHIHIIvIvHIHIIvIvHIHIIvIv",
-"KuKuKvKwKxKyKzKAKBKCKDKEKFKGKHKIKJKKHVryKLKMi i0lplpKNKOKPKQKRKSKTKUKVKWKXKYKZK&L L0L1L2L3L4L5L5L6L7L8L9LaLbLcLdL0L LeLfKELgL2LhLiLjLkKzLlLmLnKvLoLoKvKvLpLqLrLsLtLuLvLwLxLyLnKvKuKuKvKvLzLALBLCLDKxKvKvLmKuKvKvKuKuLELFLGLHLILJLKqGLLtQLMLNLOLPKuKuLQKxKuKuLRLRKuKuKvKvKuKuKxLSLTFNLULVLWLXLYEeLZL&M M0M1M2KvKvKuKuKxKxM3M3KxKxM3M4KvKvKuKuKvKvM5M5M6M7KpKpM8kyKuKuKvKvKuKuKvKvKuKuKvKvKuKuM9M9KuKuKvKvKuKuKvKv",
-"KuKuKvKvLQKyKzKAKBMaMbKEMcMdMeMfMgMhHVryKLKLi i0lpMiMjMkMlMmMnMoMpMqMrMsMtMuMvMwMxMyMzLhMAMBMCMCMDMEMFL5MGMHMbMIMJMyMKMLLgMbLhMMLjLkMNKzLmLmKvKvMOLoKvKvMPMQMRMSMTMUMVMWMXMYKvLnKuKuKvKvMZMZLPLPLQLQLnKvKuKuKvKvKuKuM&M&N N0N1N2N3qFN4N5nhnhLPN6LmKuKxKxKuLmLRLRKuKuKvKvLmKuKxKxN7N7N8N9NaNbNcNdNeNfNgNgNhM2LnKvKuKuKxKxM3M3KxKxM3M3KvKvKuKuKvKvM5NiNjNkw8hjNlNmLmKuKvKvKuKuKvKvKuKuKvKvKuKuM9M9KuKuKvKvKuKuKvKv",
-"NnNnNnNoNpNpNqNrNsNtNuNvNwNxNyNzNABmHVryNBi NCNCeKgzNDNENFNGNHNINJNKNLNMNNNONPNQNRNSNTNUNVNWNXNYNZN&O O0O1O2NTO3O4O4O5O6O6O7NtO1NWO8NYO9NpNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnOaOaNnNnNnNoNnNnNnNnNpNpNnNpObObObObOcOdNnNnNpNnOcOdNnNoNnNnNnNnNpNnNpNnNnNnNnNnNpNnOeOfNpNnNnNnNnNnNnNoNnNpNnNnNpNnNpNnOdOdNnNnNnNnNnNnmLOgOhOiOjOkOlOmOnOnOoOpbdOqOrOsOtOuOdOdNnNpNnNnNnNnObObNnNnNnNnNnNnNnNnNnNnNnNnNnNn",
-"OvOvOvOvOvO8OwOxO2OyNuNvK&OzOAOBOCODOEOFNBi NCNCeKeLOGOHOIOJOKOLOMONOOOPNOLCNQOQORNSNTNUOSNVOTOTOUOUO0OVO2NtNTNTOWO4O6O3O3O7NtO2OSNVNXNYOvOvOvOvOvOvOvOvOvOvOvO8O8OvOvOvOvO8OvOvOvOvOXOXOvNpOvOvOvOvOvOvOvOvOvOvNYO9NYO9OYOYOvO8OvOvOYNZO8OvO8OvOvOvO8OvOvOvOvOvOvOvOvOvOZOZOvOvOvOvO8OvOvO8OvOvOvOvOvOvOvOvOYOYOvOvO8O8O8OvO&P P02gP1P2P3P4P5P6P7P8up3 P9PaPbPbOYOYOvOvOvOvOvOvO9O9OvOvOvOvOvOvOvOvOvOvOvOvOvOv",
-"PcPcPdPdPePePfPgPhPiPjPkPlPmPnPoPpPqrdPrNBi i0i0HXHXPsPtPuPvPwPxPyNLPzPAPBPCPDPEPFPGPHPhPIPIPfPfPJPJPgPgPhPHPHPHPKPLPMPMPFPGPNPOPIPPPgPdPePePdPdPJPePfPdPePQPdPdPePJPdPdPePePdPfPQPePRPRPJPePdPdPePePdPdPPPSPTPdPUPUPdPdPVPVPPPVPePePVPVPePePdPfPcPcPRPRPePePdPdPePePdPdPePePdPdPePePWPRPePePdPdPePePdPdPePePdPdPePePRPWPXPYFqPZrnP&vhQ Q0Q1Q2Q3Q4Q5Q6Q7Q8Q9PfPdPePePdPdPePePdPdPePePVPVQaQaPdPdPePePdPdPePePdPd",
-"QbQbPgPgQcQcPgPOPHQdPjQePlQfQgQhQiQjQkQli i i0lpHXd4QmQnQoQpQqQrQsQtQuQvQwQxPEQyPGQzQAPhPhPhPOPOQBQBPgPOPhPhPHPHQCQCQDQEQzQzPNPOPhPhPgPgPJQcPgPgQcQcPgPgQcQcPOPgQcQcPOPgQcQcPgPOQcQcQFQFPJQcPgPgQcQcPgPgPIPIPgPgPUQGPfPgPIPIPIPIQcQcPIPIQBQcPgPgQHQbQFQFQcQcPgPgQcQcPgPgPJQcPgPgQcQBQFQFQBQcPgPOQcQcPgPfQcQcPgPgQcQcQFQFQIQJQKpsQLplqOpsQMQNQ3QOQPQQQRQSQTMaPOPgQcQcPgPgQcQcPfPgQcQcPIPIQUQUPgPgQcQcPgPgQcQcPgPg",
-"QUQUQUQUQUQUQVQVQAQdQWQXQYQZQ&R R0R1R2R3NBi i0lpeLeKBmR4R5R6R7R8QfR9RaRbRcRdPiQAReReQVQVQUQURfRfQUQUQUQUQVQVReReReRePNPNReQVQVQVQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQURgRgQUQUPJQcQVQVRhRiRjQPRkRlRmRnRoRpRqRrRsRtRuMAQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQU",
-"QUQUQUQURvQUQUQVPHPiQWRwRxRyRzRARBRCRDREi i i0lpeLeKRFRGRHR6RIRJRKRLRMRNROQdQAPHQVQUQUQUQUQURfRfQUQUQUQUQUQUQUQUQVQVPOPOQVQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQURgRgQUQUQcQcQVQURPRQRRQPRSRTRURVRWRXRrRYRZR&MAL4QUQUQURvQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQU",
-"PgPgPgPgPgPgPgPOPHPiS S0S1S2S3S4S5S6S7S8OFS9SaSbScKKSdSeSfSgShSiSjSkSlSmSnSoPNPOPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPfPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgQUQUPOPgPgPgSpSqRrpsSrSsStSuSvpsSwSxSyMMPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPg",
-"PgPgPgPgPfPgPgPgPHQAS SzSASBSCS4SDSESFSGSHSISJSKSLSMSNSOSPSgSQSRSSSTSUSVSoSWPOPOPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgQUQUPfPgPgPgRhSXSYpsSZSZS&SZpsiMT T0MMT1PgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPg",
-"POPOPOPOPOPOPOPOPNSWQyT2RbT3T4T5T6T7T8T9TaugTbTcTdTdTeTfTgThTiTjTkTlTmSVTnToPNPOTpTpQVQVPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPNPOTqTrTsTtTuTvdUTwTxTyTzTAPOPNPOPOPNPNPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPO",
-"POPOPOPOPOPOPOPOPNSWTBTCRNTDTETFTGTHTITJTKTKTLTLTMTNTOTPTQTRTSTTPzTUTmSVTVToPNPOTpTpQVQVPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOTWTqTXTYRTTZT&U U0U1TAU2POPOPOPOPNPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPO",
-"U3U3U3U3U3U3U4U4U5U6U7U8TmU9UaUbUcUdUeUfUgT9UhSdUiUjI1UkUlUmUnUoUpRMUqUrTVToU5U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U5U3U3U3U5U3UsU7U3U3U3U3U3U3TpUtU3UuU3U3U3UuU3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4",
-"U5U5U5U5U5U5UvUvU5UwU7U8SmUxSTUyUzUAUBUCUDUEUFUGUHUIUJUKULUMUNUOUPUQURUrTVToU5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U3U5U5U5UwUwUwU5USUSUwU5U5UwUwU5UtUtU5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUv",
-"UTUTUTUTUTUTUTUTUTUUUVUWUXUYUZU&V V0V1V2V3V4V5V6V7V8V9VaVbVcVdVeVfVgUXVhViUUUTUTVjVjUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTVkVkVlVlU3U3UTUTVlVlVmVmUTUTVkVkUTUTVlVlUTUTUTUTUTUTVjVjUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUT",
-"UUUUUUUUUUUUUUUUUUVnVoUWUXVpVqVrVsV VtVuVvVwVxVxVyVzVAVBVCVDVEVFVGVHUXVhViVnUTUUVIVIUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUVJVJUsUsU5U5UUUUUsUsVKVKUUUUVJVJUUUUUsUsUUUUUUUUUUUUVIVIUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU",
-"KCKCMGMGMGMGMGMGKCKCMHLaVLVMVNLdVOVPVQVRVSVTIjVUVVVWVXVYVZV&W W0LcLgLaL3W1KCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGW2W2MGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMG",
-"W3W4W5W5W4W5W3W6W6W7W8W9WaWbWcWdWeWfWgWhWiWjWkWlWmWnWoWpWqWrWsWtWuWvWwWxWyWzWAWBWCWDWEWFWGWHWIWJWKWLWMWNWOWPWQWRWSWTWUWVWWWXWYWZW&X X0X1X2X3X4X5X6X7X8X9XaXbXcXdXeXfXgXhXiXjXkXlXmXnXoXpXqXrXsXsXtXtXuXtXvXvXvXuXuXuXwXxXyXzXAXBXCXDXEXEXFXGXHXIXJXKXLXMXNXOXPXQXRXSXTXUXVXWXXXYXZX&Y Y0Y1Y2Y3Y4Y5Y6Y7Y8Y9YaYbYcYdYeYfYgYhYiYjYkYlYmYnYoYpYqYrYsYtYuYvYwYxYyYzYAYBYCYDYEYFYGYHYIYJYKYLYMYNYOYPYQYRYRYSYTYTYUYUYV"};
-
+/* XPM */
+static const char *AboutBox_WxStaticBitmap1_XPM[]={
+/* AboutBox_WxStaticBitmap1 */
+"200 60 3963 2",
+" c None",
+" 0 c #98CAFD",
+" 1 c #99CBFC",
+" 2 c #97C9FC",
+" 3 c #96C8F9",
+" 4 c #95C7F8",
+" 5 c #94C6F7",
+" 6 c #93C5F6",
+" 7 c #92C2F2",
+" 8 c #91C1F1",
+" 9 c #91C0EC",
+" a c #8DBCE8",
+" b c #8BB6E3",
+" c c #81ACD9",
+" d c #707CA6",
+" e c #B1BDE7",
+" f c #BCCAEF",
+" g c #526085",
+" h c #6E98C2",
+" i c #8BB5DF",
+" j c #90C0F0",
+" k c #93C5F8",
+" l c #94C6F9",
+" m c #97C9FA",
+" n c #99CBFE",
+" o c #9ACAFB",
+" p c #9ACCFD",
+" q c #9ACCFF",
+" r c #92C4F5",
+" s c #8EBDE9",
+" t c #8CB7E4",
+" u c #79A4D1",
+" v c #6F7BA5",
+" w c #D7E3FF",
+" x c #8E9CC1",
+" y c #58668B",
+" z c #6B95BF",
+" A c #8AB4DE",
+" B c #95C5F5",
+" C c #95C7FA",
+" D c #9BCDFE",
+" E c #9BCDFF",
+" F c #9CCCFD",
+" G c #A0D1FC",
+" H c #A1D0FC",
+" I c #A0D0FE",
+" J c #9FCFFD",
+" K c #9FCEFA",
+" L c #9ECDF9",
+" M c #9CCBF5",
+" N c #9BCAF4",
+" O c #9AC7F1",
+" P c #97C4EE",
+" Q c #94BFE9",
+" R c #93BEE8",
+" S c #91BBE3",
+" T c #8BB5DD",
+" U c #8EA2D5",
+" V c #6F83B6",
+" W c #B7BDDF",
+" X c #BDC3E5",
+" Y c #556B90",
+" Z c #61779C",
+" & c #779FC2",
+"0 c #91B9DC",
+"00 c #97C4ED",
+"01 c #9AC7F0",
+"02 c #9DC9F6",
+"03 c #A0CCF9",
+"04 c #9ECFFA",
+"05 c #9FD0FB",
+"06 c #A0D1FA",
+"07 c #A1D0FE",
+"08 c #A2D3FE",
+"09 c #A3D2FE",
+"0a c #A1D1FF",
+"0b c #9DCCF6",
+"0c c #9AC9F3",
+"0d c #96C3ED",
+"0e c #91BCE6",
+"0f c #89B3DB",
+"0g c #78A2CA",
+"0h c #7488BB",
+"0i c #99ADE0",
+"0j c #C7CDEF",
+"0k c #6D7395",
+"0l c #546A8F",
+"0m c #748AAF",
+"0n c #85ADD0",
+"0o c #96BEE1",
+"0p c #99C6EF",
+"0q c #9BC8F1",
+"0r c #A1CDFA",
+"0s c #A1D2FD",
+"0t c #A2D3FC",
+"0u c #A3D2FF",
+"0v c #A6D6FC",
+"0w c #A8D5FC",
+"0x c #A7D4FB",
+"0y c #A6D3FA",
+"0z c #A5D2F9",
+"0A c #A4D0F7",
+"0B c #A2CEF5",
+"0C c #A0CCF1",
+"0D c #9DC9EE",
+"0E c #9CC4E8",
+"0F c #99C1E5",
+"0G c #99BDE1",
+"0H c #89ADD1",
+"0I c #8094C6",
+"0J c #798DBF",
+"0K c #9EAAD4",
+"0L c #AFBBE5",
+"0M c #617598",
+"0N c #53678A",
+"0O c #6689A7",
+"0P c #80A3C1",
+"0Q c #8FBADD",
+"0R c #99C4E7",
+"0S c #9CC8ED",
+"0T c #9FCBF0",
+"0U c #A2CFF6",
+"0V c #A3D0F7",
+"0W c #A8D5FE",
+"0X c #A5D5FB",
+"0Y c #A9D5FC",
+"0Z c #A8D8FE",
+"0& c #AAD7FE",
+"1 c #A9D6FD",
+"10 c #85A9CD",
+"11 c #7094B8",
+"12 c #7F93C5",
+"13 c #97ABDD",
+"14 c #9DA9D3",
+"15 c #64709A",
+"16 c #54688B",
+"17 c #7185A8",
+"18 c #7FA2C0",
+"19 c #94B7D5",
+"1a c #98C3E6",
+"1b c #9DC8EB",
+"1c c #A2CEF3",
+"1d c #AAD7FF",
+"1e c #A7D7FD",
+"1f c #ABD7FE",
+"1g c #AED9FB",
+"1h c #AED9FC",
+"1i c #ADD8FA",
+"1j c #ACD7FA",
+"1k c #ABD6F9",
+"1l c #AAD5F7",
+"1m c #A7D2F4",
+"1n c #A7D0F0",
+"1o c #A5CEEE",
+"1p c #A2C9E8",
+"1q c #9FC6E5",
+"1r c #9DBAE2",
+"1s c #84A1C9",
+"1t c #7586BC",
+"1u c #899AD0",
+"1v c #95A3D2",
+"1w c #8593C2",
+"1x c #586D8A",
+"1y c #5A6F8C",
+"1z c #6B8BA4",
+"1A c #82A2BB",
+"1B c #91B8D7",
+"1C c #9AC1E0",
+"1D c #9EC7E7",
+"1E c #A1CAEA",
+"1F c #A8D3F5",
+"1G c #ABD6F8",
+"1H c #ACD7F9",
+"1I c #ADD8FB",
+"1J c #B0D8FB",
+"1K c #AED8FE",
+"1L c #707D86",
+"1M c #3D4A53",
+"1N c #798B99",
+"1O c #B6C8D6",
+"1P c #B8D6EE",
+"1Q c #B1D8F9",
+"1R c #AFDAFC",
+"1S c #B1DCFE",
+"1T c #B1DCFF",
+"1U c #B0DBFD",
+"1V c #AFDAFD",
+"1W c #A6CFEF",
+"1X c #A3CCEC",
+"1Y c #A0C7E6",
+"1Z c #96BDDC",
+"1& c #86A3CB",
+"2 c #83A0C8",
+"20 c #8C9DD3",
+"21 c #8A9BD1",
+"22 c #7280AF",
+"23 c #5A6897",
+"24 c #647996",
+"25 c #7B90AD",
+"26 c #89A9C2",
+"27 c #9ABAD3",
+"28 c #9CC3E2",
+"29 c #A1C8E7",
+"2a c #A2CBEB",
+"2b c #A9D2F2",
+"2c c #B0DBFE",
+"2d c #B3DBFE",
+"2e c #B1DBFF",
+"2f c #2D3A43",
+"2g c #606D76",
+"2h c #3F515F",
+"2i c #000F1D",
+"2j c #1E3C54",
+"2k c #537189",
+"2l c #7DA4C5",
+"2m c #AED5F6",
+"2n c #B6DFFB",
+"2o c #B6DFFD",
+"2p c #B5DEFA",
+"2q c #B4DDF9",
+"2r c #B4DBFC",
+"2s c #AED5F2",
+"2t c #AAD1EE",
+"2u c #A8CDE8",
+"2v c #A4C9E4",
+"2w c #9BB4DD",
+"2x c #849DC6",
+"2y c #8C9CD8",
+"2z c #93A3DF",
+"2A c #8497BF",
+"2B c #6679A1",
+"2C c #5C758B",
+"2D c #6F889E",
+"2E c #7C9FB5",
+"2F c #8FB2C8",
+"2G c #9ABED8",
+"2H c #A2C6E0",
+"2I c #A4C9E3",
+"2J c #A7CCE6",
+"2K c #A8D0EA",
+"2L c #A9D1EB",
+"2M c #ABD3ED",
+"2N c #ADD5EF",
+"2O c #B0D7F4",
+"2P c #B0D9F5",
+"2Q c #B2DBF7",
+"2R c #B3DAF9",
+"2S c #B7E0FE",
+"2T c #B7DEFB",
+"2U c #B6DFFF",
+"2V c #B7E0FF",
+"2W c #3D4547",
+"2X c #A5ADAF",
+"2Y c #F8F8F6",
+"2Z c #F1F1EF",
+"2& c #B8B8B8",
+"3 c #797979",
+"30 c #3E3E3E",
+"31 c #090909",
+"32 c #272F32",
+"33 c #50585B",
+"34 c #788691",
+"35 c #A8B6C1",
+"36 c #C1DCED",
+"37 c #B9DEF9",
+"38 c #B7DEFD",
+"39 c #B8E1FD",
+"3a c #B8E1FF",
+"3b c #B7E0FC",
+"3c c #B5DCFD",
+"3d c #B2D9FA",
+"3e c #A6CBE6",
+"3f c #9ABFDA",
+"3g c #859EC7",
+"3h c #8BA4CD",
+"3i c #98A8E4",
+"3j c #8191CD",
+"3k c #60739B",
+"3l c #63769E",
+"3m c #7891A7",
+"3n c #8CA5BB",
+"3o c #95B8CE",
+"3p c #9EC1D7",
+"3q c #A3C7E1",
+"3r c #A6CAE4",
+"3s c #A9CEE8",
+"3t c #AAD2EC",
+"3u c #ACD4EE",
+"3v c #B1DAF6",
+"3w c #B4DBFA",
+"3x c #B8DFFC",
+"3y c #BAE1FE",
+"3z c #464E50",
+"3A c #9EA6A8",
+"3B c #FDFDFB",
+"3C c #FCFCFA",
+"3D c #FDFDFD",
+"3E c #F9F9F9",
+"3F c #C5CDD0",
+"3G c #929A9D",
+"3H c #56646F",
+"3I c #192732",
+"3J c #052031",
+"3K c #405B6C",
+"3L c #779CB7",
+"3M c #BCE1FC",
+"3N c #B9E0FF",
+"3O c #B8DFFE",
+"3P c #BCE5FB",
+"3Q c #BCE4FD",
+"3R c #BBE5FD",
+"3S c #BEE4FB",
+"3T c #BBE4FA",
+"3U c #B9E2F8",
+"3V c #B8DEF5",
+"3W c #B5DBF2",
+"3X c #B1D5EB",
+"3Y c #ABCFE5",
+"3Z c #A4C0E7",
+"3& c #88A4CB",
+"4 c #91A4DF",
+"40 c #A1B4EF",
+"41 c #8391B6",
+"42 c #637196",
+"43 c #647F90",
+"44 c #7D98A9",
+"45 c #8FAFC4",
+"46 c #9BBBD0",
+"47 c #A1C4D8",
+"48 c #A6C9DD",
+"49 c #A8CBE1",
+"4a c #AACDE3",
+"4b c #ABD1E6",
+"4c c #ADD3E8",
+"4d c #AED3E6",
+"4e c #B0D5E8",
+"4f c #B1D5ED",
+"4g c #B2D6EE",
+"4h c #B3D7EF",
+"4i c #B5D9F1",
+"4j c #B6DCF3",
+"4k c #B8DEF3",
+"4l c #B9DFF4",
+"4m c #BBE0FA",
+"4n c #BCE1FB",
+"4o c #BAE3F9",
+"4p c #BEE3FD",
+"4q c #4B5356",
+"4r c #9DA5A8",
+"4s c #FEFFFF",
+"4t c #FDFFFE",
+"4u c #FFFFFF",
+"4v c #FEFEFE",
+"4w c #DFDFE1",
+"4x c #969698",
+"4y c #454545",
+"4z c #030303",
+"4A c #526875",
+"4B c #C8DEEB",
+"4C c #BBE3FC",
+"4D c #BEE7FD",
+"4E c #BEE6FF",
+"4F c #BDE7FF",
+"4G c #C0E6FD",
+"4H c #BAE0F7",
+"4I c #B2D6EC",
+"4J c #A9CDE3",
+"4K c #97B3DA",
+"4L c #8CA8CF",
+"4M c #AABDF8",
+"4N c #899CD7",
+"4O c #627095",
+"4P c #6A789D",
+"4Q c #93AEBF",
+"4R c #A1C1D6",
+"4S c #A3C6DA",
+"4T c #A7CAE0",
+"4U c #A9CCE2",
+"4V c #A8CCE2",
+"4W c #A9CFE4",
+"4X c #AAD0E5",
+"4Y c #ACD1E4",
+"4Z c #AED2EA",
+"4& c #ADD1E9",
+"5 c #AFD3EB",
+"50 c #B3D9F0",
+"51 c #B4DAF1",
+"52 c #B5DBF0",
+"53 c #BFE5FC",
+"54 c #BDE6FC",
+"55 c #C0E5FF",
+"56 c #495154",
+"57 c #9EA6A9",
+"58 c #FCFEFD",
+"59 c #FEFEFF",
+"5a c #E7E7E7",
+"5b c #182E3B",
+"5c c #8197A4",
+"5d c #BDE5FE",
+"5e c #C2E8FD",
+"5f c #C3E7FF",
+"5g c #C3E9FE",
+"5h c #C2E6FE",
+"5i c #C1E5FB",
+"5j c #BEE2F8",
+"5k c #BCDFF5",
+"5l c #B7DAF0",
+"5m c #B4D4EB",
+"5n c #A6C6DD",
+"5o c #90A5DE",
+"5p c #A5BAF3",
+"5q c #A4B6E4",
+"5r c #6577A5",
+"5s c #647786",
+"5t c #8093A2",
+"5u c #8DAABA",
+"5v c #9CB9C9",
+"5w c #9FBED0",
+"5x c #A2C1D3",
+"5y c #A5C6D9",
+"5z c #A6C7DA",
+"5A c #A9CADD",
+"5B c #A8C9DC",
+"5C c #AAC9DE",
+"5D c #ABCADF",
+"5E c #AEC7E6",
+"5F c #ADC8E6",
+"5G c #AEC9E7",
+"5H c #ADCCE0",
+"5I c #B0CFE3",
+"5J c #B2D2E7",
+"5K c #B6D6EB",
+"5L c #B5DAEC",
+"5M c #B8DDEF",
+"5N c #B9DDF3",
+"5O c #BCE0F6",
+"5P c #C1E5FD",
+"5Q c #C2E8FB",
+"5R c #C1E7FC",
+"5S c #C4E8FF",
+"5T c #454A4E",
+"5U c #A9AEB2",
+"5V c #E9E9E9",
+"5W c #000D1A",
+"5X c #C4DAE7",
+"5Y c #C4E6FF",
+"5Z c #C3E5FE",
+"5& c #C0E4FC",
+"6 c #BFE3F9",
+"60 c #BADDF3",
+"61 c #B5D8EE",
+"62 c #B1D1E8",
+"63 c #96B6CD",
+"64 c #94A9E2",
+"65 c #BDD2FF",
+"66 c #8092C0",
+"67 c #5E709E",
+"68 c #728594",
+"69 c #8C9FAE",
+"6a c #92AFBF",
+"6b c #99B6C6",
+"6c c #9AB9CB",
+"6d c #9CBBCD",
+"6e c #9EBFD2",
+"6f c #9FC0D3",
+"6g c #9DBED1",
+"6h c #96B5CA",
+"6i c #89A8BD",
+"6j c #7891B0",
+"6k c #6E87A6",
+"6l c #6E89A7",
+"6m c #809BB9",
+"6n c #94B3C7",
+"6o c #A3C2D6",
+"6p c #A8C8DD",
+"6q c #ADCDE2",
+"6r c #AED3E5",
+"6s c #B1D6E8",
+"6t c #B4D8EE",
+"6u c #B7DBF1",
+"6v c #BADEF4",
+"6w c #BEE2FA",
+"6x c #C0E6FB",
+"6y c #C1E7FA",
+"6z c #C2E6FF",
+"6A c #393E42",
+"6B c #B6BBBF",
+"6C c #8D8D8D",
+"6D c #415764",
+"6E c #CDE3F0",
+"6F c #C2E4FD",
+"6G c #BCE6FE",
+"6H c #BCE2F9",
+"6I c #B9DFF6",
+"6J c #B7DBF3",
+"6K c #AFCDF3",
+"6L c #91AFD5",
+"6M c #A9BEEB",
+"6N c #BED3FF",
+"6O c #687B9C",
+"6P c #627596",
+"6Q c #7792A5",
+"6R c #8AA5B8",
+"6S c #90ADBF",
+"6T c #93B0C2",
+"6U c #96B3C5",
+"6V c #98B5C7",
+"6W c #98B7CB",
+"6X c #97B6CA",
+"6Y c #98B0D2",
+"6Z c #93ABCD",
+"6& c #8A9FD6",
+"7 c #768BC2",
+"70 c #6E7CBD",
+"71 c #6F7DBE",
+"72 c #6E7BAF",
+"73 c #6D77B2",
+"74 c #6B75B0",
+"75 c #6D7FAF",
+"76 c #8496C6",
+"77 c #9BBACF",
+"78 c #A4C3D8",
+"79 c #A6CBDE",
+"7a c #ABD0E3",
+"7b c #AED2E8",
+"7c c #B7DDF4",
+"7d c #BDE2FC",
+"7e c #BCE5F9",
+"7f c #BDE6FA",
+"7g c #BEE7FB",
+"7h c #BFE7FF",
+"7i c #292D2E",
+"7j c #CBCFD0",
+"7k c #FDFEFF",
+"7l c #2B2C2E",
+"7m c #82A8BD",
+"7n c #B9E3FB",
+"7o c #B8E2FA",
+"7p c #B4D8F0",
+"7q c #AAC8EE",
+"7r c #86A4CA",
+"7s c #ABC0ED",
+"7t c #677A9B",
+"7u c #657899",
+"7v c #7994A7",
+"7w c #87A2B5",
+"7x c #8AA7B9",
+"7y c #8CA9BB",
+"7z c #8EABBD",
+"7A c #8DAABC",
+"7B c #88A7BB",
+"7C c #87A6BA",
+"7D c #8098BA",
+"7E c #7189AB",
+"7F c #6D82B9",
+"7G c #6F84BB",
+"7H c #7785C6",
+"7I c #8A98D9",
+"7J c #ADBAEE",
+"7K c #C4D1FF",
+"7L c #B6C0FB",
+"7M c #838DC8",
+"7N c #6779A9",
+"7O c #6678A8",
+"7P c #7493A8",
+"7Q c #91B0C5",
+"7R c #9CC1D4",
+"7S c #A1C6D9",
+"7T c #A6CAE0",
+"7U c #ACD0E6",
+"7V c #AFD5EC",
+"7W c #B7DCF6",
+"7X c #B9DEF8",
+"7Y c #B9E2F6",
+"7Z c #BAE3F7",
+"7& c #BBE4F8",
+"8 c #111516",
+"80 c #E4E8E9",
+"81 c #C9CACC",
+"82 c #202123",
+"83 c #BEE4F9",
+"84 c #BAE4FD",
+"85 c #BAE3FF",
+"86 c #B8E4FD",
+"87 c #B9E3FC",
+"88 c #B8E2FB",
+"89 c #B4DCF6",
+"8a c #B1D9F3",
+"8b c #AED3ED",
+"8c c #A4C6E2",
+"8d c #85A7C3",
+"8e c #A0B4E9",
+"8f c #C1D5FF",
+"8g c #8594CB",
+"8h c #5D6CA3",
+"8i c #6779A1",
+"8j c #7385AD",
+"8k c #7990AF",
+"8l c #8097B6",
+"8m c #7D92BD",
+"8n c #798BCB",
+"8o c #7183C3",
+"8p c #7584BD",
+"8q c #7D8CC5",
+"8r c #909DBD",
+"8s c #B0BDDD",
+"8t c #D4E0EE",
+"8u c #E9F5FF",
+"8v c #EDF8FE",
+"8w c #EEF9FF",
+"8x c #EFF7FF",
+"8y c #D9E1EC",
+"8z c #939FC9",
+"8A c #6372AB",
+"8B c #7483BC",
+"8C c #8DACC1",
+"8D c #9AB9CE",
+"8E c #A0C2DB",
+"8F c #A7C9E2",
+"8G c #A9CFE6",
+"8H c #AED4EB",
+"8I c #B1D9F2",
+"8J c #B3DBF4",
+"8K c #B5DFF8",
+"8L c #B7E1FA",
+"8M c #B9E2FE",
+"8N c #BAE4FC",
+"8O c #5B6972",
+"8P c #64727B",
+"8Q c #BBE5FE",
+"8R c #BBE3FD",
+"8S c #BBE4FF",
+"8T c #B7E3FC",
+"8U c #B9E2FF",
+"8V c #B6E0F9",
+"8W c #AACFE9",
+"8X c #9FC1DD",
+"8Y c #87A9C5",
+"8Z c #8195CA",
+"8& c #A7BBF0",
+"9 c #8998CF",
+"90 c #7382B9",
+"91 c #6E80A8",
+"92 c #63759D",
+"93 c #5F7695",
+"94 c #7188A7",
+"95 c #758AB5",
+"96 c #7388B3",
+"97 c #788ACA",
+"98 c #8092D2",
+"99 c #99A8E1",
+"9a c #C2D1FF",
+"9b c #DEEBFF",
+"9c c #E4F1FF",
+"9d c #E7F3FF",
+"9e c #F0F8FF",
+"9f c #DDE9FF",
+"9g c #A2AED8",
+"9h c #6C7BB4",
+"9i c #6170A9",
+"9j c #68879C",
+"9k c #88A7BC",
+"9l c #95B7D0",
+"9m c #9EC0D9",
+"9n c #A3C9E0",
+"9o c #ACD4ED",
+"9p c #B0D8F1",
+"9q c #B2DCF5",
+"9r c #B4DEF7",
+"9s c #BAE2FB",
+"9t c #90B8D1",
+"9u c #2D2D2D",
+"9v c #F4F4F4",
+"9w c #03111A",
+"9x c #B1BFC8",
+"9y c #B9E1FB",
+"9z c #BAE2FC",
+"9A c #B5E1FC",
+"9B c #B5E1FE",
+"9C c #B4E0FD",
+"9D c #ADD4F1",
+"9E c #A9D0ED",
+"9F c #A5CAE7",
+"9G c #9FC4E1",
+"9H c #9ABCD8",
+"9I c #88AAC6",
+"9J c #7A8DD1",
+"9K c #7B8ED2",
+"9L c #8B9FD2",
+"9M c #9DB1E4",
+"9N c #97A9E7",
+"9O c #7B8DCB",
+"9P c #6B7CC1",
+"9Q c #7384C9",
+"9R c #8191C4",
+"9S c #8B9BCE",
+"9T c #ABBBD5",
+"9U c #CADAF4",
+"9V c #DBEAFF",
+"9W c #DAE9FF",
+"9X c #D2E0FF",
+"9Y c #D4E2FF",
+"9Z c #E3F0FF",
+"9& c #E8F5FF",
+"a c #EDF7FF",
+"a0 c #EDFAFF",
+"a1 c #F0F9FE",
+"a2 c #EDF6FB",
+"a3 c #A6AFD6",
+"a4 c #717AA1",
+"a5 c #5E6EA2",
+"a6 c #6B7BAF",
+"a7 c #85A5BC",
+"a8 c #98B8CF",
+"a9 c #9DC3D8",
+"aa c #A4CADF",
+"ab c #A8CFEC",
+"ac c #ACD3F0",
+"ad c #AFD8F4",
+"ae c #B4DDFB",
+"af c #B3DFFC",
+"ag c #B6E2FD",
+"ah c #BADFF9",
+"ai c #B4E0FB",
+"aj c #B5E1FA",
+"ak c #B5E0FF",
+"al c #BEDEF5",
+"am c #7090A7",
+"an c #595959",
+"ao c #9E9E9E",
+"ap c #28485D",
+"aq c #BEDEF3",
+"ar c #B6E2FF",
+"as c #B3DFFA",
+"at c #B2DEFB",
+"au c #B1DDFA",
+"av c #AED7F3",
+"aw c #AAD3EF",
+"ax c #A7CEEB",
+"ay c #A2C9E6",
+"az c #98BDDA",
+"aA c #93B5D1",
+"aB c #84A6C2",
+"aC c #8194D8",
+"aD c #95A8EC",
+"aE c #B4C8FB",
+"aF c #ABBFF2",
+"aG c #90A2E0",
+"aH c #7C8ECC",
+"aI c #7F90D5",
+"aJ c #91A2E7",
+"aK c #B0C0F3",
+"aL c #CDDDFF",
+"aM c #DEEEFF",
+"aN c #D8E8FF",
+"aO c #CDDCFD",
+"aP c #BECDEE",
+"aQ c #AFBDEC",
+"aR c #A9B7E6",
+"aS c #CFDCED",
+"aT c #ECF6FF",
+"aU c #E7F1FA",
+"aV c #E2EFF7",
+"aW c #ECF5FA",
+"aX c #F1FAFF",
+"aY c #EAF3FF",
+"aZ c #6777AB",
+"a& c #5D6DA1",
+"b c #608097",
+"b0 c #82A2B9",
+"b1 c #92B8CD",
+"b2 c #A1C8E5",
+"b3 c #A6CDEA",
+"b4 c #A9D2EE",
+"b5 c #AFD8F6",
+"b6 c #B0D9F7",
+"b7 c #ABD7F2",
+"b8 c #83A8C2",
+"b9 c #90B5CF",
+"ba c #B4E0F9",
+"bb c #B4DFFF",
+"bc c #45657C",
+"bd c #8A8A8A",
+"be c #3A3A3A",
+"bf c #7595AA",
+"bg c #BDDDF2",
+"bh c #B1E0FE",
+"bi c #B2DFFE",
+"bj c #B1DEFD",
+"bk c #B0DDFC",
+"bl c #AFDCFB",
+"bm c #ADDAF9",
+"bn c #ABD8F5",
+"bo c #AAD7F4",
+"bp c #A8D4F1",
+"bq c #A3CFEC",
+"br c #A2CAE4",
+"bs c #9CC4DE",
+"bt c #99BED8",
+"bu c #91B6D0",
+"bv c #8FACD8",
+"bw c #7F9CC8",
+"bx c #8599DE",
+"by c #9BAFF4",
+"bz c #8FA2E4",
+"bA c #7E91D3",
+"bB c #8698C8",
+"bC c #99ABDB",
+"bD c #B4C4DD",
+"bE c #D0E0F9",
+"bF c #DEEEFD",
+"bG c #DFEFFE",
+"bH c #DEEFFF",
+"bI c #C5D6F4",
+"bJ c #B5B6FF",
+"bK c #9E9FFF",
+"bL c #7F83FE",
+"bM c #7C80FB",
+"bN c #BFCDE8",
+"bO c #E2F0FF",
+"bP c #C9F5E6",
+"bQ c #BBE7D8",
+"bR c #98EAA8",
+"bS c #8DDF9D",
+"bT c #C4E4D9",
+"bU c #E0FFF5",
+"bV c #F3FBFE",
+"bW c #EFF7FA",
+"bX c #A5ADD1",
+"bY c #6E769A",
+"bZ c #5D6B9C",
+"b& c #6B79AA",
+"c c #83A7BD",
+"c0 c #96BAD0",
+"c1 c #9BC2DF",
+"c2 c #A3CFEA",
+"c3 c #A6D2ED",
+"c4 c #AAD6F3",
+"c5 c #ACD8F5",
+"c6 c #AEDBFC",
+"c7 c #B0DDFE",
+"c8 c #BDDCF1",
+"c9 c #C4DAE8",
+"ca c #9CB2C0",
+"cb c #7A848E",
+"cc c #4F5963",
+"cd c #25292A",
+"ce c #080C0D",
+"cf c #343537",
+"cg c #000103",
+"ch c #B2DFFF",
+"ci c #B9DDF7",
+"cj c #B6DDFA",
+"ck c #B0DFFD",
+"cl c #B2DFFC",
+"cm c #B3DEFE",
+"cn c #B1E0FC",
+"co c #C1DBEC",
+"cp c #1C3647",
+"cq c #C2C2C2",
+"cr c #CBD0D6",
+"cs c #000208",
+"ct c #B9DDF5",
+"cu c #C5DBE9",
+"cv c #9AB0BE",
+"cw c #6F7A80",
+"cx c #49545A",
+"cy c #383D41",
+"cz c #34393D",
+"cA c #3E474E",
+"cB c #5B646B",
+"cC c #889EAC",
+"cD c #C0DBEE",
+"cE c #BFDAED",
+"cF c #86A0B1",
+"cG c #A1B3C1",
+"cH c #9FB1BF",
+"cI c #BBD2E0",
+"cJ c #C3DAE8",
+"cK c #C0DCEA",
+"cL c #C1DDEB",
+"cM c #B1DFFF",
+"cN c #AFDEFC",
+"cO c #ACD9F8",
+"cP c #AAD7F6",
+"cQ c #A7D4F1",
+"cR c #A5D2EF",
+"cS c #A1CDEA",
+"cT c #9ECAE7",
+"cU c #9BC3DD",
+"cV c #95BDD7",
+"cW c #92B7D1",
+"cX c #8BB0CA",
+"cY c #7794C0",
+"cZ c #7D9AC6",
+"c& c #7E92D7",
+"d c #8497D9",
+"d0 c #9AADEF",
+"d1 c #B5C7F7",
+"d2 c #CEE0FF",
+"d3 c #DDEDFF",
+"d4 c #DBECFF",
+"d5 c #C1D2F0",
+"d6 c #898AF4",
+"d7 c #7273DD",
+"d8 c #696DE8",
+"d9 c #9498FF",
+"da c #D7E5FF",
+"db c #D9E7FF",
+"dc c #B1DDCE",
+"dd c #9FCBBC",
+"de c #73C583",
+"df c #59AB69",
+"dg c #A7C7BC",
+"dh c #DDFDF2",
+"di c #F4FCFF",
+"dj c #E8F0FF",
+"dk c #A6AED2",
+"dl c #6270A1",
+"dm c #5A6899",
+"dn c #5E8298",
+"do c #89ADC3",
+"dp c #93BAD7",
+"dq c #9ECAE5",
+"dr c #A2CEE9",
+"ds c #A7D3F0",
+"dt c #ACD9FA",
+"du c #8CB8D5",
+"dv c #58778C",
+"dw c #214055",
+"dx c #000816",
+"dy c #1F3543",
+"dz c #5C6670",
+"dA c #929CA6",
+"dB c #CED2D3",
+"dC c #F8FCFD",
+"dD c #B8B9BB",
+"dE c #333436",
+"dF c #B1DEFF",
+"dG c #A6D3F4",
+"dH c #7A9EB8",
+"dI c #557993",
+"dJ c #44677D",
+"dK c #4A6D83",
+"dL c #678EAB",
+"dM c #B1DEFB",
+"dN c #B2DDFD",
+"dO c #AFDEFA",
+"dP c #B0DFFB",
+"dQ c #B5CFE0",
+"dR c #000F20",
+"dS c #F8F8F8",
+"dT c #5D6268",
+"dU c #666B71",
+"dV c #84A8C0",
+"dW c #3F637B",
+"dX c #091F2D",
+"dY c #1C3240",
+"dZ c #667177",
+"d& c #98A3A9",
+"e c #B8BDC1",
+"e0 c #BBC0C4",
+"e1 c #AAB3BA",
+"e2 c #7E878E",
+"e3 c #263C4A",
+"e4 c #192F3D",
+"e5 c #7AA6C1",
+"e6 c #B2DEF9",
+"e7 c #7FAACA",
+"e8 c #425D70",
+"e9 c #000A1D",
+"ea c #062031",
+"eb c #5A7485",
+"ec c #90BDDC",
+"ed c #000B19",
+"ee c #0C1E2C",
+"ef c #001422",
+"eg c #000917",
+"eh c #001220",
+"ei c #031F2D",
+"ej c #719DB8",
+"ek c #B0DEFF",
+"el c #AFDDFE",
+"em c #AEDCFD",
+"en c #AEDCFF",
+"eo c #AEDCFE",
+"ep c #ACDDFD",
+"eq c #ABDCFC",
+"er c #ACDAFC",
+"es c #AAD8F9",
+"et c #A8D6F7",
+"eu c #A8D5F6",
+"ev c #A5D2F3",
+"ew c #A2CFEE",
+"ex c #9FCCEB",
+"ey c #9FC8E6",
+"ez c #99C2E0",
+"eA c #96BBD8",
+"eB c #90B5D2",
+"eC c #839ECB",
+"eD c #6984B1",
+"eE c #798ED1",
+"eF c #7C91D4",
+"eG c #8698CA",
+"eH c #9EB0E2",
+"eI c #B9CAE4",
+"eJ c #CFE0FA",
+"eK c #DAEBFD",
+"eL c #DBECFE",
+"eM c #E0F0FF",
+"eN c #E1F1FF",
+"eO c #E2EEFF",
+"eP c #D7E3F9",
+"eQ c #AFB6ED",
+"eR c #9EA5DC",
+"eS c #B6BFDC",
+"eT c #D7E0FD",
+"eU c #E3F6FD",
+"eV c #CEE1E8",
+"eW c #88DA92",
+"eX c #69BB73",
+"eY c #43A945",
+"eZ c #44AA46",
+"e& c #BCD4C7",
+"f c #E7FFF2",
+"f0 c #F6FBFF",
+"f1 c #F7FCFF",
+"f2 c #E9EEF2",
+"f3 c #9AA1CD",
+"f4 c #646B97",
+"f5 c #546590",
+"f6 c #7182AD",
+"f7 c #8AAFCA",
+"f8 c #94B9D4",
+"f9 c #97C3E0",
+"fa c #A1CEEF",
+"fb c #A7D5F6",
+"fc c #A9D7F8",
+"fd c #ADDBFD",
+"fe c #ADDBFC",
+"ff c #C3D6E5",
+"fg c #6F8291",
+"fh c #2A2E31",
+"fi c #1D2124",
+"fj c #707070",
+"fk c #B6B6B6",
+"fl c #F0F0F0",
+"fm c #FCFCFC",
+"fn c #FBFDFC",
+"fo c #FAFCFB",
+"fp c #FBFBFD",
+"fq c #72797F",
+"fr c #5E656B",
+"fs c #3D4144",
+"ft c #060A0D",
+"fu c #474747",
+"fv c #747474",
+"fw c #858585",
+"fx c #535353",
+"fy c #050505",
+"fz c #59707E",
+"fA c #C0D7E5",
+"fB c #AFDBFE",
+"fC c #85939C",
+"fD c #3A4851",
+"fE c #FBFBFB",
+"fF c #FBFCFE",
+"fG c #FCFDFF",
+"fH c #FCFCFE",
+"fI c #E1E1E1",
+"fJ c #000C1E",
+"fK c #AAC7D9",
+"fL c #B6DAF4",
+"fM c #B5D9F3",
+"fN c #848E98",
+"fO c #2B353F",
+"fP c #252525",
+"fQ c #868686",
+"fR c #DADCDB",
+"fS c #AFAFAF",
+"fT c #071017",
+"fU c #868F96",
+"fV c #AFDCFD",
+"fW c #ACDDFE",
+"fX c #B3DAF7",
+"fY c #B4DBF8",
+"fZ c #B1C3CF",
+"f& c #647682",
+"g c #262729",
+"g0 c #2A2B2D",
+"g1 c #898B8A",
+"g2 c #E4E6E5",
+"g3 c #7A848D",
+"g4 c #5B656E",
+"g5 c #C3D6E4",
+"g6 c #263947",
+"g7 c #919191",
+"g8 c #EBEFF2",
+"g9 c #262A2D",
+"ga c #5C83A2",
+"gb c #ACDAFB",
+"gc c #ACDAFE",
+"gd c #A9DAFA",
+"ge c #A8D9F9",
+"gf c #A8D6F8",
+"gg c #A7D5F7",
+"gh c #A6D4F5",
+"gi c #A3D1F2",
+"gj c #A2CFF0",
+"gk c #9FCCED",
+"gl c #9BC8E7",
+"gm c #97C4E3",
+"gn c #96BFDD",
+"go c #90B9D7",
+"gp c #89AECB",
+"gq c #6D92AF",
+"gr c #7691BE",
+"gs c #7B96C3",
+"gt c #7E93D6",
+"gu c #94A9EC",
+"gv c #B7C9FB",
+"gw c #CADCFF",
+"gx c #D7E8FF",
+"gy c #D9EAFF",
+"gz c #DCEDFF",
+"gA c #DFEFFF",
+"gB c #D9E9F9",
+"gC c #D6E2F8",
+"gD c #DBE2FF",
+"gE c #DDE4FF",
+"gF c #EBF4FF",
+"gG c #E9F2FF",
+"gH c #E4F7FE",
+"gI c #D8EBF2",
+"gJ c #95E79F",
+"gK c #74C67E",
+"gL c #67CD69",
+"gM c #87ED89",
+"gN c #E0F8EB",
+"gO c #EBFFF6",
+"gP c #F8FDFF",
+"gQ c #D7DEFF",
+"gR c #8990BC",
+"gS c #586994",
+"gT c #7196B1",
+"gU c #8CB1CC",
+"gV c #91BDDA",
+"gW c #9CC9EA",
+"gX c #A4D2F3",
+"gY c #A9D7F9",
+"gZ c #AAD8FA",
+"g& c #ABD9FA",
+"h c #A1CFF0",
+"h0 c #132635",
+"h1 c #3B4E5D",
+"h2 c #B9BDC0",
+"h3 c #F6FAFD",
+"h4 c #F8FAF9",
+"h5 c #F9FBFA",
+"h6 c #F9F9FB",
+"h7 c #343B41",
+"h8 c #3B4248",
+"h9 c #A3A7AA",
+"ha c #EEF2F5",
+"hb c #FAFAFA",
+"hc c #DBDBDB",
+"hd c #324957",
+"he c #ADD9FC",
+"hf c #4F5D66",
+"hg c #829099",
+"hh c #F9FAFC",
+"hi c #FAFAFC",
+"hj c #6C6C6C",
+"hk c #436072",
+"hl c #BAD7E9",
+"hm c #84A8C2",
+"hn c #1B3F59",
+"ho c #A8B2BC",
+"hp c #BBC4CB",
+"hq c #000910",
+"hr c #8CB9DA",
+"hs c #ADDAFB",
+"ht c #AADBFC",
+"hu c #A9DAFB",
+"hv c #8CB3D0",
+"hw c #5E85A2",
+"hx c #00111D",
+"hy c #576975",
+"hz c #C4C5C7",
+"hA c #828C95",
+"hB c #545E67",
+"hC c #536674",
+"hD c #415462",
+"hE c #606467",
+"hF c #44484B",
+"hG c #B1D8F7",
+"hH c #AADBFB",
+"hI c #A8DAFD",
+"hJ c #A9D9FF",
+"hK c #A8DAFF",
+"hL c #A7D7FB",
+"hM c #A5D5F9",
+"hN c #A4D2F6",
+"hO c #A2D0F2",
+"hP c #9FCDEF",
+"hQ c #99C6E7",
+"hR c #98C1DF",
+"hS c #93BCDA",
+"hT c #90AFDD",
+"hU c #7B9AC8",
+"hV c #788DCE",
+"hW c #7F94D5",
+"hX c #8295CD",
+"hY c #96A9E1",
+"hZ c #B2C7E6",
+"h& c #C5DAF9",
+"i c #D7E9FF",
+"i0 c #D8EAFF",
+"i1 c #DBEBFB",
+"i2 c #DDEDFD",
+"i3 c #DDEEFF",
+"i4 c #DDF0FF",
+"i5 c #F2DAD6",
+"i6 c #E9D1CD",
+"i7 c #FFB781",
+"i8 c #FFAA74",
+"i9 c #D9AB94",
+"ia c #FFE1CA",
+"ib c #E5F5FF",
+"ic c #E5E8DD",
+"id c #E2E5DA",
+"ie c #D5E5D8",
+"if c #D4E4D7",
+"ig c #DCEAEA",
+"ih c #EAF8F8",
+"ii c #FAFFFF",
+"ij c #F7FAFF",
+"ik c #CCCFD8",
+"il c #727CAF",
+"im c #586295",
+"in c #5C7496",
+"io c #839BBD",
+"ip c #8BB4D2",
+"iq c #94BDDB",
+"ir c #A3CFF2",
+"is c #A5D1F4",
+"it c #A7D9FC",
+"iu c #A9DBFE",
+"iv c #A9D9FD",
+"iw c #8FBFE3",
+"ix c #1A1A1A",
+"iy c #F7F8FA",
+"iz c #F6F8F7",
+"iA c #F7F9F8",
+"iB c #F7F7F7",
+"iC c #CDCDCD",
+"iD c #E1E6E9",
+"iE c #84898C",
+"iF c #304352",
+"iG c #112433",
+"iH c #26353C",
+"iI c #85949B",
+"iJ c #F5F5F5",
+"iK c #F6F6F6",
+"iL c #F3F3F3",
+"iM c #545454",
+"iN c #3B5669",
+"iO c #BAD5E8",
+"iP c #AADAFF",
+"iQ c #ACD7F7",
+"iR c #A6D1F1",
+"iS c #DDDDDD",
+"iT c #F9F7F8",
+"iU c #F8F8FA",
+"iV c #F7F7F9",
+"iW c #D8DDE1",
+"iX c #03080C",
+"iY c #91BFE1",
+"iZ c #ABD9FB",
+"i& c #BED3E4",
+"j c #526778",
+"j0 c #171717",
+"j1 c #F7F5F6",
+"j2 c #E6E6E8",
+"j3 c #8D97A0",
+"j4 c #505A63",
+"j5 c #32434D",
+"j6 c #54656F",
+"j7 c #C4C4C4",
+"j8 c #838584",
+"j9 c #304C61",
+"ja c #B8D4E9",
+"jb c #B8D7EC",
+"jc c #B7D6EB",
+"jd c #828F97",
+"je c #334048",
+"jf c #1B191A",
+"jg c #8A8889",
+"jh c #EBEBEB",
+"ji c #899299",
+"jj c #4E575E",
+"jk c #B7D5ED",
+"jl c #7391A9",
+"jm c #202020",
+"jn c #E6E6E6",
+"jo c #0A2D49",
+"jp c #AACDE9",
+"jq c #A7D9FE",
+"jr c #A6D8FD",
+"js c #A4D4F8",
+"jt c #A2D2F6",
+"ju c #A3D1F5",
+"jv c #9FCDF1",
+"jw c #9DCBED",
+"jx c #98C6E8",
+"jy c #95C2E3",
+"jz c #90BDDE",
+"jA c #8DB6D4",
+"jB c #78A1BF",
+"jC c #7897C5",
+"jD c #7D9CCA",
+"jE c #8EA3E4",
+"jF c #ADC0F8",
+"jG c #C2D5FF",
+"jH c #D1E6FF",
+"jI c #D4E9FF",
+"jJ c #DCECFC",
+"jK c #DCEFFF",
+"jL c #D7EAFB",
+"jM c #E2CAC6",
+"jN c #D0B8B4",
+"jO c #ED9660",
+"jP c #D8814B",
+"jQ c #B4866F",
+"jR c #FFE4CD",
+"jS c #DAEAF9",
+"jT c #DBEBFA",
+"jU c #E9ECE1",
+"jV c #DFE2D7",
+"jW c #E2F2E5",
+"jX c #EDFBFB",
+"jY c #EEFCFC",
+"jZ c #FBFEFF",
+"j& c #F1F4FD",
+"k c #ABB5E8",
+"k0 c #606A9D",
+"k1 c #50688A",
+"k2 c #677FA1",
+"k3 c #80A9C7",
+"k4 c #8CB5D3",
+"k5 c #93BEE1",
+"k6 c #9FCBEE",
+"k7 c #A2CEF1",
+"k8 c #A3D3F9",
+"k9 c #A6D8FB",
+"ka c #020202",
+"kb c #F1F1F1",
+"kc c #F3F4F6",
+"kd c #F3F5F4",
+"ke c #F4F6F5",
+"kf c #EFEFEF",
+"kg c #0A0F12",
+"kh c #474C4F",
+"ki c #7E91A0",
+"kj c #A3B6C5",
+"kk c #8A99A0",
+"kl c #29383F",
+"km c #575757",
+"kn c #F2F2F2",
+"ko c #E8E8E8",
+"kp c #062134",
+"kq c #86A1B4",
+"kr c #507B9B",
+"ks c #F5F3F4",
+"kt c #F3F3F5",
+"ku c #F4F4F6",
+"kv c #595E62",
+"kw c #5A5F63",
+"kx c #A1CFF1",
+"ky c #2C4152",
+"kz c #394E5F",
+"kA c #F4F2F3",
+"kB c #727274",
+"kC c #0A0A0C",
+"kD c #3D4750",
+"kE c #757F88",
+"kF c #8899A3",
+"kG c #61727C",
+"kH c #000000",
+"kI c #989898",
+"kJ c #F2F4F3",
+"kK c #E7E9E8",
+"kL c #001227",
+"kM c #A3BFD4",
+"kN c #A8D8FC",
+"kO c #98C8EC",
+"kP c #57768B",
+"kQ c #00081D",
+"kR c #323F47",
+"kS c #98A5AD",
+"kT c #F0EEEF",
+"kU c #9099A0",
+"kV c #475057",
+"kW c #9BB9D1",
+"kX c #000A22",
+"kY c #BEBEBE",
+"kZ c #AAAAAA",
+"k& c #8EB1CD",
+"l c #B2D5F1",
+"l0 c #A8D8FF",
+"l1 c #A3D7FC",
+"l2 c #A5D6FE",
+"l3 c #A2D6FB",
+"l4 c #A3D4FC",
+"l5 c #A2D3FB",
+"l6 c #A0D2F7",
+"l7 c #9FD1F6",
+"l8 c #9DCDF3",
+"l9 c #99C9EF",
+"la c #97C5E7",
+"lb c #92C0E2",
+"lc c #91B7DC",
+"ld c #85ABD0",
+"le c #7B94D4",
+"lf c #738CCC",
+"lg c #8196D7",
+"lh c #889DDE",
+"li c #A3BAE4",
+"lj c #BBD2FC",
+"lk c #CEE2FD",
+"ll c #D0E4FF",
+"lm c #D1E3F9",
+"ln c #D3E5FB",
+"lo c #D6E8FF",
+"lp c #D9EBFF",
+"lq c #DBEDFF",
+"lr c #D7E8FA",
+"ls c #F5AD87",
+"lt c #D18963",
+"lu c #DE7130",
+"lv c #D86B2A",
+"lw c #C8BBB5",
+"lx c #F8EBE5",
+"ly c #EFE5A8",
+"lz c #F6ECAF",
+"lA c #FFE545",
+"lB c #FFD939",
+"lC c #E4D793",
+"lD c #FBEEAA",
+"lE c #F1F9FC",
+"lF c #F9FFFF",
+"lG c #FBFFFF",
+"lH c #E1E6F9",
+"lI c #959AAD",
+"lJ c #576397",
+"lK c #596599",
+"lL c #6F92AE",
+"lM c #89ACC8",
+"lN c #8DB9DC",
+"lO c #93BFE2",
+"lP c #9CCCF0",
+"lQ c #A0D1F9",
+"lR c #A1D5FA",
+"lS c #A3D7FE",
+"lT c #A4D8FD",
+"lU c #0E1215",
+"lV c #D6DADD",
+"lW c #F2F2F4",
+"lX c #E0E0E0",
+"lY c #243B4D",
+"lZ c #283F51",
+"l& c #80B0D4",
+"m c #A6D6FA",
+"m0 c #A4D5FD",
+"m1 c #25323B",
+"m2 c #86939C",
+"m3 c #7B8489",
+"m4 c #4A5358",
+"m5 c #A2D8FC",
+"m6 c #A5D6FF",
+"m7 c #BED1DF",
+"m8 c #000513",
+"m9 c #C5C7C6",
+"ma c #F1F3F2",
+"mb c #C5C5C5",
+"mc c #000821",
+"md c #A5C5DE",
+"me c #B4C7D5",
+"mf c #213442",
+"mg c #F0F2F1",
+"mh c #F1F1F3",
+"mi c #BDC4CA",
+"mj c #1C2329",
+"mk c #2B5472",
+"ml c #8EB7D5",
+"mm c #8EA8BF",
+"mn c #000F26",
+"mo c #E0DEDF",
+"mp c #F2F0F1",
+"mq c #404D56",
+"mr c #7A8790",
+"ms c #5E6367",
+"mt c #050A0E",
+"mu c #5F5F5F",
+"mv c #C6C6C6",
+"mw c #959EA5",
+"mx c #404950",
+"my c #A9D6F7",
+"mz c #AAD7F8",
+"mA c #383C3F",
+"mB c #7F8386",
+"mC c #BDBFBE",
+"mD c #001026",
+"mE c #7D99AF",
+"mF c #A0D4F9",
+"mG c #A1D2FA",
+"mH c #9FD0F8",
+"mI c #9ED0F5",
+"mJ c #9BCDF2",
+"mK c #95C5EB",
+"mL c #8BB9DB",
+"mM c #7CA2C7",
+"mN c #749ABF",
+"mO c #829BDB",
+"mP c #819ADA",
+"mQ c #96ABEC",
+"mR c #B7CCFF",
+"mS c #C3DAFF",
+"mT c #B4CBF5",
+"mU c #99ADC8",
+"mV c #8397B2",
+"mW c #788AA0",
+"mX c #8597AD",
+"mY c #99ABC3",
+"mZ c #C5D7EF",
+"m& c #D7E9FD",
+"n c #FFCEA8",
+"n0 c #F6AE88",
+"n1 c #FFA362",
+"n2 c #FFBF7E",
+"n3 c #F7EAE4",
+"n4 c #F5E8E2",
+"n5 c #EDE3A6",
+"n6 c #E5DB9E",
+"n7 c #FAD030",
+"n8 c #F6CC2C",
+"n9 c #EEE19D",
+"na c #FFFAB6",
+"nb c #F2FAFD",
+"nc c #C3C8DB",
+"nd c #6C78AC",
+"ne c #527591",
+"nf c #7B9EBA",
+"ng c #86B2D5",
+"nh c #8FBBDE",
+"ni c #94C4E8",
+"nj c #99C9ED",
+"nk c #9ECFF7",
+"nl c #A2D6FD",
+"nm c #222629",
+"nn c #BDC1C4",
+"no c #EFEFF1",
+"np c #EEEEEE",
+"nq c #515151",
+"nr c #566D7F",
+"ns c #B9D0E2",
+"nt c #95A2AB",
+"nu c #26333C",
+"nv c #EDEDED",
+"nw c #BEC7CC",
+"nx c #161F24",
+"ny c #A1D7FB",
+"nz c #A3D4FD",
+"nA c #A4D5FE",
+"nB c #647785",
+"nC c #3E515F",
+"nD c #EEF0EF",
+"nE c #EDEFEE",
+"nF c #F0F0F2",
+"nG c #5A7A93",
+"nH c #B1D1EA",
+"nI c #2B3E4C",
+"nJ c #5B6E7C",
+"nK c #A8A8AA",
+"nL c #030A10",
+"nM c #757C82",
+"nN c #ABD4F2",
+"nO c #B5CFE6",
+"nP c #2F4960",
+"nQ c #9A9899",
+"nR c #EFEDEE",
+"nS c #6B7881",
+"nT c #48555E",
+"nU c #3A3F43",
+"nV c #DBE0E4",
+"nW c #EEEEF0",
+"nX c #9BA4AB",
+"nY c #3A434A",
+"nZ c #426F90",
+"n& c #414548",
+"o c #E8ECEF",
+"o0 c #CDCFCE",
+"o1 c #131514",
+"o2 c #6B879D",
+"o3 c #B5D1E7",
+"o4 c #9FD4FC",
+"o5 c #9FD4FE",
+"o6 c #9ED3FD",
+"o7 c #9FD3FB",
+"o8 c #9ED2FA",
+"o9 c #9CD0F8",
+"oa c #9BCFF7",
+"ob c #9BCCF4",
+"oc c #97C8F0",
+"od c #8FBFE5",
+"oe c #8EB4E5",
+"of c #81A7D8",
+"og c #7D91DA",
+"oh c #8599E2",
+"oi c #8EA5D7",
+"oj c #ABC2F4",
+"ok c #C5D9F4",
+"ol c #AFC3DE",
+"om c #8B9096",
+"on c #858A90",
+"oo c #A8A7AC",
+"op c #B7B6BB",
+"oq c #C3C5C4",
+"or c #A3A5A4",
+"os c #8F9092",
+"ot c #737476",
+"ou c #A3AFBF",
+"ov c #D7E3F3",
+"ow c #DDECFF",
+"ox c #DEEDFF",
+"oy c #E3EFFD",
+"oz c #E1EDFB",
+"oA c #E3EDF7",
+"oB c #E7F1FB",
+"oC c #E6F2FE",
+"oD c #E9EBD6",
+"oE c #E0E2CD",
+"oF c #E8E0B9",
+"oG c #F4ECC5",
+"oH c #EFF7F9",
+"oI c #F2FAFC",
+"oJ c #F3FAFF",
+"oK c #F9FEFF",
+"oL c #FAFEFD",
+"oM c #FBFFFE",
+"oN c #F2F3F5",
+"oO c #A3A7D4",
+"oP c #626693",
+"oQ c #51678E",
+"oR c #6C82A9",
+"oS c #7EA9CB",
+"oT c #8BB6D8",
+"oU c #90C0E6",
+"oV c #98CCF4",
+"oW c #9ACEF6",
+"oX c #9DD1F9",
+"oY c #A0D3FE",
+"oZ c #9FD2FD",
+"o& c #303B41",
+"p c #A0ABB1",
+"p0 c #EAEAEA",
+"p1 c #A9B2B7",
+"p2 c #000308",
+"p3 c #9ED3FB",
+"p4 c #9FD5FB",
+"p5 c #99AEBF",
+"p6 c #132839",
+"p7 c #E7E5E6",
+"p8 c #040203",
+"p9 c #A0D4FC",
+"pa c #9FD2FF",
+"pb c #A5D3F5",
+"pc c #C3C3C3",
+"pd c #E9EBEA",
+"pe c #EAECEB",
+"pf c #EBEBED",
+"pg c #EAEAEC",
+"ph c #87949D",
+"pi c #24313A",
+"pj c #B3CFE5",
+"pk c #476379",
+"pl c #484848",
+"pm c #A1AAB1",
+"pn c #00060D",
+"po c #6B9BC3",
+"pp c #A3D3FB",
+"pq c #AAD1F0",
+"pr c #446B8A",
+"ps c #777777",
+"pt c #76838C",
+"pu c #4C5962",
+"pv c #090E12",
+"pw c #D3D8DC",
+"px c #ECECEC",
+"py c #A1A8AE",
+"pz c #333A40",
+"pA c #858F98",
+"pB c #101A23",
+"pC c #D8D8D8",
+"pD c #D6D6D6",
+"pE c #0C273C",
+"pF c #5B768B",
+"pG c #A1D4FF",
+"pH c #9DD2FC",
+"pI c #98C9F1",
+"pJ c #94C5ED",
+"pK c #91C1E7",
+"pL c #8BBBE1",
+"pM c #83A9DA",
+"pN c #7DA3D4",
+"pO c #879BE4",
+"pP c #97ABF4",
+"pQ c #BBD2FF",
+"pR c #9BAFCA",
+"pS c #7B8FAA",
+"pT c #B1B6BC",
+"pU c #C3C8CE",
+"pV c #CCCBD0",
+"pW c #CAC9CE",
+"pX c #C1C3C2",
+"pY c #B9BBBA",
+"pZ c #AEAFB1",
+"p& c #9C9D9F",
+"q c #778393",
+"q0 c #A8B4C4",
+"q1 c #DCEBFE",
+"q2 c #E4F0FE",
+"q3 c #E5F1FF",
+"q4 c #E8F2FC",
+"q5 c #E8F4FF",
+"q6 c #F4F6E1",
+"q7 c #F6F8E3",
+"q8 c #FFF8D1",
+"q9 c #F0F8FA",
+"qa c #F1F8FE",
+"qb c #F2F9FF",
+"qc c #F5FDFF",
+"qd c #D1D5FF",
+"qe c #8084B1",
+"qf c #546A91",
+"qg c #729DBF",
+"qh c #85B0D2",
+"qi c #8CBCE2",
+"qj c #92C2E8",
+"qk c #95C9F1",
+"ql c #9ED1FC",
+"qm c #3E494F",
+"qn c #8C979D",
+"qo c #343D42",
+"qp c #737C81",
+"qq c #9ED4FA",
+"qr c #8DA2B3",
+"qs c #1F3445",
+"qt c #E8E6E7",
+"qu c #141213",
+"qv c #8BBFE7",
+"qw c #9DD2FA",
+"qx c #A4D2F4",
+"qy c #3E6C8E",
+"qz c #585858",
+"qA c #E6E8E7",
+"qB c #E7E7E9",
+"qC c #CECED0",
+"qD c #05121B",
+"qE c #8D9AA3",
+"qF c #809CB2",
+"qG c #00192F",
+"qH c #D4D4D4",
+"qI c #D2D2D2",
+"qJ c #091219",
+"qK c #879097",
+"qL c #A2D2FA",
+"qM c #A9D0EF",
+"qN c #456C8B",
+"qO c #757575",
+"qP c #65727B",
+"qQ c #58656E",
+"qR c #51565A",
+"qS c #A4ABB1",
+"qT c #2E353B",
+"qU c #8ABFE7",
+"qV c #0F1922",
+"qW c #A6B0B9",
+"qX c #313131",
+"qY c #4A657A",
+"qZ c #B3CEE3",
+"q& c #9BD1FD",
+"r c #9BD1FF",
+"r0 c #9AD0FE",
+"r1 c #99D0F9",
+"r2 c #97CEF7",
+"r3 c #97CCF8",
+"r4 c #94C9F5",
+"r5 c #91C4EF",
+"r6 c #8EC1EC",
+"r7 c #8DBDE5",
+"r8 c #86B6DE",
+"r9 c #869DE9",
+"ra c #879EEA",
+"rb c #9BB7E6",
+"rc c #BFDBFF",
+"rd c #C7DFFB",
+"re c #9CB4D0",
+"rf c #96979B",
+"rg c #CBCCD0",
+"rh c #D0D0D0",
+"ri c #BBBBBB",
+"rj c #BFBFBF",
+"rk c #B7B7B5",
+"rl c #ACACAA",
+"rm c #929292",
+"rn c #7E7E7E",
+"ro c #85868A",
+"rp c #949599",
+"rq c #D8E5F6",
+"rr c #E1EEFF",
+"rs c #E4F0FC",
+"rt c #EAF4FF",
+"ru c #E9F6FF",
+"rv c #EAF7FF",
+"rw c #EBF8FF",
+"rx c #DCF0FF",
+"ry c #D3E7FF",
+"rz c #D5E7FF",
+"rA c #E1F3FF",
+"rB c #F0FAFF",
+"rC c #F3FDFF",
+"rD c #FAFCFF",
+"rE c #B1B3BF",
+"rF c #616CA2",
+"rG c #576298",
+"rH c #6185A5",
+"rI c #81A5C5",
+"rJ c #87B8E0",
+"rK c #8DBEE6",
+"rL c #92C5F0",
+"rM c #95C8F3",
+"rN c #96CCF8",
+"rO c #98CEFA",
+"rP c #47515B",
+"rQ c #7D8791",
+"rR c #E5E5E5",
+"rS c #BDBDBD",
+"rT c #000924",
+"rU c #ABCDE8",
+"rV c #9AD0FC",
+"rW c #9CD2FE",
+"rX c #6C7680",
+"rY c #505A64",
+"rZ c #E4E4E4",
+"r& c #161616",
+"s c #84B9E3",
+"s0 c #9CD1F9",
+"s1 c #A4CFF1",
+"s2 c #ABCEEC",
+"s3 c #AACDEB",
+"s4 c #9CD1FB",
+"s5 c #9FAFBE",
+"s6 c #000C1B",
+"s7 c #CBCBCD",
+"s8 c #E5E5E7",
+"s9 c #E0E4E7",
+"sa c #3B3F42",
+"sb c #3B698D",
+"sc c #A1CFF3",
+"sd c #373B3E",
+"se c #868A8D",
+"sf c #616161",
+"sg c #346286",
+"sh c #A2D0F4",
+"si c #9CD0FF",
+"sj c #9BCFFE",
+"sk c #AECCE6",
+"sl c #2C4A64",
+"sm c #34495A",
+"sn c #6E8394",
+"so c #98BBD7",
+"sp c #000723",
+"sq c #B2B2B0",
+"sr c #E5E5E3",
+"ss c #E5E3E4",
+"st c #E6E4E5",
+"su c #AAAFB5",
+"sv c #2C3137",
+"sw c #B3CCE0",
+"sx c #2A4357",
+"sy c #E1E1E3",
+"sz c #334A5C",
+"sA c #3B5264",
+"sB c #99CFFD",
+"sC c #98CFF8",
+"sD c #95CCF5",
+"sE c #96CBF7",
+"sF c #92C7F3",
+"sG c #90C3EE",
+"sH c #8CBFEA",
+"sI c #8ABAE2",
+"sJ c #83B3DB",
+"sK c #859CE8",
+"sL c #91A8F4",
+"sM c #B3CFFE",
+"sN c #B4CCE8",
+"sO c #829AB6",
+"sP c #AFB0B4",
+"sQ c #DADBDF",
+"sR c #C8C8C8",
+"sS c #B4B4B4",
+"sT c #AAAAA8",
+"sU c #A0A09E",
+"sV c #949494",
+"sW c #838383",
+"sX c #828387",
+"sY c #9D9EA2",
+"sZ c #D5E2F3",
+"s& c #E0EDFE",
+"t c #E5F1FD",
+"t0 c #E8F5FE",
+"t1 c #E7F4FD",
+"t2 c #E0EDFD",
+"t3 c #D8E5F5",
+"t4 c #CEE2FA",
+"t5 c #CFE3FB",
+"t6 c #D3E5FD",
+"t7 c #D2E4FC",
+"t8 c #E2ECF5",
+"t9 c #EFF9FF",
+"ta c #FBFDFF",
+"tb c #E2E4F0",
+"tc c #7F8AC0",
+"td c #586399",
+"te c #4B6F8F",
+"tf c #769ABA",
+"tg c #83B4DC",
+"th c #8ABBE3",
+"ti c #8FC2ED",
+"tj c #93C6F1",
+"tk c #94CAF6",
+"tl c #98CEFC",
+"tm c #99CFFB",
+"tn c #747E88",
+"to c #E2E2E2",
+"tp c #666666",
+"tq c #41637E",
+"tr c #A9CBE6",
+"ts c #29333D",
+"tt c #96A0AA",
+"tu c #0A0A0A",
+"tv c #8CC1EB",
+"tw c #9BD0FA",
+"tx c #9BD0F8",
+"ty c #7DB2DA",
+"tz c #5C87A9",
+"tA c #356082",
+"tB c #234664",
+"tC c #315472",
+"tD c #7DB2DC",
+"tE c #9ACFF9",
+"tF c #3E4E5D",
+"tG c #647483",
+"tH c #717578",
+"tI c #303437",
+"tJ c #81AFD3",
+"tK c #0F1316",
+"tL c #D7DBDE",
+"tM c #DADADA",
+"tN c #0D0D0D",
+"tO c #88B6DA",
+"tP c #A7C5DF",
+"tQ c #000923",
+"tR c #CBCBCB",
+"tS c #000D1E",
+"tT c #9EB3C4",
+"tU c #A8CBE7",
+"tV c #5E819D",
+"tW c #20201E",
+"tX c #D5D5D3",
+"tY c #E1DFE0",
+"tZ c #272C32",
+"t& c #556E82",
+"u c #253E52",
+"u0 c #5C5C5E",
+"u1 c #294052",
+"u2 c #B2C9DB",
+"u3 c #95CFFD",
+"u4 c #95CDFE",
+"u5 c #94CCFD",
+"u6 c #92CAFB",
+"u7 c #92C8F6",
+"u8 c #8EC4F2",
+"u9 c #8DC2EE",
+"ua c #88BDE9",
+"ub c #85B6DF",
+"uc c #7FB0D9",
+"ud c #839DE8",
+"ue c #8FA9F4",
+"uf c #B0D1FA",
+"ug c #B9DAFF",
+"uh c #AEBAC8",
+"ui c #8894A2",
+"uj c #C4C4C6",
+"uk c #BBBBBD",
+"ul c #B1B1B1",
+"um c #A8A8A8",
+"un c #9E9EA0",
+"uo c #939395",
+"up c #898989",
+"uq c #808080",
+"ur c #7E7F83",
+"us c #A8A9AD",
+"ut c #DDEAFA",
+"uu c #E1EEFE",
+"uv c #E4F2FF",
+"uw c #E5F3FF",
+"ux c #E6F4FF",
+"uy c #E3F4FF",
+"uz c #E1F2FF",
+"uA c #D5EDFF",
+"uB c #CDE5FF",
+"uC c #C7E0FF",
+"uD c #C8E1FF",
+"uE c #C9E0FF",
+"uF c #C8DFFF",
+"uG c #C3D3FF",
+"uH c #B2C2F3",
+"uI c #AAB8E7",
+"uJ c #C8D6FF",
+"uK c #F4FDFF",
+"uL c #FCFFFF",
+"uM c #F9FCFF",
+"uN c #A0ABD9",
+"uO c #616C9A",
+"uP c #4E678F",
+"uQ c #6C85AD",
+"uR c #7BACD4",
+"uS c #8BC0EC",
+"uT c #8FC4F0",
+"uU c #8FC8F5",
+"uV c #91CAF7",
+"uW c #94CCFB",
+"uX c #96CEFF",
+"uY c #94CEFE",
+"uZ c #95CFFF",
+"u& c #505C68",
+"v c #6B7783",
+"v0 c #DCDCDC",
+"v1 c #DEDCDD",
+"v2 c #DADBDD",
+"v3 c #1A1B1D",
+"v4 c #72A8D6",
+"v5 c #A1CCEF",
+"v6 c #6E99BC",
+"v7 c #D9D9D9",
+"v8 c #CFD0D4",
+"v9 c #010206",
+"va c #96CEFD",
+"vb c #95CDFC",
+"vc c #AFC8DE",
+"vd c #597288",
+"ve c #1F2324",
+"vf c #171B1C",
+"vg c #4E4E4E",
+"vh c #7A7A7A",
+"vi c #969696",
+"vj c #606060",
+"vk c #0B2A46",
+"vl c #A9C8E4",
+"vm c #A5C9E9",
+"vn c #698DAD",
+"vo c #1C1C1C",
+"vp c #DCDCDE",
+"vq c #DDDDDF",
+"vr c #9D9D9D",
+"vs c #000828",
+"vt c #8AAECE",
+"vu c #A4CBEC",
+"vv c #446B8C",
+"vw c #9FA6B0",
+"vx c #2B323C",
+"vy c #97CDF9",
+"vz c #5D646A",
+"vA c #4A5157",
+"vB c #828284",
+"vC c #1B4367",
+"vD c #A3CBEF",
+"vE c #94CEFC",
+"vF c #3A5065",
+"vG c #374D62",
+"vH c #DEDEDE",
+"vI c #DBDDDC",
+"vJ c #252C32",
+"vK c #76A2C5",
+"vL c #0E0E10",
+"vM c #C3C3C5",
+"vN c #687888",
+"vO c #1B2B3B",
+"vP c #8DC5F4",
+"vQ c #98CDFF",
+"vR c #96D0FE",
+"vS c #97CFFF",
+"vT c #93CDFB",
+"vU c #93CBFC",
+"vV c #91C9FA",
+"vW c #90C8F9",
+"vX c #90C6F4",
+"vY c #8DC3F1",
+"vZ c #8ABFEB",
+"v& c #85BAE6",
+"w c #83B4DD",
+"w0 c #7CADD6",
+"w1 c #87A1EC",
+"w2 c #AFD0F9",
+"w3 c #85919F",
+"w4 c #BABABA",
+"w5 c #B4B4B6",
+"w6 c #AFAFB1",
+"w7 c #A5A5A5",
+"w8 c #9B9B9B",
+"w9 c #8F8F91",
+"wa c #7D7D7D",
+"wb c #787878",
+"wc c #8C8D91",
+"wd c #C6C7CB",
+"we c #E2F0FD",
+"wf c #D2E3F5",
+"wg c #C6DEF8",
+"wh c #C5DEFD",
+"wi c #C6DFFE",
+"wj c #BED5F7",
+"wk c #ABC2E4",
+"wl c #8C9CCD",
+"wm c #6979AA",
+"wn c #5F6D9C",
+"wo c #8492C1",
+"wp c #BFC8D7",
+"wq c #E6EFFE",
+"wr c #F7FBFC",
+"ws c #FAFEFF",
+"wt c #FAFDFF",
+"wu c #F0F3FA",
+"wv c #C3CEFC",
+"ww c #737EAC",
+"wx c #506991",
+"wy c #5A739B",
+"wz c #73A4CC",
+"wA c #85B6DE",
+"wB c #87BCE8",
+"wC c #8CC5F2",
+"wD c #91C9F8",
+"wE c #92CAF9",
+"wF c #92CCFA",
+"wG c #93CDFD",
+"wH c #4E5A66",
+"wI c #D7D7D7",
+"wJ c #D9D7D8",
+"wK c #D8D6D7",
+"wL c #AFB0B2",
+"wM c #1B1C1E",
+"wN c #96CCFA",
+"wO c #A0CBEE",
+"wP c #0C375A",
+"wQ c #8F8F8F",
+"wR c #A9AAAE",
+"wS c #232428",
+"wT c #84BCEB",
+"wU c #1E374D",
+"wV c #263F55",
+"wW c #A3A7A8",
+"wX c #D5D9DA",
+"wY c #B2B2B2",
+"wZ c #001531",
+"w& c #A8C7E3",
+"x c #94B8D8",
+"x0 c #A1A1A1",
+"x1 c #D7D7D9",
+"x2 c #D8D8DA",
+"x3 c #0C0C0C",
+"x4 c #6B8FAF",
+"x5 c #A4C8E8",
+"x6 c #A2C9EA",
+"x7 c #0A3152",
+"x8 c #A2A2A2",
+"x9 c #787F89",
+"xa c #4C535D",
+"xb c #92CCFC",
+"xc c #95CBF7",
+"xd c #6AA0CC",
+"xe c #060D13",
+"xf c #BAC1C7",
+"xg c #18181A",
+"xh c #6C94B8",
+"xi c #A0C8EC",
+"xj c #AFC5DA",
+"xk c #1C3247",
+"xl c #686868",
+"xm c #D7D9D8",
+"xn c #D6D8D7",
+"xo c #9AA1A7",
+"xp c #2B3238",
+"xq c #9ECAED",
+"xr c #083457",
+"xs c #8B8B8D",
+"xt c #8D8D8F",
+"xu c #081828",
+"xv c #99A9B9",
+"xw c #96CBFD",
+"xx c #90CDFC",
+"xy c #91CBFD",
+"xz c #90CAFC",
+"xA c #8FC9F9",
+"xB c #8DC7F7",
+"xC c #8CC4F5",
+"xD c #89C1F2",
+"xE c #87BDEB",
+"xF c #82B8E6",
+"xG c #80B1DC",
+"xH c #7AABD6",
+"xI c #8298E4",
+"xJ c #899FEB",
+"xK c #ABCBFA",
+"xL c #B6D6FF",
+"xM c #B5C5D5",
+"xN c #8696A6",
+"xO c #A0A0A0",
+"xP c #A6A6A6",
+"xQ c #999999",
+"xR c #7B797A",
+"xS c #6B696A",
+"xT c #767678",
+"xU c #878789",
+"xV c #B2BCC5",
+"xW c #E1EBF4",
+"xX c #DEEEFE",
+"xY c #DFF1FF",
+"xZ c #D2EBFF",
+"x& c #CBE4FF",
+"y c #C1DDFF",
+"y0 c #C3DDFF",
+"y1 c #BCD0FF",
+"y2 c #A8BCEF",
+"y3 c #8E9DD8",
+"y4 c #6D7CB7",
+"y5 c #5C6D99",
+"y6 c #4E5F8B",
+"y7 c #506290",
+"y8 c #596B99",
+"y9 c #717DB7",
+"ya c #A7B3ED",
+"yb c #D6E4FF",
+"yc c #E8F6FF",
+"yd c #F2FCFF",
+"ye c #F0FCFF",
+"yf c #EEFAFF",
+"yg c #E1F4FF",
+"yh c #D9ECFD",
+"yi c #D5E4FF",
+"yj c #7D8CB3",
+"yk c #556795",
+"yl c #546694",
+"ym c #6B9CC4",
+"yn c #81B2DA",
+"yo c #84BAE9",
+"yp c #89BFEE",
+"yq c #8AC2F3",
+"yr c #8EC6F7",
+"ys c #8EC8FA",
+"yt c #8FC9FB",
+"yu c #8FCCFB",
+"yv c #92CCFE",
+"yw c #8FCDFC",
+"yx c #8ECCFB",
+"yy c #49565F",
+"yz c #6E7B84",
+"yA c #D3D3D3",
+"yB c #435362",
+"yC c #93CBFA",
+"yD c #5F686D",
+"yE c #353E43",
+"yF c #6D7B88",
+"yG c #404E5B",
+"yH c #AAC6DC",
+"yI c #1B374D",
+"yJ c #646464",
+"yK c #D3D3D5",
+"yL c #A7A7A9",
+"yM c #98999D",
+"yN c #CECFD3",
+"yO c #CDD1D4",
+"yP c #4B4F52",
+"yQ c #295071",
+"yR c #A1C8E9",
+"yS c #34393C",
+"yT c #676C6F",
+"yU c #D5D3D4",
+"yV c #B9B7B8",
+"yW c #001C35",
+"yX c #9FBBD0",
+"yY c #000B20",
+"yZ c #CECECE",
+"y& c #6F7983",
+"z c #8FCCF9",
+"z0 c #90CDFA",
+"z1 c #9AACBA",
+"z2 c #8F9190",
+"z3 c #D2D4D3",
+"z4 c #526574",
+"z5 c #314453",
+"z6 c #8FCDFE",
+"z7 c #8ECCFD",
+"z8 c #7CB6E6",
+"z9 c #102131",
+"za c #647585",
+"zb c #D4D4D6",
+"zc c #D5D5D5",
+"zd c #303940",
+"ze c #585F65",
+"zf c #3C4349",
+"zg c #9AA4AD",
+"zh c #00060F",
+"zi c #659DCC",
+"zj c #92CBFF",
+"zk c #8ECBFA",
+"zl c #8BC5F5",
+"zm c #8BC3F4",
+"zn c #87BFF0",
+"zo c #84BAE8",
+"zp c #80B6E4",
+"zq c #7FB0DB",
+"zr c #78A9D4",
+"zs c #8096E2",
+"zt c #879DE9",
+"zu c #A3C3F2",
+"zv c #B4D4FF",
+"zw c #CBDBEB",
+"zx c #A1B1C1",
+"zy c #959595",
+"zz c #747273",
+"zA c #787677",
+"zB c #DEE8F1",
+"zC c #E4EEF7",
+"zD c #DAEAFA",
+"zE c #CDDFF7",
+"zF c #C1DAF9",
+"zG c #BEDAFF",
+"zH c #BAD4F7",
+"zI c #A4BEE1",
+"zJ c #8CA0D3",
+"zK c #6E82B5",
+"zL c #5D6CA7",
+"zM c #51609B",
+"zN c #445581",
+"zO c #475987",
+"zP c #4B5D8B",
+"zQ c #58649E",
+"zR c #6470AA",
+"zS c #99A7C2",
+"zT c #C5D3EE",
+"zU c #E2ECF6",
+"zV c #E1EDF9",
+"zW c #DDE9F5",
+"zX c #D6E9FA",
+"zY c #CAD9FF",
+"zZ c #7584AB",
+"z& c #536593",
+"A c #699AC2",
+"A0 c #83B9E8",
+"A1 c #87BDEC",
+"A2 c #8BC5F7",
+"A3 c #8DC7F9",
+"A4 c #8DCAF9",
+"A5 c #8DCBFA",
+"A6 c #3F4C55",
+"A7 c #75828B",
+"A8 c #CFCFCF",
+"A9 c #283847",
+"Aa c #758594",
+"Ab c #6BA3D2",
+"Ac c #060F14",
+"Ad c #B0B9BE",
+"Ae c #354350",
+"Af c #6E7C89",
+"Ag c #637F95",
+"Ah c #1A364C",
+"Ai c #979799",
+"Aj c #030305",
+"Ak c #030408",
+"Al c #03070A",
+"Am c #282C2F",
+"An c #8AB1D2",
+"Ao c #214869",
+"Ap c #4B5053",
+"Aq c #C9CED1",
+"Ar c #B7B5B6",
+"As c #4E6E87",
+"At c #A4C4DD",
+"Au c #819DB2",
+"Av c #0D293E",
+"Aw c #828C96",
+"Ax c #37414B",
+"Ay c #8ECBF8",
+"Az c #90C8F7",
+"AA c #75ADDC",
+"AB c #132533",
+"AC c #697B89",
+"AD c #969897",
+"AE c #001221",
+"AF c #98ABBA",
+"AG c #8CCAFB",
+"AH c #8DCBFC",
+"AI c #90CAFA",
+"AJ c #93A4B4",
+"AK c #6C6C6E",
+"AL c #848D94",
+"AM c #363F46",
+"AN c #0B1218",
+"AO c #B5BCC2",
+"AP c #08121B",
+"AQ c #747E87",
+"AR c #90C9FE",
+"AS c #8DCBFE",
+"AT c #8CCAFD",
+"AU c #8BC8FE",
+"AV c #8AC7FD",
+"AW c #89C6FC",
+"AX c #87C4FA",
+"AY c #86C2F4",
+"AZ c #82BEF0",
+"A& c #82BAE9",
+"B c #7DB5E4",
+"B0 c #7AAEDD",
+"B1 c #74A8D7",
+"B2 c #7B96DD",
+"B3 c #839EE5",
+"B4 c #9DBCF2",
+"B5 c #B3D2FF",
+"B6 c #C4D8F3",
+"B7 c #AFB8C7",
+"B8 c #A0A9B8",
+"B9 c #9CA1A5",
+"Ba c #909599",
+"Bb c #8D9095",
+"Bc c #93969B",
+"Bd c #99A2A7",
+"Be c #B4BDC2",
+"Bf c #CDDAEA",
+"Bg c #DFECFC",
+"Bh c #DAEFFF",
+"Bi c #D3ECFF",
+"Bj c #CDE6FF",
+"Bk c #C4E2FF",
+"Bl c #BEDCFF",
+"Bm c #B8D8FF",
+"Bn c #BAD7FF",
+"Bo c #BACFFF",
+"Bp c #A2B7EE",
+"Bq c #8E9CD9",
+"Br c #7381BE",
+"Bs c #6072A0",
+"Bt c #526492",
+"Bu c #3E5B7B",
+"Bv c #3F5C7C",
+"Bw c #4E7596",
+"Bx c #547C9F",
+"By c #4D7598",
+"Bz c #476089",
+"BA c #506992",
+"BB c #5C68A2",
+"BC c #838FC9",
+"BD c #ADBEEA",
+"BE c #CCDDFF",
+"BF c #D2E5FF",
+"BG c #D1E4FF",
+"BH c #CCDFFF",
+"BI c #9EA9E1",
+"BJ c #6570A8",
+"BK c #4B648C",
+"BL c #679CC6",
+"BM c #7DBAE9",
+"BN c #81BEED",
+"BO c #87C1F3",
+"BP c #89C3F5",
+"BQ c #89C5FB",
+"BR c #8AC6FC",
+"BS c #8CC9FF",
+"BT c #323941",
+"BU c #888F97",
+"BV c #CACACC",
+"BW c #CACACA",
+"BX c #C9C9C9",
+"BY c #C0C0C0",
+"BZ c #000A29",
+"B& c #97B8D7",
+"C c #8DC9FF",
+"C0 c #A8C2D9",
+"C1 c #142E45",
+"C2 c #828483",
+"C3 c #C9CBCA",
+"C4 c #C8CAC9",
+"C5 c #C7C9C8",
+"C6 c #000F2B",
+"C7 c #90B2CE",
+"C8 c #394249",
+"C9 c #778087",
+"Ca c #223343",
+"Cb c #728393",
+"Cc c #94C7F2",
+"Cd c #83B6E1",
+"Ce c #8BAAC7",
+"Cf c #83A2BF",
+"Cg c #292C31",
+"Ch c #4E5156",
+"Ci c #C7C7C7",
+"Cj c #C9C9CB",
+"Ck c #ABABAB",
+"Cl c #001F3B",
+"Cm c #496884",
+"Cn c #8BC9FC",
+"Co c #7B95A6",
+"Cp c #183243",
+"Cq c #B4B5B7",
+"Cr c #0E0F11",
+"Cs c #91C7F5",
+"Ct c #00040E",
+"Cu c #78797B",
+"Cv c #C8C9CB",
+"Cw c #A2ABB2",
+"Cx c #060F16",
+"Cy c #568EBF",
+"Cz c #8FC7F8",
+"CA c #8DC9FB",
+"CB c #74B0E2",
+"CC c #122335",
+"CD c #5D6E80",
+"CE c #7C8083",
+"CF c #25292C",
+"CG c #858688",
+"CH c #B8BDC3",
+"CI c #1C2127",
+"CJ c #3B719F",
+"CK c #8DC9FD",
+"CL c #88C5FB",
+"CM c #80B8E7",
+"CN c #7BAFDE",
+"CO c #7792D9",
+"CP c #819CE3",
+"CQ c #94B3E9",
+"CR c #B2D1FF",
+"CS c #CBDFFA",
+"CT c #D1E5FF",
+"CU c #D8E1F0",
+"CV c #CDD6E5",
+"CW c #C8CDD1",
+"CX c #C3C8CC",
+"CY c #C6C9CE",
+"CZ c #CFD2D7",
+"C& c #D5DEE3",
+"D c #E2EBF0",
+"D0 c #DEEBFB",
+"D1 c #D2E7FA",
+"D2 c #CDE2F5",
+"D3 c #C3DCFA",
+"D4 c #BED7F5",
+"D5 c #B7D5F9",
+"D6 c #B6D6FD",
+"D7 c #B7D7FE",
+"D8 c #AFCCF6",
+"D9 c #9FBCE6",
+"Da c #7287BE",
+"Db c #6472AF",
+"Dc c #54629F",
+"Dd c #455785",
+"De c #465886",
+"Df c #4D6A8A",
+"Dg c #5A7797",
+"Dh c #5F86A7",
+"Di c #668DAE",
+"Dj c #6991B4",
+"Dk c #668EB1",
+"Dl c #657EA7",
+"Dm c #4A638C",
+"Dn c #54609A",
+"Do c #6C7DA9",
+"Dp c #95A6D2",
+"Dq c #ADC0E0",
+"Dr c #B0C3E3",
+"Ds c #AABDDE",
+"Dt c #92A5C6",
+"Du c #6B76AE",
+"Dv c #57629A",
+"Dw c #455E86",
+"Dx c #5D769E",
+"Dy c #6DA2CC",
+"Dz c #7FB4DE",
+"DA c #7EBBEA",
+"DB c #86C0F2",
+"DC c #1E252D",
+"DD c #99A0A8",
+"DE c #153655",
+"DF c #A1C2E1",
+"DG c #8BC9FA",
+"DH c #8CC8FE",
+"DI c #8AC8FB",
+"DJ c #486279",
+"DK c #2B455C",
+"DL c #C4C6C5",
+"DM c #C2C4C3",
+"DN c #153753",
+"DO c #A1C3DF",
+"DP c #1F282F",
+"DQ c #929BA2",
+"DR c #304151",
+"DS c #4C5D6D",
+"DT c #6598C3",
+"DU c #477AA5",
+"DV c #2C4B68",
+"DW c #00112E",
+"DX c #75787D",
+"DY c #C0C3C8",
+"DZ c #C5C5C7",
+"D& c #909090",
+"E c #0E0E0E",
+"E0 c #4E6D89",
+"E1 c #A3C2DE",
+"E2 c #89A3B4",
+"E3 c #031D2E",
+"E4 c #C3C4C6",
+"E5 c #303133",
+"E6 c #4F87B6",
+"E7 c #8EC6F5",
+"E8 c #366C9A",
+"E9 c #06101A",
+"Ea c #858F99",
+"Eb c #C2C3C5",
+"Ec c #A6A7A9",
+"Ed c #0E171E",
+"Ee c #636C73",
+"Ef c #8CC8FA",
+"Eg c #93A4B6",
+"Eh c #091A2C",
+"Ei c #707477",
+"Ej c #BFC0C2",
+"Ek c #31363C",
+"El c #4C5157",
+"Em c #8CC8FC",
+"En c #85C6FC",
+"Eo c #86C5FB",
+"Ep c #85C4FA",
+"Eq c #84C3F9",
+"Er c #84C0F6",
+"Es c #81BDF3",
+"Et c #7CB8EC",
+"Eu c #79B5E9",
+"Ev c #77AFE0",
+"Ew c #70A8D9",
+"Ex c #7594D4",
+"Ey c #7D9CDC",
+"Ez c #8CAAE6",
+"EA c #B1CFFF",
+"EB c #C6DFFD",
+"EC c #CCE5FF",
+"ED c #D0E6FE",
+"EE c #D2E8FF",
+"EF c #D5EAFF",
+"EG c #D7ECFF",
+"EH c #D8EAFE",
+"EI c #D3EBFF",
+"EJ c #CAE2FE",
+"EK c #B7D9FF",
+"EL c #B3D5FF",
+"EM c #B0D2FF",
+"EN c #B1D3FF",
+"EO c #B4D3FF",
+"EP c #AEC3FF",
+"EQ c #95AAE9",
+"ER c #8496D6",
+"ES c #7587C7",
+"ET c #667AAC",
+"EU c #596D9F",
+"EV c #3E5F80",
+"EW c #3C5D7E",
+"EX c #436E91",
+"EY c #517C9F",
+"EZ c #5889B2",
+"E& c #6394BD",
+"F c #659AC6",
+"F0 c #699ECA",
+"F1 c #689DC9",
+"F2 c #6497C2",
+"F3 c #5C8FBA",
+"F4 c #4D739A",
+"F5 c #41678E",
+"F6 c #536498",
+"F7 c #5C6DA1",
+"F8 c #6B7AB1",
+"F9 c #6E7DB4",
+"Fa c #6979AD",
+"Fb c #5B6B9F",
+"Fc c #4F658C",
+"Fd c #435980",
+"Fe c #436F96",
+"Ff c #618DB4",
+"Fg c #6FA9DB",
+"Fh c #7BB5E7",
+"Fi c #7CB9EF",
+"Fj c #7FBCF2",
+"Fk c #7FC0F6",
+"Fl c #82C3F9",
+"Fm c #84C5FB",
+"Fn c #87C6FC",
+"Fo c #87C5F8",
+"Fp c #88C6F9",
+"Fq c #010101",
+"Fr c #B3B3B3",
+"Fs c #505050",
+"Ft c #366A99",
+"Fu c #8FC3F2",
+"Fv c #86C7FD",
+"Fw c #8BC3F2",
+"Fx c #7AB2E1",
+"Fy c #050706",
+"Fz c #A7A9A8",
+"FA c #373737",
+"FB c #407AAA",
+"FC c #1C252C",
+"FD c #8A939A",
+"FE c #BCBEBD",
+"FF c #5B5B5B",
+"FG c #3B3B3B",
+"FH c #4F4F4F",
+"FI c #B0B0B0",
+"FJ c #BEBEC0",
+"FK c #BDBDBF",
+"FL c #B5BAC0",
+"FM c #575C62",
+"FN c #000A2C",
+"FO c #5A85A7",
+"FP c #001438",
+"FQ c #A2A2A4",
+"FR c #BEBEBC",
+"FS c #91918F",
+"FT c #00040D",
+"FU c #77818A",
+"FV c #7C8FA0",
+"FW c #4E6172",
+"FX c #17181A",
+"FY c #3F4042",
+"FZ c #839099",
+"F& c #3870A1",
+"G c #85C7FB",
+"G0 c #88C5FC",
+"G1 c #89C6FD",
+"G2 c #619FD2",
+"G3 c #88929B",
+"G4 c #BEBCBD",
+"G5 c #BFBDBE",
+"G6 c #AEAEAE",
+"G7 c #0D426E",
+"G8 c #85C6FE",
+"G9 c #82C1F7",
+"Ga c #83BFF5",
+"Gb c #80BCF2",
+"Gc c #71A9DA",
+"Gd c #6A89C9",
+"Ge c #7B9ADA",
+"Gf c #86A4E0",
+"Gg c #ABC9FF",
+"Gh c #C1DAF8",
+"Gi c #CFE5FD",
+"Gj c #D1E7FF",
+"Gk c #D3E8FD",
+"Gl c #D8E9FD",
+"Gm c #D7E8FC",
+"Gn c #D2EAFF",
+"Go c #C0D8F4",
+"Gp c #AED0FD",
+"Gq c #AFD1FF",
+"Gr c #ADCFFD",
+"Gs c #9FBEED",
+"Gt c #87A6D5",
+"Gu c #7E93D2",
+"Gv c #6E83C2",
+"Gw c #6779B9",
+"Gx c #596BAB",
+"Gy c #465A8C",
+"Gz c #435789",
+"GA c #496A8B",
+"GB c #58799A",
+"GC c #608BAE",
+"GD c #6A95B8",
+"GE c #6B9CC5",
+"GF c #6FA0C9",
+"GG c #71A6D2",
+"GH c #70A5D1",
+"GI c #6EA1CC",
+"GJ c #6B9EC9",
+"GK c #6F95BC",
+"GL c #5D83AA",
+"GM c #526397",
+"GN c #516296",
+"GO c #516097",
+"GP c #505F96",
+"GQ c #506094",
+"GR c #48588C",
+"GS c #455B82",
+"GT c #5C88AF",
+"GU c #739FC6",
+"GV c #76B0E2",
+"GW c #7DB7E9",
+"GX c #7DBAF0",
+"GY c #80BDF3",
+"GZ c #80C1F7",
+"G& c #66A4D7",
+"H c #B9B9B9",
+"H0 c #B7B9B8",
+"H1 c #B7B7B7",
+"H2 c #669AC9",
+"H3 c #8EC2F1",
+"H4 c #28608F",
+"H5 c #505251",
+"H6 c #86C0F0",
+"H7 c #8AC4F4",
+"H8 c #384148",
+"H9 c #626B72",
+"Ha c #B6B8B7",
+"Hb c #B9B9BB",
+"Hc c #B8B8BA",
+"Hd c #878787",
+"He c #191E24",
+"Hf c #353A40",
+"Hg c #7DA8CA",
+"Hh c #96C1E3",
+"Hi c #83C4FA",
+"Hj c #98C0E4",
+"Hk c #325A7E",
+"Hl c #404042",
+"Hm c #B8B8B6",
+"Hn c #7E8891",
+"Ho c #313B44",
+"Hp c #233647",
+"Hq c #495C6D",
+"Hr c #999A9C",
+"Hs c #B7B8BA",
+"Ht c #555555",
+"Hu c #00050E",
+"Hv c #6D7A83",
+"Hw c #83C5F9",
+"Hx c #84C6FA",
+"Hy c #87C4FB",
+"Hz c #86C4F7",
+"HA c #727C85",
+"HB c #0A141D",
+"HC c #B5B5B5",
+"HD c #81B6E2",
+"HE c #84C5FD",
+"HF c #81C4F9",
+"HG c #82C3FB",
+"HH c #81C2FA",
+"HI c #7FC2F9",
+"HJ c #7CBFF6",
+"HK c #80BFF5",
+"HL c #7DBCF2",
+"HM c #77B4EA",
+"HN c #75AFE1",
+"HO c #6A91CA",
+"HP c #7198D1",
+"HQ c #83A0E2",
+"HR c #A4C1FF",
+"HS c #BBD8FA",
+"HT c #C9E6FF",
+"HU c #D1E5FE",
+"HV c #D2E6FF",
+"HW c #D9EAFE",
+"HX c #DAEBFF",
+"HY c #BBD4F3",
+"HZ c #AECDFF",
+"H& c #A8C7FD",
+"I c #9AADF1",
+"I0 c #8699DD",
+"I1 c #788AC8",
+"I2 c #6D7FBD",
+"I3 c #657AA9",
+"I4 c #526796",
+"I5 c #3A5D7D",
+"I6 c #3E6181",
+"I7 c #517DA4",
+"I8 c #578CB8",
+"I9 c #6297C3",
+"Ia c #68A0D1",
+"Ib c #6DA5D6",
+"Ic c #70AADC",
+"Id c #72ACDE",
+"Ie c #71ADE1",
+"If c #71ADDF",
+"Ig c #6DA5D4",
+"Ih c #69A1D0",
+"Ii c #6095C1",
+"Ij c #5186B2",
+"Ik c #4B789F",
+"Il c #46739A",
+"Im c #5083AE",
+"In c #5D90BB",
+"Io c #67A0D5",
+"Ip c #72ABE0",
+"Iq c #7AB7ED",
+"Ir c #7CBBF1",
+"Is c #7EBDF3",
+"It c #7EBFF7",
+"Iu c #7FC0F8",
+"Iv c #80C1F9",
+"Iw c #81C4FB",
+"Ix c #92BFE6",
+"Iy c #3E6B92",
+"Iz c #484A49",
+"IA c #B1B3B2",
+"IB c #B0B2B1",
+"IC c #949BA1",
+"ID c #9DBBD5",
+"IE c #ACB0AF",
+"IF c #9CA09F",
+"IG c #888F95",
+"IH c #798086",
+"II c #13334C",
+"IJ c #476780",
+"IK c #001C38",
+"IL c #A3A3A3",
+"IM c #B3B1B4",
+"IN c #888888",
+"IO c #001C32",
+"IP c #407CAE",
+"IQ c #85C1F3",
+"IR c #7BBCF4",
+"IS c #000515",
+"IT c #4D5E6E",
+"IU c #AAAFB2",
+"IV c #696E71",
+"IW c #20425E",
+"IX c #6CABE1",
+"IY c #81C2F8",
+"IZ c #84C2FB",
+"I& c #83C1FA",
+"J c #88C2F2",
+"J0 c #255F8F",
+"J1 c #323637",
+"J2 c #AEB2B3",
+"J3 c #000F30",
+"J4 c #6E95B6",
+"J5 c #83C4FC",
+"J6 c #7FC4FB",
+"J7 c #7FC2F7",
+"J8 c #7EC1F8",
+"J9 c #7DC0F7",
+"Ja c #7FBEF4",
+"Jb c #7BB8EE",
+"Jc c #78B5EB",
+"Jd c #6E95CE",
+"Je c #6D94CD",
+"Jf c #7F9CDE",
+"Jg c #99B6F8",
+"Jh c #B8D5F7",
+"Ji c #C7E4FF",
+"Jj c #D1EAFF",
+"Jk c #B7D0EF",
+"Jl c #7897CD",
+"Jm c #7487CB",
+"Jn c #6D80C4",
+"Jo c #6072B0",
+"Jp c #4C5E9C",
+"Jq c #3D5281",
+"Jr c #445988",
+"Js c #4A6D8D",
+"Jt c #597C9C",
+"Ju c #5E8AB1",
+"Jv c #6A96BD",
+"Jw c #6A9FCB",
+"Jx c #6FA4D0",
+"Jy c #73ABDC",
+"Jz c #74AEE0",
+"JA c #77B1E3",
+"JB c #76B2E6",
+"JC c #76B2E4",
+"JD c #75B1E3",
+"JE c #74ACDB",
+"JF c #72AAD9",
+"JG c #6CA1CD",
+"JH c #6C99C0",
+"JI c #6996BD",
+"JJ c #6895BC",
+"JK c #6A97BE",
+"JL c #6A9DC8",
+"JM c #71A4CF",
+"JN c #77B0E5",
+"JO c #90BDE4",
+"JP c #002B52",
+"JQ c #818382",
+"JR c #AAACAB",
+"JS c #A9ABAA",
+"JT c #60676D",
+"JU c #7694AE",
+"JV c #000D27",
+"JW c #1F1F1F",
+"JX c #0F0F0F",
+"JY c #000201",
+"JZ c #090D0C",
+"J& c #171E24",
+"K c #282F35",
+"K0 c #25455E",
+"K1 c #9BBBD4",
+"K2 c #30536F",
+"K3 c #151515",
+"K4 c #6A6A6A",
+"K5 c #9A9A9A",
+"K6 c #ACAAAD",
+"K7 c #9E9C9F",
+"K8 c #232323",
+"K9 c #4E6A80",
+"Ka c #9EBAD0",
+"Kb c #84C0F2",
+"Kc c #8C9DAD",
+"Kd c #152636",
+"Ke c #333333",
+"Kf c #ABADAC",
+"Kg c #0F1417",
+"Kh c #2A2F32",
+"Ki c #6385A1",
+"Kj c #99BBD7",
+"Kk c #83C2F8",
+"Kl c #82C0F9",
+"Km c #85BFEF",
+"Kn c #202425",
+"Ko c #6D7172",
+"Kp c #A4A4A4",
+"Kq c #1D1D1D",
+"Kr c #4B7293",
+"Ks c #96BDDE",
+"Kt c #7DC2F9",
+"Ku c #7AC1F9",
+"Kv c #7BC0FB",
+"Kw c #79BEF9",
+"Kx c #7BC0F9",
+"Ky c #79BEF7",
+"Kz c #7ABCF6",
+"KA c #78BAF4",
+"KB c #76B9EE",
+"KC c #72B5EA",
+"KD c #71B0E5",
+"KE c #6BAADF",
+"KF c #689ACD",
+"KG c #6193C6",
+"KH c #8197E0",
+"KI c #94AAF3",
+"KJ c #B5D2FA",
+"KK c #C2DFFF",
+"KL c #D4E9FE",
+"KM c #D6EBFF",
+"KN c #CFE9FF",
+"KO c #AFC9EE",
+"KP c #889BDD",
+"KQ c #6B7EC0",
+"KR c #5C739C",
+"KS c #445B84",
+"KT c #335777",
+"KU c #3B5F7F",
+"KV c #3F7098",
+"KW c #4D7EA6",
+"KX c #558BB9",
+"KY c #6096C4",
+"KZ c #649ECE",
+"K& c #69A3D3",
+"L c #6AA9DC",
+"L0 c #6BAADD",
+"L1 c #6FAEE4",
+"L2 c #71B0E6",
+"L3 c #71B2E8",
+"L4 c #74B5EB",
+"L5 c #75B6EE",
+"L6 c #73B6ED",
+"L7 c #74B7EE",
+"L8 c #74B5ED",
+"L9 c #72B3EB",
+"La c #70B1E7",
+"Lb c #6FB0E6",
+"Lc c #6FAEE3",
+"Ld c #6CABE0",
+"Le c #6AA7DD",
+"Lf c #6BA8DE",
+"Lg c #70AFE4",
+"Lh c #74B3E9",
+"Li c #74B6F0",
+"Lj c #76B8F2",
+"Lk c #77B9F3",
+"Ll c #78BFF7",
+"Lm c #79C0F8",
+"Ln c #7ABFFA",
+"Lo c #7AC1F7",
+"Lp c #64839F",
+"Lq c #001632",
+"Lr c #68707B",
+"Ls c #656D78",
+"Lt c #576572",
+"Lu c #485663",
+"Lv c #2C4355",
+"Lw c #102739",
+"Lx c #001034",
+"Ly c #4D7B9F",
+"Lz c #7DBFF3",
+"LA c #4587BB",
+"LB c #5897CC",
+"LC c #69A8DD",
+"LD c #74B9F2",
+"LE c #4A7FA9",
+"LF c #063B65",
+"LG c #000F29",
+"LH c #00102A",
+"LI c #001A30",
+"LJ c #08243A",
+"LK c #052137",
+"LL c #000C26",
+"LM c #00284B",
+"LN c #123E61",
+"LO c #4483B8",
+"LP c #80BFF4",
+"LQ c #7ABFF8",
+"LR c #7AC0FB",
+"LS c #78BDF6",
+"LT c #336183",
+"LU c #081D30",
+"LV c #33485B",
+"LW c #616870",
+"LX c #747B83",
+"LY c #737C83",
+"LZ c #384F5F",
+"L& c #0B2232",
+"M c #00082B",
+"M0 c #20486B",
+"M1 c #67ACE3",
+"M2 c #7BC0F7",
+"M3 c #79C2F9",
+"M4 c #78C1F8",
+"M5 c #82BEF2",
+"M6 c #272A2F",
+"M7 c #64676C",
+"M8 c #3C5162",
+"M9 c #7BBFFC",
+"Ma c #73B6EB",
+"Mb c #73B2E7",
+"Mc c #6C9ED1",
+"Md c #6092C5",
+"Me c #7E94DD",
+"Mf c #8CA2EB",
+"Mg c #B3D0F8",
+"Mh c #BFDCFF",
+"Mi c #DAECFF",
+"Mj c #D0EAFF",
+"Mk c #AAC4E9",
+"Ml c #7D90D2",
+"Mm c #576AAC",
+"Mn c #395079",
+"Mo c #425982",
+"Mp c #486C8C",
+"Mq c #567A9A",
+"Mr c #598AB2",
+"Ms c #6394BC",
+"Mt c #659BC9",
+"Mu c #6AA0CE",
+"Mv c #6BA5D5",
+"Mw c #6FA9D9",
+"Mx c #6EADE0",
+"My c #70AFE2",
+"Mz c #73B2E8",
+"MA c #75B6EC",
+"MB c #76B7ED",
+"MC c #77B8F0",
+"MD c #75B8EF",
+"ME c #76B9F0",
+"MF c #76B7EF",
+"MG c #73B4EA",
+"MH c #72B3E9",
+"MI c #72B1E6",
+"MJ c #6FAEE1",
+"MK c #70ADE3",
+"ML c #71AEE4",
+"MM c #77B6EC",
+"MN c #79BBF5",
+"MO c #7BC2F8",
+"MP c #85A4C0",
+"MQ c #153450",
+"MR c #272F3A",
+"MS c #2F3742",
+"MT c #364451",
+"MU c #44525F",
+"MV c #546B7D",
+"MW c #71889A",
+"MX c #80AED2",
+"MY c #8EBCE0",
+"MZ c #7EC0F4",
+"M& c #88BDE7",
+"N c #96BAD4",
+"N0 c #85A9C3",
+"N1 c #7B97AD",
+"N2 c #7793A9",
+"N3 c #7894AA",
+"N4 c #87ABC5",
+"N5 c #97BBD5",
+"N6 c #7FBEF3",
+"N7 c #8EBCDE",
+"N8 c #74899C",
+"N9 c #495E71",
+"Na c #313840",
+"Nb c #1D242C",
+"Nc c #1D262D",
+"Nd c #2F383F",
+"Ne c #435A6A",
+"Nf c #6D8494",
+"Ng c #92BADD",
+"Nh c #7ABFF6",
+"Ni c #205C90",
+"Nj c #2E3136",
+"Nk c #979A9F",
+"Nl c #000617",
+"Nm c #889DAE",
+"Nn c #76BEF9",
+"No c #77BFFA",
+"Np c #75BDF8",
+"Nq c #76BAF7",
+"Nr c #74B8F5",
+"Ns c #72B9F1",
+"Nt c #6FB6EE",
+"Nu c #6EB1E8",
+"Nv c #69ACE3",
+"Nw c #68A2D2",
+"Nx c #4F89B9",
+"Ny c #798FD8",
+"Nz c #869CE5",
+"NA c #A3C3F4",
+"NB c #D6E8FE",
+"NC c #D9E9FF",
+"ND c #CEEAFF",
+"NE c #A7C3EA",
+"NF c #7B8FCE",
+"NG c #586CAB",
+"NH c #365C80",
+"NI c #486E92",
+"NJ c #4F84B0",
+"NK c #598EBA",
+"NL c #5C98CA",
+"NM c #619DCF",
+"NN c #63A2D7",
+"NO c #66A5DA",
+"NP c #67AADF",
+"NQ c #6AADE2",
+"NR c #6CB1E8",
+"NS c #6EB3EA",
+"NT c #70B5EE",
+"NU c #71B6EF",
+"NV c #71B9F4",
+"NW c #72BAF5",
+"NX c #73B9F5",
+"NY c #74BAF6",
+"NZ c #73BBF5",
+"N& c #72BAF4",
+"O c #74B9F4",
+"O0 c #73B8F3",
+"O1 c #71B8F0",
+"O2 c #70B7EF",
+"O3 c #6EB3EC",
+"O4 c #6CB3E9",
+"O5 c #6CB1EA",
+"O6 c #6DB2EB",
+"O7 c #6FB4ED",
+"O8 c #73BBF6",
+"O9 c #75BBF7",
+"Oa c #76BDFB",
+"Ob c #77BDF9",
+"Oc c #75BDF7",
+"Od c #76BEF8",
+"Oe c #73BEF8",
+"Of c #74BFF9",
+"Og c #77A5C7",
+"Oh c #4E5B64",
+"Oi c #1C2932",
+"Oj c #0A1117",
+"Ok c #2A3137",
+"Ol c #5E87A7",
+"Om c #8FB8D8",
+"On c #7ABBF3",
+"Oo c #5F6972",
+"Op c #0E1821",
+"Oq c #939393",
+"Or c #6F7982",
+"Os c #000912",
+"Ot c #4B8CC2",
+"Ou c #7ABBF1",
+"Ov c #74BCF7",
+"Ow c #75B9F6",
+"Ox c #73B7F4",
+"Oy c #6DB4EC",
+"Oz c #538DBD",
+"OA c #7288D1",
+"OB c #8298E1",
+"OC c #99B9EA",
+"OD c #B5D5FF",
+"OE c #CFE3FC",
+"OF c #D4E8FF",
+"OG c #C6E2FF",
+"OH c #A6C2E9",
+"OI c #768AC9",
+"OJ c #576BAA",
+"OK c #395F83",
+"OL c #50769A",
+"OM c #558AB6",
+"ON c #5E93BF",
+"OO c #5F9BCD",
+"OP c #64A0D2",
+"OQ c #6DB0E5",
+"OR c #6DB2E9",
+"OS c #70B8F3",
+"OT c #72B8F4",
+"OU c #71B9F3",
+"OV c #72B7F2",
+"OW c #6DB4EA",
+"OX c #74BBF9",
+"OY c #74BCF6",
+"OZ c #72BDF7",
+"O& c #4A789A",
+"P c #001133",
+"P0 c #323F48",
+"P1 c #767D83",
+"P2 c #51585E",
+"P3 c #001434",
+"P4 c #3E6787",
+"P5 c #79BAF2",
+"P6 c #3E7FB7",
+"P7 c #030D16",
+"P8 c #6D7780",
+"P9 c #061019",
+"Pa c #626C75",
+"Pb c #78B9EF",
+"Pc c #6DBCF7",
+"Pd c #70BAF9",
+"Pe c #6FBBF7",
+"Pf c #6FB9F8",
+"Pg c #6EB8F7",
+"Ph c #6DB7F4",
+"Pi c #6AB4F1",
+"Pj c #6AB0EB",
+"Pk c #62A8E3",
+"Pl c #64A3D6",
+"Pm c #5594C7",
+"Pn c #6685C6",
+"Po c #7897D8",
+"Pp c #8FACE6",
+"Pq c #B2CFFF",
+"Pr c #D1E9FF",
+"Ps c #C3E3FF",
+"Pt c #A0C0E9",
+"Pu c #7080BC",
+"Pv c #4E5E9A",
+"Pw c #356289",
+"Px c #4F7CA3",
+"Py c #538FC1",
+"Pz c #5FA0D8",
+"PA c #63A4DC",
+"PB c #63ACE3",
+"PC c #66AFE6",
+"PD c #6AB0EE",
+"PE c #6BB1EF",
+"PF c #6AB5EF",
+"PG c #6BB6F0",
+"PH c #6CB6F3",
+"PI c #6EB8F5",
+"PJ c #6EBAF6",
+"PK c #6AB6F0",
+"PL c #69B5EF",
+"PM c #6CB3F1",
+"PN c #6CB6F5",
+"PO c #6DB7F6",
+"PP c #6FB9F6",
+"PQ c #70BCF8",
+"PR c #72B9F9",
+"PS c #71BBF8",
+"PT c #71BBFA",
+"PU c #6EBAF4",
+"PV c #70BAF7",
+"PW c #71B8F8",
+"PX c #76B8EC",
+"PY c #6DAFE3",
+"PZ c #656565",
+"P& c #6D6D6D",
+"Q c #7F7F7F",
+"Q0 c #6A6E6F",
+"Q1 c #000405",
+"Q2 c #6C7A87",
+"Q3 c #000A17",
+"Q4 c #646665",
+"Q5 c #7E807F",
+"Q6 c #6E777E",
+"Q7 c #0C151C",
+"Q8 c #25689D",
+"Q9 c #75B8ED",
+"Qa c #6FBBF9",
+"Qb c #6BBAF5",
+"Qc c #6DB9F5",
+"Qd c #69B3F0",
+"Qe c #65ABE6",
+"Qf c #5998CB",
+"Qg c #5E7DBE",
+"Qh c #7392D3",
+"Qi c #86A3DD",
+"Qj c #AAC7FF",
+"Qk c #C4DCF8",
+"Ql c #D0E8FF",
+"Qm c #BEDEFF",
+"Qn c #9FBFE8",
+"Qo c #6F7FBB",
+"Qp c #4B5B97",
+"Qq c #38658C",
+"Qr c #5380A7",
+"Qs c #5692C4",
+"Qt c #5E9ACC",
+"Qu c #61A2DA",
+"Qv c #66A7DF",
+"Qw c #64ADE4",
+"Qx c #67B0E7",
+"Qy c #6CB2F0",
+"Qz c #6CB7F1",
+"QA c #6BB5F2",
+"QB c #6CB8F4",
+"QC c #6BB7F1",
+"QD c #6DB4F2",
+"QE c #6FB6F4",
+"QF c #70B7F7",
+"QG c #6DB9F3",
+"QH c #6AB9F4",
+"QI c #75B7EB",
+"QJ c #1F6195",
+"QK c #2F2F2F",
+"QL c #303030",
+"QM c #505455",
+"QN c #15191A",
+"QO c #515F6C",
+"QP c #757776",
+"QQ c #6F7170",
+"QR c #111A21",
+"QS c #464F56",
+"QT c #74B7EC",
+"QU c #6DB9F7",
+"QV c #6CB8F6",
+"QW c #69AFEB",
+"QX c #65ABE7",
+"QY c #62A5DC",
+"QZ c #599CD3",
+"Q& c #537AB3",
+"R c #668DC6",
+"R0 c #829BDE",
+"R1 c #A1BAFD",
+"R2 c #BED8FB",
+"R3 c #CCE6FF",
+"R4 c #98B8EB",
+"R5 c #6C7FB9",
+"R6 c #465993",
+"R7 c #396A93",
+"R8 c #5485AE",
+"R9 c #5F9ED1",
+"Ra c #62A4E0",
+"Rb c #67A9E5",
+"Rc c #64AEEB",
+"Rd c #67B1EE",
+"Re c #6BB7F5",
+"Rf c #6DB8F9",
+"Rg c #6BB9F7",
+"Rh c #8CB0D0",
+"Ri c #001838",
+"Rj c #626463",
+"Rk c #090A0C",
+"Rl c #636466",
+"Rm c #64696F",
+"Rn c #3F444A",
+"Ro c #040605",
+"Rp c #080A09",
+"Rq c #5E5E5E",
+"Rr c #767676",
+"Rs c #6A7378",
+"Rt c #141D22",
+"Ru c #13548A",
+"Rv c #6EBAF8",
+"Rw c #66ACE8",
+"Rx c #63A6DD",
+"Ry c #5DA0D7",
+"Rz c #5D84BD",
+"RA c #5F86BF",
+"RB c #7B94D7",
+"RC c #95AEF1",
+"RD c #B8D2F5",
+"RE c #C8E2FF",
+"RF c #B0D0FF",
+"RG c #90B0E3",
+"RH c #687BB5",
+"RI c #3C6D96",
+"RJ c #5788B1",
+"RK c #5A99CC",
+"RL c #61A0D3",
+"RM c #65A7E3",
+"RN c #69ABE7",
+"RO c #66B0ED",
+"RP c #7498B8",
+"RQ c #001232",
+"RR c #767877",
+"RS c #101113",
+"RT c #0F1012",
+"RU c #01060C",
+"RV c #2D3238",
+"RW c #0F1110",
+"RX c #636564",
+"RY c #6E6E6E",
+"RZ c #121B20",
+"R& c #3E474C",
+"S c #6BB1ED",
+"S0 c #67ADE9",
+"S1 c #65A8DF",
+"S2 c #5EA1D8",
+"S3 c #5E92C4",
+"S4 c #497DAF",
+"S5 c #768DD3",
+"S6 c #8AA1E7",
+"S7 c #AAC9F7",
+"S8 c #BEDDFF",
+"S9 c #D6EAFF",
+"Sa c #D5EBFF",
+"Sb c #D6ECFF",
+"Sc c #CDEAFF",
+"Sd c #ACC9FF",
+"Se c #8BA8E2",
+"Sf c #657AAF",
+"Sg c #455A8F",
+"Sh c #4073A0",
+"Si c #588BB8",
+"Sj c #599AD0",
+"Sk c #62A3D9",
+"Sl c #65A9E6",
+"Sm c #69ADEA",
+"Sn c #69B3F2",
+"So c #6AB4F3",
+"Sp c #7296B6",
+"Sq c #000F2F",
+"Sr c #606062",
+"Ss c #171719",
+"St c #0C0C0E",
+"Su c #343436",
+"Sv c #6F6F6F",
+"Sw c #636C75",
+"Sx c #0D161F",
+"Sy c #19588E",
+"Sz c #68AEEA",
+"SA c #66A9E0",
+"SB c #60A3DA",
+"SC c #6397C9",
+"SD c #6D84CA",
+"SE c #8198DE",
+"SF c #9CBBE9",
+"SG c #B7D6FF",
+"SH c #D0E4FC",
+"SI c #D5E9FF",
+"SJ c #D1E7FE",
+"SK c #CBE1F8",
+"SL c #BCD9FB",
+"SM c #B3D0F2",
+"SN c #A9C6FF",
+"SO c #819ED8",
+"SP c #6176AB",
+"SQ c #4275A2",
+"SR c #5A8DBA",
+"SS c #5C9DD3",
+"ST c #63A4DA",
+"SU c #66AAE7",
+"SV c #6AAEEB",
+"SW c #6BB5F4",
+"SX c #002444",
+"SY c #4A4A4A",
+"SZ c #777779",
+"S& c #78787A",
+"T c #050E17",
+"T0 c #4E5760",
+"T1 c #76B5EB",
+"T2 c #68AEEC",
+"T3 c #61A3DF",
+"T4 c #609CD2",
+"T5 c #508CC2",
+"T6 c #6080BD",
+"T7 c #7090CD",
+"T8 c #90AAE7",
+"T9 c #AFC9FF",
+"Ta c #B7D8FF",
+"Tb c #B3D8FF",
+"Tc c #AED3FF",
+"Td c #A9CDFD",
+"Te c #ABC3FF",
+"Tf c #7C94D2",
+"Tg c #5A74A5",
+"Th c #435D8E",
+"Ti c #457AAC",
+"Tj c #5B90C2",
+"Tk c #5E9FD7",
+"Tl c #64A5DD",
+"Tm c #67ABE8",
+"Tn c #6BB2F2",
+"To c #6DB4F4",
+"Tp c #6FB6F6",
+"Tq c #70B4F1",
+"Tr c #4589C6",
+"Ts c #000419",
+"Tt c #23394E",
+"Tu c #616264",
+"Tv c #727375",
+"Tw c #474C52",
+"Tx c #04223C",
+"Ty c #000721",
+"Tz c #3375AF",
+"TA c #73B5EF",
+"TB c #6DB3F1",
+"TC c #69AFED",
+"TD c #63A5E1",
+"TE c #629ED4",
+"TF c #5A96CC",
+"TG c #5676B3",
+"TH c #6A8AC7",
+"TI c #7F99D6",
+"TJ c #9FB9F6",
+"TK c #ADCEF9",
+"TL c #AACFFB",
+"TM c #AACEFE",
+"TN c #A8CCFC",
+"TO c #95ADEB",
+"TP c #6D85C3",
+"TQ c #516B9C",
+"TR c #466091",
+"TS c #4C81B3",
+"TT c #6095C7",
+"TU c #65A6DE",
+"TV c #6CB3F3",
+"TW c #71B5F2",
+"TX c #7C92A7",
+"TY c #30465B",
+"TZ c #000002",
+"T& c #050A10",
+"U c #2A2F35",
+"U0 c #4E6C86",
+"U1 c #90AEC8",
+"U2 c #72B4EE",
+"U3 c #6FB6F8",
+"U4 c #6DB7F8",
+"U5 c #6EB5F7",
+"U6 c #6CB3F5",
+"U7 c #6CB1F2",
+"U8 c #6AAFF0",
+"U9 c #63A7E4",
+"Ua c #60A1D7",
+"Ub c #5B9CD2",
+"Uc c #588ABF",
+"Ud c #5082B7",
+"Ue c #788BD0",
+"Uf c #8699DE",
+"Ug c #9EB8F5",
+"Uh c #AECBFF",
+"Ui c #A1B8FB",
+"Uj c #869DE0",
+"Uk c #687AB8",
+"Ul c #3F668F",
+"Um c #456C95",
+"Un c #4E8AC0",
+"Uo c #5E9AD0",
+"Up c #60A2DE",
+"Uq c #68ACEB",
+"Ur c #6BAFEE",
+"Us c #6FB4F5",
+"Ut c #6EB5F5",
+"Uu c #70B7F9",
+"Uv c #6CB6F7",
+"Uw c #6DB4F6",
+"Ux c #64A8E5",
+"Uy c #5FA0D6",
+"Uz c #6294C9",
+"UA c #4F81B6",
+"UB c #687BC0",
+"UC c #7588CD",
+"UD c #7A94D1",
+"UE c #829CD9",
+"UF c #829FD9",
+"UG c #7A97D1",
+"UH c #768DD0",
+"UI c #6B82C5",
+"UJ c #6476B4",
+"UK c #495B99",
+"UL c #3B628B",
+"UM c #5279A2",
+"UN c #5793C9",
+"UO c #639FD5",
+"UP c #64A6E2",
+"UQ c #66A8E4",
+"UR c #69ADEC",
+"US c #6EB3F4",
+"UT c #70B5F8",
+"UU c #6FB4F7",
+"UV c #6FB2F6",
+"UW c #6DB0F4",
+"UX c #6BAFF0",
+"UY c #67ABEC",
+"UZ c #67A7E5",
+"U& c #63A3E1",
+"V c #619ED7",
+"V0 c #5895CE",
+"V1 c #507EB2",
+"V2 c #4E7CB0",
+"V3 c #6683BB",
+"V4 c #6D8AC2",
+"V5 c #6E87BF",
+"V6 c #6D86BE",
+"V7 c #5F7EAD",
+"V8 c #496897",
+"V9 c #365F8B",
+"Va c #3F6894",
+"Vb c #467DB3",
+"Vc c #578EC4",
+"Vd c #5E9CD9",
+"Ve c #65A3E0",
+"Vf c #66A7E7",
+"Vg c #69AAEA",
+"Vh c #6DB1F2",
+"Vi c #6DB2F5",
+"Vj c #71B4F8",
+"Vk c #71B5F6",
+"Vl c #70B5F6",
+"Vm c #70B5FA",
+"Vn c #6EB3F6",
+"Vo c #6EB1F5",
+"Vp c #69ADEE",
+"Vq c #69A9E7",
+"Vr c #66A6E4",
+"Vs c #66A3DC",
+"Vt c #6593C7",
+"Vu c #5583B7",
+"Vv c #4D6AA2",
+"Vw c #415E96",
+"Vx c #405991",
+"Vy c #3E5D8C",
+"Vz c #486796",
+"VA c #4C75A1",
+"VB c #5B84B0",
+"VC c #5D94CA",
+"VD c #649BD1",
+"VE c #64A2DF",
+"VF c #68A6E3",
+"VG c #68A9E9",
+"VH c #6BACEC",
+"VI c #70B3F7",
+"VJ c #70B4F5",
+"VK c #6FB4F9",
+"VL c #70B2E6",
+"VM c #6EB0E4",
+"VN c #6EADE2",
+"VO c #6AAADA",
+"VP c #67A7D7",
+"VQ c #65A2D1",
+"VR c #619ECD",
+"VS c #5C95C2",
+"VT c #548DBA",
+"VU c #5287B3",
+"VV c #5288B4",
+"VW c #578DB9",
+"VX c #5D97C5",
+"VY c #639DCB",
+"VZ c #64A2D1",
+"V& c #68A6D5",
+"W c #69A7DA",
+"W0 c #6CAADD",
+"W1 c #71B4E9",
+"W2 c #72B5EC",
+"W3 c #627ED4",
+"W4 c #627ED5",
+"W5 c #617ED5",
+"W6 c #637ED3",
+"W7 c #647ED2",
+"W8 c #657ED1",
+"W9 c #667ED0",
+"Wa c #687FCE",
+"Wb c #687FCD",
+"Wc c #697FCC",
+"Wd c #6B7FCA",
+"We c #6D80C9",
+"Wf c #6E80C8",
+"Wg c #6E80C7",
+"Wh c #7180C4",
+"Wi c #7280C3",
+"Wj c #7481C1",
+"Wk c #7681BF",
+"Wl c #7781BD",
+"Wm c #7A81BB",
+"Wn c #7B82BA",
+"Wo c #7D82B8",
+"Wp c #7E82B6",
+"Wq c #8182B3",
+"Wr c #8283B2",
+"Ws c #8483B0",
+"Wt c #8683AE",
+"Wu c #8983AB",
+"Wv c #8B84A9",
+"Ww c #8D84A6",
+"Wx c #8E85A4",
+"Wy c #9185A2",
+"Wz c #9385A0",
+"WA c #95859D",
+"WB c #97869B",
+"WC c #998699",
+"WD c #9B8697",
+"WE c #9D8794",
+"WF c #A18790",
+"WG c #A2888F",
+"WH c #A3888D",
+"WI c #A6888B",
+"WJ c #A88889",
+"WK c #AA8987",
+"WL c #AC8984",
+"WM c #AE8981",
+"WN c #B18A7F",
+"WO c #B38A7D",
+"WP c #B58A7B",
+"WQ c #B88B78",
+"WR c #BA8B76",
+"WS c #BB8B74",
+"WT c #BE8B71",
+"WU c #C08C6F",
+"WV c #C18C6E",
+"WW c #C48D6B",
+"WX c #C58D69",
+"WY c #C88E67",
+"WZ c #CA8E64",
+"W& c #CC8E62",
+"X c #CE8E60",
+"X0 c #CF8E5E",
+"X1 c #D18F5C",
+"X2 c #D48F59",
+"X3 c #D68F57",
+"X4 c #D79057",
+"X5 c #D89055",
+"X6 c #DC9052",
+"X7 c #DC9051",
+"X8 c #DE914F",
+"X9 c #DF914E",
+"Xa c #E1914C",
+"Xb c #E2924B",
+"Xc c #E49248",
+"Xd c #E59247",
+"Xe c #E79245",
+"Xf c #E89245",
+"Xg c #EA9342",
+"Xh c #EB9342",
+"Xi c #EC9341",
+"Xj c #ED943F",
+"Xk c #EE943E",
+"Xl c #EF943D",
+"Xm c #F0943D",
+"Xn c #F1943B",
+"Xo c #F2943B",
+"Xp c #F2943A",
+"Xq c #F39539",
+"Xr c #F49539",
+"Xs c #F59539",
+"Xt c #F69537",
+"Xu c #F69637",
+"Xv c #F79637",
+"Xw c #F69638",
+"Xx c #F69639",
+"Xy c #F59639",
+"Xz c #F4963A",
+"XA c #F4963B",
+"XB c #F3953C",
+"XC c #F2953C",
+"XD c #F2963D",
+"XE c #F1963F",
+"XF c #EF9641",
+"XG c #EE9642",
+"XH c #ED9643",
+"XI c #EC9645",
+"XJ c #EA9647",
+"XK c #EA9648",
+"XL c #E99649",
+"XM c #E8954B",
+"XN c #E6954D",
+"XO c #E5954E",
+"XP c #E3944F",
+"XQ c #E29551",
+"XR c #E19553",
+"XS c #DF9556",
+"XT c #DD9558",
+"XU c #DB955A",
+"XV c #DA955C",
+"XW c #D8955E",
+"XX c #D69560",
+"XY c #D59562",
+"XZ c #D49464",
+"X& c #D29466",
+"Y c #D09468",
+"Y0 c #CE946B",
+"Y1 c #CC936D",
+"Y2 c #CA936F",
+"Y3 c #C89371",
+"Y4 c #C69374",
+"Y5 c #C49377",
+"Y6 c #C39379",
+"Y7 c #C0937C",
+"Y8 c #BE937E",
+"Y9 c #BC9281",
+"Ya c #BB9282",
+"Yb c #B89285",
+"Yc c #B79286",
+"Yd c #B49289",
+"Ye c #B3928C",
+"Yf c #B1918F",
+"Yg c #AF9191",
+"Yh c #AC9194",
+"Yi c #AA9196",
+"Yj c #A99198",
+"Yk c #A7919A",
+"Yl c #A5919D",
+"Ym c #A290A0",
+"Yn c #A190A2",
+"Yo c #9F90A4",
+"Yp c #9D90A7",
+"Yq c #9B90A9",
+"Yr c #998FAB",
+"Ys c #978FAD",
+"Yt c #958FAF",
+"Yu c #938FB2",
+"Yv c #928FB3",
+"Yw c #8F8FB8",
+"Yx c #8E8FB8",
+"Yy c #8C8EBB",
+"Yz c #8A8EBD",
+"YA c #888EBF",
+"YB c #888EC0",
+"YC c #868EC3",
+"YD c #838EC6",
+"YE c #828EC7",
+"YF c #808EC9",
+"YG c #7E8DCB",
+"YH c #7D8DCD",
+"YI c #7C8DCF",
+"YJ c #7A8DD0",
+"YK c #788DD2",
+"YL c #778DD4",
+"YM c #768DD5",
+"YN c #758CD7",
+"YO c #748CD8",
+"YP c #738CDA",
+"YQ c #718CDC",
+"YR c #6F8CDE",
+"YS c #6F8CDF",
+"YT c #6D8CE0",
+"YU c #6B8CE3",
+"YV c #6B8CE4",
+" 0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 3 4 5 6 7 8 9 a b c d e f g h i j 7 k l 3 m 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 n n 1 0 0 n 0 o o 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
+" p p q q p p q q p p q q p p q q p p q q p p q q p p n 0 3 5 r 8 j s a t u v w x y z A 7 B C 2 1 q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p D q q p D q E F F q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q",
+" G G H H G G H H G G H H G G H H G G H H G G H H I J K L M N O P Q R S T U V W X Y Z &0 000102030405 H H0606 H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H H H H H G G H H G G H H05 G H H G G H H G G H H G G H H G G0707 G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H",
+"0808090908080909080809090808090908080909080809090a I L L0b0c O0d Q0e0f0g0h0i0j0k0l0m0n0o0p0q030r G0s09090t0t0909080809090808090908080909080809090808090908080909080809090808090908080909080809090808090908080909080809090808090909090909080809090808090908080909080809090s0809090808090908080u0u0808090908080909080809090808090908080909080809090808090908080909080809090808090908080909080809090808090908080909",
+"0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0x0y0z0A0B0C0D0E0F0G0H0I0J0K0L0M0N0O0P0Q0R0S0T0U0V0y0x0w0w0v0v0W0W0v0v0w0w0v0v0W0W0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0x0X0X0x0x0v0v0w0x0X0X0v0v0v0v0Y0Y0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w",
+"0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z1 0w0w0y0A0B0C0S0E0F101112131415161718191a1b0T1c0z0y0w1 0&0&0Z0Z1d1d0Z0Z0&0&0Z0Z1d1d0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&1e0Z0&0&0Z0Z0&1 0Z0Z0&0&0Z0Z0Z0Z0Z0Z1f1f0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&",
+"1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1i1j1k1l1m1n1o1p1q1r1s1t1u1v1w1x1y1z1A1B1C1D1E1o1n1F1l1G1H1I1h1g1g1h1h1g1g1h1h1J1J1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1K1K1g1g1h1h1L1M1N1O1P1P1Q1Q1g1R1h1h1g1g1K1K1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h",
+"1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1U1V1I1G1m1W1X1Y1Z1&2 202122232425262728292a1o1n2b1l1G1i1g1V2c1U1S1T1T1S1S1T1T2d2d1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S2e2e1S1S1T1T2f2g2h2i2j2k2l2m1U1S1T1T1S1S2e2e1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T",
+"2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2p2q2r1Q2s2t2u2v2w2x2y2z2A2B2C2D2E2F2G2H2I2J2K2L2M2N2O2O2P2Q2R2R2q2p2o2S2T2T2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2p2n2U2V2W2X2Y2Z2&3 303132333435363637372n2n38382n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o",
+"39393a3a39393a3a39393a3a39393a3a39393a3a3b2n3c3d2s2t3e3f3g3h3i3j3k3l3m3n3o3p3q3r2J3s2L3t3u2N2s2O2P3v3w3w2q2p2o2S3x3y3a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a3b393a3a3z3A3B3C3D3D3D3E3F3G3H3I3J3K3L3M39393N3O39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a",
+"3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3T3U3V3W3X3Y3Z3&4 404142434445464748494a3Y3Y4b4c4d4e4f4g4h4i3W4j4k4l4m4n3T4o3Q3Q3S3S3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3T3P4p4p4q4r4s4t4u4v4v4v4s4s4v4u4w4x4y4z4A4B4C4C3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R",
+"4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E3Q3P4o4H3W4I4J4K4L4M4N4O4P444Q464R4S484T4U4V4J4W4X4Y4Y4Z4&5 4f5051524l4m4n3T3P3Q4E534G4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4E4E5454555556574s584v4v4v4u4t4t4v4v59594u5a5b5c5d5d4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F",
+"5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5g5e5f5h5i5j5k5l5m5n5o5p5q5r5s5t5u5v5w5x5y5z5A5B5A5A5C5D5E5E5F5G5H5I5J5K5L5M5N5O5j5j5P5h5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5Q5Q5f5f5e5e5f5f5R5e5f5S5T5U4u3D4v4v4v4v4u594v4v4v4v4u5V5W5X5Y5Z5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f",
+"5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5&6 5O606162636465666768696a6b6c6d6e6f6f6f6e6g6h6i6j6k6l6m6n6o6p6q6r6s6t6u6v5O6w5&6x5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h6y6y6z6z5R5R5h5h6x5R5f5h6A6B4u4v4u4u4u4u4u4u4u4u4v4v4u6C6D6E5Z6F5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h",
+"4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D6G3R6H6I6J4f6K6L6M6N6O6P6Q6R6S6T6U6V6W6X6Y6Z6&7 70717272737475767778797a7b4I517c4m7d7e7f4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4E4E4E4E7f7g4E7h7i7j4v4v4u4u4u4u4u4u4s4s4v4v7k7l7m5R7h5d4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E",
+"3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3T7n7o3V4j7p4Z7q7r7s6N7t7u7v7w7x7y7z7A7B7C7D7E7F7G7H7I7J7K7L7M7N7O7P7Q7R7S7T7U7V517W7X7Y7Z4C3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3Q3Q3Q3Q7&7&3Q3Q8 804v4v4u4u4u4u4u4u4s4s4v4u818283833Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q",
+"8484858586868585848485858484858587883b2p898a8b3s8c8d8e8f8g8h8i8j8k8l8m8m8n8o8p8q8r8s8t8u8v8w8x8y8z v8A8B8C8D8E8F8G8H8I8J8K8L8M8M8484858586868585848485858N7n858584848484878485858M8M858M8N8N858584848585848485858686858584848585868685858484858587844C8I313D4u4v4u4u4u4u4u4u4u4u4u4v8O8P8Q8485858R8R858M8487858M8484858M8484858M8R8R858584848585848Q85858487858S84848585848485858585858584848585858585858N8N858M",
+"87878M8M8T8T8M8M87888M8M87878U3a888V2p2Q8a3u8W2I8X8Y8Z8&9 909192939495969798999a9b9c9d8u8v8v9e9e9f9g9h9i9j9k9l9m9n8G9o9p9q9r2n3988878M8M8T8T8M8M87878M8M7n7n8U8U8888878787878M8M8M8M8M8M7n7o393988888M8M87878M8M8T8T8M8M87878M8M8T8T8M8M87878M8M88879s9t9u4u4u4v4u4u4u4u4u4u4u4u4u9v9w9x87878M8M9y9y393987878M8M88878M8M87878M399z9z8M8M87878M8M87888M8587888M8M87878M8M87878M8M8M8M8M8M8787858M8M8M8M397n7n8M8M",
+"9A9A9B9B9A9A2S2S9A9A9B9B9A9A9C9C2p2q2Q2P9D9E9F9G9H9I9J9K9L9M9N9O9P9Q9R9S9T9U9V9W9X9Y9Z9&a a a0a0a1a2a3a4a5a6a7a8a9aaabacad3vaeaeaf9C9B9B9A9A9B9B9A9A9B9B9Aag9B9B9A9A9B9B9A9A9B9B9A9Aahah9A9A9B9B9Aai9B9Bajaj9B9B9A9Aakak9A9A9B9B9A9A9B9B9A9A9B9Bai9Aalaman4u4u4v4u4u4u4u4u4u4s4s4uaoapaqai9A9B9B9A9A9B9B9A9A9B9Bai9Aar9B9A9A9A9A3b3b9B9B9A9A9B9B9A9A9A9A9A9A9B9C9A9A9B9B9A9A9B9B9B9B9B9B9Aai9B9C9A9A9B9B9A9A2S3a",
+"aiai9C9Caiai2o2oaias9C9Caiasatau3v2Pavawaxay9GazaAaBaCaDaEaFaGaHaIaJaKaLaMaNaOaPaQaRaS9&aTaUaVaVaWaXaYa3aZa&b b0b1a9b2b3b4avb5b6ataf9C9C9Aai9C9Caiai9Cafaias9C9C9Aai9B9Caiai9C9Basb7b8b99Aai9C9Caiai9C9Cbaba9C9Caiaibbbbaiai9C9Caiai9C9Caiai9C9Casasalbcbd4u4v4v4u4u4u4u4u4u4s4s4vbebfbgaiaiafafai9A9C9B9Aai9C9Caiai9C9Caiaiaiai2n2p9C9Casai9C9Caiaiaiasaiai9C9Caiai9C9Caiai9C9C9C9C9C9Caiai9C9Caiaiaf9Caiai2o2o",
+"bhbhbibibhbhbibibhbhbibibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb&c c0c1ayc2c3c4c5c6c7bjbjbhbhbibjbhbhbibibhbhbjbiafafc8c8c9cacbcccdcecfcgchchcici60602Tcjckbhbibibhbhchchbhbhbibibhbhclclbhbhcmcmcncncocpcq4u4u594v4u4u4u4s4s4u4ucrcscmcmbjbibibictctcucvcwcxcyczcAcBcCc9asasafafbhbhbibibhbhbibibibicmcmcDcEcFcobhbhbibibhbhbibibibjcGcHcIcJcKcLasasbibicMcMclcl",
+"ckckbjbjckckbjbjcNckbkbkblbmcOcPcQcRcScTcUcVcWcXcYcZc&c&d d0d1d2d3aMbGbGd4d5d6d7d8d9dadbdcdddedfdgdhbVdidjdkdldmdndodpc1dqdrdsc4dtc6bkbkckckbjbjckckbjbjckckbjbjaududvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdL9EckckbjbjckckdFdFckckbjbjckckdMdMckckdNdNdOdPdQdRdS4u4u594u4u4u4u4s4s4u4udTdUdNdNbkbjbjbjdVdWdXdYdZd&e e0e1e2e3e4e5e6atauckckbjbjckcNbjbkbkbkdNe7e8e9eaebckckbjbjckckbjbjbkecedeeefegeheieje6bjbjekeldMcl",
+"ememenenememeoeoepeqerereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLbHbHeMeNeOePeQeReSeTeUeVeWeXeYeZe&f f0f1f1f2f3f4f5f6f7f8f9cTfaevfbfcerfdememeoeoemfeeoeoememfffgfhfifjfkflfmfnfofpfpfqfrfsftfufv6CfwfxfyfzfAeoeoememfBfBememeoeoememeoeoememeoeoememfCfDfmfmfmfEfmfmfFfGfHfHfmfIfJfKfdeofLfMfNfOfPfQfRfnfofofmfEfEfEfEfSfTfUfVc6ememfWfWememfXfYfZf&g g0g1g2g3g4ememememfVfVeoeog5g6g73Efmfmg8g9ga2Reoeoepepeoeo",
+"gbgbgcgcgbgberergdgegfggghgigjgkglgmgngogpgqgrgsgtgugvgwgxgygzgzbHbHgAgBgCgCgDgEgFgGgHgIgJgKgLgMgNgOf0f1gPf0gQgRgSgSgTgUgVf9gWfagXghgYgZgbgberergbgbererg&h h0h1h2h33E3E3E3Eh4h5h6h6h7h8h9ha3E3E3E3Ehbhchdhderergbgbhehegbgberergbgberergbgbererg&gbhfhghbfEhb3EfEhbhhhhfphifEhjhkhlererhmhnfOhodS3Eh4h5h4h43E3Ehbhb3E3Ehphqhrhsgbgbhthug&gbhvhwhxhyhzhhh4h4hAhBgbgbgbgbhshsererhChD3E3E3E3EhEhFhGhGererhHgderer",
+"hIhIhJhJhKhK0Z0ZhLhMhNhNhOhPgWhQhRhShThUhVhWhXhYhZh&i i0i1i2eLi3i4i4i5i6i7i8i9iaibeMicidieifigihbVdif1gPiigPijikiliminioipiq0R1biris0X1eithIhJhJiuhIhJhJiviwixdSdS3EiyiyiziAdSdSdSiBiCiBiDiEiFiGiHiIiJiKiLiMiNiOhIhIhJ0ZhIhIhJhJhIhIhJhJhIhIhJiPiQiR4ziSdSdSiB3EiTiTdSdSiUiViWiXiYiZi&j j0aoj1iTdSiBiKiBiVj2j3j4j5j6j7iKizj8j9jaivivjbjcjdjejfjgjhdSiViViViUjijjithIhJiPhIitjkjljmjniziziB6CjojphIhIhJhJhIhIhJhJ",
+"itit0Z0Zjqjr1e0vjsjtjujvjwjxjyjzjAjBjCjDhWjEjFjGjHjIi i0i1jJgzi3jKjLjMjNjOjPjQjRjSjTjUjVifjWjXjYbVdif1gPiiiijZj&k k0k1k2k3k4k51ak6k7k80Xk9it0Z0Zitit0Z0ZhLjskakb9v9vkckckdke9v9viLiLkffwkgkhkikjkkklkmkniLkokpkqitit0Z0Zitit0Z0ZhIit0Z0Zitit0Z0ZiQkriM9v9v9v9v9vksks9viLktkukvkwgZkxkykzfI9vkskA9viLiL5VkBkCkDkEkFkGkHkIkJkKkLkMkNkOkPkQkRkSkTksiJ9vkuktktktkUkVitit0Z0Zitk9kWkXkYiLkJkdkZkak&l ititl0l0itit0Z0Z",
+"l1l1l2l2l3l3l4l5l6l7l8l9lalblcldlelflglhliljlklllmlnloi0lplqgzi3bHlrlsltlulvlwlxlylzlAlBlClDlEbVbVdif1gPlFiilGlGlHlIlJlKlLlMlNlOkOlPlQl5lRl3lSlSlTl1l2l2l1l1lUlViLknknkblWlWiLknfllXlYlZl&m m0m0l1l1m1m2kbkbm3m4lTl1l2m0l1l1l2l2m5m5l2l2l1l1m6m6m7m8m9maknkbktktknknkbknknmbmcmdmemfhjflmgmalWmhmhmhmimjmkmll2l2l1l1mmmnmompmqmrmsmtmumvknknlWlWiLknkbkbkbkbmwmxl1l1l2l2mymzmAmBkbkbmamCmDmEl2l2l1l1l2l2l1l1l2l2",
+"l3l3m0l4lRmFmGmHmImJl9mKlbmLmMmNmOmPmQmRmSmTmUmVmWmXmYmZm&lqgzi3bHgzn n0n1n2n3n4n5n6n7n8n9nanbbVbVdif1f1lFiilGlGf0ncndlJnenfngnhninjnkmHmFlRnlnll1l3m0m0lRl3nmnnkfkfkfkfnonokfnpkfnqnrnsjshMm0l4lRlRntnukfnvnwnxl3l3m0l4lRl3l4m0nynyl4m0lRl3nznAnBnCnDnEkfkfnonFkfkfkfkfnpbenGnHnInJnpnpnEnDnonononKnLnMnNnNm0l4l3lRnOnPnQnRnSnTnUnVnvnvnpkfnWnoflkfkfnpnpnpnXnYl3l3m0l4eunZn&o npnpo0o1o2o3l4m0l3l3m0m0l3l3m0m0",
+"o4o4o5o6o7o8o9oaobocmKodoeofogohoiojokolomonooopoqorosotouovowoxbGeMoyozoAoBoCoCoDoEoFoGoHoIoJoJdidigPoKoLoMfG7k7koNoOoPoQoRoSoToUmKoVoWoXo8oYoZo4o4oYoZo6o5o&p jhjhjhp0jhjhjhp0p1p2oYoZp3o4oYoYp4p4p5p6jhp0p7p8oap9oYoYp9o7oYoYo4o4papao4o4pbjw4zpcp0jhpdpepepejhp0pfpgphpipjpkpl5Vp0p0jhjhp0p0pmpnpoppo4o40808o4o4pqprpsp0ptpupvpwp0p0jhp0p0jhpxjhjhp0p0jhpypzp3o4o4o4pApBpC5Vp0pDpEpFo4p3oZpGp4p4oYoYo4o4oYoY",
+"p3p3o6pHoXo9oWoVpIpJpKpLpMpNpOpPpQmSpRpSpTpUpVpWpXpYpZp&q q0q1oxbGeMq2q3q4oB9dq5q6q7q8q8q9q9qaqbdiqcgPoKoLoM7k4s4s4sqdqeoQqfqgqhqiqjqkoVoaoXqloZp3p3oZoZo6pHqmqn5a5ako5a5a5a5a5aqoqpoZoZp3p3oZoZqqqqqrqsjnjnqtquqvo7oZoZo8o7oZqlp3p3papap3qwqxqyqz5ajn5aqAqAqAqA5a5aqBqCqDqEqFqGqH5a5ajnjn5a5aqIqJqKqLqLp3qw0s0sp3p3qMqNqOjnqPqQqRkwjnjn5a5ajn5ako5ajn5ajn5aqSqTp3p3p3qUqVqW5ajniSqXqYqZp3p3oZoZqqqqoZoZp3p3oZoZ",
+"q&q&r r0r1r2r3r4r5r6r7r8r9rarbrcrdrerfrgrhrikYrjrkrlrmrnrorprqrreMeMrsoCoC9drtrtrurvrw9&rxryrzrArBrCgPoKiiii4t4s4v4vrDrErFrGrHrIrJrKrLrMrNrOr0r0q&q&r r0q&q&rPrQrRrRrRrRrRrRrRrSrTrUr0r q&rVr0r q&rWrXrYrZrRrRr&s pHr r s0s0s1s1s2s3s4s4q&q&s5s6s7s8rRrRrZrRrRrRrRrZs9sasbscsdserZrRrRrRrRrZrRsfsgshr0r q&rVsisjq&q&skslrmrRsmsnsospsqsrrRrRrRrRrRjnrRrZssstsusvq&q&swsxqOrZs8syszsAr r0q&q&r r0q&q&r r q&q&r r ",
+"rVrVsBsBsCsDsEsFsGsHsIsJsKsLsMrcsNsOsPsQrhsRrSsSsTsUsVsWsXsYsZs&eMeNt oCoC9drtrtt0t1t2t3t4t5t6t7t8t9f1oKiiii4t4s4v4vtatbtctdtetftgthtitjtkrNtlsBrVrVr0sBtmrVcctnfIfItofIfIfIfItptqtrr0r0rVtmr0r0rVq&tsttlXlXtotutvtwr0r0txtytztAtBtCtDtErVrVtFtGsysyfIfIlXfIfIfIlXfItHtIsctJtKtLfIfIfIfIfIfItMtNtOscsBsBtmrVsjsjtmrVtPtQtRpDtStTtUtVtWtXfIfItofItofIfIlXtYtYsutZrVrVt&u iSlXsyu0u1u2sBsBrVrVr0r0rVrVr0r0rVrVr0r0",
+"u3u3u4u5u5u6u7u8u9uaubucudueufuguhuipciCujukulumunuoupuqurusutuueMeNuvuwuwuxuyuzuAuBuCuDuEuFuGuHuIuJgFuKlGlG584t4s4tuLuMuNuOuPuQuRrJuSuTuUuVuWuWu3u3uXuXuYuZu&v iSiSiSv0v1v1v2v3v4sBuXu4u3u3uXuXv5v6jmv7v0v0v8v9vavbvcvdvevfvgvhvivjvkvlvmvnvoqHvpvqiSiSiSiSiSiSiSvrvsvtvuvvvjv0iSiSiSv0v0v0vwvxuZuZuXuXu3u3uXuXvyrOvzvAvqvBvCvDvEu3vFvGhcv0vqvqvHiSvIvIv0v0qSvJk6vKvLvMvpvpvNvOvPvavQvQvRu3vSuXu3u3uXuXu3u3uXuX",
+"vTvTvUu6vVvWvXvYvZv&w w0udw1w2uguhw32&w4w5w6w7w8w9vBwawbwcwd9cuueNeNuwuxuwwegzwfwgwgwhwiwjwkwlwmwnwowpwqwrws584s4t4twtwuwvwwwxwywzwAwBuSwCuUwDwEwFvTvUu5wGwGwHv pCpCpCwIwJwKwLwMwNwNu5vUvTvTu5u5wOwPwQwIwIwIwRwSuWwTwUwVwWwXwIwIpDwYwZw&x vsx0pCx1x2pCpCpCpCpCwIulx3x4x5x6x7x8wIpCpCpCwIpDpCx9xawGxbu5u5vTvEu5u5xcxdxexfqCxgxhxiwFvTxjxkxlpCx1x1pCpCxmxnwIwIxoxpxqxrxsx1x1xtxuxvuWuWxwxwvTvTu5u5vTvTu5u5vTvTu5u5",
+"xxxxxyxzxAxBxCxDxExFxGxHxIxJxKxLxMxNxOw7xPx8xQwQxRxSxTxUxVxWxXgAeMeNxYlqxZx&y y y0y0y1y2y3y4y5y6y7y8y9yaybycydydyeyfygyhyiyjykylymynyoypyqyrysytyuxxyvyvywyxyyyzqHqHqHyAyAqHtGyBxxxxxxxxxxxxyCyCyDyEyAyAyAyAyFyGyHyIyJqIyKyLyMyNyOyPyQyRySyTyAyAqHqHqHqHqHqHyUyVyWnGxyxyyXyYyZqHqHqHqHyAyAqHy&ccz z0yvyvxxxxyCyCz1eez2z3z4z5yvyvz6z7xbz8z9zazbyKqHzcqHyAyAyAkUzdzezfqHqHzgzhziwExbxbzjzjxxxxyvyvxxxxyvyvxxxxyvyv",
+"zkzkytysxBzlzmznzozpzqzrzsztzuzvzwzxzyx0xOzy6CuqzzzA4xujzBzCgAgAi2zDt7zEzFzFzGrczHzIzJzKzLzMzNzNzOzPzQzRzSzTzUoAzVzWzXzXzYzZz&y7A ynA0A1yqxCA2A3A4zkxzxzA5A5A6A7A8A8A8yZyZA8A9AazkzkzkyuzkzkwDAbAcAdyZyZA8yZAeAfAgAhyZyZAiAjwSAkAlAmAnAoApAqiCA8A8A8A8A8yZA8ArjfAsAtytxzAuAvyZyZA8A8A8A8yZyZAwAxAyAyytytA4A4AzAAABACo0ADAEAFytytAGAHAIAIAJz9AKqCA8A8A8yZyZyZALAMANAOiCwYAPAQAzwDAIAIARARyuzkxzxzzkzkxzxzzkzkxzxz",
+"ASATAUAVAWAXAYAZA&B B0B1B2B3B4B5lkB6B7B8B9BaBbBcBdBeBfBgBhBhBiBjBkBlBmBmBnBnBoBpBqBrBsBtBuBvvvBwBxByBzBABBBCBDBEBFBGBFBHBIBJBKwxBLtDBMBNBOBPBQBRAUBSBSBSATATBTBUBVBVBWBWBXBYBZB&AHAGC C ATATC0C1C2C3C4C5BXcqC6C7C8C9BWBXCaCbCcCdCeCfCgChCiBXBXBWs7CjBXBXBXCkClCmASCnAUBSCoCpC4C3tRBWBWBXBWBXCqCrAzAzBSAUCsu7fNCtCuCvCwCxCyCzBSBSATATBSAUCACBCCCDBWBWBXBXBXBXCECFCGCvCHCICJCsAUBSATATCKCKASATBSBSATATBSBSATATBSBS",
+"CnCnAVAWCLAXAYAZCMB CNB1COCPCQCRCSCTCUCVCWCXCYCZC&D uuD0D1D2D3D4D5D5D6D7D8D96&DaDbDcDdDeDfDgDhDiDjDkDlDmDnzQDoDpDqDrDsDtDuDvDwDxDyDzDABNDBBPBQBRAUAUAUAUCnCnDCDDujujpcj7j7upDEDFDGDGDHDHDICnDJDKDLoqDMoqpcfwDNDODPDQj7pcDRDSDTDUDVDWDXDYj7j7j7mbDZujj7j7D&E E0E1CnCnAVAUE2E3DMDMmbj7j7pcj7j7E4E5E6E7AUAUCsE8E9EaEbEcEdEeCzvWAVAUCnCnAVAUEfEfEgEhvhj7j7pcpcpcEifsEbEjEkElCsCsAUAUDICnEmEmCnCnAUAUCnCnAUAUCnCnAUAU",
+"EnEnEoEpEpEqErEsEtEuEvEwExEyEzEAEBECEDEEEFEGgzd4lpEHEIEJEKELEMENEOB5EPEQERESETEUEVEWEXEYEZE&F F0F0F1F2F3F4F5F6F7F8F9FaFbFcFdFeFfFgFhFiFjFkFlEpEpFmEnFnEoFoFpFqFrrjkYmCmCkYFsFtFuFvEnFnFnFwFxFyFzkYrSkYkYkYFAFBzlFCFDFEFEulFFFGFHpsFIkYrSmCFEFJFKkYkYFLFMFNFOFnEoEnEnFnFn0FFPFQFJkYrjkYkYrSkYFRFSFTFUFVFWFXFYkZrSFZqDF&xCFmEnFnFnG G G0G1EnEnFoG2zhG3rSkYG4G5psG6kYfxG7uTFmEnFnFnG8G8FnFnEnEnFnFnEnEnFnFnEnEnFnFn",
+"FmFmEoEpEqG9GaGbEtEuEvGcGdGeGfGgGhx&GiGjGkGkGlGmEHEHGnGoGpGpGqGrGsGtGuGvGwGxGyGzGAGBGCGDGEGFGGGHGGGHGIGJGKGLGMGNGOGPGQGRGSqfGTGUGVGWGXGYFkGZEqEpFmFmEoEoFoG&ix2&H 2&H0H0H1ixH2H3FmFmEoEoFwH4H5H02&H12&2&kIkHH6H7H8H9HaHaH1H12&H12&2&2&2&H0H0HbHc2&HdHeHfHgHhEpEoHiFmEoEoHjHkHlHc2&2&2&H12&H1HmHmHnHoHpHqHrHsFIHtHuHvzmyqHiFmEoEoHwHxHyHyFmFmFoHzHAHBum2&yVyVHC2&fvFqHDu9HiFmEoEoHEHEEoEoFmFmEoEoFmFmEoEoFmFmEoEo",
+"HFHFHGHHHIHJHKHLFiHMHNFgHOHPHQHRHSHTHUHVrzloi i0HWHXxZHYHZH&I I0I1I2I3I4I5I6FeI7I8I9IaIbIcIdIeIeIfIfIdFgIgIhIiIjIkIlIlIkImInIoIpHMIqIrIsItIuIvHHIwIwHGHHIxIyIzIAIBIBIBIAICcsHGHHIwIwHGHGIDtQaoulIEIFIGIHIIIJHGHHtVIKILulwYwYIAIAwYwYIMIMwYulwYINyIIOIPIQIwIwHGHGIwIwHGHGHGIRISITFIulIBIBwYwYululwYwYulwYIUIVIKIWIXEqHGHGIwIwHFHFIwIwHiIYIwIwIZI&J J0J1J2wYulwYrmJ3J4HGHGIwIwHGJ5J6J6HGHGIwIwHGHGIwIwHGHGIwIwHGHG",
+"J7J7IvIuJ8J9JaHLJbJcGVFgJdJeJfJgJhJiHVHVrzloi i0HWHXJjJkCQJlJmJnJoJpJqJrJsJtJuJvJwJxEwJyJzJAJBJBJCJDJAJzJEJFGGJGJHJIJJJKJLJMIpJNJcIqIrJaItIuIuIvHIHIIvIvJOJPJQJRJSJRJRJRJTh8IvIvHIHIIvIvJUJVJWJXJYJZJ&K K0K1IvIvsoK2K3K4K5CkJRJSCkkZK6K7fwyJK8kHK9KaKbKbJ8HIIvIvHIHIIvIvIuIvKcKdKeupKfJRkZkZkZkZCkCkD&HtKgKhKiKjG9KkIvIvHIHIJ7J7HIHIGZGZHIHIKlKlKmKmKnKoCkkZKpKqKrKsIvHHHIHIIvIvKtKtIvIvHIHIIvIvHIHIIvIvHIHIIvIv",
+"KuKuKvKwKxKyKzKAKBKCKDKEKFKGKHKIKJKKHVryKLKMi i0lplpKNKOKPKQKRKSKTKUKVKWKXKYKZK&L L0L1L2L3L4L5L5L6L7L8L9LaLbLcLdL0L LeLfKELgL2LhLiLjLkKzLlLmLnKvLoLoKvKvLpLqLrLsLtLuLvLwLxLyLnKvKuKuKvKvLzLALBLCLDKxKvKvLmKuKvKvKuKuLELFLGLHLILJLKqGLLtQLMLNLOLPKuKuLQKxKuKuLRLRKuKuKvKvKuKuKxLSLTFNLULVLWLXLYEeLZL&M M0M1M2KvKvKuKuKxKxM3M3KxKxM3M4KvKvKuKuKvKvM5M5M6M7KpKpM8kyKuKuKvKvKuKuKvKvKuKuKvKvKuKuM9M9KuKuKvKvKuKuKvKv",
+"KuKuKvKvLQKyKzKAKBMaMbKEMcMdMeMfMgMhHVryKLKLi i0lpMiMjMkMlMmMnMoMpMqMrMsMtMuMvMwMxMyMzLhMAMBMCMCMDMEMFL5MGMHMbMIMJMyMKMLLgMbLhMMLjLkMNKzLmLmKvKvMOLoKvKvMPMQMRMSMTMUMVMWMXMYKvLnKuKuKvKvMZMZLPLPLQLQLnKvKuKuKvKvKuKuM&M&N N0N1N2N3qFN4N5nhnhLPN6LmKuKxKxKuLmLRLRKuKuKvKvLmKuKxKxN7N7N8N9NaNbNcNdNeNfNgNgNhM2LnKvKuKuKxKxM3M3KxKxM3M3KvKvKuKuKvKvM5NiNjNkw8hjNlNmLmKuKvKvKuKuKvKvKuKuKvKvKuKuM9M9KuKuKvKvKuKuKvKv",
+"NnNnNnNoNpNpNqNrNsNtNuNvNwNxNyNzNABmHVryNBi NCNCeKgzNDNENFNGNHNINJNKNLNMNNNONPNQNRNSNTNUNVNWNXNYNZN&O O0O1O2NTO3O4O4O5O6O6O7NtO1NWO8NYO9NpNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnOaOaNnNnNnNoNnNnNnNnNpNpNnNpObObObObOcOdNnNnNpNnOcOdNnNoNnNnNnNnNpNnNpNnNnNnNnNnNpNnOeOfNpNnNnNnNnNnNnNoNnNpNnNnNpNnNpNnOdOdNnNnNnNnNnNnmLOgOhOiOjOkOlOmOnOnOoOpbdOqOrOsOtOuOdOdNnNpNnNnNnNnObObNnNnNnNnNnNnNnNnNnNnNnNnNnNn",
+"OvOvOvOvOvO8OwOxO2OyNuNvK&OzOAOBOCODOEOFNBi NCNCeKeLOGOHOIOJOKOLOMONOOOPNOLCNQOQORNSNTNUOSNVOTOTOUOUO0OVO2NtNTNTOWO4O6O3O3O7NtO2OSNVNXNYOvOvOvOvOvOvOvOvOvOvOvO8O8OvOvOvOvO8OvOvOvOvOXOXOvNpOvOvOvOvOvOvOvOvOvOvNYO9NYO9OYOYOvO8OvOvOYNZO8OvO8OvOvOvO8OvOvOvOvOvOvOvOvOvOZOZOvOvOvOvO8OvOvO8OvOvOvOvOvOvOvOvOYOYOvOvO8O8O8OvO&P P02gP1P2P3P4P5P6P7P8up3 P9PaPbPbOYOYOvOvOvOvOvOvO9O9OvOvOvOvOvOvOvOvOvOvOvOvOvOv",
+"PcPcPdPdPePePfPgPhPiPjPkPlPmPnPoPpPqrdPrNBi i0i0HXHXPsPtPuPvPwPxPyNLPzPAPBPCPDPEPFPGPHPhPIPIPfPfPJPJPgPgPhPHPHPHPKPLPMPMPFPGPNPOPIPPPgPdPePePdPdPJPePfPdPePQPdPdPePJPdPdPePePdPfPQPePRPRPJPePdPdPePePdPdPPPSPTPdPUPUPdPdPVPVPPPVPePePVPVPePePdPfPcPcPRPRPePePdPdPePePdPdPePePdPdPePePWPRPePePdPdPePePdPdPePePdPdPePePRPWPXPYFqPZrnP&vhQ Q0Q1Q2Q3Q4Q5Q6Q7Q8Q9PfPdPePePdPdPePePdPdPePePVPVQaQaPdPdPePePdPdPePePdPd",
+"QbQbPgPgQcQcPgPOPHQdPjQePlQfQgQhQiQjQkQli i i0lpHXd4QmQnQoQpQqQrQsQtQuQvQwQxPEQyPGQzQAPhPhPhPOPOQBQBPgPOPhPhPHPHQCQCQDQEQzQzPNPOPhPhPgPgPJQcPgPgQcQcPgPgQcQcPOPgQcQcPOPgQcQcPgPOQcQcQFQFPJQcPgPgQcQcPgPgPIPIPgPgPUQGPfPgPIPIPIPIQcQcPIPIQBQcPgPgQHQbQFQFQcQcPgPgQcQcPgPgPJQcPgPgQcQBQFQFQBQcPgPOQcQcPgPfQcQcPgPgQcQcQFQFQIQJQKpsQLplqOpsQMQNQ3QOQPQQQRQSQTMaPOPgQcQcPgPgQcQcPfPgQcQcPIPIQUQUPgPgQcQcPgPgQcQcPgPg",
+"QUQUQUQUQUQUQVQVQAQdQWQXQYQZQ&R R0R1R2R3NBi i0lpeLeKBmR4R5R6R7R8QfR9RaRbRcRdPiQAReReQVQVQUQURfRfQUQUQUQUQVQVReReReRePNPNReQVQVQVQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQURgRgQUQUPJQcQVQVRhRiRjQPRkRlRmRnRoRpRqRrRsRtRuMAQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQU",
+"QUQUQUQURvQUQUQVPHPiQWRwRxRyRzRARBRCRDREi i i0lpeLeKRFRGRHR6RIRJRKRLRMRNROQdQAPHQVQUQUQUQUQURfRfQUQUQUQUQUQUQUQUQVQVPOPOQVQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQURgRgQUQUQcQcQVQURPRQRRQPRSRTRURVRWRXRrRYRZR&MAL4QUQUQURvQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQU",
+"PgPgPgPgPgPgPgPOPHPiS S0S1S2S3S4S5S6S7S8OFS9SaSbScKKSdSeSfSgShSiSjSkSlSmSnSoPNPOPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPfPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgQUQUPOPgPgPgSpSqRrpsSrSsStSuSvpsSwSxSyMMPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPg",
+"PgPgPgPgPfPgPgPgPHQAS SzSASBSCS4SDSESFSGSHSISJSKSLSMSNSOSPSgSQSRSSSTSUSVSoSWPOPOPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgQUQUPfPgPgPgRhSXSYpsSZSZS&SZpsiMT T0MMT1PgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPg",
+"POPOPOPOPOPOPOPOPNSWQyT2RbT3T4T5T6T7T8T9TaugTbTcTdTdTeTfTgThTiTjTkTlTmSVTnToPNPOTpTpQVQVPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPNPOTqTrTsTtTuTvdUTwTxTyTzTAPOPNPOPOPNPNPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPO",
+"POPOPOPOPOPOPOPOPNSWTBTCRNTDTETFTGTHTITJTKTKTLTLTMTNTOTPTQTRTSTTPzTUTmSVTVToPNPOTpTpQVQVPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOTWTqTXTYRTTZT&U U0U1TAU2POPOPOPOPNPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPO",
+"U3U3U3U3U3U3U4U4U5U6U7U8TmU9UaUbUcUdUeUfUgT9UhSdUiUjI1UkUlUmUnUoUpRMUqUrTVToU5U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U5U3U3U3U5U3UsU7U3U3U3U3U3U3TpUtU3UuU3U3U3UuU3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4",
+"U5U5U5U5U5U5UvUvU5UwU7U8SmUxSTUyUzUAUBUCUDUEUFUGUHUIUJUKULUMUNUOUPUQURUrTVToU5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U3U5U5U5UwUwUwU5USUSUwU5U5UwUwU5UtUtU5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUv",
+"UTUTUTUTUTUTUTUTUTUUUVUWUXUYUZU&V V0V1V2V3V4V5V6V7V8V9VaVbVcVdVeVfVgUXVhViUUUTUTVjVjUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTVkVkVlVlU3U3UTUTVlVlVmVmUTUTVkVkUTUTVlVlUTUTUTUTUTUTVjVjUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUT",
+"UUUUUUUUUUUUUUUUUUVnVoUWUXVpVqVrVsV VtVuVvVwVxVxVyVzVAVBVCVDVEVFVGVHUXVhViVnUTUUVIVIUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUVJVJUsUsU5U5UUUUUsUsVKVKUUUUVJVJUUUUUsUsUUUUUUUUUUUUVIVIUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU",
+"KCKCMGMGMGMGMGMGKCKCMHLaVLVMVNLdVOVPVQVRVSVTIjVUVVVWVXVYVZV&W W0LcLgLaL3W1KCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGW2W2MGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMG",
+"W3W4W5W5W4W5W3W6W6W7W8W9WaWbWcWdWeWfWgWhWiWjWkWlWmWnWoWpWqWrWsWtWuWvWwWxWyWzWAWBWCWDWEWFWGWHWIWJWKWLWMWNWOWPWQWRWSWTWUWVWWWXWYWZW&X X0X1X2X3X4X5X6X7X8X9XaXbXcXdXeXfXgXhXiXjXkXlXmXnXoXpXqXrXsXsXtXtXuXtXvXvXvXuXuXuXwXxXyXzXAXBXCXDXEXEXFXGXHXIXJXKXLXMXNXOXPXQXRXSXTXUXVXWXXXYXZX&Y Y0Y1Y2Y3Y4Y5Y6Y7Y8Y9YaYbYcYdYeYfYgYhYiYjYkYlYmYnYoYpYqYrYsYtYuYvYwYxYyYzYAYBYCYDYEYFYGYHYIYJYKYLYMYNYOYPYQYRYRYSYTYTYUYUYV"};
+
diff --git a/Source/Plugins/Plugin_nJoy_Testing/Src/GUI/Images/njoy.xpm b/Source/Plugins/Plugin_nJoy_Testing/Src/GUI/Images/njoy.xpm
index 2214139485..746e6569c7 100644
--- a/Source/Plugins/Plugin_nJoy_Testing/Src/GUI/Images/njoy.xpm
+++ b/Source/Plugins/Plugin_nJoy_Testing/Src/GUI/Images/njoy.xpm
@@ -1,4028 +1,4028 @@
-/* XPM */
-static const char *AboutBox_WxStaticBitmap1_XPM[]={
-/* AboutBox_WxStaticBitmap1 */
-"200 60 3963 2",
-" c None",
-" 0 c #98CAFD",
-" 1 c #99CBFC",
-" 2 c #97C9FC",
-" 3 c #96C8F9",
-" 4 c #95C7F8",
-" 5 c #94C6F7",
-" 6 c #93C5F6",
-" 7 c #92C2F2",
-" 8 c #91C1F1",
-" 9 c #91C0EC",
-" a c #8DBCE8",
-" b c #8BB6E3",
-" c c #81ACD9",
-" d c #707CA6",
-" e c #B1BDE7",
-" f c #BCCAEF",
-" g c #526085",
-" h c #6E98C2",
-" i c #8BB5DF",
-" j c #90C0F0",
-" k c #93C5F8",
-" l c #94C6F9",
-" m c #97C9FA",
-" n c #99CBFE",
-" o c #9ACAFB",
-" p c #9ACCFD",
-" q c #9ACCFF",
-" r c #92C4F5",
-" s c #8EBDE9",
-" t c #8CB7E4",
-" u c #79A4D1",
-" v c #6F7BA5",
-" w c #D7E3FF",
-" x c #8E9CC1",
-" y c #58668B",
-" z c #6B95BF",
-" A c #8AB4DE",
-" B c #95C5F5",
-" C c #95C7FA",
-" D c #9BCDFE",
-" E c #9BCDFF",
-" F c #9CCCFD",
-" G c #A0D1FC",
-" H c #A1D0FC",
-" I c #A0D0FE",
-" J c #9FCFFD",
-" K c #9FCEFA",
-" L c #9ECDF9",
-" M c #9CCBF5",
-" N c #9BCAF4",
-" O c #9AC7F1",
-" P c #97C4EE",
-" Q c #94BFE9",
-" R c #93BEE8",
-" S c #91BBE3",
-" T c #8BB5DD",
-" U c #8EA2D5",
-" V c #6F83B6",
-" W c #B7BDDF",
-" X c #BDC3E5",
-" Y c #556B90",
-" Z c #61779C",
-" & c #779FC2",
-"0 c #91B9DC",
-"00 c #97C4ED",
-"01 c #9AC7F0",
-"02 c #9DC9F6",
-"03 c #A0CCF9",
-"04 c #9ECFFA",
-"05 c #9FD0FB",
-"06 c #A0D1FA",
-"07 c #A1D0FE",
-"08 c #A2D3FE",
-"09 c #A3D2FE",
-"0a c #A1D1FF",
-"0b c #9DCCF6",
-"0c c #9AC9F3",
-"0d c #96C3ED",
-"0e c #91BCE6",
-"0f c #89B3DB",
-"0g c #78A2CA",
-"0h c #7488BB",
-"0i c #99ADE0",
-"0j c #C7CDEF",
-"0k c #6D7395",
-"0l c #546A8F",
-"0m c #748AAF",
-"0n c #85ADD0",
-"0o c #96BEE1",
-"0p c #99C6EF",
-"0q c #9BC8F1",
-"0r c #A1CDFA",
-"0s c #A1D2FD",
-"0t c #A2D3FC",
-"0u c #A3D2FF",
-"0v c #A6D6FC",
-"0w c #A8D5FC",
-"0x c #A7D4FB",
-"0y c #A6D3FA",
-"0z c #A5D2F9",
-"0A c #A4D0F7",
-"0B c #A2CEF5",
-"0C c #A0CCF1",
-"0D c #9DC9EE",
-"0E c #9CC4E8",
-"0F c #99C1E5",
-"0G c #99BDE1",
-"0H c #89ADD1",
-"0I c #8094C6",
-"0J c #798DBF",
-"0K c #9EAAD4",
-"0L c #AFBBE5",
-"0M c #617598",
-"0N c #53678A",
-"0O c #6689A7",
-"0P c #80A3C1",
-"0Q c #8FBADD",
-"0R c #99C4E7",
-"0S c #9CC8ED",
-"0T c #9FCBF0",
-"0U c #A2CFF6",
-"0V c #A3D0F7",
-"0W c #A8D5FE",
-"0X c #A5D5FB",
-"0Y c #A9D5FC",
-"0Z c #A8D8FE",
-"0& c #AAD7FE",
-"1 c #A9D6FD",
-"10 c #85A9CD",
-"11 c #7094B8",
-"12 c #7F93C5",
-"13 c #97ABDD",
-"14 c #9DA9D3",
-"15 c #64709A",
-"16 c #54688B",
-"17 c #7185A8",
-"18 c #7FA2C0",
-"19 c #94B7D5",
-"1a c #98C3E6",
-"1b c #9DC8EB",
-"1c c #A2CEF3",
-"1d c #AAD7FF",
-"1e c #A7D7FD",
-"1f c #ABD7FE",
-"1g c #AED9FB",
-"1h c #AED9FC",
-"1i c #ADD8FA",
-"1j c #ACD7FA",
-"1k c #ABD6F9",
-"1l c #AAD5F7",
-"1m c #A7D2F4",
-"1n c #A7D0F0",
-"1o c #A5CEEE",
-"1p c #A2C9E8",
-"1q c #9FC6E5",
-"1r c #9DBAE2",
-"1s c #84A1C9",
-"1t c #7586BC",
-"1u c #899AD0",
-"1v c #95A3D2",
-"1w c #8593C2",
-"1x c #586D8A",
-"1y c #5A6F8C",
-"1z c #6B8BA4",
-"1A c #82A2BB",
-"1B c #91B8D7",
-"1C c #9AC1E0",
-"1D c #9EC7E7",
-"1E c #A1CAEA",
-"1F c #A8D3F5",
-"1G c #ABD6F8",
-"1H c #ACD7F9",
-"1I c #ADD8FB",
-"1J c #B0D8FB",
-"1K c #AED8FE",
-"1L c #707D86",
-"1M c #3D4A53",
-"1N c #798B99",
-"1O c #B6C8D6",
-"1P c #B8D6EE",
-"1Q c #B1D8F9",
-"1R c #AFDAFC",
-"1S c #B1DCFE",
-"1T c #B1DCFF",
-"1U c #B0DBFD",
-"1V c #AFDAFD",
-"1W c #A6CFEF",
-"1X c #A3CCEC",
-"1Y c #A0C7E6",
-"1Z c #96BDDC",
-"1& c #86A3CB",
-"2 c #83A0C8",
-"20 c #8C9DD3",
-"21 c #8A9BD1",
-"22 c #7280AF",
-"23 c #5A6897",
-"24 c #647996",
-"25 c #7B90AD",
-"26 c #89A9C2",
-"27 c #9ABAD3",
-"28 c #9CC3E2",
-"29 c #A1C8E7",
-"2a c #A2CBEB",
-"2b c #A9D2F2",
-"2c c #B0DBFE",
-"2d c #B3DBFE",
-"2e c #B1DBFF",
-"2f c #2D3A43",
-"2g c #606D76",
-"2h c #3F515F",
-"2i c #000F1D",
-"2j c #1E3C54",
-"2k c #537189",
-"2l c #7DA4C5",
-"2m c #AED5F6",
-"2n c #B6DFFB",
-"2o c #B6DFFD",
-"2p c #B5DEFA",
-"2q c #B4DDF9",
-"2r c #B4DBFC",
-"2s c #AED5F2",
-"2t c #AAD1EE",
-"2u c #A8CDE8",
-"2v c #A4C9E4",
-"2w c #9BB4DD",
-"2x c #849DC6",
-"2y c #8C9CD8",
-"2z c #93A3DF",
-"2A c #8497BF",
-"2B c #6679A1",
-"2C c #5C758B",
-"2D c #6F889E",
-"2E c #7C9FB5",
-"2F c #8FB2C8",
-"2G c #9ABED8",
-"2H c #A2C6E0",
-"2I c #A4C9E3",
-"2J c #A7CCE6",
-"2K c #A8D0EA",
-"2L c #A9D1EB",
-"2M c #ABD3ED",
-"2N c #ADD5EF",
-"2O c #B0D7F4",
-"2P c #B0D9F5",
-"2Q c #B2DBF7",
-"2R c #B3DAF9",
-"2S c #B7E0FE",
-"2T c #B7DEFB",
-"2U c #B6DFFF",
-"2V c #B7E0FF",
-"2W c #3D4547",
-"2X c #A5ADAF",
-"2Y c #F8F8F6",
-"2Z c #F1F1EF",
-"2& c #B8B8B8",
-"3 c #797979",
-"30 c #3E3E3E",
-"31 c #090909",
-"32 c #272F32",
-"33 c #50585B",
-"34 c #788691",
-"35 c #A8B6C1",
-"36 c #C1DCED",
-"37 c #B9DEF9",
-"38 c #B7DEFD",
-"39 c #B8E1FD",
-"3a c #B8E1FF",
-"3b c #B7E0FC",
-"3c c #B5DCFD",
-"3d c #B2D9FA",
-"3e c #A6CBE6",
-"3f c #9ABFDA",
-"3g c #859EC7",
-"3h c #8BA4CD",
-"3i c #98A8E4",
-"3j c #8191CD",
-"3k c #60739B",
-"3l c #63769E",
-"3m c #7891A7",
-"3n c #8CA5BB",
-"3o c #95B8CE",
-"3p c #9EC1D7",
-"3q c #A3C7E1",
-"3r c #A6CAE4",
-"3s c #A9CEE8",
-"3t c #AAD2EC",
-"3u c #ACD4EE",
-"3v c #B1DAF6",
-"3w c #B4DBFA",
-"3x c #B8DFFC",
-"3y c #BAE1FE",
-"3z c #464E50",
-"3A c #9EA6A8",
-"3B c #FDFDFB",
-"3C c #FCFCFA",
-"3D c #FDFDFD",
-"3E c #F9F9F9",
-"3F c #C5CDD0",
-"3G c #929A9D",
-"3H c #56646F",
-"3I c #192732",
-"3J c #052031",
-"3K c #405B6C",
-"3L c #779CB7",
-"3M c #BCE1FC",
-"3N c #B9E0FF",
-"3O c #B8DFFE",
-"3P c #BCE5FB",
-"3Q c #BCE4FD",
-"3R c #BBE5FD",
-"3S c #BEE4FB",
-"3T c #BBE4FA",
-"3U c #B9E2F8",
-"3V c #B8DEF5",
-"3W c #B5DBF2",
-"3X c #B1D5EB",
-"3Y c #ABCFE5",
-"3Z c #A4C0E7",
-"3& c #88A4CB",
-"4 c #91A4DF",
-"40 c #A1B4EF",
-"41 c #8391B6",
-"42 c #637196",
-"43 c #647F90",
-"44 c #7D98A9",
-"45 c #8FAFC4",
-"46 c #9BBBD0",
-"47 c #A1C4D8",
-"48 c #A6C9DD",
-"49 c #A8CBE1",
-"4a c #AACDE3",
-"4b c #ABD1E6",
-"4c c #ADD3E8",
-"4d c #AED3E6",
-"4e c #B0D5E8",
-"4f c #B1D5ED",
-"4g c #B2D6EE",
-"4h c #B3D7EF",
-"4i c #B5D9F1",
-"4j c #B6DCF3",
-"4k c #B8DEF3",
-"4l c #B9DFF4",
-"4m c #BBE0FA",
-"4n c #BCE1FB",
-"4o c #BAE3F9",
-"4p c #BEE3FD",
-"4q c #4B5356",
-"4r c #9DA5A8",
-"4s c #FEFFFF",
-"4t c #FDFFFE",
-"4u c #FFFFFF",
-"4v c #FEFEFE",
-"4w c #DFDFE1",
-"4x c #969698",
-"4y c #454545",
-"4z c #030303",
-"4A c #526875",
-"4B c #C8DEEB",
-"4C c #BBE3FC",
-"4D c #BEE7FD",
-"4E c #BEE6FF",
-"4F c #BDE7FF",
-"4G c #C0E6FD",
-"4H c #BAE0F7",
-"4I c #B2D6EC",
-"4J c #A9CDE3",
-"4K c #97B3DA",
-"4L c #8CA8CF",
-"4M c #AABDF8",
-"4N c #899CD7",
-"4O c #627095",
-"4P c #6A789D",
-"4Q c #93AEBF",
-"4R c #A1C1D6",
-"4S c #A3C6DA",
-"4T c #A7CAE0",
-"4U c #A9CCE2",
-"4V c #A8CCE2",
-"4W c #A9CFE4",
-"4X c #AAD0E5",
-"4Y c #ACD1E4",
-"4Z c #AED2EA",
-"4& c #ADD1E9",
-"5 c #AFD3EB",
-"50 c #B3D9F0",
-"51 c #B4DAF1",
-"52 c #B5DBF0",
-"53 c #BFE5FC",
-"54 c #BDE6FC",
-"55 c #C0E5FF",
-"56 c #495154",
-"57 c #9EA6A9",
-"58 c #FCFEFD",
-"59 c #FEFEFF",
-"5a c #E7E7E7",
-"5b c #182E3B",
-"5c c #8197A4",
-"5d c #BDE5FE",
-"5e c #C2E8FD",
-"5f c #C3E7FF",
-"5g c #C3E9FE",
-"5h c #C2E6FE",
-"5i c #C1E5FB",
-"5j c #BEE2F8",
-"5k c #BCDFF5",
-"5l c #B7DAF0",
-"5m c #B4D4EB",
-"5n c #A6C6DD",
-"5o c #90A5DE",
-"5p c #A5BAF3",
-"5q c #A4B6E4",
-"5r c #6577A5",
-"5s c #647786",
-"5t c #8093A2",
-"5u c #8DAABA",
-"5v c #9CB9C9",
-"5w c #9FBED0",
-"5x c #A2C1D3",
-"5y c #A5C6D9",
-"5z c #A6C7DA",
-"5A c #A9CADD",
-"5B c #A8C9DC",
-"5C c #AAC9DE",
-"5D c #ABCADF",
-"5E c #AEC7E6",
-"5F c #ADC8E6",
-"5G c #AEC9E7",
-"5H c #ADCCE0",
-"5I c #B0CFE3",
-"5J c #B2D2E7",
-"5K c #B6D6EB",
-"5L c #B5DAEC",
-"5M c #B8DDEF",
-"5N c #B9DDF3",
-"5O c #BCE0F6",
-"5P c #C1E5FD",
-"5Q c #C2E8FB",
-"5R c #C1E7FC",
-"5S c #C4E8FF",
-"5T c #454A4E",
-"5U c #A9AEB2",
-"5V c #E9E9E9",
-"5W c #000D1A",
-"5X c #C4DAE7",
-"5Y c #C4E6FF",
-"5Z c #C3E5FE",
-"5& c #C0E4FC",
-"6 c #BFE3F9",
-"60 c #BADDF3",
-"61 c #B5D8EE",
-"62 c #B1D1E8",
-"63 c #96B6CD",
-"64 c #94A9E2",
-"65 c #BDD2FF",
-"66 c #8092C0",
-"67 c #5E709E",
-"68 c #728594",
-"69 c #8C9FAE",
-"6a c #92AFBF",
-"6b c #99B6C6",
-"6c c #9AB9CB",
-"6d c #9CBBCD",
-"6e c #9EBFD2",
-"6f c #9FC0D3",
-"6g c #9DBED1",
-"6h c #96B5CA",
-"6i c #89A8BD",
-"6j c #7891B0",
-"6k c #6E87A6",
-"6l c #6E89A7",
-"6m c #809BB9",
-"6n c #94B3C7",
-"6o c #A3C2D6",
-"6p c #A8C8DD",
-"6q c #ADCDE2",
-"6r c #AED3E5",
-"6s c #B1D6E8",
-"6t c #B4D8EE",
-"6u c #B7DBF1",
-"6v c #BADEF4",
-"6w c #BEE2FA",
-"6x c #C0E6FB",
-"6y c #C1E7FA",
-"6z c #C2E6FF",
-"6A c #393E42",
-"6B c #B6BBBF",
-"6C c #8D8D8D",
-"6D c #415764",
-"6E c #CDE3F0",
-"6F c #C2E4FD",
-"6G c #BCE6FE",
-"6H c #BCE2F9",
-"6I c #B9DFF6",
-"6J c #B7DBF3",
-"6K c #AFCDF3",
-"6L c #91AFD5",
-"6M c #A9BEEB",
-"6N c #BED3FF",
-"6O c #687B9C",
-"6P c #627596",
-"6Q c #7792A5",
-"6R c #8AA5B8",
-"6S c #90ADBF",
-"6T c #93B0C2",
-"6U c #96B3C5",
-"6V c #98B5C7",
-"6W c #98B7CB",
-"6X c #97B6CA",
-"6Y c #98B0D2",
-"6Z c #93ABCD",
-"6& c #8A9FD6",
-"7 c #768BC2",
-"70 c #6E7CBD",
-"71 c #6F7DBE",
-"72 c #6E7BAF",
-"73 c #6D77B2",
-"74 c #6B75B0",
-"75 c #6D7FAF",
-"76 c #8496C6",
-"77 c #9BBACF",
-"78 c #A4C3D8",
-"79 c #A6CBDE",
-"7a c #ABD0E3",
-"7b c #AED2E8",
-"7c c #B7DDF4",
-"7d c #BDE2FC",
-"7e c #BCE5F9",
-"7f c #BDE6FA",
-"7g c #BEE7FB",
-"7h c #BFE7FF",
-"7i c #292D2E",
-"7j c #CBCFD0",
-"7k c #FDFEFF",
-"7l c #2B2C2E",
-"7m c #82A8BD",
-"7n c #B9E3FB",
-"7o c #B8E2FA",
-"7p c #B4D8F0",
-"7q c #AAC8EE",
-"7r c #86A4CA",
-"7s c #ABC0ED",
-"7t c #677A9B",
-"7u c #657899",
-"7v c #7994A7",
-"7w c #87A2B5",
-"7x c #8AA7B9",
-"7y c #8CA9BB",
-"7z c #8EABBD",
-"7A c #8DAABC",
-"7B c #88A7BB",
-"7C c #87A6BA",
-"7D c #8098BA",
-"7E c #7189AB",
-"7F c #6D82B9",
-"7G c #6F84BB",
-"7H c #7785C6",
-"7I c #8A98D9",
-"7J c #ADBAEE",
-"7K c #C4D1FF",
-"7L c #B6C0FB",
-"7M c #838DC8",
-"7N c #6779A9",
-"7O c #6678A8",
-"7P c #7493A8",
-"7Q c #91B0C5",
-"7R c #9CC1D4",
-"7S c #A1C6D9",
-"7T c #A6CAE0",
-"7U c #ACD0E6",
-"7V c #AFD5EC",
-"7W c #B7DCF6",
-"7X c #B9DEF8",
-"7Y c #B9E2F6",
-"7Z c #BAE3F7",
-"7& c #BBE4F8",
-"8 c #111516",
-"80 c #E4E8E9",
-"81 c #C9CACC",
-"82 c #202123",
-"83 c #BEE4F9",
-"84 c #BAE4FD",
-"85 c #BAE3FF",
-"86 c #B8E4FD",
-"87 c #B9E3FC",
-"88 c #B8E2FB",
-"89 c #B4DCF6",
-"8a c #B1D9F3",
-"8b c #AED3ED",
-"8c c #A4C6E2",
-"8d c #85A7C3",
-"8e c #A0B4E9",
-"8f c #C1D5FF",
-"8g c #8594CB",
-"8h c #5D6CA3",
-"8i c #6779A1",
-"8j c #7385AD",
-"8k c #7990AF",
-"8l c #8097B6",
-"8m c #7D92BD",
-"8n c #798BCB",
-"8o c #7183C3",
-"8p c #7584BD",
-"8q c #7D8CC5",
-"8r c #909DBD",
-"8s c #B0BDDD",
-"8t c #D4E0EE",
-"8u c #E9F5FF",
-"8v c #EDF8FE",
-"8w c #EEF9FF",
-"8x c #EFF7FF",
-"8y c #D9E1EC",
-"8z c #939FC9",
-"8A c #6372AB",
-"8B c #7483BC",
-"8C c #8DACC1",
-"8D c #9AB9CE",
-"8E c #A0C2DB",
-"8F c #A7C9E2",
-"8G c #A9CFE6",
-"8H c #AED4EB",
-"8I c #B1D9F2",
-"8J c #B3DBF4",
-"8K c #B5DFF8",
-"8L c #B7E1FA",
-"8M c #B9E2FE",
-"8N c #BAE4FC",
-"8O c #5B6972",
-"8P c #64727B",
-"8Q c #BBE5FE",
-"8R c #BBE3FD",
-"8S c #BBE4FF",
-"8T c #B7E3FC",
-"8U c #B9E2FF",
-"8V c #B6E0F9",
-"8W c #AACFE9",
-"8X c #9FC1DD",
-"8Y c #87A9C5",
-"8Z c #8195CA",
-"8& c #A7BBF0",
-"9 c #8998CF",
-"90 c #7382B9",
-"91 c #6E80A8",
-"92 c #63759D",
-"93 c #5F7695",
-"94 c #7188A7",
-"95 c #758AB5",
-"96 c #7388B3",
-"97 c #788ACA",
-"98 c #8092D2",
-"99 c #99A8E1",
-"9a c #C2D1FF",
-"9b c #DEEBFF",
-"9c c #E4F1FF",
-"9d c #E7F3FF",
-"9e c #F0F8FF",
-"9f c #DDE9FF",
-"9g c #A2AED8",
-"9h c #6C7BB4",
-"9i c #6170A9",
-"9j c #68879C",
-"9k c #88A7BC",
-"9l c #95B7D0",
-"9m c #9EC0D9",
-"9n c #A3C9E0",
-"9o c #ACD4ED",
-"9p c #B0D8F1",
-"9q c #B2DCF5",
-"9r c #B4DEF7",
-"9s c #BAE2FB",
-"9t c #90B8D1",
-"9u c #2D2D2D",
-"9v c #F4F4F4",
-"9w c #03111A",
-"9x c #B1BFC8",
-"9y c #B9E1FB",
-"9z c #BAE2FC",
-"9A c #B5E1FC",
-"9B c #B5E1FE",
-"9C c #B4E0FD",
-"9D c #ADD4F1",
-"9E c #A9D0ED",
-"9F c #A5CAE7",
-"9G c #9FC4E1",
-"9H c #9ABCD8",
-"9I c #88AAC6",
-"9J c #7A8DD1",
-"9K c #7B8ED2",
-"9L c #8B9FD2",
-"9M c #9DB1E4",
-"9N c #97A9E7",
-"9O c #7B8DCB",
-"9P c #6B7CC1",
-"9Q c #7384C9",
-"9R c #8191C4",
-"9S c #8B9BCE",
-"9T c #ABBBD5",
-"9U c #CADAF4",
-"9V c #DBEAFF",
-"9W c #DAE9FF",
-"9X c #D2E0FF",
-"9Y c #D4E2FF",
-"9Z c #E3F0FF",
-"9& c #E8F5FF",
-"a c #EDF7FF",
-"a0 c #EDFAFF",
-"a1 c #F0F9FE",
-"a2 c #EDF6FB",
-"a3 c #A6AFD6",
-"a4 c #717AA1",
-"a5 c #5E6EA2",
-"a6 c #6B7BAF",
-"a7 c #85A5BC",
-"a8 c #98B8CF",
-"a9 c #9DC3D8",
-"aa c #A4CADF",
-"ab c #A8CFEC",
-"ac c #ACD3F0",
-"ad c #AFD8F4",
-"ae c #B4DDFB",
-"af c #B3DFFC",
-"ag c #B6E2FD",
-"ah c #BADFF9",
-"ai c #B4E0FB",
-"aj c #B5E1FA",
-"ak c #B5E0FF",
-"al c #BEDEF5",
-"am c #7090A7",
-"an c #595959",
-"ao c #9E9E9E",
-"ap c #28485D",
-"aq c #BEDEF3",
-"ar c #B6E2FF",
-"as c #B3DFFA",
-"at c #B2DEFB",
-"au c #B1DDFA",
-"av c #AED7F3",
-"aw c #AAD3EF",
-"ax c #A7CEEB",
-"ay c #A2C9E6",
-"az c #98BDDA",
-"aA c #93B5D1",
-"aB c #84A6C2",
-"aC c #8194D8",
-"aD c #95A8EC",
-"aE c #B4C8FB",
-"aF c #ABBFF2",
-"aG c #90A2E0",
-"aH c #7C8ECC",
-"aI c #7F90D5",
-"aJ c #91A2E7",
-"aK c #B0C0F3",
-"aL c #CDDDFF",
-"aM c #DEEEFF",
-"aN c #D8E8FF",
-"aO c #CDDCFD",
-"aP c #BECDEE",
-"aQ c #AFBDEC",
-"aR c #A9B7E6",
-"aS c #CFDCED",
-"aT c #ECF6FF",
-"aU c #E7F1FA",
-"aV c #E2EFF7",
-"aW c #ECF5FA",
-"aX c #F1FAFF",
-"aY c #EAF3FF",
-"aZ c #6777AB",
-"a& c #5D6DA1",
-"b c #608097",
-"b0 c #82A2B9",
-"b1 c #92B8CD",
-"b2 c #A1C8E5",
-"b3 c #A6CDEA",
-"b4 c #A9D2EE",
-"b5 c #AFD8F6",
-"b6 c #B0D9F7",
-"b7 c #ABD7F2",
-"b8 c #83A8C2",
-"b9 c #90B5CF",
-"ba c #B4E0F9",
-"bb c #B4DFFF",
-"bc c #45657C",
-"bd c #8A8A8A",
-"be c #3A3A3A",
-"bf c #7595AA",
-"bg c #BDDDF2",
-"bh c #B1E0FE",
-"bi c #B2DFFE",
-"bj c #B1DEFD",
-"bk c #B0DDFC",
-"bl c #AFDCFB",
-"bm c #ADDAF9",
-"bn c #ABD8F5",
-"bo c #AAD7F4",
-"bp c #A8D4F1",
-"bq c #A3CFEC",
-"br c #A2CAE4",
-"bs c #9CC4DE",
-"bt c #99BED8",
-"bu c #91B6D0",
-"bv c #8FACD8",
-"bw c #7F9CC8",
-"bx c #8599DE",
-"by c #9BAFF4",
-"bz c #8FA2E4",
-"bA c #7E91D3",
-"bB c #8698C8",
-"bC c #99ABDB",
-"bD c #B4C4DD",
-"bE c #D0E0F9",
-"bF c #DEEEFD",
-"bG c #DFEFFE",
-"bH c #DEEFFF",
-"bI c #C5D6F4",
-"bJ c #B5B6FF",
-"bK c #9E9FFF",
-"bL c #7F83FE",
-"bM c #7C80FB",
-"bN c #BFCDE8",
-"bO c #E2F0FF",
-"bP c #C9F5E6",
-"bQ c #BBE7D8",
-"bR c #98EAA8",
-"bS c #8DDF9D",
-"bT c #C4E4D9",
-"bU c #E0FFF5",
-"bV c #F3FBFE",
-"bW c #EFF7FA",
-"bX c #A5ADD1",
-"bY c #6E769A",
-"bZ c #5D6B9C",
-"b& c #6B79AA",
-"c c #83A7BD",
-"c0 c #96BAD0",
-"c1 c #9BC2DF",
-"c2 c #A3CFEA",
-"c3 c #A6D2ED",
-"c4 c #AAD6F3",
-"c5 c #ACD8F5",
-"c6 c #AEDBFC",
-"c7 c #B0DDFE",
-"c8 c #BDDCF1",
-"c9 c #C4DAE8",
-"ca c #9CB2C0",
-"cb c #7A848E",
-"cc c #4F5963",
-"cd c #25292A",
-"ce c #080C0D",
-"cf c #343537",
-"cg c #000103",
-"ch c #B2DFFF",
-"ci c #B9DDF7",
-"cj c #B6DDFA",
-"ck c #B0DFFD",
-"cl c #B2DFFC",
-"cm c #B3DEFE",
-"cn c #B1E0FC",
-"co c #C1DBEC",
-"cp c #1C3647",
-"cq c #C2C2C2",
-"cr c #CBD0D6",
-"cs c #000208",
-"ct c #B9DDF5",
-"cu c #C5DBE9",
-"cv c #9AB0BE",
-"cw c #6F7A80",
-"cx c #49545A",
-"cy c #383D41",
-"cz c #34393D",
-"cA c #3E474E",
-"cB c #5B646B",
-"cC c #889EAC",
-"cD c #C0DBEE",
-"cE c #BFDAED",
-"cF c #86A0B1",
-"cG c #A1B3C1",
-"cH c #9FB1BF",
-"cI c #BBD2E0",
-"cJ c #C3DAE8",
-"cK c #C0DCEA",
-"cL c #C1DDEB",
-"cM c #B1DFFF",
-"cN c #AFDEFC",
-"cO c #ACD9F8",
-"cP c #AAD7F6",
-"cQ c #A7D4F1",
-"cR c #A5D2EF",
-"cS c #A1CDEA",
-"cT c #9ECAE7",
-"cU c #9BC3DD",
-"cV c #95BDD7",
-"cW c #92B7D1",
-"cX c #8BB0CA",
-"cY c #7794C0",
-"cZ c #7D9AC6",
-"c& c #7E92D7",
-"d c #8497D9",
-"d0 c #9AADEF",
-"d1 c #B5C7F7",
-"d2 c #CEE0FF",
-"d3 c #DDEDFF",
-"d4 c #DBECFF",
-"d5 c #C1D2F0",
-"d6 c #898AF4",
-"d7 c #7273DD",
-"d8 c #696DE8",
-"d9 c #9498FF",
-"da c #D7E5FF",
-"db c #D9E7FF",
-"dc c #B1DDCE",
-"dd c #9FCBBC",
-"de c #73C583",
-"df c #59AB69",
-"dg c #A7C7BC",
-"dh c #DDFDF2",
-"di c #F4FCFF",
-"dj c #E8F0FF",
-"dk c #A6AED2",
-"dl c #6270A1",
-"dm c #5A6899",
-"dn c #5E8298",
-"do c #89ADC3",
-"dp c #93BAD7",
-"dq c #9ECAE5",
-"dr c #A2CEE9",
-"ds c #A7D3F0",
-"dt c #ACD9FA",
-"du c #8CB8D5",
-"dv c #58778C",
-"dw c #214055",
-"dx c #000816",
-"dy c #1F3543",
-"dz c #5C6670",
-"dA c #929CA6",
-"dB c #CED2D3",
-"dC c #F8FCFD",
-"dD c #B8B9BB",
-"dE c #333436",
-"dF c #B1DEFF",
-"dG c #A6D3F4",
-"dH c #7A9EB8",
-"dI c #557993",
-"dJ c #44677D",
-"dK c #4A6D83",
-"dL c #678EAB",
-"dM c #B1DEFB",
-"dN c #B2DDFD",
-"dO c #AFDEFA",
-"dP c #B0DFFB",
-"dQ c #B5CFE0",
-"dR c #000F20",
-"dS c #F8F8F8",
-"dT c #5D6268",
-"dU c #666B71",
-"dV c #84A8C0",
-"dW c #3F637B",
-"dX c #091F2D",
-"dY c #1C3240",
-"dZ c #667177",
-"d& c #98A3A9",
-"e c #B8BDC1",
-"e0 c #BBC0C4",
-"e1 c #AAB3BA",
-"e2 c #7E878E",
-"e3 c #263C4A",
-"e4 c #192F3D",
-"e5 c #7AA6C1",
-"e6 c #B2DEF9",
-"e7 c #7FAACA",
-"e8 c #425D70",
-"e9 c #000A1D",
-"ea c #062031",
-"eb c #5A7485",
-"ec c #90BDDC",
-"ed c #000B19",
-"ee c #0C1E2C",
-"ef c #001422",
-"eg c #000917",
-"eh c #001220",
-"ei c #031F2D",
-"ej c #719DB8",
-"ek c #B0DEFF",
-"el c #AFDDFE",
-"em c #AEDCFD",
-"en c #AEDCFF",
-"eo c #AEDCFE",
-"ep c #ACDDFD",
-"eq c #ABDCFC",
-"er c #ACDAFC",
-"es c #AAD8F9",
-"et c #A8D6F7",
-"eu c #A8D5F6",
-"ev c #A5D2F3",
-"ew c #A2CFEE",
-"ex c #9FCCEB",
-"ey c #9FC8E6",
-"ez c #99C2E0",
-"eA c #96BBD8",
-"eB c #90B5D2",
-"eC c #839ECB",
-"eD c #6984B1",
-"eE c #798ED1",
-"eF c #7C91D4",
-"eG c #8698CA",
-"eH c #9EB0E2",
-"eI c #B9CAE4",
-"eJ c #CFE0FA",
-"eK c #DAEBFD",
-"eL c #DBECFE",
-"eM c #E0F0FF",
-"eN c #E1F1FF",
-"eO c #E2EEFF",
-"eP c #D7E3F9",
-"eQ c #AFB6ED",
-"eR c #9EA5DC",
-"eS c #B6BFDC",
-"eT c #D7E0FD",
-"eU c #E3F6FD",
-"eV c #CEE1E8",
-"eW c #88DA92",
-"eX c #69BB73",
-"eY c #43A945",
-"eZ c #44AA46",
-"e& c #BCD4C7",
-"f c #E7FFF2",
-"f0 c #F6FBFF",
-"f1 c #F7FCFF",
-"f2 c #E9EEF2",
-"f3 c #9AA1CD",
-"f4 c #646B97",
-"f5 c #546590",
-"f6 c #7182AD",
-"f7 c #8AAFCA",
-"f8 c #94B9D4",
-"f9 c #97C3E0",
-"fa c #A1CEEF",
-"fb c #A7D5F6",
-"fc c #A9D7F8",
-"fd c #ADDBFD",
-"fe c #ADDBFC",
-"ff c #C3D6E5",
-"fg c #6F8291",
-"fh c #2A2E31",
-"fi c #1D2124",
-"fj c #707070",
-"fk c #B6B6B6",
-"fl c #F0F0F0",
-"fm c #FCFCFC",
-"fn c #FBFDFC",
-"fo c #FAFCFB",
-"fp c #FBFBFD",
-"fq c #72797F",
-"fr c #5E656B",
-"fs c #3D4144",
-"ft c #060A0D",
-"fu c #474747",
-"fv c #747474",
-"fw c #858585",
-"fx c #535353",
-"fy c #050505",
-"fz c #59707E",
-"fA c #C0D7E5",
-"fB c #AFDBFE",
-"fC c #85939C",
-"fD c #3A4851",
-"fE c #FBFBFB",
-"fF c #FBFCFE",
-"fG c #FCFDFF",
-"fH c #FCFCFE",
-"fI c #E1E1E1",
-"fJ c #000C1E",
-"fK c #AAC7D9",
-"fL c #B6DAF4",
-"fM c #B5D9F3",
-"fN c #848E98",
-"fO c #2B353F",
-"fP c #252525",
-"fQ c #868686",
-"fR c #DADCDB",
-"fS c #AFAFAF",
-"fT c #071017",
-"fU c #868F96",
-"fV c #AFDCFD",
-"fW c #ACDDFE",
-"fX c #B3DAF7",
-"fY c #B4DBF8",
-"fZ c #B1C3CF",
-"f& c #647682",
-"g c #262729",
-"g0 c #2A2B2D",
-"g1 c #898B8A",
-"g2 c #E4E6E5",
-"g3 c #7A848D",
-"g4 c #5B656E",
-"g5 c #C3D6E4",
-"g6 c #263947",
-"g7 c #919191",
-"g8 c #EBEFF2",
-"g9 c #262A2D",
-"ga c #5C83A2",
-"gb c #ACDAFB",
-"gc c #ACDAFE",
-"gd c #A9DAFA",
-"ge c #A8D9F9",
-"gf c #A8D6F8",
-"gg c #A7D5F7",
-"gh c #A6D4F5",
-"gi c #A3D1F2",
-"gj c #A2CFF0",
-"gk c #9FCCED",
-"gl c #9BC8E7",
-"gm c #97C4E3",
-"gn c #96BFDD",
-"go c #90B9D7",
-"gp c #89AECB",
-"gq c #6D92AF",
-"gr c #7691BE",
-"gs c #7B96C3",
-"gt c #7E93D6",
-"gu c #94A9EC",
-"gv c #B7C9FB",
-"gw c #CADCFF",
-"gx c #D7E8FF",
-"gy c #D9EAFF",
-"gz c #DCEDFF",
-"gA c #DFEFFF",
-"gB c #D9E9F9",
-"gC c #D6E2F8",
-"gD c #DBE2FF",
-"gE c #DDE4FF",
-"gF c #EBF4FF",
-"gG c #E9F2FF",
-"gH c #E4F7FE",
-"gI c #D8EBF2",
-"gJ c #95E79F",
-"gK c #74C67E",
-"gL c #67CD69",
-"gM c #87ED89",
-"gN c #E0F8EB",
-"gO c #EBFFF6",
-"gP c #F8FDFF",
-"gQ c #D7DEFF",
-"gR c #8990BC",
-"gS c #586994",
-"gT c #7196B1",
-"gU c #8CB1CC",
-"gV c #91BDDA",
-"gW c #9CC9EA",
-"gX c #A4D2F3",
-"gY c #A9D7F9",
-"gZ c #AAD8FA",
-"g& c #ABD9FA",
-"h c #A1CFF0",
-"h0 c #132635",
-"h1 c #3B4E5D",
-"h2 c #B9BDC0",
-"h3 c #F6FAFD",
-"h4 c #F8FAF9",
-"h5 c #F9FBFA",
-"h6 c #F9F9FB",
-"h7 c #343B41",
-"h8 c #3B4248",
-"h9 c #A3A7AA",
-"ha c #EEF2F5",
-"hb c #FAFAFA",
-"hc c #DBDBDB",
-"hd c #324957",
-"he c #ADD9FC",
-"hf c #4F5D66",
-"hg c #829099",
-"hh c #F9FAFC",
-"hi c #FAFAFC",
-"hj c #6C6C6C",
-"hk c #436072",
-"hl c #BAD7E9",
-"hm c #84A8C2",
-"hn c #1B3F59",
-"ho c #A8B2BC",
-"hp c #BBC4CB",
-"hq c #000910",
-"hr c #8CB9DA",
-"hs c #ADDAFB",
-"ht c #AADBFC",
-"hu c #A9DAFB",
-"hv c #8CB3D0",
-"hw c #5E85A2",
-"hx c #00111D",
-"hy c #576975",
-"hz c #C4C5C7",
-"hA c #828C95",
-"hB c #545E67",
-"hC c #536674",
-"hD c #415462",
-"hE c #606467",
-"hF c #44484B",
-"hG c #B1D8F7",
-"hH c #AADBFB",
-"hI c #A8DAFD",
-"hJ c #A9D9FF",
-"hK c #A8DAFF",
-"hL c #A7D7FB",
-"hM c #A5D5F9",
-"hN c #A4D2F6",
-"hO c #A2D0F2",
-"hP c #9FCDEF",
-"hQ c #99C6E7",
-"hR c #98C1DF",
-"hS c #93BCDA",
-"hT c #90AFDD",
-"hU c #7B9AC8",
-"hV c #788DCE",
-"hW c #7F94D5",
-"hX c #8295CD",
-"hY c #96A9E1",
-"hZ c #B2C7E6",
-"h& c #C5DAF9",
-"i c #D7E9FF",
-"i0 c #D8EAFF",
-"i1 c #DBEBFB",
-"i2 c #DDEDFD",
-"i3 c #DDEEFF",
-"i4 c #DDF0FF",
-"i5 c #F2DAD6",
-"i6 c #E9D1CD",
-"i7 c #FFB781",
-"i8 c #FFAA74",
-"i9 c #D9AB94",
-"ia c #FFE1CA",
-"ib c #E5F5FF",
-"ic c #E5E8DD",
-"id c #E2E5DA",
-"ie c #D5E5D8",
-"if c #D4E4D7",
-"ig c #DCEAEA",
-"ih c #EAF8F8",
-"ii c #FAFFFF",
-"ij c #F7FAFF",
-"ik c #CCCFD8",
-"il c #727CAF",
-"im c #586295",
-"in c #5C7496",
-"io c #839BBD",
-"ip c #8BB4D2",
-"iq c #94BDDB",
-"ir c #A3CFF2",
-"is c #A5D1F4",
-"it c #A7D9FC",
-"iu c #A9DBFE",
-"iv c #A9D9FD",
-"iw c #8FBFE3",
-"ix c #1A1A1A",
-"iy c #F7F8FA",
-"iz c #F6F8F7",
-"iA c #F7F9F8",
-"iB c #F7F7F7",
-"iC c #CDCDCD",
-"iD c #E1E6E9",
-"iE c #84898C",
-"iF c #304352",
-"iG c #112433",
-"iH c #26353C",
-"iI c #85949B",
-"iJ c #F5F5F5",
-"iK c #F6F6F6",
-"iL c #F3F3F3",
-"iM c #545454",
-"iN c #3B5669",
-"iO c #BAD5E8",
-"iP c #AADAFF",
-"iQ c #ACD7F7",
-"iR c #A6D1F1",
-"iS c #DDDDDD",
-"iT c #F9F7F8",
-"iU c #F8F8FA",
-"iV c #F7F7F9",
-"iW c #D8DDE1",
-"iX c #03080C",
-"iY c #91BFE1",
-"iZ c #ABD9FB",
-"i& c #BED3E4",
-"j c #526778",
-"j0 c #171717",
-"j1 c #F7F5F6",
-"j2 c #E6E6E8",
-"j3 c #8D97A0",
-"j4 c #505A63",
-"j5 c #32434D",
-"j6 c #54656F",
-"j7 c #C4C4C4",
-"j8 c #838584",
-"j9 c #304C61",
-"ja c #B8D4E9",
-"jb c #B8D7EC",
-"jc c #B7D6EB",
-"jd c #828F97",
-"je c #334048",
-"jf c #1B191A",
-"jg c #8A8889",
-"jh c #EBEBEB",
-"ji c #899299",
-"jj c #4E575E",
-"jk c #B7D5ED",
-"jl c #7391A9",
-"jm c #202020",
-"jn c #E6E6E6",
-"jo c #0A2D49",
-"jp c #AACDE9",
-"jq c #A7D9FE",
-"jr c #A6D8FD",
-"js c #A4D4F8",
-"jt c #A2D2F6",
-"ju c #A3D1F5",
-"jv c #9FCDF1",
-"jw c #9DCBED",
-"jx c #98C6E8",
-"jy c #95C2E3",
-"jz c #90BDDE",
-"jA c #8DB6D4",
-"jB c #78A1BF",
-"jC c #7897C5",
-"jD c #7D9CCA",
-"jE c #8EA3E4",
-"jF c #ADC0F8",
-"jG c #C2D5FF",
-"jH c #D1E6FF",
-"jI c #D4E9FF",
-"jJ c #DCECFC",
-"jK c #DCEFFF",
-"jL c #D7EAFB",
-"jM c #E2CAC6",
-"jN c #D0B8B4",
-"jO c #ED9660",
-"jP c #D8814B",
-"jQ c #B4866F",
-"jR c #FFE4CD",
-"jS c #DAEAF9",
-"jT c #DBEBFA",
-"jU c #E9ECE1",
-"jV c #DFE2D7",
-"jW c #E2F2E5",
-"jX c #EDFBFB",
-"jY c #EEFCFC",
-"jZ c #FBFEFF",
-"j& c #F1F4FD",
-"k c #ABB5E8",
-"k0 c #606A9D",
-"k1 c #50688A",
-"k2 c #677FA1",
-"k3 c #80A9C7",
-"k4 c #8CB5D3",
-"k5 c #93BEE1",
-"k6 c #9FCBEE",
-"k7 c #A2CEF1",
-"k8 c #A3D3F9",
-"k9 c #A6D8FB",
-"ka c #020202",
-"kb c #F1F1F1",
-"kc c #F3F4F6",
-"kd c #F3F5F4",
-"ke c #F4F6F5",
-"kf c #EFEFEF",
-"kg c #0A0F12",
-"kh c #474C4F",
-"ki c #7E91A0",
-"kj c #A3B6C5",
-"kk c #8A99A0",
-"kl c #29383F",
-"km c #575757",
-"kn c #F2F2F2",
-"ko c #E8E8E8",
-"kp c #062134",
-"kq c #86A1B4",
-"kr c #507B9B",
-"ks c #F5F3F4",
-"kt c #F3F3F5",
-"ku c #F4F4F6",
-"kv c #595E62",
-"kw c #5A5F63",
-"kx c #A1CFF1",
-"ky c #2C4152",
-"kz c #394E5F",
-"kA c #F4F2F3",
-"kB c #727274",
-"kC c #0A0A0C",
-"kD c #3D4750",
-"kE c #757F88",
-"kF c #8899A3",
-"kG c #61727C",
-"kH c #000000",
-"kI c #989898",
-"kJ c #F2F4F3",
-"kK c #E7E9E8",
-"kL c #001227",
-"kM c #A3BFD4",
-"kN c #A8D8FC",
-"kO c #98C8EC",
-"kP c #57768B",
-"kQ c #00081D",
-"kR c #323F47",
-"kS c #98A5AD",
-"kT c #F0EEEF",
-"kU c #9099A0",
-"kV c #475057",
-"kW c #9BB9D1",
-"kX c #000A22",
-"kY c #BEBEBE",
-"kZ c #AAAAAA",
-"k& c #8EB1CD",
-"l c #B2D5F1",
-"l0 c #A8D8FF",
-"l1 c #A3D7FC",
-"l2 c #A5D6FE",
-"l3 c #A2D6FB",
-"l4 c #A3D4FC",
-"l5 c #A2D3FB",
-"l6 c #A0D2F7",
-"l7 c #9FD1F6",
-"l8 c #9DCDF3",
-"l9 c #99C9EF",
-"la c #97C5E7",
-"lb c #92C0E2",
-"lc c #91B7DC",
-"ld c #85ABD0",
-"le c #7B94D4",
-"lf c #738CCC",
-"lg c #8196D7",
-"lh c #889DDE",
-"li c #A3BAE4",
-"lj c #BBD2FC",
-"lk c #CEE2FD",
-"ll c #D0E4FF",
-"lm c #D1E3F9",
-"ln c #D3E5FB",
-"lo c #D6E8FF",
-"lp c #D9EBFF",
-"lq c #DBEDFF",
-"lr c #D7E8FA",
-"ls c #F5AD87",
-"lt c #D18963",
-"lu c #DE7130",
-"lv c #D86B2A",
-"lw c #C8BBB5",
-"lx c #F8EBE5",
-"ly c #EFE5A8",
-"lz c #F6ECAF",
-"lA c #FFE545",
-"lB c #FFD939",
-"lC c #E4D793",
-"lD c #FBEEAA",
-"lE c #F1F9FC",
-"lF c #F9FFFF",
-"lG c #FBFFFF",
-"lH c #E1E6F9",
-"lI c #959AAD",
-"lJ c #576397",
-"lK c #596599",
-"lL c #6F92AE",
-"lM c #89ACC8",
-"lN c #8DB9DC",
-"lO c #93BFE2",
-"lP c #9CCCF0",
-"lQ c #A0D1F9",
-"lR c #A1D5FA",
-"lS c #A3D7FE",
-"lT c #A4D8FD",
-"lU c #0E1215",
-"lV c #D6DADD",
-"lW c #F2F2F4",
-"lX c #E0E0E0",
-"lY c #243B4D",
-"lZ c #283F51",
-"l& c #80B0D4",
-"m c #A6D6FA",
-"m0 c #A4D5FD",
-"m1 c #25323B",
-"m2 c #86939C",
-"m3 c #7B8489",
-"m4 c #4A5358",
-"m5 c #A2D8FC",
-"m6 c #A5D6FF",
-"m7 c #BED1DF",
-"m8 c #000513",
-"m9 c #C5C7C6",
-"ma c #F1F3F2",
-"mb c #C5C5C5",
-"mc c #000821",
-"md c #A5C5DE",
-"me c #B4C7D5",
-"mf c #213442",
-"mg c #F0F2F1",
-"mh c #F1F1F3",
-"mi c #BDC4CA",
-"mj c #1C2329",
-"mk c #2B5472",
-"ml c #8EB7D5",
-"mm c #8EA8BF",
-"mn c #000F26",
-"mo c #E0DEDF",
-"mp c #F2F0F1",
-"mq c #404D56",
-"mr c #7A8790",
-"ms c #5E6367",
-"mt c #050A0E",
-"mu c #5F5F5F",
-"mv c #C6C6C6",
-"mw c #959EA5",
-"mx c #404950",
-"my c #A9D6F7",
-"mz c #AAD7F8",
-"mA c #383C3F",
-"mB c #7F8386",
-"mC c #BDBFBE",
-"mD c #001026",
-"mE c #7D99AF",
-"mF c #A0D4F9",
-"mG c #A1D2FA",
-"mH c #9FD0F8",
-"mI c #9ED0F5",
-"mJ c #9BCDF2",
-"mK c #95C5EB",
-"mL c #8BB9DB",
-"mM c #7CA2C7",
-"mN c #749ABF",
-"mO c #829BDB",
-"mP c #819ADA",
-"mQ c #96ABEC",
-"mR c #B7CCFF",
-"mS c #C3DAFF",
-"mT c #B4CBF5",
-"mU c #99ADC8",
-"mV c #8397B2",
-"mW c #788AA0",
-"mX c #8597AD",
-"mY c #99ABC3",
-"mZ c #C5D7EF",
-"m& c #D7E9FD",
-"n c #FFCEA8",
-"n0 c #F6AE88",
-"n1 c #FFA362",
-"n2 c #FFBF7E",
-"n3 c #F7EAE4",
-"n4 c #F5E8E2",
-"n5 c #EDE3A6",
-"n6 c #E5DB9E",
-"n7 c #FAD030",
-"n8 c #F6CC2C",
-"n9 c #EEE19D",
-"na c #FFFAB6",
-"nb c #F2FAFD",
-"nc c #C3C8DB",
-"nd c #6C78AC",
-"ne c #527591",
-"nf c #7B9EBA",
-"ng c #86B2D5",
-"nh c #8FBBDE",
-"ni c #94C4E8",
-"nj c #99C9ED",
-"nk c #9ECFF7",
-"nl c #A2D6FD",
-"nm c #222629",
-"nn c #BDC1C4",
-"no c #EFEFF1",
-"np c #EEEEEE",
-"nq c #515151",
-"nr c #566D7F",
-"ns c #B9D0E2",
-"nt c #95A2AB",
-"nu c #26333C",
-"nv c #EDEDED",
-"nw c #BEC7CC",
-"nx c #161F24",
-"ny c #A1D7FB",
-"nz c #A3D4FD",
-"nA c #A4D5FE",
-"nB c #647785",
-"nC c #3E515F",
-"nD c #EEF0EF",
-"nE c #EDEFEE",
-"nF c #F0F0F2",
-"nG c #5A7A93",
-"nH c #B1D1EA",
-"nI c #2B3E4C",
-"nJ c #5B6E7C",
-"nK c #A8A8AA",
-"nL c #030A10",
-"nM c #757C82",
-"nN c #ABD4F2",
-"nO c #B5CFE6",
-"nP c #2F4960",
-"nQ c #9A9899",
-"nR c #EFEDEE",
-"nS c #6B7881",
-"nT c #48555E",
-"nU c #3A3F43",
-"nV c #DBE0E4",
-"nW c #EEEEF0",
-"nX c #9BA4AB",
-"nY c #3A434A",
-"nZ c #426F90",
-"n& c #414548",
-"o c #E8ECEF",
-"o0 c #CDCFCE",
-"o1 c #131514",
-"o2 c #6B879D",
-"o3 c #B5D1E7",
-"o4 c #9FD4FC",
-"o5 c #9FD4FE",
-"o6 c #9ED3FD",
-"o7 c #9FD3FB",
-"o8 c #9ED2FA",
-"o9 c #9CD0F8",
-"oa c #9BCFF7",
-"ob c #9BCCF4",
-"oc c #97C8F0",
-"od c #8FBFE5",
-"oe c #8EB4E5",
-"of c #81A7D8",
-"og c #7D91DA",
-"oh c #8599E2",
-"oi c #8EA5D7",
-"oj c #ABC2F4",
-"ok c #C5D9F4",
-"ol c #AFC3DE",
-"om c #8B9096",
-"on c #858A90",
-"oo c #A8A7AC",
-"op c #B7B6BB",
-"oq c #C3C5C4",
-"or c #A3A5A4",
-"os c #8F9092",
-"ot c #737476",
-"ou c #A3AFBF",
-"ov c #D7E3F3",
-"ow c #DDECFF",
-"ox c #DEEDFF",
-"oy c #E3EFFD",
-"oz c #E1EDFB",
-"oA c #E3EDF7",
-"oB c #E7F1FB",
-"oC c #E6F2FE",
-"oD c #E9EBD6",
-"oE c #E0E2CD",
-"oF c #E8E0B9",
-"oG c #F4ECC5",
-"oH c #EFF7F9",
-"oI c #F2FAFC",
-"oJ c #F3FAFF",
-"oK c #F9FEFF",
-"oL c #FAFEFD",
-"oM c #FBFFFE",
-"oN c #F2F3F5",
-"oO c #A3A7D4",
-"oP c #626693",
-"oQ c #51678E",
-"oR c #6C82A9",
-"oS c #7EA9CB",
-"oT c #8BB6D8",
-"oU c #90C0E6",
-"oV c #98CCF4",
-"oW c #9ACEF6",
-"oX c #9DD1F9",
-"oY c #A0D3FE",
-"oZ c #9FD2FD",
-"o& c #303B41",
-"p c #A0ABB1",
-"p0 c #EAEAEA",
-"p1 c #A9B2B7",
-"p2 c #000308",
-"p3 c #9ED3FB",
-"p4 c #9FD5FB",
-"p5 c #99AEBF",
-"p6 c #132839",
-"p7 c #E7E5E6",
-"p8 c #040203",
-"p9 c #A0D4FC",
-"pa c #9FD2FF",
-"pb c #A5D3F5",
-"pc c #C3C3C3",
-"pd c #E9EBEA",
-"pe c #EAECEB",
-"pf c #EBEBED",
-"pg c #EAEAEC",
-"ph c #87949D",
-"pi c #24313A",
-"pj c #B3CFE5",
-"pk c #476379",
-"pl c #484848",
-"pm c #A1AAB1",
-"pn c #00060D",
-"po c #6B9BC3",
-"pp c #A3D3FB",
-"pq c #AAD1F0",
-"pr c #446B8A",
-"ps c #777777",
-"pt c #76838C",
-"pu c #4C5962",
-"pv c #090E12",
-"pw c #D3D8DC",
-"px c #ECECEC",
-"py c #A1A8AE",
-"pz c #333A40",
-"pA c #858F98",
-"pB c #101A23",
-"pC c #D8D8D8",
-"pD c #D6D6D6",
-"pE c #0C273C",
-"pF c #5B768B",
-"pG c #A1D4FF",
-"pH c #9DD2FC",
-"pI c #98C9F1",
-"pJ c #94C5ED",
-"pK c #91C1E7",
-"pL c #8BBBE1",
-"pM c #83A9DA",
-"pN c #7DA3D4",
-"pO c #879BE4",
-"pP c #97ABF4",
-"pQ c #BBD2FF",
-"pR c #9BAFCA",
-"pS c #7B8FAA",
-"pT c #B1B6BC",
-"pU c #C3C8CE",
-"pV c #CCCBD0",
-"pW c #CAC9CE",
-"pX c #C1C3C2",
-"pY c #B9BBBA",
-"pZ c #AEAFB1",
-"p& c #9C9D9F",
-"q c #778393",
-"q0 c #A8B4C4",
-"q1 c #DCEBFE",
-"q2 c #E4F0FE",
-"q3 c #E5F1FF",
-"q4 c #E8F2FC",
-"q5 c #E8F4FF",
-"q6 c #F4F6E1",
-"q7 c #F6F8E3",
-"q8 c #FFF8D1",
-"q9 c #F0F8FA",
-"qa c #F1F8FE",
-"qb c #F2F9FF",
-"qc c #F5FDFF",
-"qd c #D1D5FF",
-"qe c #8084B1",
-"qf c #546A91",
-"qg c #729DBF",
-"qh c #85B0D2",
-"qi c #8CBCE2",
-"qj c #92C2E8",
-"qk c #95C9F1",
-"ql c #9ED1FC",
-"qm c #3E494F",
-"qn c #8C979D",
-"qo c #343D42",
-"qp c #737C81",
-"qq c #9ED4FA",
-"qr c #8DA2B3",
-"qs c #1F3445",
-"qt c #E8E6E7",
-"qu c #141213",
-"qv c #8BBFE7",
-"qw c #9DD2FA",
-"qx c #A4D2F4",
-"qy c #3E6C8E",
-"qz c #585858",
-"qA c #E6E8E7",
-"qB c #E7E7E9",
-"qC c #CECED0",
-"qD c #05121B",
-"qE c #8D9AA3",
-"qF c #809CB2",
-"qG c #00192F",
-"qH c #D4D4D4",
-"qI c #D2D2D2",
-"qJ c #091219",
-"qK c #879097",
-"qL c #A2D2FA",
-"qM c #A9D0EF",
-"qN c #456C8B",
-"qO c #757575",
-"qP c #65727B",
-"qQ c #58656E",
-"qR c #51565A",
-"qS c #A4ABB1",
-"qT c #2E353B",
-"qU c #8ABFE7",
-"qV c #0F1922",
-"qW c #A6B0B9",
-"qX c #313131",
-"qY c #4A657A",
-"qZ c #B3CEE3",
-"q& c #9BD1FD",
-"r c #9BD1FF",
-"r0 c #9AD0FE",
-"r1 c #99D0F9",
-"r2 c #97CEF7",
-"r3 c #97CCF8",
-"r4 c #94C9F5",
-"r5 c #91C4EF",
-"r6 c #8EC1EC",
-"r7 c #8DBDE5",
-"r8 c #86B6DE",
-"r9 c #869DE9",
-"ra c #879EEA",
-"rb c #9BB7E6",
-"rc c #BFDBFF",
-"rd c #C7DFFB",
-"re c #9CB4D0",
-"rf c #96979B",
-"rg c #CBCCD0",
-"rh c #D0D0D0",
-"ri c #BBBBBB",
-"rj c #BFBFBF",
-"rk c #B7B7B5",
-"rl c #ACACAA",
-"rm c #929292",
-"rn c #7E7E7E",
-"ro c #85868A",
-"rp c #949599",
-"rq c #D8E5F6",
-"rr c #E1EEFF",
-"rs c #E4F0FC",
-"rt c #EAF4FF",
-"ru c #E9F6FF",
-"rv c #EAF7FF",
-"rw c #EBF8FF",
-"rx c #DCF0FF",
-"ry c #D3E7FF",
-"rz c #D5E7FF",
-"rA c #E1F3FF",
-"rB c #F0FAFF",
-"rC c #F3FDFF",
-"rD c #FAFCFF",
-"rE c #B1B3BF",
-"rF c #616CA2",
-"rG c #576298",
-"rH c #6185A5",
-"rI c #81A5C5",
-"rJ c #87B8E0",
-"rK c #8DBEE6",
-"rL c #92C5F0",
-"rM c #95C8F3",
-"rN c #96CCF8",
-"rO c #98CEFA",
-"rP c #47515B",
-"rQ c #7D8791",
-"rR c #E5E5E5",
-"rS c #BDBDBD",
-"rT c #000924",
-"rU c #ABCDE8",
-"rV c #9AD0FC",
-"rW c #9CD2FE",
-"rX c #6C7680",
-"rY c #505A64",
-"rZ c #E4E4E4",
-"r& c #161616",
-"s c #84B9E3",
-"s0 c #9CD1F9",
-"s1 c #A4CFF1",
-"s2 c #ABCEEC",
-"s3 c #AACDEB",
-"s4 c #9CD1FB",
-"s5 c #9FAFBE",
-"s6 c #000C1B",
-"s7 c #CBCBCD",
-"s8 c #E5E5E7",
-"s9 c #E0E4E7",
-"sa c #3B3F42",
-"sb c #3B698D",
-"sc c #A1CFF3",
-"sd c #373B3E",
-"se c #868A8D",
-"sf c #616161",
-"sg c #346286",
-"sh c #A2D0F4",
-"si c #9CD0FF",
-"sj c #9BCFFE",
-"sk c #AECCE6",
-"sl c #2C4A64",
-"sm c #34495A",
-"sn c #6E8394",
-"so c #98BBD7",
-"sp c #000723",
-"sq c #B2B2B0",
-"sr c #E5E5E3",
-"ss c #E5E3E4",
-"st c #E6E4E5",
-"su c #AAAFB5",
-"sv c #2C3137",
-"sw c #B3CCE0",
-"sx c #2A4357",
-"sy c #E1E1E3",
-"sz c #334A5C",
-"sA c #3B5264",
-"sB c #99CFFD",
-"sC c #98CFF8",
-"sD c #95CCF5",
-"sE c #96CBF7",
-"sF c #92C7F3",
-"sG c #90C3EE",
-"sH c #8CBFEA",
-"sI c #8ABAE2",
-"sJ c #83B3DB",
-"sK c #859CE8",
-"sL c #91A8F4",
-"sM c #B3CFFE",
-"sN c #B4CCE8",
-"sO c #829AB6",
-"sP c #AFB0B4",
-"sQ c #DADBDF",
-"sR c #C8C8C8",
-"sS c #B4B4B4",
-"sT c #AAAAA8",
-"sU c #A0A09E",
-"sV c #949494",
-"sW c #838383",
-"sX c #828387",
-"sY c #9D9EA2",
-"sZ c #D5E2F3",
-"s& c #E0EDFE",
-"t c #E5F1FD",
-"t0 c #E8F5FE",
-"t1 c #E7F4FD",
-"t2 c #E0EDFD",
-"t3 c #D8E5F5",
-"t4 c #CEE2FA",
-"t5 c #CFE3FB",
-"t6 c #D3E5FD",
-"t7 c #D2E4FC",
-"t8 c #E2ECF5",
-"t9 c #EFF9FF",
-"ta c #FBFDFF",
-"tb c #E2E4F0",
-"tc c #7F8AC0",
-"td c #586399",
-"te c #4B6F8F",
-"tf c #769ABA",
-"tg c #83B4DC",
-"th c #8ABBE3",
-"ti c #8FC2ED",
-"tj c #93C6F1",
-"tk c #94CAF6",
-"tl c #98CEFC",
-"tm c #99CFFB",
-"tn c #747E88",
-"to c #E2E2E2",
-"tp c #666666",
-"tq c #41637E",
-"tr c #A9CBE6",
-"ts c #29333D",
-"tt c #96A0AA",
-"tu c #0A0A0A",
-"tv c #8CC1EB",
-"tw c #9BD0FA",
-"tx c #9BD0F8",
-"ty c #7DB2DA",
-"tz c #5C87A9",
-"tA c #356082",
-"tB c #234664",
-"tC c #315472",
-"tD c #7DB2DC",
-"tE c #9ACFF9",
-"tF c #3E4E5D",
-"tG c #647483",
-"tH c #717578",
-"tI c #303437",
-"tJ c #81AFD3",
-"tK c #0F1316",
-"tL c #D7DBDE",
-"tM c #DADADA",
-"tN c #0D0D0D",
-"tO c #88B6DA",
-"tP c #A7C5DF",
-"tQ c #000923",
-"tR c #CBCBCB",
-"tS c #000D1E",
-"tT c #9EB3C4",
-"tU c #A8CBE7",
-"tV c #5E819D",
-"tW c #20201E",
-"tX c #D5D5D3",
-"tY c #E1DFE0",
-"tZ c #272C32",
-"t& c #556E82",
-"u c #253E52",
-"u0 c #5C5C5E",
-"u1 c #294052",
-"u2 c #B2C9DB",
-"u3 c #95CFFD",
-"u4 c #95CDFE",
-"u5 c #94CCFD",
-"u6 c #92CAFB",
-"u7 c #92C8F6",
-"u8 c #8EC4F2",
-"u9 c #8DC2EE",
-"ua c #88BDE9",
-"ub c #85B6DF",
-"uc c #7FB0D9",
-"ud c #839DE8",
-"ue c #8FA9F4",
-"uf c #B0D1FA",
-"ug c #B9DAFF",
-"uh c #AEBAC8",
-"ui c #8894A2",
-"uj c #C4C4C6",
-"uk c #BBBBBD",
-"ul c #B1B1B1",
-"um c #A8A8A8",
-"un c #9E9EA0",
-"uo c #939395",
-"up c #898989",
-"uq c #808080",
-"ur c #7E7F83",
-"us c #A8A9AD",
-"ut c #DDEAFA",
-"uu c #E1EEFE",
-"uv c #E4F2FF",
-"uw c #E5F3FF",
-"ux c #E6F4FF",
-"uy c #E3F4FF",
-"uz c #E1F2FF",
-"uA c #D5EDFF",
-"uB c #CDE5FF",
-"uC c #C7E0FF",
-"uD c #C8E1FF",
-"uE c #C9E0FF",
-"uF c #C8DFFF",
-"uG c #C3D3FF",
-"uH c #B2C2F3",
-"uI c #AAB8E7",
-"uJ c #C8D6FF",
-"uK c #F4FDFF",
-"uL c #FCFFFF",
-"uM c #F9FCFF",
-"uN c #A0ABD9",
-"uO c #616C9A",
-"uP c #4E678F",
-"uQ c #6C85AD",
-"uR c #7BACD4",
-"uS c #8BC0EC",
-"uT c #8FC4F0",
-"uU c #8FC8F5",
-"uV c #91CAF7",
-"uW c #94CCFB",
-"uX c #96CEFF",
-"uY c #94CEFE",
-"uZ c #95CFFF",
-"u& c #505C68",
-"v c #6B7783",
-"v0 c #DCDCDC",
-"v1 c #DEDCDD",
-"v2 c #DADBDD",
-"v3 c #1A1B1D",
-"v4 c #72A8D6",
-"v5 c #A1CCEF",
-"v6 c #6E99BC",
-"v7 c #D9D9D9",
-"v8 c #CFD0D4",
-"v9 c #010206",
-"va c #96CEFD",
-"vb c #95CDFC",
-"vc c #AFC8DE",
-"vd c #597288",
-"ve c #1F2324",
-"vf c #171B1C",
-"vg c #4E4E4E",
-"vh c #7A7A7A",
-"vi c #969696",
-"vj c #606060",
-"vk c #0B2A46",
-"vl c #A9C8E4",
-"vm c #A5C9E9",
-"vn c #698DAD",
-"vo c #1C1C1C",
-"vp c #DCDCDE",
-"vq c #DDDDDF",
-"vr c #9D9D9D",
-"vs c #000828",
-"vt c #8AAECE",
-"vu c #A4CBEC",
-"vv c #446B8C",
-"vw c #9FA6B0",
-"vx c #2B323C",
-"vy c #97CDF9",
-"vz c #5D646A",
-"vA c #4A5157",
-"vB c #828284",
-"vC c #1B4367",
-"vD c #A3CBEF",
-"vE c #94CEFC",
-"vF c #3A5065",
-"vG c #374D62",
-"vH c #DEDEDE",
-"vI c #DBDDDC",
-"vJ c #252C32",
-"vK c #76A2C5",
-"vL c #0E0E10",
-"vM c #C3C3C5",
-"vN c #687888",
-"vO c #1B2B3B",
-"vP c #8DC5F4",
-"vQ c #98CDFF",
-"vR c #96D0FE",
-"vS c #97CFFF",
-"vT c #93CDFB",
-"vU c #93CBFC",
-"vV c #91C9FA",
-"vW c #90C8F9",
-"vX c #90C6F4",
-"vY c #8DC3F1",
-"vZ c #8ABFEB",
-"v& c #85BAE6",
-"w c #83B4DD",
-"w0 c #7CADD6",
-"w1 c #87A1EC",
-"w2 c #AFD0F9",
-"w3 c #85919F",
-"w4 c #BABABA",
-"w5 c #B4B4B6",
-"w6 c #AFAFB1",
-"w7 c #A5A5A5",
-"w8 c #9B9B9B",
-"w9 c #8F8F91",
-"wa c #7D7D7D",
-"wb c #787878",
-"wc c #8C8D91",
-"wd c #C6C7CB",
-"we c #E2F0FD",
-"wf c #D2E3F5",
-"wg c #C6DEF8",
-"wh c #C5DEFD",
-"wi c #C6DFFE",
-"wj c #BED5F7",
-"wk c #ABC2E4",
-"wl c #8C9CCD",
-"wm c #6979AA",
-"wn c #5F6D9C",
-"wo c #8492C1",
-"wp c #BFC8D7",
-"wq c #E6EFFE",
-"wr c #F7FBFC",
-"ws c #FAFEFF",
-"wt c #FAFDFF",
-"wu c #F0F3FA",
-"wv c #C3CEFC",
-"ww c #737EAC",
-"wx c #506991",
-"wy c #5A739B",
-"wz c #73A4CC",
-"wA c #85B6DE",
-"wB c #87BCE8",
-"wC c #8CC5F2",
-"wD c #91C9F8",
-"wE c #92CAF9",
-"wF c #92CCFA",
-"wG c #93CDFD",
-"wH c #4E5A66",
-"wI c #D7D7D7",
-"wJ c #D9D7D8",
-"wK c #D8D6D7",
-"wL c #AFB0B2",
-"wM c #1B1C1E",
-"wN c #96CCFA",
-"wO c #A0CBEE",
-"wP c #0C375A",
-"wQ c #8F8F8F",
-"wR c #A9AAAE",
-"wS c #232428",
-"wT c #84BCEB",
-"wU c #1E374D",
-"wV c #263F55",
-"wW c #A3A7A8",
-"wX c #D5D9DA",
-"wY c #B2B2B2",
-"wZ c #001531",
-"w& c #A8C7E3",
-"x c #94B8D8",
-"x0 c #A1A1A1",
-"x1 c #D7D7D9",
-"x2 c #D8D8DA",
-"x3 c #0C0C0C",
-"x4 c #6B8FAF",
-"x5 c #A4C8E8",
-"x6 c #A2C9EA",
-"x7 c #0A3152",
-"x8 c #A2A2A2",
-"x9 c #787F89",
-"xa c #4C535D",
-"xb c #92CCFC",
-"xc c #95CBF7",
-"xd c #6AA0CC",
-"xe c #060D13",
-"xf c #BAC1C7",
-"xg c #18181A",
-"xh c #6C94B8",
-"xi c #A0C8EC",
-"xj c #AFC5DA",
-"xk c #1C3247",
-"xl c #686868",
-"xm c #D7D9D8",
-"xn c #D6D8D7",
-"xo c #9AA1A7",
-"xp c #2B3238",
-"xq c #9ECAED",
-"xr c #083457",
-"xs c #8B8B8D",
-"xt c #8D8D8F",
-"xu c #081828",
-"xv c #99A9B9",
-"xw c #96CBFD",
-"xx c #90CDFC",
-"xy c #91CBFD",
-"xz c #90CAFC",
-"xA c #8FC9F9",
-"xB c #8DC7F7",
-"xC c #8CC4F5",
-"xD c #89C1F2",
-"xE c #87BDEB",
-"xF c #82B8E6",
-"xG c #80B1DC",
-"xH c #7AABD6",
-"xI c #8298E4",
-"xJ c #899FEB",
-"xK c #ABCBFA",
-"xL c #B6D6FF",
-"xM c #B5C5D5",
-"xN c #8696A6",
-"xO c #A0A0A0",
-"xP c #A6A6A6",
-"xQ c #999999",
-"xR c #7B797A",
-"xS c #6B696A",
-"xT c #767678",
-"xU c #878789",
-"xV c #B2BCC5",
-"xW c #E1EBF4",
-"xX c #DEEEFE",
-"xY c #DFF1FF",
-"xZ c #D2EBFF",
-"x& c #CBE4FF",
-"y c #C1DDFF",
-"y0 c #C3DDFF",
-"y1 c #BCD0FF",
-"y2 c #A8BCEF",
-"y3 c #8E9DD8",
-"y4 c #6D7CB7",
-"y5 c #5C6D99",
-"y6 c #4E5F8B",
-"y7 c #506290",
-"y8 c #596B99",
-"y9 c #717DB7",
-"ya c #A7B3ED",
-"yb c #D6E4FF",
-"yc c #E8F6FF",
-"yd c #F2FCFF",
-"ye c #F0FCFF",
-"yf c #EEFAFF",
-"yg c #E1F4FF",
-"yh c #D9ECFD",
-"yi c #D5E4FF",
-"yj c #7D8CB3",
-"yk c #556795",
-"yl c #546694",
-"ym c #6B9CC4",
-"yn c #81B2DA",
-"yo c #84BAE9",
-"yp c #89BFEE",
-"yq c #8AC2F3",
-"yr c #8EC6F7",
-"ys c #8EC8FA",
-"yt c #8FC9FB",
-"yu c #8FCCFB",
-"yv c #92CCFE",
-"yw c #8FCDFC",
-"yx c #8ECCFB",
-"yy c #49565F",
-"yz c #6E7B84",
-"yA c #D3D3D3",
-"yB c #435362",
-"yC c #93CBFA",
-"yD c #5F686D",
-"yE c #353E43",
-"yF c #6D7B88",
-"yG c #404E5B",
-"yH c #AAC6DC",
-"yI c #1B374D",
-"yJ c #646464",
-"yK c #D3D3D5",
-"yL c #A7A7A9",
-"yM c #98999D",
-"yN c #CECFD3",
-"yO c #CDD1D4",
-"yP c #4B4F52",
-"yQ c #295071",
-"yR c #A1C8E9",
-"yS c #34393C",
-"yT c #676C6F",
-"yU c #D5D3D4",
-"yV c #B9B7B8",
-"yW c #001C35",
-"yX c #9FBBD0",
-"yY c #000B20",
-"yZ c #CECECE",
-"y& c #6F7983",
-"z c #8FCCF9",
-"z0 c #90CDFA",
-"z1 c #9AACBA",
-"z2 c #8F9190",
-"z3 c #D2D4D3",
-"z4 c #526574",
-"z5 c #314453",
-"z6 c #8FCDFE",
-"z7 c #8ECCFD",
-"z8 c #7CB6E6",
-"z9 c #102131",
-"za c #647585",
-"zb c #D4D4D6",
-"zc c #D5D5D5",
-"zd c #303940",
-"ze c #585F65",
-"zf c #3C4349",
-"zg c #9AA4AD",
-"zh c #00060F",
-"zi c #659DCC",
-"zj c #92CBFF",
-"zk c #8ECBFA",
-"zl c #8BC5F5",
-"zm c #8BC3F4",
-"zn c #87BFF0",
-"zo c #84BAE8",
-"zp c #80B6E4",
-"zq c #7FB0DB",
-"zr c #78A9D4",
-"zs c #8096E2",
-"zt c #879DE9",
-"zu c #A3C3F2",
-"zv c #B4D4FF",
-"zw c #CBDBEB",
-"zx c #A1B1C1",
-"zy c #959595",
-"zz c #747273",
-"zA c #787677",
-"zB c #DEE8F1",
-"zC c #E4EEF7",
-"zD c #DAEAFA",
-"zE c #CDDFF7",
-"zF c #C1DAF9",
-"zG c #BEDAFF",
-"zH c #BAD4F7",
-"zI c #A4BEE1",
-"zJ c #8CA0D3",
-"zK c #6E82B5",
-"zL c #5D6CA7",
-"zM c #51609B",
-"zN c #445581",
-"zO c #475987",
-"zP c #4B5D8B",
-"zQ c #58649E",
-"zR c #6470AA",
-"zS c #99A7C2",
-"zT c #C5D3EE",
-"zU c #E2ECF6",
-"zV c #E1EDF9",
-"zW c #DDE9F5",
-"zX c #D6E9FA",
-"zY c #CAD9FF",
-"zZ c #7584AB",
-"z& c #536593",
-"A c #699AC2",
-"A0 c #83B9E8",
-"A1 c #87BDEC",
-"A2 c #8BC5F7",
-"A3 c #8DC7F9",
-"A4 c #8DCAF9",
-"A5 c #8DCBFA",
-"A6 c #3F4C55",
-"A7 c #75828B",
-"A8 c #CFCFCF",
-"A9 c #283847",
-"Aa c #758594",
-"Ab c #6BA3D2",
-"Ac c #060F14",
-"Ad c #B0B9BE",
-"Ae c #354350",
-"Af c #6E7C89",
-"Ag c #637F95",
-"Ah c #1A364C",
-"Ai c #979799",
-"Aj c #030305",
-"Ak c #030408",
-"Al c #03070A",
-"Am c #282C2F",
-"An c #8AB1D2",
-"Ao c #214869",
-"Ap c #4B5053",
-"Aq c #C9CED1",
-"Ar c #B7B5B6",
-"As c #4E6E87",
-"At c #A4C4DD",
-"Au c #819DB2",
-"Av c #0D293E",
-"Aw c #828C96",
-"Ax c #37414B",
-"Ay c #8ECBF8",
-"Az c #90C8F7",
-"AA c #75ADDC",
-"AB c #132533",
-"AC c #697B89",
-"AD c #969897",
-"AE c #001221",
-"AF c #98ABBA",
-"AG c #8CCAFB",
-"AH c #8DCBFC",
-"AI c #90CAFA",
-"AJ c #93A4B4",
-"AK c #6C6C6E",
-"AL c #848D94",
-"AM c #363F46",
-"AN c #0B1218",
-"AO c #B5BCC2",
-"AP c #08121B",
-"AQ c #747E87",
-"AR c #90C9FE",
-"AS c #8DCBFE",
-"AT c #8CCAFD",
-"AU c #8BC8FE",
-"AV c #8AC7FD",
-"AW c #89C6FC",
-"AX c #87C4FA",
-"AY c #86C2F4",
-"AZ c #82BEF0",
-"A& c #82BAE9",
-"B c #7DB5E4",
-"B0 c #7AAEDD",
-"B1 c #74A8D7",
-"B2 c #7B96DD",
-"B3 c #839EE5",
-"B4 c #9DBCF2",
-"B5 c #B3D2FF",
-"B6 c #C4D8F3",
-"B7 c #AFB8C7",
-"B8 c #A0A9B8",
-"B9 c #9CA1A5",
-"Ba c #909599",
-"Bb c #8D9095",
-"Bc c #93969B",
-"Bd c #99A2A7",
-"Be c #B4BDC2",
-"Bf c #CDDAEA",
-"Bg c #DFECFC",
-"Bh c #DAEFFF",
-"Bi c #D3ECFF",
-"Bj c #CDE6FF",
-"Bk c #C4E2FF",
-"Bl c #BEDCFF",
-"Bm c #B8D8FF",
-"Bn c #BAD7FF",
-"Bo c #BACFFF",
-"Bp c #A2B7EE",
-"Bq c #8E9CD9",
-"Br c #7381BE",
-"Bs c #6072A0",
-"Bt c #526492",
-"Bu c #3E5B7B",
-"Bv c #3F5C7C",
-"Bw c #4E7596",
-"Bx c #547C9F",
-"By c #4D7598",
-"Bz c #476089",
-"BA c #506992",
-"BB c #5C68A2",
-"BC c #838FC9",
-"BD c #ADBEEA",
-"BE c #CCDDFF",
-"BF c #D2E5FF",
-"BG c #D1E4FF",
-"BH c #CCDFFF",
-"BI c #9EA9E1",
-"BJ c #6570A8",
-"BK c #4B648C",
-"BL c #679CC6",
-"BM c #7DBAE9",
-"BN c #81BEED",
-"BO c #87C1F3",
-"BP c #89C3F5",
-"BQ c #89C5FB",
-"BR c #8AC6FC",
-"BS c #8CC9FF",
-"BT c #323941",
-"BU c #888F97",
-"BV c #CACACC",
-"BW c #CACACA",
-"BX c #C9C9C9",
-"BY c #C0C0C0",
-"BZ c #000A29",
-"B& c #97B8D7",
-"C c #8DC9FF",
-"C0 c #A8C2D9",
-"C1 c #142E45",
-"C2 c #828483",
-"C3 c #C9CBCA",
-"C4 c #C8CAC9",
-"C5 c #C7C9C8",
-"C6 c #000F2B",
-"C7 c #90B2CE",
-"C8 c #394249",
-"C9 c #778087",
-"Ca c #223343",
-"Cb c #728393",
-"Cc c #94C7F2",
-"Cd c #83B6E1",
-"Ce c #8BAAC7",
-"Cf c #83A2BF",
-"Cg c #292C31",
-"Ch c #4E5156",
-"Ci c #C7C7C7",
-"Cj c #C9C9CB",
-"Ck c #ABABAB",
-"Cl c #001F3B",
-"Cm c #496884",
-"Cn c #8BC9FC",
-"Co c #7B95A6",
-"Cp c #183243",
-"Cq c #B4B5B7",
-"Cr c #0E0F11",
-"Cs c #91C7F5",
-"Ct c #00040E",
-"Cu c #78797B",
-"Cv c #C8C9CB",
-"Cw c #A2ABB2",
-"Cx c #060F16",
-"Cy c #568EBF",
-"Cz c #8FC7F8",
-"CA c #8DC9FB",
-"CB c #74B0E2",
-"CC c #122335",
-"CD c #5D6E80",
-"CE c #7C8083",
-"CF c #25292C",
-"CG c #858688",
-"CH c #B8BDC3",
-"CI c #1C2127",
-"CJ c #3B719F",
-"CK c #8DC9FD",
-"CL c #88C5FB",
-"CM c #80B8E7",
-"CN c #7BAFDE",
-"CO c #7792D9",
-"CP c #819CE3",
-"CQ c #94B3E9",
-"CR c #B2D1FF",
-"CS c #CBDFFA",
-"CT c #D1E5FF",
-"CU c #D8E1F0",
-"CV c #CDD6E5",
-"CW c #C8CDD1",
-"CX c #C3C8CC",
-"CY c #C6C9CE",
-"CZ c #CFD2D7",
-"C& c #D5DEE3",
-"D c #E2EBF0",
-"D0 c #DEEBFB",
-"D1 c #D2E7FA",
-"D2 c #CDE2F5",
-"D3 c #C3DCFA",
-"D4 c #BED7F5",
-"D5 c #B7D5F9",
-"D6 c #B6D6FD",
-"D7 c #B7D7FE",
-"D8 c #AFCCF6",
-"D9 c #9FBCE6",
-"Da c #7287BE",
-"Db c #6472AF",
-"Dc c #54629F",
-"Dd c #455785",
-"De c #465886",
-"Df c #4D6A8A",
-"Dg c #5A7797",
-"Dh c #5F86A7",
-"Di c #668DAE",
-"Dj c #6991B4",
-"Dk c #668EB1",
-"Dl c #657EA7",
-"Dm c #4A638C",
-"Dn c #54609A",
-"Do c #6C7DA9",
-"Dp c #95A6D2",
-"Dq c #ADC0E0",
-"Dr c #B0C3E3",
-"Ds c #AABDDE",
-"Dt c #92A5C6",
-"Du c #6B76AE",
-"Dv c #57629A",
-"Dw c #455E86",
-"Dx c #5D769E",
-"Dy c #6DA2CC",
-"Dz c #7FB4DE",
-"DA c #7EBBEA",
-"DB c #86C0F2",
-"DC c #1E252D",
-"DD c #99A0A8",
-"DE c #153655",
-"DF c #A1C2E1",
-"DG c #8BC9FA",
-"DH c #8CC8FE",
-"DI c #8AC8FB",
-"DJ c #486279",
-"DK c #2B455C",
-"DL c #C4C6C5",
-"DM c #C2C4C3",
-"DN c #153753",
-"DO c #A1C3DF",
-"DP c #1F282F",
-"DQ c #929BA2",
-"DR c #304151",
-"DS c #4C5D6D",
-"DT c #6598C3",
-"DU c #477AA5",
-"DV c #2C4B68",
-"DW c #00112E",
-"DX c #75787D",
-"DY c #C0C3C8",
-"DZ c #C5C5C7",
-"D& c #909090",
-"E c #0E0E0E",
-"E0 c #4E6D89",
-"E1 c #A3C2DE",
-"E2 c #89A3B4",
-"E3 c #031D2E",
-"E4 c #C3C4C6",
-"E5 c #303133",
-"E6 c #4F87B6",
-"E7 c #8EC6F5",
-"E8 c #366C9A",
-"E9 c #06101A",
-"Ea c #858F99",
-"Eb c #C2C3C5",
-"Ec c #A6A7A9",
-"Ed c #0E171E",
-"Ee c #636C73",
-"Ef c #8CC8FA",
-"Eg c #93A4B6",
-"Eh c #091A2C",
-"Ei c #707477",
-"Ej c #BFC0C2",
-"Ek c #31363C",
-"El c #4C5157",
-"Em c #8CC8FC",
-"En c #85C6FC",
-"Eo c #86C5FB",
-"Ep c #85C4FA",
-"Eq c #84C3F9",
-"Er c #84C0F6",
-"Es c #81BDF3",
-"Et c #7CB8EC",
-"Eu c #79B5E9",
-"Ev c #77AFE0",
-"Ew c #70A8D9",
-"Ex c #7594D4",
-"Ey c #7D9CDC",
-"Ez c #8CAAE6",
-"EA c #B1CFFF",
-"EB c #C6DFFD",
-"EC c #CCE5FF",
-"ED c #D0E6FE",
-"EE c #D2E8FF",
-"EF c #D5EAFF",
-"EG c #D7ECFF",
-"EH c #D8EAFE",
-"EI c #D3EBFF",
-"EJ c #CAE2FE",
-"EK c #B7D9FF",
-"EL c #B3D5FF",
-"EM c #B0D2FF",
-"EN c #B1D3FF",
-"EO c #B4D3FF",
-"EP c #AEC3FF",
-"EQ c #95AAE9",
-"ER c #8496D6",
-"ES c #7587C7",
-"ET c #667AAC",
-"EU c #596D9F",
-"EV c #3E5F80",
-"EW c #3C5D7E",
-"EX c #436E91",
-"EY c #517C9F",
-"EZ c #5889B2",
-"E& c #6394BD",
-"F c #659AC6",
-"F0 c #699ECA",
-"F1 c #689DC9",
-"F2 c #6497C2",
-"F3 c #5C8FBA",
-"F4 c #4D739A",
-"F5 c #41678E",
-"F6 c #536498",
-"F7 c #5C6DA1",
-"F8 c #6B7AB1",
-"F9 c #6E7DB4",
-"Fa c #6979AD",
-"Fb c #5B6B9F",
-"Fc c #4F658C",
-"Fd c #435980",
-"Fe c #436F96",
-"Ff c #618DB4",
-"Fg c #6FA9DB",
-"Fh c #7BB5E7",
-"Fi c #7CB9EF",
-"Fj c #7FBCF2",
-"Fk c #7FC0F6",
-"Fl c #82C3F9",
-"Fm c #84C5FB",
-"Fn c #87C6FC",
-"Fo c #87C5F8",
-"Fp c #88C6F9",
-"Fq c #010101",
-"Fr c #B3B3B3",
-"Fs c #505050",
-"Ft c #366A99",
-"Fu c #8FC3F2",
-"Fv c #86C7FD",
-"Fw c #8BC3F2",
-"Fx c #7AB2E1",
-"Fy c #050706",
-"Fz c #A7A9A8",
-"FA c #373737",
-"FB c #407AAA",
-"FC c #1C252C",
-"FD c #8A939A",
-"FE c #BCBEBD",
-"FF c #5B5B5B",
-"FG c #3B3B3B",
-"FH c #4F4F4F",
-"FI c #B0B0B0",
-"FJ c #BEBEC0",
-"FK c #BDBDBF",
-"FL c #B5BAC0",
-"FM c #575C62",
-"FN c #000A2C",
-"FO c #5A85A7",
-"FP c #001438",
-"FQ c #A2A2A4",
-"FR c #BEBEBC",
-"FS c #91918F",
-"FT c #00040D",
-"FU c #77818A",
-"FV c #7C8FA0",
-"FW c #4E6172",
-"FX c #17181A",
-"FY c #3F4042",
-"FZ c #839099",
-"F& c #3870A1",
-"G c #85C7FB",
-"G0 c #88C5FC",
-"G1 c #89C6FD",
-"G2 c #619FD2",
-"G3 c #88929B",
-"G4 c #BEBCBD",
-"G5 c #BFBDBE",
-"G6 c #AEAEAE",
-"G7 c #0D426E",
-"G8 c #85C6FE",
-"G9 c #82C1F7",
-"Ga c #83BFF5",
-"Gb c #80BCF2",
-"Gc c #71A9DA",
-"Gd c #6A89C9",
-"Ge c #7B9ADA",
-"Gf c #86A4E0",
-"Gg c #ABC9FF",
-"Gh c #C1DAF8",
-"Gi c #CFE5FD",
-"Gj c #D1E7FF",
-"Gk c #D3E8FD",
-"Gl c #D8E9FD",
-"Gm c #D7E8FC",
-"Gn c #D2EAFF",
-"Go c #C0D8F4",
-"Gp c #AED0FD",
-"Gq c #AFD1FF",
-"Gr c #ADCFFD",
-"Gs c #9FBEED",
-"Gt c #87A6D5",
-"Gu c #7E93D2",
-"Gv c #6E83C2",
-"Gw c #6779B9",
-"Gx c #596BAB",
-"Gy c #465A8C",
-"Gz c #435789",
-"GA c #496A8B",
-"GB c #58799A",
-"GC c #608BAE",
-"GD c #6A95B8",
-"GE c #6B9CC5",
-"GF c #6FA0C9",
-"GG c #71A6D2",
-"GH c #70A5D1",
-"GI c #6EA1CC",
-"GJ c #6B9EC9",
-"GK c #6F95BC",
-"GL c #5D83AA",
-"GM c #526397",
-"GN c #516296",
-"GO c #516097",
-"GP c #505F96",
-"GQ c #506094",
-"GR c #48588C",
-"GS c #455B82",
-"GT c #5C88AF",
-"GU c #739FC6",
-"GV c #76B0E2",
-"GW c #7DB7E9",
-"GX c #7DBAF0",
-"GY c #80BDF3",
-"GZ c #80C1F7",
-"G& c #66A4D7",
-"H c #B9B9B9",
-"H0 c #B7B9B8",
-"H1 c #B7B7B7",
-"H2 c #669AC9",
-"H3 c #8EC2F1",
-"H4 c #28608F",
-"H5 c #505251",
-"H6 c #86C0F0",
-"H7 c #8AC4F4",
-"H8 c #384148",
-"H9 c #626B72",
-"Ha c #B6B8B7",
-"Hb c #B9B9BB",
-"Hc c #B8B8BA",
-"Hd c #878787",
-"He c #191E24",
-"Hf c #353A40",
-"Hg c #7DA8CA",
-"Hh c #96C1E3",
-"Hi c #83C4FA",
-"Hj c #98C0E4",
-"Hk c #325A7E",
-"Hl c #404042",
-"Hm c #B8B8B6",
-"Hn c #7E8891",
-"Ho c #313B44",
-"Hp c #233647",
-"Hq c #495C6D",
-"Hr c #999A9C",
-"Hs c #B7B8BA",
-"Ht c #555555",
-"Hu c #00050E",
-"Hv c #6D7A83",
-"Hw c #83C5F9",
-"Hx c #84C6FA",
-"Hy c #87C4FB",
-"Hz c #86C4F7",
-"HA c #727C85",
-"HB c #0A141D",
-"HC c #B5B5B5",
-"HD c #81B6E2",
-"HE c #84C5FD",
-"HF c #81C4F9",
-"HG c #82C3FB",
-"HH c #81C2FA",
-"HI c #7FC2F9",
-"HJ c #7CBFF6",
-"HK c #80BFF5",
-"HL c #7DBCF2",
-"HM c #77B4EA",
-"HN c #75AFE1",
-"HO c #6A91CA",
-"HP c #7198D1",
-"HQ c #83A0E2",
-"HR c #A4C1FF",
-"HS c #BBD8FA",
-"HT c #C9E6FF",
-"HU c #D1E5FE",
-"HV c #D2E6FF",
-"HW c #D9EAFE",
-"HX c #DAEBFF",
-"HY c #BBD4F3",
-"HZ c #AECDFF",
-"H& c #A8C7FD",
-"I c #9AADF1",
-"I0 c #8699DD",
-"I1 c #788AC8",
-"I2 c #6D7FBD",
-"I3 c #657AA9",
-"I4 c #526796",
-"I5 c #3A5D7D",
-"I6 c #3E6181",
-"I7 c #517DA4",
-"I8 c #578CB8",
-"I9 c #6297C3",
-"Ia c #68A0D1",
-"Ib c #6DA5D6",
-"Ic c #70AADC",
-"Id c #72ACDE",
-"Ie c #71ADE1",
-"If c #71ADDF",
-"Ig c #6DA5D4",
-"Ih c #69A1D0",
-"Ii c #6095C1",
-"Ij c #5186B2",
-"Ik c #4B789F",
-"Il c #46739A",
-"Im c #5083AE",
-"In c #5D90BB",
-"Io c #67A0D5",
-"Ip c #72ABE0",
-"Iq c #7AB7ED",
-"Ir c #7CBBF1",
-"Is c #7EBDF3",
-"It c #7EBFF7",
-"Iu c #7FC0F8",
-"Iv c #80C1F9",
-"Iw c #81C4FB",
-"Ix c #92BFE6",
-"Iy c #3E6B92",
-"Iz c #484A49",
-"IA c #B1B3B2",
-"IB c #B0B2B1",
-"IC c #949BA1",
-"ID c #9DBBD5",
-"IE c #ACB0AF",
-"IF c #9CA09F",
-"IG c #888F95",
-"IH c #798086",
-"II c #13334C",
-"IJ c #476780",
-"IK c #001C38",
-"IL c #A3A3A3",
-"IM c #B3B1B4",
-"IN c #888888",
-"IO c #001C32",
-"IP c #407CAE",
-"IQ c #85C1F3",
-"IR c #7BBCF4",
-"IS c #000515",
-"IT c #4D5E6E",
-"IU c #AAAFB2",
-"IV c #696E71",
-"IW c #20425E",
-"IX c #6CABE1",
-"IY c #81C2F8",
-"IZ c #84C2FB",
-"I& c #83C1FA",
-"J c #88C2F2",
-"J0 c #255F8F",
-"J1 c #323637",
-"J2 c #AEB2B3",
-"J3 c #000F30",
-"J4 c #6E95B6",
-"J5 c #83C4FC",
-"J6 c #7FC4FB",
-"J7 c #7FC2F7",
-"J8 c #7EC1F8",
-"J9 c #7DC0F7",
-"Ja c #7FBEF4",
-"Jb c #7BB8EE",
-"Jc c #78B5EB",
-"Jd c #6E95CE",
-"Je c #6D94CD",
-"Jf c #7F9CDE",
-"Jg c #99B6F8",
-"Jh c #B8D5F7",
-"Ji c #C7E4FF",
-"Jj c #D1EAFF",
-"Jk c #B7D0EF",
-"Jl c #7897CD",
-"Jm c #7487CB",
-"Jn c #6D80C4",
-"Jo c #6072B0",
-"Jp c #4C5E9C",
-"Jq c #3D5281",
-"Jr c #445988",
-"Js c #4A6D8D",
-"Jt c #597C9C",
-"Ju c #5E8AB1",
-"Jv c #6A96BD",
-"Jw c #6A9FCB",
-"Jx c #6FA4D0",
-"Jy c #73ABDC",
-"Jz c #74AEE0",
-"JA c #77B1E3",
-"JB c #76B2E6",
-"JC c #76B2E4",
-"JD c #75B1E3",
-"JE c #74ACDB",
-"JF c #72AAD9",
-"JG c #6CA1CD",
-"JH c #6C99C0",
-"JI c #6996BD",
-"JJ c #6895BC",
-"JK c #6A97BE",
-"JL c #6A9DC8",
-"JM c #71A4CF",
-"JN c #77B0E5",
-"JO c #90BDE4",
-"JP c #002B52",
-"JQ c #818382",
-"JR c #AAACAB",
-"JS c #A9ABAA",
-"JT c #60676D",
-"JU c #7694AE",
-"JV c #000D27",
-"JW c #1F1F1F",
-"JX c #0F0F0F",
-"JY c #000201",
-"JZ c #090D0C",
-"J& c #171E24",
-"K c #282F35",
-"K0 c #25455E",
-"K1 c #9BBBD4",
-"K2 c #30536F",
-"K3 c #151515",
-"K4 c #6A6A6A",
-"K5 c #9A9A9A",
-"K6 c #ACAAAD",
-"K7 c #9E9C9F",
-"K8 c #232323",
-"K9 c #4E6A80",
-"Ka c #9EBAD0",
-"Kb c #84C0F2",
-"Kc c #8C9DAD",
-"Kd c #152636",
-"Ke c #333333",
-"Kf c #ABADAC",
-"Kg c #0F1417",
-"Kh c #2A2F32",
-"Ki c #6385A1",
-"Kj c #99BBD7",
-"Kk c #83C2F8",
-"Kl c #82C0F9",
-"Km c #85BFEF",
-"Kn c #202425",
-"Ko c #6D7172",
-"Kp c #A4A4A4",
-"Kq c #1D1D1D",
-"Kr c #4B7293",
-"Ks c #96BDDE",
-"Kt c #7DC2F9",
-"Ku c #7AC1F9",
-"Kv c #7BC0FB",
-"Kw c #79BEF9",
-"Kx c #7BC0F9",
-"Ky c #79BEF7",
-"Kz c #7ABCF6",
-"KA c #78BAF4",
-"KB c #76B9EE",
-"KC c #72B5EA",
-"KD c #71B0E5",
-"KE c #6BAADF",
-"KF c #689ACD",
-"KG c #6193C6",
-"KH c #8197E0",
-"KI c #94AAF3",
-"KJ c #B5D2FA",
-"KK c #C2DFFF",
-"KL c #D4E9FE",
-"KM c #D6EBFF",
-"KN c #CFE9FF",
-"KO c #AFC9EE",
-"KP c #889BDD",
-"KQ c #6B7EC0",
-"KR c #5C739C",
-"KS c #445B84",
-"KT c #335777",
-"KU c #3B5F7F",
-"KV c #3F7098",
-"KW c #4D7EA6",
-"KX c #558BB9",
-"KY c #6096C4",
-"KZ c #649ECE",
-"K& c #69A3D3",
-"L c #6AA9DC",
-"L0 c #6BAADD",
-"L1 c #6FAEE4",
-"L2 c #71B0E6",
-"L3 c #71B2E8",
-"L4 c #74B5EB",
-"L5 c #75B6EE",
-"L6 c #73B6ED",
-"L7 c #74B7EE",
-"L8 c #74B5ED",
-"L9 c #72B3EB",
-"La c #70B1E7",
-"Lb c #6FB0E6",
-"Lc c #6FAEE3",
-"Ld c #6CABE0",
-"Le c #6AA7DD",
-"Lf c #6BA8DE",
-"Lg c #70AFE4",
-"Lh c #74B3E9",
-"Li c #74B6F0",
-"Lj c #76B8F2",
-"Lk c #77B9F3",
-"Ll c #78BFF7",
-"Lm c #79C0F8",
-"Ln c #7ABFFA",
-"Lo c #7AC1F7",
-"Lp c #64839F",
-"Lq c #001632",
-"Lr c #68707B",
-"Ls c #656D78",
-"Lt c #576572",
-"Lu c #485663",
-"Lv c #2C4355",
-"Lw c #102739",
-"Lx c #001034",
-"Ly c #4D7B9F",
-"Lz c #7DBFF3",
-"LA c #4587BB",
-"LB c #5897CC",
-"LC c #69A8DD",
-"LD c #74B9F2",
-"LE c #4A7FA9",
-"LF c #063B65",
-"LG c #000F29",
-"LH c #00102A",
-"LI c #001A30",
-"LJ c #08243A",
-"LK c #052137",
-"LL c #000C26",
-"LM c #00284B",
-"LN c #123E61",
-"LO c #4483B8",
-"LP c #80BFF4",
-"LQ c #7ABFF8",
-"LR c #7AC0FB",
-"LS c #78BDF6",
-"LT c #336183",
-"LU c #081D30",
-"LV c #33485B",
-"LW c #616870",
-"LX c #747B83",
-"LY c #737C83",
-"LZ c #384F5F",
-"L& c #0B2232",
-"M c #00082B",
-"M0 c #20486B",
-"M1 c #67ACE3",
-"M2 c #7BC0F7",
-"M3 c #79C2F9",
-"M4 c #78C1F8",
-"M5 c #82BEF2",
-"M6 c #272A2F",
-"M7 c #64676C",
-"M8 c #3C5162",
-"M9 c #7BBFFC",
-"Ma c #73B6EB",
-"Mb c #73B2E7",
-"Mc c #6C9ED1",
-"Md c #6092C5",
-"Me c #7E94DD",
-"Mf c #8CA2EB",
-"Mg c #B3D0F8",
-"Mh c #BFDCFF",
-"Mi c #DAECFF",
-"Mj c #D0EAFF",
-"Mk c #AAC4E9",
-"Ml c #7D90D2",
-"Mm c #576AAC",
-"Mn c #395079",
-"Mo c #425982",
-"Mp c #486C8C",
-"Mq c #567A9A",
-"Mr c #598AB2",
-"Ms c #6394BC",
-"Mt c #659BC9",
-"Mu c #6AA0CE",
-"Mv c #6BA5D5",
-"Mw c #6FA9D9",
-"Mx c #6EADE0",
-"My c #70AFE2",
-"Mz c #73B2E8",
-"MA c #75B6EC",
-"MB c #76B7ED",
-"MC c #77B8F0",
-"MD c #75B8EF",
-"ME c #76B9F0",
-"MF c #76B7EF",
-"MG c #73B4EA",
-"MH c #72B3E9",
-"MI c #72B1E6",
-"MJ c #6FAEE1",
-"MK c #70ADE3",
-"ML c #71AEE4",
-"MM c #77B6EC",
-"MN c #79BBF5",
-"MO c #7BC2F8",
-"MP c #85A4C0",
-"MQ c #153450",
-"MR c #272F3A",
-"MS c #2F3742",
-"MT c #364451",
-"MU c #44525F",
-"MV c #546B7D",
-"MW c #71889A",
-"MX c #80AED2",
-"MY c #8EBCE0",
-"MZ c #7EC0F4",
-"M& c #88BDE7",
-"N c #96BAD4",
-"N0 c #85A9C3",
-"N1 c #7B97AD",
-"N2 c #7793A9",
-"N3 c #7894AA",
-"N4 c #87ABC5",
-"N5 c #97BBD5",
-"N6 c #7FBEF3",
-"N7 c #8EBCDE",
-"N8 c #74899C",
-"N9 c #495E71",
-"Na c #313840",
-"Nb c #1D242C",
-"Nc c #1D262D",
-"Nd c #2F383F",
-"Ne c #435A6A",
-"Nf c #6D8494",
-"Ng c #92BADD",
-"Nh c #7ABFF6",
-"Ni c #205C90",
-"Nj c #2E3136",
-"Nk c #979A9F",
-"Nl c #000617",
-"Nm c #889DAE",
-"Nn c #76BEF9",
-"No c #77BFFA",
-"Np c #75BDF8",
-"Nq c #76BAF7",
-"Nr c #74B8F5",
-"Ns c #72B9F1",
-"Nt c #6FB6EE",
-"Nu c #6EB1E8",
-"Nv c #69ACE3",
-"Nw c #68A2D2",
-"Nx c #4F89B9",
-"Ny c #798FD8",
-"Nz c #869CE5",
-"NA c #A3C3F4",
-"NB c #D6E8FE",
-"NC c #D9E9FF",
-"ND c #CEEAFF",
-"NE c #A7C3EA",
-"NF c #7B8FCE",
-"NG c #586CAB",
-"NH c #365C80",
-"NI c #486E92",
-"NJ c #4F84B0",
-"NK c #598EBA",
-"NL c #5C98CA",
-"NM c #619DCF",
-"NN c #63A2D7",
-"NO c #66A5DA",
-"NP c #67AADF",
-"NQ c #6AADE2",
-"NR c #6CB1E8",
-"NS c #6EB3EA",
-"NT c #70B5EE",
-"NU c #71B6EF",
-"NV c #71B9F4",
-"NW c #72BAF5",
-"NX c #73B9F5",
-"NY c #74BAF6",
-"NZ c #73BBF5",
-"N& c #72BAF4",
-"O c #74B9F4",
-"O0 c #73B8F3",
-"O1 c #71B8F0",
-"O2 c #70B7EF",
-"O3 c #6EB3EC",
-"O4 c #6CB3E9",
-"O5 c #6CB1EA",
-"O6 c #6DB2EB",
-"O7 c #6FB4ED",
-"O8 c #73BBF6",
-"O9 c #75BBF7",
-"Oa c #76BDFB",
-"Ob c #77BDF9",
-"Oc c #75BDF7",
-"Od c #76BEF8",
-"Oe c #73BEF8",
-"Of c #74BFF9",
-"Og c #77A5C7",
-"Oh c #4E5B64",
-"Oi c #1C2932",
-"Oj c #0A1117",
-"Ok c #2A3137",
-"Ol c #5E87A7",
-"Om c #8FB8D8",
-"On c #7ABBF3",
-"Oo c #5F6972",
-"Op c #0E1821",
-"Oq c #939393",
-"Or c #6F7982",
-"Os c #000912",
-"Ot c #4B8CC2",
-"Ou c #7ABBF1",
-"Ov c #74BCF7",
-"Ow c #75B9F6",
-"Ox c #73B7F4",
-"Oy c #6DB4EC",
-"Oz c #538DBD",
-"OA c #7288D1",
-"OB c #8298E1",
-"OC c #99B9EA",
-"OD c #B5D5FF",
-"OE c #CFE3FC",
-"OF c #D4E8FF",
-"OG c #C6E2FF",
-"OH c #A6C2E9",
-"OI c #768AC9",
-"OJ c #576BAA",
-"OK c #395F83",
-"OL c #50769A",
-"OM c #558AB6",
-"ON c #5E93BF",
-"OO c #5F9BCD",
-"OP c #64A0D2",
-"OQ c #6DB0E5",
-"OR c #6DB2E9",
-"OS c #70B8F3",
-"OT c #72B8F4",
-"OU c #71B9F3",
-"OV c #72B7F2",
-"OW c #6DB4EA",
-"OX c #74BBF9",
-"OY c #74BCF6",
-"OZ c #72BDF7",
-"O& c #4A789A",
-"P c #001133",
-"P0 c #323F48",
-"P1 c #767D83",
-"P2 c #51585E",
-"P3 c #001434",
-"P4 c #3E6787",
-"P5 c #79BAF2",
-"P6 c #3E7FB7",
-"P7 c #030D16",
-"P8 c #6D7780",
-"P9 c #061019",
-"Pa c #626C75",
-"Pb c #78B9EF",
-"Pc c #6DBCF7",
-"Pd c #70BAF9",
-"Pe c #6FBBF7",
-"Pf c #6FB9F8",
-"Pg c #6EB8F7",
-"Ph c #6DB7F4",
-"Pi c #6AB4F1",
-"Pj c #6AB0EB",
-"Pk c #62A8E3",
-"Pl c #64A3D6",
-"Pm c #5594C7",
-"Pn c #6685C6",
-"Po c #7897D8",
-"Pp c #8FACE6",
-"Pq c #B2CFFF",
-"Pr c #D1E9FF",
-"Ps c #C3E3FF",
-"Pt c #A0C0E9",
-"Pu c #7080BC",
-"Pv c #4E5E9A",
-"Pw c #356289",
-"Px c #4F7CA3",
-"Py c #538FC1",
-"Pz c #5FA0D8",
-"PA c #63A4DC",
-"PB c #63ACE3",
-"PC c #66AFE6",
-"PD c #6AB0EE",
-"PE c #6BB1EF",
-"PF c #6AB5EF",
-"PG c #6BB6F0",
-"PH c #6CB6F3",
-"PI c #6EB8F5",
-"PJ c #6EBAF6",
-"PK c #6AB6F0",
-"PL c #69B5EF",
-"PM c #6CB3F1",
-"PN c #6CB6F5",
-"PO c #6DB7F6",
-"PP c #6FB9F6",
-"PQ c #70BCF8",
-"PR c #72B9F9",
-"PS c #71BBF8",
-"PT c #71BBFA",
-"PU c #6EBAF4",
-"PV c #70BAF7",
-"PW c #71B8F8",
-"PX c #76B8EC",
-"PY c #6DAFE3",
-"PZ c #656565",
-"P& c #6D6D6D",
-"Q c #7F7F7F",
-"Q0 c #6A6E6F",
-"Q1 c #000405",
-"Q2 c #6C7A87",
-"Q3 c #000A17",
-"Q4 c #646665",
-"Q5 c #7E807F",
-"Q6 c #6E777E",
-"Q7 c #0C151C",
-"Q8 c #25689D",
-"Q9 c #75B8ED",
-"Qa c #6FBBF9",
-"Qb c #6BBAF5",
-"Qc c #6DB9F5",
-"Qd c #69B3F0",
-"Qe c #65ABE6",
-"Qf c #5998CB",
-"Qg c #5E7DBE",
-"Qh c #7392D3",
-"Qi c #86A3DD",
-"Qj c #AAC7FF",
-"Qk c #C4DCF8",
-"Ql c #D0E8FF",
-"Qm c #BEDEFF",
-"Qn c #9FBFE8",
-"Qo c #6F7FBB",
-"Qp c #4B5B97",
-"Qq c #38658C",
-"Qr c #5380A7",
-"Qs c #5692C4",
-"Qt c #5E9ACC",
-"Qu c #61A2DA",
-"Qv c #66A7DF",
-"Qw c #64ADE4",
-"Qx c #67B0E7",
-"Qy c #6CB2F0",
-"Qz c #6CB7F1",
-"QA c #6BB5F2",
-"QB c #6CB8F4",
-"QC c #6BB7F1",
-"QD c #6DB4F2",
-"QE c #6FB6F4",
-"QF c #70B7F7",
-"QG c #6DB9F3",
-"QH c #6AB9F4",
-"QI c #75B7EB",
-"QJ c #1F6195",
-"QK c #2F2F2F",
-"QL c #303030",
-"QM c #505455",
-"QN c #15191A",
-"QO c #515F6C",
-"QP c #757776",
-"QQ c #6F7170",
-"QR c #111A21",
-"QS c #464F56",
-"QT c #74B7EC",
-"QU c #6DB9F7",
-"QV c #6CB8F6",
-"QW c #69AFEB",
-"QX c #65ABE7",
-"QY c #62A5DC",
-"QZ c #599CD3",
-"Q& c #537AB3",
-"R c #668DC6",
-"R0 c #829BDE",
-"R1 c #A1BAFD",
-"R2 c #BED8FB",
-"R3 c #CCE6FF",
-"R4 c #98B8EB",
-"R5 c #6C7FB9",
-"R6 c #465993",
-"R7 c #396A93",
-"R8 c #5485AE",
-"R9 c #5F9ED1",
-"Ra c #62A4E0",
-"Rb c #67A9E5",
-"Rc c #64AEEB",
-"Rd c #67B1EE",
-"Re c #6BB7F5",
-"Rf c #6DB8F9",
-"Rg c #6BB9F7",
-"Rh c #8CB0D0",
-"Ri c #001838",
-"Rj c #626463",
-"Rk c #090A0C",
-"Rl c #636466",
-"Rm c #64696F",
-"Rn c #3F444A",
-"Ro c #040605",
-"Rp c #080A09",
-"Rq c #5E5E5E",
-"Rr c #767676",
-"Rs c #6A7378",
-"Rt c #141D22",
-"Ru c #13548A",
-"Rv c #6EBAF8",
-"Rw c #66ACE8",
-"Rx c #63A6DD",
-"Ry c #5DA0D7",
-"Rz c #5D84BD",
-"RA c #5F86BF",
-"RB c #7B94D7",
-"RC c #95AEF1",
-"RD c #B8D2F5",
-"RE c #C8E2FF",
-"RF c #B0D0FF",
-"RG c #90B0E3",
-"RH c #687BB5",
-"RI c #3C6D96",
-"RJ c #5788B1",
-"RK c #5A99CC",
-"RL c #61A0D3",
-"RM c #65A7E3",
-"RN c #69ABE7",
-"RO c #66B0ED",
-"RP c #7498B8",
-"RQ c #001232",
-"RR c #767877",
-"RS c #101113",
-"RT c #0F1012",
-"RU c #01060C",
-"RV c #2D3238",
-"RW c #0F1110",
-"RX c #636564",
-"RY c #6E6E6E",
-"RZ c #121B20",
-"R& c #3E474C",
-"S c #6BB1ED",
-"S0 c #67ADE9",
-"S1 c #65A8DF",
-"S2 c #5EA1D8",
-"S3 c #5E92C4",
-"S4 c #497DAF",
-"S5 c #768DD3",
-"S6 c #8AA1E7",
-"S7 c #AAC9F7",
-"S8 c #BEDDFF",
-"S9 c #D6EAFF",
-"Sa c #D5EBFF",
-"Sb c #D6ECFF",
-"Sc c #CDEAFF",
-"Sd c #ACC9FF",
-"Se c #8BA8E2",
-"Sf c #657AAF",
-"Sg c #455A8F",
-"Sh c #4073A0",
-"Si c #588BB8",
-"Sj c #599AD0",
-"Sk c #62A3D9",
-"Sl c #65A9E6",
-"Sm c #69ADEA",
-"Sn c #69B3F2",
-"So c #6AB4F3",
-"Sp c #7296B6",
-"Sq c #000F2F",
-"Sr c #606062",
-"Ss c #171719",
-"St c #0C0C0E",
-"Su c #343436",
-"Sv c #6F6F6F",
-"Sw c #636C75",
-"Sx c #0D161F",
-"Sy c #19588E",
-"Sz c #68AEEA",
-"SA c #66A9E0",
-"SB c #60A3DA",
-"SC c #6397C9",
-"SD c #6D84CA",
-"SE c #8198DE",
-"SF c #9CBBE9",
-"SG c #B7D6FF",
-"SH c #D0E4FC",
-"SI c #D5E9FF",
-"SJ c #D1E7FE",
-"SK c #CBE1F8",
-"SL c #BCD9FB",
-"SM c #B3D0F2",
-"SN c #A9C6FF",
-"SO c #819ED8",
-"SP c #6176AB",
-"SQ c #4275A2",
-"SR c #5A8DBA",
-"SS c #5C9DD3",
-"ST c #63A4DA",
-"SU c #66AAE7",
-"SV c #6AAEEB",
-"SW c #6BB5F4",
-"SX c #002444",
-"SY c #4A4A4A",
-"SZ c #777779",
-"S& c #78787A",
-"T c #050E17",
-"T0 c #4E5760",
-"T1 c #76B5EB",
-"T2 c #68AEEC",
-"T3 c #61A3DF",
-"T4 c #609CD2",
-"T5 c #508CC2",
-"T6 c #6080BD",
-"T7 c #7090CD",
-"T8 c #90AAE7",
-"T9 c #AFC9FF",
-"Ta c #B7D8FF",
-"Tb c #B3D8FF",
-"Tc c #AED3FF",
-"Td c #A9CDFD",
-"Te c #ABC3FF",
-"Tf c #7C94D2",
-"Tg c #5A74A5",
-"Th c #435D8E",
-"Ti c #457AAC",
-"Tj c #5B90C2",
-"Tk c #5E9FD7",
-"Tl c #64A5DD",
-"Tm c #67ABE8",
-"Tn c #6BB2F2",
-"To c #6DB4F4",
-"Tp c #6FB6F6",
-"Tq c #70B4F1",
-"Tr c #4589C6",
-"Ts c #000419",
-"Tt c #23394E",
-"Tu c #616264",
-"Tv c #727375",
-"Tw c #474C52",
-"Tx c #04223C",
-"Ty c #000721",
-"Tz c #3375AF",
-"TA c #73B5EF",
-"TB c #6DB3F1",
-"TC c #69AFED",
-"TD c #63A5E1",
-"TE c #629ED4",
-"TF c #5A96CC",
-"TG c #5676B3",
-"TH c #6A8AC7",
-"TI c #7F99D6",
-"TJ c #9FB9F6",
-"TK c #ADCEF9",
-"TL c #AACFFB",
-"TM c #AACEFE",
-"TN c #A8CCFC",
-"TO c #95ADEB",
-"TP c #6D85C3",
-"TQ c #516B9C",
-"TR c #466091",
-"TS c #4C81B3",
-"TT c #6095C7",
-"TU c #65A6DE",
-"TV c #6CB3F3",
-"TW c #71B5F2",
-"TX c #7C92A7",
-"TY c #30465B",
-"TZ c #000002",
-"T& c #050A10",
-"U c #2A2F35",
-"U0 c #4E6C86",
-"U1 c #90AEC8",
-"U2 c #72B4EE",
-"U3 c #6FB6F8",
-"U4 c #6DB7F8",
-"U5 c #6EB5F7",
-"U6 c #6CB3F5",
-"U7 c #6CB1F2",
-"U8 c #6AAFF0",
-"U9 c #63A7E4",
-"Ua c #60A1D7",
-"Ub c #5B9CD2",
-"Uc c #588ABF",
-"Ud c #5082B7",
-"Ue c #788BD0",
-"Uf c #8699DE",
-"Ug c #9EB8F5",
-"Uh c #AECBFF",
-"Ui c #A1B8FB",
-"Uj c #869DE0",
-"Uk c #687AB8",
-"Ul c #3F668F",
-"Um c #456C95",
-"Un c #4E8AC0",
-"Uo c #5E9AD0",
-"Up c #60A2DE",
-"Uq c #68ACEB",
-"Ur c #6BAFEE",
-"Us c #6FB4F5",
-"Ut c #6EB5F5",
-"Uu c #70B7F9",
-"Uv c #6CB6F7",
-"Uw c #6DB4F6",
-"Ux c #64A8E5",
-"Uy c #5FA0D6",
-"Uz c #6294C9",
-"UA c #4F81B6",
-"UB c #687BC0",
-"UC c #7588CD",
-"UD c #7A94D1",
-"UE c #829CD9",
-"UF c #829FD9",
-"UG c #7A97D1",
-"UH c #768DD0",
-"UI c #6B82C5",
-"UJ c #6476B4",
-"UK c #495B99",
-"UL c #3B628B",
-"UM c #5279A2",
-"UN c #5793C9",
-"UO c #639FD5",
-"UP c #64A6E2",
-"UQ c #66A8E4",
-"UR c #69ADEC",
-"US c #6EB3F4",
-"UT c #70B5F8",
-"UU c #6FB4F7",
-"UV c #6FB2F6",
-"UW c #6DB0F4",
-"UX c #6BAFF0",
-"UY c #67ABEC",
-"UZ c #67A7E5",
-"U& c #63A3E1",
-"V c #619ED7",
-"V0 c #5895CE",
-"V1 c #507EB2",
-"V2 c #4E7CB0",
-"V3 c #6683BB",
-"V4 c #6D8AC2",
-"V5 c #6E87BF",
-"V6 c #6D86BE",
-"V7 c #5F7EAD",
-"V8 c #496897",
-"V9 c #365F8B",
-"Va c #3F6894",
-"Vb c #467DB3",
-"Vc c #578EC4",
-"Vd c #5E9CD9",
-"Ve c #65A3E0",
-"Vf c #66A7E7",
-"Vg c #69AAEA",
-"Vh c #6DB1F2",
-"Vi c #6DB2F5",
-"Vj c #71B4F8",
-"Vk c #71B5F6",
-"Vl c #70B5F6",
-"Vm c #70B5FA",
-"Vn c #6EB3F6",
-"Vo c #6EB1F5",
-"Vp c #69ADEE",
-"Vq c #69A9E7",
-"Vr c #66A6E4",
-"Vs c #66A3DC",
-"Vt c #6593C7",
-"Vu c #5583B7",
-"Vv c #4D6AA2",
-"Vw c #415E96",
-"Vx c #405991",
-"Vy c #3E5D8C",
-"Vz c #486796",
-"VA c #4C75A1",
-"VB c #5B84B0",
-"VC c #5D94CA",
-"VD c #649BD1",
-"VE c #64A2DF",
-"VF c #68A6E3",
-"VG c #68A9E9",
-"VH c #6BACEC",
-"VI c #70B3F7",
-"VJ c #70B4F5",
-"VK c #6FB4F9",
-"VL c #70B2E6",
-"VM c #6EB0E4",
-"VN c #6EADE2",
-"VO c #6AAADA",
-"VP c #67A7D7",
-"VQ c #65A2D1",
-"VR c #619ECD",
-"VS c #5C95C2",
-"VT c #548DBA",
-"VU c #5287B3",
-"VV c #5288B4",
-"VW c #578DB9",
-"VX c #5D97C5",
-"VY c #639DCB",
-"VZ c #64A2D1",
-"V& c #68A6D5",
-"W c #69A7DA",
-"W0 c #6CAADD",
-"W1 c #71B4E9",
-"W2 c #72B5EC",
-"W3 c #627ED4",
-"W4 c #627ED5",
-"W5 c #617ED5",
-"W6 c #637ED3",
-"W7 c #647ED2",
-"W8 c #657ED1",
-"W9 c #667ED0",
-"Wa c #687FCE",
-"Wb c #687FCD",
-"Wc c #697FCC",
-"Wd c #6B7FCA",
-"We c #6D80C9",
-"Wf c #6E80C8",
-"Wg c #6E80C7",
-"Wh c #7180C4",
-"Wi c #7280C3",
-"Wj c #7481C1",
-"Wk c #7681BF",
-"Wl c #7781BD",
-"Wm c #7A81BB",
-"Wn c #7B82BA",
-"Wo c #7D82B8",
-"Wp c #7E82B6",
-"Wq c #8182B3",
-"Wr c #8283B2",
-"Ws c #8483B0",
-"Wt c #8683AE",
-"Wu c #8983AB",
-"Wv c #8B84A9",
-"Ww c #8D84A6",
-"Wx c #8E85A4",
-"Wy c #9185A2",
-"Wz c #9385A0",
-"WA c #95859D",
-"WB c #97869B",
-"WC c #998699",
-"WD c #9B8697",
-"WE c #9D8794",
-"WF c #A18790",
-"WG c #A2888F",
-"WH c #A3888D",
-"WI c #A6888B",
-"WJ c #A88889",
-"WK c #AA8987",
-"WL c #AC8984",
-"WM c #AE8981",
-"WN c #B18A7F",
-"WO c #B38A7D",
-"WP c #B58A7B",
-"WQ c #B88B78",
-"WR c #BA8B76",
-"WS c #BB8B74",
-"WT c #BE8B71",
-"WU c #C08C6F",
-"WV c #C18C6E",
-"WW c #C48D6B",
-"WX c #C58D69",
-"WY c #C88E67",
-"WZ c #CA8E64",
-"W& c #CC8E62",
-"X c #CE8E60",
-"X0 c #CF8E5E",
-"X1 c #D18F5C",
-"X2 c #D48F59",
-"X3 c #D68F57",
-"X4 c #D79057",
-"X5 c #D89055",
-"X6 c #DC9052",
-"X7 c #DC9051",
-"X8 c #DE914F",
-"X9 c #DF914E",
-"Xa c #E1914C",
-"Xb c #E2924B",
-"Xc c #E49248",
-"Xd c #E59247",
-"Xe c #E79245",
-"Xf c #E89245",
-"Xg c #EA9342",
-"Xh c #EB9342",
-"Xi c #EC9341",
-"Xj c #ED943F",
-"Xk c #EE943E",
-"Xl c #EF943D",
-"Xm c #F0943D",
-"Xn c #F1943B",
-"Xo c #F2943B",
-"Xp c #F2943A",
-"Xq c #F39539",
-"Xr c #F49539",
-"Xs c #F59539",
-"Xt c #F69537",
-"Xu c #F69637",
-"Xv c #F79637",
-"Xw c #F69638",
-"Xx c #F69639",
-"Xy c #F59639",
-"Xz c #F4963A",
-"XA c #F4963B",
-"XB c #F3953C",
-"XC c #F2953C",
-"XD c #F2963D",
-"XE c #F1963F",
-"XF c #EF9641",
-"XG c #EE9642",
-"XH c #ED9643",
-"XI c #EC9645",
-"XJ c #EA9647",
-"XK c #EA9648",
-"XL c #E99649",
-"XM c #E8954B",
-"XN c #E6954D",
-"XO c #E5954E",
-"XP c #E3944F",
-"XQ c #E29551",
-"XR c #E19553",
-"XS c #DF9556",
-"XT c #DD9558",
-"XU c #DB955A",
-"XV c #DA955C",
-"XW c #D8955E",
-"XX c #D69560",
-"XY c #D59562",
-"XZ c #D49464",
-"X& c #D29466",
-"Y c #D09468",
-"Y0 c #CE946B",
-"Y1 c #CC936D",
-"Y2 c #CA936F",
-"Y3 c #C89371",
-"Y4 c #C69374",
-"Y5 c #C49377",
-"Y6 c #C39379",
-"Y7 c #C0937C",
-"Y8 c #BE937E",
-"Y9 c #BC9281",
-"Ya c #BB9282",
-"Yb c #B89285",
-"Yc c #B79286",
-"Yd c #B49289",
-"Ye c #B3928C",
-"Yf c #B1918F",
-"Yg c #AF9191",
-"Yh c #AC9194",
-"Yi c #AA9196",
-"Yj c #A99198",
-"Yk c #A7919A",
-"Yl c #A5919D",
-"Ym c #A290A0",
-"Yn c #A190A2",
-"Yo c #9F90A4",
-"Yp c #9D90A7",
-"Yq c #9B90A9",
-"Yr c #998FAB",
-"Ys c #978FAD",
-"Yt c #958FAF",
-"Yu c #938FB2",
-"Yv c #928FB3",
-"Yw c #8F8FB8",
-"Yx c #8E8FB8",
-"Yy c #8C8EBB",
-"Yz c #8A8EBD",
-"YA c #888EBF",
-"YB c #888EC0",
-"YC c #868EC3",
-"YD c #838EC6",
-"YE c #828EC7",
-"YF c #808EC9",
-"YG c #7E8DCB",
-"YH c #7D8DCD",
-"YI c #7C8DCF",
-"YJ c #7A8DD0",
-"YK c #788DD2",
-"YL c #778DD4",
-"YM c #768DD5",
-"YN c #758CD7",
-"YO c #748CD8",
-"YP c #738CDA",
-"YQ c #718CDC",
-"YR c #6F8CDE",
-"YS c #6F8CDF",
-"YT c #6D8CE0",
-"YU c #6B8CE3",
-"YV c #6B8CE4",
-" 0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 3 4 5 6 7 8 9 a b c d e f g h i j 7 k l 3 m 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 n n 1 0 0 n 0 o o 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
-" p p q q p p q q p p q q p p q q p p q q p p q q p p n 0 3 5 r 8 j s a t u v w x y z A 7 B C 2 1 q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p D q q p D q E F F q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q",
-" G G H H G G H H G G H H G G H H G G H H G G H H I J K L M N O P Q R S T U V W X Y Z &0 000102030405 H H0606 H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H H H H H G G H H G G H H05 G H H G G H H G G H H G G H H G G0707 G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H",
-"0808090908080909080809090808090908080909080809090a I L L0b0c O0d Q0e0f0g0h0i0j0k0l0m0n0o0p0q030r G0s09090t0t0909080809090808090908080909080809090808090908080909080809090808090908080909080809090808090908080909080809090808090909090909080809090808090908080909080809090s0809090808090908080u0u0808090908080909080809090808090908080909080809090808090908080909080809090808090908080909080809090808090908080909",
-"0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0x0y0z0A0B0C0D0E0F0G0H0I0J0K0L0M0N0O0P0Q0R0S0T0U0V0y0x0w0w0v0v0W0W0v0v0w0w0v0v0W0W0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0x0X0X0x0x0v0v0w0x0X0X0v0v0v0v0Y0Y0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w",
-"0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z1 0w0w0y0A0B0C0S0E0F101112131415161718191a1b0T1c0z0y0w1 0&0&0Z0Z1d1d0Z0Z0&0&0Z0Z1d1d0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&1e0Z0&0&0Z0Z0&1 0Z0Z0&0&0Z0Z0Z0Z0Z0Z1f1f0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&",
-"1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1i1j1k1l1m1n1o1p1q1r1s1t1u1v1w1x1y1z1A1B1C1D1E1o1n1F1l1G1H1I1h1g1g1h1h1g1g1h1h1J1J1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1K1K1g1g1h1h1L1M1N1O1P1P1Q1Q1g1R1h1h1g1g1K1K1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h",
-"1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1U1V1I1G1m1W1X1Y1Z1&2 202122232425262728292a1o1n2b1l1G1i1g1V2c1U1S1T1T1S1S1T1T2d2d1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S2e2e1S1S1T1T2f2g2h2i2j2k2l2m1U1S1T1T1S1S2e2e1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T",
-"2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2p2q2r1Q2s2t2u2v2w2x2y2z2A2B2C2D2E2F2G2H2I2J2K2L2M2N2O2O2P2Q2R2R2q2p2o2S2T2T2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2p2n2U2V2W2X2Y2Z2&3 303132333435363637372n2n38382n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o",
-"39393a3a39393a3a39393a3a39393a3a39393a3a3b2n3c3d2s2t3e3f3g3h3i3j3k3l3m3n3o3p3q3r2J3s2L3t3u2N2s2O2P3v3w3w2q2p2o2S3x3y3a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a3b393a3a3z3A3B3C3D3D3D3E3F3G3H3I3J3K3L3M39393N3O39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a",
-"3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3T3U3V3W3X3Y3Z3&4 404142434445464748494a3Y3Y4b4c4d4e4f4g4h4i3W4j4k4l4m4n3T4o3Q3Q3S3S3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3T3P4p4p4q4r4s4t4u4v4v4v4s4s4v4u4w4x4y4z4A4B4C4C3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R",
-"4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E3Q3P4o4H3W4I4J4K4L4M4N4O4P444Q464R4S484T4U4V4J4W4X4Y4Y4Z4&5 4f5051524l4m4n3T3P3Q4E534G4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4E4E5454555556574s584v4v4v4u4t4t4v4v59594u5a5b5c5d5d4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F",
-"5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5g5e5f5h5i5j5k5l5m5n5o5p5q5r5s5t5u5v5w5x5y5z5A5B5A5A5C5D5E5E5F5G5H5I5J5K5L5M5N5O5j5j5P5h5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5Q5Q5f5f5e5e5f5f5R5e5f5S5T5U4u3D4v4v4v4v4u594v4v4v4v4u5V5W5X5Y5Z5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f",
-"5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5&6 5O606162636465666768696a6b6c6d6e6f6f6f6e6g6h6i6j6k6l6m6n6o6p6q6r6s6t6u6v5O6w5&6x5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h6y6y6z6z5R5R5h5h6x5R5f5h6A6B4u4v4u4u4u4u4u4u4u4u4v4v4u6C6D6E5Z6F5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h",
-"4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D6G3R6H6I6J4f6K6L6M6N6O6P6Q6R6S6T6U6V6W6X6Y6Z6&7 70717272737475767778797a7b4I517c4m7d7e7f4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4E4E4E4E7f7g4E7h7i7j4v4v4u4u4u4u4u4u4s4s4v4v7k7l7m5R7h5d4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E",
-"3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3T7n7o3V4j7p4Z7q7r7s6N7t7u7v7w7x7y7z7A7B7C7D7E7F7G7H7I7J7K7L7M7N7O7P7Q7R7S7T7U7V517W7X7Y7Z4C3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3Q3Q3Q3Q7&7&3Q3Q8 804v4v4u4u4u4u4u4u4s4s4v4u818283833Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q",
-"8484858586868585848485858484858587883b2p898a8b3s8c8d8e8f8g8h8i8j8k8l8m8m8n8o8p8q8r8s8t8u8v8w8x8y8z v8A8B8C8D8E8F8G8H8I8J8K8L8M8M8484858586868585848485858N7n858584848484878485858M8M858M8N8N858584848585848485858686858584848585868685858484858587844C8I313D4u4v4u4u4u4u4u4u4u4u4u4v8O8P8Q8485858R8R858M8487858M8484858M8484858M8R8R858584848585848Q85858487858S84848585848485858585858584848585858585858N8N858M",
-"87878M8M8T8T8M8M87888M8M87878U3a888V2p2Q8a3u8W2I8X8Y8Z8&9 909192939495969798999a9b9c9d8u8v8v9e9e9f9g9h9i9j9k9l9m9n8G9o9p9q9r2n3988878M8M8T8T8M8M87878M8M7n7n8U8U8888878787878M8M8M8M8M8M7n7o393988888M8M87878M8M8T8T8M8M87878M8M8T8T8M8M87878M8M88879s9t9u4u4u4v4u4u4u4u4u4u4u4u4u9v9w9x87878M8M9y9y393987878M8M88878M8M87878M399z9z8M8M87878M8M87888M8587888M8M87878M8M87878M8M8M8M8M8M8787858M8M8M8M397n7n8M8M",
-"9A9A9B9B9A9A2S2S9A9A9B9B9A9A9C9C2p2q2Q2P9D9E9F9G9H9I9J9K9L9M9N9O9P9Q9R9S9T9U9V9W9X9Y9Z9&a a a0a0a1a2a3a4a5a6a7a8a9aaabacad3vaeaeaf9C9B9B9A9A9B9B9A9A9B9B9Aag9B9B9A9A9B9B9A9A9B9B9A9Aahah9A9A9B9B9Aai9B9Bajaj9B9B9A9Aakak9A9A9B9B9A9A9B9B9A9A9B9Bai9Aalaman4u4u4v4u4u4u4u4u4u4s4s4uaoapaqai9A9B9B9A9A9B9B9A9A9B9Bai9Aar9B9A9A9A9A3b3b9B9B9A9A9B9B9A9A9A9A9A9A9B9C9A9A9B9B9A9A9B9B9B9B9B9B9Aai9B9C9A9A9B9B9A9A2S3a",
-"aiai9C9Caiai2o2oaias9C9Caiasatau3v2Pavawaxay9GazaAaBaCaDaEaFaGaHaIaJaKaLaMaNaOaPaQaRaS9&aTaUaVaVaWaXaYa3aZa&b b0b1a9b2b3b4avb5b6ataf9C9C9Aai9C9Caiai9Cafaias9C9C9Aai9B9Caiai9C9Basb7b8b99Aai9C9Caiai9C9Cbaba9C9Caiaibbbbaiai9C9Caiai9C9Caiai9C9Casasalbcbd4u4v4v4u4u4u4u4u4u4s4s4vbebfbgaiaiafafai9A9C9B9Aai9C9Caiai9C9Caiaiaiai2n2p9C9Casai9C9Caiaiaiasaiai9C9Caiai9C9Caiai9C9C9C9C9C9Caiai9C9Caiaiaf9Caiai2o2o",
-"bhbhbibibhbhbibibhbhbibibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb&c c0c1ayc2c3c4c5c6c7bjbjbhbhbibjbhbhbibibhbhbjbiafafc8c8c9cacbcccdcecfcgchchcici60602Tcjckbhbibibhbhchchbhbhbibibhbhclclbhbhcmcmcncncocpcq4u4u594v4u4u4u4s4s4u4ucrcscmcmbjbibibictctcucvcwcxcyczcAcBcCc9asasafafbhbhbibibhbhbibibibicmcmcDcEcFcobhbhbibibhbhbibibibjcGcHcIcJcKcLasasbibicMcMclcl",
-"ckckbjbjckckbjbjcNckbkbkblbmcOcPcQcRcScTcUcVcWcXcYcZc&c&d d0d1d2d3aMbGbGd4d5d6d7d8d9dadbdcdddedfdgdhbVdidjdkdldmdndodpc1dqdrdsc4dtc6bkbkckckbjbjckckbjbjckckbjbjaududvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdL9EckckbjbjckckdFdFckckbjbjckckdMdMckckdNdNdOdPdQdRdS4u4u594u4u4u4u4s4s4u4udTdUdNdNbkbjbjbjdVdWdXdYdZd&e e0e1e2e3e4e5e6atauckckbjbjckcNbjbkbkbkdNe7e8e9eaebckckbjbjckckbjbjbkecedeeefegeheieje6bjbjekeldMcl",
-"ememenenememeoeoepeqerereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLbHbHeMeNeOePeQeReSeTeUeVeWeXeYeZe&f f0f1f1f2f3f4f5f6f7f8f9cTfaevfbfcerfdememeoeoemfeeoeoememfffgfhfifjfkflfmfnfofpfpfqfrfsftfufv6CfwfxfyfzfAeoeoememfBfBememeoeoememeoeoememeoeoememfCfDfmfmfmfEfmfmfFfGfHfHfmfIfJfKfdeofLfMfNfOfPfQfRfnfofofmfEfEfEfEfSfTfUfVc6ememfWfWememfXfYfZf&g g0g1g2g3g4ememememfVfVeoeog5g6g73Efmfmg8g9ga2Reoeoepepeoeo",
-"gbgbgcgcgbgberergdgegfggghgigjgkglgmgngogpgqgrgsgtgugvgwgxgygzgzbHbHgAgBgCgCgDgEgFgGgHgIgJgKgLgMgNgOf0f1gPf0gQgRgSgSgTgUgVf9gWfagXghgYgZgbgberergbgbererg&h h0h1h2h33E3E3E3Eh4h5h6h6h7h8h9ha3E3E3E3Ehbhchdhderergbgbhehegbgberergbgberergbgbererg&gbhfhghbfEhb3EfEhbhhhhfphifEhjhkhlererhmhnfOhodS3Eh4h5h4h43E3Ehbhb3E3Ehphqhrhsgbgbhthug&gbhvhwhxhyhzhhh4h4hAhBgbgbgbgbhshsererhChD3E3E3E3EhEhFhGhGererhHgderer",
-"hIhIhJhJhKhK0Z0ZhLhMhNhNhOhPgWhQhRhShThUhVhWhXhYhZh&i i0i1i2eLi3i4i4i5i6i7i8i9iaibeMicidieifigihbVdif1gPiigPijikiliminioipiq0R1biris0X1eithIhJhJiuhIhJhJiviwixdSdS3EiyiyiziAdSdSdSiBiCiBiDiEiFiGiHiIiJiKiLiMiNiOhIhIhJ0ZhIhIhJhJhIhIhJhJhIhIhJiPiQiR4ziSdSdSiB3EiTiTdSdSiUiViWiXiYiZi&j j0aoj1iTdSiBiKiBiVj2j3j4j5j6j7iKizj8j9jaivivjbjcjdjejfjgjhdSiViViViUjijjithIhJiPhIitjkjljmjniziziB6CjojphIhIhJhJhIhIhJhJ",
-"itit0Z0Zjqjr1e0vjsjtjujvjwjxjyjzjAjBjCjDhWjEjFjGjHjIi i0i1jJgzi3jKjLjMjNjOjPjQjRjSjTjUjVifjWjXjYbVdif1gPiiiijZj&k k0k1k2k3k4k51ak6k7k80Xk9it0Z0Zitit0Z0ZhLjskakb9v9vkckckdke9v9viLiLkffwkgkhkikjkkklkmkniLkokpkqitit0Z0Zitit0Z0ZhIit0Z0Zitit0Z0ZiQkriM9v9v9v9v9vksks9viLktkukvkwgZkxkykzfI9vkskA9viLiL5VkBkCkDkEkFkGkHkIkJkKkLkMkNkOkPkQkRkSkTksiJ9vkuktktktkUkVitit0Z0Zitk9kWkXkYiLkJkdkZkak&l ititl0l0itit0Z0Z",
-"l1l1l2l2l3l3l4l5l6l7l8l9lalblcldlelflglhliljlklllmlnloi0lplqgzi3bHlrlsltlulvlwlxlylzlAlBlClDlEbVbVdif1gPlFiilGlGlHlIlJlKlLlMlNlOkOlPlQl5lRl3lSlSlTl1l2l2l1l1lUlViLknknkblWlWiLknfllXlYlZl&m m0m0l1l1m1m2kbkbm3m4lTl1l2m0l1l1l2l2m5m5l2l2l1l1m6m6m7m8m9maknkbktktknknkbknknmbmcmdmemfhjflmgmalWmhmhmhmimjmkmll2l2l1l1mmmnmompmqmrmsmtmumvknknlWlWiLknkbkbkbkbmwmxl1l1l2l2mymzmAmBkbkbmamCmDmEl2l2l1l1l2l2l1l1l2l2",
-"l3l3m0l4lRmFmGmHmImJl9mKlbmLmMmNmOmPmQmRmSmTmUmVmWmXmYmZm&lqgzi3bHgzn n0n1n2n3n4n5n6n7n8n9nanbbVbVdif1f1lFiilGlGf0ncndlJnenfngnhninjnkmHmFlRnlnll1l3m0m0lRl3nmnnkfkfkfkfnonokfnpkfnqnrnsjshMm0l4lRlRntnukfnvnwnxl3l3m0l4lRl3l4m0nynyl4m0lRl3nznAnBnCnDnEkfkfnonFkfkfkfkfnpbenGnHnInJnpnpnEnDnonononKnLnMnNnNm0l4l3lRnOnPnQnRnSnTnUnVnvnvnpkfnWnoflkfkfnpnpnpnXnYl3l3m0l4eunZn&o npnpo0o1o2o3l4m0l3l3m0m0l3l3m0m0",
-"o4o4o5o6o7o8o9oaobocmKodoeofogohoiojokolomonooopoqorosotouovowoxbGeMoyozoAoBoCoCoDoEoFoGoHoIoJoJdidigPoKoLoMfG7k7koNoOoPoQoRoSoToUmKoVoWoXo8oYoZo4o4oYoZo6o5o&p jhjhjhp0jhjhjhp0p1p2oYoZp3o4oYoYp4p4p5p6jhp0p7p8oap9oYoYp9o7oYoYo4o4papao4o4pbjw4zpcp0jhpdpepepejhp0pfpgphpipjpkpl5Vp0p0jhjhp0p0pmpnpoppo4o40808o4o4pqprpsp0ptpupvpwp0p0jhp0p0jhpxjhjhp0p0jhpypzp3o4o4o4pApBpC5Vp0pDpEpFo4p3oZpGp4p4oYoYo4o4oYoY",
-"p3p3o6pHoXo9oWoVpIpJpKpLpMpNpOpPpQmSpRpSpTpUpVpWpXpYpZp&q q0q1oxbGeMq2q3q4oB9dq5q6q7q8q8q9q9qaqbdiqcgPoKoLoM7k4s4s4sqdqeoQqfqgqhqiqjqkoVoaoXqloZp3p3oZoZo6pHqmqn5a5ako5a5a5a5a5aqoqpoZoZp3p3oZoZqqqqqrqsjnjnqtquqvo7oZoZo8o7oZqlp3p3papap3qwqxqyqz5ajn5aqAqAqAqA5a5aqBqCqDqEqFqGqH5a5ajnjn5a5aqIqJqKqLqLp3qw0s0sp3p3qMqNqOjnqPqQqRkwjnjn5a5ajn5ako5ajn5ajn5aqSqTp3p3p3qUqVqW5ajniSqXqYqZp3p3oZoZqqqqoZoZp3p3oZoZ",
-"q&q&r r0r1r2r3r4r5r6r7r8r9rarbrcrdrerfrgrhrikYrjrkrlrmrnrorprqrreMeMrsoCoC9drtrtrurvrw9&rxryrzrArBrCgPoKiiii4t4s4v4vrDrErFrGrHrIrJrKrLrMrNrOr0r0q&q&r r0q&q&rPrQrRrRrRrRrRrRrRrSrTrUr0r q&rVr0r q&rWrXrYrZrRrRr&s pHr r s0s0s1s1s2s3s4s4q&q&s5s6s7s8rRrRrZrRrRrRrRrZs9sasbscsdserZrRrRrRrRrZrRsfsgshr0r q&rVsisjq&q&skslrmrRsmsnsospsqsrrRrRrRrRrRjnrRrZssstsusvq&q&swsxqOrZs8syszsAr r0q&q&r r0q&q&r r q&q&r r ",
-"rVrVsBsBsCsDsEsFsGsHsIsJsKsLsMrcsNsOsPsQrhsRrSsSsTsUsVsWsXsYsZs&eMeNt oCoC9drtrtt0t1t2t3t4t5t6t7t8t9f1oKiiii4t4s4v4vtatbtctdtetftgthtitjtkrNtlsBrVrVr0sBtmrVcctnfIfItofIfIfIfItptqtrr0r0rVtmr0r0rVq&tsttlXlXtotutvtwr0r0txtytztAtBtCtDtErVrVtFtGsysyfIfIlXfIfIfIlXfItHtIsctJtKtLfIfIfIfIfIfItMtNtOscsBsBtmrVsjsjtmrVtPtQtRpDtStTtUtVtWtXfIfItofItofIfIlXtYtYsutZrVrVt&u iSlXsyu0u1u2sBsBrVrVr0r0rVrVr0r0rVrVr0r0",
-"u3u3u4u5u5u6u7u8u9uaubucudueufuguhuipciCujukulumunuoupuqurusutuueMeNuvuwuwuxuyuzuAuBuCuDuEuFuGuHuIuJgFuKlGlG584t4s4tuLuMuNuOuPuQuRrJuSuTuUuVuWuWu3u3uXuXuYuZu&v iSiSiSv0v1v1v2v3v4sBuXu4u3u3uXuXv5v6jmv7v0v0v8v9vavbvcvdvevfvgvhvivjvkvlvmvnvoqHvpvqiSiSiSiSiSiSiSvrvsvtvuvvvjv0iSiSiSv0v0v0vwvxuZuZuXuXu3u3uXuXvyrOvzvAvqvBvCvDvEu3vFvGhcv0vqvqvHiSvIvIv0v0qSvJk6vKvLvMvpvpvNvOvPvavQvQvRu3vSuXu3u3uXuXu3u3uXuX",
-"vTvTvUu6vVvWvXvYvZv&w w0udw1w2uguhw32&w4w5w6w7w8w9vBwawbwcwd9cuueNeNuwuxuwwegzwfwgwgwhwiwjwkwlwmwnwowpwqwrws584s4t4twtwuwvwwwxwywzwAwBuSwCuUwDwEwFvTvUu5wGwGwHv pCpCpCwIwJwKwLwMwNwNu5vUvTvTu5u5wOwPwQwIwIwIwRwSuWwTwUwVwWwXwIwIpDwYwZw&x vsx0pCx1x2pCpCpCpCpCwIulx3x4x5x6x7x8wIpCpCpCwIpDpCx9xawGxbu5u5vTvEu5u5xcxdxexfqCxgxhxiwFvTxjxkxlpCx1x1pCpCxmxnwIwIxoxpxqxrxsx1x1xtxuxvuWuWxwxwvTvTu5u5vTvTu5u5vTvTu5u5",
-"xxxxxyxzxAxBxCxDxExFxGxHxIxJxKxLxMxNxOw7xPx8xQwQxRxSxTxUxVxWxXgAeMeNxYlqxZx&y y y0y0y1y2y3y4y5y6y7y8y9yaybycydydyeyfygyhyiyjykylymynyoypyqyrysytyuxxyvyvywyxyyyzqHqHqHyAyAqHtGyBxxxxxxxxxxxxyCyCyDyEyAyAyAyAyFyGyHyIyJqIyKyLyMyNyOyPyQyRySyTyAyAqHqHqHqHqHqHyUyVyWnGxyxyyXyYyZqHqHqHqHyAyAqHy&ccz z0yvyvxxxxyCyCz1eez2z3z4z5yvyvz6z7xbz8z9zazbyKqHzcqHyAyAyAkUzdzezfqHqHzgzhziwExbxbzjzjxxxxyvyvxxxxyvyvxxxxyvyv",
-"zkzkytysxBzlzmznzozpzqzrzsztzuzvzwzxzyx0xOzy6CuqzzzA4xujzBzCgAgAi2zDt7zEzFzFzGrczHzIzJzKzLzMzNzNzOzPzQzRzSzTzUoAzVzWzXzXzYzZz&y7A ynA0A1yqxCA2A3A4zkxzxzA5A5A6A7A8A8A8yZyZA8A9AazkzkzkyuzkzkwDAbAcAdyZyZA8yZAeAfAgAhyZyZAiAjwSAkAlAmAnAoApAqiCA8A8A8A8A8yZA8ArjfAsAtytxzAuAvyZyZA8A8A8A8yZyZAwAxAyAyytytA4A4AzAAABACo0ADAEAFytytAGAHAIAIAJz9AKqCA8A8A8yZyZyZALAMANAOiCwYAPAQAzwDAIAIARARyuzkxzxzzkzkxzxzzkzkxzxz",
-"ASATAUAVAWAXAYAZA&B B0B1B2B3B4B5lkB6B7B8B9BaBbBcBdBeBfBgBhBhBiBjBkBlBmBmBnBnBoBpBqBrBsBtBuBvvvBwBxByBzBABBBCBDBEBFBGBFBHBIBJBKwxBLtDBMBNBOBPBQBRAUBSBSBSATATBTBUBVBVBWBWBXBYBZB&AHAGC C ATATC0C1C2C3C4C5BXcqC6C7C8C9BWBXCaCbCcCdCeCfCgChCiBXBXBWs7CjBXBXBXCkClCmASCnAUBSCoCpC4C3tRBWBWBXBWBXCqCrAzAzBSAUCsu7fNCtCuCvCwCxCyCzBSBSATATBSAUCACBCCCDBWBWBXBXBXBXCECFCGCvCHCICJCsAUBSATATCKCKASATBSBSATATBSBSATATBSBS",
-"CnCnAVAWCLAXAYAZCMB CNB1COCPCQCRCSCTCUCVCWCXCYCZC&D uuD0D1D2D3D4D5D5D6D7D8D96&DaDbDcDdDeDfDgDhDiDjDkDlDmDnzQDoDpDqDrDsDtDuDvDwDxDyDzDABNDBBPBQBRAUAUAUAUCnCnDCDDujujpcj7j7upDEDFDGDGDHDHDICnDJDKDLoqDMoqpcfwDNDODPDQj7pcDRDSDTDUDVDWDXDYj7j7j7mbDZujj7j7D&E E0E1CnCnAVAUE2E3DMDMmbj7j7pcj7j7E4E5E6E7AUAUCsE8E9EaEbEcEdEeCzvWAVAUCnCnAVAUEfEfEgEhvhj7j7pcpcpcEifsEbEjEkElCsCsAUAUDICnEmEmCnCnAUAUCnCnAUAUCnCnAUAU",
-"EnEnEoEpEpEqErEsEtEuEvEwExEyEzEAEBECEDEEEFEGgzd4lpEHEIEJEKELEMENEOB5EPEQERESETEUEVEWEXEYEZE&F F0F0F1F2F3F4F5F6F7F8F9FaFbFcFdFeFfFgFhFiFjFkFlEpEpFmEnFnEoFoFpFqFrrjkYmCmCkYFsFtFuFvEnFnFnFwFxFyFzkYrSkYkYkYFAFBzlFCFDFEFEulFFFGFHpsFIkYrSmCFEFJFKkYkYFLFMFNFOFnEoEnEnFnFn0FFPFQFJkYrjkYkYrSkYFRFSFTFUFVFWFXFYkZrSFZqDF&xCFmEnFnFnG G G0G1EnEnFoG2zhG3rSkYG4G5psG6kYfxG7uTFmEnFnFnG8G8FnFnEnEnFnFnEnEnFnFnEnEnFnFn",
-"FmFmEoEpEqG9GaGbEtEuEvGcGdGeGfGgGhx&GiGjGkGkGlGmEHEHGnGoGpGpGqGrGsGtGuGvGwGxGyGzGAGBGCGDGEGFGGGHGGGHGIGJGKGLGMGNGOGPGQGRGSqfGTGUGVGWGXGYFkGZEqEpFmFmEoEoFoG&ix2&H 2&H0H0H1ixH2H3FmFmEoEoFwH4H5H02&H12&2&kIkHH6H7H8H9HaHaH1H12&H12&2&2&2&H0H0HbHc2&HdHeHfHgHhEpEoHiFmEoEoHjHkHlHc2&2&2&H12&H1HmHmHnHoHpHqHrHsFIHtHuHvzmyqHiFmEoEoHwHxHyHyFmFmFoHzHAHBum2&yVyVHC2&fvFqHDu9HiFmEoEoHEHEEoEoFmFmEoEoFmFmEoEoFmFmEoEo",
-"HFHFHGHHHIHJHKHLFiHMHNFgHOHPHQHRHSHTHUHVrzloi i0HWHXxZHYHZH&I I0I1I2I3I4I5I6FeI7I8I9IaIbIcIdIeIeIfIfIdFgIgIhIiIjIkIlIlIkImInIoIpHMIqIrIsItIuIvHHIwIwHGHHIxIyIzIAIBIBIBIAICcsHGHHIwIwHGHGIDtQaoulIEIFIGIHIIIJHGHHtVIKILulwYwYIAIAwYwYIMIMwYulwYINyIIOIPIQIwIwHGHGIwIwHGHGHGIRISITFIulIBIBwYwYululwYwYulwYIUIVIKIWIXEqHGHGIwIwHFHFIwIwHiIYIwIwIZI&J J0J1J2wYulwYrmJ3J4HGHGIwIwHGJ5J6J6HGHGIwIwHGHGIwIwHGHGIwIwHGHG",
-"J7J7IvIuJ8J9JaHLJbJcGVFgJdJeJfJgJhJiHVHVrzloi i0HWHXJjJkCQJlJmJnJoJpJqJrJsJtJuJvJwJxEwJyJzJAJBJBJCJDJAJzJEJFGGJGJHJIJJJKJLJMIpJNJcIqIrJaItIuIuIvHIHIIvIvJOJPJQJRJSJRJRJRJTh8IvIvHIHIIvIvJUJVJWJXJYJZJ&K K0K1IvIvsoK2K3K4K5CkJRJSCkkZK6K7fwyJK8kHK9KaKbKbJ8HIIvIvHIHIIvIvIuIvKcKdKeupKfJRkZkZkZkZCkCkD&HtKgKhKiKjG9KkIvIvHIHIJ7J7HIHIGZGZHIHIKlKlKmKmKnKoCkkZKpKqKrKsIvHHHIHIIvIvKtKtIvIvHIHIIvIvHIHIIvIvHIHIIvIv",
-"KuKuKvKwKxKyKzKAKBKCKDKEKFKGKHKIKJKKHVryKLKMi i0lplpKNKOKPKQKRKSKTKUKVKWKXKYKZK&L L0L1L2L3L4L5L5L6L7L8L9LaLbLcLdL0L LeLfKELgL2LhLiLjLkKzLlLmLnKvLoLoKvKvLpLqLrLsLtLuLvLwLxLyLnKvKuKuKvKvLzLALBLCLDKxKvKvLmKuKvKvKuKuLELFLGLHLILJLKqGLLtQLMLNLOLPKuKuLQKxKuKuLRLRKuKuKvKvKuKuKxLSLTFNLULVLWLXLYEeLZL&M M0M1M2KvKvKuKuKxKxM3M3KxKxM3M4KvKvKuKuKvKvM5M5M6M7KpKpM8kyKuKuKvKvKuKuKvKvKuKuKvKvKuKuM9M9KuKuKvKvKuKuKvKv",
-"KuKuKvKvLQKyKzKAKBMaMbKEMcMdMeMfMgMhHVryKLKLi i0lpMiMjMkMlMmMnMoMpMqMrMsMtMuMvMwMxMyMzLhMAMBMCMCMDMEMFL5MGMHMbMIMJMyMKMLLgMbLhMMLjLkMNKzLmLmKvKvMOLoKvKvMPMQMRMSMTMUMVMWMXMYKvLnKuKuKvKvMZMZLPLPLQLQLnKvKuKuKvKvKuKuM&M&N N0N1N2N3qFN4N5nhnhLPN6LmKuKxKxKuLmLRLRKuKuKvKvLmKuKxKxN7N7N8N9NaNbNcNdNeNfNgNgNhM2LnKvKuKuKxKxM3M3KxKxM3M3KvKvKuKuKvKvM5NiNjNkw8hjNlNmLmKuKvKvKuKuKvKvKuKuKvKvKuKuM9M9KuKuKvKvKuKuKvKv",
-"NnNnNnNoNpNpNqNrNsNtNuNvNwNxNyNzNABmHVryNBi NCNCeKgzNDNENFNGNHNINJNKNLNMNNNONPNQNRNSNTNUNVNWNXNYNZN&O O0O1O2NTO3O4O4O5O6O6O7NtO1NWO8NYO9NpNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnOaOaNnNnNnNoNnNnNnNnNpNpNnNpObObObObOcOdNnNnNpNnOcOdNnNoNnNnNnNnNpNnNpNnNnNnNnNnNpNnOeOfNpNnNnNnNnNnNnNoNnNpNnNnNpNnNpNnOdOdNnNnNnNnNnNnmLOgOhOiOjOkOlOmOnOnOoOpbdOqOrOsOtOuOdOdNnNpNnNnNnNnObObNnNnNnNnNnNnNnNnNnNnNnNnNnNn",
-"OvOvOvOvOvO8OwOxO2OyNuNvK&OzOAOBOCODOEOFNBi NCNCeKeLOGOHOIOJOKOLOMONOOOPNOLCNQOQORNSNTNUOSNVOTOTOUOUO0OVO2NtNTNTOWO4O6O3O3O7NtO2OSNVNXNYOvOvOvOvOvOvOvOvOvOvOvO8O8OvOvOvOvO8OvOvOvOvOXOXOvNpOvOvOvOvOvOvOvOvOvOvNYO9NYO9OYOYOvO8OvOvOYNZO8OvO8OvOvOvO8OvOvOvOvOvOvOvOvOvOZOZOvOvOvOvO8OvOvO8OvOvOvOvOvOvOvOvOYOYOvOvO8O8O8OvO&P P02gP1P2P3P4P5P6P7P8up3 P9PaPbPbOYOYOvOvOvOvOvOvO9O9OvOvOvOvOvOvOvOvOvOvOvOvOvOv",
-"PcPcPdPdPePePfPgPhPiPjPkPlPmPnPoPpPqrdPrNBi i0i0HXHXPsPtPuPvPwPxPyNLPzPAPBPCPDPEPFPGPHPhPIPIPfPfPJPJPgPgPhPHPHPHPKPLPMPMPFPGPNPOPIPPPgPdPePePdPdPJPePfPdPePQPdPdPePJPdPdPePePdPfPQPePRPRPJPePdPdPePePdPdPPPSPTPdPUPUPdPdPVPVPPPVPePePVPVPePePdPfPcPcPRPRPePePdPdPePePdPdPePePdPdPePePWPRPePePdPdPePePdPdPePePdPdPePePRPWPXPYFqPZrnP&vhQ Q0Q1Q2Q3Q4Q5Q6Q7Q8Q9PfPdPePePdPdPePePdPdPePePVPVQaQaPdPdPePePdPdPePePdPd",
-"QbQbPgPgQcQcPgPOPHQdPjQePlQfQgQhQiQjQkQli i i0lpHXd4QmQnQoQpQqQrQsQtQuQvQwQxPEQyPGQzQAPhPhPhPOPOQBQBPgPOPhPhPHPHQCQCQDQEQzQzPNPOPhPhPgPgPJQcPgPgQcQcPgPgQcQcPOPgQcQcPOPgQcQcPgPOQcQcQFQFPJQcPgPgQcQcPgPgPIPIPgPgPUQGPfPgPIPIPIPIQcQcPIPIQBQcPgPgQHQbQFQFQcQcPgPgQcQcPgPgPJQcPgPgQcQBQFQFQBQcPgPOQcQcPgPfQcQcPgPgQcQcQFQFQIQJQKpsQLplqOpsQMQNQ3QOQPQQQRQSQTMaPOPgQcQcPgPgQcQcPfPgQcQcPIPIQUQUPgPgQcQcPgPgQcQcPgPg",
-"QUQUQUQUQUQUQVQVQAQdQWQXQYQZQ&R R0R1R2R3NBi i0lpeLeKBmR4R5R6R7R8QfR9RaRbRcRdPiQAReReQVQVQUQURfRfQUQUQUQUQVQVReReReRePNPNReQVQVQVQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQURgRgQUQUPJQcQVQVRhRiRjQPRkRlRmRnRoRpRqRrRsRtRuMAQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQU",
-"QUQUQUQURvQUQUQVPHPiQWRwRxRyRzRARBRCRDREi i i0lpeLeKRFRGRHR6RIRJRKRLRMRNROQdQAPHQVQUQUQUQUQURfRfQUQUQUQUQUQUQUQUQVQVPOPOQVQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQURgRgQUQUQcQcQVQURPRQRRQPRSRTRURVRWRXRrRYRZR&MAL4QUQUQURvQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQU",
-"PgPgPgPgPgPgPgPOPHPiS S0S1S2S3S4S5S6S7S8OFS9SaSbScKKSdSeSfSgShSiSjSkSlSmSnSoPNPOPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPfPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgQUQUPOPgPgPgSpSqRrpsSrSsStSuSvpsSwSxSyMMPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPg",
-"PgPgPgPgPfPgPgPgPHQAS SzSASBSCS4SDSESFSGSHSISJSKSLSMSNSOSPSgSQSRSSSTSUSVSoSWPOPOPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgQUQUPfPgPgPgRhSXSYpsSZSZS&SZpsiMT T0MMT1PgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPg",
-"POPOPOPOPOPOPOPOPNSWQyT2RbT3T4T5T6T7T8T9TaugTbTcTdTdTeTfTgThTiTjTkTlTmSVTnToPNPOTpTpQVQVPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPNPOTqTrTsTtTuTvdUTwTxTyTzTAPOPNPOPOPNPNPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPO",
-"POPOPOPOPOPOPOPOPNSWTBTCRNTDTETFTGTHTITJTKTKTLTLTMTNTOTPTQTRTSTTPzTUTmSVTVToPNPOTpTpQVQVPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOTWTqTXTYRTTZT&U U0U1TAU2POPOPOPOPNPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPO",
-"U3U3U3U3U3U3U4U4U5U6U7U8TmU9UaUbUcUdUeUfUgT9UhSdUiUjI1UkUlUmUnUoUpRMUqUrTVToU5U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U5U3U3U3U5U3UsU7U3U3U3U3U3U3TpUtU3UuU3U3U3UuU3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4",
-"U5U5U5U5U5U5UvUvU5UwU7U8SmUxSTUyUzUAUBUCUDUEUFUGUHUIUJUKULUMUNUOUPUQURUrTVToU5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U3U5U5U5UwUwUwU5USUSUwU5U5UwUwU5UtUtU5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUv",
-"UTUTUTUTUTUTUTUTUTUUUVUWUXUYUZU&V V0V1V2V3V4V5V6V7V8V9VaVbVcVdVeVfVgUXVhViUUUTUTVjVjUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTVkVkVlVlU3U3UTUTVlVlVmVmUTUTVkVkUTUTVlVlUTUTUTUTUTUTVjVjUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUT",
-"UUUUUUUUUUUUUUUUUUVnVoUWUXVpVqVrVsV VtVuVvVwVxVxVyVzVAVBVCVDVEVFVGVHUXVhViVnUTUUVIVIUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUVJVJUsUsU5U5UUUUUsUsVKVKUUUUVJVJUUUUUsUsUUUUUUUUUUUUVIVIUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU",
-"KCKCMGMGMGMGMGMGKCKCMHLaVLVMVNLdVOVPVQVRVSVTIjVUVVVWVXVYVZV&W W0LcLgLaL3W1KCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGW2W2MGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMG",
-"W3W4W5W5W4W5W3W6W6W7W8W9WaWbWcWdWeWfWgWhWiWjWkWlWmWnWoWpWqWrWsWtWuWvWwWxWyWzWAWBWCWDWEWFWGWHWIWJWKWLWMWNWOWPWQWRWSWTWUWVWWWXWYWZW&X X0X1X2X3X4X5X6X7X8X9XaXbXcXdXeXfXgXhXiXjXkXlXmXnXoXpXqXrXsXsXtXtXuXtXvXvXvXuXuXuXwXxXyXzXAXBXCXDXEXEXFXGXHXIXJXKXLXMXNXOXPXQXRXSXTXUXVXWXXXYXZX&Y Y0Y1Y2Y3Y4Y5Y6Y7Y8Y9YaYbYcYdYeYfYgYhYiYjYkYlYmYnYoYpYqYrYsYtYuYvYwYxYyYzYAYBYCYDYEYFYGYHYIYJYKYLYMYNYOYPYQYRYRYSYTYTYUYUYV"};
-
+/* XPM */
+static const char *AboutBox_WxStaticBitmap1_XPM[]={
+/* AboutBox_WxStaticBitmap1 */
+"200 60 3963 2",
+" c None",
+" 0 c #98CAFD",
+" 1 c #99CBFC",
+" 2 c #97C9FC",
+" 3 c #96C8F9",
+" 4 c #95C7F8",
+" 5 c #94C6F7",
+" 6 c #93C5F6",
+" 7 c #92C2F2",
+" 8 c #91C1F1",
+" 9 c #91C0EC",
+" a c #8DBCE8",
+" b c #8BB6E3",
+" c c #81ACD9",
+" d c #707CA6",
+" e c #B1BDE7",
+" f c #BCCAEF",
+" g c #526085",
+" h c #6E98C2",
+" i c #8BB5DF",
+" j c #90C0F0",
+" k c #93C5F8",
+" l c #94C6F9",
+" m c #97C9FA",
+" n c #99CBFE",
+" o c #9ACAFB",
+" p c #9ACCFD",
+" q c #9ACCFF",
+" r c #92C4F5",
+" s c #8EBDE9",
+" t c #8CB7E4",
+" u c #79A4D1",
+" v c #6F7BA5",
+" w c #D7E3FF",
+" x c #8E9CC1",
+" y c #58668B",
+" z c #6B95BF",
+" A c #8AB4DE",
+" B c #95C5F5",
+" C c #95C7FA",
+" D c #9BCDFE",
+" E c #9BCDFF",
+" F c #9CCCFD",
+" G c #A0D1FC",
+" H c #A1D0FC",
+" I c #A0D0FE",
+" J c #9FCFFD",
+" K c #9FCEFA",
+" L c #9ECDF9",
+" M c #9CCBF5",
+" N c #9BCAF4",
+" O c #9AC7F1",
+" P c #97C4EE",
+" Q c #94BFE9",
+" R c #93BEE8",
+" S c #91BBE3",
+" T c #8BB5DD",
+" U c #8EA2D5",
+" V c #6F83B6",
+" W c #B7BDDF",
+" X c #BDC3E5",
+" Y c #556B90",
+" Z c #61779C",
+" & c #779FC2",
+"0 c #91B9DC",
+"00 c #97C4ED",
+"01 c #9AC7F0",
+"02 c #9DC9F6",
+"03 c #A0CCF9",
+"04 c #9ECFFA",
+"05 c #9FD0FB",
+"06 c #A0D1FA",
+"07 c #A1D0FE",
+"08 c #A2D3FE",
+"09 c #A3D2FE",
+"0a c #A1D1FF",
+"0b c #9DCCF6",
+"0c c #9AC9F3",
+"0d c #96C3ED",
+"0e c #91BCE6",
+"0f c #89B3DB",
+"0g c #78A2CA",
+"0h c #7488BB",
+"0i c #99ADE0",
+"0j c #C7CDEF",
+"0k c #6D7395",
+"0l c #546A8F",
+"0m c #748AAF",
+"0n c #85ADD0",
+"0o c #96BEE1",
+"0p c #99C6EF",
+"0q c #9BC8F1",
+"0r c #A1CDFA",
+"0s c #A1D2FD",
+"0t c #A2D3FC",
+"0u c #A3D2FF",
+"0v c #A6D6FC",
+"0w c #A8D5FC",
+"0x c #A7D4FB",
+"0y c #A6D3FA",
+"0z c #A5D2F9",
+"0A c #A4D0F7",
+"0B c #A2CEF5",
+"0C c #A0CCF1",
+"0D c #9DC9EE",
+"0E c #9CC4E8",
+"0F c #99C1E5",
+"0G c #99BDE1",
+"0H c #89ADD1",
+"0I c #8094C6",
+"0J c #798DBF",
+"0K c #9EAAD4",
+"0L c #AFBBE5",
+"0M c #617598",
+"0N c #53678A",
+"0O c #6689A7",
+"0P c #80A3C1",
+"0Q c #8FBADD",
+"0R c #99C4E7",
+"0S c #9CC8ED",
+"0T c #9FCBF0",
+"0U c #A2CFF6",
+"0V c #A3D0F7",
+"0W c #A8D5FE",
+"0X c #A5D5FB",
+"0Y c #A9D5FC",
+"0Z c #A8D8FE",
+"0& c #AAD7FE",
+"1 c #A9D6FD",
+"10 c #85A9CD",
+"11 c #7094B8",
+"12 c #7F93C5",
+"13 c #97ABDD",
+"14 c #9DA9D3",
+"15 c #64709A",
+"16 c #54688B",
+"17 c #7185A8",
+"18 c #7FA2C0",
+"19 c #94B7D5",
+"1a c #98C3E6",
+"1b c #9DC8EB",
+"1c c #A2CEF3",
+"1d c #AAD7FF",
+"1e c #A7D7FD",
+"1f c #ABD7FE",
+"1g c #AED9FB",
+"1h c #AED9FC",
+"1i c #ADD8FA",
+"1j c #ACD7FA",
+"1k c #ABD6F9",
+"1l c #AAD5F7",
+"1m c #A7D2F4",
+"1n c #A7D0F0",
+"1o c #A5CEEE",
+"1p c #A2C9E8",
+"1q c #9FC6E5",
+"1r c #9DBAE2",
+"1s c #84A1C9",
+"1t c #7586BC",
+"1u c #899AD0",
+"1v c #95A3D2",
+"1w c #8593C2",
+"1x c #586D8A",
+"1y c #5A6F8C",
+"1z c #6B8BA4",
+"1A c #82A2BB",
+"1B c #91B8D7",
+"1C c #9AC1E0",
+"1D c #9EC7E7",
+"1E c #A1CAEA",
+"1F c #A8D3F5",
+"1G c #ABD6F8",
+"1H c #ACD7F9",
+"1I c #ADD8FB",
+"1J c #B0D8FB",
+"1K c #AED8FE",
+"1L c #707D86",
+"1M c #3D4A53",
+"1N c #798B99",
+"1O c #B6C8D6",
+"1P c #B8D6EE",
+"1Q c #B1D8F9",
+"1R c #AFDAFC",
+"1S c #B1DCFE",
+"1T c #B1DCFF",
+"1U c #B0DBFD",
+"1V c #AFDAFD",
+"1W c #A6CFEF",
+"1X c #A3CCEC",
+"1Y c #A0C7E6",
+"1Z c #96BDDC",
+"1& c #86A3CB",
+"2 c #83A0C8",
+"20 c #8C9DD3",
+"21 c #8A9BD1",
+"22 c #7280AF",
+"23 c #5A6897",
+"24 c #647996",
+"25 c #7B90AD",
+"26 c #89A9C2",
+"27 c #9ABAD3",
+"28 c #9CC3E2",
+"29 c #A1C8E7",
+"2a c #A2CBEB",
+"2b c #A9D2F2",
+"2c c #B0DBFE",
+"2d c #B3DBFE",
+"2e c #B1DBFF",
+"2f c #2D3A43",
+"2g c #606D76",
+"2h c #3F515F",
+"2i c #000F1D",
+"2j c #1E3C54",
+"2k c #537189",
+"2l c #7DA4C5",
+"2m c #AED5F6",
+"2n c #B6DFFB",
+"2o c #B6DFFD",
+"2p c #B5DEFA",
+"2q c #B4DDF9",
+"2r c #B4DBFC",
+"2s c #AED5F2",
+"2t c #AAD1EE",
+"2u c #A8CDE8",
+"2v c #A4C9E4",
+"2w c #9BB4DD",
+"2x c #849DC6",
+"2y c #8C9CD8",
+"2z c #93A3DF",
+"2A c #8497BF",
+"2B c #6679A1",
+"2C c #5C758B",
+"2D c #6F889E",
+"2E c #7C9FB5",
+"2F c #8FB2C8",
+"2G c #9ABED8",
+"2H c #A2C6E0",
+"2I c #A4C9E3",
+"2J c #A7CCE6",
+"2K c #A8D0EA",
+"2L c #A9D1EB",
+"2M c #ABD3ED",
+"2N c #ADD5EF",
+"2O c #B0D7F4",
+"2P c #B0D9F5",
+"2Q c #B2DBF7",
+"2R c #B3DAF9",
+"2S c #B7E0FE",
+"2T c #B7DEFB",
+"2U c #B6DFFF",
+"2V c #B7E0FF",
+"2W c #3D4547",
+"2X c #A5ADAF",
+"2Y c #F8F8F6",
+"2Z c #F1F1EF",
+"2& c #B8B8B8",
+"3 c #797979",
+"30 c #3E3E3E",
+"31 c #090909",
+"32 c #272F32",
+"33 c #50585B",
+"34 c #788691",
+"35 c #A8B6C1",
+"36 c #C1DCED",
+"37 c #B9DEF9",
+"38 c #B7DEFD",
+"39 c #B8E1FD",
+"3a c #B8E1FF",
+"3b c #B7E0FC",
+"3c c #B5DCFD",
+"3d c #B2D9FA",
+"3e c #A6CBE6",
+"3f c #9ABFDA",
+"3g c #859EC7",
+"3h c #8BA4CD",
+"3i c #98A8E4",
+"3j c #8191CD",
+"3k c #60739B",
+"3l c #63769E",
+"3m c #7891A7",
+"3n c #8CA5BB",
+"3o c #95B8CE",
+"3p c #9EC1D7",
+"3q c #A3C7E1",
+"3r c #A6CAE4",
+"3s c #A9CEE8",
+"3t c #AAD2EC",
+"3u c #ACD4EE",
+"3v c #B1DAF6",
+"3w c #B4DBFA",
+"3x c #B8DFFC",
+"3y c #BAE1FE",
+"3z c #464E50",
+"3A c #9EA6A8",
+"3B c #FDFDFB",
+"3C c #FCFCFA",
+"3D c #FDFDFD",
+"3E c #F9F9F9",
+"3F c #C5CDD0",
+"3G c #929A9D",
+"3H c #56646F",
+"3I c #192732",
+"3J c #052031",
+"3K c #405B6C",
+"3L c #779CB7",
+"3M c #BCE1FC",
+"3N c #B9E0FF",
+"3O c #B8DFFE",
+"3P c #BCE5FB",
+"3Q c #BCE4FD",
+"3R c #BBE5FD",
+"3S c #BEE4FB",
+"3T c #BBE4FA",
+"3U c #B9E2F8",
+"3V c #B8DEF5",
+"3W c #B5DBF2",
+"3X c #B1D5EB",
+"3Y c #ABCFE5",
+"3Z c #A4C0E7",
+"3& c #88A4CB",
+"4 c #91A4DF",
+"40 c #A1B4EF",
+"41 c #8391B6",
+"42 c #637196",
+"43 c #647F90",
+"44 c #7D98A9",
+"45 c #8FAFC4",
+"46 c #9BBBD0",
+"47 c #A1C4D8",
+"48 c #A6C9DD",
+"49 c #A8CBE1",
+"4a c #AACDE3",
+"4b c #ABD1E6",
+"4c c #ADD3E8",
+"4d c #AED3E6",
+"4e c #B0D5E8",
+"4f c #B1D5ED",
+"4g c #B2D6EE",
+"4h c #B3D7EF",
+"4i c #B5D9F1",
+"4j c #B6DCF3",
+"4k c #B8DEF3",
+"4l c #B9DFF4",
+"4m c #BBE0FA",
+"4n c #BCE1FB",
+"4o c #BAE3F9",
+"4p c #BEE3FD",
+"4q c #4B5356",
+"4r c #9DA5A8",
+"4s c #FEFFFF",
+"4t c #FDFFFE",
+"4u c #FFFFFF",
+"4v c #FEFEFE",
+"4w c #DFDFE1",
+"4x c #969698",
+"4y c #454545",
+"4z c #030303",
+"4A c #526875",
+"4B c #C8DEEB",
+"4C c #BBE3FC",
+"4D c #BEE7FD",
+"4E c #BEE6FF",
+"4F c #BDE7FF",
+"4G c #C0E6FD",
+"4H c #BAE0F7",
+"4I c #B2D6EC",
+"4J c #A9CDE3",
+"4K c #97B3DA",
+"4L c #8CA8CF",
+"4M c #AABDF8",
+"4N c #899CD7",
+"4O c #627095",
+"4P c #6A789D",
+"4Q c #93AEBF",
+"4R c #A1C1D6",
+"4S c #A3C6DA",
+"4T c #A7CAE0",
+"4U c #A9CCE2",
+"4V c #A8CCE2",
+"4W c #A9CFE4",
+"4X c #AAD0E5",
+"4Y c #ACD1E4",
+"4Z c #AED2EA",
+"4& c #ADD1E9",
+"5 c #AFD3EB",
+"50 c #B3D9F0",
+"51 c #B4DAF1",
+"52 c #B5DBF0",
+"53 c #BFE5FC",
+"54 c #BDE6FC",
+"55 c #C0E5FF",
+"56 c #495154",
+"57 c #9EA6A9",
+"58 c #FCFEFD",
+"59 c #FEFEFF",
+"5a c #E7E7E7",
+"5b c #182E3B",
+"5c c #8197A4",
+"5d c #BDE5FE",
+"5e c #C2E8FD",
+"5f c #C3E7FF",
+"5g c #C3E9FE",
+"5h c #C2E6FE",
+"5i c #C1E5FB",
+"5j c #BEE2F8",
+"5k c #BCDFF5",
+"5l c #B7DAF0",
+"5m c #B4D4EB",
+"5n c #A6C6DD",
+"5o c #90A5DE",
+"5p c #A5BAF3",
+"5q c #A4B6E4",
+"5r c #6577A5",
+"5s c #647786",
+"5t c #8093A2",
+"5u c #8DAABA",
+"5v c #9CB9C9",
+"5w c #9FBED0",
+"5x c #A2C1D3",
+"5y c #A5C6D9",
+"5z c #A6C7DA",
+"5A c #A9CADD",
+"5B c #A8C9DC",
+"5C c #AAC9DE",
+"5D c #ABCADF",
+"5E c #AEC7E6",
+"5F c #ADC8E6",
+"5G c #AEC9E7",
+"5H c #ADCCE0",
+"5I c #B0CFE3",
+"5J c #B2D2E7",
+"5K c #B6D6EB",
+"5L c #B5DAEC",
+"5M c #B8DDEF",
+"5N c #B9DDF3",
+"5O c #BCE0F6",
+"5P c #C1E5FD",
+"5Q c #C2E8FB",
+"5R c #C1E7FC",
+"5S c #C4E8FF",
+"5T c #454A4E",
+"5U c #A9AEB2",
+"5V c #E9E9E9",
+"5W c #000D1A",
+"5X c #C4DAE7",
+"5Y c #C4E6FF",
+"5Z c #C3E5FE",
+"5& c #C0E4FC",
+"6 c #BFE3F9",
+"60 c #BADDF3",
+"61 c #B5D8EE",
+"62 c #B1D1E8",
+"63 c #96B6CD",
+"64 c #94A9E2",
+"65 c #BDD2FF",
+"66 c #8092C0",
+"67 c #5E709E",
+"68 c #728594",
+"69 c #8C9FAE",
+"6a c #92AFBF",
+"6b c #99B6C6",
+"6c c #9AB9CB",
+"6d c #9CBBCD",
+"6e c #9EBFD2",
+"6f c #9FC0D3",
+"6g c #9DBED1",
+"6h c #96B5CA",
+"6i c #89A8BD",
+"6j c #7891B0",
+"6k c #6E87A6",
+"6l c #6E89A7",
+"6m c #809BB9",
+"6n c #94B3C7",
+"6o c #A3C2D6",
+"6p c #A8C8DD",
+"6q c #ADCDE2",
+"6r c #AED3E5",
+"6s c #B1D6E8",
+"6t c #B4D8EE",
+"6u c #B7DBF1",
+"6v c #BADEF4",
+"6w c #BEE2FA",
+"6x c #C0E6FB",
+"6y c #C1E7FA",
+"6z c #C2E6FF",
+"6A c #393E42",
+"6B c #B6BBBF",
+"6C c #8D8D8D",
+"6D c #415764",
+"6E c #CDE3F0",
+"6F c #C2E4FD",
+"6G c #BCE6FE",
+"6H c #BCE2F9",
+"6I c #B9DFF6",
+"6J c #B7DBF3",
+"6K c #AFCDF3",
+"6L c #91AFD5",
+"6M c #A9BEEB",
+"6N c #BED3FF",
+"6O c #687B9C",
+"6P c #627596",
+"6Q c #7792A5",
+"6R c #8AA5B8",
+"6S c #90ADBF",
+"6T c #93B0C2",
+"6U c #96B3C5",
+"6V c #98B5C7",
+"6W c #98B7CB",
+"6X c #97B6CA",
+"6Y c #98B0D2",
+"6Z c #93ABCD",
+"6& c #8A9FD6",
+"7 c #768BC2",
+"70 c #6E7CBD",
+"71 c #6F7DBE",
+"72 c #6E7BAF",
+"73 c #6D77B2",
+"74 c #6B75B0",
+"75 c #6D7FAF",
+"76 c #8496C6",
+"77 c #9BBACF",
+"78 c #A4C3D8",
+"79 c #A6CBDE",
+"7a c #ABD0E3",
+"7b c #AED2E8",
+"7c c #B7DDF4",
+"7d c #BDE2FC",
+"7e c #BCE5F9",
+"7f c #BDE6FA",
+"7g c #BEE7FB",
+"7h c #BFE7FF",
+"7i c #292D2E",
+"7j c #CBCFD0",
+"7k c #FDFEFF",
+"7l c #2B2C2E",
+"7m c #82A8BD",
+"7n c #B9E3FB",
+"7o c #B8E2FA",
+"7p c #B4D8F0",
+"7q c #AAC8EE",
+"7r c #86A4CA",
+"7s c #ABC0ED",
+"7t c #677A9B",
+"7u c #657899",
+"7v c #7994A7",
+"7w c #87A2B5",
+"7x c #8AA7B9",
+"7y c #8CA9BB",
+"7z c #8EABBD",
+"7A c #8DAABC",
+"7B c #88A7BB",
+"7C c #87A6BA",
+"7D c #8098BA",
+"7E c #7189AB",
+"7F c #6D82B9",
+"7G c #6F84BB",
+"7H c #7785C6",
+"7I c #8A98D9",
+"7J c #ADBAEE",
+"7K c #C4D1FF",
+"7L c #B6C0FB",
+"7M c #838DC8",
+"7N c #6779A9",
+"7O c #6678A8",
+"7P c #7493A8",
+"7Q c #91B0C5",
+"7R c #9CC1D4",
+"7S c #A1C6D9",
+"7T c #A6CAE0",
+"7U c #ACD0E6",
+"7V c #AFD5EC",
+"7W c #B7DCF6",
+"7X c #B9DEF8",
+"7Y c #B9E2F6",
+"7Z c #BAE3F7",
+"7& c #BBE4F8",
+"8 c #111516",
+"80 c #E4E8E9",
+"81 c #C9CACC",
+"82 c #202123",
+"83 c #BEE4F9",
+"84 c #BAE4FD",
+"85 c #BAE3FF",
+"86 c #B8E4FD",
+"87 c #B9E3FC",
+"88 c #B8E2FB",
+"89 c #B4DCF6",
+"8a c #B1D9F3",
+"8b c #AED3ED",
+"8c c #A4C6E2",
+"8d c #85A7C3",
+"8e c #A0B4E9",
+"8f c #C1D5FF",
+"8g c #8594CB",
+"8h c #5D6CA3",
+"8i c #6779A1",
+"8j c #7385AD",
+"8k c #7990AF",
+"8l c #8097B6",
+"8m c #7D92BD",
+"8n c #798BCB",
+"8o c #7183C3",
+"8p c #7584BD",
+"8q c #7D8CC5",
+"8r c #909DBD",
+"8s c #B0BDDD",
+"8t c #D4E0EE",
+"8u c #E9F5FF",
+"8v c #EDF8FE",
+"8w c #EEF9FF",
+"8x c #EFF7FF",
+"8y c #D9E1EC",
+"8z c #939FC9",
+"8A c #6372AB",
+"8B c #7483BC",
+"8C c #8DACC1",
+"8D c #9AB9CE",
+"8E c #A0C2DB",
+"8F c #A7C9E2",
+"8G c #A9CFE6",
+"8H c #AED4EB",
+"8I c #B1D9F2",
+"8J c #B3DBF4",
+"8K c #B5DFF8",
+"8L c #B7E1FA",
+"8M c #B9E2FE",
+"8N c #BAE4FC",
+"8O c #5B6972",
+"8P c #64727B",
+"8Q c #BBE5FE",
+"8R c #BBE3FD",
+"8S c #BBE4FF",
+"8T c #B7E3FC",
+"8U c #B9E2FF",
+"8V c #B6E0F9",
+"8W c #AACFE9",
+"8X c #9FC1DD",
+"8Y c #87A9C5",
+"8Z c #8195CA",
+"8& c #A7BBF0",
+"9 c #8998CF",
+"90 c #7382B9",
+"91 c #6E80A8",
+"92 c #63759D",
+"93 c #5F7695",
+"94 c #7188A7",
+"95 c #758AB5",
+"96 c #7388B3",
+"97 c #788ACA",
+"98 c #8092D2",
+"99 c #99A8E1",
+"9a c #C2D1FF",
+"9b c #DEEBFF",
+"9c c #E4F1FF",
+"9d c #E7F3FF",
+"9e c #F0F8FF",
+"9f c #DDE9FF",
+"9g c #A2AED8",
+"9h c #6C7BB4",
+"9i c #6170A9",
+"9j c #68879C",
+"9k c #88A7BC",
+"9l c #95B7D0",
+"9m c #9EC0D9",
+"9n c #A3C9E0",
+"9o c #ACD4ED",
+"9p c #B0D8F1",
+"9q c #B2DCF5",
+"9r c #B4DEF7",
+"9s c #BAE2FB",
+"9t c #90B8D1",
+"9u c #2D2D2D",
+"9v c #F4F4F4",
+"9w c #03111A",
+"9x c #B1BFC8",
+"9y c #B9E1FB",
+"9z c #BAE2FC",
+"9A c #B5E1FC",
+"9B c #B5E1FE",
+"9C c #B4E0FD",
+"9D c #ADD4F1",
+"9E c #A9D0ED",
+"9F c #A5CAE7",
+"9G c #9FC4E1",
+"9H c #9ABCD8",
+"9I c #88AAC6",
+"9J c #7A8DD1",
+"9K c #7B8ED2",
+"9L c #8B9FD2",
+"9M c #9DB1E4",
+"9N c #97A9E7",
+"9O c #7B8DCB",
+"9P c #6B7CC1",
+"9Q c #7384C9",
+"9R c #8191C4",
+"9S c #8B9BCE",
+"9T c #ABBBD5",
+"9U c #CADAF4",
+"9V c #DBEAFF",
+"9W c #DAE9FF",
+"9X c #D2E0FF",
+"9Y c #D4E2FF",
+"9Z c #E3F0FF",
+"9& c #E8F5FF",
+"a c #EDF7FF",
+"a0 c #EDFAFF",
+"a1 c #F0F9FE",
+"a2 c #EDF6FB",
+"a3 c #A6AFD6",
+"a4 c #717AA1",
+"a5 c #5E6EA2",
+"a6 c #6B7BAF",
+"a7 c #85A5BC",
+"a8 c #98B8CF",
+"a9 c #9DC3D8",
+"aa c #A4CADF",
+"ab c #A8CFEC",
+"ac c #ACD3F0",
+"ad c #AFD8F4",
+"ae c #B4DDFB",
+"af c #B3DFFC",
+"ag c #B6E2FD",
+"ah c #BADFF9",
+"ai c #B4E0FB",
+"aj c #B5E1FA",
+"ak c #B5E0FF",
+"al c #BEDEF5",
+"am c #7090A7",
+"an c #595959",
+"ao c #9E9E9E",
+"ap c #28485D",
+"aq c #BEDEF3",
+"ar c #B6E2FF",
+"as c #B3DFFA",
+"at c #B2DEFB",
+"au c #B1DDFA",
+"av c #AED7F3",
+"aw c #AAD3EF",
+"ax c #A7CEEB",
+"ay c #A2C9E6",
+"az c #98BDDA",
+"aA c #93B5D1",
+"aB c #84A6C2",
+"aC c #8194D8",
+"aD c #95A8EC",
+"aE c #B4C8FB",
+"aF c #ABBFF2",
+"aG c #90A2E0",
+"aH c #7C8ECC",
+"aI c #7F90D5",
+"aJ c #91A2E7",
+"aK c #B0C0F3",
+"aL c #CDDDFF",
+"aM c #DEEEFF",
+"aN c #D8E8FF",
+"aO c #CDDCFD",
+"aP c #BECDEE",
+"aQ c #AFBDEC",
+"aR c #A9B7E6",
+"aS c #CFDCED",
+"aT c #ECF6FF",
+"aU c #E7F1FA",
+"aV c #E2EFF7",
+"aW c #ECF5FA",
+"aX c #F1FAFF",
+"aY c #EAF3FF",
+"aZ c #6777AB",
+"a& c #5D6DA1",
+"b c #608097",
+"b0 c #82A2B9",
+"b1 c #92B8CD",
+"b2 c #A1C8E5",
+"b3 c #A6CDEA",
+"b4 c #A9D2EE",
+"b5 c #AFD8F6",
+"b6 c #B0D9F7",
+"b7 c #ABD7F2",
+"b8 c #83A8C2",
+"b9 c #90B5CF",
+"ba c #B4E0F9",
+"bb c #B4DFFF",
+"bc c #45657C",
+"bd c #8A8A8A",
+"be c #3A3A3A",
+"bf c #7595AA",
+"bg c #BDDDF2",
+"bh c #B1E0FE",
+"bi c #B2DFFE",
+"bj c #B1DEFD",
+"bk c #B0DDFC",
+"bl c #AFDCFB",
+"bm c #ADDAF9",
+"bn c #ABD8F5",
+"bo c #AAD7F4",
+"bp c #A8D4F1",
+"bq c #A3CFEC",
+"br c #A2CAE4",
+"bs c #9CC4DE",
+"bt c #99BED8",
+"bu c #91B6D0",
+"bv c #8FACD8",
+"bw c #7F9CC8",
+"bx c #8599DE",
+"by c #9BAFF4",
+"bz c #8FA2E4",
+"bA c #7E91D3",
+"bB c #8698C8",
+"bC c #99ABDB",
+"bD c #B4C4DD",
+"bE c #D0E0F9",
+"bF c #DEEEFD",
+"bG c #DFEFFE",
+"bH c #DEEFFF",
+"bI c #C5D6F4",
+"bJ c #B5B6FF",
+"bK c #9E9FFF",
+"bL c #7F83FE",
+"bM c #7C80FB",
+"bN c #BFCDE8",
+"bO c #E2F0FF",
+"bP c #C9F5E6",
+"bQ c #BBE7D8",
+"bR c #98EAA8",
+"bS c #8DDF9D",
+"bT c #C4E4D9",
+"bU c #E0FFF5",
+"bV c #F3FBFE",
+"bW c #EFF7FA",
+"bX c #A5ADD1",
+"bY c #6E769A",
+"bZ c #5D6B9C",
+"b& c #6B79AA",
+"c c #83A7BD",
+"c0 c #96BAD0",
+"c1 c #9BC2DF",
+"c2 c #A3CFEA",
+"c3 c #A6D2ED",
+"c4 c #AAD6F3",
+"c5 c #ACD8F5",
+"c6 c #AEDBFC",
+"c7 c #B0DDFE",
+"c8 c #BDDCF1",
+"c9 c #C4DAE8",
+"ca c #9CB2C0",
+"cb c #7A848E",
+"cc c #4F5963",
+"cd c #25292A",
+"ce c #080C0D",
+"cf c #343537",
+"cg c #000103",
+"ch c #B2DFFF",
+"ci c #B9DDF7",
+"cj c #B6DDFA",
+"ck c #B0DFFD",
+"cl c #B2DFFC",
+"cm c #B3DEFE",
+"cn c #B1E0FC",
+"co c #C1DBEC",
+"cp c #1C3647",
+"cq c #C2C2C2",
+"cr c #CBD0D6",
+"cs c #000208",
+"ct c #B9DDF5",
+"cu c #C5DBE9",
+"cv c #9AB0BE",
+"cw c #6F7A80",
+"cx c #49545A",
+"cy c #383D41",
+"cz c #34393D",
+"cA c #3E474E",
+"cB c #5B646B",
+"cC c #889EAC",
+"cD c #C0DBEE",
+"cE c #BFDAED",
+"cF c #86A0B1",
+"cG c #A1B3C1",
+"cH c #9FB1BF",
+"cI c #BBD2E0",
+"cJ c #C3DAE8",
+"cK c #C0DCEA",
+"cL c #C1DDEB",
+"cM c #B1DFFF",
+"cN c #AFDEFC",
+"cO c #ACD9F8",
+"cP c #AAD7F6",
+"cQ c #A7D4F1",
+"cR c #A5D2EF",
+"cS c #A1CDEA",
+"cT c #9ECAE7",
+"cU c #9BC3DD",
+"cV c #95BDD7",
+"cW c #92B7D1",
+"cX c #8BB0CA",
+"cY c #7794C0",
+"cZ c #7D9AC6",
+"c& c #7E92D7",
+"d c #8497D9",
+"d0 c #9AADEF",
+"d1 c #B5C7F7",
+"d2 c #CEE0FF",
+"d3 c #DDEDFF",
+"d4 c #DBECFF",
+"d5 c #C1D2F0",
+"d6 c #898AF4",
+"d7 c #7273DD",
+"d8 c #696DE8",
+"d9 c #9498FF",
+"da c #D7E5FF",
+"db c #D9E7FF",
+"dc c #B1DDCE",
+"dd c #9FCBBC",
+"de c #73C583",
+"df c #59AB69",
+"dg c #A7C7BC",
+"dh c #DDFDF2",
+"di c #F4FCFF",
+"dj c #E8F0FF",
+"dk c #A6AED2",
+"dl c #6270A1",
+"dm c #5A6899",
+"dn c #5E8298",
+"do c #89ADC3",
+"dp c #93BAD7",
+"dq c #9ECAE5",
+"dr c #A2CEE9",
+"ds c #A7D3F0",
+"dt c #ACD9FA",
+"du c #8CB8D5",
+"dv c #58778C",
+"dw c #214055",
+"dx c #000816",
+"dy c #1F3543",
+"dz c #5C6670",
+"dA c #929CA6",
+"dB c #CED2D3",
+"dC c #F8FCFD",
+"dD c #B8B9BB",
+"dE c #333436",
+"dF c #B1DEFF",
+"dG c #A6D3F4",
+"dH c #7A9EB8",
+"dI c #557993",
+"dJ c #44677D",
+"dK c #4A6D83",
+"dL c #678EAB",
+"dM c #B1DEFB",
+"dN c #B2DDFD",
+"dO c #AFDEFA",
+"dP c #B0DFFB",
+"dQ c #B5CFE0",
+"dR c #000F20",
+"dS c #F8F8F8",
+"dT c #5D6268",
+"dU c #666B71",
+"dV c #84A8C0",
+"dW c #3F637B",
+"dX c #091F2D",
+"dY c #1C3240",
+"dZ c #667177",
+"d& c #98A3A9",
+"e c #B8BDC1",
+"e0 c #BBC0C4",
+"e1 c #AAB3BA",
+"e2 c #7E878E",
+"e3 c #263C4A",
+"e4 c #192F3D",
+"e5 c #7AA6C1",
+"e6 c #B2DEF9",
+"e7 c #7FAACA",
+"e8 c #425D70",
+"e9 c #000A1D",
+"ea c #062031",
+"eb c #5A7485",
+"ec c #90BDDC",
+"ed c #000B19",
+"ee c #0C1E2C",
+"ef c #001422",
+"eg c #000917",
+"eh c #001220",
+"ei c #031F2D",
+"ej c #719DB8",
+"ek c #B0DEFF",
+"el c #AFDDFE",
+"em c #AEDCFD",
+"en c #AEDCFF",
+"eo c #AEDCFE",
+"ep c #ACDDFD",
+"eq c #ABDCFC",
+"er c #ACDAFC",
+"es c #AAD8F9",
+"et c #A8D6F7",
+"eu c #A8D5F6",
+"ev c #A5D2F3",
+"ew c #A2CFEE",
+"ex c #9FCCEB",
+"ey c #9FC8E6",
+"ez c #99C2E0",
+"eA c #96BBD8",
+"eB c #90B5D2",
+"eC c #839ECB",
+"eD c #6984B1",
+"eE c #798ED1",
+"eF c #7C91D4",
+"eG c #8698CA",
+"eH c #9EB0E2",
+"eI c #B9CAE4",
+"eJ c #CFE0FA",
+"eK c #DAEBFD",
+"eL c #DBECFE",
+"eM c #E0F0FF",
+"eN c #E1F1FF",
+"eO c #E2EEFF",
+"eP c #D7E3F9",
+"eQ c #AFB6ED",
+"eR c #9EA5DC",
+"eS c #B6BFDC",
+"eT c #D7E0FD",
+"eU c #E3F6FD",
+"eV c #CEE1E8",
+"eW c #88DA92",
+"eX c #69BB73",
+"eY c #43A945",
+"eZ c #44AA46",
+"e& c #BCD4C7",
+"f c #E7FFF2",
+"f0 c #F6FBFF",
+"f1 c #F7FCFF",
+"f2 c #E9EEF2",
+"f3 c #9AA1CD",
+"f4 c #646B97",
+"f5 c #546590",
+"f6 c #7182AD",
+"f7 c #8AAFCA",
+"f8 c #94B9D4",
+"f9 c #97C3E0",
+"fa c #A1CEEF",
+"fb c #A7D5F6",
+"fc c #A9D7F8",
+"fd c #ADDBFD",
+"fe c #ADDBFC",
+"ff c #C3D6E5",
+"fg c #6F8291",
+"fh c #2A2E31",
+"fi c #1D2124",
+"fj c #707070",
+"fk c #B6B6B6",
+"fl c #F0F0F0",
+"fm c #FCFCFC",
+"fn c #FBFDFC",
+"fo c #FAFCFB",
+"fp c #FBFBFD",
+"fq c #72797F",
+"fr c #5E656B",
+"fs c #3D4144",
+"ft c #060A0D",
+"fu c #474747",
+"fv c #747474",
+"fw c #858585",
+"fx c #535353",
+"fy c #050505",
+"fz c #59707E",
+"fA c #C0D7E5",
+"fB c #AFDBFE",
+"fC c #85939C",
+"fD c #3A4851",
+"fE c #FBFBFB",
+"fF c #FBFCFE",
+"fG c #FCFDFF",
+"fH c #FCFCFE",
+"fI c #E1E1E1",
+"fJ c #000C1E",
+"fK c #AAC7D9",
+"fL c #B6DAF4",
+"fM c #B5D9F3",
+"fN c #848E98",
+"fO c #2B353F",
+"fP c #252525",
+"fQ c #868686",
+"fR c #DADCDB",
+"fS c #AFAFAF",
+"fT c #071017",
+"fU c #868F96",
+"fV c #AFDCFD",
+"fW c #ACDDFE",
+"fX c #B3DAF7",
+"fY c #B4DBF8",
+"fZ c #B1C3CF",
+"f& c #647682",
+"g c #262729",
+"g0 c #2A2B2D",
+"g1 c #898B8A",
+"g2 c #E4E6E5",
+"g3 c #7A848D",
+"g4 c #5B656E",
+"g5 c #C3D6E4",
+"g6 c #263947",
+"g7 c #919191",
+"g8 c #EBEFF2",
+"g9 c #262A2D",
+"ga c #5C83A2",
+"gb c #ACDAFB",
+"gc c #ACDAFE",
+"gd c #A9DAFA",
+"ge c #A8D9F9",
+"gf c #A8D6F8",
+"gg c #A7D5F7",
+"gh c #A6D4F5",
+"gi c #A3D1F2",
+"gj c #A2CFF0",
+"gk c #9FCCED",
+"gl c #9BC8E7",
+"gm c #97C4E3",
+"gn c #96BFDD",
+"go c #90B9D7",
+"gp c #89AECB",
+"gq c #6D92AF",
+"gr c #7691BE",
+"gs c #7B96C3",
+"gt c #7E93D6",
+"gu c #94A9EC",
+"gv c #B7C9FB",
+"gw c #CADCFF",
+"gx c #D7E8FF",
+"gy c #D9EAFF",
+"gz c #DCEDFF",
+"gA c #DFEFFF",
+"gB c #D9E9F9",
+"gC c #D6E2F8",
+"gD c #DBE2FF",
+"gE c #DDE4FF",
+"gF c #EBF4FF",
+"gG c #E9F2FF",
+"gH c #E4F7FE",
+"gI c #D8EBF2",
+"gJ c #95E79F",
+"gK c #74C67E",
+"gL c #67CD69",
+"gM c #87ED89",
+"gN c #E0F8EB",
+"gO c #EBFFF6",
+"gP c #F8FDFF",
+"gQ c #D7DEFF",
+"gR c #8990BC",
+"gS c #586994",
+"gT c #7196B1",
+"gU c #8CB1CC",
+"gV c #91BDDA",
+"gW c #9CC9EA",
+"gX c #A4D2F3",
+"gY c #A9D7F9",
+"gZ c #AAD8FA",
+"g& c #ABD9FA",
+"h c #A1CFF0",
+"h0 c #132635",
+"h1 c #3B4E5D",
+"h2 c #B9BDC0",
+"h3 c #F6FAFD",
+"h4 c #F8FAF9",
+"h5 c #F9FBFA",
+"h6 c #F9F9FB",
+"h7 c #343B41",
+"h8 c #3B4248",
+"h9 c #A3A7AA",
+"ha c #EEF2F5",
+"hb c #FAFAFA",
+"hc c #DBDBDB",
+"hd c #324957",
+"he c #ADD9FC",
+"hf c #4F5D66",
+"hg c #829099",
+"hh c #F9FAFC",
+"hi c #FAFAFC",
+"hj c #6C6C6C",
+"hk c #436072",
+"hl c #BAD7E9",
+"hm c #84A8C2",
+"hn c #1B3F59",
+"ho c #A8B2BC",
+"hp c #BBC4CB",
+"hq c #000910",
+"hr c #8CB9DA",
+"hs c #ADDAFB",
+"ht c #AADBFC",
+"hu c #A9DAFB",
+"hv c #8CB3D0",
+"hw c #5E85A2",
+"hx c #00111D",
+"hy c #576975",
+"hz c #C4C5C7",
+"hA c #828C95",
+"hB c #545E67",
+"hC c #536674",
+"hD c #415462",
+"hE c #606467",
+"hF c #44484B",
+"hG c #B1D8F7",
+"hH c #AADBFB",
+"hI c #A8DAFD",
+"hJ c #A9D9FF",
+"hK c #A8DAFF",
+"hL c #A7D7FB",
+"hM c #A5D5F9",
+"hN c #A4D2F6",
+"hO c #A2D0F2",
+"hP c #9FCDEF",
+"hQ c #99C6E7",
+"hR c #98C1DF",
+"hS c #93BCDA",
+"hT c #90AFDD",
+"hU c #7B9AC8",
+"hV c #788DCE",
+"hW c #7F94D5",
+"hX c #8295CD",
+"hY c #96A9E1",
+"hZ c #B2C7E6",
+"h& c #C5DAF9",
+"i c #D7E9FF",
+"i0 c #D8EAFF",
+"i1 c #DBEBFB",
+"i2 c #DDEDFD",
+"i3 c #DDEEFF",
+"i4 c #DDF0FF",
+"i5 c #F2DAD6",
+"i6 c #E9D1CD",
+"i7 c #FFB781",
+"i8 c #FFAA74",
+"i9 c #D9AB94",
+"ia c #FFE1CA",
+"ib c #E5F5FF",
+"ic c #E5E8DD",
+"id c #E2E5DA",
+"ie c #D5E5D8",
+"if c #D4E4D7",
+"ig c #DCEAEA",
+"ih c #EAF8F8",
+"ii c #FAFFFF",
+"ij c #F7FAFF",
+"ik c #CCCFD8",
+"il c #727CAF",
+"im c #586295",
+"in c #5C7496",
+"io c #839BBD",
+"ip c #8BB4D2",
+"iq c #94BDDB",
+"ir c #A3CFF2",
+"is c #A5D1F4",
+"it c #A7D9FC",
+"iu c #A9DBFE",
+"iv c #A9D9FD",
+"iw c #8FBFE3",
+"ix c #1A1A1A",
+"iy c #F7F8FA",
+"iz c #F6F8F7",
+"iA c #F7F9F8",
+"iB c #F7F7F7",
+"iC c #CDCDCD",
+"iD c #E1E6E9",
+"iE c #84898C",
+"iF c #304352",
+"iG c #112433",
+"iH c #26353C",
+"iI c #85949B",
+"iJ c #F5F5F5",
+"iK c #F6F6F6",
+"iL c #F3F3F3",
+"iM c #545454",
+"iN c #3B5669",
+"iO c #BAD5E8",
+"iP c #AADAFF",
+"iQ c #ACD7F7",
+"iR c #A6D1F1",
+"iS c #DDDDDD",
+"iT c #F9F7F8",
+"iU c #F8F8FA",
+"iV c #F7F7F9",
+"iW c #D8DDE1",
+"iX c #03080C",
+"iY c #91BFE1",
+"iZ c #ABD9FB",
+"i& c #BED3E4",
+"j c #526778",
+"j0 c #171717",
+"j1 c #F7F5F6",
+"j2 c #E6E6E8",
+"j3 c #8D97A0",
+"j4 c #505A63",
+"j5 c #32434D",
+"j6 c #54656F",
+"j7 c #C4C4C4",
+"j8 c #838584",
+"j9 c #304C61",
+"ja c #B8D4E9",
+"jb c #B8D7EC",
+"jc c #B7D6EB",
+"jd c #828F97",
+"je c #334048",
+"jf c #1B191A",
+"jg c #8A8889",
+"jh c #EBEBEB",
+"ji c #899299",
+"jj c #4E575E",
+"jk c #B7D5ED",
+"jl c #7391A9",
+"jm c #202020",
+"jn c #E6E6E6",
+"jo c #0A2D49",
+"jp c #AACDE9",
+"jq c #A7D9FE",
+"jr c #A6D8FD",
+"js c #A4D4F8",
+"jt c #A2D2F6",
+"ju c #A3D1F5",
+"jv c #9FCDF1",
+"jw c #9DCBED",
+"jx c #98C6E8",
+"jy c #95C2E3",
+"jz c #90BDDE",
+"jA c #8DB6D4",
+"jB c #78A1BF",
+"jC c #7897C5",
+"jD c #7D9CCA",
+"jE c #8EA3E4",
+"jF c #ADC0F8",
+"jG c #C2D5FF",
+"jH c #D1E6FF",
+"jI c #D4E9FF",
+"jJ c #DCECFC",
+"jK c #DCEFFF",
+"jL c #D7EAFB",
+"jM c #E2CAC6",
+"jN c #D0B8B4",
+"jO c #ED9660",
+"jP c #D8814B",
+"jQ c #B4866F",
+"jR c #FFE4CD",
+"jS c #DAEAF9",
+"jT c #DBEBFA",
+"jU c #E9ECE1",
+"jV c #DFE2D7",
+"jW c #E2F2E5",
+"jX c #EDFBFB",
+"jY c #EEFCFC",
+"jZ c #FBFEFF",
+"j& c #F1F4FD",
+"k c #ABB5E8",
+"k0 c #606A9D",
+"k1 c #50688A",
+"k2 c #677FA1",
+"k3 c #80A9C7",
+"k4 c #8CB5D3",
+"k5 c #93BEE1",
+"k6 c #9FCBEE",
+"k7 c #A2CEF1",
+"k8 c #A3D3F9",
+"k9 c #A6D8FB",
+"ka c #020202",
+"kb c #F1F1F1",
+"kc c #F3F4F6",
+"kd c #F3F5F4",
+"ke c #F4F6F5",
+"kf c #EFEFEF",
+"kg c #0A0F12",
+"kh c #474C4F",
+"ki c #7E91A0",
+"kj c #A3B6C5",
+"kk c #8A99A0",
+"kl c #29383F",
+"km c #575757",
+"kn c #F2F2F2",
+"ko c #E8E8E8",
+"kp c #062134",
+"kq c #86A1B4",
+"kr c #507B9B",
+"ks c #F5F3F4",
+"kt c #F3F3F5",
+"ku c #F4F4F6",
+"kv c #595E62",
+"kw c #5A5F63",
+"kx c #A1CFF1",
+"ky c #2C4152",
+"kz c #394E5F",
+"kA c #F4F2F3",
+"kB c #727274",
+"kC c #0A0A0C",
+"kD c #3D4750",
+"kE c #757F88",
+"kF c #8899A3",
+"kG c #61727C",
+"kH c #000000",
+"kI c #989898",
+"kJ c #F2F4F3",
+"kK c #E7E9E8",
+"kL c #001227",
+"kM c #A3BFD4",
+"kN c #A8D8FC",
+"kO c #98C8EC",
+"kP c #57768B",
+"kQ c #00081D",
+"kR c #323F47",
+"kS c #98A5AD",
+"kT c #F0EEEF",
+"kU c #9099A0",
+"kV c #475057",
+"kW c #9BB9D1",
+"kX c #000A22",
+"kY c #BEBEBE",
+"kZ c #AAAAAA",
+"k& c #8EB1CD",
+"l c #B2D5F1",
+"l0 c #A8D8FF",
+"l1 c #A3D7FC",
+"l2 c #A5D6FE",
+"l3 c #A2D6FB",
+"l4 c #A3D4FC",
+"l5 c #A2D3FB",
+"l6 c #A0D2F7",
+"l7 c #9FD1F6",
+"l8 c #9DCDF3",
+"l9 c #99C9EF",
+"la c #97C5E7",
+"lb c #92C0E2",
+"lc c #91B7DC",
+"ld c #85ABD0",
+"le c #7B94D4",
+"lf c #738CCC",
+"lg c #8196D7",
+"lh c #889DDE",
+"li c #A3BAE4",
+"lj c #BBD2FC",
+"lk c #CEE2FD",
+"ll c #D0E4FF",
+"lm c #D1E3F9",
+"ln c #D3E5FB",
+"lo c #D6E8FF",
+"lp c #D9EBFF",
+"lq c #DBEDFF",
+"lr c #D7E8FA",
+"ls c #F5AD87",
+"lt c #D18963",
+"lu c #DE7130",
+"lv c #D86B2A",
+"lw c #C8BBB5",
+"lx c #F8EBE5",
+"ly c #EFE5A8",
+"lz c #F6ECAF",
+"lA c #FFE545",
+"lB c #FFD939",
+"lC c #E4D793",
+"lD c #FBEEAA",
+"lE c #F1F9FC",
+"lF c #F9FFFF",
+"lG c #FBFFFF",
+"lH c #E1E6F9",
+"lI c #959AAD",
+"lJ c #576397",
+"lK c #596599",
+"lL c #6F92AE",
+"lM c #89ACC8",
+"lN c #8DB9DC",
+"lO c #93BFE2",
+"lP c #9CCCF0",
+"lQ c #A0D1F9",
+"lR c #A1D5FA",
+"lS c #A3D7FE",
+"lT c #A4D8FD",
+"lU c #0E1215",
+"lV c #D6DADD",
+"lW c #F2F2F4",
+"lX c #E0E0E0",
+"lY c #243B4D",
+"lZ c #283F51",
+"l& c #80B0D4",
+"m c #A6D6FA",
+"m0 c #A4D5FD",
+"m1 c #25323B",
+"m2 c #86939C",
+"m3 c #7B8489",
+"m4 c #4A5358",
+"m5 c #A2D8FC",
+"m6 c #A5D6FF",
+"m7 c #BED1DF",
+"m8 c #000513",
+"m9 c #C5C7C6",
+"ma c #F1F3F2",
+"mb c #C5C5C5",
+"mc c #000821",
+"md c #A5C5DE",
+"me c #B4C7D5",
+"mf c #213442",
+"mg c #F0F2F1",
+"mh c #F1F1F3",
+"mi c #BDC4CA",
+"mj c #1C2329",
+"mk c #2B5472",
+"ml c #8EB7D5",
+"mm c #8EA8BF",
+"mn c #000F26",
+"mo c #E0DEDF",
+"mp c #F2F0F1",
+"mq c #404D56",
+"mr c #7A8790",
+"ms c #5E6367",
+"mt c #050A0E",
+"mu c #5F5F5F",
+"mv c #C6C6C6",
+"mw c #959EA5",
+"mx c #404950",
+"my c #A9D6F7",
+"mz c #AAD7F8",
+"mA c #383C3F",
+"mB c #7F8386",
+"mC c #BDBFBE",
+"mD c #001026",
+"mE c #7D99AF",
+"mF c #A0D4F9",
+"mG c #A1D2FA",
+"mH c #9FD0F8",
+"mI c #9ED0F5",
+"mJ c #9BCDF2",
+"mK c #95C5EB",
+"mL c #8BB9DB",
+"mM c #7CA2C7",
+"mN c #749ABF",
+"mO c #829BDB",
+"mP c #819ADA",
+"mQ c #96ABEC",
+"mR c #B7CCFF",
+"mS c #C3DAFF",
+"mT c #B4CBF5",
+"mU c #99ADC8",
+"mV c #8397B2",
+"mW c #788AA0",
+"mX c #8597AD",
+"mY c #99ABC3",
+"mZ c #C5D7EF",
+"m& c #D7E9FD",
+"n c #FFCEA8",
+"n0 c #F6AE88",
+"n1 c #FFA362",
+"n2 c #FFBF7E",
+"n3 c #F7EAE4",
+"n4 c #F5E8E2",
+"n5 c #EDE3A6",
+"n6 c #E5DB9E",
+"n7 c #FAD030",
+"n8 c #F6CC2C",
+"n9 c #EEE19D",
+"na c #FFFAB6",
+"nb c #F2FAFD",
+"nc c #C3C8DB",
+"nd c #6C78AC",
+"ne c #527591",
+"nf c #7B9EBA",
+"ng c #86B2D5",
+"nh c #8FBBDE",
+"ni c #94C4E8",
+"nj c #99C9ED",
+"nk c #9ECFF7",
+"nl c #A2D6FD",
+"nm c #222629",
+"nn c #BDC1C4",
+"no c #EFEFF1",
+"np c #EEEEEE",
+"nq c #515151",
+"nr c #566D7F",
+"ns c #B9D0E2",
+"nt c #95A2AB",
+"nu c #26333C",
+"nv c #EDEDED",
+"nw c #BEC7CC",
+"nx c #161F24",
+"ny c #A1D7FB",
+"nz c #A3D4FD",
+"nA c #A4D5FE",
+"nB c #647785",
+"nC c #3E515F",
+"nD c #EEF0EF",
+"nE c #EDEFEE",
+"nF c #F0F0F2",
+"nG c #5A7A93",
+"nH c #B1D1EA",
+"nI c #2B3E4C",
+"nJ c #5B6E7C",
+"nK c #A8A8AA",
+"nL c #030A10",
+"nM c #757C82",
+"nN c #ABD4F2",
+"nO c #B5CFE6",
+"nP c #2F4960",
+"nQ c #9A9899",
+"nR c #EFEDEE",
+"nS c #6B7881",
+"nT c #48555E",
+"nU c #3A3F43",
+"nV c #DBE0E4",
+"nW c #EEEEF0",
+"nX c #9BA4AB",
+"nY c #3A434A",
+"nZ c #426F90",
+"n& c #414548",
+"o c #E8ECEF",
+"o0 c #CDCFCE",
+"o1 c #131514",
+"o2 c #6B879D",
+"o3 c #B5D1E7",
+"o4 c #9FD4FC",
+"o5 c #9FD4FE",
+"o6 c #9ED3FD",
+"o7 c #9FD3FB",
+"o8 c #9ED2FA",
+"o9 c #9CD0F8",
+"oa c #9BCFF7",
+"ob c #9BCCF4",
+"oc c #97C8F0",
+"od c #8FBFE5",
+"oe c #8EB4E5",
+"of c #81A7D8",
+"og c #7D91DA",
+"oh c #8599E2",
+"oi c #8EA5D7",
+"oj c #ABC2F4",
+"ok c #C5D9F4",
+"ol c #AFC3DE",
+"om c #8B9096",
+"on c #858A90",
+"oo c #A8A7AC",
+"op c #B7B6BB",
+"oq c #C3C5C4",
+"or c #A3A5A4",
+"os c #8F9092",
+"ot c #737476",
+"ou c #A3AFBF",
+"ov c #D7E3F3",
+"ow c #DDECFF",
+"ox c #DEEDFF",
+"oy c #E3EFFD",
+"oz c #E1EDFB",
+"oA c #E3EDF7",
+"oB c #E7F1FB",
+"oC c #E6F2FE",
+"oD c #E9EBD6",
+"oE c #E0E2CD",
+"oF c #E8E0B9",
+"oG c #F4ECC5",
+"oH c #EFF7F9",
+"oI c #F2FAFC",
+"oJ c #F3FAFF",
+"oK c #F9FEFF",
+"oL c #FAFEFD",
+"oM c #FBFFFE",
+"oN c #F2F3F5",
+"oO c #A3A7D4",
+"oP c #626693",
+"oQ c #51678E",
+"oR c #6C82A9",
+"oS c #7EA9CB",
+"oT c #8BB6D8",
+"oU c #90C0E6",
+"oV c #98CCF4",
+"oW c #9ACEF6",
+"oX c #9DD1F9",
+"oY c #A0D3FE",
+"oZ c #9FD2FD",
+"o& c #303B41",
+"p c #A0ABB1",
+"p0 c #EAEAEA",
+"p1 c #A9B2B7",
+"p2 c #000308",
+"p3 c #9ED3FB",
+"p4 c #9FD5FB",
+"p5 c #99AEBF",
+"p6 c #132839",
+"p7 c #E7E5E6",
+"p8 c #040203",
+"p9 c #A0D4FC",
+"pa c #9FD2FF",
+"pb c #A5D3F5",
+"pc c #C3C3C3",
+"pd c #E9EBEA",
+"pe c #EAECEB",
+"pf c #EBEBED",
+"pg c #EAEAEC",
+"ph c #87949D",
+"pi c #24313A",
+"pj c #B3CFE5",
+"pk c #476379",
+"pl c #484848",
+"pm c #A1AAB1",
+"pn c #00060D",
+"po c #6B9BC3",
+"pp c #A3D3FB",
+"pq c #AAD1F0",
+"pr c #446B8A",
+"ps c #777777",
+"pt c #76838C",
+"pu c #4C5962",
+"pv c #090E12",
+"pw c #D3D8DC",
+"px c #ECECEC",
+"py c #A1A8AE",
+"pz c #333A40",
+"pA c #858F98",
+"pB c #101A23",
+"pC c #D8D8D8",
+"pD c #D6D6D6",
+"pE c #0C273C",
+"pF c #5B768B",
+"pG c #A1D4FF",
+"pH c #9DD2FC",
+"pI c #98C9F1",
+"pJ c #94C5ED",
+"pK c #91C1E7",
+"pL c #8BBBE1",
+"pM c #83A9DA",
+"pN c #7DA3D4",
+"pO c #879BE4",
+"pP c #97ABF4",
+"pQ c #BBD2FF",
+"pR c #9BAFCA",
+"pS c #7B8FAA",
+"pT c #B1B6BC",
+"pU c #C3C8CE",
+"pV c #CCCBD0",
+"pW c #CAC9CE",
+"pX c #C1C3C2",
+"pY c #B9BBBA",
+"pZ c #AEAFB1",
+"p& c #9C9D9F",
+"q c #778393",
+"q0 c #A8B4C4",
+"q1 c #DCEBFE",
+"q2 c #E4F0FE",
+"q3 c #E5F1FF",
+"q4 c #E8F2FC",
+"q5 c #E8F4FF",
+"q6 c #F4F6E1",
+"q7 c #F6F8E3",
+"q8 c #FFF8D1",
+"q9 c #F0F8FA",
+"qa c #F1F8FE",
+"qb c #F2F9FF",
+"qc c #F5FDFF",
+"qd c #D1D5FF",
+"qe c #8084B1",
+"qf c #546A91",
+"qg c #729DBF",
+"qh c #85B0D2",
+"qi c #8CBCE2",
+"qj c #92C2E8",
+"qk c #95C9F1",
+"ql c #9ED1FC",
+"qm c #3E494F",
+"qn c #8C979D",
+"qo c #343D42",
+"qp c #737C81",
+"qq c #9ED4FA",
+"qr c #8DA2B3",
+"qs c #1F3445",
+"qt c #E8E6E7",
+"qu c #141213",
+"qv c #8BBFE7",
+"qw c #9DD2FA",
+"qx c #A4D2F4",
+"qy c #3E6C8E",
+"qz c #585858",
+"qA c #E6E8E7",
+"qB c #E7E7E9",
+"qC c #CECED0",
+"qD c #05121B",
+"qE c #8D9AA3",
+"qF c #809CB2",
+"qG c #00192F",
+"qH c #D4D4D4",
+"qI c #D2D2D2",
+"qJ c #091219",
+"qK c #879097",
+"qL c #A2D2FA",
+"qM c #A9D0EF",
+"qN c #456C8B",
+"qO c #757575",
+"qP c #65727B",
+"qQ c #58656E",
+"qR c #51565A",
+"qS c #A4ABB1",
+"qT c #2E353B",
+"qU c #8ABFE7",
+"qV c #0F1922",
+"qW c #A6B0B9",
+"qX c #313131",
+"qY c #4A657A",
+"qZ c #B3CEE3",
+"q& c #9BD1FD",
+"r c #9BD1FF",
+"r0 c #9AD0FE",
+"r1 c #99D0F9",
+"r2 c #97CEF7",
+"r3 c #97CCF8",
+"r4 c #94C9F5",
+"r5 c #91C4EF",
+"r6 c #8EC1EC",
+"r7 c #8DBDE5",
+"r8 c #86B6DE",
+"r9 c #869DE9",
+"ra c #879EEA",
+"rb c #9BB7E6",
+"rc c #BFDBFF",
+"rd c #C7DFFB",
+"re c #9CB4D0",
+"rf c #96979B",
+"rg c #CBCCD0",
+"rh c #D0D0D0",
+"ri c #BBBBBB",
+"rj c #BFBFBF",
+"rk c #B7B7B5",
+"rl c #ACACAA",
+"rm c #929292",
+"rn c #7E7E7E",
+"ro c #85868A",
+"rp c #949599",
+"rq c #D8E5F6",
+"rr c #E1EEFF",
+"rs c #E4F0FC",
+"rt c #EAF4FF",
+"ru c #E9F6FF",
+"rv c #EAF7FF",
+"rw c #EBF8FF",
+"rx c #DCF0FF",
+"ry c #D3E7FF",
+"rz c #D5E7FF",
+"rA c #E1F3FF",
+"rB c #F0FAFF",
+"rC c #F3FDFF",
+"rD c #FAFCFF",
+"rE c #B1B3BF",
+"rF c #616CA2",
+"rG c #576298",
+"rH c #6185A5",
+"rI c #81A5C5",
+"rJ c #87B8E0",
+"rK c #8DBEE6",
+"rL c #92C5F0",
+"rM c #95C8F3",
+"rN c #96CCF8",
+"rO c #98CEFA",
+"rP c #47515B",
+"rQ c #7D8791",
+"rR c #E5E5E5",
+"rS c #BDBDBD",
+"rT c #000924",
+"rU c #ABCDE8",
+"rV c #9AD0FC",
+"rW c #9CD2FE",
+"rX c #6C7680",
+"rY c #505A64",
+"rZ c #E4E4E4",
+"r& c #161616",
+"s c #84B9E3",
+"s0 c #9CD1F9",
+"s1 c #A4CFF1",
+"s2 c #ABCEEC",
+"s3 c #AACDEB",
+"s4 c #9CD1FB",
+"s5 c #9FAFBE",
+"s6 c #000C1B",
+"s7 c #CBCBCD",
+"s8 c #E5E5E7",
+"s9 c #E0E4E7",
+"sa c #3B3F42",
+"sb c #3B698D",
+"sc c #A1CFF3",
+"sd c #373B3E",
+"se c #868A8D",
+"sf c #616161",
+"sg c #346286",
+"sh c #A2D0F4",
+"si c #9CD0FF",
+"sj c #9BCFFE",
+"sk c #AECCE6",
+"sl c #2C4A64",
+"sm c #34495A",
+"sn c #6E8394",
+"so c #98BBD7",
+"sp c #000723",
+"sq c #B2B2B0",
+"sr c #E5E5E3",
+"ss c #E5E3E4",
+"st c #E6E4E5",
+"su c #AAAFB5",
+"sv c #2C3137",
+"sw c #B3CCE0",
+"sx c #2A4357",
+"sy c #E1E1E3",
+"sz c #334A5C",
+"sA c #3B5264",
+"sB c #99CFFD",
+"sC c #98CFF8",
+"sD c #95CCF5",
+"sE c #96CBF7",
+"sF c #92C7F3",
+"sG c #90C3EE",
+"sH c #8CBFEA",
+"sI c #8ABAE2",
+"sJ c #83B3DB",
+"sK c #859CE8",
+"sL c #91A8F4",
+"sM c #B3CFFE",
+"sN c #B4CCE8",
+"sO c #829AB6",
+"sP c #AFB0B4",
+"sQ c #DADBDF",
+"sR c #C8C8C8",
+"sS c #B4B4B4",
+"sT c #AAAAA8",
+"sU c #A0A09E",
+"sV c #949494",
+"sW c #838383",
+"sX c #828387",
+"sY c #9D9EA2",
+"sZ c #D5E2F3",
+"s& c #E0EDFE",
+"t c #E5F1FD",
+"t0 c #E8F5FE",
+"t1 c #E7F4FD",
+"t2 c #E0EDFD",
+"t3 c #D8E5F5",
+"t4 c #CEE2FA",
+"t5 c #CFE3FB",
+"t6 c #D3E5FD",
+"t7 c #D2E4FC",
+"t8 c #E2ECF5",
+"t9 c #EFF9FF",
+"ta c #FBFDFF",
+"tb c #E2E4F0",
+"tc c #7F8AC0",
+"td c #586399",
+"te c #4B6F8F",
+"tf c #769ABA",
+"tg c #83B4DC",
+"th c #8ABBE3",
+"ti c #8FC2ED",
+"tj c #93C6F1",
+"tk c #94CAF6",
+"tl c #98CEFC",
+"tm c #99CFFB",
+"tn c #747E88",
+"to c #E2E2E2",
+"tp c #666666",
+"tq c #41637E",
+"tr c #A9CBE6",
+"ts c #29333D",
+"tt c #96A0AA",
+"tu c #0A0A0A",
+"tv c #8CC1EB",
+"tw c #9BD0FA",
+"tx c #9BD0F8",
+"ty c #7DB2DA",
+"tz c #5C87A9",
+"tA c #356082",
+"tB c #234664",
+"tC c #315472",
+"tD c #7DB2DC",
+"tE c #9ACFF9",
+"tF c #3E4E5D",
+"tG c #647483",
+"tH c #717578",
+"tI c #303437",
+"tJ c #81AFD3",
+"tK c #0F1316",
+"tL c #D7DBDE",
+"tM c #DADADA",
+"tN c #0D0D0D",
+"tO c #88B6DA",
+"tP c #A7C5DF",
+"tQ c #000923",
+"tR c #CBCBCB",
+"tS c #000D1E",
+"tT c #9EB3C4",
+"tU c #A8CBE7",
+"tV c #5E819D",
+"tW c #20201E",
+"tX c #D5D5D3",
+"tY c #E1DFE0",
+"tZ c #272C32",
+"t& c #556E82",
+"u c #253E52",
+"u0 c #5C5C5E",
+"u1 c #294052",
+"u2 c #B2C9DB",
+"u3 c #95CFFD",
+"u4 c #95CDFE",
+"u5 c #94CCFD",
+"u6 c #92CAFB",
+"u7 c #92C8F6",
+"u8 c #8EC4F2",
+"u9 c #8DC2EE",
+"ua c #88BDE9",
+"ub c #85B6DF",
+"uc c #7FB0D9",
+"ud c #839DE8",
+"ue c #8FA9F4",
+"uf c #B0D1FA",
+"ug c #B9DAFF",
+"uh c #AEBAC8",
+"ui c #8894A2",
+"uj c #C4C4C6",
+"uk c #BBBBBD",
+"ul c #B1B1B1",
+"um c #A8A8A8",
+"un c #9E9EA0",
+"uo c #939395",
+"up c #898989",
+"uq c #808080",
+"ur c #7E7F83",
+"us c #A8A9AD",
+"ut c #DDEAFA",
+"uu c #E1EEFE",
+"uv c #E4F2FF",
+"uw c #E5F3FF",
+"ux c #E6F4FF",
+"uy c #E3F4FF",
+"uz c #E1F2FF",
+"uA c #D5EDFF",
+"uB c #CDE5FF",
+"uC c #C7E0FF",
+"uD c #C8E1FF",
+"uE c #C9E0FF",
+"uF c #C8DFFF",
+"uG c #C3D3FF",
+"uH c #B2C2F3",
+"uI c #AAB8E7",
+"uJ c #C8D6FF",
+"uK c #F4FDFF",
+"uL c #FCFFFF",
+"uM c #F9FCFF",
+"uN c #A0ABD9",
+"uO c #616C9A",
+"uP c #4E678F",
+"uQ c #6C85AD",
+"uR c #7BACD4",
+"uS c #8BC0EC",
+"uT c #8FC4F0",
+"uU c #8FC8F5",
+"uV c #91CAF7",
+"uW c #94CCFB",
+"uX c #96CEFF",
+"uY c #94CEFE",
+"uZ c #95CFFF",
+"u& c #505C68",
+"v c #6B7783",
+"v0 c #DCDCDC",
+"v1 c #DEDCDD",
+"v2 c #DADBDD",
+"v3 c #1A1B1D",
+"v4 c #72A8D6",
+"v5 c #A1CCEF",
+"v6 c #6E99BC",
+"v7 c #D9D9D9",
+"v8 c #CFD0D4",
+"v9 c #010206",
+"va c #96CEFD",
+"vb c #95CDFC",
+"vc c #AFC8DE",
+"vd c #597288",
+"ve c #1F2324",
+"vf c #171B1C",
+"vg c #4E4E4E",
+"vh c #7A7A7A",
+"vi c #969696",
+"vj c #606060",
+"vk c #0B2A46",
+"vl c #A9C8E4",
+"vm c #A5C9E9",
+"vn c #698DAD",
+"vo c #1C1C1C",
+"vp c #DCDCDE",
+"vq c #DDDDDF",
+"vr c #9D9D9D",
+"vs c #000828",
+"vt c #8AAECE",
+"vu c #A4CBEC",
+"vv c #446B8C",
+"vw c #9FA6B0",
+"vx c #2B323C",
+"vy c #97CDF9",
+"vz c #5D646A",
+"vA c #4A5157",
+"vB c #828284",
+"vC c #1B4367",
+"vD c #A3CBEF",
+"vE c #94CEFC",
+"vF c #3A5065",
+"vG c #374D62",
+"vH c #DEDEDE",
+"vI c #DBDDDC",
+"vJ c #252C32",
+"vK c #76A2C5",
+"vL c #0E0E10",
+"vM c #C3C3C5",
+"vN c #687888",
+"vO c #1B2B3B",
+"vP c #8DC5F4",
+"vQ c #98CDFF",
+"vR c #96D0FE",
+"vS c #97CFFF",
+"vT c #93CDFB",
+"vU c #93CBFC",
+"vV c #91C9FA",
+"vW c #90C8F9",
+"vX c #90C6F4",
+"vY c #8DC3F1",
+"vZ c #8ABFEB",
+"v& c #85BAE6",
+"w c #83B4DD",
+"w0 c #7CADD6",
+"w1 c #87A1EC",
+"w2 c #AFD0F9",
+"w3 c #85919F",
+"w4 c #BABABA",
+"w5 c #B4B4B6",
+"w6 c #AFAFB1",
+"w7 c #A5A5A5",
+"w8 c #9B9B9B",
+"w9 c #8F8F91",
+"wa c #7D7D7D",
+"wb c #787878",
+"wc c #8C8D91",
+"wd c #C6C7CB",
+"we c #E2F0FD",
+"wf c #D2E3F5",
+"wg c #C6DEF8",
+"wh c #C5DEFD",
+"wi c #C6DFFE",
+"wj c #BED5F7",
+"wk c #ABC2E4",
+"wl c #8C9CCD",
+"wm c #6979AA",
+"wn c #5F6D9C",
+"wo c #8492C1",
+"wp c #BFC8D7",
+"wq c #E6EFFE",
+"wr c #F7FBFC",
+"ws c #FAFEFF",
+"wt c #FAFDFF",
+"wu c #F0F3FA",
+"wv c #C3CEFC",
+"ww c #737EAC",
+"wx c #506991",
+"wy c #5A739B",
+"wz c #73A4CC",
+"wA c #85B6DE",
+"wB c #87BCE8",
+"wC c #8CC5F2",
+"wD c #91C9F8",
+"wE c #92CAF9",
+"wF c #92CCFA",
+"wG c #93CDFD",
+"wH c #4E5A66",
+"wI c #D7D7D7",
+"wJ c #D9D7D8",
+"wK c #D8D6D7",
+"wL c #AFB0B2",
+"wM c #1B1C1E",
+"wN c #96CCFA",
+"wO c #A0CBEE",
+"wP c #0C375A",
+"wQ c #8F8F8F",
+"wR c #A9AAAE",
+"wS c #232428",
+"wT c #84BCEB",
+"wU c #1E374D",
+"wV c #263F55",
+"wW c #A3A7A8",
+"wX c #D5D9DA",
+"wY c #B2B2B2",
+"wZ c #001531",
+"w& c #A8C7E3",
+"x c #94B8D8",
+"x0 c #A1A1A1",
+"x1 c #D7D7D9",
+"x2 c #D8D8DA",
+"x3 c #0C0C0C",
+"x4 c #6B8FAF",
+"x5 c #A4C8E8",
+"x6 c #A2C9EA",
+"x7 c #0A3152",
+"x8 c #A2A2A2",
+"x9 c #787F89",
+"xa c #4C535D",
+"xb c #92CCFC",
+"xc c #95CBF7",
+"xd c #6AA0CC",
+"xe c #060D13",
+"xf c #BAC1C7",
+"xg c #18181A",
+"xh c #6C94B8",
+"xi c #A0C8EC",
+"xj c #AFC5DA",
+"xk c #1C3247",
+"xl c #686868",
+"xm c #D7D9D8",
+"xn c #D6D8D7",
+"xo c #9AA1A7",
+"xp c #2B3238",
+"xq c #9ECAED",
+"xr c #083457",
+"xs c #8B8B8D",
+"xt c #8D8D8F",
+"xu c #081828",
+"xv c #99A9B9",
+"xw c #96CBFD",
+"xx c #90CDFC",
+"xy c #91CBFD",
+"xz c #90CAFC",
+"xA c #8FC9F9",
+"xB c #8DC7F7",
+"xC c #8CC4F5",
+"xD c #89C1F2",
+"xE c #87BDEB",
+"xF c #82B8E6",
+"xG c #80B1DC",
+"xH c #7AABD6",
+"xI c #8298E4",
+"xJ c #899FEB",
+"xK c #ABCBFA",
+"xL c #B6D6FF",
+"xM c #B5C5D5",
+"xN c #8696A6",
+"xO c #A0A0A0",
+"xP c #A6A6A6",
+"xQ c #999999",
+"xR c #7B797A",
+"xS c #6B696A",
+"xT c #767678",
+"xU c #878789",
+"xV c #B2BCC5",
+"xW c #E1EBF4",
+"xX c #DEEEFE",
+"xY c #DFF1FF",
+"xZ c #D2EBFF",
+"x& c #CBE4FF",
+"y c #C1DDFF",
+"y0 c #C3DDFF",
+"y1 c #BCD0FF",
+"y2 c #A8BCEF",
+"y3 c #8E9DD8",
+"y4 c #6D7CB7",
+"y5 c #5C6D99",
+"y6 c #4E5F8B",
+"y7 c #506290",
+"y8 c #596B99",
+"y9 c #717DB7",
+"ya c #A7B3ED",
+"yb c #D6E4FF",
+"yc c #E8F6FF",
+"yd c #F2FCFF",
+"ye c #F0FCFF",
+"yf c #EEFAFF",
+"yg c #E1F4FF",
+"yh c #D9ECFD",
+"yi c #D5E4FF",
+"yj c #7D8CB3",
+"yk c #556795",
+"yl c #546694",
+"ym c #6B9CC4",
+"yn c #81B2DA",
+"yo c #84BAE9",
+"yp c #89BFEE",
+"yq c #8AC2F3",
+"yr c #8EC6F7",
+"ys c #8EC8FA",
+"yt c #8FC9FB",
+"yu c #8FCCFB",
+"yv c #92CCFE",
+"yw c #8FCDFC",
+"yx c #8ECCFB",
+"yy c #49565F",
+"yz c #6E7B84",
+"yA c #D3D3D3",
+"yB c #435362",
+"yC c #93CBFA",
+"yD c #5F686D",
+"yE c #353E43",
+"yF c #6D7B88",
+"yG c #404E5B",
+"yH c #AAC6DC",
+"yI c #1B374D",
+"yJ c #646464",
+"yK c #D3D3D5",
+"yL c #A7A7A9",
+"yM c #98999D",
+"yN c #CECFD3",
+"yO c #CDD1D4",
+"yP c #4B4F52",
+"yQ c #295071",
+"yR c #A1C8E9",
+"yS c #34393C",
+"yT c #676C6F",
+"yU c #D5D3D4",
+"yV c #B9B7B8",
+"yW c #001C35",
+"yX c #9FBBD0",
+"yY c #000B20",
+"yZ c #CECECE",
+"y& c #6F7983",
+"z c #8FCCF9",
+"z0 c #90CDFA",
+"z1 c #9AACBA",
+"z2 c #8F9190",
+"z3 c #D2D4D3",
+"z4 c #526574",
+"z5 c #314453",
+"z6 c #8FCDFE",
+"z7 c #8ECCFD",
+"z8 c #7CB6E6",
+"z9 c #102131",
+"za c #647585",
+"zb c #D4D4D6",
+"zc c #D5D5D5",
+"zd c #303940",
+"ze c #585F65",
+"zf c #3C4349",
+"zg c #9AA4AD",
+"zh c #00060F",
+"zi c #659DCC",
+"zj c #92CBFF",
+"zk c #8ECBFA",
+"zl c #8BC5F5",
+"zm c #8BC3F4",
+"zn c #87BFF0",
+"zo c #84BAE8",
+"zp c #80B6E4",
+"zq c #7FB0DB",
+"zr c #78A9D4",
+"zs c #8096E2",
+"zt c #879DE9",
+"zu c #A3C3F2",
+"zv c #B4D4FF",
+"zw c #CBDBEB",
+"zx c #A1B1C1",
+"zy c #959595",
+"zz c #747273",
+"zA c #787677",
+"zB c #DEE8F1",
+"zC c #E4EEF7",
+"zD c #DAEAFA",
+"zE c #CDDFF7",
+"zF c #C1DAF9",
+"zG c #BEDAFF",
+"zH c #BAD4F7",
+"zI c #A4BEE1",
+"zJ c #8CA0D3",
+"zK c #6E82B5",
+"zL c #5D6CA7",
+"zM c #51609B",
+"zN c #445581",
+"zO c #475987",
+"zP c #4B5D8B",
+"zQ c #58649E",
+"zR c #6470AA",
+"zS c #99A7C2",
+"zT c #C5D3EE",
+"zU c #E2ECF6",
+"zV c #E1EDF9",
+"zW c #DDE9F5",
+"zX c #D6E9FA",
+"zY c #CAD9FF",
+"zZ c #7584AB",
+"z& c #536593",
+"A c #699AC2",
+"A0 c #83B9E8",
+"A1 c #87BDEC",
+"A2 c #8BC5F7",
+"A3 c #8DC7F9",
+"A4 c #8DCAF9",
+"A5 c #8DCBFA",
+"A6 c #3F4C55",
+"A7 c #75828B",
+"A8 c #CFCFCF",
+"A9 c #283847",
+"Aa c #758594",
+"Ab c #6BA3D2",
+"Ac c #060F14",
+"Ad c #B0B9BE",
+"Ae c #354350",
+"Af c #6E7C89",
+"Ag c #637F95",
+"Ah c #1A364C",
+"Ai c #979799",
+"Aj c #030305",
+"Ak c #030408",
+"Al c #03070A",
+"Am c #282C2F",
+"An c #8AB1D2",
+"Ao c #214869",
+"Ap c #4B5053",
+"Aq c #C9CED1",
+"Ar c #B7B5B6",
+"As c #4E6E87",
+"At c #A4C4DD",
+"Au c #819DB2",
+"Av c #0D293E",
+"Aw c #828C96",
+"Ax c #37414B",
+"Ay c #8ECBF8",
+"Az c #90C8F7",
+"AA c #75ADDC",
+"AB c #132533",
+"AC c #697B89",
+"AD c #969897",
+"AE c #001221",
+"AF c #98ABBA",
+"AG c #8CCAFB",
+"AH c #8DCBFC",
+"AI c #90CAFA",
+"AJ c #93A4B4",
+"AK c #6C6C6E",
+"AL c #848D94",
+"AM c #363F46",
+"AN c #0B1218",
+"AO c #B5BCC2",
+"AP c #08121B",
+"AQ c #747E87",
+"AR c #90C9FE",
+"AS c #8DCBFE",
+"AT c #8CCAFD",
+"AU c #8BC8FE",
+"AV c #8AC7FD",
+"AW c #89C6FC",
+"AX c #87C4FA",
+"AY c #86C2F4",
+"AZ c #82BEF0",
+"A& c #82BAE9",
+"B c #7DB5E4",
+"B0 c #7AAEDD",
+"B1 c #74A8D7",
+"B2 c #7B96DD",
+"B3 c #839EE5",
+"B4 c #9DBCF2",
+"B5 c #B3D2FF",
+"B6 c #C4D8F3",
+"B7 c #AFB8C7",
+"B8 c #A0A9B8",
+"B9 c #9CA1A5",
+"Ba c #909599",
+"Bb c #8D9095",
+"Bc c #93969B",
+"Bd c #99A2A7",
+"Be c #B4BDC2",
+"Bf c #CDDAEA",
+"Bg c #DFECFC",
+"Bh c #DAEFFF",
+"Bi c #D3ECFF",
+"Bj c #CDE6FF",
+"Bk c #C4E2FF",
+"Bl c #BEDCFF",
+"Bm c #B8D8FF",
+"Bn c #BAD7FF",
+"Bo c #BACFFF",
+"Bp c #A2B7EE",
+"Bq c #8E9CD9",
+"Br c #7381BE",
+"Bs c #6072A0",
+"Bt c #526492",
+"Bu c #3E5B7B",
+"Bv c #3F5C7C",
+"Bw c #4E7596",
+"Bx c #547C9F",
+"By c #4D7598",
+"Bz c #476089",
+"BA c #506992",
+"BB c #5C68A2",
+"BC c #838FC9",
+"BD c #ADBEEA",
+"BE c #CCDDFF",
+"BF c #D2E5FF",
+"BG c #D1E4FF",
+"BH c #CCDFFF",
+"BI c #9EA9E1",
+"BJ c #6570A8",
+"BK c #4B648C",
+"BL c #679CC6",
+"BM c #7DBAE9",
+"BN c #81BEED",
+"BO c #87C1F3",
+"BP c #89C3F5",
+"BQ c #89C5FB",
+"BR c #8AC6FC",
+"BS c #8CC9FF",
+"BT c #323941",
+"BU c #888F97",
+"BV c #CACACC",
+"BW c #CACACA",
+"BX c #C9C9C9",
+"BY c #C0C0C0",
+"BZ c #000A29",
+"B& c #97B8D7",
+"C c #8DC9FF",
+"C0 c #A8C2D9",
+"C1 c #142E45",
+"C2 c #828483",
+"C3 c #C9CBCA",
+"C4 c #C8CAC9",
+"C5 c #C7C9C8",
+"C6 c #000F2B",
+"C7 c #90B2CE",
+"C8 c #394249",
+"C9 c #778087",
+"Ca c #223343",
+"Cb c #728393",
+"Cc c #94C7F2",
+"Cd c #83B6E1",
+"Ce c #8BAAC7",
+"Cf c #83A2BF",
+"Cg c #292C31",
+"Ch c #4E5156",
+"Ci c #C7C7C7",
+"Cj c #C9C9CB",
+"Ck c #ABABAB",
+"Cl c #001F3B",
+"Cm c #496884",
+"Cn c #8BC9FC",
+"Co c #7B95A6",
+"Cp c #183243",
+"Cq c #B4B5B7",
+"Cr c #0E0F11",
+"Cs c #91C7F5",
+"Ct c #00040E",
+"Cu c #78797B",
+"Cv c #C8C9CB",
+"Cw c #A2ABB2",
+"Cx c #060F16",
+"Cy c #568EBF",
+"Cz c #8FC7F8",
+"CA c #8DC9FB",
+"CB c #74B0E2",
+"CC c #122335",
+"CD c #5D6E80",
+"CE c #7C8083",
+"CF c #25292C",
+"CG c #858688",
+"CH c #B8BDC3",
+"CI c #1C2127",
+"CJ c #3B719F",
+"CK c #8DC9FD",
+"CL c #88C5FB",
+"CM c #80B8E7",
+"CN c #7BAFDE",
+"CO c #7792D9",
+"CP c #819CE3",
+"CQ c #94B3E9",
+"CR c #B2D1FF",
+"CS c #CBDFFA",
+"CT c #D1E5FF",
+"CU c #D8E1F0",
+"CV c #CDD6E5",
+"CW c #C8CDD1",
+"CX c #C3C8CC",
+"CY c #C6C9CE",
+"CZ c #CFD2D7",
+"C& c #D5DEE3",
+"D c #E2EBF0",
+"D0 c #DEEBFB",
+"D1 c #D2E7FA",
+"D2 c #CDE2F5",
+"D3 c #C3DCFA",
+"D4 c #BED7F5",
+"D5 c #B7D5F9",
+"D6 c #B6D6FD",
+"D7 c #B7D7FE",
+"D8 c #AFCCF6",
+"D9 c #9FBCE6",
+"Da c #7287BE",
+"Db c #6472AF",
+"Dc c #54629F",
+"Dd c #455785",
+"De c #465886",
+"Df c #4D6A8A",
+"Dg c #5A7797",
+"Dh c #5F86A7",
+"Di c #668DAE",
+"Dj c #6991B4",
+"Dk c #668EB1",
+"Dl c #657EA7",
+"Dm c #4A638C",
+"Dn c #54609A",
+"Do c #6C7DA9",
+"Dp c #95A6D2",
+"Dq c #ADC0E0",
+"Dr c #B0C3E3",
+"Ds c #AABDDE",
+"Dt c #92A5C6",
+"Du c #6B76AE",
+"Dv c #57629A",
+"Dw c #455E86",
+"Dx c #5D769E",
+"Dy c #6DA2CC",
+"Dz c #7FB4DE",
+"DA c #7EBBEA",
+"DB c #86C0F2",
+"DC c #1E252D",
+"DD c #99A0A8",
+"DE c #153655",
+"DF c #A1C2E1",
+"DG c #8BC9FA",
+"DH c #8CC8FE",
+"DI c #8AC8FB",
+"DJ c #486279",
+"DK c #2B455C",
+"DL c #C4C6C5",
+"DM c #C2C4C3",
+"DN c #153753",
+"DO c #A1C3DF",
+"DP c #1F282F",
+"DQ c #929BA2",
+"DR c #304151",
+"DS c #4C5D6D",
+"DT c #6598C3",
+"DU c #477AA5",
+"DV c #2C4B68",
+"DW c #00112E",
+"DX c #75787D",
+"DY c #C0C3C8",
+"DZ c #C5C5C7",
+"D& c #909090",
+"E c #0E0E0E",
+"E0 c #4E6D89",
+"E1 c #A3C2DE",
+"E2 c #89A3B4",
+"E3 c #031D2E",
+"E4 c #C3C4C6",
+"E5 c #303133",
+"E6 c #4F87B6",
+"E7 c #8EC6F5",
+"E8 c #366C9A",
+"E9 c #06101A",
+"Ea c #858F99",
+"Eb c #C2C3C5",
+"Ec c #A6A7A9",
+"Ed c #0E171E",
+"Ee c #636C73",
+"Ef c #8CC8FA",
+"Eg c #93A4B6",
+"Eh c #091A2C",
+"Ei c #707477",
+"Ej c #BFC0C2",
+"Ek c #31363C",
+"El c #4C5157",
+"Em c #8CC8FC",
+"En c #85C6FC",
+"Eo c #86C5FB",
+"Ep c #85C4FA",
+"Eq c #84C3F9",
+"Er c #84C0F6",
+"Es c #81BDF3",
+"Et c #7CB8EC",
+"Eu c #79B5E9",
+"Ev c #77AFE0",
+"Ew c #70A8D9",
+"Ex c #7594D4",
+"Ey c #7D9CDC",
+"Ez c #8CAAE6",
+"EA c #B1CFFF",
+"EB c #C6DFFD",
+"EC c #CCE5FF",
+"ED c #D0E6FE",
+"EE c #D2E8FF",
+"EF c #D5EAFF",
+"EG c #D7ECFF",
+"EH c #D8EAFE",
+"EI c #D3EBFF",
+"EJ c #CAE2FE",
+"EK c #B7D9FF",
+"EL c #B3D5FF",
+"EM c #B0D2FF",
+"EN c #B1D3FF",
+"EO c #B4D3FF",
+"EP c #AEC3FF",
+"EQ c #95AAE9",
+"ER c #8496D6",
+"ES c #7587C7",
+"ET c #667AAC",
+"EU c #596D9F",
+"EV c #3E5F80",
+"EW c #3C5D7E",
+"EX c #436E91",
+"EY c #517C9F",
+"EZ c #5889B2",
+"E& c #6394BD",
+"F c #659AC6",
+"F0 c #699ECA",
+"F1 c #689DC9",
+"F2 c #6497C2",
+"F3 c #5C8FBA",
+"F4 c #4D739A",
+"F5 c #41678E",
+"F6 c #536498",
+"F7 c #5C6DA1",
+"F8 c #6B7AB1",
+"F9 c #6E7DB4",
+"Fa c #6979AD",
+"Fb c #5B6B9F",
+"Fc c #4F658C",
+"Fd c #435980",
+"Fe c #436F96",
+"Ff c #618DB4",
+"Fg c #6FA9DB",
+"Fh c #7BB5E7",
+"Fi c #7CB9EF",
+"Fj c #7FBCF2",
+"Fk c #7FC0F6",
+"Fl c #82C3F9",
+"Fm c #84C5FB",
+"Fn c #87C6FC",
+"Fo c #87C5F8",
+"Fp c #88C6F9",
+"Fq c #010101",
+"Fr c #B3B3B3",
+"Fs c #505050",
+"Ft c #366A99",
+"Fu c #8FC3F2",
+"Fv c #86C7FD",
+"Fw c #8BC3F2",
+"Fx c #7AB2E1",
+"Fy c #050706",
+"Fz c #A7A9A8",
+"FA c #373737",
+"FB c #407AAA",
+"FC c #1C252C",
+"FD c #8A939A",
+"FE c #BCBEBD",
+"FF c #5B5B5B",
+"FG c #3B3B3B",
+"FH c #4F4F4F",
+"FI c #B0B0B0",
+"FJ c #BEBEC0",
+"FK c #BDBDBF",
+"FL c #B5BAC0",
+"FM c #575C62",
+"FN c #000A2C",
+"FO c #5A85A7",
+"FP c #001438",
+"FQ c #A2A2A4",
+"FR c #BEBEBC",
+"FS c #91918F",
+"FT c #00040D",
+"FU c #77818A",
+"FV c #7C8FA0",
+"FW c #4E6172",
+"FX c #17181A",
+"FY c #3F4042",
+"FZ c #839099",
+"F& c #3870A1",
+"G c #85C7FB",
+"G0 c #88C5FC",
+"G1 c #89C6FD",
+"G2 c #619FD2",
+"G3 c #88929B",
+"G4 c #BEBCBD",
+"G5 c #BFBDBE",
+"G6 c #AEAEAE",
+"G7 c #0D426E",
+"G8 c #85C6FE",
+"G9 c #82C1F7",
+"Ga c #83BFF5",
+"Gb c #80BCF2",
+"Gc c #71A9DA",
+"Gd c #6A89C9",
+"Ge c #7B9ADA",
+"Gf c #86A4E0",
+"Gg c #ABC9FF",
+"Gh c #C1DAF8",
+"Gi c #CFE5FD",
+"Gj c #D1E7FF",
+"Gk c #D3E8FD",
+"Gl c #D8E9FD",
+"Gm c #D7E8FC",
+"Gn c #D2EAFF",
+"Go c #C0D8F4",
+"Gp c #AED0FD",
+"Gq c #AFD1FF",
+"Gr c #ADCFFD",
+"Gs c #9FBEED",
+"Gt c #87A6D5",
+"Gu c #7E93D2",
+"Gv c #6E83C2",
+"Gw c #6779B9",
+"Gx c #596BAB",
+"Gy c #465A8C",
+"Gz c #435789",
+"GA c #496A8B",
+"GB c #58799A",
+"GC c #608BAE",
+"GD c #6A95B8",
+"GE c #6B9CC5",
+"GF c #6FA0C9",
+"GG c #71A6D2",
+"GH c #70A5D1",
+"GI c #6EA1CC",
+"GJ c #6B9EC9",
+"GK c #6F95BC",
+"GL c #5D83AA",
+"GM c #526397",
+"GN c #516296",
+"GO c #516097",
+"GP c #505F96",
+"GQ c #506094",
+"GR c #48588C",
+"GS c #455B82",
+"GT c #5C88AF",
+"GU c #739FC6",
+"GV c #76B0E2",
+"GW c #7DB7E9",
+"GX c #7DBAF0",
+"GY c #80BDF3",
+"GZ c #80C1F7",
+"G& c #66A4D7",
+"H c #B9B9B9",
+"H0 c #B7B9B8",
+"H1 c #B7B7B7",
+"H2 c #669AC9",
+"H3 c #8EC2F1",
+"H4 c #28608F",
+"H5 c #505251",
+"H6 c #86C0F0",
+"H7 c #8AC4F4",
+"H8 c #384148",
+"H9 c #626B72",
+"Ha c #B6B8B7",
+"Hb c #B9B9BB",
+"Hc c #B8B8BA",
+"Hd c #878787",
+"He c #191E24",
+"Hf c #353A40",
+"Hg c #7DA8CA",
+"Hh c #96C1E3",
+"Hi c #83C4FA",
+"Hj c #98C0E4",
+"Hk c #325A7E",
+"Hl c #404042",
+"Hm c #B8B8B6",
+"Hn c #7E8891",
+"Ho c #313B44",
+"Hp c #233647",
+"Hq c #495C6D",
+"Hr c #999A9C",
+"Hs c #B7B8BA",
+"Ht c #555555",
+"Hu c #00050E",
+"Hv c #6D7A83",
+"Hw c #83C5F9",
+"Hx c #84C6FA",
+"Hy c #87C4FB",
+"Hz c #86C4F7",
+"HA c #727C85",
+"HB c #0A141D",
+"HC c #B5B5B5",
+"HD c #81B6E2",
+"HE c #84C5FD",
+"HF c #81C4F9",
+"HG c #82C3FB",
+"HH c #81C2FA",
+"HI c #7FC2F9",
+"HJ c #7CBFF6",
+"HK c #80BFF5",
+"HL c #7DBCF2",
+"HM c #77B4EA",
+"HN c #75AFE1",
+"HO c #6A91CA",
+"HP c #7198D1",
+"HQ c #83A0E2",
+"HR c #A4C1FF",
+"HS c #BBD8FA",
+"HT c #C9E6FF",
+"HU c #D1E5FE",
+"HV c #D2E6FF",
+"HW c #D9EAFE",
+"HX c #DAEBFF",
+"HY c #BBD4F3",
+"HZ c #AECDFF",
+"H& c #A8C7FD",
+"I c #9AADF1",
+"I0 c #8699DD",
+"I1 c #788AC8",
+"I2 c #6D7FBD",
+"I3 c #657AA9",
+"I4 c #526796",
+"I5 c #3A5D7D",
+"I6 c #3E6181",
+"I7 c #517DA4",
+"I8 c #578CB8",
+"I9 c #6297C3",
+"Ia c #68A0D1",
+"Ib c #6DA5D6",
+"Ic c #70AADC",
+"Id c #72ACDE",
+"Ie c #71ADE1",
+"If c #71ADDF",
+"Ig c #6DA5D4",
+"Ih c #69A1D0",
+"Ii c #6095C1",
+"Ij c #5186B2",
+"Ik c #4B789F",
+"Il c #46739A",
+"Im c #5083AE",
+"In c #5D90BB",
+"Io c #67A0D5",
+"Ip c #72ABE0",
+"Iq c #7AB7ED",
+"Ir c #7CBBF1",
+"Is c #7EBDF3",
+"It c #7EBFF7",
+"Iu c #7FC0F8",
+"Iv c #80C1F9",
+"Iw c #81C4FB",
+"Ix c #92BFE6",
+"Iy c #3E6B92",
+"Iz c #484A49",
+"IA c #B1B3B2",
+"IB c #B0B2B1",
+"IC c #949BA1",
+"ID c #9DBBD5",
+"IE c #ACB0AF",
+"IF c #9CA09F",
+"IG c #888F95",
+"IH c #798086",
+"II c #13334C",
+"IJ c #476780",
+"IK c #001C38",
+"IL c #A3A3A3",
+"IM c #B3B1B4",
+"IN c #888888",
+"IO c #001C32",
+"IP c #407CAE",
+"IQ c #85C1F3",
+"IR c #7BBCF4",
+"IS c #000515",
+"IT c #4D5E6E",
+"IU c #AAAFB2",
+"IV c #696E71",
+"IW c #20425E",
+"IX c #6CABE1",
+"IY c #81C2F8",
+"IZ c #84C2FB",
+"I& c #83C1FA",
+"J c #88C2F2",
+"J0 c #255F8F",
+"J1 c #323637",
+"J2 c #AEB2B3",
+"J3 c #000F30",
+"J4 c #6E95B6",
+"J5 c #83C4FC",
+"J6 c #7FC4FB",
+"J7 c #7FC2F7",
+"J8 c #7EC1F8",
+"J9 c #7DC0F7",
+"Ja c #7FBEF4",
+"Jb c #7BB8EE",
+"Jc c #78B5EB",
+"Jd c #6E95CE",
+"Je c #6D94CD",
+"Jf c #7F9CDE",
+"Jg c #99B6F8",
+"Jh c #B8D5F7",
+"Ji c #C7E4FF",
+"Jj c #D1EAFF",
+"Jk c #B7D0EF",
+"Jl c #7897CD",
+"Jm c #7487CB",
+"Jn c #6D80C4",
+"Jo c #6072B0",
+"Jp c #4C5E9C",
+"Jq c #3D5281",
+"Jr c #445988",
+"Js c #4A6D8D",
+"Jt c #597C9C",
+"Ju c #5E8AB1",
+"Jv c #6A96BD",
+"Jw c #6A9FCB",
+"Jx c #6FA4D0",
+"Jy c #73ABDC",
+"Jz c #74AEE0",
+"JA c #77B1E3",
+"JB c #76B2E6",
+"JC c #76B2E4",
+"JD c #75B1E3",
+"JE c #74ACDB",
+"JF c #72AAD9",
+"JG c #6CA1CD",
+"JH c #6C99C0",
+"JI c #6996BD",
+"JJ c #6895BC",
+"JK c #6A97BE",
+"JL c #6A9DC8",
+"JM c #71A4CF",
+"JN c #77B0E5",
+"JO c #90BDE4",
+"JP c #002B52",
+"JQ c #818382",
+"JR c #AAACAB",
+"JS c #A9ABAA",
+"JT c #60676D",
+"JU c #7694AE",
+"JV c #000D27",
+"JW c #1F1F1F",
+"JX c #0F0F0F",
+"JY c #000201",
+"JZ c #090D0C",
+"J& c #171E24",
+"K c #282F35",
+"K0 c #25455E",
+"K1 c #9BBBD4",
+"K2 c #30536F",
+"K3 c #151515",
+"K4 c #6A6A6A",
+"K5 c #9A9A9A",
+"K6 c #ACAAAD",
+"K7 c #9E9C9F",
+"K8 c #232323",
+"K9 c #4E6A80",
+"Ka c #9EBAD0",
+"Kb c #84C0F2",
+"Kc c #8C9DAD",
+"Kd c #152636",
+"Ke c #333333",
+"Kf c #ABADAC",
+"Kg c #0F1417",
+"Kh c #2A2F32",
+"Ki c #6385A1",
+"Kj c #99BBD7",
+"Kk c #83C2F8",
+"Kl c #82C0F9",
+"Km c #85BFEF",
+"Kn c #202425",
+"Ko c #6D7172",
+"Kp c #A4A4A4",
+"Kq c #1D1D1D",
+"Kr c #4B7293",
+"Ks c #96BDDE",
+"Kt c #7DC2F9",
+"Ku c #7AC1F9",
+"Kv c #7BC0FB",
+"Kw c #79BEF9",
+"Kx c #7BC0F9",
+"Ky c #79BEF7",
+"Kz c #7ABCF6",
+"KA c #78BAF4",
+"KB c #76B9EE",
+"KC c #72B5EA",
+"KD c #71B0E5",
+"KE c #6BAADF",
+"KF c #689ACD",
+"KG c #6193C6",
+"KH c #8197E0",
+"KI c #94AAF3",
+"KJ c #B5D2FA",
+"KK c #C2DFFF",
+"KL c #D4E9FE",
+"KM c #D6EBFF",
+"KN c #CFE9FF",
+"KO c #AFC9EE",
+"KP c #889BDD",
+"KQ c #6B7EC0",
+"KR c #5C739C",
+"KS c #445B84",
+"KT c #335777",
+"KU c #3B5F7F",
+"KV c #3F7098",
+"KW c #4D7EA6",
+"KX c #558BB9",
+"KY c #6096C4",
+"KZ c #649ECE",
+"K& c #69A3D3",
+"L c #6AA9DC",
+"L0 c #6BAADD",
+"L1 c #6FAEE4",
+"L2 c #71B0E6",
+"L3 c #71B2E8",
+"L4 c #74B5EB",
+"L5 c #75B6EE",
+"L6 c #73B6ED",
+"L7 c #74B7EE",
+"L8 c #74B5ED",
+"L9 c #72B3EB",
+"La c #70B1E7",
+"Lb c #6FB0E6",
+"Lc c #6FAEE3",
+"Ld c #6CABE0",
+"Le c #6AA7DD",
+"Lf c #6BA8DE",
+"Lg c #70AFE4",
+"Lh c #74B3E9",
+"Li c #74B6F0",
+"Lj c #76B8F2",
+"Lk c #77B9F3",
+"Ll c #78BFF7",
+"Lm c #79C0F8",
+"Ln c #7ABFFA",
+"Lo c #7AC1F7",
+"Lp c #64839F",
+"Lq c #001632",
+"Lr c #68707B",
+"Ls c #656D78",
+"Lt c #576572",
+"Lu c #485663",
+"Lv c #2C4355",
+"Lw c #102739",
+"Lx c #001034",
+"Ly c #4D7B9F",
+"Lz c #7DBFF3",
+"LA c #4587BB",
+"LB c #5897CC",
+"LC c #69A8DD",
+"LD c #74B9F2",
+"LE c #4A7FA9",
+"LF c #063B65",
+"LG c #000F29",
+"LH c #00102A",
+"LI c #001A30",
+"LJ c #08243A",
+"LK c #052137",
+"LL c #000C26",
+"LM c #00284B",
+"LN c #123E61",
+"LO c #4483B8",
+"LP c #80BFF4",
+"LQ c #7ABFF8",
+"LR c #7AC0FB",
+"LS c #78BDF6",
+"LT c #336183",
+"LU c #081D30",
+"LV c #33485B",
+"LW c #616870",
+"LX c #747B83",
+"LY c #737C83",
+"LZ c #384F5F",
+"L& c #0B2232",
+"M c #00082B",
+"M0 c #20486B",
+"M1 c #67ACE3",
+"M2 c #7BC0F7",
+"M3 c #79C2F9",
+"M4 c #78C1F8",
+"M5 c #82BEF2",
+"M6 c #272A2F",
+"M7 c #64676C",
+"M8 c #3C5162",
+"M9 c #7BBFFC",
+"Ma c #73B6EB",
+"Mb c #73B2E7",
+"Mc c #6C9ED1",
+"Md c #6092C5",
+"Me c #7E94DD",
+"Mf c #8CA2EB",
+"Mg c #B3D0F8",
+"Mh c #BFDCFF",
+"Mi c #DAECFF",
+"Mj c #D0EAFF",
+"Mk c #AAC4E9",
+"Ml c #7D90D2",
+"Mm c #576AAC",
+"Mn c #395079",
+"Mo c #425982",
+"Mp c #486C8C",
+"Mq c #567A9A",
+"Mr c #598AB2",
+"Ms c #6394BC",
+"Mt c #659BC9",
+"Mu c #6AA0CE",
+"Mv c #6BA5D5",
+"Mw c #6FA9D9",
+"Mx c #6EADE0",
+"My c #70AFE2",
+"Mz c #73B2E8",
+"MA c #75B6EC",
+"MB c #76B7ED",
+"MC c #77B8F0",
+"MD c #75B8EF",
+"ME c #76B9F0",
+"MF c #76B7EF",
+"MG c #73B4EA",
+"MH c #72B3E9",
+"MI c #72B1E6",
+"MJ c #6FAEE1",
+"MK c #70ADE3",
+"ML c #71AEE4",
+"MM c #77B6EC",
+"MN c #79BBF5",
+"MO c #7BC2F8",
+"MP c #85A4C0",
+"MQ c #153450",
+"MR c #272F3A",
+"MS c #2F3742",
+"MT c #364451",
+"MU c #44525F",
+"MV c #546B7D",
+"MW c #71889A",
+"MX c #80AED2",
+"MY c #8EBCE0",
+"MZ c #7EC0F4",
+"M& c #88BDE7",
+"N c #96BAD4",
+"N0 c #85A9C3",
+"N1 c #7B97AD",
+"N2 c #7793A9",
+"N3 c #7894AA",
+"N4 c #87ABC5",
+"N5 c #97BBD5",
+"N6 c #7FBEF3",
+"N7 c #8EBCDE",
+"N8 c #74899C",
+"N9 c #495E71",
+"Na c #313840",
+"Nb c #1D242C",
+"Nc c #1D262D",
+"Nd c #2F383F",
+"Ne c #435A6A",
+"Nf c #6D8494",
+"Ng c #92BADD",
+"Nh c #7ABFF6",
+"Ni c #205C90",
+"Nj c #2E3136",
+"Nk c #979A9F",
+"Nl c #000617",
+"Nm c #889DAE",
+"Nn c #76BEF9",
+"No c #77BFFA",
+"Np c #75BDF8",
+"Nq c #76BAF7",
+"Nr c #74B8F5",
+"Ns c #72B9F1",
+"Nt c #6FB6EE",
+"Nu c #6EB1E8",
+"Nv c #69ACE3",
+"Nw c #68A2D2",
+"Nx c #4F89B9",
+"Ny c #798FD8",
+"Nz c #869CE5",
+"NA c #A3C3F4",
+"NB c #D6E8FE",
+"NC c #D9E9FF",
+"ND c #CEEAFF",
+"NE c #A7C3EA",
+"NF c #7B8FCE",
+"NG c #586CAB",
+"NH c #365C80",
+"NI c #486E92",
+"NJ c #4F84B0",
+"NK c #598EBA",
+"NL c #5C98CA",
+"NM c #619DCF",
+"NN c #63A2D7",
+"NO c #66A5DA",
+"NP c #67AADF",
+"NQ c #6AADE2",
+"NR c #6CB1E8",
+"NS c #6EB3EA",
+"NT c #70B5EE",
+"NU c #71B6EF",
+"NV c #71B9F4",
+"NW c #72BAF5",
+"NX c #73B9F5",
+"NY c #74BAF6",
+"NZ c #73BBF5",
+"N& c #72BAF4",
+"O c #74B9F4",
+"O0 c #73B8F3",
+"O1 c #71B8F0",
+"O2 c #70B7EF",
+"O3 c #6EB3EC",
+"O4 c #6CB3E9",
+"O5 c #6CB1EA",
+"O6 c #6DB2EB",
+"O7 c #6FB4ED",
+"O8 c #73BBF6",
+"O9 c #75BBF7",
+"Oa c #76BDFB",
+"Ob c #77BDF9",
+"Oc c #75BDF7",
+"Od c #76BEF8",
+"Oe c #73BEF8",
+"Of c #74BFF9",
+"Og c #77A5C7",
+"Oh c #4E5B64",
+"Oi c #1C2932",
+"Oj c #0A1117",
+"Ok c #2A3137",
+"Ol c #5E87A7",
+"Om c #8FB8D8",
+"On c #7ABBF3",
+"Oo c #5F6972",
+"Op c #0E1821",
+"Oq c #939393",
+"Or c #6F7982",
+"Os c #000912",
+"Ot c #4B8CC2",
+"Ou c #7ABBF1",
+"Ov c #74BCF7",
+"Ow c #75B9F6",
+"Ox c #73B7F4",
+"Oy c #6DB4EC",
+"Oz c #538DBD",
+"OA c #7288D1",
+"OB c #8298E1",
+"OC c #99B9EA",
+"OD c #B5D5FF",
+"OE c #CFE3FC",
+"OF c #D4E8FF",
+"OG c #C6E2FF",
+"OH c #A6C2E9",
+"OI c #768AC9",
+"OJ c #576BAA",
+"OK c #395F83",
+"OL c #50769A",
+"OM c #558AB6",
+"ON c #5E93BF",
+"OO c #5F9BCD",
+"OP c #64A0D2",
+"OQ c #6DB0E5",
+"OR c #6DB2E9",
+"OS c #70B8F3",
+"OT c #72B8F4",
+"OU c #71B9F3",
+"OV c #72B7F2",
+"OW c #6DB4EA",
+"OX c #74BBF9",
+"OY c #74BCF6",
+"OZ c #72BDF7",
+"O& c #4A789A",
+"P c #001133",
+"P0 c #323F48",
+"P1 c #767D83",
+"P2 c #51585E",
+"P3 c #001434",
+"P4 c #3E6787",
+"P5 c #79BAF2",
+"P6 c #3E7FB7",
+"P7 c #030D16",
+"P8 c #6D7780",
+"P9 c #061019",
+"Pa c #626C75",
+"Pb c #78B9EF",
+"Pc c #6DBCF7",
+"Pd c #70BAF9",
+"Pe c #6FBBF7",
+"Pf c #6FB9F8",
+"Pg c #6EB8F7",
+"Ph c #6DB7F4",
+"Pi c #6AB4F1",
+"Pj c #6AB0EB",
+"Pk c #62A8E3",
+"Pl c #64A3D6",
+"Pm c #5594C7",
+"Pn c #6685C6",
+"Po c #7897D8",
+"Pp c #8FACE6",
+"Pq c #B2CFFF",
+"Pr c #D1E9FF",
+"Ps c #C3E3FF",
+"Pt c #A0C0E9",
+"Pu c #7080BC",
+"Pv c #4E5E9A",
+"Pw c #356289",
+"Px c #4F7CA3",
+"Py c #538FC1",
+"Pz c #5FA0D8",
+"PA c #63A4DC",
+"PB c #63ACE3",
+"PC c #66AFE6",
+"PD c #6AB0EE",
+"PE c #6BB1EF",
+"PF c #6AB5EF",
+"PG c #6BB6F0",
+"PH c #6CB6F3",
+"PI c #6EB8F5",
+"PJ c #6EBAF6",
+"PK c #6AB6F0",
+"PL c #69B5EF",
+"PM c #6CB3F1",
+"PN c #6CB6F5",
+"PO c #6DB7F6",
+"PP c #6FB9F6",
+"PQ c #70BCF8",
+"PR c #72B9F9",
+"PS c #71BBF8",
+"PT c #71BBFA",
+"PU c #6EBAF4",
+"PV c #70BAF7",
+"PW c #71B8F8",
+"PX c #76B8EC",
+"PY c #6DAFE3",
+"PZ c #656565",
+"P& c #6D6D6D",
+"Q c #7F7F7F",
+"Q0 c #6A6E6F",
+"Q1 c #000405",
+"Q2 c #6C7A87",
+"Q3 c #000A17",
+"Q4 c #646665",
+"Q5 c #7E807F",
+"Q6 c #6E777E",
+"Q7 c #0C151C",
+"Q8 c #25689D",
+"Q9 c #75B8ED",
+"Qa c #6FBBF9",
+"Qb c #6BBAF5",
+"Qc c #6DB9F5",
+"Qd c #69B3F0",
+"Qe c #65ABE6",
+"Qf c #5998CB",
+"Qg c #5E7DBE",
+"Qh c #7392D3",
+"Qi c #86A3DD",
+"Qj c #AAC7FF",
+"Qk c #C4DCF8",
+"Ql c #D0E8FF",
+"Qm c #BEDEFF",
+"Qn c #9FBFE8",
+"Qo c #6F7FBB",
+"Qp c #4B5B97",
+"Qq c #38658C",
+"Qr c #5380A7",
+"Qs c #5692C4",
+"Qt c #5E9ACC",
+"Qu c #61A2DA",
+"Qv c #66A7DF",
+"Qw c #64ADE4",
+"Qx c #67B0E7",
+"Qy c #6CB2F0",
+"Qz c #6CB7F1",
+"QA c #6BB5F2",
+"QB c #6CB8F4",
+"QC c #6BB7F1",
+"QD c #6DB4F2",
+"QE c #6FB6F4",
+"QF c #70B7F7",
+"QG c #6DB9F3",
+"QH c #6AB9F4",
+"QI c #75B7EB",
+"QJ c #1F6195",
+"QK c #2F2F2F",
+"QL c #303030",
+"QM c #505455",
+"QN c #15191A",
+"QO c #515F6C",
+"QP c #757776",
+"QQ c #6F7170",
+"QR c #111A21",
+"QS c #464F56",
+"QT c #74B7EC",
+"QU c #6DB9F7",
+"QV c #6CB8F6",
+"QW c #69AFEB",
+"QX c #65ABE7",
+"QY c #62A5DC",
+"QZ c #599CD3",
+"Q& c #537AB3",
+"R c #668DC6",
+"R0 c #829BDE",
+"R1 c #A1BAFD",
+"R2 c #BED8FB",
+"R3 c #CCE6FF",
+"R4 c #98B8EB",
+"R5 c #6C7FB9",
+"R6 c #465993",
+"R7 c #396A93",
+"R8 c #5485AE",
+"R9 c #5F9ED1",
+"Ra c #62A4E0",
+"Rb c #67A9E5",
+"Rc c #64AEEB",
+"Rd c #67B1EE",
+"Re c #6BB7F5",
+"Rf c #6DB8F9",
+"Rg c #6BB9F7",
+"Rh c #8CB0D0",
+"Ri c #001838",
+"Rj c #626463",
+"Rk c #090A0C",
+"Rl c #636466",
+"Rm c #64696F",
+"Rn c #3F444A",
+"Ro c #040605",
+"Rp c #080A09",
+"Rq c #5E5E5E",
+"Rr c #767676",
+"Rs c #6A7378",
+"Rt c #141D22",
+"Ru c #13548A",
+"Rv c #6EBAF8",
+"Rw c #66ACE8",
+"Rx c #63A6DD",
+"Ry c #5DA0D7",
+"Rz c #5D84BD",
+"RA c #5F86BF",
+"RB c #7B94D7",
+"RC c #95AEF1",
+"RD c #B8D2F5",
+"RE c #C8E2FF",
+"RF c #B0D0FF",
+"RG c #90B0E3",
+"RH c #687BB5",
+"RI c #3C6D96",
+"RJ c #5788B1",
+"RK c #5A99CC",
+"RL c #61A0D3",
+"RM c #65A7E3",
+"RN c #69ABE7",
+"RO c #66B0ED",
+"RP c #7498B8",
+"RQ c #001232",
+"RR c #767877",
+"RS c #101113",
+"RT c #0F1012",
+"RU c #01060C",
+"RV c #2D3238",
+"RW c #0F1110",
+"RX c #636564",
+"RY c #6E6E6E",
+"RZ c #121B20",
+"R& c #3E474C",
+"S c #6BB1ED",
+"S0 c #67ADE9",
+"S1 c #65A8DF",
+"S2 c #5EA1D8",
+"S3 c #5E92C4",
+"S4 c #497DAF",
+"S5 c #768DD3",
+"S6 c #8AA1E7",
+"S7 c #AAC9F7",
+"S8 c #BEDDFF",
+"S9 c #D6EAFF",
+"Sa c #D5EBFF",
+"Sb c #D6ECFF",
+"Sc c #CDEAFF",
+"Sd c #ACC9FF",
+"Se c #8BA8E2",
+"Sf c #657AAF",
+"Sg c #455A8F",
+"Sh c #4073A0",
+"Si c #588BB8",
+"Sj c #599AD0",
+"Sk c #62A3D9",
+"Sl c #65A9E6",
+"Sm c #69ADEA",
+"Sn c #69B3F2",
+"So c #6AB4F3",
+"Sp c #7296B6",
+"Sq c #000F2F",
+"Sr c #606062",
+"Ss c #171719",
+"St c #0C0C0E",
+"Su c #343436",
+"Sv c #6F6F6F",
+"Sw c #636C75",
+"Sx c #0D161F",
+"Sy c #19588E",
+"Sz c #68AEEA",
+"SA c #66A9E0",
+"SB c #60A3DA",
+"SC c #6397C9",
+"SD c #6D84CA",
+"SE c #8198DE",
+"SF c #9CBBE9",
+"SG c #B7D6FF",
+"SH c #D0E4FC",
+"SI c #D5E9FF",
+"SJ c #D1E7FE",
+"SK c #CBE1F8",
+"SL c #BCD9FB",
+"SM c #B3D0F2",
+"SN c #A9C6FF",
+"SO c #819ED8",
+"SP c #6176AB",
+"SQ c #4275A2",
+"SR c #5A8DBA",
+"SS c #5C9DD3",
+"ST c #63A4DA",
+"SU c #66AAE7",
+"SV c #6AAEEB",
+"SW c #6BB5F4",
+"SX c #002444",
+"SY c #4A4A4A",
+"SZ c #777779",
+"S& c #78787A",
+"T c #050E17",
+"T0 c #4E5760",
+"T1 c #76B5EB",
+"T2 c #68AEEC",
+"T3 c #61A3DF",
+"T4 c #609CD2",
+"T5 c #508CC2",
+"T6 c #6080BD",
+"T7 c #7090CD",
+"T8 c #90AAE7",
+"T9 c #AFC9FF",
+"Ta c #B7D8FF",
+"Tb c #B3D8FF",
+"Tc c #AED3FF",
+"Td c #A9CDFD",
+"Te c #ABC3FF",
+"Tf c #7C94D2",
+"Tg c #5A74A5",
+"Th c #435D8E",
+"Ti c #457AAC",
+"Tj c #5B90C2",
+"Tk c #5E9FD7",
+"Tl c #64A5DD",
+"Tm c #67ABE8",
+"Tn c #6BB2F2",
+"To c #6DB4F4",
+"Tp c #6FB6F6",
+"Tq c #70B4F1",
+"Tr c #4589C6",
+"Ts c #000419",
+"Tt c #23394E",
+"Tu c #616264",
+"Tv c #727375",
+"Tw c #474C52",
+"Tx c #04223C",
+"Ty c #000721",
+"Tz c #3375AF",
+"TA c #73B5EF",
+"TB c #6DB3F1",
+"TC c #69AFED",
+"TD c #63A5E1",
+"TE c #629ED4",
+"TF c #5A96CC",
+"TG c #5676B3",
+"TH c #6A8AC7",
+"TI c #7F99D6",
+"TJ c #9FB9F6",
+"TK c #ADCEF9",
+"TL c #AACFFB",
+"TM c #AACEFE",
+"TN c #A8CCFC",
+"TO c #95ADEB",
+"TP c #6D85C3",
+"TQ c #516B9C",
+"TR c #466091",
+"TS c #4C81B3",
+"TT c #6095C7",
+"TU c #65A6DE",
+"TV c #6CB3F3",
+"TW c #71B5F2",
+"TX c #7C92A7",
+"TY c #30465B",
+"TZ c #000002",
+"T& c #050A10",
+"U c #2A2F35",
+"U0 c #4E6C86",
+"U1 c #90AEC8",
+"U2 c #72B4EE",
+"U3 c #6FB6F8",
+"U4 c #6DB7F8",
+"U5 c #6EB5F7",
+"U6 c #6CB3F5",
+"U7 c #6CB1F2",
+"U8 c #6AAFF0",
+"U9 c #63A7E4",
+"Ua c #60A1D7",
+"Ub c #5B9CD2",
+"Uc c #588ABF",
+"Ud c #5082B7",
+"Ue c #788BD0",
+"Uf c #8699DE",
+"Ug c #9EB8F5",
+"Uh c #AECBFF",
+"Ui c #A1B8FB",
+"Uj c #869DE0",
+"Uk c #687AB8",
+"Ul c #3F668F",
+"Um c #456C95",
+"Un c #4E8AC0",
+"Uo c #5E9AD0",
+"Up c #60A2DE",
+"Uq c #68ACEB",
+"Ur c #6BAFEE",
+"Us c #6FB4F5",
+"Ut c #6EB5F5",
+"Uu c #70B7F9",
+"Uv c #6CB6F7",
+"Uw c #6DB4F6",
+"Ux c #64A8E5",
+"Uy c #5FA0D6",
+"Uz c #6294C9",
+"UA c #4F81B6",
+"UB c #687BC0",
+"UC c #7588CD",
+"UD c #7A94D1",
+"UE c #829CD9",
+"UF c #829FD9",
+"UG c #7A97D1",
+"UH c #768DD0",
+"UI c #6B82C5",
+"UJ c #6476B4",
+"UK c #495B99",
+"UL c #3B628B",
+"UM c #5279A2",
+"UN c #5793C9",
+"UO c #639FD5",
+"UP c #64A6E2",
+"UQ c #66A8E4",
+"UR c #69ADEC",
+"US c #6EB3F4",
+"UT c #70B5F8",
+"UU c #6FB4F7",
+"UV c #6FB2F6",
+"UW c #6DB0F4",
+"UX c #6BAFF0",
+"UY c #67ABEC",
+"UZ c #67A7E5",
+"U& c #63A3E1",
+"V c #619ED7",
+"V0 c #5895CE",
+"V1 c #507EB2",
+"V2 c #4E7CB0",
+"V3 c #6683BB",
+"V4 c #6D8AC2",
+"V5 c #6E87BF",
+"V6 c #6D86BE",
+"V7 c #5F7EAD",
+"V8 c #496897",
+"V9 c #365F8B",
+"Va c #3F6894",
+"Vb c #467DB3",
+"Vc c #578EC4",
+"Vd c #5E9CD9",
+"Ve c #65A3E0",
+"Vf c #66A7E7",
+"Vg c #69AAEA",
+"Vh c #6DB1F2",
+"Vi c #6DB2F5",
+"Vj c #71B4F8",
+"Vk c #71B5F6",
+"Vl c #70B5F6",
+"Vm c #70B5FA",
+"Vn c #6EB3F6",
+"Vo c #6EB1F5",
+"Vp c #69ADEE",
+"Vq c #69A9E7",
+"Vr c #66A6E4",
+"Vs c #66A3DC",
+"Vt c #6593C7",
+"Vu c #5583B7",
+"Vv c #4D6AA2",
+"Vw c #415E96",
+"Vx c #405991",
+"Vy c #3E5D8C",
+"Vz c #486796",
+"VA c #4C75A1",
+"VB c #5B84B0",
+"VC c #5D94CA",
+"VD c #649BD1",
+"VE c #64A2DF",
+"VF c #68A6E3",
+"VG c #68A9E9",
+"VH c #6BACEC",
+"VI c #70B3F7",
+"VJ c #70B4F5",
+"VK c #6FB4F9",
+"VL c #70B2E6",
+"VM c #6EB0E4",
+"VN c #6EADE2",
+"VO c #6AAADA",
+"VP c #67A7D7",
+"VQ c #65A2D1",
+"VR c #619ECD",
+"VS c #5C95C2",
+"VT c #548DBA",
+"VU c #5287B3",
+"VV c #5288B4",
+"VW c #578DB9",
+"VX c #5D97C5",
+"VY c #639DCB",
+"VZ c #64A2D1",
+"V& c #68A6D5",
+"W c #69A7DA",
+"W0 c #6CAADD",
+"W1 c #71B4E9",
+"W2 c #72B5EC",
+"W3 c #627ED4",
+"W4 c #627ED5",
+"W5 c #617ED5",
+"W6 c #637ED3",
+"W7 c #647ED2",
+"W8 c #657ED1",
+"W9 c #667ED0",
+"Wa c #687FCE",
+"Wb c #687FCD",
+"Wc c #697FCC",
+"Wd c #6B7FCA",
+"We c #6D80C9",
+"Wf c #6E80C8",
+"Wg c #6E80C7",
+"Wh c #7180C4",
+"Wi c #7280C3",
+"Wj c #7481C1",
+"Wk c #7681BF",
+"Wl c #7781BD",
+"Wm c #7A81BB",
+"Wn c #7B82BA",
+"Wo c #7D82B8",
+"Wp c #7E82B6",
+"Wq c #8182B3",
+"Wr c #8283B2",
+"Ws c #8483B0",
+"Wt c #8683AE",
+"Wu c #8983AB",
+"Wv c #8B84A9",
+"Ww c #8D84A6",
+"Wx c #8E85A4",
+"Wy c #9185A2",
+"Wz c #9385A0",
+"WA c #95859D",
+"WB c #97869B",
+"WC c #998699",
+"WD c #9B8697",
+"WE c #9D8794",
+"WF c #A18790",
+"WG c #A2888F",
+"WH c #A3888D",
+"WI c #A6888B",
+"WJ c #A88889",
+"WK c #AA8987",
+"WL c #AC8984",
+"WM c #AE8981",
+"WN c #B18A7F",
+"WO c #B38A7D",
+"WP c #B58A7B",
+"WQ c #B88B78",
+"WR c #BA8B76",
+"WS c #BB8B74",
+"WT c #BE8B71",
+"WU c #C08C6F",
+"WV c #C18C6E",
+"WW c #C48D6B",
+"WX c #C58D69",
+"WY c #C88E67",
+"WZ c #CA8E64",
+"W& c #CC8E62",
+"X c #CE8E60",
+"X0 c #CF8E5E",
+"X1 c #D18F5C",
+"X2 c #D48F59",
+"X3 c #D68F57",
+"X4 c #D79057",
+"X5 c #D89055",
+"X6 c #DC9052",
+"X7 c #DC9051",
+"X8 c #DE914F",
+"X9 c #DF914E",
+"Xa c #E1914C",
+"Xb c #E2924B",
+"Xc c #E49248",
+"Xd c #E59247",
+"Xe c #E79245",
+"Xf c #E89245",
+"Xg c #EA9342",
+"Xh c #EB9342",
+"Xi c #EC9341",
+"Xj c #ED943F",
+"Xk c #EE943E",
+"Xl c #EF943D",
+"Xm c #F0943D",
+"Xn c #F1943B",
+"Xo c #F2943B",
+"Xp c #F2943A",
+"Xq c #F39539",
+"Xr c #F49539",
+"Xs c #F59539",
+"Xt c #F69537",
+"Xu c #F69637",
+"Xv c #F79637",
+"Xw c #F69638",
+"Xx c #F69639",
+"Xy c #F59639",
+"Xz c #F4963A",
+"XA c #F4963B",
+"XB c #F3953C",
+"XC c #F2953C",
+"XD c #F2963D",
+"XE c #F1963F",
+"XF c #EF9641",
+"XG c #EE9642",
+"XH c #ED9643",
+"XI c #EC9645",
+"XJ c #EA9647",
+"XK c #EA9648",
+"XL c #E99649",
+"XM c #E8954B",
+"XN c #E6954D",
+"XO c #E5954E",
+"XP c #E3944F",
+"XQ c #E29551",
+"XR c #E19553",
+"XS c #DF9556",
+"XT c #DD9558",
+"XU c #DB955A",
+"XV c #DA955C",
+"XW c #D8955E",
+"XX c #D69560",
+"XY c #D59562",
+"XZ c #D49464",
+"X& c #D29466",
+"Y c #D09468",
+"Y0 c #CE946B",
+"Y1 c #CC936D",
+"Y2 c #CA936F",
+"Y3 c #C89371",
+"Y4 c #C69374",
+"Y5 c #C49377",
+"Y6 c #C39379",
+"Y7 c #C0937C",
+"Y8 c #BE937E",
+"Y9 c #BC9281",
+"Ya c #BB9282",
+"Yb c #B89285",
+"Yc c #B79286",
+"Yd c #B49289",
+"Ye c #B3928C",
+"Yf c #B1918F",
+"Yg c #AF9191",
+"Yh c #AC9194",
+"Yi c #AA9196",
+"Yj c #A99198",
+"Yk c #A7919A",
+"Yl c #A5919D",
+"Ym c #A290A0",
+"Yn c #A190A2",
+"Yo c #9F90A4",
+"Yp c #9D90A7",
+"Yq c #9B90A9",
+"Yr c #998FAB",
+"Ys c #978FAD",
+"Yt c #958FAF",
+"Yu c #938FB2",
+"Yv c #928FB3",
+"Yw c #8F8FB8",
+"Yx c #8E8FB8",
+"Yy c #8C8EBB",
+"Yz c #8A8EBD",
+"YA c #888EBF",
+"YB c #888EC0",
+"YC c #868EC3",
+"YD c #838EC6",
+"YE c #828EC7",
+"YF c #808EC9",
+"YG c #7E8DCB",
+"YH c #7D8DCD",
+"YI c #7C8DCF",
+"YJ c #7A8DD0",
+"YK c #788DD2",
+"YL c #778DD4",
+"YM c #768DD5",
+"YN c #758CD7",
+"YO c #748CD8",
+"YP c #738CDA",
+"YQ c #718CDC",
+"YR c #6F8CDE",
+"YS c #6F8CDF",
+"YT c #6D8CE0",
+"YU c #6B8CE3",
+"YV c #6B8CE4",
+" 0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 3 4 5 6 7 8 9 a b c d e f g h i j 7 k l 3 m 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 n n 1 0 0 n 0 o o 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
+" p p q q p p q q p p q q p p q q p p q q p p q q p p n 0 3 5 r 8 j s a t u v w x y z A 7 B C 2 1 q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p D q q p D q E F F q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q p p q q",
+" G G H H G G H H G G H H G G H H G G H H G G H H I J K L M N O P Q R S T U V W X Y Z &0 000102030405 H H0606 H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H H H H H G G H H G G H H05 G H H G G H H G G H H G G H H G G0707 G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H G G H H",
+"0808090908080909080809090808090908080909080809090a I L L0b0c O0d Q0e0f0g0h0i0j0k0l0m0n0o0p0q030r G0s09090t0t0909080809090808090908080909080809090808090908080909080809090808090908080909080809090808090908080909080809090808090909090909080809090808090908080909080809090s0809090808090908080u0u0808090908080909080809090808090908080909080809090808090908080909080809090808090908080909080809090808090908080909",
+"0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0x0y0z0A0B0C0D0E0F0G0H0I0J0K0L0M0N0O0P0Q0R0S0T0U0V0y0x0w0w0v0v0W0W0v0v0w0w0v0v0W0W0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0x0X0X0x0x0v0v0w0x0X0X0v0v0v0v0Y0Y0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w0v0v0w0w",
+"0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z1 0w0w0y0A0B0C0S0E0F101112131415161718191a1b0T1c0z0y0w1 0&0&0Z0Z1d1d0Z0Z0&0&0Z0Z1d1d0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&1e0Z0&0&0Z0Z0&1 0Z0Z0&0&0Z0Z0Z0Z0Z0Z1f1f0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&0Z0Z0&0&",
+"1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1i1j1k1l1m1n1o1p1q1r1s1t1u1v1w1x1y1z1A1B1C1D1E1o1n1F1l1G1H1I1h1g1g1h1h1g1g1h1h1J1J1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1K1K1g1g1h1h1L1M1N1O1P1P1Q1Q1g1R1h1h1g1g1K1K1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h1g1g1h1h",
+"1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1U1V1I1G1m1W1X1Y1Z1&2 202122232425262728292a1o1n2b1l1G1i1g1V2c1U1S1T1T1S1S1T1T2d2d1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S2e2e1S1S1T1T2f2g2h2i2j2k2l2m1U1S1T1T1S1S2e2e1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T1S1S1T1T",
+"2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2p2q2r1Q2s2t2u2v2w2x2y2z2A2B2C2D2E2F2G2H2I2J2K2L2M2N2O2O2P2Q2R2R2q2p2o2S2T2T2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2p2n2U2V2W2X2Y2Z2&3 303132333435363637372n2n38382n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o2n2n2o2o",
+"39393a3a39393a3a39393a3a39393a3a39393a3a3b2n3c3d2s2t3e3f3g3h3i3j3k3l3m3n3o3p3q3r2J3s2L3t3u2N2s2O2P3v3w3w2q2p2o2S3x3y3a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a3b393a3a3z3A3B3C3D3D3D3E3F3G3H3I3J3K3L3M39393N3O39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a39393a3a",
+"3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3T3U3V3W3X3Y3Z3&4 404142434445464748494a3Y3Y4b4c4d4e4f4g4h4i3W4j4k4l4m4n3T4o3Q3Q3S3S3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3T3P4p4p4q4r4s4t4u4v4v4v4s4s4v4u4w4x4y4z4A4B4C4C3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R3S3S3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3R3R",
+"4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E3Q3P4o4H3W4I4J4K4L4M4N4O4P444Q464R4S484T4U4V4J4W4X4Y4Y4Z4&5 4f5051524l4m4n3T3P3Q4E534G4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4E4E5454555556574s584v4v4v4u4t4t4v4v59594u5a5b5c5d5d4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F4G4G4E4E4D4D4E4E4D4D4E4E4D4D4F4F",
+"5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5g5e5f5h5i5j5k5l5m5n5o5p5q5r5s5t5u5v5w5x5y5z5A5B5A5A5C5D5E5E5F5G5H5I5J5K5L5M5N5O5j5j5P5h5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5Q5Q5f5f5e5e5f5f5R5e5f5S5T5U4u3D4v4v4v4v4u594v4v4v4v4u5V5W5X5Y5Z5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f5e5e5f5f",
+"5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5&6 5O606162636465666768696a6b6c6d6e6f6f6f6e6g6h6i6j6k6l6m6n6o6p6q6r6s6t6u6v5O6w5&6x5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h6y6y6z6z5R5R5h5h6x5R5f5h6A6B4u4v4u4u4u4u4u4u4u4u4v4v4u6C6D6E5Z6F5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h5R5R5h5h",
+"4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D6G3R6H6I6J4f6K6L6M6N6O6P6Q6R6S6T6U6V6W6X6Y6Z6&7 70717272737475767778797a7b4I517c4m7d7e7f4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4E4E4E4E7f7g4E7h7i7j4v4v4u4u4u4u4u4u4s4s4v4v7k7l7m5R7h5d4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E4D4D4E4E",
+"3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3T7n7o3V4j7p4Z7q7r7s6N7t7u7v7w7x7y7z7A7B7C7D7E7F7G7H7I7J7K7L7M7N7O7P7Q7R7S7T7U7V517W7X7Y7Z4C3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3Q3Q3Q3Q7&7&3Q3Q8 804v4v4u4u4u4u4u4u4s4s4v4u818283833Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q3P3P3Q3Q",
+"8484858586868585848485858484858587883b2p898a8b3s8c8d8e8f8g8h8i8j8k8l8m8m8n8o8p8q8r8s8t8u8v8w8x8y8z v8A8B8C8D8E8F8G8H8I8J8K8L8M8M8484858586868585848485858N7n858584848484878485858M8M858M8N8N858584848585848485858686858584848585868685858484858587844C8I313D4u4v4u4u4u4u4u4u4u4u4u4v8O8P8Q8485858R8R858M8487858M8484858M8484858M8R8R858584848585848Q85858487858S84848585848485858585858584848585858585858N8N858M",
+"87878M8M8T8T8M8M87888M8M87878U3a888V2p2Q8a3u8W2I8X8Y8Z8&9 909192939495969798999a9b9c9d8u8v8v9e9e9f9g9h9i9j9k9l9m9n8G9o9p9q9r2n3988878M8M8T8T8M8M87878M8M7n7n8U8U8888878787878M8M8M8M8M8M7n7o393988888M8M87878M8M8T8T8M8M87878M8M8T8T8M8M87878M8M88879s9t9u4u4u4v4u4u4u4u4u4u4u4u4u9v9w9x87878M8M9y9y393987878M8M88878M8M87878M399z9z8M8M87878M8M87888M8587888M8M87878M8M87878M8M8M8M8M8M8787858M8M8M8M397n7n8M8M",
+"9A9A9B9B9A9A2S2S9A9A9B9B9A9A9C9C2p2q2Q2P9D9E9F9G9H9I9J9K9L9M9N9O9P9Q9R9S9T9U9V9W9X9Y9Z9&a a a0a0a1a2a3a4a5a6a7a8a9aaabacad3vaeaeaf9C9B9B9A9A9B9B9A9A9B9B9Aag9B9B9A9A9B9B9A9A9B9B9A9Aahah9A9A9B9B9Aai9B9Bajaj9B9B9A9Aakak9A9A9B9B9A9A9B9B9A9A9B9Bai9Aalaman4u4u4v4u4u4u4u4u4u4s4s4uaoapaqai9A9B9B9A9A9B9B9A9A9B9Bai9Aar9B9A9A9A9A3b3b9B9B9A9A9B9B9A9A9A9A9A9A9B9C9A9A9B9B9A9A9B9B9B9B9B9B9Aai9B9C9A9A9B9B9A9A2S3a",
+"aiai9C9Caiai2o2oaias9C9Caiasatau3v2Pavawaxay9GazaAaBaCaDaEaFaGaHaIaJaKaLaMaNaOaPaQaRaS9&aTaUaVaVaWaXaYa3aZa&b b0b1a9b2b3b4avb5b6ataf9C9C9Aai9C9Caiai9Cafaias9C9C9Aai9B9Caiai9C9Basb7b8b99Aai9C9Caiai9C9Cbaba9C9Caiaibbbbaiai9C9Caiai9C9Caiai9C9Casasalbcbd4u4v4v4u4u4u4u4u4u4s4s4vbebfbgaiaiafafai9A9C9B9Aai9C9Caiai9C9Caiaiaiai2n2p9C9Casai9C9Caiaiaiasaiai9C9Caiai9C9Caiai9C9C9C9C9C9Caiai9C9Caiaiaf9Caiai2o2o",
+"bhbhbibibhbhbibibhbhbibibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb&c c0c1ayc2c3c4c5c6c7bjbjbhbhbibjbhbhbibibhbhbjbiafafc8c8c9cacbcccdcecfcgchchcici60602Tcjckbhbibibhbhchchbhbhbibibhbhclclbhbhcmcmcncncocpcq4u4u594v4u4u4u4s4s4u4ucrcscmcmbjbibibictctcucvcwcxcyczcAcBcCc9asasafafbhbhbibibhbhbibibibicmcmcDcEcFcobhbhbibibhbhbibibibjcGcHcIcJcKcLasasbibicMcMclcl",
+"ckckbjbjckckbjbjcNckbkbkblbmcOcPcQcRcScTcUcVcWcXcYcZc&c&d d0d1d2d3aMbGbGd4d5d6d7d8d9dadbdcdddedfdgdhbVdidjdkdldmdndodpc1dqdrdsc4dtc6bkbkckckbjbjckckbjbjckckbjbjaududvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdL9EckckbjbjckckdFdFckckbjbjckckdMdMckckdNdNdOdPdQdRdS4u4u594u4u4u4u4s4s4u4udTdUdNdNbkbjbjbjdVdWdXdYdZd&e e0e1e2e3e4e5e6atauckckbjbjckcNbjbkbkbkdNe7e8e9eaebckckbjbjckckbjbjbkecedeeefegeheieje6bjbjekeldMcl",
+"ememenenememeoeoepeqerereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLbHbHeMeNeOePeQeReSeTeUeVeWeXeYeZe&f f0f1f1f2f3f4f5f6f7f8f9cTfaevfbfcerfdememeoeoemfeeoeoememfffgfhfifjfkflfmfnfofpfpfqfrfsftfufv6CfwfxfyfzfAeoeoememfBfBememeoeoememeoeoememeoeoememfCfDfmfmfmfEfmfmfFfGfHfHfmfIfJfKfdeofLfMfNfOfPfQfRfnfofofmfEfEfEfEfSfTfUfVc6ememfWfWememfXfYfZf&g g0g1g2g3g4ememememfVfVeoeog5g6g73Efmfmg8g9ga2Reoeoepepeoeo",
+"gbgbgcgcgbgberergdgegfggghgigjgkglgmgngogpgqgrgsgtgugvgwgxgygzgzbHbHgAgBgCgCgDgEgFgGgHgIgJgKgLgMgNgOf0f1gPf0gQgRgSgSgTgUgVf9gWfagXghgYgZgbgberergbgbererg&h h0h1h2h33E3E3E3Eh4h5h6h6h7h8h9ha3E3E3E3Ehbhchdhderergbgbhehegbgberergbgberergbgbererg&gbhfhghbfEhb3EfEhbhhhhfphifEhjhkhlererhmhnfOhodS3Eh4h5h4h43E3Ehbhb3E3Ehphqhrhsgbgbhthug&gbhvhwhxhyhzhhh4h4hAhBgbgbgbgbhshsererhChD3E3E3E3EhEhFhGhGererhHgderer",
+"hIhIhJhJhKhK0Z0ZhLhMhNhNhOhPgWhQhRhShThUhVhWhXhYhZh&i i0i1i2eLi3i4i4i5i6i7i8i9iaibeMicidieifigihbVdif1gPiigPijikiliminioipiq0R1biris0X1eithIhJhJiuhIhJhJiviwixdSdS3EiyiyiziAdSdSdSiBiCiBiDiEiFiGiHiIiJiKiLiMiNiOhIhIhJ0ZhIhIhJhJhIhIhJhJhIhIhJiPiQiR4ziSdSdSiB3EiTiTdSdSiUiViWiXiYiZi&j j0aoj1iTdSiBiKiBiVj2j3j4j5j6j7iKizj8j9jaivivjbjcjdjejfjgjhdSiViViViUjijjithIhJiPhIitjkjljmjniziziB6CjojphIhIhJhJhIhIhJhJ",
+"itit0Z0Zjqjr1e0vjsjtjujvjwjxjyjzjAjBjCjDhWjEjFjGjHjIi i0i1jJgzi3jKjLjMjNjOjPjQjRjSjTjUjVifjWjXjYbVdif1gPiiiijZj&k k0k1k2k3k4k51ak6k7k80Xk9it0Z0Zitit0Z0ZhLjskakb9v9vkckckdke9v9viLiLkffwkgkhkikjkkklkmkniLkokpkqitit0Z0Zitit0Z0ZhIit0Z0Zitit0Z0ZiQkriM9v9v9v9v9vksks9viLktkukvkwgZkxkykzfI9vkskA9viLiL5VkBkCkDkEkFkGkHkIkJkKkLkMkNkOkPkQkRkSkTksiJ9vkuktktktkUkVitit0Z0Zitk9kWkXkYiLkJkdkZkak&l ititl0l0itit0Z0Z",
+"l1l1l2l2l3l3l4l5l6l7l8l9lalblcldlelflglhliljlklllmlnloi0lplqgzi3bHlrlsltlulvlwlxlylzlAlBlClDlEbVbVdif1gPlFiilGlGlHlIlJlKlLlMlNlOkOlPlQl5lRl3lSlSlTl1l2l2l1l1lUlViLknknkblWlWiLknfllXlYlZl&m m0m0l1l1m1m2kbkbm3m4lTl1l2m0l1l1l2l2m5m5l2l2l1l1m6m6m7m8m9maknkbktktknknkbknknmbmcmdmemfhjflmgmalWmhmhmhmimjmkmll2l2l1l1mmmnmompmqmrmsmtmumvknknlWlWiLknkbkbkbkbmwmxl1l1l2l2mymzmAmBkbkbmamCmDmEl2l2l1l1l2l2l1l1l2l2",
+"l3l3m0l4lRmFmGmHmImJl9mKlbmLmMmNmOmPmQmRmSmTmUmVmWmXmYmZm&lqgzi3bHgzn n0n1n2n3n4n5n6n7n8n9nanbbVbVdif1f1lFiilGlGf0ncndlJnenfngnhninjnkmHmFlRnlnll1l3m0m0lRl3nmnnkfkfkfkfnonokfnpkfnqnrnsjshMm0l4lRlRntnukfnvnwnxl3l3m0l4lRl3l4m0nynyl4m0lRl3nznAnBnCnDnEkfkfnonFkfkfkfkfnpbenGnHnInJnpnpnEnDnonononKnLnMnNnNm0l4l3lRnOnPnQnRnSnTnUnVnvnvnpkfnWnoflkfkfnpnpnpnXnYl3l3m0l4eunZn&o npnpo0o1o2o3l4m0l3l3m0m0l3l3m0m0",
+"o4o4o5o6o7o8o9oaobocmKodoeofogohoiojokolomonooopoqorosotouovowoxbGeMoyozoAoBoCoCoDoEoFoGoHoIoJoJdidigPoKoLoMfG7k7koNoOoPoQoRoSoToUmKoVoWoXo8oYoZo4o4oYoZo6o5o&p jhjhjhp0jhjhjhp0p1p2oYoZp3o4oYoYp4p4p5p6jhp0p7p8oap9oYoYp9o7oYoYo4o4papao4o4pbjw4zpcp0jhpdpepepejhp0pfpgphpipjpkpl5Vp0p0jhjhp0p0pmpnpoppo4o40808o4o4pqprpsp0ptpupvpwp0p0jhp0p0jhpxjhjhp0p0jhpypzp3o4o4o4pApBpC5Vp0pDpEpFo4p3oZpGp4p4oYoYo4o4oYoY",
+"p3p3o6pHoXo9oWoVpIpJpKpLpMpNpOpPpQmSpRpSpTpUpVpWpXpYpZp&q q0q1oxbGeMq2q3q4oB9dq5q6q7q8q8q9q9qaqbdiqcgPoKoLoM7k4s4s4sqdqeoQqfqgqhqiqjqkoVoaoXqloZp3p3oZoZo6pHqmqn5a5ako5a5a5a5a5aqoqpoZoZp3p3oZoZqqqqqrqsjnjnqtquqvo7oZoZo8o7oZqlp3p3papap3qwqxqyqz5ajn5aqAqAqAqA5a5aqBqCqDqEqFqGqH5a5ajnjn5a5aqIqJqKqLqLp3qw0s0sp3p3qMqNqOjnqPqQqRkwjnjn5a5ajn5ako5ajn5ajn5aqSqTp3p3p3qUqVqW5ajniSqXqYqZp3p3oZoZqqqqoZoZp3p3oZoZ",
+"q&q&r r0r1r2r3r4r5r6r7r8r9rarbrcrdrerfrgrhrikYrjrkrlrmrnrorprqrreMeMrsoCoC9drtrtrurvrw9&rxryrzrArBrCgPoKiiii4t4s4v4vrDrErFrGrHrIrJrKrLrMrNrOr0r0q&q&r r0q&q&rPrQrRrRrRrRrRrRrRrSrTrUr0r q&rVr0r q&rWrXrYrZrRrRr&s pHr r s0s0s1s1s2s3s4s4q&q&s5s6s7s8rRrRrZrRrRrRrRrZs9sasbscsdserZrRrRrRrRrZrRsfsgshr0r q&rVsisjq&q&skslrmrRsmsnsospsqsrrRrRrRrRrRjnrRrZssstsusvq&q&swsxqOrZs8syszsAr r0q&q&r r0q&q&r r q&q&r r ",
+"rVrVsBsBsCsDsEsFsGsHsIsJsKsLsMrcsNsOsPsQrhsRrSsSsTsUsVsWsXsYsZs&eMeNt oCoC9drtrtt0t1t2t3t4t5t6t7t8t9f1oKiiii4t4s4v4vtatbtctdtetftgthtitjtkrNtlsBrVrVr0sBtmrVcctnfIfItofIfIfIfItptqtrr0r0rVtmr0r0rVq&tsttlXlXtotutvtwr0r0txtytztAtBtCtDtErVrVtFtGsysyfIfIlXfIfIfIlXfItHtIsctJtKtLfIfIfIfIfIfItMtNtOscsBsBtmrVsjsjtmrVtPtQtRpDtStTtUtVtWtXfIfItofItofIfIlXtYtYsutZrVrVt&u iSlXsyu0u1u2sBsBrVrVr0r0rVrVr0r0rVrVr0r0",
+"u3u3u4u5u5u6u7u8u9uaubucudueufuguhuipciCujukulumunuoupuqurusutuueMeNuvuwuwuxuyuzuAuBuCuDuEuFuGuHuIuJgFuKlGlG584t4s4tuLuMuNuOuPuQuRrJuSuTuUuVuWuWu3u3uXuXuYuZu&v iSiSiSv0v1v1v2v3v4sBuXu4u3u3uXuXv5v6jmv7v0v0v8v9vavbvcvdvevfvgvhvivjvkvlvmvnvoqHvpvqiSiSiSiSiSiSiSvrvsvtvuvvvjv0iSiSiSv0v0v0vwvxuZuZuXuXu3u3uXuXvyrOvzvAvqvBvCvDvEu3vFvGhcv0vqvqvHiSvIvIv0v0qSvJk6vKvLvMvpvpvNvOvPvavQvQvRu3vSuXu3u3uXuXu3u3uXuX",
+"vTvTvUu6vVvWvXvYvZv&w w0udw1w2uguhw32&w4w5w6w7w8w9vBwawbwcwd9cuueNeNuwuxuwwegzwfwgwgwhwiwjwkwlwmwnwowpwqwrws584s4t4twtwuwvwwwxwywzwAwBuSwCuUwDwEwFvTvUu5wGwGwHv pCpCpCwIwJwKwLwMwNwNu5vUvTvTu5u5wOwPwQwIwIwIwRwSuWwTwUwVwWwXwIwIpDwYwZw&x vsx0pCx1x2pCpCpCpCpCwIulx3x4x5x6x7x8wIpCpCpCwIpDpCx9xawGxbu5u5vTvEu5u5xcxdxexfqCxgxhxiwFvTxjxkxlpCx1x1pCpCxmxnwIwIxoxpxqxrxsx1x1xtxuxvuWuWxwxwvTvTu5u5vTvTu5u5vTvTu5u5",
+"xxxxxyxzxAxBxCxDxExFxGxHxIxJxKxLxMxNxOw7xPx8xQwQxRxSxTxUxVxWxXgAeMeNxYlqxZx&y y y0y0y1y2y3y4y5y6y7y8y9yaybycydydyeyfygyhyiyjykylymynyoypyqyrysytyuxxyvyvywyxyyyzqHqHqHyAyAqHtGyBxxxxxxxxxxxxyCyCyDyEyAyAyAyAyFyGyHyIyJqIyKyLyMyNyOyPyQyRySyTyAyAqHqHqHqHqHqHyUyVyWnGxyxyyXyYyZqHqHqHqHyAyAqHy&ccz z0yvyvxxxxyCyCz1eez2z3z4z5yvyvz6z7xbz8z9zazbyKqHzcqHyAyAyAkUzdzezfqHqHzgzhziwExbxbzjzjxxxxyvyvxxxxyvyvxxxxyvyv",
+"zkzkytysxBzlzmznzozpzqzrzsztzuzvzwzxzyx0xOzy6CuqzzzA4xujzBzCgAgAi2zDt7zEzFzFzGrczHzIzJzKzLzMzNzNzOzPzQzRzSzTzUoAzVzWzXzXzYzZz&y7A ynA0A1yqxCA2A3A4zkxzxzA5A5A6A7A8A8A8yZyZA8A9AazkzkzkyuzkzkwDAbAcAdyZyZA8yZAeAfAgAhyZyZAiAjwSAkAlAmAnAoApAqiCA8A8A8A8A8yZA8ArjfAsAtytxzAuAvyZyZA8A8A8A8yZyZAwAxAyAyytytA4A4AzAAABACo0ADAEAFytytAGAHAIAIAJz9AKqCA8A8A8yZyZyZALAMANAOiCwYAPAQAzwDAIAIARARyuzkxzxzzkzkxzxzzkzkxzxz",
+"ASATAUAVAWAXAYAZA&B B0B1B2B3B4B5lkB6B7B8B9BaBbBcBdBeBfBgBhBhBiBjBkBlBmBmBnBnBoBpBqBrBsBtBuBvvvBwBxByBzBABBBCBDBEBFBGBFBHBIBJBKwxBLtDBMBNBOBPBQBRAUBSBSBSATATBTBUBVBVBWBWBXBYBZB&AHAGC C ATATC0C1C2C3C4C5BXcqC6C7C8C9BWBXCaCbCcCdCeCfCgChCiBXBXBWs7CjBXBXBXCkClCmASCnAUBSCoCpC4C3tRBWBWBXBWBXCqCrAzAzBSAUCsu7fNCtCuCvCwCxCyCzBSBSATATBSAUCACBCCCDBWBWBXBXBXBXCECFCGCvCHCICJCsAUBSATATCKCKASATBSBSATATBSBSATATBSBS",
+"CnCnAVAWCLAXAYAZCMB CNB1COCPCQCRCSCTCUCVCWCXCYCZC&D uuD0D1D2D3D4D5D5D6D7D8D96&DaDbDcDdDeDfDgDhDiDjDkDlDmDnzQDoDpDqDrDsDtDuDvDwDxDyDzDABNDBBPBQBRAUAUAUAUCnCnDCDDujujpcj7j7upDEDFDGDGDHDHDICnDJDKDLoqDMoqpcfwDNDODPDQj7pcDRDSDTDUDVDWDXDYj7j7j7mbDZujj7j7D&E E0E1CnCnAVAUE2E3DMDMmbj7j7pcj7j7E4E5E6E7AUAUCsE8E9EaEbEcEdEeCzvWAVAUCnCnAVAUEfEfEgEhvhj7j7pcpcpcEifsEbEjEkElCsCsAUAUDICnEmEmCnCnAUAUCnCnAUAUCnCnAUAU",
+"EnEnEoEpEpEqErEsEtEuEvEwExEyEzEAEBECEDEEEFEGgzd4lpEHEIEJEKELEMENEOB5EPEQERESETEUEVEWEXEYEZE&F F0F0F1F2F3F4F5F6F7F8F9FaFbFcFdFeFfFgFhFiFjFkFlEpEpFmEnFnEoFoFpFqFrrjkYmCmCkYFsFtFuFvEnFnFnFwFxFyFzkYrSkYkYkYFAFBzlFCFDFEFEulFFFGFHpsFIkYrSmCFEFJFKkYkYFLFMFNFOFnEoEnEnFnFn0FFPFQFJkYrjkYkYrSkYFRFSFTFUFVFWFXFYkZrSFZqDF&xCFmEnFnFnG G G0G1EnEnFoG2zhG3rSkYG4G5psG6kYfxG7uTFmEnFnFnG8G8FnFnEnEnFnFnEnEnFnFnEnEnFnFn",
+"FmFmEoEpEqG9GaGbEtEuEvGcGdGeGfGgGhx&GiGjGkGkGlGmEHEHGnGoGpGpGqGrGsGtGuGvGwGxGyGzGAGBGCGDGEGFGGGHGGGHGIGJGKGLGMGNGOGPGQGRGSqfGTGUGVGWGXGYFkGZEqEpFmFmEoEoFoG&ix2&H 2&H0H0H1ixH2H3FmFmEoEoFwH4H5H02&H12&2&kIkHH6H7H8H9HaHaH1H12&H12&2&2&2&H0H0HbHc2&HdHeHfHgHhEpEoHiFmEoEoHjHkHlHc2&2&2&H12&H1HmHmHnHoHpHqHrHsFIHtHuHvzmyqHiFmEoEoHwHxHyHyFmFmFoHzHAHBum2&yVyVHC2&fvFqHDu9HiFmEoEoHEHEEoEoFmFmEoEoFmFmEoEoFmFmEoEo",
+"HFHFHGHHHIHJHKHLFiHMHNFgHOHPHQHRHSHTHUHVrzloi i0HWHXxZHYHZH&I I0I1I2I3I4I5I6FeI7I8I9IaIbIcIdIeIeIfIfIdFgIgIhIiIjIkIlIlIkImInIoIpHMIqIrIsItIuIvHHIwIwHGHHIxIyIzIAIBIBIBIAICcsHGHHIwIwHGHGIDtQaoulIEIFIGIHIIIJHGHHtVIKILulwYwYIAIAwYwYIMIMwYulwYINyIIOIPIQIwIwHGHGIwIwHGHGHGIRISITFIulIBIBwYwYululwYwYulwYIUIVIKIWIXEqHGHGIwIwHFHFIwIwHiIYIwIwIZI&J J0J1J2wYulwYrmJ3J4HGHGIwIwHGJ5J6J6HGHGIwIwHGHGIwIwHGHGIwIwHGHG",
+"J7J7IvIuJ8J9JaHLJbJcGVFgJdJeJfJgJhJiHVHVrzloi i0HWHXJjJkCQJlJmJnJoJpJqJrJsJtJuJvJwJxEwJyJzJAJBJBJCJDJAJzJEJFGGJGJHJIJJJKJLJMIpJNJcIqIrJaItIuIuIvHIHIIvIvJOJPJQJRJSJRJRJRJTh8IvIvHIHIIvIvJUJVJWJXJYJZJ&K K0K1IvIvsoK2K3K4K5CkJRJSCkkZK6K7fwyJK8kHK9KaKbKbJ8HIIvIvHIHIIvIvIuIvKcKdKeupKfJRkZkZkZkZCkCkD&HtKgKhKiKjG9KkIvIvHIHIJ7J7HIHIGZGZHIHIKlKlKmKmKnKoCkkZKpKqKrKsIvHHHIHIIvIvKtKtIvIvHIHIIvIvHIHIIvIvHIHIIvIv",
+"KuKuKvKwKxKyKzKAKBKCKDKEKFKGKHKIKJKKHVryKLKMi i0lplpKNKOKPKQKRKSKTKUKVKWKXKYKZK&L L0L1L2L3L4L5L5L6L7L8L9LaLbLcLdL0L LeLfKELgL2LhLiLjLkKzLlLmLnKvLoLoKvKvLpLqLrLsLtLuLvLwLxLyLnKvKuKuKvKvLzLALBLCLDKxKvKvLmKuKvKvKuKuLELFLGLHLILJLKqGLLtQLMLNLOLPKuKuLQKxKuKuLRLRKuKuKvKvKuKuKxLSLTFNLULVLWLXLYEeLZL&M M0M1M2KvKvKuKuKxKxM3M3KxKxM3M4KvKvKuKuKvKvM5M5M6M7KpKpM8kyKuKuKvKvKuKuKvKvKuKuKvKvKuKuM9M9KuKuKvKvKuKuKvKv",
+"KuKuKvKvLQKyKzKAKBMaMbKEMcMdMeMfMgMhHVryKLKLi i0lpMiMjMkMlMmMnMoMpMqMrMsMtMuMvMwMxMyMzLhMAMBMCMCMDMEMFL5MGMHMbMIMJMyMKMLLgMbLhMMLjLkMNKzLmLmKvKvMOLoKvKvMPMQMRMSMTMUMVMWMXMYKvLnKuKuKvKvMZMZLPLPLQLQLnKvKuKuKvKvKuKuM&M&N N0N1N2N3qFN4N5nhnhLPN6LmKuKxKxKuLmLRLRKuKuKvKvLmKuKxKxN7N7N8N9NaNbNcNdNeNfNgNgNhM2LnKvKuKuKxKxM3M3KxKxM3M3KvKvKuKuKvKvM5NiNjNkw8hjNlNmLmKuKvKvKuKuKvKvKuKuKvKvKuKuM9M9KuKuKvKvKuKuKvKv",
+"NnNnNnNoNpNpNqNrNsNtNuNvNwNxNyNzNABmHVryNBi NCNCeKgzNDNENFNGNHNINJNKNLNMNNNONPNQNRNSNTNUNVNWNXNYNZN&O O0O1O2NTO3O4O4O5O6O6O7NtO1NWO8NYO9NpNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnOaOaNnNnNnNoNnNnNnNnNpNpNnNpObObObObOcOdNnNnNpNnOcOdNnNoNnNnNnNnNpNnNpNnNnNnNnNnNpNnOeOfNpNnNnNnNnNnNnNoNnNpNnNnNpNnNpNnOdOdNnNnNnNnNnNnmLOgOhOiOjOkOlOmOnOnOoOpbdOqOrOsOtOuOdOdNnNpNnNnNnNnObObNnNnNnNnNnNnNnNnNnNnNnNnNnNn",
+"OvOvOvOvOvO8OwOxO2OyNuNvK&OzOAOBOCODOEOFNBi NCNCeKeLOGOHOIOJOKOLOMONOOOPNOLCNQOQORNSNTNUOSNVOTOTOUOUO0OVO2NtNTNTOWO4O6O3O3O7NtO2OSNVNXNYOvOvOvOvOvOvOvOvOvOvOvO8O8OvOvOvOvO8OvOvOvOvOXOXOvNpOvOvOvOvOvOvOvOvOvOvNYO9NYO9OYOYOvO8OvOvOYNZO8OvO8OvOvOvO8OvOvOvOvOvOvOvOvOvOZOZOvOvOvOvO8OvOvO8OvOvOvOvOvOvOvOvOYOYOvOvO8O8O8OvO&P P02gP1P2P3P4P5P6P7P8up3 P9PaPbPbOYOYOvOvOvOvOvOvO9O9OvOvOvOvOvOvOvOvOvOvOvOvOvOv",
+"PcPcPdPdPePePfPgPhPiPjPkPlPmPnPoPpPqrdPrNBi i0i0HXHXPsPtPuPvPwPxPyNLPzPAPBPCPDPEPFPGPHPhPIPIPfPfPJPJPgPgPhPHPHPHPKPLPMPMPFPGPNPOPIPPPgPdPePePdPdPJPePfPdPePQPdPdPePJPdPdPePePdPfPQPePRPRPJPePdPdPePePdPdPPPSPTPdPUPUPdPdPVPVPPPVPePePVPVPePePdPfPcPcPRPRPePePdPdPePePdPdPePePdPdPePePWPRPePePdPdPePePdPdPePePdPdPePePRPWPXPYFqPZrnP&vhQ Q0Q1Q2Q3Q4Q5Q6Q7Q8Q9PfPdPePePdPdPePePdPdPePePVPVQaQaPdPdPePePdPdPePePdPd",
+"QbQbPgPgQcQcPgPOPHQdPjQePlQfQgQhQiQjQkQli i i0lpHXd4QmQnQoQpQqQrQsQtQuQvQwQxPEQyPGQzQAPhPhPhPOPOQBQBPgPOPhPhPHPHQCQCQDQEQzQzPNPOPhPhPgPgPJQcPgPgQcQcPgPgQcQcPOPgQcQcPOPgQcQcPgPOQcQcQFQFPJQcPgPgQcQcPgPgPIPIPgPgPUQGPfPgPIPIPIPIQcQcPIPIQBQcPgPgQHQbQFQFQcQcPgPgQcQcPgPgPJQcPgPgQcQBQFQFQBQcPgPOQcQcPgPfQcQcPgPgQcQcQFQFQIQJQKpsQLplqOpsQMQNQ3QOQPQQQRQSQTMaPOPgQcQcPgPgQcQcPfPgQcQcPIPIQUQUPgPgQcQcPgPgQcQcPgPg",
+"QUQUQUQUQUQUQVQVQAQdQWQXQYQZQ&R R0R1R2R3NBi i0lpeLeKBmR4R5R6R7R8QfR9RaRbRcRdPiQAReReQVQVQUQURfRfQUQUQUQUQVQVReReReRePNPNReQVQVQVQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQURgRgQUQUPJQcQVQVRhRiRjQPRkRlRmRnRoRpRqRrRsRtRuMAQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQU",
+"QUQUQUQURvQUQUQVPHPiQWRwRxRyRzRARBRCRDREi i i0lpeLeKRFRGRHR6RIRJRKRLRMRNROQdQAPHQVQUQUQUQUQURfRfQUQUQUQUQUQUQUQUQVQVPOPOQVQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQURgRgQUQUQcQcQVQURPRQRRQPRSRTRURVRWRXRrRYRZR&MAL4QUQUQURvQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQUQU",
+"PgPgPgPgPgPgPgPOPHPiS S0S1S2S3S4S5S6S7S8OFS9SaSbScKKSdSeSfSgShSiSjSkSlSmSnSoPNPOPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPfPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgQUQUPOPgPgPgSpSqRrpsSrSsStSuSvpsSwSxSyMMPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPg",
+"PgPgPgPgPfPgPgPgPHQAS SzSASBSCS4SDSESFSGSHSISJSKSLSMSNSOSPSgSQSRSSSTSUSVSoSWPOPOPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgQUQUPfPgPgPgRhSXSYpsSZSZS&SZpsiMT T0MMT1PgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPg",
+"POPOPOPOPOPOPOPOPNSWQyT2RbT3T4T5T6T7T8T9TaugTbTcTdTdTeTfTgThTiTjTkTlTmSVTnToPNPOTpTpQVQVPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPNPOTqTrTsTtTuTvdUTwTxTyTzTAPOPNPOPOPNPNPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPO",
+"POPOPOPOPOPOPOPOPNSWTBTCRNTDTETFTGTHTITJTKTKTLTLTMTNTOTPTQTRTSTTPzTUTmSVTVToPNPOTpTpQVQVPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOTWTqTXTYRTTZT&U U0U1TAU2POPOPOPOPNPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPO",
+"U3U3U3U3U3U3U4U4U5U6U7U8TmU9UaUbUcUdUeUfUgT9UhSdUiUjI1UkUlUmUnUoUpRMUqUrTVToU5U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U3U5U3U3U3U5U3UsU7U3U3U3U3U3U3TpUtU3UuU3U3U3UuU3U3U3U3U3U3U4U4U3U3U3U3U3U3U3U3U3U3U3U3U3U3U4U4",
+"U5U5U5U5U5U5UvUvU5UwU7U8SmUxSTUyUzUAUBUCUDUEUFUGUHUIUJUKULUMUNUOUPUQURUrTVToU5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U5U3U5U5U5UwUwUwU5USUSUwU5U5UwUwU5UtUtU5U5U5U5U5U5U5U5U5U5U5U5UvUvU5U5U5U5U5U5U5U5U5U5U5U5U5U5UvUv",
+"UTUTUTUTUTUTUTUTUTUUUVUWUXUYUZU&V V0V1V2V3V4V5V6V7V8V9VaVbVcVdVeVfVgUXVhViUUUTUTVjVjUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTVkVkVlVlU3U3UTUTVlVlVmVmUTUTVkVkUTUTVlVlUTUTUTUTUTUTVjVjUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUTUT",
+"UUUUUUUUUUUUUUUUUUVnVoUWUXVpVqVrVsV VtVuVvVwVxVxVyVzVAVBVCVDVEVFVGVHUXVhViVnUTUUVIVIUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUVJVJUsUsU5U5UUUUUsUsVKVKUUUUVJVJUUUUUsUsUUUUUUUUUUUUVIVIUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU",
+"KCKCMGMGMGMGMGMGKCKCMHLaVLVMVNLdVOVPVQVRVSVTIjVUVVVWVXVYVZV&W W0LcLgLaL3W1KCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGW2W2MGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMGKCKCMGMG",
+"W3W4W5W5W4W5W3W6W6W7W8W9WaWbWcWdWeWfWgWhWiWjWkWlWmWnWoWpWqWrWsWtWuWvWwWxWyWzWAWBWCWDWEWFWGWHWIWJWKWLWMWNWOWPWQWRWSWTWUWVWWWXWYWZW&X X0X1X2X3X4X5X6X7X8X9XaXbXcXdXeXfXgXhXiXjXkXlXmXnXoXpXqXrXsXsXtXtXuXtXvXvXvXuXuXuXwXxXyXzXAXBXCXDXEXEXFXGXHXIXJXKXLXMXNXOXPXQXRXSXTXUXVXWXXXYXZX&Y Y0Y1Y2Y3Y4Y5Y6Y7Y8Y9YaYbYcYdYeYfYgYhYiYjYkYlYmYnYoYpYqYrYsYtYuYvYwYxYyYzYAYBYCYDYEYFYGYHYIYJYKYLYMYNYOYPYQYRYRYSYTYTYUYUYV"};
+
diff --git a/Source/TestSuite/FPU/source/dolphintest_fpu.cpp b/Source/TestSuite/FPU/source/dolphintest_fpu.cpp
index 28e19671b9..d465b0c614 100644
--- a/Source/TestSuite/FPU/source/dolphintest_fpu.cpp
+++ b/Source/TestSuite/FPU/source/dolphintest_fpu.cpp
@@ -1,108 +1,108 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <malloc.h>
-#include <ogcsys.h>
-#include <gccore.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <math.h>
-#include <wiiuse/wpad.h>
-
-// Pull in the assembly functions.
-extern "C" {
-void TestFRES1(u32 *fpscr, float *result, float *result2);
-};
-
-int doreload=0, dooff=0;
-void reload() { doreload=1; }
-void shutdown() { dooff=1; }
-
-
-void Compare(const char *a, const char *b) {
- if (!strcmp(a, b)) {
- printf("SUCCESS - %s\n", a);
- } else {
- printf("FAIL - %s != \n"
- " %s\n", a, b);
- }
-}
-
-void TestDivision() {
- double a, b, c, d, e;
- a = 1.0;
- b = 0.0;
- c = a / b;
- d = b / a;
- e = sqrt(-1);
- char temp[100];
- sprintf(temp, "%1.1f %1.1f %1.1f %1.1f %1.1f", a, b, c, d, e);
- Compare(temp, "1.0 0.0 inf 0.0 nan");
-}
-
-void TestFres() {
- u32 fpscr[2];
- float out, out2;
- TestFRES1(fpscr, &out, &out2);
- char temp[100];
- sprintf(temp, "%08x %1.1f %1.1f", fpscr[1], out, out2);
- Compare(temp, "86002004 inf 0.0");
-}
-
-void TestNormalize() {
- //float a[3] = {2,2,2};
- //d_guVecNormalize(a);
- //printf("%f %f %f\n", a[0], a[1], a[2]);
-}
-
-
-int main(int argc, char **argv) {
- void *xfb[2];
- int fbi = 0;
- GXRModeObj *rmode = NULL;
-
- VIDEO_Init();
- PAD_Init();
- WPAD_Init();
-
- rmode = VIDEO_GetPreferredMode(NULL);
-
- // double buffering, prevents flickering (is it needed for LCD TV? i don't have one to test)
- xfb[0] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
- xfb[1] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
-
- VIDEO_Configure(rmode);
- VIDEO_SetNextFramebuffer(xfb[0]);
- VIDEO_SetBlack(FALSE);
- VIDEO_Flush();
- VIDEO_WaitVSync();
- if (rmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
-
- SYS_SetResetCallback(reload);
- SYS_SetPowerCallback(shutdown);
-
- WPAD_SetDataFormat(0, WPAD_FMT_BTNS_ACC_IR);
- WPAD_SetVRes(0, rmode->fbWidth, rmode->xfbHeight);
-
- CON_Init(xfb[fbi],0,0,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
-
- printf(" ");
- printf("Tests\n\n");
-
- TestDivision();
- TestFres();
-
- while (!doreload && !dooff) {
- WPAD_ScanPads();
- if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME)
- exit(0);
-
- VIDEO_SetNextFramebuffer(xfb[fbi]);
- VIDEO_Flush();
- VIDEO_WaitVSync();
- }
- if(doreload) return 0;
- if(dooff) SYS_ResetSystem(SYS_SHUTDOWN,0,0);
-
- return 0;
-}
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include <ogcsys.h>
+#include <gccore.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <math.h>
+#include <wiiuse/wpad.h>
+
+// Pull in the assembly functions.
+extern "C" {
+void TestFRES1(u32 *fpscr, float *result, float *result2);
+};
+
+int doreload=0, dooff=0;
+void reload() { doreload=1; }
+void shutdown() { dooff=1; }
+
+
+void Compare(const char *a, const char *b) {
+ if (!strcmp(a, b)) {
+ printf("SUCCESS - %s\n", a);
+ } else {
+ printf("FAIL - %s != \n"
+ " %s\n", a, b);
+ }
+}
+
+void TestDivision() {
+ double a, b, c, d, e;
+ a = 1.0;
+ b = 0.0;
+ c = a / b;
+ d = b / a;
+ e = sqrt(-1);
+ char temp[100];
+ sprintf(temp, "%1.1f %1.1f %1.1f %1.1f %1.1f", a, b, c, d, e);
+ Compare(temp, "1.0 0.0 inf 0.0 nan");
+}
+
+void TestFres() {
+ u32 fpscr[2];
+ float out, out2;
+ TestFRES1(fpscr, &out, &out2);
+ char temp[100];
+ sprintf(temp, "%08x %1.1f %1.1f", fpscr[1], out, out2);
+ Compare(temp, "86002004 inf 0.0");
+}
+
+void TestNormalize() {
+ //float a[3] = {2,2,2};
+ //d_guVecNormalize(a);
+ //printf("%f %f %f\n", a[0], a[1], a[2]);
+}
+
+
+int main(int argc, char **argv) {
+ void *xfb[2];
+ int fbi = 0;
+ GXRModeObj *rmode = NULL;
+
+ VIDEO_Init();
+ PAD_Init();
+ WPAD_Init();
+
+ rmode = VIDEO_GetPreferredMode(NULL);
+
+ // double buffering, prevents flickering (is it needed for LCD TV? i don't have one to test)
+ xfb[0] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
+ xfb[1] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
+
+ VIDEO_Configure(rmode);
+ VIDEO_SetNextFramebuffer(xfb[0]);
+ VIDEO_SetBlack(FALSE);
+ VIDEO_Flush();
+ VIDEO_WaitVSync();
+ if (rmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
+
+ SYS_SetResetCallback(reload);
+ SYS_SetPowerCallback(shutdown);
+
+ WPAD_SetDataFormat(0, WPAD_FMT_BTNS_ACC_IR);
+ WPAD_SetVRes(0, rmode->fbWidth, rmode->xfbHeight);
+
+ CON_Init(xfb[fbi],0,0,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
+
+ printf(" ");
+ printf("Tests\n\n");
+
+ TestDivision();
+ TestFres();
+
+ while (!doreload && !dooff) {
+ WPAD_ScanPads();
+ if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME)
+ exit(0);
+
+ VIDEO_SetNextFramebuffer(xfb[fbi]);
+ VIDEO_Flush();
+ VIDEO_WaitVSync();
+ }
+ if(doreload) return 0;
+ if(dooff) SYS_ResetSystem(SYS_SHUTDOWN,0,0);
+
+ return 0;
+}
diff --git a/Source/TestSuite/PAD/source/dolphintest_pad.cpp b/Source/TestSuite/PAD/source/dolphintest_pad.cpp
index 81ec596323..ef85a4c356 100644
--- a/Source/TestSuite/PAD/source/dolphintest_pad.cpp
+++ b/Source/TestSuite/PAD/source/dolphintest_pad.cpp
@@ -61,37 +61,37 @@ int main()
}
}
-void Initialise()
-{
- // Initialise the video system
- VIDEO_Init();
-
- // This function initialises the attached controllers
- PAD_Init();
-
- // Obtain the preferred video mode from the system
- // This will correspond to the settings in the Wii menu
- rmode = VIDEO_GetPreferredMode(NULL);
-
- // Allocate memory for the display in the uncached region
- xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
-
- // Initialise the console, required for printf
- console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
-
- // Set up the video registers with the chosen mode
- VIDEO_Configure(rmode);
-
- // Tell the video hardware where our display memory is
- VIDEO_SetNextFramebuffer(xfb);
-
- // Make the display visible
- VIDEO_SetBlack(FALSE);
-
- // Flush the video register changes to the hardware
- VIDEO_Flush();
-
- // Wait for Video setup to complete
- VIDEO_WaitVSync();
- if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
+void Initialise()
+{
+ // Initialise the video system
+ VIDEO_Init();
+
+ // This function initialises the attached controllers
+ PAD_Init();
+
+ // Obtain the preferred video mode from the system
+ // This will correspond to the settings in the Wii menu
+ rmode = VIDEO_GetPreferredMode(NULL);
+
+ // Allocate memory for the display in the uncached region
+ xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
+
+ // Initialise the console, required for printf
+ console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
+
+ // Set up the video registers with the chosen mode
+ VIDEO_Configure(rmode);
+
+ // Tell the video hardware where our display memory is
+ VIDEO_SetNextFramebuffer(xfb);
+
+ // Make the display visible
+ VIDEO_SetBlack(FALSE);
+
+ // Flush the video register changes to the hardware
+ VIDEO_Flush();
+
+ // Wait for Video setup to complete
+ VIDEO_WaitVSync();
+ if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
}
diff --git a/Source/TestSuite/RTC/source/dolphintest_rtc.cpp b/Source/TestSuite/RTC/source/dolphintest_rtc.cpp
index b0825f4ddc..bcab3588af 100644
--- a/Source/TestSuite/RTC/source/dolphintest_rtc.cpp
+++ b/Source/TestSuite/RTC/source/dolphintest_rtc.cpp
@@ -1,72 +1,72 @@
-#include <gccore.h>
-#include <malloc.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ogcsys.h>
-#include <time.h>
-#include <sys/time.h>
-
-#include <iostream>
-#include <debug.h>
-#include <math.h>
-
-static void *xfb = NULL;
-
-u32 first_frame = 1;
-GXRModeObj *rmode;
-
-void Initialise();
-
-
-int main()
-{
- Initialise();
-
- time_t gc_time;
- gc_time = time(NULL);
-
- srand(gc_time);
-
- while(1)
- {
- gc_time = time(NULL);
- std::cout<<"\x1b[10;0HGC RTC time is"<<ctime(&gc_time);
-
- VIDEO_WaitVSync();
- }
-}
-
-void Initialise()
-{
- // Initialise the video system
- VIDEO_Init();
-
- // This function initialises the attached controllers
- PAD_Init();
-
- // Obtain the preferred video mode from the system
- // This will correspond to the settings in the Wii menu
- rmode = VIDEO_GetPreferredMode(NULL);
-
- // Allocate memory for the display in the uncached region
- xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
-
- // Initialise the console, required for printf
- console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
-
- // Set up the video registers with the chosen mode
- VIDEO_Configure(rmode);
-
- // Tell the video hardware where our display memory is
- VIDEO_SetNextFramebuffer(xfb);
-
- // Make the display visible
- VIDEO_SetBlack(FALSE);
-
- // Flush the video register changes to the hardware
- VIDEO_Flush();
-
- // Wait for Video setup to complete
- VIDEO_WaitVSync();
- if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
+#include <gccore.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ogcsys.h>
+#include <time.h>
+#include <sys/time.h>
+
+#include <iostream>
+#include <debug.h>
+#include <math.h>
+
+static void *xfb = NULL;
+
+u32 first_frame = 1;
+GXRModeObj *rmode;
+
+void Initialise();
+
+
+int main()
+{
+ Initialise();
+
+ time_t gc_time;
+ gc_time = time(NULL);
+
+ srand(gc_time);
+
+ while(1)
+ {
+ gc_time = time(NULL);
+ std::cout<<"\x1b[10;0HGC RTC time is"<<ctime(&gc_time);
+
+ VIDEO_WaitVSync();
+ }
+}
+
+void Initialise()
+{
+ // Initialise the video system
+ VIDEO_Init();
+
+ // This function initialises the attached controllers
+ PAD_Init();
+
+ // Obtain the preferred video mode from the system
+ // This will correspond to the settings in the Wii menu
+ rmode = VIDEO_GetPreferredMode(NULL);
+
+ // Allocate memory for the display in the uncached region
+ xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
+
+ // Initialise the console, required for printf
+ console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
+
+ // Set up the video registers with the chosen mode
+ VIDEO_Configure(rmode);
+
+ // Tell the video hardware where our display memory is
+ VIDEO_SetNextFramebuffer(xfb);
+
+ // Make the display visible
+ VIDEO_SetBlack(FALSE);
+
+ // Flush the video register changes to the hardware
+ VIDEO_Flush();
+
+ // Wait for Video setup to complete
+ VIDEO_WaitVSync();
+ if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
}
diff --git a/Source/TestSuite/WRTC/source/dolphintest_wrtc.cpp b/Source/TestSuite/WRTC/source/dolphintest_wrtc.cpp
index f96e08369e..d64d7d6777 100644
--- a/Source/TestSuite/WRTC/source/dolphintest_wrtc.cpp
+++ b/Source/TestSuite/WRTC/source/dolphintest_wrtc.cpp
@@ -1,72 +1,72 @@
-#include <gccore.h>
-#include <malloc.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ogcsys.h>
-#include <time.h>
-#include <sys/time.h>
-
-#include <iostream>
-#include <debug.h>
-#include <math.h>
-
-static void *xfb = NULL;
-
-u32 first_frame = 1;
-GXRModeObj *rmode;
-
-void Initialise();
-
-
-int main()
-{
- Initialise();
-
- time_t wii_time;
- wii_time = time(NULL);
-
- srand(wii_time);
-
- while(1)
- {
- wii_time = time(NULL);
- std::cout<<"\x1b[10;0HWii RTC time is"<<ctime(&wii_time);
-
- VIDEO_WaitVSync();
- }
-}
-
-void Initialise()
-{
- // Initialise the video system
- VIDEO_Init();
-
- // This function initialises the attached controllers
- PAD_Init();
-
- // Obtain the preferred video mode from the system
- // This will correspond to the settings in the Wii menu
- rmode = VIDEO_GetPreferredMode(NULL);
-
- // Allocate memory for the display in the uncached region
- xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
-
- // Initialise the console, required for printf
- console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
-
- // Set up the video registers with the chosen mode
- VIDEO_Configure(rmode);
-
- // Tell the video hardware where our display memory is
- VIDEO_SetNextFramebuffer(xfb);
-
- // Make the display visible
- VIDEO_SetBlack(FALSE);
-
- // Flush the video register changes to the hardware
- VIDEO_Flush();
-
- // Wait for Video setup to complete
- VIDEO_WaitVSync();
- if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
+#include <gccore.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ogcsys.h>
+#include <time.h>
+#include <sys/time.h>
+
+#include <iostream>
+#include <debug.h>
+#include <math.h>
+
+static void *xfb = NULL;
+
+u32 first_frame = 1;
+GXRModeObj *rmode;
+
+void Initialise();
+
+
+int main()
+{
+ Initialise();
+
+ time_t wii_time;
+ wii_time = time(NULL);
+
+ srand(wii_time);
+
+ while(1)
+ {
+ wii_time = time(NULL);
+ std::cout<<"\x1b[10;0HWii RTC time is"<<ctime(&wii_time);
+
+ VIDEO_WaitVSync();
+ }
+}
+
+void Initialise()
+{
+ // Initialise the video system
+ VIDEO_Init();
+
+ // This function initialises the attached controllers
+ PAD_Init();
+
+ // Obtain the preferred video mode from the system
+ // This will correspond to the settings in the Wii menu
+ rmode = VIDEO_GetPreferredMode(NULL);
+
+ // Allocate memory for the display in the uncached region
+ xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
+
+ // Initialise the console, required for printf
+ console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
+
+ // Set up the video registers with the chosen mode
+ VIDEO_Configure(rmode);
+
+ // Tell the video hardware where our display memory is
+ VIDEO_SetNextFramebuffer(xfb);
+
+ // Make the display visible
+ VIDEO_SetBlack(FALSE);
+
+ // Flush the video register changes to the hardware
+ VIDEO_Flush();
+
+ // Wait for Video setup to complete
+ VIDEO_WaitVSync();
+ if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
}
diff --git a/Source/UnitTests/UnitTests.cpp b/Source/UnitTests/UnitTests.cpp
index 06c8f2fc4c..0a1b39faae 100644
--- a/Source/UnitTests/UnitTests.cpp
+++ b/Source/UnitTests/UnitTests.cpp
@@ -1,142 +1,142 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include <cmath>
-#include <iostream>
-
-#include "StringUtil.h"
-#include "MathUtil.h"
-#include "PowerPC/PowerPC.h"
-#include "HW/SI_DeviceGCController.h"
-
-using namespace std;
-
-int fail_count = 0;
-
-#define EXPECT_TRUE(a) \
- if (!a) { \
- cout << "FAIL (" __FUNCTION__ "): " << #a << " is false" << endl; \
- cout << "Value: " << a << endl << "Expected: true" << endl; \
- fail_count++; \
- }
-
-#define EXPECT_FALSE(a) \
- if (a) { \
- cout << "FAIL (" __FUNCTION__ "): " << #a << " is true" << endl; \
- cout << "Value: " << a << endl << "Expected: false" << endl; \
- fail_count++; \
- }
-
-#define EXPECT_EQ(a, b) \
- if ((a) != (b)) { \
- cout << "FAIL (" __FUNCTION__ "): " << #a << " is not equal to " << #b << endl; \
- cout << "Actual: " << a << endl << "Expected: " << b << endl; \
- fail_count++; \
- }
-
-void CoreTests()
-{
-}
-
-void MathTests()
-{
- // Tests that our fp classifier is correct.
- EXPECT_EQ(MathUtil::ClassifyDouble(1.0), MathUtil::PPC_FPCLASS_PN);
- EXPECT_EQ(MathUtil::ClassifyDouble(-1.0), MathUtil::PPC_FPCLASS_NN);
- EXPECT_EQ(MathUtil::ClassifyDouble(1235223.0), MathUtil::PPC_FPCLASS_PN);
- EXPECT_EQ(MathUtil::ClassifyDouble(-1263221.0), MathUtil::PPC_FPCLASS_NN);
- EXPECT_EQ(MathUtil::ClassifyDouble(1.0E-308), MathUtil::PPC_FPCLASS_PD);
- EXPECT_EQ(MathUtil::ClassifyDouble(-1.0E-308), MathUtil::PPC_FPCLASS_ND);
- EXPECT_EQ(MathUtil::ClassifyDouble(0.0), MathUtil::PPC_FPCLASS_PZ);
- EXPECT_EQ(MathUtil::ClassifyDouble(-0.0), MathUtil::PPC_FPCLASS_NZ);
- EXPECT_EQ(MathUtil::ClassifyDouble(HUGE_VAL), MathUtil::PPC_FPCLASS_PINF); // weird #define for infinity
- EXPECT_EQ(MathUtil::ClassifyDouble(-HUGE_VAL), MathUtil::PPC_FPCLASS_NINF);
- EXPECT_EQ(MathUtil::ClassifyDouble(sqrt(-1.0)), MathUtil::PPC_FPCLASS_QNAN);
-
- // Float version
- EXPECT_EQ(MathUtil::ClassifyFloat(1.0f), MathUtil::PPC_FPCLASS_PN);
- EXPECT_EQ(MathUtil::ClassifyFloat(-1.0f), MathUtil::PPC_FPCLASS_NN);
- EXPECT_EQ(MathUtil::ClassifyFloat(1235223.0f), MathUtil::PPC_FPCLASS_PN);
- EXPECT_EQ(MathUtil::ClassifyFloat(-1263221.0f), MathUtil::PPC_FPCLASS_NN);
- EXPECT_EQ(MathUtil::ClassifyFloat(1.0E-43f), MathUtil::PPC_FPCLASS_PD);
- EXPECT_EQ(MathUtil::ClassifyFloat(-1.0E-43f), MathUtil::PPC_FPCLASS_ND);
- EXPECT_EQ(MathUtil::ClassifyFloat(0.0f), MathUtil::PPC_FPCLASS_PZ);
- EXPECT_EQ(MathUtil::ClassifyFloat(-0.0f), MathUtil::PPC_FPCLASS_NZ);
- EXPECT_EQ(MathUtil::ClassifyFloat((float)HUGE_VAL), MathUtil::PPC_FPCLASS_PINF); // weird #define for infinity
- EXPECT_EQ(MathUtil::ClassifyFloat((float)-HUGE_VAL), MathUtil::PPC_FPCLASS_NINF);
- EXPECT_EQ(MathUtil::ClassifyFloat(sqrtf(-1.0f)), MathUtil::PPC_FPCLASS_QNAN);
-
- EXPECT_FALSE(MathUtil::IsNAN(1.0));
- EXPECT_TRUE(MathUtil::IsNAN(sqrt(-1.0)));
- EXPECT_FALSE(MathUtil::IsSNAN(sqrt(-1.0)));
-
- // EXPECT_TRUE(MathUtil::IsQNAN(sqrt(-1.0))); // Hmm...
- EXPECT_EQ(pow2(2.0), 4.0);
- EXPECT_EQ(pow2(-2.0), 4.0);
-}
-
-void StringTests()
-{
- EXPECT_EQ(StripSpaces(" abc "), "abc");
- EXPECT_EQ(StripNewline(" abc \n"), " abc ");
- EXPECT_EQ(StripNewline(" abc \n "), " abc \n ");
- EXPECT_EQ(StripQuotes("\"abc\""), "abc");
- EXPECT_EQ(StripQuotes("\"abc\" "), "\"abc\" ");
- EXPECT_EQ(TabsToSpaces(4, "a\tb"), "a b");
-}
-
-int main(int argc, _TCHAR* argv[])
-{
- CoreTests();
- MathTests();
- StringTests();
- if (fail_count == 0)
- {
- printf("All tests passed.\n");
- }
- return 0;
-}
-
-
-// Pretend that we are a host so we can link to core.... urgh.
-//==============================================================
-void Host_UpdateMainFrame(){}
-void Host_UpdateDisasmDialog(){}
-void Host_UpdateLogDisplay(){}
-void Host_UpdateMemoryView(){}
-void Host_NotifyMapLoaded(){}
-void Host_UpdateBreakPointView(){}
-void Host_SetDebugMode(bool enable){}
-
-void Host_SetWaitCursor(bool enable){}
-
-void Host_UpdateStatusBar(const char* _pText, int Filed = 0){}
-#ifdef SETUP_TIMER_WAITING
-void Host_UpdateGUI(){}
-#endif
-
-void Host_SysMessage(const char *fmt, ...){}
-void Host_SetWiiMoteConnectionState(int _State){}
-
-void Host_UpdateLeds(int bits){}
-void Host_UpdateSpeakerStatus(int index, int bits){}
-void Host_UpdateStatus(){}
-
-int CSIDevice_GCController::GetNetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus)
-{
- return 0;
-}
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include <cmath>
+#include <iostream>
+
+#include "StringUtil.h"
+#include "MathUtil.h"
+#include "PowerPC/PowerPC.h"
+#include "HW/SI_DeviceGCController.h"
+
+using namespace std;
+
+int fail_count = 0;
+
+#define EXPECT_TRUE(a) \
+ if (!a) { \
+ cout << "FAIL (" __FUNCTION__ "): " << #a << " is false" << endl; \
+ cout << "Value: " << a << endl << "Expected: true" << endl; \
+ fail_count++; \
+ }
+
+#define EXPECT_FALSE(a) \
+ if (a) { \
+ cout << "FAIL (" __FUNCTION__ "): " << #a << " is true" << endl; \
+ cout << "Value: " << a << endl << "Expected: false" << endl; \
+ fail_count++; \
+ }
+
+#define EXPECT_EQ(a, b) \
+ if ((a) != (b)) { \
+ cout << "FAIL (" __FUNCTION__ "): " << #a << " is not equal to " << #b << endl; \
+ cout << "Actual: " << a << endl << "Expected: " << b << endl; \
+ fail_count++; \
+ }
+
+void CoreTests()
+{
+}
+
+void MathTests()
+{
+ // Tests that our fp classifier is correct.
+ EXPECT_EQ(MathUtil::ClassifyDouble(1.0), MathUtil::PPC_FPCLASS_PN);
+ EXPECT_EQ(MathUtil::ClassifyDouble(-1.0), MathUtil::PPC_FPCLASS_NN);
+ EXPECT_EQ(MathUtil::ClassifyDouble(1235223.0), MathUtil::PPC_FPCLASS_PN);
+ EXPECT_EQ(MathUtil::ClassifyDouble(-1263221.0), MathUtil::PPC_FPCLASS_NN);
+ EXPECT_EQ(MathUtil::ClassifyDouble(1.0E-308), MathUtil::PPC_FPCLASS_PD);
+ EXPECT_EQ(MathUtil::ClassifyDouble(-1.0E-308), MathUtil::PPC_FPCLASS_ND);
+ EXPECT_EQ(MathUtil::ClassifyDouble(0.0), MathUtil::PPC_FPCLASS_PZ);
+ EXPECT_EQ(MathUtil::ClassifyDouble(-0.0), MathUtil::PPC_FPCLASS_NZ);
+ EXPECT_EQ(MathUtil::ClassifyDouble(HUGE_VAL), MathUtil::PPC_FPCLASS_PINF); // weird #define for infinity
+ EXPECT_EQ(MathUtil::ClassifyDouble(-HUGE_VAL), MathUtil::PPC_FPCLASS_NINF);
+ EXPECT_EQ(MathUtil::ClassifyDouble(sqrt(-1.0)), MathUtil::PPC_FPCLASS_QNAN);
+
+ // Float version
+ EXPECT_EQ(MathUtil::ClassifyFloat(1.0f), MathUtil::PPC_FPCLASS_PN);
+ EXPECT_EQ(MathUtil::ClassifyFloat(-1.0f), MathUtil::PPC_FPCLASS_NN);
+ EXPECT_EQ(MathUtil::ClassifyFloat(1235223.0f), MathUtil::PPC_FPCLASS_PN);
+ EXPECT_EQ(MathUtil::ClassifyFloat(-1263221.0f), MathUtil::PPC_FPCLASS_NN);
+ EXPECT_EQ(MathUtil::ClassifyFloat(1.0E-43f), MathUtil::PPC_FPCLASS_PD);
+ EXPECT_EQ(MathUtil::ClassifyFloat(-1.0E-43f), MathUtil::PPC_FPCLASS_ND);
+ EXPECT_EQ(MathUtil::ClassifyFloat(0.0f), MathUtil::PPC_FPCLASS_PZ);
+ EXPECT_EQ(MathUtil::ClassifyFloat(-0.0f), MathUtil::PPC_FPCLASS_NZ);
+ EXPECT_EQ(MathUtil::ClassifyFloat((float)HUGE_VAL), MathUtil::PPC_FPCLASS_PINF); // weird #define for infinity
+ EXPECT_EQ(MathUtil::ClassifyFloat((float)-HUGE_VAL), MathUtil::PPC_FPCLASS_NINF);
+ EXPECT_EQ(MathUtil::ClassifyFloat(sqrtf(-1.0f)), MathUtil::PPC_FPCLASS_QNAN);
+
+ EXPECT_FALSE(MathUtil::IsNAN(1.0));
+ EXPECT_TRUE(MathUtil::IsNAN(sqrt(-1.0)));
+ EXPECT_FALSE(MathUtil::IsSNAN(sqrt(-1.0)));
+
+ // EXPECT_TRUE(MathUtil::IsQNAN(sqrt(-1.0))); // Hmm...
+ EXPECT_EQ(pow2(2.0), 4.0);
+ EXPECT_EQ(pow2(-2.0), 4.0);
+}
+
+void StringTests()
+{
+ EXPECT_EQ(StripSpaces(" abc "), "abc");
+ EXPECT_EQ(StripNewline(" abc \n"), " abc ");
+ EXPECT_EQ(StripNewline(" abc \n "), " abc \n ");
+ EXPECT_EQ(StripQuotes("\"abc\""), "abc");
+ EXPECT_EQ(StripQuotes("\"abc\" "), "\"abc\" ");
+ EXPECT_EQ(TabsToSpaces(4, "a\tb"), "a b");
+}
+
+int main(int argc, _TCHAR* argv[])
+{
+ CoreTests();
+ MathTests();
+ StringTests();
+ if (fail_count == 0)
+ {
+ printf("All tests passed.\n");
+ }
+ return 0;
+}
+
+
+// Pretend that we are a host so we can link to core.... urgh.
+//==============================================================
+void Host_UpdateMainFrame(){}
+void Host_UpdateDisasmDialog(){}
+void Host_UpdateLogDisplay(){}
+void Host_UpdateMemoryView(){}
+void Host_NotifyMapLoaded(){}
+void Host_UpdateBreakPointView(){}
+void Host_SetDebugMode(bool enable){}
+
+void Host_SetWaitCursor(bool enable){}
+
+void Host_UpdateStatusBar(const char* _pText, int Filed = 0){}
+#ifdef SETUP_TIMER_WAITING
+void Host_UpdateGUI(){}
+#endif
+
+void Host_SysMessage(const char *fmt, ...){}
+void Host_SetWiiMoteConnectionState(int _State){}
+
+void Host_UpdateLeds(int bits){}
+void Host_UpdateSpeakerStatus(int index, int bits){}
+void Host_UpdateStatus(){}
+
+int CSIDevice_GCController::GetNetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus)
+{
+ return 0;
+}