DEV9: Allow configuring HDD in UI & add progress UI for HDD creation

This commit is contained in:
TheLastRar 2020-11-23 19:55:08 +00:00 committed by refractionpcsx2
parent 31a3ee3cbc
commit dc3bd53f7b
8 changed files with 682 additions and 262 deletions

View File

@ -20,8 +20,54 @@
void HddCreate::Start() void HddCreate::Start()
{ {
//This can be called from the EE Core thread
//ensure that UI creation/deletaion is done on main thread
if (!wxIsMainThread())
{
wxTheApp->CallAfter([&] { Start(); });
//Block until done
std::unique_lock competedLock(completedMutex);
completedCV.wait(competedLock, [&] { return completed; });
return;
}
//This creates a modeless dialog
progressDialog = new wxProgressDialog("Creating HDD file", "Creating HDD file", neededSize, nullptr, wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME | wxPD_REMAINING_TIME);
fileThread = std::thread(&HddCreate::WriteImage, this, filePath, neededSize); fileThread = std::thread(&HddCreate::WriteImage, this, filePath, neededSize);
//This code was written for a modal dialog, however wxProgressDialog is modeless only
//The idea was block here in a ShowModal() call, and have the worker thread update the UI
//via CallAfter()
//Instead, loop here to update UI
char msg[32] = {0};
int currentSize;
while ((currentSize = written.load()) != neededSize && !errored.load())
{
snprintf(msg, 32, "%i / %i MiB", written.load(), neededSize);
if (!progressDialog->Update(currentSize, msg))
canceled.store(true);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
fileThread.join(); fileThread.join();
if (errored.load())
{
wxMessageDialog dialog(nullptr, "Failed to create HDD file", "Info", wxOK);
dialog.ShowModal();
}
delete progressDialog;
//Signal calling thread to resume
{
std::lock_guard ioSignallock(completedMutex);
completed = true;
}
completedCV.notify_all();
} }
void HddCreate::WriteImage(ghc::filesystem::path hddPath, int reqSizeMiB) void HddCreate::WriteImage(ghc::filesystem::path hddPath, int reqSizeMiB)
@ -73,35 +119,31 @@ void HddCreate::WriteImage(ghc::filesystem::path hddPath, int reqSizeMiB)
return; return;
} }
} }
SetFileProgress(iMiB + 1);
const std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
if (std::chrono::duration_cast<std::chrono::milliseconds>(now - lastUpdate).count() >= 100 || (iMiB + 1) == neededSize)
{
lastUpdate = now;
SetFileProgress(iMiB + 1);
}
if (canceled.load())
{
newImage.close();
ghc::filesystem::remove(filePath);
SetError();
return;
}
} }
newImage.flush(); newImage.flush();
newImage.close(); newImage.close();
SetDone();
} }
void HddCreate::SetFileProgress(int currentSize) void HddCreate::SetFileProgress(int currentSize)
{ {
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); written.store(currentSize);
if (std::chrono::duration_cast<std::chrono::seconds>(now - lastUpdate).count() >= 1)
{
lastUpdate = now;
fprintf(stdout, "%i / %i MiB\n", currentSize, neededSize);
}
} }
void HddCreate::SetError() void HddCreate::SetError()
{ {
fprintf(stderr, "Unable to create file\n");
errored.store(true); errored.store(true);
completed.store(true);
} }
void HddCreate::SetDone()
{
fprintf(stdout, "%i / %i MiB\n", neededSize, neededSize);
fprintf(stdout, "Done\n");
completed.store(true);
}

View File

@ -15,9 +15,12 @@
#pragma once #pragma once
#include <wx/progdlg.h>
#include <string> #include <string>
#include <thread> #include <thread>
#include <atomic> #include <atomic>
#include <condition_variable>
#include <chrono> #include <chrono>
#include "ghc/filesystem.h" #include "ghc/filesystem.h"
@ -30,8 +33,16 @@ public:
std::atomic_bool errored{false}; std::atomic_bool errored{false};
private: private:
wxProgressDialog* progressDialog;
std::atomic_int written{0};
std::thread fileThread; std::thread fileThread;
std::atomic_bool completed{false};
std::atomic_bool canceled{false};
std::mutex completedMutex;
std::condition_variable completedCV;
bool completed = false;
std::chrono::steady_clock::time_point lastUpdate; std::chrono::steady_clock::time_point lastUpdate;
@ -41,6 +52,5 @@ public:
private: private:
void SetFileProgress(int currentSize); void SetFileProgress(int currentSize);
void SetError(); void SetError();
void SetDone();
void WriteImage(ghc::filesystem::path hddPath, int reqSizeMB); void WriteImage(ghc::filesystem::path hddPath, int reqSizeMB);
}; };

