Fix #2 again, and finish the emu config panel

This commit is contained in:
Alcaro 2017-05-16 20:02:16 +02:00
parent f55477c669
commit de30ca5507
3 changed files with 88 additions and 20 deletions

View File

@ -146,6 +146,7 @@ void bpsdeltaEnd()
if (!bpsdCancel) gtk_widget_destroy(windowBpsd);
}
//'force' sets the filename even if the file doesn't exist
static void setoutpath(GtkFileChooser* dialog, const char * name, bool force)
{
if (!name) return;
@ -216,6 +217,7 @@ static char * SelectRom(const char * defaultname, const char * title, bool isFor
return ret;
}
//returns path if demandLocal, else URI
static GSList * SelectPatches(bool allowMulti, bool demandLocal)
{
GtkWidget* dialog=gtk_file_chooser_dialog_new(allowMulti?"Select Patches to Use":"Select Patch to Use", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN,
@ -431,11 +433,11 @@ static void a_ApplyPatch(GtkButton* widget, gpointer user_data)
if (!inromname) goto cleanup;
{
char * patchbasename=GetBaseName(filename);
//char * patchbasename=GetBaseName(filename);
const char * inromext=GetExtension(inromname);
if (!inromext) inromext="";
char * outromname_d=g_strndup(patchbasename, strlen(patchbasename)+strlen(inromext)+1);
char * outromname_d=g_strndup(filename, strlen(filename)+strlen(inromext)+1);
char * ext=GetExtension(outromname_d);
strcpy(ext, inromext);
@ -465,7 +467,9 @@ static void a_ApplyPatch(GtkButton* widget, gpointer user_data)
}
struct multiapplystate state;
char * inromname=SelectRom(NULL, "Select Base File", false);
//picking one at random isn't always correct, but it's better than nothing
char * inromname=SelectRom((gchar*)filenames->data, "Select Base File", false);
if (!inromname) return;
state.romext=GetExtension(inromname);
if (!*state.romext) state.romext=".sfc";
state.rommem=ReadWholeFile(inromname);
@ -606,7 +610,12 @@ static void a_ApplyRun(GtkButton* widget, gpointer user_data)
}
if (cfg.getint("autorom")) romname=g_strdup(FindRomForPatch(patchfile, NULL)); // g_strdup(NULL) is NULL
if (!romname) romname=SelectRom(patchname, "Select Base File", false);
if (!romname)
{
char* patch_uri = g_filename_to_uri(patchname, NULL, NULL);
romname=SelectRom(patch_uri, "Select Base File", false);
g_free(patch_uri);
}
if (!romname) goto cleanup;
if (!GetEmuFor(romname)) a_SetEmulatorFor(NULL, romname);
@ -731,6 +740,10 @@ static void a_SetEmulatorFor(GtkButton* widget, gpointer user_data)
gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_URI, filterExecOnly, NULL, NULL);
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
char* emu_uri = g_filename_to_uri(GetEmuFor((const char*)user_data), NULL, NULL);
setoutpath(GTK_FILE_CHOOSER(dialog), emu_uri, false);
g_free(emu_uri);
if (gtk_dialog_run(GTK_DIALOG(dialog))==GTK_RESPONSE_ACCEPT)
{
SetEmuFor((const char*)user_data, gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)));
@ -741,11 +754,22 @@ static void a_SetEmulatorFor(GtkButton* widget, gpointer user_data)
static void SetEmuActivate(GtkTreeView* tree_view, GtkTreePath* path, GtkTreeViewColumn* column, gpointer user_data)
{
//GtkListStore* list = GTK_LIST_STORE(gtk_tree_view_get_model(tree_view));
//int item = gtk_tree_path_get_indices(path)[0];
//
////TODO
//printf("%i\n",item);
GtkListStore* list = GTK_LIST_STORE(gtk_tree_view_get_model(tree_view));
int item = gtk_tree_path_get_indices(path)[0];
GtkTreeModel* model = gtk_tree_view_get_model(tree_view);
GtkTreeIter iter;
gtk_tree_model_get_iter(model, &iter, path);
char* ext;
gtk_tree_model_get(model, &iter, 0,&ext, -1);
char* name = g_strdup_printf(".%s", ext);
a_SetEmulatorFor(NULL, name);
gtk_list_store_set(list, &iter, 1,GetEmuFor(name), -1);
g_free(name);
g_free(ext);
}
static void SetEmuDelete(GtkButton* widget, gpointer user_data)
@ -757,8 +781,15 @@ static void SetEmuDelete(GtkButton* widget, gpointer user_data)
GtkTreeModel* model = gtk_tree_view_get_model(listview);
GtkTreeIter it;
gtk_tree_model_get_iter(model, &it, (GtkTreePath*)list->data);
gtk_list_store_remove(GTK_LIST_STORE(model), &it);
char* ext;
gtk_tree_model_get(model, &it, 0,&ext, -1);
char* name = g_strdup_printf("emu.%s", ext);
cfg.set(name, NULL);
g_free(name);
g_free(ext);
gtk_list_store_remove(GTK_LIST_STORE(model), &it);
g_list_free_full(list, (GDestroyNotify)gtk_tree_path_free);
}
@ -780,13 +811,13 @@ static void a_SetEmulator(GtkButton* widget, gpointer user_data)
const char * name = cfg.getnamebyid(i);
const char * value = cfg.getvaluebyid(i);
//if (strncmp(name, "emu.", strlen("emu.")) != 0) continue;
if (strncmp(name, "emu.", strlen("emu.")) != 0) continue;
if (value==NULL) continue;
GtkTreeIter iter;
gtk_list_store_append(list, &iter);
//gtk_list_store_set(list, &iter, 0,name+strlen("emu."), 1,value, -1);
gtk_list_store_set(list, &iter, 0,name, 1,value, -1);
gtk_list_store_set(list, &iter, 0,name+strlen("emu."), 1,value, -1);
//gtk_list_store_set(list, &iter, 0,name, 1,value, -1);
}
const char * columns[]={"Type", "Emulator"};

