/* ZeroGS * Copyright (C) 2002-2004 GSsoft Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include "GS.h" #include "Linux.h" #include "zerogs.h" #include static map mapConfOpts; void CALLBACK GSkeyEvent(keyEvent *ev) { //static bool bShift = false; static bool bAlt = false; switch (ev->evt) { case KEYPRESS: switch (ev->key) { case XK_F5: case XK_F6: case XK_F7: case XK_F9: THR_KeyEvent = ev->key ; break; case XK_Escape: if (conf.options & GSOPTION_FULLSCREEN) GSclose(); break; case XK_Shift_L: case XK_Shift_R: //bShift = true; THR_bShift = true; break; case XK_Alt_L: case XK_Alt_R: bAlt = true; break; } break; case KEYRELEASE: switch (ev->key) { case XK_Shift_L: case XK_Shift_R: //bShift = false; THR_bShift = false; break; case XK_Alt_L: case XK_Alt_R: bAlt = false; break; } } } void add_map_entry(u32 option, const char *key, const char *desc) { confOpts.value = option; confOpts.desc = desc; mapConfOpts[key] = confOpts; } void CreateGameHackTable(GtkWidget *treeview) { char descbuf[255]; bool itval; GtkCellRenderer *treerend; GtkListStore *treestore;//Gets typecast as GtkTreeModel as needed. GtkTreeIter treeiter; GtkTreeViewColumn *treecol; //--------- Let's build a treeview for our advanced options! --------// treestore = gtk_list_store_new(2, G_TYPE_BOOLEAN, G_TYPE_STRING); //setup columns in treeview //COLUMN 0 is the checkboxes treecol = gtk_tree_view_column_new(); gtk_tree_view_column_set_title(treecol, "Select"); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), treecol); treerend = gtk_cell_renderer_toggle_new(); gtk_tree_view_column_pack_start(treecol, treerend, true); gtk_tree_view_column_add_attribute(treecol, treerend, "active", 0);//link 'active' attrib to first column of model g_object_set(treerend, "activatable", true, NULL);//set 'activatable' attrib true by default for all rows regardless of model. g_signal_connect(treerend, "toggled", (GCallback) OnToggle_advopts, treestore);//set a global callback, we also pass a reference to our treestore. //COLUMN 1 is the text descriptions treecol = gtk_tree_view_column_new(); gtk_tree_view_column_set_title(treecol, "Description"); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), treecol); treerend = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(treecol, treerend, true); gtk_tree_view_column_add_attribute(treecol, treerend, "text", 1);//link 'text' attrib to second column of model //setup the model with all our rows of option data mapConfOpts.clear(); add_map_entry(GAME_TEXTURETARGS, "00000001", "Tex Target checking - 00000001\nLego Racers"); add_map_entry(GAME_AUTORESET, "00000002", "Auto reset targs - 00000002\nShadow Hearts, Samurai Warriors. Use when game is slow and toggling AA fixes it."); add_map_entry(GAME_NOTARGETRESOLVE, "00000010", "No target resolves - 00000010\nStops all resolving of targets. Try this first for really slow games. Dark Cloud 1"); add_map_entry(GAME_EXACTCOLOR, "00000020", "Exact color testing - 00000020\nFixes overbright or shadow/black artifacts (Crash 'n Burn)."); add_map_entry(GAME_NOCOLORCLAMP, "00000040", "No color clamping - 00000040\nSpeeds up games, but might be too bright or too dim."); add_map_entry(GAME_NOALPHAFAIL, "00000100", "Alpha Fail hack - 00000100\nFor Sonic Unleashed, Shadow the Hedgehog, Ghost in the Shell. Remove vertical stripes or other coloring artefacts. Break Persona 4 and MGS3"); add_map_entry(GAME_NODEPTHUPDATE, "00000200", "Disable depth updates - 00000200"); add_map_entry(GAME_QUICKRESOLVE1, "00000400", "Resolve Hack #1 - 00000400\nKingdom Hearts. Speeds some games."); add_map_entry(GAME_NOQUICKRESOLVE, "00000800", "Resolve Hack #2 - 00000800\nShadow Hearts, Urbz. Destroy FFX"); add_map_entry(GAME_NOTARGETCLUT, "00001000", "No target CLUT - 00001000\nResident Evil 4, or foggy scenes."); add_map_entry(GAME_NOSTENCIL, "00002000", "Disable stencil buffer - 00002000\nUsually safe to do for simple scenes. Harvest Moon"); add_map_entry(GAME_NODEPTHRESOLVE, "00008000", "No depth resolve - 00008000\nMight give z buffer artifacts."); add_map_entry(GAME_FULL16BITRES, "00010000", "Full 16 bit resolution - 00010000\nUse when half the screen is missing."); add_map_entry(GAME_RESOLVEPROMOTED, "00020000", "Resolve Hack #3 - 00020000\nNeopets"); add_map_entry(GAME_FASTUPDATE, "00040000", "Fast Update - 00040000\nOkami. Speeds some games. Needs for Sonic Unleashed"); add_map_entry(GAME_NOALPHATEST, "00080000", "Disable alpha testing - 00080000"); add_map_entry(GAME_DISABLEMRTDEPTH, "00100000", "Enable Multiple RTs - 00100000"); add_map_entry(GAME_XENOSPECHACK, "01000000", "Specular Highlights - 01000000\nMakes Xenosaga and Okage graphics faster by removing highlights"); add_map_entry(GAME_PARTIALPOINTERS, "02000000", "Partial targets - 02000000"); add_map_entry(GAME_PARTIALDEPTH, "04000000", "Partial depth - 04000000"); add_map_entry(GAME_GUSTHACK, "10000000", "Gust fix, made gustgame more clean and fast - 10000000"); add_map_entry(GAME_NOLOGZ, "20000000", "No logarithmic Z, could decrease number of Z-artefacts - 20000000"); add_map_entry(GAME_INTERLACE2X, "00000004", "Interlace 2X - 00000004\nFixes 2x bigger screen (Gradius 3)."); for (map::iterator it = mapConfOpts.begin(); it != mapConfOpts.end(); ++it) { gtk_list_store_append(treestore, &treeiter);//new row itval = (conf.gamesettings & it->second.value) ? true : false; snprintf(descbuf, 254, "%s", it->second.desc); gtk_list_store_set(treestore, &treeiter, 0, itval, 1, descbuf, -1); } gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(treestore));//NB: store is cast as tree model. g_object_unref(treestore);//allow model to be destroyed when the tree is destroyed. //don't select/highlight rows gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), GTK_SELECTION_NONE); //------treeview done -------// } void SaveGameHackTable(GtkWidget *treeview) { GtkTreeModel *treemodel; GtkTreeIter treeiter; gboolean treeoptval; //------- get advanced options from the treeview model -------// treemodel = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview)); gtk_tree_model_get_iter_first(treemodel, &treeiter); conf.gamesettings = 0; for (map::iterator it = mapConfOpts.begin(); it != mapConfOpts.end(); ++it) { treeoptval = false; gtk_tree_model_get(treemodel, &treeiter, 0, &treeoptval, -1); if (treeoptval) conf.gamesettings |= it->second.value; gtk_tree_model_iter_next(treemodel, &treeiter); } GSsetGameCRC(0, conf.gamesettings); //---------- done getting advanced options ---------// } void OnToggle_advopts(GtkCellRendererToggle *cell, gchar *path, gpointer user_data) { GtkTreeIter treeiter; gboolean val; gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(user_data), &treeiter, path); gtk_tree_model_get(GTK_TREE_MODEL(user_data), &treeiter, 0, &val, -1); val = !val; gtk_list_store_set(GTK_LIST_STORE(user_data), &treeiter, 0, val, -1); } void DisplayDialog() { int return_value; GtkWidget *dialog; GtkWidget *main_frame, *main_box; GtkWidget *option_frame, *option_box; GtkWidget *log_check; GtkWidget *int_label, *int_box; GtkWidget *bilinear_check, *bilinear_label; GtkWidget *aa_label, *aa_box; GtkWidget *wireframe_check, *avi_check; GtkWidget *snap_label, *snap_box; GtkWidget *size_label, *size_box; GtkWidget *fullscreen_check, *widescreen_check; GtkWidget *advanced_frame, *advanced_box; GtkWidget *advanced_scroll; GtkWidget *tree; if (!(conf.options & GSOPTION_LOADED)) LoadConfig(); /* Create the widgets */ dialog = gtk_dialog_new_with_buttons( "ZZOgl PG Config", NULL, /* parent window*/ (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); log_check = gtk_check_button_new_with_label("Logging (For Debugging):"); int_label = gtk_label_new("Interlacing: (F5 to toggle)"); int_box = gtk_combo_box_new_text(); gtk_combo_box_append_text(GTK_COMBO_BOX(int_box), "No Interlacing"); gtk_combo_box_append_text(GTK_COMBO_BOX(int_box), "Interlace 0"); gtk_combo_box_append_text(GTK_COMBO_BOX(int_box), "Interlace 1"); gtk_combo_box_set_active(GTK_COMBO_BOX(int_box), conf.interlace); bilinear_check = gtk_check_button_new_with_label("Bilinear Filtering (Shift + F5)"); bilinear_label = gtk_label_new("Best quality is off. Turn on for speed."); aa_label = gtk_label_new("Anti-Aliasing for Higher Quality(F6)"); aa_box = gtk_combo_box_new_text(); gtk_combo_box_append_text(GTK_COMBO_BOX(aa_box), "1X - No Anti-Aliasing"); gtk_combo_box_append_text(GTK_COMBO_BOX(aa_box), "2X - Anti-Aliasing x 2"); gtk_combo_box_append_text(GTK_COMBO_BOX(aa_box), "4X - Anti-Aliasing x 4"); gtk_combo_box_append_text(GTK_COMBO_BOX(aa_box), "8X - Anti-Aliasing x 8"); gtk_combo_box_append_text(GTK_COMBO_BOX(aa_box), "16X - Anti-Aliasing x 16"); gtk_combo_box_set_active(GTK_COMBO_BOX(aa_box), conf.aa); wireframe_check = gtk_check_button_new_with_label("Wireframe Rendering(Shift + F6)"); avi_check = gtk_check_button_new_with_label("Capture Avi (as zerogs.avi)(F7)"); snap_label = gtk_label_new("Snapshot format:"); snap_box = gtk_combo_box_new_text(); gtk_combo_box_append_text(GTK_COMBO_BOX(snap_box), "JPEG"); gtk_combo_box_append_text(GTK_COMBO_BOX(snap_box), "TIFF"); gtk_combo_box_set_active(GTK_COMBO_BOX(snap_box), conf.options & GSOPTION_TGASNAP); fullscreen_check = gtk_check_button_new_with_label("Fullscreen (Alt + Enter)"); widescreen_check = gtk_check_button_new_with_label("Widescreen"); size_label = gtk_label_new("Default Window Size: (no speed impact)"); size_box = gtk_combo_box_new_text(); gtk_combo_box_append_text(GTK_COMBO_BOX(size_box), "640x480"); gtk_combo_box_append_text(GTK_COMBO_BOX(size_box), "800x600"); gtk_combo_box_append_text(GTK_COMBO_BOX(size_box), "1024x768"); gtk_combo_box_append_text(GTK_COMBO_BOX(size_box), "1280x960"); gtk_combo_box_set_active(GTK_COMBO_BOX(size_box), (conf.options&GSOPTION_WINDIMS) >> 4); main_box = gtk_hbox_new(false, 5); main_frame = gtk_frame_new("ZZOgl PG Config"); gtk_container_add(GTK_CONTAINER(main_frame), main_box); option_box = gtk_vbox_new(false, 5); option_frame = gtk_frame_new(""); gtk_container_add(GTK_CONTAINER(option_frame), option_box); advanced_box = gtk_vbox_new(false, 5); advanced_frame = gtk_frame_new("Advanced Settings:"); gtk_container_add(GTK_CONTAINER(advanced_frame), advanced_box); tree = gtk_tree_view_new(); CreateGameHackTable(tree); advanced_scroll = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(advanced_scroll), tree); gtk_box_pack_start(GTK_BOX(option_box), log_check, false, false, 2); gtk_box_pack_start(GTK_BOX(option_box), int_label, false, false, 2); gtk_box_pack_start(GTK_BOX(option_box), int_box, false, false, 2); gtk_box_pack_start(GTK_BOX(option_box), bilinear_check, false, false, 2); gtk_box_pack_start(GTK_BOX(option_box), bilinear_label, false, false, 2); gtk_box_pack_start(GTK_BOX(option_box), aa_label, false, false, 2); gtk_box_pack_start(GTK_BOX(option_box), aa_box, false, false, 2); gtk_box_pack_start(GTK_BOX(option_box), wireframe_check, false, false, 2); gtk_box_pack_start(GTK_BOX(option_box), avi_check, false, false, 2); gtk_box_pack_start(GTK_BOX(option_box), snap_label, false, false, 2); gtk_box_pack_start(GTK_BOX(option_box), snap_box, false, false, 2); gtk_box_pack_start(GTK_BOX(option_box), fullscreen_check, false, false, 2); gtk_box_pack_start(GTK_BOX(option_box), widescreen_check, false, false, 2); gtk_box_pack_start(GTK_BOX(option_box), size_label, false, false, 2); gtk_box_pack_start(GTK_BOX(option_box), size_box, false, false, 2); gtk_box_pack_start(GTK_BOX(advanced_box), advanced_scroll, true, true, 2); gtk_box_pack_start(GTK_BOX(main_box), option_frame, false, false, 2); gtk_box_pack_start(GTK_BOX(main_box), advanced_frame, true, true, 2); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(log_check), conf.log); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bilinear_check), conf.bilinear); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wireframe_check), (conf.options & GSOPTION_WIREFRAME)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(avi_check), (conf.options & GSOPTION_CAPTUREAVI)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fullscreen_check), (conf.options & GSOPTION_FULLSCREEN)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widescreen_check), (conf.options & GSOPTION_WIDESCREEN)); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), main_frame); gtk_widget_show_all(dialog); return_value = gtk_dialog_run(GTK_DIALOG(dialog)); if (return_value == GTK_RESPONSE_ACCEPT) { int fake_options = 0; SaveGameHackTable(tree); if (gtk_combo_box_get_active(GTK_COMBO_BOX(int_box)) != -1) conf.interlace = gtk_combo_box_get_active(GTK_COMBO_BOX(int_box)); if (gtk_combo_box_get_active(GTK_COMBO_BOX(aa_box)) != -1) conf.aa = gtk_combo_box_get_active(GTK_COMBO_BOX(aa_box)); conf.negaa = 0; switch (gtk_combo_box_get_active(GTK_COMBO_BOX(size_box))) { case 0: fake_options |= GSOPTION_WIN640; break; case 1: fake_options |= GSOPTION_WIN800; break; case 2: fake_options |= GSOPTION_WIN1024; break; case 3: fake_options |= GSOPTION_WIN1280; break; } conf.log = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(log_check)); conf.bilinear = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bilinear_check)); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wireframe_check))) fake_options |= GSOPTION_WIREFRAME; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(avi_check))) fake_options |= GSOPTION_CAPTUREAVI; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fullscreen_check))) fake_options |= GSOPTION_FULLSCREEN; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widescreen_check))) fake_options |= GSOPTION_WIDESCREEN; if (gtk_combo_box_get_active(GTK_COMBO_BOX(snap_box)) == 1) fake_options |= GSOPTION_TGASNAP; conf.options = fake_options; SaveConfig(); } gtk_widget_destroy(dialog); } void CALLBACK GSconfigure() { char strcurdir[256]; getcwd(strcurdir, 256); if (!(conf.options & GSOPTION_LOADED)) LoadConfig(); DisplayDialog(); } void SysMessage(const char *fmt, ...) { va_list list; char msg[512]; va_start(list, fmt); vsprintf(msg, fmt, list); va_end(list); if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0; GtkWidget *dialog; dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", msg); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } void CALLBACK GSabout() { SysMessage("ZZOgl PG: by Zeydlitz (PG version worked on by arcum42). Based off of ZeroGS, by zerofrog."); } s32 CALLBACK GStest() { return 0; } void *SysLoadLibrary(char *lib) { return dlopen(lib, RTLD_NOW | RTLD_GLOBAL); } void *SysLoadSym(void *lib, char *sym) { void *ret = dlsym(lib, sym); if (ret == NULL) printf("null: %s\n", sym); return dlsym(lib, sym); } char *SysLibError() { return dlerror(); } void SysCloseLibrary(void *lib) { dlclose(lib); }