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()
{
//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);
//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();
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)
@ -73,35 +119,31 @@ void HddCreate::WriteImage(ghc::filesystem::path hddPath, int reqSizeMiB)
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.close();
SetDone();
}
void HddCreate::SetFileProgress(int currentSize)
{
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
if (std::chrono::duration_cast<std::chrono::seconds>(now - lastUpdate).count() >= 1)
{
lastUpdate = now;
fprintf(stdout, "%i / %i MiB\n", currentSize, neededSize);
}
written.store(currentSize);
}
void HddCreate::SetError()
{
fprintf(stderr, "Unable to create file\n");
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
#include <wx/progdlg.h>
#include <string>
#include <thread>
#include <atomic>
#include <condition_variable>
#include <chrono>
#include "ghc/filesystem.h"
@ -30,8 +33,16 @@ public:
std::atomic_bool errored{false};
private:
wxProgressDialog* progressDialog;
std::atomic_int written{0};
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;
@ -41,6 +52,5 @@ public:
private:
void SetFileProgress(int currentSize);
void SetError();
void SetDone();
void WriteImage(ghc::filesystem::path hddPath, int reqSizeMB);
};

View File

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

View File

@ -22,6 +22,9 @@
#include <pwd.h>
#include <string.h>
#include <string>
#include "ghc/filesystem.h"
#include "../Config.h"
#include "../DEV9.h"
#include "pcap.h"
@ -29,7 +32,9 @@
#include "../net.h"
#include "AppCoreThread.h"
static GtkBuilder* builder;
#include "../ATA/HddCreate.h"
static GtkBuilder* builder = nullptr;
void SysMessage(char* fmt, ...)
{
@ -72,7 +77,29 @@ void OnInitDialog()
}
idx++;
}
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"),
config.ethEnable);
gtk_toggle_button_set_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_HDDENABLED"),
@ -81,46 +108,77 @@ void OnInitDialog()
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()
{
char* ptr = gtk_combo_box_text_get_active_text((GtkComboBoxText*)gtk_builder_get_object(builder, "IDC_ETHDEV"));
if (ptr != nullptr)
strcpy(config.Eth, ptr);
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.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() */
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)
if (hddPath.is_relative())
{
return 0;
//GHC uses UTF8 on all platforms
ghc::filesystem::path path(GetSettingsFolder().ToUTF8().data());
hddPath = path / hddPath;
}
buffer_length = 0;
buffer = (const gchar*)g_bytes_get_data(data, &buffer_length);
g_assert(buffer != NULL);
if (config.hddEnable && !ghc::filesystem::exists(hddPath))
{
HddCreate hddCreator;
hddCreator.filePath = hddPath;
hddCreator.neededSize = config.HddSize;
hddCreator.Start();
}
ret = gtk_builder_add_from_string(builder, buffer, buffer_length, error);
g_bytes_unref(data);
return ret;
SaveConf();
}
void DEV9configure()
@ -128,12 +186,22 @@ void DEV9configure()
ScopedCoreThreadPause paused_core;
gtk_init(NULL, NULL);
GError* error = NULL;
builder = gtk_builder_new();
if (!builder_add_from_resource(builder, "/net/pcsx2/dev9/DEV9/Linux/dev9.ui", &error))
if (builder == nullptr)
{
g_warning("Could not build config ui: %s", error->message);
g_error_free(error);
g_object_unref(G_OBJECT(builder));
builder = gtk_builder_new();
gtk_builder_add_callback_symbols(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"));
OnInitDialog();

View File

@ -1,241 +1,302 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="2.24"/>
<!-- interface-naming-policy project-wide -->
<requires lib="gtk+" version="3.0"/>
<object class="GtkDialog" id="IDD_CONFDLG">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Network and HDD Settings</property>
<property name="resizable">False</property>
<property name="type_hint">dialog</property>
<child type="titlebar">
<placeholder/>
</child>
<child internal-child="vbox">
<object class="GtkVBox" 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">
<object class="GtkBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="IDOK">
<property name="label" translatable="yes">OK</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">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="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<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 class="GtkButton" id="IDOK">
<property name="label" translatable="yes">OK</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">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="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>
</child>
<child>
<object class="GtkComboBoxText" id="IDC_ETHDEV">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="has_entry">False</property>
<property name="entry_text_column">0</property>
<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">True</property>
<property name="fill">True</property>
<property name="position">1</property>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</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>
<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>
<object class="GtkVBox" id="vbox2">
<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>
<object class="GtkExpander" id="expander1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">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="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>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox5">
<object class="GtkExpander" id="expander2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can_focus">True</property>
<child>
<object class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">HDD File: </property>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</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>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="IDC_HDDFILE">
<property name="sensitive">False</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<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</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">True</property>
<property name="fill">True</property>
<property name="position">1</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</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>
</child>
<action-widgets>

View File

@ -15,7 +15,7 @@
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Espagnol (Argentine) resources
// Spanish (Argentina) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ESS)
LANGUAGE LANG_SPANISH, SUBLANG_SPANISH_ARGENTINA
@ -54,23 +54,30 @@ END
// Dialog
//
IDD_CONFIG DIALOGEX 0, 0, 290, 170
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
IDD_CONFIG DIALOGEX 0, 0, 290, 205
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Network and HDD Settings"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,92,150,50,14
PUSHBUTTON "Cancel",IDCANCEL,148,150,50,14
DEFPUSHBUTTON "OK",IDOK,92,185,50,14
PUSHBUTTON "Cancel",IDCANCEL,148,185,50,14
LTEXT "DEV9 Type:",IDC_STATIC,15,10,41,11,SS_CENTERIMAGE
COMBOBOX IDC_BAYTYPE,60,8,223,47,CBS_DROPDOWNLIST | CBS_SORT | WS_DISABLED
GROUPBOX "Ethernet",IDC_STATIC,7,30,276,50
COMBOBOX IDC_BAYTYPE,61,8,223,47,CBS_DROPDOWNLIST | CBS_SORT | WS_DISABLED
GROUPBOX "Ethernet",IDC_STATIC,7,30,277,50
CONTROL "Enabled",IDC_ETHENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,45,42,8
LTEXT "Ethernet Device:",IDC_STATIC,26,60,60,8,SS_CENTERIMAGE
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
CONTROL "Enabled",IDC_HDDENABLED,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,15,105,42,8
LTEXT "HDD File:",IDC_STATIC,26,120,60,8,SS_CENTERIMAGE | WS_DISABLED
EDITTEXT IDC_HDDFILE,94,118,182,13,ES_AUTOHSCROLL | WS_DISABLED
GROUPBOX "Hard Disk Drive",IDC_STATIC,7,90,277,85
CONTROL "Enabled",IDC_HDDENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,105,42,8
LTEXT "HDD File:",IDC_STATIC,26,120,60,8,SS_CENTERIMAGE
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
@ -85,14 +92,25 @@ BEGIN
IDD_CONFIG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 283
RIGHTMARGIN, 284
TOPMARGIN, 7
BOTTOMMARGIN, 164
BOTTOMMARGIN, 273
END
END
#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 <stdio.h>
//#include <windows.h>
//#include <windowsx.h>
#include <commdlg.h>
#include <filesystem>
#include <string>
#include "ghc/filesystem.h"
#include "..\Config.h"
#include "resource.h"
@ -28,6 +28,8 @@
#include "tap.h"
#include "AppCoreThread.h"
#include "../ATA/HddCreate.h"
extern HINSTANCE hInst;
//HANDLE handleDEV9Thread = NULL;
//DWORD dwThreadId, dwThrdParam;
@ -77,10 +79,87 @@ void OnInitDialog(HWND hW)
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_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)
{
int i = ComboBox_GetCurSel(GetDlgItem(hW, IDC_ETHDEV));
@ -110,9 +189,44 @@ void OnOk(HWND hW)
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.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();
EndDialog(hW, TRUE);
@ -134,9 +248,109 @@ BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
EndDialog(hW, FALSE);
return TRUE;
case IDOK:
if (GetFocus() != GetDlgItem(hW, IDOK))
{
SetFocus(GetDlgItem(hW, IDOK));
return TRUE;
}
OnOk(hW);
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;
}

View File

@ -1,6 +1,6 @@
//{{NO_DEPENDENCIES}}
// fichier Include Microsoft Visual C++.
// Utilisé par DEV9ghzdrk.rc
// Microsoft Visual C++ generated include file.
// Used by DEV9ghzdrk.rc
//
#define IDD_CONFDLG 801
#define IDD_CONFIG 801
@ -11,15 +11,19 @@
#define IDC_ETHENABLED 8009
#define IDC_HDDFILE 8010
#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
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#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_CONTROL_VALUE 8011
#define _APS_NEXT_CONTROL_VALUE 8018
#define _APS_NEXT_SYMED_VALUE 801
#endif
#endif