mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-05 20:50:43 +00:00
529 lines
9.8 KiB
Objective-C
529 lines
9.8 KiB
Objective-C
//======================================
|
|
//
|
|
// QuakeEd Project Management
|
|
//
|
|
//======================================
|
|
|
|
#include <unistd.h>
|
|
|
|
#include "QF/quakefs.h"
|
|
#include "QF/sys.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
|
|
|
|
-init
|
|
{
|
|
project_i = self;
|
|
|
|
return self;
|
|
}
|
|
|
|
//===========================================================
|
|
//
|
|
// Project code
|
|
//
|
|
//===========================================================
|
|
-initVars
|
|
{
|
|
char *s;
|
|
const char *pe;
|
|
|
|
s =[preferences_i getProjectPath];
|
|
pe = QFS_SkipPath (s);
|
|
s[pe - s] = 0;
|
|
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: [NSString stringWithCString:s]];
|
|
// in Project Inspector
|
|
|
|
#if 0
|
|
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
|
|
//
|
|
-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
|
|
//
|
|
-addToOutput:(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;
|
|
}
|
|
|
|
-clearBspOutput:sender
|
|
{
|
|
int end;
|
|
|
|
end =[BSPoutput_i textLength];
|
|
[BSPoutput_i replaceCharactersInRange: NSMakeRange (0, end) withString:@""];
|
|
|
|
return self;
|
|
}
|
|
|
|
-print
|
|
{
|
|
// XXX [BSPoutput_i printPSCode:self];
|
|
return self;
|
|
}
|
|
|
|
|
|
-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
|
|
//
|
|
-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!
|
|
//
|
|
-clickedOnMap:sender
|
|
{
|
|
id matrix;
|
|
int row;
|
|
char fname[1024];
|
|
id panel;
|
|
NSModalSession session;
|
|
|
|
matrix =[sender matrixInColumn:0];
|
|
row =[matrix selectedRow];
|
|
sprintf (fname, "%s/%s.map", path_mapdirectory, (char *)[mapList elementAt:row]);
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
-setTextureWad:(char *) wf
|
|
{
|
|
int i, c;
|
|
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 = (char *)[wadList elementAt:i];
|
|
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
|
|
//
|
|
-clickedOnWad:sender
|
|
{
|
|
id matrix;
|
|
int row;
|
|
char *name;
|
|
|
|
matrix =[sender matrixInColumn:0];
|
|
row =[matrix selectedRow];
|
|
|
|
name = (char *)[wadList elementAt:row];
|
|
[self setTextureWad:name];
|
|
|
|
return self;
|
|
}
|
|
|
|
|
|
//
|
|
// Read in the <name>.QE_Project file
|
|
//
|
|
-parseProjectFile
|
|
{
|
|
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) // can't run without a project
|
|
[NSApp terminate:self];
|
|
return self;
|
|
}
|
|
|
|
[self openProjectFile:path];
|
|
return self;
|
|
}
|
|
|
|
//
|
|
// Loads and parses a project file
|
|
//
|
|
-openProjectFile:(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;
|
|
}
|
|
|
|
-(char *) currentProjectFile
|
|
{
|
|
return path_projectinfo;
|
|
}
|
|
|
|
//
|
|
// Open a project file
|
|
//
|
|
-openProject
|
|
{
|
|
char path[128];
|
|
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 = "";
|
|
sprintf (path, "%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:(char *)
|
|
str in:(id) obj
|
|
{
|
|
int i;
|
|
int max;
|
|
char *s;
|
|
|
|
max =[obj count];
|
|
for (i = 0; i < max; i++) {
|
|
s = (char *)[obj elementAt:i];
|
|
if (!strcmp (s, str))
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
-(char *) getMapDirectory
|
|
{
|
|
return path_mapdirectory;
|
|
}
|
|
|
|
-(char *) getFinalMapDirectory
|
|
{
|
|
return path_finalmapdir;
|
|
}
|
|
|
|
-(char *) getProgDirectory
|
|
{
|
|
return path_progdir;
|
|
}
|
|
|
|
|
|
//
|
|
// Return the WAD name for cmd-8
|
|
//
|
|
-(char *) getWAD8
|
|
{
|
|
if (!path_wad8[0])
|
|
return NULL;
|
|
return path_wad8;
|
|
}
|
|
|
|
//
|
|
// Return the WAD name for cmd-9
|
|
//
|
|
-(char *) getWAD9
|
|
{
|
|
if (!path_wad9[0])
|
|
return NULL;
|
|
return path_wad9;
|
|
}
|
|
|
|
//
|
|
// Return the WAD name for cmd-0
|
|
//
|
|
-(char *) getWAD0
|
|
{
|
|
if (!path_wad0[0])
|
|
return NULL;
|
|
return path_wad0;
|
|
}
|
|
|
|
//
|
|
// Return the FULLVIS cmd string
|
|
//
|
|
-(char *) getFullVisCmd
|
|
{
|
|
if (!string_fullvis[0])
|
|
return NULL;
|
|
return string_fullvis;
|
|
}
|
|
|
|
//
|
|
// Return the FASTVIS cmd string
|
|
//
|
|
-(char *) getFastVisCmd
|
|
{
|
|
if (!string_fastvis[0])
|
|
return NULL;
|
|
return string_fastvis;
|
|
}
|
|
|
|
//
|
|
// Return the NOVIS cmd string
|
|
//
|
|
-(char *) getNoVisCmd
|
|
{
|
|
if (!string_novis[0])
|
|
return NULL;
|
|
return string_novis;
|
|
}
|
|
|
|
//
|
|
// Return the RELIGHT cmd string
|
|
//
|
|
-(char *) getRelightCmd
|
|
{
|
|
if (!string_relight[0])
|
|
return NULL;
|
|
return string_relight;
|
|
}
|
|
|
|
//
|
|
// Return the LEAKTEST cmd string
|
|
//
|
|
-(char *) getLeaktestCmd
|
|
{
|
|
if (!string_leaktest[0])
|
|
return NULL;
|
|
return string_leaktest;
|
|
}
|
|
|
|
-(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)
|
|
{
|
|
int j;
|
|
|
|
for (j = 0; j < strlen (string); j++)
|
|
if (string[j] == cf)
|
|
string[j] = ct;
|
|
}
|