diff --git a/flips-gtk.cpp b/flips-gtk.cpp index 543afcc..0989937 100644 --- a/flips-gtk.cpp +++ b/flips-gtk.cpp @@ -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"}; diff --git a/flips.cpp b/flips.cpp index 8c22f1f..7835c97 100644 --- a/flips.cpp +++ b/flips.cpp @@ -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 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;inumentries;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;inumentries;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)); diff --git a/flips.h b/flips.h index 1b78008..2b94dc9 100644 --- a/flips.h +++ b/flips.h @@ -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,