View File

@ -65,6 +65,9 @@ bool rx_fifo_can_rx();
#define HDD_DEF "DEV9hdd.raw" #define HDD_DEF "DEV9hdd.raw"
#endif #endif
#define HDD_MIN_GB 8
#define HDD_MAX_GB 120
typedef struct typedef struct
{ {
char Eth[256]; char Eth[256];

View File

@ -22,6 +22,9 @@
#include <pwd.h> #include <pwd.h>
#include <string.h> #include <string.h>
#include <string>
#include "ghc/filesystem.h"
#include "../Config.h" #include "../Config.h"
#include "../DEV9.h" #include "../DEV9.h"
#include "pcap.h" #include "pcap.h"
@ -29,7 +32,9 @@
#include "../net.h" #include "../net.h"
#include "AppCoreThread.h" #include "AppCoreThread.h"
static GtkBuilder* builder; #include "../ATA/HddCreate.h"
static GtkBuilder* builder = nullptr;
void SysMessage(char* fmt, ...) void SysMessage(char* fmt, ...)
{ {
@ -72,7 +77,29 @@ void OnInitDialog()
} }
idx++; idx++;
} }
gtk_entry_set_text((GtkEntry*)gtk_builder_get_object(builder, "IDC_HDDFILE"), config.Hdd); gtk_entry_set_text((GtkEntry*)gtk_builder_get_object(builder, "IDC_HDDFILE"), config.Hdd);
//HDDSpin
gtk_spin_button_set_range((GtkSpinButton*)gtk_builder_get_object(builder, "IDC_HDDSIZE_SPIN"), HDD_MIN_GB, HDD_MAX_GB);
gtk_spin_button_set_increments((GtkSpinButton*)gtk_builder_get_object(builder, "IDC_HDDSIZE_SPIN"), 1, 10);
gtk_spin_button_set_value((GtkSpinButton*)gtk_builder_get_object(builder, "IDC_HDDSIZE_SPIN"), config.HddSize / 1024);
//HDDSlider
gtk_range_set_range((GtkRange*)gtk_builder_get_object(builder, "IDC_HDDSIZE_SLIDER"), HDD_MIN_GB, HDD_MAX_GB);
gtk_range_set_increments((GtkRange*)gtk_builder_get_object(builder, "IDC_HDDSIZE_SLIDER"), 1, 10);
gtk_scale_add_mark((GtkScale*)gtk_builder_get_object(builder, "IDC_HDDSIZE_SLIDER"), HDD_MIN_GB, GTK_POS_BOTTOM, (std::to_string(HDD_MIN_GB) + " GiB").c_str());
gtk_scale_add_mark((GtkScale*)gtk_builder_get_object(builder, "IDC_HDDSIZE_SLIDER"), HDD_MAX_GB, GTK_POS_BOTTOM, (std::to_string(HDD_MAX_GB) + " GiB").c_str());
for (int i = 15; i < HDD_MAX_GB; i += 5)
{
gtk_scale_add_mark((GtkScale*)gtk_builder_get_object(builder, "IDC_HDDSIZE_SLIDER"), i, GTK_POS_BOTTOM, nullptr);
}
gtk_range_set_value((GtkRange*)gtk_builder_get_object(builder, "IDC_HDDSIZE_SLIDER"), config.HddSize / 1024);
//Checkboxes
gtk_toggle_button_set_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_ETHENABLED"), gtk_toggle_button_set_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_ETHENABLED"),
config.ethEnable); config.ethEnable);
gtk_toggle_button_set_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_HDDENABLED"), gtk_toggle_button_set_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_HDDENABLED"),
@ -81,46 +108,77 @@ void OnInitDialog()
initialized = 1; initialized = 1;
} }
void OnBrowse(GtkButton* button, gpointer usr_data)
{
ghc::filesystem::path inis(GetSettingsFolder().ToString().ToStdString());
static const wxChar* hddFilterType = L"HDD|*.raw;*.RAW";
wxFileDialog ctrl(nullptr, _("HDD Image File"), GetSettingsFolder().ToString(), HDD_DEF,
(wxString)hddFilterType + L"|" + _("All Files (*.*)") + L"|*.*", wxFD_SAVE);
if (ctrl.ShowModal() != wxID_CANCEL)
{
ghc::filesystem::path hddFile(ctrl.GetPath().ToStdString());
if (ghc::filesystem::exists(hddFile))
{
//Get file size
int filesizeGb = ghc::filesystem::file_size(hddFile) / (1024 * 1024 * 1024);
gtk_range_set_value((GtkRange*)gtk_builder_get_object(builder, "IDC_HDDSIZE_SLIDER"), filesizeGb);
gtk_spin_button_set_value((GtkSpinButton*)gtk_builder_get_object(builder, "IDC_HDDSIZE_SPIN"), filesizeGb);
}
if (hddFile.parent_path() == inis)
hddFile = hddFile.filename();
gtk_entry_set_text((GtkEntry*)gtk_builder_get_object(builder, "IDC_HDDFILE"), hddFile.c_str());
}
}
void OnSpin(GtkSpinButton* spin, gpointer usr_data)
{
gtk_range_set_value((GtkRange*)gtk_builder_get_object(builder, "IDC_HDDSIZE_SLIDER"),
gtk_spin_button_get_value(spin));
}
void OnSlide(GtkRange* range, gpointer usr_data)
{
gtk_spin_button_set_value((GtkSpinButton*)gtk_builder_get_object(builder, "IDC_HDDSIZE_SPIN"),
gtk_range_get_value(range));
}
void OnOk() void OnOk()
{ {
char* ptr = gtk_combo_box_text_get_active_text((GtkComboBoxText*)gtk_builder_get_object(builder, "IDC_ETHDEV")); char* ptr = gtk_combo_box_text_get_active_text((GtkComboBoxText*)gtk_builder_get_object(builder, "IDC_ETHDEV"));
if (ptr != nullptr) if (ptr != nullptr)
strcpy(config.Eth, ptr); strcpy(config.Eth, ptr);
strcpy(config.Hdd, gtk_entry_get_text((GtkEntry*)gtk_builder_get_object(builder, "IDC_HDDFILE"))); strcpy(config.Hdd, gtk_entry_get_text((GtkEntry*)gtk_builder_get_object(builder, "IDC_HDDFILE")));
config.HddSize = gtk_spin_button_get_value((GtkSpinButton*)gtk_builder_get_object(builder, "IDC_HDDSIZE_SPIN")) * 1024;
config.ethEnable = gtk_toggle_button_get_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_ETHENABLED")); config.ethEnable = gtk_toggle_button_get_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_ETHENABLED"));
config.hddEnable = gtk_toggle_button_get_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_HDDENABLED")); config.hddEnable = gtk_toggle_button_get_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_HDDENABLED"));
SaveConf(); ghc::filesystem::path hddPath(config.Hdd);
}
/* Simple GTK+2 variant of gtk_builder_add_from_resource() */ if (hddPath.is_relative())
static guint builder_add_from_resource(GtkBuilder* builder, const gchar* resource_path, GError** error)
{
GBytes* data;
const gchar* buffer;
gsize buffer_length;
guint ret;
g_assert(error && *error == NULL);
data = g_resources_lookup_data(resource_path, G_RESOURCE_LOOKUP_FLAGS_NONE, error);
if (data == NULL)
{ {
return 0; //GHC uses UTF8 on all platforms
ghc::filesystem::path path(GetSettingsFolder().ToUTF8().data());
hddPath = path / hddPath;
} }
buffer_length = 0; if (config.hddEnable && !ghc::filesystem::exists(hddPath))
buffer = (const gchar*)g_bytes_get_data(data, &buffer_length); {
g_assert(buffer != NULL); HddCreate hddCreator;
hddCreator.filePath = hddPath;
hddCreator.neededSize = config.HddSize;
hddCreator.Start();
}
ret = gtk_builder_add_from_string(builder, buffer, buffer_length, error); SaveConf();
g_bytes_unref(data);
return ret;
} }
void DEV9configure() void DEV9configure()
@ -128,12 +186,22 @@ void DEV9configure()
ScopedCoreThreadPause paused_core; ScopedCoreThreadPause paused_core;
gtk_init(NULL, NULL); gtk_init(NULL, NULL);
GError* error = NULL; GError* error = NULL;
builder = gtk_builder_new(); if (builder == nullptr)
if (!builder_add_from_resource(builder, "/net/pcsx2/dev9/DEV9/Linux/dev9.ui", &error))
{ {
g_warning("Could not build config ui: %s", error->message); builder = gtk_builder_new();
g_error_free(error); gtk_builder_add_callback_symbols(builder,
g_object_unref(G_OBJECT(builder)); "OnBrowse", G_CALLBACK(&OnBrowse),
"OnSpin", G_CALLBACK(&OnSpin),
"OnSlide", G_CALLBACK(&OnSlide), nullptr);
if (!gtk_builder_add_from_resource(builder, "/net/pcsx2/dev9/DEV9/Linux/dev9.ui", &error))
{
g_warning("Could not build config ui: %s", error->message);
g_error_free(error);
g_object_unref(G_OBJECT(builder));
builder = nullptr;
return;
}
gtk_builder_connect_signals(builder, nullptr);
} }
GtkDialog* dlg = GTK_DIALOG(gtk_builder_get_object(builder, "IDD_CONFDLG")); GtkDialog* dlg = GTK_DIALOG(gtk_builder_get_object(builder, "IDD_CONFDLG"));
OnInitDialog(); OnInitDialog();

