Project.m 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. //======================================
  2. //
  3. // QuakeEd Project Management
  4. //
  5. //======================================
  6. #import "qedefs.h"
  7. id project_i;
  8. @implementation Project
  9. - init
  10. {
  11. project_i = self;
  12. return self;
  13. }
  14. //===========================================================
  15. //
  16. // Project code
  17. //
  18. //===========================================================
  19. - initVars
  20. {
  21. char *s;
  22. s = [preferences_i getProjectPath];
  23. StripFilename(s);
  24. strcpy(path_basepath,s);
  25. strcpy(path_progdir,s);
  26. strcat(path_progdir,"/"SUBDIR_ENT);
  27. strcpy(path_mapdirectory,s);
  28. strcat(path_mapdirectory,"/"SUBDIR_MAPS); // source dir
  29. strcpy(path_finalmapdir,s);
  30. strcat(path_finalmapdir,"/"SUBDIR_MAPS); // dest dir
  31. [basepathinfo_i setStringValue:s]; // in Project Inspector
  32. #if 0
  33. if ((s = [projectInfo getStringFor:BASEPATHKEY]))
  34. {
  35. strcpy(path_basepath,s);
  36. strcpy(path_progdir,s);
  37. strcat(path_progdir,"/"SUBDIR_ENT);
  38. strcpy(path_mapdirectory,s);
  39. strcat(path_mapdirectory,"/"SUBDIR_MAPS); // source dir
  40. strcpy(path_finalmapdir,s);
  41. strcat(path_finalmapdir,"/"SUBDIR_MAPS); // dest dir
  42. [basepathinfo_i setStringValue:s]; // in Project Inspector
  43. }
  44. #endif
  45. if ((s = [projectInfo getStringFor:BSPFULLVIS]))
  46. {
  47. strcpy(string_fullvis,s);
  48. changeString('@','\"',string_fullvis);
  49. }
  50. if ((s = [projectInfo getStringFor:BSPFASTVIS]))
  51. {
  52. strcpy(string_fastvis,s);
  53. changeString('@','\"',string_fastvis);
  54. }
  55. if ((s = [projectInfo getStringFor:BSPNOVIS]))
  56. {
  57. strcpy(string_novis,s);
  58. changeString('@','\"',string_novis);
  59. }
  60. if ((s = [projectInfo getStringFor:BSPRELIGHT]))
  61. {
  62. strcpy(string_relight,s);
  63. changeString('@','\"',string_relight);
  64. }
  65. if ((s = [projectInfo getStringFor:BSPLEAKTEST]))
  66. {
  67. strcpy(string_leaktest,s);
  68. changeString('@','\"',string_leaktest);
  69. }
  70. if ((s = [projectInfo getStringFor:BSPENTITIES]))
  71. {
  72. strcpy(string_entities,s);
  73. changeString('@','\"', string_entities);
  74. }
  75. // Build list of wads
  76. wadList = [projectInfo parseMultipleFrom:WADSKEY];
  77. // Build list of maps & descriptions
  78. mapList = [projectInfo parseMultipleFrom:MAPNAMESKEY];
  79. descList = [projectInfo parseMultipleFrom:DESCKEY];
  80. [self changeChar:'_' to:' ' in:descList];
  81. [self initProjSettings];
  82. return self;
  83. }
  84. //
  85. // Init Project Settings fields
  86. //
  87. - initProjSettings
  88. {
  89. [pis_basepath_i setStringValue:path_basepath];
  90. [pis_fullvis_i setStringValue:string_fullvis];
  91. [pis_fastvis_i setStringValue:string_fastvis];
  92. [pis_novis_i setStringValue:string_novis];
  93. [pis_relight_i setStringValue:string_relight];
  94. [pis_leaktest_i setStringValue:string_leaktest];
  95. return self;
  96. }
  97. //
  98. // Add text to the BSP Output window
  99. //
  100. - addToOutput:(char *)string
  101. {
  102. int end;
  103. end = [BSPoutput_i textLength];
  104. [BSPoutput_i setSel:end :end];
  105. [BSPoutput_i replaceSel:string];
  106. end = [BSPoutput_i textLength];
  107. [BSPoutput_i setSel:end :end];
  108. [BSPoutput_i scrollSelToVisible];
  109. return self;
  110. }
  111. - clearBspOutput:sender
  112. {
  113. [BSPoutput_i selectAll:self];
  114. [BSPoutput_i replaceSel:"\0"];
  115. return self;
  116. }
  117. - print
  118. {
  119. [BSPoutput_i printPSCode:self];
  120. return self;
  121. }
  122. - initProject
  123. {
  124. [self parseProjectFile];
  125. if (projectInfo == NULL)
  126. return self;
  127. [self initVars];
  128. [mapbrowse_i reuseColumns:YES];
  129. [mapbrowse_i loadColumnZero];
  130. [pis_wads_i reuseColumns:YES];
  131. [pis_wads_i loadColumnZero];
  132. [things_i initEntities];
  133. return self;
  134. }
  135. //
  136. // Change a character to another in a Storage list of strings
  137. //
  138. - changeChar:(char)f to:(char)t in:(id)obj
  139. {
  140. int i;
  141. int max;
  142. char *string;
  143. max = [obj count];
  144. for (i = 0;i < max;i++)
  145. {
  146. string = [obj elementAt:i];
  147. changeString(f,t,string);
  148. }
  149. return self;
  150. }
  151. //
  152. // Fill the QuakeEd Maps or wads browser
  153. // (Delegate method - delegated in Interface Builder)
  154. //
  155. - (int)browser:sender fillMatrix:matrix inColumn:(int)column
  156. {
  157. id cell, list;
  158. int max;
  159. char *name;
  160. int i;
  161. if (sender == mapbrowse_i)
  162. list = mapList;
  163. else if (sender == pis_wads_i)
  164. list = wadList;
  165. else
  166. {
  167. list = nil;
  168. Error ("Project: unknown browser to fill");
  169. }
  170. max = [list count];
  171. for (i = 0 ; i<max ; i++)
  172. {
  173. name = [list elementAt:i];
  174. [matrix addRow];
  175. cell = [matrix cellAt:i :0];
  176. [cell setStringValue:name];
  177. [cell setLeaf:YES];
  178. [cell setLoaded:YES];
  179. }
  180. return i;
  181. }
  182. //
  183. // Clicked on a map name or description!
  184. //
  185. - clickedOnMap:sender
  186. {
  187. id matrix;
  188. int row;
  189. char fname[1024];
  190. id panel;
  191. matrix = [sender matrixInColumn:0];
  192. row = [matrix selectedRow];
  193. sprintf(fname,"%s/%s.map",path_mapdirectory,
  194. (char *)[mapList elementAt:row]);
  195. panel = NXGetAlertPanel("Loading...",
  196. "Loading map. Please wait.",NULL,NULL,NULL);
  197. [panel orderFront:NULL];
  198. [quakeed_i doOpen:fname];
  199. [panel performClose:NULL];
  200. NXFreeAlertPanel(panel);
  201. return self;
  202. }
  203. - setTextureWad: (char *)wf
  204. {
  205. int i, c;
  206. char *name;
  207. qprintf ("loading %s", wf);
  208. // set the row in the settings inspector wad browser
  209. c = [wadList count];
  210. for (i=0 ; i<c ; i++)
  211. {
  212. name = (char *)[wadList elementAt:i];
  213. if (!strcmp(name, wf))
  214. {
  215. [[pis_wads_i matrixInColumn:0] selectCellAt: i : 0];
  216. break;
  217. }
  218. }
  219. // update the texture inspector
  220. [texturepalette_i initPaletteFromWadfile:wf ];
  221. [[map_i objectAt: 0] setKey:"wad" toValue: wf];
  222. // [inspcontrol_i changeInspectorTo:i_textures];
  223. [quakeed_i updateAll];
  224. return self;
  225. }
  226. //
  227. // Clicked on a wad name
  228. //
  229. - clickedOnWad:sender
  230. {
  231. id matrix;
  232. int row;
  233. char *name;
  234. matrix = [sender matrixInColumn:0];
  235. row = [matrix selectedRow];
  236. name = (char *)[wadList elementAt:row];
  237. [self setTextureWad: name];
  238. return self;
  239. }
  240. //
  241. // Read in the <name>.QE_Project file
  242. //
  243. - parseProjectFile
  244. {
  245. char *path;
  246. int rtn;
  247. path = [preferences_i getProjectPath];
  248. if (!path || !path[0] || access(path,0))
  249. {
  250. rtn = NXRunAlertPanel("Project Error!",
  251. "A default project has not been found.\n"
  252. , "Open Project", NULL, NULL);
  253. if ([self openProject] == nil)
  254. while (1) // can't run without a project
  255. [NXApp terminate: self];
  256. return self;
  257. }
  258. [self openProjectFile:path];
  259. return self;
  260. }
  261. //
  262. // Loads and parses a project file
  263. //
  264. - openProjectFile:(char *)path
  265. {
  266. FILE *fp;
  267. struct stat s;
  268. strcpy(path_projectinfo,path);
  269. projectInfo = NULL;
  270. fp = fopen(path,"r+t");
  271. if (fp == NULL)
  272. return self;
  273. stat(path,&s);
  274. lastModified = s.st_mtime;
  275. projectInfo = [(Dict *)[Dict alloc] initFromFile:fp];
  276. fclose(fp);
  277. return self;
  278. }
  279. - (char *)currentProjectFile
  280. {
  281. return path_projectinfo;
  282. }
  283. //
  284. // Open a project file
  285. //
  286. - openProject
  287. {
  288. char path[128];
  289. id openpanel;
  290. int rtn;
  291. char *projtypes[2] = {"qpr",NULL};
  292. char **filenames;
  293. char *dir;
  294. openpanel = [OpenPanel new];
  295. [openpanel allowMultipleFiles:NO];
  296. [openpanel chooseDirectories:NO];
  297. rtn = [openpanel runModalForTypes:projtypes];
  298. if (rtn == NX_OKTAG)
  299. {
  300. (const char *const *)filenames = [openpanel filenames];
  301. dir = (char *)[openpanel directory];
  302. sprintf(path,"%s/%s",dir,filenames[0]);
  303. strcpy(path_projectinfo,path);
  304. [self openProjectFile:path];
  305. return self;
  306. }
  307. return nil;
  308. }
  309. //
  310. // Search for a string in a List of strings
  311. //
  312. - (int)searchForString:(char *)str in:(id)obj
  313. {
  314. int i;
  315. int max;
  316. char *s;
  317. max = [obj count];
  318. for (i = 0;i < max; i++)
  319. {
  320. s = (char *)[obj elementAt:i];
  321. if (!strcmp(s,str))
  322. return 1;
  323. }
  324. return 0;
  325. }
  326. - (char *)getMapDirectory
  327. {
  328. return path_mapdirectory;
  329. }
  330. - (char *)getFinalMapDirectory
  331. {
  332. return path_finalmapdir;
  333. }
  334. - (char *)getProgDirectory
  335. {
  336. return path_progdir;
  337. }
  338. //
  339. // Return the WAD name for cmd-8
  340. //
  341. - (char *)getWAD8
  342. {
  343. if (!path_wad8[0])
  344. return NULL;
  345. return path_wad8;
  346. }
  347. //
  348. // Return the WAD name for cmd-9
  349. //
  350. - (char *)getWAD9
  351. {
  352. if (!path_wad9[0])
  353. return NULL;
  354. return path_wad9;
  355. }
  356. //
  357. // Return the WAD name for cmd-0
  358. //
  359. - (char *)getWAD0
  360. {
  361. if (!path_wad0[0])
  362. return NULL;
  363. return path_wad0;
  364. }
  365. //
  366. // Return the FULLVIS cmd string
  367. //
  368. - (char *)getFullVisCmd
  369. {
  370. if (!string_fullvis[0])
  371. return NULL;
  372. return string_fullvis;
  373. }
  374. //
  375. // Return the FASTVIS cmd string
  376. //
  377. - (char *)getFastVisCmd
  378. {
  379. if (!string_fastvis[0])
  380. return NULL;
  381. return string_fastvis;
  382. }
  383. //
  384. // Return the NOVIS cmd string
  385. //
  386. - (char *)getNoVisCmd
  387. {
  388. if (!string_novis[0])
  389. return NULL;
  390. return string_novis;
  391. }
  392. //
  393. // Return the RELIGHT cmd string
  394. //
  395. - (char *)getRelightCmd
  396. {
  397. if (!string_relight[0])
  398. return NULL;
  399. return string_relight;
  400. }
  401. //
  402. // Return the LEAKTEST cmd string
  403. //
  404. - (char *)getLeaktestCmd
  405. {
  406. if (!string_leaktest[0])
  407. return NULL;
  408. return string_leaktest;
  409. }
  410. - (char *)getEntitiesCmd
  411. {
  412. if (!string_entities[0])
  413. return NULL;
  414. return string_entities;
  415. }
  416. @end
  417. //====================================================
  418. // C Functions
  419. //====================================================
  420. //
  421. // Change a character to a different char in a string
  422. //
  423. void changeString(char cf,char ct,char *string)
  424. {
  425. int j;
  426. for (j = 0;j < strlen(string);j++)
  427. if (string[j] == cf)
  428. string[j] = ct;
  429. }