/* Copyright (C) 2015 Marco "eukara" Hladik Copyright (C) 1996-1997 Id Software, Inc. 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. */ // A GTK based editor suite for the engine // // gint VID_EditorLoadPalette(gpointer data) // gint VID_EditorViewColormap(gpointer data) // gint VID_EditorGenerateColormap(gpointer data) // gint VID_EditorSaveFile(gpointer data) // gint VID_EditorLoadFile(gpointer data) // gint VID_EditorCreatePic(gpointer data) // gint VID_EditorNewFile(gpointer data) // gint VID_EditorImportFile(gpointer data) // gint VID_EditorExportFile(gpointer data) // void VID_EditorDrawTile(void) // gint VID_EditorQuit(gpointer data) // gint VID_EditorUpdate(gpointer data) // void VID_LaunchEditor(void) #include "globaldef.h" #include #include /* * NGUNIX EDITOR GUFF * ================== * Most engines don't come with an integrated toolset. * We are not one of those guys. */ GtkWidget *ed_window; GdkGC *ed_pic; GdkGC *ed_palpic; qpic_t *ed_file; qpic_t *ed_palfile; GtkWidget *ed_menubar; GdkRgbCmap *ed_cmap = NULL; unsigned char *ed_palette; qboolean vid_ineditor = false; extern GtkWidget *x_win; extern GdkGC *x_gc; extern GdkRgbCmap *x_cmap; /* EDITOR: PALETTE SWITCHER * ======================== * TODO: This somehow affects the main engine despite us using our own GdkColmap... */ gint VID_EditorLoadPalette(gpointer data) { int i; GtkWidget *dialog; GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN; gint res; loadedfile_t *palfile; unsigned int colors[256]; dialog = gtk_file_chooser_dialog_new ("NGUNIXEd - Open Palette (.lmp) File", NULL, action, ("_Cancel"), GTK_RESPONSE_CANCEL, ("_Open"), GTK_RESPONSE_ACCEPT, NULL); // Set the dialog and the default path (current directory) GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog); char path[MAX_OSPATH]; sprintf(path, "file://%s", get_current_dir_name()); gtk_file_chooser_set_current_folder_uri(chooser, path); // Add the filter for .lmp files GtkFileFilter *filter = gtk_file_filter_new (); gtk_file_filter_add_pattern (filter, "*.lmp"); gtk_file_chooser_set_filter (chooser, filter); res = gtk_dialog_run (GTK_DIALOG (dialog)); if (res == GTK_RESPONSE_ACCEPT) { char *filename; filename = gtk_file_chooser_get_filename (chooser); palfile = COM_LoadFile (filename, 2); if(palfile) { Con_Printf("[EDITOR] Switching palette to %s\n", filename); for(i=0; i < 16*16*3; i++) ed_palette[i] = palfile->data[i]; if (ed_cmap) gdk_rgb_cmap_free(ed_cmap); for (i = 0; i < 256; i++) { unsigned char r, g, b; r = *ed_palette++; g = *ed_palette++; b = *ed_palette++; colors[i] = r << 16 | g << 8 | b; } ed_cmap = gdk_rgb_cmap_new(colors, 256); } g_free (filename); } gtk_widget_destroy (dialog); return 0; } /* EDITOR: COLORMAP VIEWER * ======================= * Colormaps differ from lump files in the way that they don't start with a width | height header * Otherwise they are identical in how they refer to palette indexes for their color */ gint VID_EditorViewColormap(gpointer data) { int i; GtkWidget *dialog; GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN; gint res; loadedfile_t *pic; dialog = gtk_file_chooser_dialog_new ("NGUNIXEd - Open Colormap (.lmp) File", NULL, action, ("_Cancel"), GTK_RESPONSE_CANCEL, ("_Open"), GTK_RESPONSE_ACCEPT, NULL); // Set the dialog and the default path (current directory) GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog); char path[MAX_OSPATH]; sprintf(path, "file://%s", get_current_dir_name()); gtk_file_chooser_set_current_folder_uri(chooser, path); // Add the filter for .lmp files GtkFileFilter *filter = gtk_file_filter_new (); gtk_file_filter_add_pattern (filter, "*.lmp"); gtk_file_chooser_set_filter (chooser, filter); res = gtk_dialog_run (GTK_DIALOG (dialog)); if (res == GTK_RESPONSE_ACCEPT) { char *filename; filename = gtk_file_chooser_get_filename (chooser); pic = COM_LoadFile (filename, 2); if(pic) { Con_Printf("[EDITOR] Previewing Colormap %s\n", filename); ed_file = malloc(16385 + (sizeof(int) * 2)); ed_file->width = 256; ed_file->height = 64; for(i = 0; i < 256 * 64; i++) ed_file->data[i] = pic->data[i]; gtk_window_resize(ed_window, ed_file->width + ed_palfile->width, ed_file->height + ed_menubar->allocation.height); } g_free (filename); } gtk_widget_destroy (dialog); return 0; } /* EDITOR: GENERATE COLORMAP * =============== * Generate a colormap for the current palette... * makes use of our builtin function for generating them */ gint VID_EditorGenerateColormap(gpointer data) { GtkWidget *dialog; GtkFileChooser *chooser; GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE; gint res; byte *pic; dialog = gtk_file_chooser_dialog_new ("NGUNIXEd - Save Generated Colormap (.lmp) File", NULL, action, ("_Cancel"), GTK_RESPONSE_CANCEL, ("_Save"), GTK_RESPONSE_ACCEPT, NULL); chooser = GTK_FILE_CHOOSER (dialog); gtk_file_chooser_set_do_overwrite_confirmation (chooser, TRUE); // Set the default path (current directory) char path[MAX_OSPATH]; sprintf(path, "file://%s", get_current_dir_name()); gtk_file_chooser_set_current_folder_uri(chooser, path); // Add the filter for .lmp files GtkFileFilter *filter = gtk_file_filter_new (); gtk_file_filter_add_pattern (filter, "*.lmp"); gtk_file_chooser_set_filter (chooser, filter); res = gtk_dialog_run (GTK_DIALOG (dialog)); if (res == GTK_RESPONSE_ACCEPT) { char *filename; filename = gtk_file_chooser_get_filename (chooser); byte out_colormap[16384]; Con_Printf("[EDITOR] Generating colormap based on current palette...\n"); Colormap_Generate(ed_palette, out_colormap); COM_WriteFile (filename, out_colormap, 16384); g_free (filename); } gtk_widget_destroy (dialog); return 0; } /* EDITOR: SAVE LUMP * ================= * Saves the pic currently displayed as a lump... * This means that you can save special files, such as colormaps as regular piclumps, too! */ gint VID_EditorSaveFile(gpointer data) { GtkWidget *dialog; GtkFileChooser *chooser; GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE; gint res; if(!ed_file) return; dialog = gtk_file_chooser_dialog_new ("NGUNIXEd - Save LUMP (.lmp) File", NULL, action, ("_Cancel"), GTK_RESPONSE_CANCEL, ("_Save"), GTK_RESPONSE_ACCEPT, NULL); chooser = GTK_FILE_CHOOSER (dialog); gtk_file_chooser_set_do_overwrite_confirmation (chooser, TRUE); // Set the default path (current directory) char path[MAX_OSPATH]; sprintf(path, "file://%s", get_current_dir_name()); gtk_file_chooser_set_current_folder_uri(chooser, path); // Add the filter for .lmp files GtkFileFilter *filter = gtk_file_filter_new (); gtk_file_filter_add_pattern (filter, "*.lmp"); gtk_file_chooser_set_filter (chooser, filter); //if (user_edited_a_new_document) gtk_file_chooser_set_current_name (chooser, ("untitled.lmp")); //else // gtk_file_chooser_set_filename (chooser, // existing_filename); res = gtk_dialog_run (GTK_DIALOG (dialog)); if (res == GTK_RESPONSE_ACCEPT) { char *filename; filename = gtk_file_chooser_get_filename (chooser); Con_Printf("[EDITOR] Saving LUMP as %s...\n", filename); #if 0 printf("Saving IMAGE: %i, %i\n", pic[0], pic[1]); for(i = 2; i < pic[0] * pic[1]+2; i++) printf("%i,", pic[i]); printf("\n...DONE\n"); #endif COM_WriteFile (filename, ed_file, ed_file->width * ed_file->height + 2); g_free (filename); // free(pic); } gtk_widget_destroy (dialog); return 0; } /* EDITOR: LOAD LUMP * ================= * Loads a lump into the editor as a pic... * There is nothing more to it, really */ gint VID_EditorLoadFile(gpointer data) { GtkWidget *dialog; GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN; gint res; loadedfile_t *pic; dialog = gtk_file_chooser_dialog_new ("NGUNIXEd - Open LUMP (.lmp) File", NULL, action, ("_Cancel"), GTK_RESPONSE_CANCEL, ("_Open"), GTK_RESPONSE_ACCEPT, NULL); // Set the dialog and the default path (current directory) GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog); char path[MAX_OSPATH]; sprintf(path, "file://%s", get_current_dir_name()); gtk_file_chooser_set_current_folder_uri(chooser, path); // Add the filter for .lmp files GtkFileFilter *filter = gtk_file_filter_new (); gtk_file_filter_add_pattern (filter, "*.lmp"); gtk_file_chooser_set_filter (chooser, filter); res = gtk_dialog_run (GTK_DIALOG (dialog)); if (res == GTK_RESPONSE_ACCEPT) { char *filename; filename = gtk_file_chooser_get_filename (chooser); pic = COM_LoadFile (filename, 2); if(pic) { Con_Printf("[EDITOR] Loading LUMP at %s...\n", filename); ed_file = (qpic_t *)pic->data; gtk_window_resize(ed_window, ed_file->width + ed_palfile->width, ed_file->height + ed_menubar->allocation.height); } g_free (filename); } gtk_widget_destroy (dialog); return 0; } /* EDITOR: CREATE LUMP * =================== * Creates a lump based on width*height chosen by the user * The default pixel color is 255 - which is transparent in-engine */ GtkWidget *ed_newwindow; GtkWidget *ed_widthbox; GtkWidget *ed_heightbox; gint VID_EditorCreatePic(gpointer data) { int i; int mem; mem = (size_t)((sizeof(int) * 2) + (gtk_spin_button_get_value_as_int (ed_widthbox) * gtk_spin_button_get_value_as_int (ed_heightbox))); //mem = 262152; Con_Printf("[EDITOR] Creating new %ix%i LUMP\n", gtk_spin_button_get_value_as_int (ed_widthbox), gtk_spin_button_get_value_as_int (ed_heightbox)); ed_file = Hunk_Alloc((size_t)mem); ed_file->width = gtk_spin_button_get_value_as_int (ed_widthbox); ed_file->height = gtk_spin_button_get_value_as_int (ed_heightbox); for(i=0; i < (ed_file->width * ed_file->height); i++) ed_file->data[i] = 255; gtk_window_resize(ed_window, ed_file->width + ed_palfile->width, ed_file->height + ed_menubar->allocation.height); gtk_widget_destroy(ed_newwindow); } gint VID_EditorNewFile(gpointer data) { GtkWidget *table; GtkWidget *label1; GtkWidget *label2; ed_newwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(ed_newwindow), GTK_WIN_POS_CENTER); gtk_window_set_title(GTK_WINDOW(ed_newwindow), "New LMP"); gtk_container_set_border_width(GTK_CONTAINER(ed_newwindow), 10); table = gtk_table_new(3, 2, FALSE); gtk_container_add(GTK_CONTAINER(ed_newwindow), table); label1 = gtk_label_new("Width"); label2 = gtk_label_new("Height"); gtk_table_attach(GTK_TABLE(table), label1, 0, 1, 0, 1, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); gtk_table_attach(GTK_TABLE(table), label2, 0, 1, 1, 2, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); ed_widthbox = gtk_spin_button_new_with_range (1, 512, 1); ed_heightbox = gtk_spin_button_new_with_range (1, 512, 1); gtk_table_attach(GTK_TABLE(table), ed_widthbox, 1, 2, 0, 1, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); gtk_table_attach(GTK_TABLE(table), ed_heightbox, 1, 2, 1, 2, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); GtkWidget *btnok = gtk_button_new_with_label("Create"); gtk_table_attach(GTK_TABLE(table), btnok, 1, 2, 2, 3, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); gtk_widget_show_all(ed_newwindow); g_signal_connect(ed_newwindow, "destroy", G_CALLBACK(gtk_widget_destroy), NULL); g_signal_connect(btnok, "clicked", G_CALLBACK(VID_EditorCreatePic), G_OBJECT(ed_newwindow)); } /* EDITOR: LOAD PCX * ================ * Loads a PCX into the editor as a pic... */ gint VID_EditorImportFile(gpointer data) { GtkWidget *dialog; GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN; gint res; loadedfile_t *pic; dialog = gtk_file_chooser_dialog_new ("NGUNIXEd - Picture Exchange (.pcx) File", NULL, action, ("_Cancel"), GTK_RESPONSE_CANCEL, ("_Open"), GTK_RESPONSE_ACCEPT, NULL); // Set the dialog and the default path (current directory) GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog); char path[MAX_OSPATH]; sprintf(path, "file://%s", get_current_dir_name()); gtk_file_chooser_set_current_folder_uri(chooser, path); // Add the filter for .lmp files GtkFileFilter *filter = gtk_file_filter_new (); gtk_file_filter_add_pattern (filter, "*.pcx"); gtk_file_chooser_set_filter (chooser, filter); res = gtk_dialog_run (GTK_DIALOG (dialog)); if (res == GTK_RESPONSE_ACCEPT) { char *filename; byte *temp; filename = gtk_file_chooser_get_filename (chooser); pic = COM_LoadFile (filename, 2); if (pic) { int pic_width, pic_height; Con_Printf("[EDITOR] Importing PCX at %s...\n", filename); byte *pic_data = Hunk_Alloc(pic->filelen); pic_data = Image_ReadPCXFile(pic->data, pic->filelen, &pic_width, &pic_height, ed_palette); if(pic_data == NULL) { g_free(filename); gtk_widget_destroy (dialog); return 0; } ed_file = Hunk_Alloc((sizeof(int) * 2) + (pic_width * pic_height)); ed_file->width = pic_width; ed_file->height = pic_height; int i; for(i = 0; i < pic_width * pic_height; i++) ed_file->data[i] = pic_data[i]; gtk_window_resize(ed_window, ed_file->width + ed_palfile->width, ed_file->height + ed_menubar->allocation.height); } g_free (filename); } gtk_widget_destroy (dialog); return 0; } /* EDITOR: EXPORT LUMP * =================== * Saves the pic currently displayed as a PCX file... */ gint VID_EditorExportFile(gpointer data) { GtkWidget *dialog; GtkFileChooser *chooser; GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE; gint res; byte *pic; if(!ed_file) return; dialog = gtk_file_chooser_dialog_new ("NGUNIXEd - Save Picture Exchange (.pcx) File", NULL, action, ("_Cancel"), GTK_RESPONSE_CANCEL, ("_Save"), GTK_RESPONSE_ACCEPT, NULL); chooser = GTK_FILE_CHOOSER (dialog); gtk_file_chooser_set_do_overwrite_confirmation (chooser, TRUE); // Set the default path (current directory) char path[MAX_OSPATH]; sprintf(path, "file://%s", get_current_dir_name()); gtk_file_chooser_set_current_folder_uri(chooser, path); // Add the filter for .lmp files GtkFileFilter *filter = gtk_file_filter_new (); gtk_file_filter_add_pattern (filter, "*.pcx"); gtk_file_chooser_set_filter (chooser, filter); //if (user_edited_a_new_document) gtk_file_chooser_set_current_name (chooser, ("untitled.pcx")); //else // gtk_file_chooser_set_filename (chooser, // existing_filename); res = gtk_dialog_run (GTK_DIALOG (dialog)); if (res == GTK_RESPONSE_ACCEPT) { char *filename; filename = gtk_file_chooser_get_filename (chooser); Con_Printf("[EDITOR] Exporting PCX to %s...\n", filename); int w, h; w = ed_file->width; h = ed_file->height; pic = Hunk_Alloc(ed_file->width * ed_file->height); memcpy(pic, &ed_file->data, (ed_file->width * ed_file->height)); Image_WritePCXfile (filename, pic, w, h, ed_file->width, host_basepal); g_free (filename); } gtk_widget_destroy (dialog); return 0; } /* EDITOR: DRAWTILE * ============ * Draw a tiling backg into the engine window */ qpic_t *ed_backtile; void VID_EditorDrawTile(void) { ed_backtile = malloc(vid.width * vid.height + (2 * sizeof(int))); ed_backtile->width = vid.width; ed_backtile->height = vid.height; int rgb[3]; rgb[0] = 107; rgb[1] = 107; rgb[2] = 151; int color = Convert_24_to_8(host_basepal, rgb); int i, j; for(i = 0; i < vid.width * vid.height; i++) ed_backtile->data[i] = 0; for(i = 0; i < vid.height; i++) { for(j = 0; j < vid.width; j++) ed_backtile->data[i*vid.width + j] = color; i += 16; } for(i = 0; i < vid.width; i++) { for(j = 0; j < vid.height; j++) ed_backtile->data[j * vid.width + i] = color; i += 16; } } /* EDITOR: QUIT * ============ * Kills the editor, unloads any pics, etc. */ gint VID_EditorQuit(gpointer data) { if(vid_ineditor == true) { Con_Printf("[EDITOR] Shutting down\n"); gtk_widget_destroy(ed_window); vid_ineditor = false; gtk_main_quit(); } } /* EDITOR: UPDATE * ============== * Called every once in a while to update the picture inside the window... */ //int ed_tilecol = 0; gint VID_EditorUpdate(gpointer data) { /*if(ed_tilecol >= 255-16) ed_tilecol = 0; int i, j; for(i = 0; i < vid.height; i++) { for(j = 0; j < vid.width; j++) ed_backtile->data[i * vid.width + j] = ed_tilecol; i += 16; } for(i = 0; i < vid.width; i++) { for(j = 0; j < vid.height; j++) ed_backtile->data[j * vid.width + i] = ed_tilecol; i += 16; } ed_tilecol++; */ gdk_draw_indexed_image(gtk_widget_get_window(x_win), x_gc, 0, 0, ed_backtile->width, ed_backtile->height, GDK_RGB_DITHER_NONE, ed_backtile->data, ed_backtile->width, x_cmap); if(ed_file) { gdk_draw_indexed_image(gtk_widget_get_window(ed_window), ed_pic, 0, ed_menubar->allocation.height, ed_file->width, ed_file->height, GDK_RGB_DITHER_NONE, ed_file->data, ed_file->width, ed_cmap); gdk_draw_indexed_image(gtk_widget_get_window(ed_window), ed_pic, ed_file->width, ed_menubar->allocation.height, ed_palfile->width, ed_palfile->height, GDK_RGB_DITHER_NONE, ed_palfile->data, ed_palfile->width, ed_cmap); return 1; } gdk_draw_indexed_image(gtk_widget_get_window(ed_window), ed_pic, 0, ed_menubar->allocation.height, ed_palfile->width, ed_palfile->height, GDK_RGB_DITHER_NONE, ed_palfile->data, ed_palfile->width, ed_cmap); return 1; } /* EDITOR: MAIN FUNCTION * ===================== * This is the first function called when calling the editor. * Here we get functions to Create, Load and Save LUMPS, as well as * play with palettes and generate colormaps. * * TODO: Import/Export of PCX files */ void VID_LaunchEditor(void) { GtkWidget *vbox; GtkWidget *fileMenu; GtkWidget *extraMenu; unsigned int ed_colors[256]; ed_palfile = malloc(256+8); ed_palette = malloc(16*16*3); memcpy(&ed_palette, &host_basepal, sizeof(16*16*3)); int i; for (i = 0; i < 256; i++) { unsigned char r, g, b; r = *ed_palette++; g = *ed_palette++; b = *ed_palette++; ed_colors[i] = r << 16 | g << 8 | b; ed_palfile->data[i] = i; } ed_cmap = gdk_rgb_cmap_new(ed_colors, 256); ed_palfile = Image_Resize(ed_palfile->data, 16, 16, 64, 64); VID_EditorDrawTile(); ed_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(ed_window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(ed_window), 300, 200); gtk_window_set_title(GTK_WINDOW(ed_window), "NGUNIXEd - 2D Lump Editor"); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(ed_window), vbox); ed_menubar = gtk_menu_bar_new(); fileMenu = gtk_menu_new(); extraMenu = gtk_menu_new(); GtkWidget *fileMi = gtk_menu_item_new_with_label("File"); GtkWidget *newMi = gtk_menu_item_new_with_label("New"); GtkWidget *loadMi = gtk_menu_item_new_with_label("Load..."); GtkWidget *saveMi = gtk_menu_item_new_with_label("Save..."); GtkWidget *importMi = gtk_menu_item_new_with_label("Import..."); GtkWidget *exportMi = gtk_menu_item_new_with_label("Export..."); GtkWidget *extrMi = gtk_menu_item_new_with_label("Extra"); GtkWidget *swipalMi = gtk_menu_item_new_with_label("Switch Palette..."); GtkWidget *viewcolmapMi = gtk_menu_item_new_with_label("View Colormap..."); GtkWidget *gencolmapMi = gtk_menu_item_new_with_label("Generate Colormap..."); gtk_menu_item_set_submenu(GTK_MENU_ITEM(fileMi), fileMenu); gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), newMi); gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), loadMi); gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), saveMi); gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), importMi); gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), exportMi); gtk_menu_shell_append(GTK_MENU_SHELL(ed_menubar), fileMi); gtk_menu_item_set_submenu(GTK_MENU_ITEM(extrMi), extraMenu); gtk_menu_shell_append(GTK_MENU_SHELL(extraMenu), swipalMi); gtk_menu_shell_append(GTK_MENU_SHELL(extraMenu), viewcolmapMi); gtk_menu_shell_append(GTK_MENU_SHELL(extraMenu), gencolmapMi); gtk_menu_shell_append(GTK_MENU_SHELL(ed_menubar), extrMi); gtk_box_pack_start(GTK_BOX(vbox), ed_menubar, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(ed_window), "destroy", G_CALLBACK(VID_EditorQuit), NULL); g_signal_connect(G_OBJECT(newMi), "activate", G_CALLBACK(VID_EditorNewFile), NULL); g_signal_connect(G_OBJECT(loadMi), "activate", G_CALLBACK(VID_EditorLoadFile), NULL); g_signal_connect(G_OBJECT(saveMi), "activate", G_CALLBACK(VID_EditorSaveFile), NULL); g_signal_connect(G_OBJECT(importMi), "activate", G_CALLBACK(VID_EditorImportFile), NULL); g_signal_connect(G_OBJECT(exportMi), "activate", G_CALLBACK(VID_EditorExportFile), NULL); g_signal_connect(G_OBJECT(swipalMi), "activate", G_CALLBACK(VID_EditorLoadPalette), NULL); g_signal_connect(G_OBJECT(viewcolmapMi), "activate", G_CALLBACK(VID_EditorViewColormap), NULL); g_signal_connect(G_OBJECT(gencolmapMi), "activate", G_CALLBACK(VID_EditorGenerateColormap), NULL); gtk_timeout_add(100, VID_EditorUpdate, NULL); gtk_widget_realize(ed_window); gtk_widget_realize(ed_menubar); ed_pic = gdk_gc_new(gtk_widget_get_window(ed_window)); gtk_widget_show_all(ed_window); Con_Printf("[EDITOR] Initialized\n"); vid_ineditor = true; gtk_main(); }