View File

@ -1,241 +1,302 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface> <interface>
<requires lib="gtk+" version="2.24"/> <requires lib="gtk+" version="3.0"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkDialog" id="IDD_CONFDLG"> <object class="GtkDialog" id="IDD_CONFDLG">
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="border_width">5</property> <property name="border_width">5</property>
<property name="title" translatable="yes">Network and HDD Settings</property> <property name="title" translatable="yes">Network and HDD Settings</property>
<property name="resizable">False</property>
<property name="type_hint">dialog</property> <property name="type_hint">dialog</property>
<child type="titlebar">
<placeholder/>
</child>
<child internal-child="vbox"> <child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox1"> <object class="GtkBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="layout_style">end</property> <property name="orientation">vertical</property>
<child> <property name="spacing">2</property>
<object class="GtkButton" id="IDOK"> <child internal-child="action_area">
<property name="label" translatable="yes">OK</property> <object class="GtkButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="IDCANCEL">
<property name="label" translatable="yes">Cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">DEV9 Type: </property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="IDC_BAYTYPE">
<property name="sensitive">False</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="has_entry">True</property>
<property name="entry_text_column">0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkExpander" id="expander1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkCheckButton" id="IDC_ETHENABLED">
<property name="label" translatable="yes">Enabled</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox3">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="layout_style">end</property>
<child> <child>
<object class="GtkLabel" id="label4"> <object class="GtkButton" id="IDOK">
<property name="visible">True</property> <property name="label" translatable="yes">OK</property>
<property name="can_focus">False</property> <property name="visible">True</property>
<property name="label" translatable="yes">Ethernet Device: </property> <property name="can_focus">True</property>
<property name="receives_default">True</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="IDCANCEL">
<property name="label" translatable="yes">Cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property> <property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<child>
<object class="GtkComboBoxText" id="IDC_BAYTYPE">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="has_entry">True</property>
<child internal-child="entry">
<object class="GtkEntry">
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkComboBoxText" id="IDC_ETHDEV"> <object class="GtkLabel" id="label3">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="has_entry">False</property> <property name="label" translatable="yes">DEV9 Type: </property>
<property name="entry_text_column">0</property>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="left_attach">0</property>
<property name="fill">True</property> <property name="top_attach">0</property>
<property name="position">1</property>
</packing> </packing>
</child> </child>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">False</property>
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Ethernet</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkExpander" id="expander2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child> <child>
<object class="GtkVBox" id="vbox2"> <object class="GtkExpander" id="expander1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkCheckButton" id="IDC_HDDENABLED">
<property name="label" translatable="yes">ENABLED</property>
<property name="sensitive">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <child>
<property name="draw_indicator">True</property> <object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<child>
<object class="GtkComboBoxText" id="IDC_ETHDEV">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Ethernet Device: </property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="IDC_ETHENABLED">
<property name="label" translatable="yes">Enabled</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Ethernet</property>
</object>
</child>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">False</property>
<property name="position">0</property> <property name="position">2</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkHBox" id="hbox5"> <object class="GtkExpander" id="expander2">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">True</property>
<child> <child>
<object class="GtkLabel" id="label5"> <object class="GtkGrid">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">HDD File: </property> <property name="hexpand">True</property>
<child>
<object class="GtkCheckButton" id="IDC_HDDENABLED">
<property name="label" translatable="yes">Enabled</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<child>
<object class="GtkEntry" id="IDC_HDDFILE">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">HDD File: </property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="IDC_BROWSE">
<property name="label" translatable="yes">Browse</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="OnBrowse" swapped="no"/>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">HDD Size (GiB): </property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="IDC_HDDSIZE_SPIN">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<signal name="value-changed" handler="OnSpin" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkScale" id="IDC_HDDSIZE_SLIDER">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="round_digits">0</property>
<property name="digits">0</property>
<property name="value_pos">bottom</property>
<signal name="value-changed" handler="OnSlide" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> </child>
<child> <child type="label">
<object class="GtkEntry" id="IDC_HDDFILE"> <object class="GtkLabel" id="label2">
<property name="sensitive">False</property> <property name="visible">True</property>
<property name="visible">True</property> <property name="can_focus">False</property>
<property name="can_focus">False</property> <property name="label" translatable="yes">Hard Disk Drive</property>
</object> </object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child> </child>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">False</property>
<property name="position">1</property> <property name="position">3</property>
</packing> </packing>
</child> </child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Hard Disk Drive (not yet properly implemented)</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</object> </object>
</child> </child>
<action-widgets> <action-widgets>

