mirror of https://github.com/PCSX2/pcsx2.git
Compare commits
6 Commits
4dcb34b631
...
5add834ed9
Author | SHA1 | Date |
---|---|---|
TheTechnician27 | 5add834ed9 | |
TheTechnician27 | 33bf65adf2 | |
Ty | 4a57bd7fd4 | |
shockdude | fbe0c8b9cc | |
Ziemas | 2e3501366f | |
Ziemas | ef7169dbbf |
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
|
@ -47,6 +47,8 @@
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
InputRecordingUI::InputRecordingData g_InputRecordingData;
|
||||||
|
|
||||||
namespace ImGuiManager
|
namespace ImGuiManager
|
||||||
{
|
{
|
||||||
static void FormatProcessorStat(SmallStringBase& text, double usage, double time);
|
static void FormatProcessorStat(SmallStringBase& text, double usage, double time);
|
||||||
|
@ -680,7 +682,7 @@ __ri void ImGuiManager::DrawInputRecordingOverlay(float& position_y, float scale
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
// Status Indicators
|
// Status Indicators
|
||||||
if (g_InputRecording.getControls().isRecording())
|
if (g_InputRecordingData.is_recording)
|
||||||
{
|
{
|
||||||
DRAW_LINE(standard_font, TinyString::from_format(TRANSLATE_FS("ImGuiOverlays", "{} Recording Input"), ICON_PF_CIRCLE).c_str(), IM_COL32(255, 0, 0, 255));
|
DRAW_LINE(standard_font, TinyString::from_format(TRANSLATE_FS("ImGuiOverlays", "{} Recording Input"), ICON_PF_CIRCLE).c_str(), IM_COL32(255, 0, 0, 255));
|
||||||
}
|
}
|
||||||
|
@ -690,9 +692,9 @@ __ri void ImGuiManager::DrawInputRecordingOverlay(float& position_y, float scale
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input Recording Metadata
|
// Input Recording Metadata
|
||||||
DRAW_LINE(fixed_font, TinyString::from_format(TRANSLATE_FS("ImGuiOverlays", "Input Recording Active: {}"), g_InputRecording.getData().getFilename()).c_str(), IM_COL32(117, 255, 241, 255));
|
DRAW_LINE(fixed_font, g_InputRecordingData.recording_active_message.c_str(), IM_COL32(117, 255, 241, 255));
|
||||||
DRAW_LINE(fixed_font, TinyString::from_format(TRANSLATE_FS("ImGuiOverlays", "Frame: {}/{} ({})"), g_InputRecording.getFrameCounter() + 1, g_InputRecording.getData().getTotalFrames(), g_FrameCount).c_str(), IM_COL32(117, 255, 241, 255));
|
DRAW_LINE(fixed_font, g_InputRecordingData.frame_data_message.c_str(), IM_COL32(117, 255, 241, 255));
|
||||||
DRAW_LINE(fixed_font, TinyString::from_format(TRANSLATE_FS("ImGuiOverlays", "Undo Count: {}"), g_InputRecording.getData().getUndoCount()).c_str(), IM_COL32(117, 255, 241, 255));
|
DRAW_LINE(fixed_font, g_InputRecordingData.undo_count_message.c_str(), IM_COL32(117, 255, 241, 255));
|
||||||
|
|
||||||
#undef DRAW_LINE
|
#undef DRAW_LINE
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,3 +28,16 @@ namespace SaveStateSelectorUI
|
||||||
void LoadCurrentSlot();
|
void LoadCurrentSlot();
|
||||||
void SaveCurrentSlot();
|
void SaveCurrentSlot();
|
||||||
} // namespace SaveStateSelectorUI
|
} // namespace SaveStateSelectorUI
|
||||||
|
|
||||||
|
namespace InputRecordingUI
|
||||||
|
{
|
||||||
|
struct InputRecordingData
|
||||||
|
{
|
||||||
|
bool is_recording = false;
|
||||||
|
TinyString recording_active_message = "";
|
||||||
|
TinyString frame_data_message = "";
|
||||||
|
TinyString undo_count_message = "";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
extern InputRecordingUI::InputRecordingData g_InputRecordingData;
|
||||||
|
|
|
@ -26,6 +26,8 @@ bool SaveStateBase::InputRecordingFreeze()
|
||||||
#include "Counters.h"
|
#include "Counters.h"
|
||||||
#include "SaveState.h"
|
#include "SaveState.h"
|
||||||
#include "VMManager.h"
|
#include "VMManager.h"
|
||||||
|
#include "Host.h"
|
||||||
|
#include "ImGui/ImGuiOverlays.h"
|
||||||
#include "DebugTools/Debug.h"
|
#include "DebugTools/Debug.h"
|
||||||
#include "GameDatabase.h"
|
#include "GameDatabase.h"
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
@ -237,8 +239,9 @@ void InputRecording::incFrameCounter()
|
||||||
|
|
||||||
if (m_controls.isReplaying())
|
if (m_controls.isReplaying())
|
||||||
{
|
{
|
||||||
|
InformGSThread();
|
||||||
// If we've reached the end of the recording while replaying, pause
|
// If we've reached the end of the recording while replaying, pause
|
||||||
if (m_frame_counter == m_file.getTotalFrames() - 1)
|
if (m_frame_counter == m_file.getTotalFrames())
|
||||||
{
|
{
|
||||||
VMManager::SetPaused(true);
|
VMManager::SetPaused(true);
|
||||||
// Can also stop watching for re-records, they've watched to the end of the recording
|
// Can also stop watching for re-records, they've watched to the end of the recording
|
||||||
|
@ -247,6 +250,7 @@ void InputRecording::incFrameCounter()
|
||||||
}
|
}
|
||||||
if (m_controls.isRecording())
|
if (m_controls.isRecording())
|
||||||
{
|
{
|
||||||
|
m_frame_counter_stateless++;
|
||||||
m_file.setTotalFrames(m_frame_counter);
|
m_file.setTotalFrames(m_frame_counter);
|
||||||
// If we've been in record mode and moved to the next frame, we've overrote something
|
// If we've been in record mode and moved to the next frame, we've overrote something
|
||||||
// if this was following a save-state loading, this is considered a re-record, a.k.a an undo
|
// if this was following a save-state loading, this is considered a re-record, a.k.a an undo
|
||||||
|
@ -255,14 +259,20 @@ void InputRecording::incFrameCounter()
|
||||||
m_file.incrementUndoCount();
|
m_file.incrementUndoCount();
|
||||||
m_watching_for_rerecords = false;
|
m_watching_for_rerecords = false;
|
||||||
}
|
}
|
||||||
|
InformGSThread();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 InputRecording::getFrameCounter() const
|
u32 InputRecording::getFrameCounter() const
|
||||||
{
|
{
|
||||||
return m_frame_counter;
|
return m_frame_counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 InputRecording::getFrameCounterStateless() const
|
||||||
|
{
|
||||||
|
return m_frame_counter_stateless;
|
||||||
|
}
|
||||||
|
|
||||||
bool InputRecording::isActive() const
|
bool InputRecording::isActive() const
|
||||||
{
|
{
|
||||||
return m_is_active;
|
return m_is_active;
|
||||||
|
@ -320,6 +330,12 @@ void InputRecording::setStartingFrame(u32 startingFrame)
|
||||||
}
|
}
|
||||||
InputRec::consoleLog(fmt::format("Internal Starting Frame: {}", startingFrame));
|
InputRec::consoleLog(fmt::format("Internal Starting Frame: {}", startingFrame));
|
||||||
m_starting_frame = startingFrame;
|
m_starting_frame = startingFrame;
|
||||||
|
InformGSThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 InputRecording::getStartingFrame()
|
||||||
|
{
|
||||||
|
return m_starting_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputRecording::adjustFrameCounterOnReRecord(u32 newFrameCounter)
|
void InputRecording::adjustFrameCounterOnReRecord(u32 newFrameCounter)
|
||||||
|
@ -351,6 +367,9 @@ void InputRecording::adjustFrameCounterOnReRecord(u32 newFrameCounter)
|
||||||
getControls().setReplayMode();
|
getControls().setReplayMode();
|
||||||
}
|
}
|
||||||
m_frame_counter = newFrameCounter - m_starting_frame;
|
m_frame_counter = newFrameCounter - m_starting_frame;
|
||||||
|
m_frame_counter_stateless--;
|
||||||
|
m_file.setTotalFrames(m_frame_counter);
|
||||||
|
InformGSThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
InputRecordingControls& InputRecording::getControls()
|
InputRecordingControls& InputRecording::getControls()
|
||||||
|
@ -367,4 +386,20 @@ void InputRecording::initializeState()
|
||||||
{
|
{
|
||||||
m_frame_counter = 0;
|
m_frame_counter = 0;
|
||||||
m_watching_for_rerecords = false;
|
m_watching_for_rerecords = false;
|
||||||
|
InformGSThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputRecording::InformGSThread()
|
||||||
|
{
|
||||||
|
TinyString recording_active_message = TinyString::from_format(TRANSLATE_FS("InputRecording", "Input Recording Active: {}"), g_InputRecording.getData().getFilename());
|
||||||
|
TinyString frame_data_message = TinyString::from_format(TRANSLATE_FS("InputRecording", "Frame: {}/{} ({})"), g_InputRecording.getFrameCounter(), g_InputRecording.getData().getTotalFrames(), g_InputRecording.getFrameCounterStateless());
|
||||||
|
TinyString undo_count_message = TinyString::from_format(TRANSLATE_FS("InputRecording", "Undo Count: {}"), g_InputRecording.getData().getUndoCount());
|
||||||
|
|
||||||
|
MTGS::RunOnGSThread([recording_active_message, frame_data_message, undo_count_message](bool is_recording = g_InputRecording.getControls().isRecording())
|
||||||
|
{
|
||||||
|
g_InputRecordingData.is_recording = is_recording;
|
||||||
|
g_InputRecordingData.recording_active_message = recording_active_message;
|
||||||
|
g_InputRecordingData.frame_data_message = frame_data_message;
|
||||||
|
g_InputRecordingData.undo_count_message = undo_count_message;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,14 +22,19 @@ public:
|
||||||
bool play(const std::string& path);
|
bool play(const std::string& path);
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
static void InformGSThread();
|
||||||
void handleControllerDataUpdate();
|
void handleControllerDataUpdate();
|
||||||
void saveControllerData(const PadData& data, const int port, const int slot);
|
void saveControllerData(const PadData& data, const int port, const int slot);
|
||||||
std::optional<PadData> updateControllerData(const int port, const int slot);
|
std::optional<PadData> updateControllerData(const int port, const int slot);
|
||||||
void incFrameCounter();
|
void incFrameCounter();
|
||||||
u64 getFrameCounter() const;
|
u32 getFrameCounter() const;
|
||||||
|
u32 getFrameCounterStateless() const;
|
||||||
bool isActive() const;
|
bool isActive() const;
|
||||||
void processRecordQueue();
|
void processRecordQueue();
|
||||||
|
|
||||||
|
void setStartingFrame(u32 startingFrame);
|
||||||
|
u32 getStartingFrame();
|
||||||
|
|
||||||
void handleExceededFrameCounter();
|
void handleExceededFrameCounter();
|
||||||
void handleReset();
|
void handleReset();
|
||||||
void handleLoadingSavestate();
|
void handleLoadingSavestate();
|
||||||
|
@ -53,11 +58,11 @@ private:
|
||||||
std::queue<std::function<void()>> m_recordingQueue;
|
std::queue<std::function<void()>> m_recordingQueue;
|
||||||
|
|
||||||
u32 m_frame_counter = 0;
|
u32 m_frame_counter = 0;
|
||||||
|
u32 m_frame_counter_stateless = 0;
|
||||||
// Either 0 for a power-on movie, or the g_FrameCount that is stored on the starting frame
|
// Either 0 for a power-on movie, or the g_FrameCount that is stored on the starting frame
|
||||||
u32 m_starting_frame = 0;
|
u32 m_starting_frame = 0;
|
||||||
|
|
||||||
void initializeState();
|
void initializeState();
|
||||||
void setStartingFrame(u32 startingFrame);
|
|
||||||
void closeActiveFile();
|
void closeActiveFile();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0+
|
// SPDX-License-Identifier: GPL-3.0+
|
||||||
|
|
||||||
#include "InputRecordingFile.h"
|
#include "InputRecordingFile.h"
|
||||||
|
#include "InputRecording.h"
|
||||||
|
|
||||||
#include "BuildVersion.h"
|
#include "BuildVersion.h"
|
||||||
#include "Utilities/InputRecordingLogger.h"
|
#include "Utilities/InputRecordingLogger.h"
|
||||||
|
@ -89,6 +90,7 @@ void InputRecordingFile::incrementUndoCount()
|
||||||
}
|
}
|
||||||
fseek(m_recordingFile, s_seekpointUndoCount, SEEK_SET);
|
fseek(m_recordingFile, s_seekpointUndoCount, SEEK_SET);
|
||||||
fwrite(&m_undoCount, 4, 1, m_recordingFile);
|
fwrite(&m_undoCount, 4, 1, m_recordingFile);
|
||||||
|
InputRecording::InformGSThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InputRecordingFile::openNew(const std::string& path, bool fromSavestate)
|
bool InputRecordingFile::openNew(const std::string& path, bool fromSavestate)
|
||||||
|
@ -104,6 +106,7 @@ bool InputRecordingFile::openNew(const std::string& path, bool fromSavestate)
|
||||||
m_undoCount = 0;
|
m_undoCount = 0;
|
||||||
m_header.init();
|
m_header.init();
|
||||||
m_savestate = fromSavestate;
|
m_savestate = fromSavestate;
|
||||||
|
InputRecording::InformGSThread();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +126,7 @@ bool InputRecordingFile::openExisting(const std::string& path)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_filename = path;
|
m_filename = path;
|
||||||
|
InputRecording::InformGSThread();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,13 +151,14 @@ std::optional<PadData> InputRecordingFile::readPadData(const uint frame, const u
|
||||||
|
|
||||||
void InputRecordingFile::setTotalFrames(u32 frame)
|
void InputRecordingFile::setTotalFrames(u32 frame)
|
||||||
{
|
{
|
||||||
if (m_recordingFile == nullptr || m_totalFrames >= frame)
|
if (m_recordingFile == nullptr)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_totalFrames = frame;
|
m_totalFrames = frame;
|
||||||
fseek(m_recordingFile, s_seekpointTotalFrames, SEEK_SET);
|
fseek(m_recordingFile, s_seekpointTotalFrames, SEEK_SET);
|
||||||
fwrite(&m_totalFrames, 4, 1, m_recordingFile);
|
fwrite(&m_totalFrames, 4, 1, m_recordingFile);
|
||||||
|
InputRecording::InformGSThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InputRecordingFile::writeHeader() const
|
bool InputRecordingFile::writeHeader() const
|
||||||
|
|
|
@ -93,19 +93,19 @@ namespace usb_pad
|
||||||
u8 right_turntable = 0x80;
|
u8 right_turntable = 0x80;
|
||||||
if (data.left_turntable_ccw > 0)
|
if (data.left_turntable_ccw > 0)
|
||||||
{
|
{
|
||||||
left_turntable -= static_cast<u8>(std::min<int>(data.left_turntable_ccw * turntable_multiplier, 0x7F));
|
left_turntable -= static_cast<u8>(std::min<int>(data.left_turntable_ccw, 0x7F));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
left_turntable += static_cast<u8>(std::min<int>(data.left_turntable_cw * turntable_multiplier, 0x7F));
|
left_turntable += static_cast<u8>(std::min<int>(data.left_turntable_cw, 0x7F));
|
||||||
}
|
}
|
||||||
if (data.right_turntable_ccw > 0)
|
if (data.right_turntable_ccw > 0)
|
||||||
{
|
{
|
||||||
right_turntable -= static_cast<u8>(std::min<int>(data.right_turntable_ccw * turntable_multiplier, 0x7F));
|
right_turntable -= static_cast<u8>(std::min<int>(data.right_turntable_ccw, 0x7F));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
right_turntable += static_cast<u8>(std::min<int>(data.right_turntable_cw * turntable_multiplier, 0x7F));
|
right_turntable += static_cast<u8>(std::min<int>(data.right_turntable_cw, 0x7F));
|
||||||
}
|
}
|
||||||
buf[3] = 0x80;
|
buf[3] = 0x80;
|
||||||
buf[4] = 0x80;
|
buf[4] = 0x80;
|
||||||
|
@ -369,19 +369,19 @@ namespace usb_pad
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CID_DJ_LEFT_TURNTABLE_CW:
|
case CID_DJ_LEFT_TURNTABLE_CW:
|
||||||
s->data.left_turntable_cw = static_cast<u32>(std::clamp<long>(std::lroundf(value * 128.0f), 0, 128));
|
s->data.left_turntable_cw = static_cast<u32>(std::clamp<long>(std::lroundf(value * s->turntable_multiplier * 128.0f), 0, 128));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CID_DJ_LEFT_TURNTABLE_CCW:
|
case CID_DJ_LEFT_TURNTABLE_CCW:
|
||||||
s->data.left_turntable_ccw = static_cast<u32>(std::clamp<long>(std::lroundf(value * 128.0f), 0, 128));
|
s->data.left_turntable_ccw = static_cast<u32>(std::clamp<long>(std::lroundf(value * s->turntable_multiplier * 128.0f), 0, 128));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CID_DJ_RIGHT_TURNTABLE_CW:
|
case CID_DJ_RIGHT_TURNTABLE_CW:
|
||||||
s->data.right_turntable_cw = static_cast<u32>(std::clamp<long>(std::lroundf(value * 128.0f), 0, 128));
|
s->data.right_turntable_cw = static_cast<u32>(std::clamp<long>(std::lroundf(value * s->turntable_multiplier * 128.0f), 0, 128));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CID_DJ_RIGHT_TURNTABLE_CCW:
|
case CID_DJ_RIGHT_TURNTABLE_CCW:
|
||||||
s->data.right_turntable_ccw = static_cast<u32>(std::clamp<long>(std::lroundf(value * 128.0f), 0, 128));
|
s->data.right_turntable_ccw = static_cast<u32>(std::clamp<long>(std::lroundf(value * s->turntable_multiplier * 128.0f), 0, 128));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CID_DJ_DPAD_UP:
|
case CID_DJ_DPAD_UP:
|
||||||
|
@ -446,8 +446,8 @@ namespace usb_pad
|
||||||
{"EffectsKnobRight", TRANSLATE_NOOP("USB", "Effects Knob Right"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_EFFECTSKNOB_RIGHT, GenericInputBinding::RightStickRight},
|
{"EffectsKnobRight", TRANSLATE_NOOP("USB", "Effects Knob Right"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_EFFECTSKNOB_RIGHT, GenericInputBinding::RightStickRight},
|
||||||
{"LeftTurntableCW", TRANSLATE_NOOP("USB", "Left Turntable Clockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_LEFT_TURNTABLE_CW, GenericInputBinding::LeftStickRight},
|
{"LeftTurntableCW", TRANSLATE_NOOP("USB", "Left Turntable Clockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_LEFT_TURNTABLE_CW, GenericInputBinding::LeftStickRight},
|
||||||
{"LeftTurntableCCW", TRANSLATE_NOOP("USB", "Left Turntable Counterclockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_LEFT_TURNTABLE_CCW, GenericInputBinding::LeftStickLeft},
|
{"LeftTurntableCCW", TRANSLATE_NOOP("USB", "Left Turntable Counterclockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_LEFT_TURNTABLE_CCW, GenericInputBinding::LeftStickLeft},
|
||||||
{"RightTurntableCW", TRANSLATE_NOOP("USB", "Right Turntable Clockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_RIGHT_TURNTABLE_CW, GenericInputBinding::LeftStickDown},
|
{"RightTurntableCW", TRANSLATE_NOOP("USB", "Right Turntable Clockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_RIGHT_TURNTABLE_CW, GenericInputBinding::LeftStickUp},
|
||||||
{"RightTurntableCCW", TRANSLATE_NOOP("USB", "Right Turntable Counterclockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_RIGHT_TURNTABLE_CCW, GenericInputBinding::LeftStickUp},
|
{"RightTurntableCCW", TRANSLATE_NOOP("USB", "Right Turntable Counterclockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_RIGHT_TURNTABLE_CCW, GenericInputBinding::LeftStickDown},
|
||||||
{"LeftTurntableGreen", TRANSLATE_NOOP("USB", "Left Turntable Green"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_GREEN, GenericInputBinding::Unknown},
|
{"LeftTurntableGreen", TRANSLATE_NOOP("USB", "Left Turntable Green"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_GREEN, GenericInputBinding::Unknown},
|
||||||
{"LeftTurntableRed", TRANSLATE_NOOP("USB", "Left Turntable Red"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_RED, GenericInputBinding::Unknown},
|
{"LeftTurntableRed", TRANSLATE_NOOP("USB", "Left Turntable Red"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_RED, GenericInputBinding::Unknown},
|
||||||
{"LeftTurntableBlue", TRANSLATE_NOOP("USB", "Left Turntable Blue"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_BLUE, GenericInputBinding::Unknown},
|
{"LeftTurntableBlue", TRANSLATE_NOOP("USB", "Left Turntable Blue"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_BLUE, GenericInputBinding::Unknown},
|
||||||
|
@ -464,8 +464,8 @@ namespace usb_pad
|
||||||
{
|
{
|
||||||
static constexpr const SettingInfo info[] = {
|
static constexpr const SettingInfo info[] = {
|
||||||
{SettingInfo::Type::Float, "TurntableMultiplier", TRANSLATE_NOOP("USB", "Turntable Multiplier"),
|
{SettingInfo::Type::Float, "TurntableMultiplier", TRANSLATE_NOOP("USB", "Turntable Multiplier"),
|
||||||
TRANSLATE_NOOP("USB", "Apply a multiplier to the turntable"),
|
TRANSLATE_NOOP("USB", "Apply a sensitivity multiplier to turntable rotation.\nXbox 360 turntables require a 256x multiplier, most other turntables can use the default 1x multiplier."),
|
||||||
"1.00", "0.00", "100.0", "1.0", "%.0fx", nullptr, nullptr, 1.0f}};
|
"1.00", "0.00", "512.0", "1.0", "%.0fx", nullptr, nullptr, 1.0f}};
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2561,6 +2561,11 @@ void VMManager::InitializeCPUProviders()
|
||||||
|
|
||||||
CpuMicroVU0.Reserve();
|
CpuMicroVU0.Reserve();
|
||||||
CpuMicroVU1.Reserve();
|
CpuMicroVU1.Reserve();
|
||||||
|
#else
|
||||||
|
// Despite not having any VU recompilers on ARM64, therefore no MTVU,
|
||||||
|
// we still need the thread alive. Otherwise the read and write positions
|
||||||
|
// of the ring buffer wont match, and various systems in the emulator end up deadlocked.
|
||||||
|
vu1Thread.Open();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VifUnpackSSE_Init();
|
VifUnpackSSE_Init();
|
||||||
|
@ -2580,6 +2585,11 @@ void VMManager::ShutdownCPUProviders()
|
||||||
|
|
||||||
psxRec.Shutdown();
|
psxRec.Shutdown();
|
||||||
recCpu.Shutdown();
|
recCpu.Shutdown();
|
||||||
|
#else
|
||||||
|
// See the comment in the InitializeCPUProviders for an explaination why we
|
||||||
|
// still need to manage the MTVU thread.
|
||||||
|
if(vu1Thread.IsOpen())
|
||||||
|
vu1Thread.WaitVU();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
|
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
|
||||||
// SPDX-License-Identifier: GPL-3.0
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
|
||||||
|
#include "common/Console.h"
|
||||||
|
#include "MTVU.h"
|
||||||
#include "SaveState.h"
|
#include "SaveState.h"
|
||||||
#include "vtlb.h"
|
#include "vtlb.h"
|
||||||
|
|
||||||
|
@ -13,6 +15,16 @@ void vtlb_DynBackpatchLoadStore(uptr code_address, u32 code_size, u32 guest_pc,
|
||||||
|
|
||||||
bool SaveStateBase::vuJITFreeze()
|
bool SaveStateBase::vuJITFreeze()
|
||||||
{
|
{
|
||||||
pxFailRel("Not implemented.");
|
if(IsSaving())
|
||||||
return false;
|
vu1Thread.WaitVU();
|
||||||
|
|
||||||
|
Console.Warning("recompiler state is stubbed in arm64!");
|
||||||
|
|
||||||
|
// HACK!!
|
||||||
|
|
||||||
|
// size of microRegInfo structure
|
||||||
|
std::array<u8,96> empty_data{};
|
||||||
|
Freeze(empty_data);
|
||||||
|
Freeze(empty_data);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1595,6 +1595,14 @@ static void iopRecRecompile(const u32 startpc)
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
BASEBLOCK* pblock = PSX_GETBLOCK(i);
|
||||||
|
if (i != startpc && pblock->GetFnptr() != (uptr)iopJITCompile)
|
||||||
|
{
|
||||||
|
// branch = 3
|
||||||
|
willbranch3 = 1;
|
||||||
|
s_nEndBlock = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
psxRegs.code = iopMemRead32(i);
|
psxRegs.code = iopMemRead32(i);
|
||||||
|
|
||||||
|
|
|
@ -2294,6 +2294,8 @@ static void recRecompile(const u32 startpc)
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
BASEBLOCK* pblock = PC_GETBLOCK(i);
|
||||||
|
|
||||||
// stop before breakpoints
|
// stop before breakpoints
|
||||||
if (isBreakpointNeeded(i) != 0 || isMemcheckNeeded(i) != 0)
|
if (isBreakpointNeeded(i) != 0 || isMemcheckNeeded(i) != 0)
|
||||||
{
|
{
|
||||||
|
@ -2311,6 +2313,13 @@ static void recRecompile(const u32 startpc)
|
||||||
eeRecPerfLog.Write("Pagesplit @ %08X : size=%d insts", startpc, (i - startpc) / 4);
|
eeRecPerfLog.Write("Pagesplit @ %08X : size=%d insts", startpc, (i - startpc) / 4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pblock->GetFnptr() != (uptr)JITCompile)
|
||||||
|
{
|
||||||
|
willbranch3 = 1;
|
||||||
|
s_nEndBlock = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//HUH ? PSM ? whut ? THIS IS VIRTUAL ACCESS GOD DAMMIT
|
//HUH ? PSM ? whut ? THIS IS VIRTUAL ACCESS GOD DAMMIT
|
||||||
|
@ -2614,6 +2623,34 @@ StartRecomp:
|
||||||
pxAssert((pc - startpc) >> 2 <= 0xffff);
|
pxAssert((pc - startpc) >> 2 <= 0xffff);
|
||||||
s_pCurBlockEx->size = (pc - startpc) >> 2;
|
s_pCurBlockEx->size = (pc - startpc) >> 2;
|
||||||
|
|
||||||
|
if (HWADDR(pc) <= Ps2MemSize::ExposedRam)
|
||||||
|
{
|
||||||
|
BASEBLOCKEX* oldBlock;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = recBlocks.LastIndex(HWADDR(pc) - 4);
|
||||||
|
while ((oldBlock = recBlocks[i--]))
|
||||||
|
{
|
||||||
|
if (oldBlock == s_pCurBlockEx)
|
||||||
|
continue;
|
||||||
|
if (oldBlock->startpc >= HWADDR(pc))
|
||||||
|
continue;
|
||||||
|
if ((oldBlock->startpc + oldBlock->size * 4) <= HWADDR(startpc))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (memcmp(&recRAMCopy[oldBlock->startpc / 4], PSM(oldBlock->startpc),
|
||||||
|
oldBlock->size * 4))
|
||||||
|
{
|
||||||
|
recClear(startpc, (pc - startpc) / 4);
|
||||||
|
s_pCurBlockEx = recBlocks.Get(HWADDR(startpc));
|
||||||
|
pxAssert(s_pCurBlockEx->startpc == HWADDR(startpc));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&recRAMCopy[HWADDR(startpc) / 4], PSM(startpc), pc - startpc);
|
||||||
|
}
|
||||||
|
|
||||||
s_pCurBlock->SetFnptr((uptr)recPtr);
|
s_pCurBlock->SetFnptr((uptr)recPtr);
|
||||||
|
|
||||||
if (!(pc & 0x10000000))
|
if (!(pc & 0x10000000))
|
||||||
|
|
Loading…
Reference in New Issue