mirror of
https://github.com/Rosalie241/RMG.git
synced 2026-07-11 09:34:00 +02:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 541724b63c | |||
| 304afbb50d | |||
| 1ba88f48bb | |||
| 8f8c9c35f1 | |||
| 1c07d032ef | |||
| c500a17b1a | |||
| 6d0347b48a | |||
| 83af0ff4af | |||
| 32c13eee1d | |||
| 42597a76f0 | |||
| 7c59a520aa | |||
| 3c124d8519 | |||
| 76282a11da | |||
| 5249bf6a56 | |||
| 12e0dac777 |
@@ -33,6 +33,24 @@
|
||||
</screenshots>
|
||||
<description/>
|
||||
<releases>
|
||||
<release version="v0.3.4" date="2023-02-11" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix mapping button size increasing when reloading settings in RMG-Input</li>
|
||||
<li>Fix analog stick mapping in-game when having buttons and axis bound in RMG-Input</li>
|
||||
<li>Fix height mismatch of "Profile" and "Input Device" UI elements in RMG-Input</li>
|
||||
<li>Fix updater script not using the correct path seperators on Windows</li>
|
||||
<li>Fix GLideN64's per game settings being overwritten by the updater on windows (or not being updated on linux)</li>
|
||||
<li>Fix "Automatic" input device not opening controller device when clicking on 'Refresh' in RMG-Input</li>
|
||||
<li>Fix game specific profile having unexpected UI behavior in RMG-Input</li>
|
||||
<li>Fix cancel and close button not working correctly in RMG-Input</li>
|
||||
<li>Fix profile saving not working correctly when having the same profile selected for multiple players in RMG-Input</li>
|
||||
<li>Add "Filter Events Based On Joystick Type For Buttons" setting to RMG-Input</li>
|
||||
<li>Add "Filter Events Based On Joystick Type For Axis" setting to RMG-Input</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.3.3" date="2023-02-09" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
|
||||
Vendored
+2
-2
@@ -57,8 +57,8 @@ if(NOT NO_GIT_CLONE)
|
||||
set(MUPEN64PLUS_GFX_ANGRYLION_URL "https://github.com/Rosalie241/angrylion-rdp-plus")
|
||||
set(MUPEN64PLUS_GFX_ANGRYLION_TAG "158e74d4ec1c818289cd19c3a05e498c3ceff758")
|
||||
|
||||
set(MUPEN64PLUS_GFX_GLIDEN64_URL "https://github.com/gonetz/GLideN64")
|
||||
set(MUPEN64PLUS_GFX_GLIDEN64_TAG "263a7bd2ca81759ece98209bd282a6c1173a129f")
|
||||
set(MUPEN64PLUS_GFX_GLIDEN64_URL "https://github.com/Rosalie241/GLideN64")
|
||||
set(MUPEN64PLUS_GFX_GLIDEN64_TAG "698f5580249e2edf86fb89cd75d921535171074c")
|
||||
|
||||
set(MUPEN64PLUS_GFX_PARALLEL_URL "https://github.com/Rosalie241/parallel-rdp-standalone")
|
||||
set(MUPEN64PLUS_GFX_PARALLEL_TAG "48abaa5e082add7848e6f98648111c69c4a71632")
|
||||
|
||||
@@ -553,6 +553,9 @@ static l_Setting get_setting(SettingsID settingId)
|
||||
case SettingsID::Input_UseProfile:
|
||||
setting = {"", "UseProfile"};
|
||||
break;
|
||||
case SettingsID::Input_UseGameProfile:
|
||||
setting = {"", "UseGameProfile"};
|
||||
break;
|
||||
case SettingsID::Input_PluggedIn:
|
||||
setting = {"", "PluggedIn"};
|
||||
break;
|
||||
@@ -580,6 +583,12 @@ static l_Setting get_setting(SettingsID settingId)
|
||||
case SettingsID::Input_RemoveDuplicateMappings:
|
||||
setting = {"", "RemoveDuplicateMappings"};
|
||||
break;
|
||||
case SettingsID::Input_FilterEventsForButtons:
|
||||
setting = {"", "FilterEventsForButtons"};
|
||||
break;
|
||||
case SettingsID::Input_FilterEventsForAxis:
|
||||
setting = {"", "FilterEventsForAxis"};
|
||||
break;
|
||||
case SettingsID::Input_A_InputType:
|
||||
setting = {"", "A_InputType"};
|
||||
break;
|
||||
@@ -1227,6 +1236,27 @@ bool CoreSettingsSectionExists(std::string section)
|
||||
return config_section_exists(section);
|
||||
}
|
||||
|
||||
bool CoreSettingsRevertSection(std::string section)
|
||||
{
|
||||
std::string error;
|
||||
m64p_error ret;
|
||||
|
||||
if (!m64p::Config.IsHooked())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = m64p::Config.RevertChanges(section.c_str());
|
||||
if (ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "CoreSettingsRevertSection m64p::Config.RevertChanges() Failed: ";
|
||||
error = m64p::Core.ErrorMessage(ret);
|
||||
CoreSetError(error);
|
||||
}
|
||||
|
||||
return ret == M64ERR_SUCCESS;
|
||||
}
|
||||
|
||||
bool CoreSettingsDeleteSection(std::string section)
|
||||
{
|
||||
std::string error;
|
||||
|
||||
@@ -27,6 +27,9 @@ bool CoreSettingsSetupDefaults(void);
|
||||
// returns whether a section exists
|
||||
bool CoreSettingsSectionExists(std::string section);
|
||||
|
||||
// reverts section to the one from the settings
|
||||
bool CoreSettingsRevertSection(std::string section);
|
||||
|
||||
// deletes given section
|
||||
bool CoreSettingsDeleteSection(std::string section);
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ enum class SettingsID
|
||||
GUI_CheckForUpdates,
|
||||
GUI_DiscordRpc,
|
||||
GUI_Version,
|
||||
|
||||
|
||||
// Core Plugin Settings
|
||||
Core_GFX_Plugin,
|
||||
Core_AUDIO_Plugin,
|
||||
@@ -160,6 +160,7 @@ enum class SettingsID
|
||||
// Input Plugin Settings
|
||||
Input_Profiles,
|
||||
Input_UseProfile,
|
||||
Input_UseGameProfile,
|
||||
Input_PluggedIn,
|
||||
Input_DeviceType,
|
||||
Input_DeviceName,
|
||||
@@ -169,6 +170,8 @@ enum class SettingsID
|
||||
Input_GameboyRom,
|
||||
Input_GameboySave,
|
||||
Input_RemoveDuplicateMappings,
|
||||
Input_FilterEventsForButtons,
|
||||
Input_FilterEventsForAxis,
|
||||
Input_A_InputType,
|
||||
Input_A_Name,
|
||||
Input_A_Data,
|
||||
|
||||
@@ -370,19 +370,37 @@ void MainDialog::on_EventFilter_KeyReleased(QKeyEvent *event)
|
||||
SDL_PeepEvents(&sdlEvent, 1, SDL_ADDEVENT, 0, 0);
|
||||
}
|
||||
|
||||
void MainDialog::on_buttonBox_clicked(QAbstractButton *button)
|
||||
void MainDialog::accept(void)
|
||||
{
|
||||
QPushButton *pushButton = (QPushButton *)button;
|
||||
QPushButton *okButton = this->buttonBox->button(QDialogButtonBox::Ok);
|
||||
Widget::ControllerWidget* controllerWidget;
|
||||
int currentIndex = this->tabWidget->currentIndex();
|
||||
|
||||
if (pushButton == okButton)
|
||||
for (int i = 0; i < this->controllerWidgets.count(); i++)
|
||||
{
|
||||
for (auto& controllerWidget : this->controllerWidgets)
|
||||
if (i != currentIndex)
|
||||
{
|
||||
controllerWidget = this->controllerWidgets.at(currentIndex);
|
||||
controllerWidget->SaveSettings();
|
||||
}
|
||||
|
||||
CoreSettingsSave();
|
||||
}
|
||||
|
||||
// the widget which has focus should be saved last
|
||||
controllerWidget = this->controllerWidgets.at(currentIndex);
|
||||
controllerWidget->SaveSettings();
|
||||
|
||||
CoreSettingsSave();
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void MainDialog::reject(void)
|
||||
{
|
||||
for (auto& controllerWidget : this->controllerWidgets)
|
||||
{
|
||||
controllerWidget->RevertSettings();
|
||||
}
|
||||
|
||||
CoreSettingsSave();
|
||||
|
||||
QDialog::reject();
|
||||
}
|
||||
|
||||
@@ -80,7 +80,8 @@ private slots:
|
||||
void on_EventFilter_KeyPressed(QKeyEvent *);
|
||||
void on_EventFilter_KeyReleased(QKeyEvent *);
|
||||
|
||||
void on_buttonBox_clicked(QAbstractButton *);
|
||||
void accept(void) Q_DECL_OVERRIDE;
|
||||
void reject(void) Q_DECL_OVERRIDE;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ OptionsDialog::OptionsDialog(QWidget* parent, OptionsDialogSettings settings) :
|
||||
this->gameboyRomLineEdit->setText(QString::fromStdString(settings.GameboyRom));
|
||||
this->gameboySaveLineEdit->setText(QString::fromStdString(settings.GameboySave));
|
||||
this->removeDuplicateMappingsCheckbox->setChecked(settings.RemoveDuplicateMappings);
|
||||
this->filterEventsForButtonsCheckBox->setChecked(settings.FilterEventsForButtons);
|
||||
this->filterEventsForAxisCheckBox->setChecked(settings.FilterEventsForAxis);
|
||||
|
||||
if (!CoreIsEmulationRunning() && !CoreIsEmulationPaused())
|
||||
{
|
||||
@@ -83,6 +85,8 @@ void OptionsDialog::on_buttonBox_clicked(QAbstractButton *button)
|
||||
this->settings.GameboyRom = this->gameboyRomLineEdit->text().toStdString();
|
||||
this->settings.GameboySave = this->gameboySaveLineEdit->text().toStdString();
|
||||
this->settings.RemoveDuplicateMappings = this->removeDuplicateMappingsCheckbox->isChecked();
|
||||
this->settings.FilterEventsForButtons = this->filterEventsForButtonsCheckBox->isChecked();
|
||||
this->settings.FilterEventsForAxis = this->filterEventsForAxisCheckBox->isChecked();
|
||||
}
|
||||
|
||||
this->accept();
|
||||
|
||||
@@ -24,6 +24,8 @@ struct OptionsDialogSettings
|
||||
|
||||
// UI settings
|
||||
bool RemoveDuplicateMappings = false;
|
||||
bool FilterEventsForButtons = true;
|
||||
bool FilterEventsForAxis = true;
|
||||
};
|
||||
|
||||
namespace UserInterface
|
||||
|
||||
@@ -202,6 +202,20 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="filterEventsForButtonsCheckBox">
|
||||
<property name="text">
|
||||
<string>Filter Events Based On Joystick Type For Buttons</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="filterEventsForAxisCheckBox">
|
||||
<property name="text">
|
||||
<string>Filter Events Based On Joystick Type For Axis</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
|
||||
@@ -302,6 +302,11 @@ bool ControllerWidget::isSectionUserProfile(QString section)
|
||||
return section.contains("User Profile");
|
||||
}
|
||||
|
||||
bool ControllerWidget::isSectionGameProfile(QString section)
|
||||
{
|
||||
return !this->isSectionUserProfile(section) && section.contains("Game");
|
||||
}
|
||||
|
||||
void ControllerWidget::setPluggedIn(bool value)
|
||||
{
|
||||
QWidget* widgetList[] =
|
||||
@@ -446,6 +451,12 @@ void ControllerWidget::CheckInputDeviceSettings()
|
||||
(this->inputDeviceComboBox->itemText(deviceNumIndex).startsWith(QString::fromStdString(deviceName))))
|
||||
{ // full match
|
||||
this->inputDeviceComboBox->setCurrentIndex(deviceNumIndex);
|
||||
|
||||
// force-refresh automatic input device
|
||||
if (deviceNum == (int)InputDeviceType::Automatic)
|
||||
{
|
||||
this->on_inputDeviceComboBox_currentIndexChanged(deviceNumIndex);
|
||||
}
|
||||
}
|
||||
else if (deviceNameIndex != -1)
|
||||
{ // name only match
|
||||
@@ -507,11 +518,7 @@ void ControllerWidget::on_profileComboBox_currentIndexChanged(int value)
|
||||
if (this->previousProfileComboBoxIndex < this->profileComboBox->count())
|
||||
{
|
||||
QString section = this->profileComboBox->itemData(this->previousProfileComboBoxIndex).toString();
|
||||
// TODO: how to handle game specific profiles here?
|
||||
if (!section.startsWith(this->settingsSection + " Game"))
|
||||
{
|
||||
this->SaveSettings(section);
|
||||
}
|
||||
this->SaveSettings(section);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -558,6 +565,7 @@ void ControllerWidget::on_addProfileButton_clicked()
|
||||
{
|
||||
std::vector<std::string> profiles;
|
||||
std::vector<std::string>::iterator profilesIter;
|
||||
QString section;
|
||||
|
||||
// retrieve profiles from settings
|
||||
profiles = CoreSettingsGetStringListValue(SettingsID::Input_Profiles);
|
||||
@@ -590,16 +598,24 @@ void ControllerWidget::on_addProfileButton_clicked()
|
||||
return;
|
||||
}
|
||||
|
||||
section = this->getUserProfileSectionName(newProfile);
|
||||
|
||||
// add profile to UI
|
||||
this->profileComboBox->addItem(newProfile, this->getUserProfileSectionName(newProfile));
|
||||
this->profileComboBox->addItem(newProfile, section);
|
||||
this->profileComboBox->setCurrentText(newProfile);
|
||||
|
||||
// add profile to settings
|
||||
profiles.push_back(newProfile.toStdString());
|
||||
CoreSettingsSetValue(SettingsID::Input_Profiles, profiles);
|
||||
|
||||
// update added profiles
|
||||
if (!this->addedProfiles.contains(section))
|
||||
{
|
||||
this->addedProfiles.push_back(section);
|
||||
}
|
||||
|
||||
// emit signal
|
||||
emit this->UserProfileAdded(newProfile, this->getUserProfileSectionName(newProfile));
|
||||
emit this->UserProfileAdded(newProfile, section);
|
||||
}
|
||||
|
||||
void ControllerWidget::on_removeProfileButton_clicked()
|
||||
@@ -623,12 +639,12 @@ void ControllerWidget::on_removeProfileButton_clicked()
|
||||
|
||||
QString currentSection = this->getCurrentSettingsSection();
|
||||
|
||||
// try to remove profile settings section when it exists
|
||||
if (CoreSettingsSectionExists(currentSection.toStdString()) &&
|
||||
!CoreSettingsDeleteSection(currentSection.toStdString()))
|
||||
{ // show error when failed
|
||||
this->showErrorMessage("CoreSettingsDeleteSection() Failed!", QString::fromStdString(CoreGetError()));
|
||||
// add to removed profiles list (will be deleted later)
|
||||
if (!this->removedProfiles.contains(currentSection))
|
||||
{
|
||||
this->removedProfiles.push_back(currentSection);
|
||||
}
|
||||
this->addedProfiles.removeAll(currentSection);
|
||||
|
||||
// if section is a user profile,
|
||||
// also remove it from the profiles list
|
||||
@@ -653,8 +669,15 @@ void ControllerWidget::on_removeProfileButton_clicked()
|
||||
emit this->UserProfileRemoved(this->profileComboBox->currentText(), currentSection);
|
||||
}
|
||||
|
||||
// change current index
|
||||
this->profileComboBox->setCurrentIndex(0);
|
||||
// switch back to main profile when deleting
|
||||
// a per game profile
|
||||
if (this->isSectionGameProfile(currentSection))
|
||||
{
|
||||
// ensure we don't save the game specific profile
|
||||
// upon switching to the main profile
|
||||
this->previousProfileComboBoxIndex = -1;
|
||||
this->profileComboBox->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerWidget::on_resetButton_clicked()
|
||||
@@ -739,7 +762,8 @@ void ControllerWidget::on_MainDialog_SdlEvent(SDL_Event* event)
|
||||
if ((event->type == SDL_CONTROLLERBUTTONDOWN) ||
|
||||
(event->type == SDL_CONTROLLERBUTTONUP))
|
||||
{ // gamepad button
|
||||
if (!this->isCurrentJoystickGameController)
|
||||
if (!this->isCurrentJoystickGameController &&
|
||||
this->optionsDialogSettings.FilterEventsForButtons)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -752,7 +776,8 @@ void ControllerWidget::on_MainDialog_SdlEvent(SDL_Event* event)
|
||||
}
|
||||
else
|
||||
{ // joystick button
|
||||
if (this->isCurrentJoystickGameController)
|
||||
if (this->isCurrentJoystickGameController &&
|
||||
this->optionsDialogSettings.FilterEventsForButtons)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -853,7 +878,8 @@ void ControllerWidget::on_MainDialog_SdlEvent(SDL_Event* event)
|
||||
|
||||
if (event->type == SDL_CONTROLLERAXISMOTION)
|
||||
{ // gamepad axis
|
||||
if (!this->isCurrentJoystickGameController)
|
||||
if (!this->isCurrentJoystickGameController &&
|
||||
this->optionsDialogSettings.FilterEventsForAxis)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -867,7 +893,8 @@ void ControllerWidget::on_MainDialog_SdlEvent(SDL_Event* event)
|
||||
}
|
||||
else
|
||||
{ // joystick axis
|
||||
if (this->isCurrentJoystickGameController)
|
||||
if (this->isCurrentJoystickGameController &&
|
||||
this->optionsDialogSettings.FilterEventsForAxis)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1077,7 +1104,6 @@ void ControllerWidget::LoadSettings()
|
||||
}
|
||||
|
||||
QString section = this->settingsSection;
|
||||
QString gameSection;
|
||||
std::vector<std::string> userProfiles;
|
||||
|
||||
// if the main profile section doesn't exist,
|
||||
@@ -1095,26 +1121,33 @@ void ControllerWidget::LoadSettings()
|
||||
if (CoreGetCurrentRomSettings(romSettings) &&
|
||||
CoreGetCurrentRomHeader(romHeader))
|
||||
{
|
||||
gameSection = section + " Game " + QString::fromStdString(romSettings.MD5);
|
||||
this->gameSection = section + " Game " + QString::fromStdString(romSettings.MD5);
|
||||
|
||||
// use internal rom name
|
||||
QString internalName = QString::fromStdString(romHeader.Name);
|
||||
|
||||
// add game specific profile when
|
||||
// it doesn't exist yet
|
||||
int index = this->profileComboBox->findData(gameSection);
|
||||
int index = this->profileComboBox->findData(this->gameSection);
|
||||
if (index == -1)
|
||||
{
|
||||
this->profileComboBox->addItem(internalName, gameSection);
|
||||
this->profileComboBox->addItem(internalName, this->gameSection);
|
||||
}
|
||||
|
||||
// if a game specific section exists,
|
||||
// select it in the profile combobox
|
||||
// and use it to load the settings
|
||||
if (CoreSettingsSectionExists(gameSection.toStdString()))
|
||||
if (CoreSettingsSectionExists(this->gameSection.toStdString()))
|
||||
{
|
||||
this->profileComboBox->setCurrentText(internalName);
|
||||
section = gameSection;
|
||||
// check if the key 'UseGameProfile' exists,
|
||||
// if it doesn't then use the profile,
|
||||
// else check if it's true and use it
|
||||
if (!CoreSettingsKeyExists(this->gameSection.toStdString(), "UseGameProfile") ||
|
||||
CoreSettingsGetBoolValue(SettingsID::Input_UseGameProfile, this->gameSection.toStdString()))
|
||||
{
|
||||
this->profileComboBox->setCurrentText(internalName);
|
||||
section = this->gameSection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1145,10 +1178,27 @@ void ControllerWidget::LoadSettings(QString sectionQString, bool loadUserProfile
|
||||
std::string section = sectionQString.toStdString();
|
||||
std::string useProfile;
|
||||
|
||||
// if the removed profiles contain
|
||||
// the section, don't load it
|
||||
if (this->removedProfiles.contains(sectionQString) &&
|
||||
!this->addedProfiles.contains(sectionQString))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// do nothing if the section doesn't exist
|
||||
if (!CoreSettingsSectionExists(section))
|
||||
{
|
||||
return;
|
||||
// fallback to main section for per game profiles
|
||||
if (this->isSectionGameProfile(sectionQString))
|
||||
{
|
||||
sectionQString = this->settingsSection;
|
||||
section = this->settingsSection.toStdString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// see if the profile contains the UseProfile setting,
|
||||
@@ -1174,6 +1224,19 @@ void ControllerWidget::LoadSettings(QString sectionQString, bool loadUserProfile
|
||||
this->optionsDialogSettings.GameboyRom = CoreSettingsGetStringValue(SettingsID::Input_GameboyRom, section);
|
||||
this->optionsDialogSettings.GameboySave = CoreSettingsGetStringValue(SettingsID::Input_GameboySave, section);
|
||||
|
||||
// keep backwards compatibility with old profiles
|
||||
if (CoreSettingsKeyExists(section, "FilterEventsForButtons") &&
|
||||
CoreSettingsKeyExists(section, "FilterEventsForAxis"))
|
||||
{
|
||||
this->optionsDialogSettings.FilterEventsForButtons = CoreSettingsGetBoolValue(SettingsID::Input_FilterEventsForButtons, section);
|
||||
this->optionsDialogSettings.FilterEventsForAxis = CoreSettingsGetBoolValue(SettingsID::Input_FilterEventsForAxis, section);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->optionsDialogSettings.FilterEventsForButtons = true;
|
||||
this->optionsDialogSettings.FilterEventsForAxis = true;
|
||||
}
|
||||
|
||||
for (auto& buttonSetting : this->buttonSettingMappings)
|
||||
{
|
||||
buttonSetting.button->Clear();
|
||||
@@ -1234,6 +1297,8 @@ void ControllerWidget::SaveDefaultSettings()
|
||||
CoreSettingsSetValue(SettingsID::Input_Deadzone, section, 9);
|
||||
CoreSettingsSetValue(SettingsID::Input_Pak, section, 0);
|
||||
CoreSettingsSetValue(SettingsID::Input_RemoveDuplicateMappings, section, true);
|
||||
CoreSettingsSetValue(SettingsID::Input_FilterEventsForButtons, section, true);
|
||||
CoreSettingsSetValue(SettingsID::Input_FilterEventsForAxis, section, true);
|
||||
|
||||
for (auto& buttonSetting : this->buttonSettingMappings)
|
||||
{
|
||||
@@ -1242,8 +1307,6 @@ void ControllerWidget::SaveDefaultSettings()
|
||||
CoreSettingsSetValue(buttonSetting.dataSettingsId, section, std::vector<int>({ 0 }));
|
||||
CoreSettingsSetValue(buttonSetting.extraDataSettingsId, section, std::vector<int>({ 0 }));
|
||||
}
|
||||
|
||||
CoreSettingsSave();
|
||||
}
|
||||
|
||||
void ControllerWidget::SaveSettings()
|
||||
@@ -1252,8 +1315,17 @@ void ControllerWidget::SaveSettings()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this->SaveSettings(this->getCurrentSettingsSection());
|
||||
|
||||
// delete all removed profile sections
|
||||
for (QString section : this->removedProfiles)
|
||||
{
|
||||
if (!this->addedProfiles.contains(section))
|
||||
{
|
||||
CoreSettingsDeleteSection(section.toStdString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerWidget::SaveUserProfileSettings()
|
||||
@@ -1289,6 +1361,18 @@ void ControllerWidget::SaveSettings(QString section)
|
||||
CoreSettingsSetValue(SettingsID::Input_UseProfile, mainSettingsSection, std::string(""));
|
||||
}
|
||||
|
||||
// when section is a game specific profile,
|
||||
// make sure we tell it whether or not to use it
|
||||
if (this->isSectionGameProfile(section))
|
||||
{
|
||||
CoreSettingsSetValue(SettingsID::Input_UseGameProfile, sectionStr, true);
|
||||
}
|
||||
else if (!this->gameSection.isEmpty() &&
|
||||
CoreSettingsSectionExists(this->gameSection.toStdString()))
|
||||
{
|
||||
CoreSettingsSetValue(SettingsID::Input_UseGameProfile, this->gameSection.toStdString(), false);
|
||||
}
|
||||
|
||||
this->GetCurrentInputDevice(deviceName, deviceNum, true);
|
||||
|
||||
CoreSettingsSetValue(SettingsID::Input_PluggedIn, sectionStr, this->IsPluggedIn());
|
||||
@@ -1299,6 +1383,8 @@ void ControllerWidget::SaveSettings(QString section)
|
||||
CoreSettingsSetValue(SettingsID::Input_GameboyRom, sectionStr, this->optionsDialogSettings.GameboyRom);
|
||||
CoreSettingsSetValue(SettingsID::Input_GameboySave, sectionStr, this->optionsDialogSettings.GameboySave);
|
||||
CoreSettingsSetValue(SettingsID::Input_RemoveDuplicateMappings, sectionStr, this->optionsDialogSettings.RemoveDuplicateMappings);
|
||||
CoreSettingsSetValue(SettingsID::Input_FilterEventsForButtons, sectionStr, this->optionsDialogSettings.FilterEventsForButtons);
|
||||
CoreSettingsSetValue(SettingsID::Input_FilterEventsForAxis, sectionStr, this->optionsDialogSettings.FilterEventsForAxis);
|
||||
|
||||
for (auto& buttonSetting : this->buttonSettingMappings)
|
||||
{
|
||||
@@ -1307,8 +1393,47 @@ void ControllerWidget::SaveSettings(QString section)
|
||||
CoreSettingsSetValue(buttonSetting.dataSettingsId, sectionStr, buttonSetting.button->GetInputData());
|
||||
CoreSettingsSetValue(buttonSetting.extraDataSettingsId, sectionStr, buttonSetting.button->GetExtraInputData());
|
||||
}
|
||||
}
|
||||
|
||||
CoreSettingsSave();
|
||||
void ControllerWidget::RevertSettings()
|
||||
{
|
||||
QList<QString> sections;
|
||||
|
||||
// add all sections from profile combobox
|
||||
for (int i = 0; i < this->profileComboBox->count(); i++)
|
||||
{
|
||||
sections.push_back(this->profileComboBox->itemData(i).toString());
|
||||
}
|
||||
|
||||
// add section with profiles list
|
||||
sections.push_back("Rosalie's Mupen GUI - Input Plugin");
|
||||
|
||||
// add removed profile sections
|
||||
for (QString section : this->removedProfiles)
|
||||
{
|
||||
// ensure it's unique
|
||||
if (!this->addedProfiles.contains(section) &&
|
||||
!sections.contains(section))
|
||||
{
|
||||
sections.push_back(section);
|
||||
}
|
||||
}
|
||||
|
||||
// revert each section
|
||||
for (QString section : sections)
|
||||
{
|
||||
CoreSettingsRevertSection(section.toStdString());
|
||||
}
|
||||
|
||||
// delete all sections for added profiles,
|
||||
// which weren't deleted
|
||||
for (QString section : this->addedProfiles)
|
||||
{
|
||||
if (!this->removedProfiles.contains(section))
|
||||
{
|
||||
CoreSettingsDeleteSection(section.toStdString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerWidget::SetCurrentJoystickID(SDL_JoystickID joystickId)
|
||||
|
||||
@@ -36,13 +36,17 @@ class ControllerWidget : public QWidget, Ui::ControllerWidget
|
||||
private:
|
||||
bool initialized = false;
|
||||
QString settingsSection;
|
||||
|
||||
QString gameSection;
|
||||
|
||||
OptionsDialogSettings optionsDialogSettings;
|
||||
|
||||
QList<QString> inputDeviceNameList;
|
||||
MappingButton* currentButton = nullptr;
|
||||
bool addMappingToButton = false;
|
||||
|
||||
|
||||
QList<QString> removedProfiles;
|
||||
QList<QString> addedProfiles;
|
||||
|
||||
struct buttonWidgetMapping
|
||||
{
|
||||
enum N64ControllerButton button;
|
||||
@@ -82,9 +86,11 @@ private:
|
||||
void removeDuplicates(MappingButton* button);
|
||||
|
||||
QString getCurrentSettingsSection();
|
||||
|
||||
|
||||
QString getUserProfileSectionName(QString profile);
|
||||
|
||||
bool isSectionUserProfile(QString section);
|
||||
bool isSectionGameProfile(QString section);
|
||||
|
||||
void setPluggedIn(bool value);
|
||||
|
||||
@@ -115,12 +121,14 @@ public:
|
||||
void LoadSettings();
|
||||
void LoadSettings(QString section, bool loadUserProfile = false);
|
||||
void LoadUserProfileSettings();
|
||||
|
||||
|
||||
void SaveDefaultSettings();
|
||||
void SaveSettings();
|
||||
void SaveUserProfileSettings();
|
||||
void SaveSettings(QString section);
|
||||
|
||||
void RevertSettings();
|
||||
|
||||
void SetCurrentJoystickID(SDL_JoystickID joystickId);
|
||||
void SetIsCurrentJoystickGameController(bool isGameController);
|
||||
|
||||
|
||||
@@ -30,6 +30,12 @@
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<item>
|
||||
<widget class="QComboBox" name="profileComboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContents</enum>
|
||||
</property>
|
||||
@@ -37,6 +43,12 @@
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addProfileButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
@@ -44,6 +56,12 @@
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="removeProfileButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
@@ -80,7 +98,7 @@
|
||||
<item>
|
||||
<widget class="QComboBox" name="inputDeviceComboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@@ -93,7 +111,7 @@
|
||||
<item>
|
||||
<widget class="QPushButton" name="inputDeviceRefreshButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@@ -128,7 +146,7 @@
|
||||
<item>
|
||||
<widget class="QSlider" name="deadZoneSlider">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
|
||||
@@ -14,8 +14,10 @@ using namespace UserInterface::Widget;
|
||||
|
||||
MappingButton::MappingButton(QWidget* parent) : QPushButton(parent)
|
||||
{
|
||||
this->countDownTimer = new QTimer(this);
|
||||
this->countDownTimer = new QTimer(this);
|
||||
connect(this->countDownTimer, &QTimer::timeout, this, &MappingButton::on_countDownTimer_triggered);
|
||||
|
||||
this->initialSize = this->size();
|
||||
}
|
||||
|
||||
MappingButton::~MappingButton()
|
||||
@@ -223,7 +225,7 @@ void MappingButton::reloadText()
|
||||
}
|
||||
}
|
||||
|
||||
QString elidedText = fontMetrics.elidedText(text, Qt::ElideRight, this->width());
|
||||
QString elidedText = fontMetrics.elidedText(text, Qt::ElideRight, this->initialSize.width());
|
||||
|
||||
// needed for spacing
|
||||
if (elidedText.isEmpty())
|
||||
|
||||
@@ -36,6 +36,7 @@ struct MappingButtonInputDataType
|
||||
class MappingButton : public QPushButton
|
||||
{
|
||||
private:
|
||||
QSize initialSize;
|
||||
QTimer* countDownTimer = nullptr;
|
||||
ControllerWidget* controllerWidget = nullptr;
|
||||
int currentCountDownNum = 0;
|
||||
|
||||
+55
-34
@@ -183,13 +183,19 @@ static void load_settings(void)
|
||||
}
|
||||
|
||||
// if game ID was retrieved,
|
||||
// check if game section exists, if it does
|
||||
// use that section instead of the main section
|
||||
// check if game section exists,
|
||||
// if it does, check if the 'UseGameProfile' key exists,
|
||||
// if it doesn't then use the profile, else
|
||||
// check if the value is true
|
||||
if (!gameId.empty())
|
||||
{
|
||||
if (CoreSettingsSectionExists(gameSection))
|
||||
{
|
||||
section = gameSection;
|
||||
if (!CoreSettingsKeyExists(gameSection, "UseGameProfile") ||
|
||||
CoreSettingsGetBoolValue(SettingsID::Input_UseGameProfile, gameSection))
|
||||
{
|
||||
section = gameSection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,7 +403,7 @@ static void close_controllers(void)
|
||||
}
|
||||
}
|
||||
|
||||
static int get_button_state(InputProfile* profile, InputMapping* inputMapping)
|
||||
static int get_button_state(InputProfile* profile, const InputMapping* inputMapping)
|
||||
{
|
||||
int state = 0;
|
||||
|
||||
@@ -439,9 +445,10 @@ static int get_button_state(InputProfile* profile, InputMapping* inputMapping)
|
||||
}
|
||||
|
||||
// returns axis input scaled to the range [-1, 1]
|
||||
static double get_axis_state(InputProfile* profile, InputMapping* inputMapping, int direction, double value)
|
||||
static double get_axis_state(InputProfile* profile, const InputMapping* inputMapping, const int direction, const double value, bool& useButtonMapping)
|
||||
{
|
||||
int state = 0;
|
||||
double axis_state = value;
|
||||
bool button_state = false;
|
||||
|
||||
for (int i = 0; i < inputMapping->Count; i++)
|
||||
{
|
||||
@@ -452,8 +459,7 @@ static double get_axis_state(InputProfile* profile, InputMapping* inputMapping,
|
||||
{
|
||||
case InputType::GamepadButton:
|
||||
{
|
||||
int buttonState = SDL_GameControllerGetButton(profile->InputDevice.GetGameControllerHandle(), (SDL_GameControllerButton)data);
|
||||
state |= buttonState;
|
||||
button_state |= SDL_GameControllerGetButton(profile->InputDevice.GetGameControllerHandle(), (SDL_GameControllerButton)data);;
|
||||
} break;
|
||||
case InputType::GamepadAxis:
|
||||
{
|
||||
@@ -462,13 +468,12 @@ static double get_axis_state(InputProfile* profile, InputMapping* inputMapping,
|
||||
{
|
||||
axis_value = (axis_value / SDL_AXIS_PEAK);
|
||||
axis_value = abs(axis_value) * direction;
|
||||
return axis_value;
|
||||
axis_state = axis_value;
|
||||
}
|
||||
} break;
|
||||
case InputType::JoystickButton:
|
||||
{
|
||||
int buttonState = SDL_JoystickGetButton(profile->InputDevice.GetJoystickHandle(), data);
|
||||
state |= buttonState;
|
||||
button_state |= SDL_JoystickGetButton(profile->InputDevice.GetJoystickHandle(), data);;
|
||||
} break;
|
||||
case InputType::JoystickAxis:
|
||||
{
|
||||
@@ -477,22 +482,37 @@ static double get_axis_state(InputProfile* profile, InputMapping* inputMapping,
|
||||
{
|
||||
axis_value = (axis_value / SDL_AXIS_PEAK);
|
||||
axis_value = abs(axis_value) * direction;
|
||||
return axis_value;
|
||||
axis_state = axis_value;
|
||||
}
|
||||
} break;
|
||||
case InputType::Keyboard:
|
||||
{
|
||||
state |= l_KeyboardState[data];
|
||||
button_state |= l_KeyboardState[data];
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return state ? direction : value;
|
||||
// when a button has been mapped
|
||||
// to an axis, we should prioritize
|
||||
// the button when it's been pressed
|
||||
if (button_state)
|
||||
{
|
||||
useButtonMapping = true;
|
||||
return direction;
|
||||
}
|
||||
else if (!useButtonMapping)
|
||||
{
|
||||
return axis_state;
|
||||
}
|
||||
else
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
static double simulate_deadzone(double n64InputAxis, double maxAxis, int deadzone, double axisRange)
|
||||
static double simulate_deadzone(const double n64InputAxis, const double maxAxis, const int deadzone, const double axisRange)
|
||||
{
|
||||
double axisAbsolute = std::abs(n64InputAxis);
|
||||
|
||||
@@ -510,12 +530,12 @@ static double simulate_deadzone(double n64InputAxis, double maxAxis, int deadzon
|
||||
}
|
||||
|
||||
// Credit: MerryMage
|
||||
static void simulate_octagon(double inputX, double inputY, double deadzoneFactor, int& outputX, int& outputY)
|
||||
static void simulate_octagon(const double inputX, const double inputY, const double deadzoneFactor, int& outputX, int& outputY)
|
||||
{
|
||||
double maxAxis = N64_AXIS_PEAK;
|
||||
double maxDiagonal = MAX_DIAGONAL_VALUE;
|
||||
int deadzone = static_cast<int>(deadzoneFactor * N64_AXIS_PEAK);
|
||||
double axisRange = maxAxis - deadzone;
|
||||
const double maxAxis = N64_AXIS_PEAK;
|
||||
const double maxDiagonal = MAX_DIAGONAL_VALUE;
|
||||
const int deadzone = (int)(deadzoneFactor * N64_AXIS_PEAK);
|
||||
const double axisRange = maxAxis - deadzone;
|
||||
// scale to [-maxAxis, maxAxis]
|
||||
double ax = inputX * maxAxis;
|
||||
double ay = inputY * maxAxis;
|
||||
@@ -539,18 +559,18 @@ static void simulate_octagon(double inputX, double inputY, double deadzoneFactor
|
||||
// bound diagonals to an octagonal range [-69, 69]
|
||||
if (ax != 0.0 && ay != 0.0)
|
||||
{
|
||||
double slope = ay / ax;
|
||||
double edgex = copysign(maxAxis / (std::abs(slope) + (maxAxis - maxDiagonal) / maxDiagonal), ax);
|
||||
double edgey = copysign(std::min(std::abs(edgex * slope), maxAxis / (1.0 / std::abs(slope) + (maxAxis - maxDiagonal) / maxDiagonal)), ay);
|
||||
const double slope = ay / ax;
|
||||
double edgex = std::copysign(maxAxis / (std::abs(slope) + (maxAxis - maxDiagonal) / maxDiagonal), ax);
|
||||
const double edgey = std::copysign(std::min(std::abs(edgex * slope), maxAxis / (1.0 / std::abs(slope) + (maxAxis - maxDiagonal) / maxDiagonal)), ay);
|
||||
edgex = edgey / slope;
|
||||
|
||||
double scale = std::sqrt(edgex*edgex + edgey*edgey) / maxAxis;
|
||||
const double scale = std::sqrt(edgex*edgex + edgey*edgey) / maxAxis;
|
||||
ax *= scale;
|
||||
ay *= scale;
|
||||
}
|
||||
|
||||
outputX = static_cast<int>(ax);
|
||||
outputY = static_cast<int>(ay);
|
||||
outputX = (int)ax;
|
||||
outputY = (int)ay;
|
||||
}
|
||||
|
||||
static unsigned char data_crc(unsigned char *data, int length)
|
||||
@@ -581,7 +601,7 @@ void sdl_init()
|
||||
{
|
||||
std::filesystem::path gameControllerDbPath;
|
||||
|
||||
for (int subsystem : {SDL_INIT_GAMECONTROLLER, SDL_INIT_VIDEO, SDL_INIT_HAPTIC})
|
||||
for (const int subsystem : {SDL_INIT_GAMECONTROLLER, SDL_INIT_VIDEO, SDL_INIT_HAPTIC})
|
||||
{
|
||||
if (!SDL_WasInit(subsystem))
|
||||
{
|
||||
@@ -598,7 +618,7 @@ void sdl_init()
|
||||
|
||||
void sdl_quit()
|
||||
{
|
||||
for (int subsystem : {SDL_INIT_GAMECONTROLLER, SDL_INIT_HAPTIC})
|
||||
for (const int subsystem : {SDL_INIT_GAMECONTROLLER, SDL_INIT_HAPTIC})
|
||||
{
|
||||
if (SDL_WasInit(subsystem))
|
||||
{
|
||||
@@ -804,7 +824,7 @@ EXPORT void CALL GetKeys(int Control, BUTTONS* Keys)
|
||||
// check if device has been disconnected,
|
||||
// if it has, try to open it again,
|
||||
// only do this every 2 seconds to prevent lag
|
||||
const auto currentTime = std::chrono::high_resolution_clock::now();
|
||||
const auto currentTime = std::chrono::high_resolution_clock::now();
|
||||
const int secondsPassed = std::chrono::duration_cast<std::chrono::seconds>(currentTime - profile->LastDeviceCheckTime).count();
|
||||
if (secondsPassed >= 2)
|
||||
{
|
||||
@@ -840,10 +860,11 @@ EXPORT void CALL GetKeys(int Control, BUTTONS* Keys)
|
||||
Keys->Z_TRIG = get_button_state(profile, &profile->Button_ZTrigger);
|
||||
|
||||
double inputX = 0, inputY = 0;
|
||||
inputY = get_axis_state(profile, &profile->AnalogStick_Up, 1, inputY);
|
||||
inputY = get_axis_state(profile, &profile->AnalogStick_Down, -1, inputY);
|
||||
inputX = get_axis_state(profile, &profile->AnalogStick_Left, -1, inputX);
|
||||
inputX = get_axis_state(profile, &profile->AnalogStick_Right, 1, inputX);
|
||||
bool useButtonMapping = false;
|
||||
inputY = get_axis_state(profile, &profile->AnalogStick_Up, 1, inputY, useButtonMapping);
|
||||
inputY = get_axis_state(profile, &profile->AnalogStick_Down, -1, inputY, useButtonMapping);
|
||||
inputX = get_axis_state(profile, &profile->AnalogStick_Left, -1, inputX, useButtonMapping);
|
||||
inputX = get_axis_state(profile, &profile->AnalogStick_Right, 1, inputX, useButtonMapping);
|
||||
|
||||
int octagonX = 0, octagonY = 0;
|
||||
simulate_octagon(
|
||||
|
||||
@@ -39,16 +39,40 @@ void InstallUpdateDialog::install(void)
|
||||
|
||||
QString appPath = QCoreApplication::applicationDirPath();
|
||||
QString appPid = QString::number(QCoreApplication::applicationPid());
|
||||
QString logPath = appPath + "/Cache/updater.log";
|
||||
|
||||
#ifdef _WIN32
|
||||
// convert paths to use the right path seperator
|
||||
this->temporaryDirectory = QDir::toNativeSeparators(this->temporaryDirectory);
|
||||
fullFilePath = QDir::toNativeSeparators(fullFilePath);
|
||||
appPath = QDir::toNativeSeparators(appPath);
|
||||
logPath = QDir::toNativeSeparators(logPath);
|
||||
|
||||
// remove log file when it exists
|
||||
QFile qLogFile(logPath);
|
||||
if (qLogFile.exists())
|
||||
{
|
||||
qLogFile.remove();
|
||||
}
|
||||
|
||||
QString outputToLogLine = " >> \"" + logPath + "\" 2>&1";
|
||||
|
||||
if (this->filename.endsWith(".exe"))
|
||||
{
|
||||
this->label->setText("Executing " + this->filename + "...");
|
||||
QStringList scriptLines =
|
||||
QStringList scriptLines =
|
||||
{
|
||||
"@echo off",
|
||||
"taskkill /F /PID:" + appPid,
|
||||
"\"" + fullFilePath + "\" /CLOSEAPPLICATIONS /SILENT /DIR=\"" + appPath + "\"",
|
||||
"(",
|
||||
" echo == Attemping to kill PID " + appPid + outputToLogLine,
|
||||
" taskkill /F /PID:" + appPid + outputToLogLine,
|
||||
" echo == Attemping to start \'" + fullFilePath + "\'" + outputToLogLine,
|
||||
" \"" + fullFilePath + "\" /CLOSEAPPLICATIONS /NOCANCEL /SILENT /DIR=\"" + appPath + "\"" + outputToLogLine,
|
||||
")",
|
||||
"IF NOT ERRORLEVEL 0 (",
|
||||
" start \"\" cmd /c \"echo Rosalie's Mupen GUI failed to update, check the updater.log file in the Cache directory for more information && pause\"",
|
||||
")",
|
||||
// remove temporary directory at last
|
||||
"rmdir /S /Q \"" + this->temporaryDirectory + "\"",
|
||||
};
|
||||
this->writeAndRunScript(scriptLines);
|
||||
@@ -77,20 +101,32 @@ void InstallUpdateDialog::install(void)
|
||||
this->showErrorMessage("CoreUnzip() Failed!", QString::fromStdString(CoreGetError()));
|
||||
this->reject();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this->label->setText("Executing update script...");
|
||||
this->progressBar->setValue(100);
|
||||
|
||||
#ifdef _WIN32
|
||||
extractDirectory = QDir::toNativeSeparators(extractDirectory);
|
||||
|
||||
QStringList scriptLines =
|
||||
{
|
||||
"@echo off",
|
||||
"del /F /Q \"" + fullFilePath + "\"",
|
||||
"taskkill /F /PID:" + appPid,
|
||||
"xcopy /S /Y /I \"" + extractDirectory + "\\*\" \"" + appPath + "/\"",
|
||||
"start \"\" \"" + appPath + "\\RMG.exe\"",
|
||||
"rmdir /S /Q \"" + this->temporaryDirectory + "\"",
|
||||
"(",
|
||||
" echo == Attempting to remove \'" + fullFilePath + "\'" + outputToLogLine,
|
||||
" del /F /Q \"" + fullFilePath + "\"" + outputToLogLine,
|
||||
" echo == Attemping to kill PID " + appPid + outputToLogLine,
|
||||
" taskkill /F /PID:" + appPid + outputToLogLine,
|
||||
" echo == Attemping to copy \'" + extractDirectory + "\' to \'" + appPath + "\'" + outputToLogLine,
|
||||
" xcopy /S /Y /I \"" + extractDirectory + "\\*\" \"" + appPath + "\"" + outputToLogLine,
|
||||
" echo == Attemping to start \'" + appPath + "\\RMG.exe\'" + outputToLogLine,
|
||||
" start \"\" \"" + appPath + "\\RMG.exe\"" + outputToLogLine,
|
||||
")",
|
||||
"IF NOT ERRORLEVEL 0 (",
|
||||
" start \"\" cmd /c \"echo Rosalie's Mupen GUI failed to update, check the updater.log file in the Cache directory for more information && pause\"",
|
||||
")",
|
||||
// remove temporary directory at last
|
||||
"rmdir /S /Q \"" + this->temporaryDirectory + "\"",
|
||||
};
|
||||
this->writeAndRunScript(scriptLines);
|
||||
#else // Linux
|
||||
|
||||
Reference in New Issue
Block a user