View File

@ -15,7 +15,7 @@
#undef APSTUDIO_READONLY_SYMBOLS #undef APSTUDIO_READONLY_SYMBOLS
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Espagnol (Argentine) resources // Spanish (Argentina) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ESS) #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ESS)
LANGUAGE LANG_SPANISH, SUBLANG_SPANISH_ARGENTINA LANGUAGE LANG_SPANISH, SUBLANG_SPANISH_ARGENTINA
@ -54,23 +54,30 @@ END
// Dialog // Dialog
// //
IDD_CONFIG DIALOGEX 0, 0, 290, 170 IDD_CONFIG DIALOGEX 0, 0, 290, 205
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Network and HDD Settings" CAPTION "Network and HDD Settings"
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
DEFPUSHBUTTON "OK",IDOK,92,150,50,14 DEFPUSHBUTTON "OK",IDOK,92,185,50,14
PUSHBUTTON "Cancel",IDCANCEL,148,150,50,14 PUSHBUTTON "Cancel",IDCANCEL,148,185,50,14
LTEXT "DEV9 Type:",IDC_STATIC,15,10,41,11,SS_CENTERIMAGE LTEXT "DEV9 Type:",IDC_STATIC,15,10,41,11,SS_CENTERIMAGE
COMBOBOX IDC_BAYTYPE,60,8,223,47,CBS_DROPDOWNLIST | CBS_SORT | WS_DISABLED COMBOBOX IDC_BAYTYPE,61,8,223,47,CBS_DROPDOWNLIST | CBS_SORT | WS_DISABLED
GROUPBOX "Ethernet",IDC_STATIC,7,30,276,50 GROUPBOX "Ethernet",IDC_STATIC,7,30,277,50
CONTROL "Enabled",IDC_ETHENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,45,42,8 CONTROL "Enabled",IDC_ETHENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,45,42,8
LTEXT "Ethernet Device:",IDC_STATIC,26,60,60,8,SS_CENTERIMAGE LTEXT "Ethernet Device:",IDC_STATIC,26,60,60,8,SS_CENTERIMAGE
COMBOBOX IDC_ETHDEV,94,58,182,82,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_ETHDEV,94,58,182,82,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Hard Disk Drive (not yet properly implemented)",IDC_STATIC,7,90,276,50 GROUPBOX "Hard Disk Drive",IDC_STATIC,7,90,277,85
CONTROL "Enabled",IDC_HDDENABLED,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,15,105,42,8 CONTROL "Enabled",IDC_HDDENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,105,42,8
LTEXT "HDD File:",IDC_STATIC,26,120,60,8,SS_CENTERIMAGE | WS_DISABLED LTEXT "HDD File:",IDC_STATIC,26,120,60,8,SS_CENTERIMAGE
EDITTEXT IDC_HDDFILE,94,118,182,13,ES_AUTOHSCROLL | WS_DISABLED EDITTEXT IDC_HDDFILE,94,118,130,13,ES_AUTOHSCROLL
CONTROL "",IDC_HDDSIZE_SLIDER,"msctls_trackbar32",WS_TABSTOP,90,141,150,15
LTEXT "HDD Size (GiB):",IDC_STATIC,26,143,60,8,SS_CENTERIMAGE
EDITTEXT IDC_HDDSIZE_TEXT,240,141,25,13,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_HDDSIZE_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS,265,141,11,13
LTEXT "8 GiB",IDC_STATIC,89,158,17,8
LTEXT "120 GiB",IDC_STATIC,219,157,25,8,0,WS_EX_RIGHT
PUSHBUTTON "Browse",IDC_BROWSE,226,117,50,15
END END
@ -85,14 +92,25 @@ BEGIN
IDD_CONFIG, DIALOG IDD_CONFIG, DIALOG
BEGIN BEGIN
LEFTMARGIN, 7 LEFTMARGIN, 7
RIGHTMARGIN, 283 RIGHTMARGIN, 284
TOPMARGIN, 7 TOPMARGIN, 7
BOTTOMMARGIN, 164 BOTTOMMARGIN, 273
END END
END END
#endif // APSTUDIO_INVOKED #endif // APSTUDIO_INVOKED
#endif // Espagnol (Argentine) resources
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_CONFIG AFX_DIALOG_LAYOUT
BEGIN
0
END
#endif // Spanish (Argentina) resources
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View File