View File

@ -244,6 +244,26 @@ void config::init_file(LPCWSTR filename)
this->filename = wcsdup(filename);
}
void config::sort()
{
//bubble sort, and called for every insertion... super fun
//but it's easy, it works, and it's fast for numentries=10 and there's no reason to go much higher than that
for (size_t i=0;i<numentries;i++)
for (size_t j=i+1;j<numentries;j++)
{
if (wcscmp(names[i], names[j]) > 0)
{
LPWSTR tmp = names[i];
names[i] = names[j];
names[j] = tmp;
tmp = values[i];
values[i] = values[j];
values[j] = tmp;
}
}
}
void config::set(LPCWSTR name, LPCWSTR value)
{
for (size_t i=0;i<this->numentries;i++)
@ -251,7 +271,18 @@ void config::set(LPCWSTR name, LPCWSTR value)
if (!wcscmp(name, this->names[i]))
{
free(this->values[i]);
this->values[i] = (value!=NULL ? wcsdup(value) : NULL);
if (value!=NULL)
{
this->values[i] = wcsdup(value);
}
else
{
free(this->names[i]);
this->names[i] = this->names[this->numentries-1];
this->values[i] = this->values[this->numentries-1];
this->numentries--;
}
return;
}
}
@ -262,6 +293,8 @@ void config::set(LPCWSTR name, LPCWSTR value)
this->names[this->numentries-1] = wcsdup(name);
this->values[this->numentries-1] = wcsdup(value);
sort();
}
LPCWSTR config::get(LPCWSTR name, LPCWSTR def)
@ -270,7 +303,8 @@ LPCWSTR config::get(LPCWSTR name, LPCWSTR def)
{
if (!wcscmp(name, this->names[i]))
{
return this->values[i];
if (this->values[i]) return this->values[i];
else return def;
}
}
return def;
@ -283,7 +317,10 @@ LPWSTR config::flatten()
size_t len = wcslen(header);
for (size_t i=0;i<this->numentries;i++)
{
len += wcslen(this->names[i]) + 1 + wcslen(this->values[i]) + 1;
if (this->values[i]!=NULL)
{
len += wcslen(this->names[i]) + 1 + wcslen(this->values[i]) + 1;
}
}
LPWSTR ret = (LPWSTR)malloc((len+1)*sizeof(WCHAR));

View File

@ -187,7 +187,7 @@ class config
LPWSTR * values;
//stupid c++, why is there no sane way to get the implementation out of the headers
bool parse(LPCWSTR contents);
void sort();
public:
@ -199,7 +199,7 @@ public:
}
//This ends up writing a really ugly format on Windows: UTF-16, no BOM, LF endings.
//This is because Microsoft are dickbutts and refuse to support UTF-8 properly. I'm not rewarding that.
//This is because Microsoft are rude and refuse to support UTF-8 properly. I'm not rewarding that.
//I'm catering to their shitty char type, that's way more than enough.
//If the input is invalid, the object will ignore the invalid parts and remain valid.
@ -210,7 +210,7 @@ public:
//The key may only contain alphanumerics, . and _.
//The value may not have leading or trailing whitespace, or contain \r or \n.
void set(LPCWSTR key, LPCWSTR value);
void set(LPCWSTR key, LPCWSTR value); // If NULL, the key is removed. This may alter or rearrange unrelated get{name,value}byid values.
LPCWSTR get(LPCWSTR key, LPCWSTR def = NULL);
void setint(LPCWSTR key, int value) { WCHAR valstr[16]; wsprintf(valstr, TEXT("%i"), value); set(key, valstr); }
@ -232,7 +232,7 @@ LPCWSTR FindRomForPatch(file* patch, bool * possibleToFind);
void AddToRomList(file* patch, LPCWSTR path);
void DeleteRomFromList(LPCWSTR path);
LPCWSTR GetEmuFor(LPCWSTR filename);
LPCWSTR GetEmuFor(LPCWSTR filename); // NULL if none
void SetEmuFor(LPCWSTR filename, LPCWSTR emu);
struct errorinfo ApplyPatchMem2(file* patch, struct mem inrom, bool removeheader, bool verifyinput,