// ====================================== // // QuakeEd Project Management // // ====================================== #include #include "QF/quakefs.h" #include "QF/sys.h" #include "QF/va.h" #include "Project.h" #include "Map.h" #include "QuakeEd.h" #include "Preferences.h" #include "Dict.h" #include "Things.h" #include "TexturePalette.h" id project_i; @implementation Project - (id) init { project_i = self; return self; } // =========================================================== // // Project code // // =========================================================== - (id) initVars { const char *s; const char *pe; char *ts; ts = strdup ([preferences_i getProjectPath]); pe = QFS_SkipPath (ts); ts[pe - ts] = 0; strcpy (path_basepath, ts); strcpy (path_progdir, ts); strcat (path_progdir, SUBDIR_ENT); strcpy (path_mapdirectory, ts); strcat (path_mapdirectory, SUBDIR_MAPS); // source dir strcpy (path_finalmapdir, ts); strcat (path_finalmapdir, SUBDIR_MAPS); // dest dir // in Project Inspector [basepathinfo_i setStringValue: [NSString stringWithCString: ts]]; #if 0 // FIXME: for "out-of-tree" projects ? if ((s = [projectInfo getStringFor: BASEPATHKEY])) { strcpy (path_basepath, s); strcpy (path_progdir, s); strcat (path_progdir, "/" SUBDIR_ENT); strcpy (path_mapdirectory, s); strcat (path_mapdirectory, "/" SUBDIR_MAPS); // source dir strcpy (path_finalmapdir, s); strcat (path_finalmapdir, "/" SUBDIR_MAPS); // dest dir [basepathinfo_i setStringValue: s]; // in Project Inspector } #endif if ((s = [projectInfo getStringFor: BSPFULLVIS])) { strcpy (string_fullvis, s); changeString ('@', '\"', string_fullvis); } if ((s = [projectInfo getStringFor: BSPFASTVIS])) { strcpy (string_fastvis, s); changeString ('@', '\"', string_fastvis); } if ((s = [projectInfo getStringFor: BSPNOVIS])) { strcpy (string_novis, s); changeString ('@', '\"', string_novis); } if ((s = [projectInfo getStringFor: BSPRELIGHT])) { strcpy (string_relight, s); changeString ('@', '\"', string_relight); } if ((s = [projectInfo getStringFor: BSPLEAKTEST])) { strcpy (string_leaktest, s); changeString ('@', '\"', string_leaktest); } if ((s = [projectInfo getStringFor: BSPENTITIES])) { strcpy (string_entities, s); changeString ('@', '\"', string_entities); } // Build list of wads wadList = [projectInfo parseMultipleFrom: WADSKEY]; // Build list of maps & descriptions mapList = [projectInfo parseMultipleFrom: MAPNAMESKEY]; descList = [projectInfo parseMultipleFrom: DESCKEY]; [self changeChar: '_' to: ' ' in: descList]; [self initProjSettings]; return self; } // // Init Project Settings fields // - (id) initProjSettings { [pis_basepath_i setStringValue: [NSString stringWithCString: path_basepath]]; [pis_fullvis_i setStringValue: [NSString stringWithCString: string_fullvis]]; [pis_fastvis_i setStringValue: [NSString stringWithCString: string_fastvis]]; [pis_novis_i setStringValue: [NSString stringWithCString: string_novis]]; [pis_relight_i setStringValue: [NSString stringWithCString: string_relight]]; [pis_leaktest_i setStringValue: [NSString stringWithCString: string_leaktest]]; return self; } // // Add text to the BSP Output window // - (id) addToOutput: (const char *)string { int end; end = [BSPoutput_i textLength]; [BSPoutput_i replaceCharactersInRange: NSMakeRange (end, 0) withString: [NSString stringWithCString: string]]; end = [BSPoutput_i textLength]; [BSPoutput_i setSelectedRange: NSMakeRange (end, 0)]; // XXX [BSPoutput_i scrollSelToVisible]; return self; } - (id) clearBspOutput: sender { int end; end = [BSPoutput_i textLength]; [BSPoutput_i replaceCharactersInRange: NSMakeRange (0, end) withString: @""]; return self; } - (id) print { // XXX [BSPoutput_i printPSCode:self]; return self; } - (id) initProject { [self parseProjectFile]; if (projectInfo == NULL) return self; [self initVars]; [mapbrowse_i setReusesColumns: YES]; [mapbrowse_i loadColumnZero]; [pis_wads_i setReusesColumns: YES]; [pis_wads_i loadColumnZero]; [things_i initEntities]; return self; } // // Change a character to another in a Storage list of strings // - (id) changeChar: (char)f to: (char)t in: (id)obj { int i; int max; char *string; max = [obj count]; for (i = 0; i < max; i++) { string = [obj elementAt: i]; changeString (f, t, string); } return self; } // // Fill the QuakeEd Maps or wads browser // (Delegate method - delegated in Interface Builder) // - (void) browser: sender createRowsForColumn: (int)column inMatrix: matrix { id cell, list; int max; char *name; int i; if (sender == mapbrowse_i) { list = mapList; } else if (sender == pis_wads_i) { list = wadList; } else { list = nil; Sys_Error ("Project: unknown browser to fill"); } max = [list count]; for (i = 0; i < max; i++) { name = [list elementAt: i]; [matrix addRow]; cell = [matrix cellAtRow: i column: 0]; [cell setStringValue: [NSString stringWithCString: name]]; [cell setLeaf: YES]; [cell setLoaded: YES]; } } // // Clicked on a map name or description! // - (id) clickedOnMap: sender { id matrix; int row; const char *fname; id panel; NSModalSession session; matrix = [sender matrixInColumn: 0]; row = [matrix selectedRow]; fname = va ("%s/%s.map", path_mapdirectory, (const char *) [mapList elementAt: row]); // XXX Storage panel = NSGetAlertPanel (@"Loading...", @"Loading map. Please wait.", NULL, NULL, NULL); session = [NSApp beginModalSessionForWindow: panel]; [NSApp runModalSession: session]; [quakeed_i doOpen: fname]; [NSApp endModalSession: session]; [panel close]; NSReleaseAlertPanel (panel); return self; } - (id) setTextureWad: (const char *)wf { int i, c; const char *name; Sys_Printf ("loading %s\n", wf); // set the row in the settings inspector wad browser c = [wadList count]; for (i = 0; i < c; i++) { name = (const char *) [wadList elementAt: i]; // XXX Storage if (!strcmp (name, wf)) { [[pis_wads_i matrixInColumn: 0] selectCellAtRow: i column: 0]; break; } } // update the texture inspector [texturepalette_i initPaletteFromWadfile: wf]; [[map_i objectAtIndex: 0] setKey: "wad" toValue: wf]; // [inspcontrol_i changeInspectorTo:i_textures]; [quakeed_i updateAll]; return self; } // // Clicked on a wad name // - (id) clickedOnWad: sender { id matrix; int row; char *name; matrix = [sender matrixInColumn: 0]; row = [matrix selectedRow]; name = (char *) [wadList elementAt: row]; // XXX Storage [self setTextureWad: name]; return self; } // // Read in the .QE_Project file // - (id) parseProjectFile { const char *path; int rtn; path = [preferences_i getProjectPath]; if (!path || !path[0] || access (path, 0)) { rtn = NSRunAlertPanel (@"Project Error!", @"A default project has not been found.\n", @"Open Project", NULL, NULL); if ([self openProject] == nil) { while (1) [NSApp terminate: self]; // can't run without a project } return self; } [self openProjectFile: path]; return self; } // // Loads and parses a project file // - (id) openProjectFile: (const char *)path { FILE *fp; struct stat s; Sys_Printf ("openProjectFile: %s\n", path); strcpy (path_projectinfo, path); projectInfo = NULL; fp = fopen (path, "r+t"); if (fp == NULL) return self; stat (path, &s); lastModified = s.st_mtime; projectInfo = [(Dict *)[Dict alloc] initFromFile: fp]; fclose (fp); return self; } - (const char *) currentProjectFile { return path_projectinfo; } // // Open a project file // - (id) openProject { const char *path; id openpanel; int rtn; NSString *projtypes[] = {@"qpr"}; NSArray *filenames; const char *dir; openpanel = [NSOpenPanel new]; // [openpanel allowMultipleFiles:NO]; // [openpanel chooseDirectories:NO]; rtn = [openpanel runModalForTypes: [NSArray arrayWithObjects: projtypes count: 1]]; if (rtn == NSOKButton) { filenames = [openpanel filenames]; dir = [[openpanel directory] cString]; dir = ""; path = va ("%s/%s", dir, [[filenames objectAtIndex: 0] cString]); strcpy (path_projectinfo, path); [self openProjectFile: path]; return self; } return nil; } // // Search for a string in a List of strings // - (int) searchForString: (const char *)str in: (id)obj { int i; int max; const char *s; max = [obj count]; for (i = 0; i < max; i++) { s = (const char *) [obj elementAt: i]; // XXX Storage? if (!strcmp (s, str)) return 1; } return 0; } - (const char *) getMapDirectory { return path_mapdirectory; } - (const char *) getFinalMapDirectory { return path_finalmapdir; } - (const char *) getProgDirectory { return path_progdir; } // // Return the WAD name for cmd-8 // - (const char *) getWAD8 { if (!path_wad8[0]) return NULL; return path_wad8; } // // Return the WAD name for cmd-9 // - (const char *) getWAD9 { if (!path_wad9[0]) return NULL; return path_wad9; } // // Return the WAD name for cmd-0 // - (const char *) getWAD0 { if (!path_wad0[0]) return NULL; return path_wad0; } // // Return the FULLVIS cmd string // - (const char *) getFullVisCmd { if (!string_fullvis[0]) return NULL; return string_fullvis; } // // Return the FASTVIS cmd string // - (const char *) getFastVisCmd { if (!string_fastvis[0]) return NULL; return string_fastvis; } // // Return the NOVIS cmd string // - (const char *) getNoVisCmd { if (!string_novis[0]) return NULL; return string_novis; } // // Return the RELIGHT cmd string // - (const char *) getRelightCmd { if (!string_relight[0]) return NULL; return string_relight; } // // Return the LEAKTEST cmd string // - (const char *) getLeaktestCmd { if (!string_leaktest[0]) return NULL; return string_leaktest; } - (const char *) getEntitiesCmd { if (!string_entities[0]) return NULL; return string_entities; } @end // ==================================================== // C Functions // ==================================================== // // Change a character to a different char in a string // void changeString (char cf, char ct, char *string) { unsigned int j; for (j = 0; j < strlen (string); j++) { if (string[j] == cf) string[j] = ct; } }