@ -15,10 +15,10 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include <stdio.h> #include <stdio.h>
//#include <windows.h> #include <commdlg.h>
//#include <windowsx.h>
#include <filesystem> #include <string>
#include "ghc/filesystem.h"
#include "..\Config.h" #include "..\Config.h"
#include "resource.h" #include "resource.h"
@ -28,6 +28,8 @@
#include "tap.h" #include "tap.h"
#include "AppCoreThread.h" #include "AppCoreThread.h"
#include "../ATA/HddCreate.h"
extern HINSTANCE hInst; extern HINSTANCE hInst;
//HANDLE handleDEV9Thread = NULL; //HANDLE handleDEV9Thread = NULL;
//DWORD dwThreadId, dwThrdParam; //DWORD dwThreadId, dwThrdParam;
@ -77,10 +79,87 @@ void OnInitDialog(HWND hW)
SetWindowText(GetDlgItem(hW, IDC_HDDFILE), config.Hdd); SetWindowText(GetDlgItem(hW, IDC_HDDFILE), config.Hdd);
//HDDText
Edit_SetText(GetDlgItem(hW, IDC_HDDSIZE_TEXT), std::to_wstring(config.HddSize / 1024).c_str());
Edit_LimitText(GetDlgItem(hW, IDC_HDDSIZE_TEXT), 3); //Excluding null char
//HDDSpin
SendMessage(GetDlgItem(hW, IDC_HDDSIZE_SPIN), UDM_SETRANGE,
(WPARAM)0,
(LPARAM)MAKELPARAM(HDD_MAX_GB, HDD_MIN_GB));
SendMessage(GetDlgItem(hW, IDC_HDDSIZE_SPIN), UDM_SETPOS,
(WPARAM)0,
(LPARAM)(config.HddSize / 1024));
//HDDSlider
SendMessage(GetDlgItem(hW, IDC_HDDSIZE_SLIDER), TBM_SETRANGE,
(WPARAM)FALSE,
(LPARAM)MAKELPARAM(HDD_MIN_GB, HDD_MAX_GB));
SendMessage(GetDlgItem(hW, IDC_HDDSIZE_SLIDER), TBM_SETPAGESIZE,
(WPARAM)0,
(LPARAM)10);
for (int i = 15; i < HDD_MAX_GB; i += 5)
{
SendMessage(GetDlgItem(hW, IDC_HDDSIZE_SLIDER), TBM_SETTIC,
(WPARAM)0,
(LPARAM)i);
}
SendMessage(GetDlgItem(hW, IDC_HDDSIZE_SLIDER), TBM_SETPOS,
(WPARAM)TRUE,
(LPARAM)(config.HddSize / 1024));
//Checkboxes
Button_SetCheck(GetDlgItem(hW, IDC_ETHENABLED), config.ethEnable); Button_SetCheck(GetDlgItem(hW, IDC_ETHENABLED), config.ethEnable);
Button_SetCheck(GetDlgItem(hW, IDC_HDDENABLED), config.hddEnable); Button_SetCheck(GetDlgItem(hW, IDC_HDDENABLED), config.hddEnable);
} }
void OnBrowse(HWND hW)
{
wchar_t wbuff[4096] = {0};
memcpy(wbuff, HDD_DEF, sizeof(HDD_DEF));
//GHC uses UTF8 on all platforms
ghc::filesystem::path inis = GetSettingsFolder().ToUTF8().data();
wstring w_inis = inis.wstring();
OPENFILENAMEW ofn;
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hW;
ofn.lpstrTitle = L"HDD image file";
ofn.lpstrFile = wbuff;
ofn.nMaxFile = ArraySize(wbuff);
ofn.lpstrFilter = L"HDD\0*.raw\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = w_inis.c_str();
ofn.Flags = OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR;
if (GetOpenFileName(&ofn))
{
ghc::filesystem::path hddFile(std::wstring(ofn.lpstrFile));
if (ghc::filesystem::exists(hddFile))
{
//Get file size
int filesizeGb = ghc::filesystem::file_size(hddFile) / (1024 * 1024 * 1024);
//Set slider
SendMessage(GetDlgItem(hW, IDC_HDDSIZE_SPIN), UDM_SETPOS,
(WPARAM)0,
(LPARAM)filesizeGb);
SendMessage(GetDlgItem(hW, IDC_HDDSIZE_SLIDER), TBM_SETPOS,
(WPARAM)TRUE,
(LPARAM)filesizeGb);
}
if (hddFile.parent_path() == inis)
hddFile = hddFile.filename();
Edit_SetText(GetDlgItem(hW, IDC_HDDFILE), hddFile.wstring().c_str());
}
}
void OnOk(HWND hW) void OnOk(HWND hW)
{ {
int i = ComboBox_GetCurSel(GetDlgItem(hW, IDC_ETHDEV)); int i = ComboBox_GetCurSel(GetDlgItem(hW, IDC_ETHDEV));
@ -110,9 +189,44 @@ void OnOk(HWND hW)
GetWindowText(GetDlgItem(hW, IDC_HDDFILE), config.Hdd, 256); GetWindowText(GetDlgItem(hW, IDC_HDDFILE), config.Hdd, 256);
if (Edit_GetTextLength(GetDlgItem(hW, IDC_HDDSIZE_TEXT)) == 0)
config.HddSize = HDD_MIN_GB * 1024;
else
{
wchar_t text[4];
GetWindowText(GetDlgItem(hW, IDC_HDDSIZE_TEXT), text, 4);
config.HddSize = stoi(text) * 1024;
}
config.ethEnable = Button_GetCheck(GetDlgItem(hW, IDC_ETHENABLED)); config.ethEnable = Button_GetCheck(GetDlgItem(hW, IDC_ETHENABLED));
config.hddEnable = Button_GetCheck(GetDlgItem(hW, IDC_HDDENABLED)); config.hddEnable = Button_GetCheck(GetDlgItem(hW, IDC_HDDENABLED));
ghc::filesystem::path hddPath(std::wstring(config.Hdd));
if (config.hddEnable && hddPath.empty())
{
SysMessage("Please specify a HDD file");
return;
}
if (hddPath.is_relative())
{
//GHC uses UTF8 on all platforms
ghc::filesystem::path path(GetSettingsFolder().ToUTF8().data());
hddPath = path / hddPath;
}
if (config.hddEnable && !ghc::filesystem::exists(hddPath))
{
HddCreate hddCreator;
hddCreator.filePath = hddPath;
hddCreator.neededSize = config.HddSize;
hddCreator.Start();
if (hddCreator.errored)
return;
}
SaveConf(); SaveConf();
EndDialog(hW, TRUE); EndDialog(hW, TRUE);
@ -134,9 +248,109 @@ BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
EndDialog(hW, FALSE); EndDialog(hW, FALSE);
return TRUE; return TRUE;
case IDOK: case IDOK:
if (GetFocus() != GetDlgItem(hW, IDOK))
{
SetFocus(GetDlgItem(hW, IDOK));
return TRUE;
}
OnOk(hW); OnOk(hW);
return TRUE; return TRUE;
case IDC_BROWSE:
OnBrowse(hW);
return TRUE;
case IDC_HDDSIZE_TEXT:
{
if (GetFocus() != GetDlgItem(hW, IDC_HDDSIZE_TEXT))
return TRUE;
if (Edit_GetTextLength(GetDlgItem(hW, IDC_HDDSIZE_TEXT)) == 0)
return TRUE;
wchar_t text[4];
Edit_GetText(GetDlgItem(hW, IDC_HDDSIZE_TEXT), text, 4); //Including null char
switch (HIWORD(wParam))
{
case EN_CHANGE:
{
int curpos = stoi(text);
if (HDD_MIN_GB > curpos)
//user may still be typing
return TRUE;
SendMessage(GetDlgItem(hW, IDC_HDDSIZE_SPIN), UDM_SETPOS,
(WPARAM)0,
(LPARAM)curpos);
SendMessage(GetDlgItem(hW, IDC_HDDSIZE_SLIDER), TBM_SETPOS,
(WPARAM)TRUE,
(LPARAM)curpos);
return TRUE;
}
}
return FALSE;
}
default:
return FALSE;
} }
case WM_HSCROLL:
{
HWND hwndDlg = (HWND)lParam;
int curpos = HIWORD(wParam);
switch (LOWORD(wParam))
{
case TB_LINEUP:
case TB_LINEDOWN:
case TB_PAGEUP:
case TB_PAGEDOWN:
case TB_TOP:
case TB_BOTTOM:
curpos = (int)SendMessage(hwndDlg, TBM_GETPOS, 0, 0);
[[fallthrough]];
case TB_THUMBPOSITION:
case TB_THUMBTRACK:
//Update Textbox
SendMessage(GetDlgItem(hW, IDC_HDDSIZE_SPIN), UDM_SETPOS,
(WPARAM)0,
(LPARAM)curpos);
return TRUE;
default:
return FALSE;
}
}
case WM_VSCROLL:
{
HWND hwndDlg = (HWND)lParam;
int curpos = HIWORD(wParam);
switch (LOWORD(wParam))
{
case SB_LINEUP:
case SB_LINEDOWN:
case SB_PAGEUP:
case SB_PAGEDOWN:
case SB_TOP:
case SB_BOTTOM:
curpos = (int)SendMessage(hwndDlg, UDM_GETPOS, 0, 0);
[[fallthrough]];
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
//Update Textbox
//Edit_SetText(GetDlgItem(hW, IDC_HDDSIZE_TEXT), to_wstring(curpos).c_str());
SendMessage(GetDlgItem(hW, IDC_HDDSIZE_SLIDER), TBM_SETPOS,
(WPARAM)TRUE,
(LPARAM)curpos);
return TRUE;
default:
return FALSE;
}
}
} }
return FALSE; return FALSE;
} }

View File

@ -1,6 +1,6 @@
//{{NO_DEPENDENCIES}} //{{NO_DEPENDENCIES}}
// fichier Include Microsoft Visual C++. // Microsoft Visual C++ generated include file.
// Utilisé par DEV9ghzdrk.rc // Used by DEV9ghzdrk.rc
// //
#define IDD_CONFDLG 801 #define IDD_CONFDLG 801
#define IDD_CONFIG 801 #define IDD_CONFIG 801
@ -11,15 +11,19 @@
#define IDC_ETHENABLED 8009 #define IDC_ETHENABLED 8009
#define IDC_HDDFILE 8010 #define IDC_HDDFILE 8010
#define IDC_HDDENABLED 8011 #define IDC_HDDENABLED 8011
#define IDC_HDDSIZE_SLIDER 8012
#define IDC_HDDSIZE_SPIN 8013
#define IDC_HDDSIZE_TEXT 8015
#define IDC_BROWSE 8017
#define IDC_STATIC -1 #define IDC_STATIC -1
// Next default values for new objects // Next default values for new objects
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 805 #define _APS_NEXT_RESOURCE_VALUE 806
#define _APS_NEXT_COMMAND_VALUE 40002 #define _APS_NEXT_COMMAND_VALUE 40002
#define _APS_NEXT_CONTROL_VALUE 8011 #define _APS_NEXT_CONTROL_VALUE 8018
#define _APS_NEXT_SYMED_VALUE 801 #define _APS_NEXT_SYMED_VALUE 801
#endif #endif
#endif #endif