GM.C 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
  12. */
  13. /*
  14. * $Source: f:/miner/source/main/rcs/gamemine.c $
  15. * $Revision: 1.45 $
  16. * $Author: john $
  17. * $Date: 1994/10/27 18:51:42 $
  18. *
  19. * Functions for loading mines in the game
  20. *
  21. * $Log: gamemine.c $
  22. * Revision 1.45 1994/10/27 18:51:42 john
  23. * Added -piglet option that only loads needed textures for a
  24. * mine. Only saved ~1MB, and code still doesn't free textures
  25. * before you load a new mine.
  26. *
  27. * Revision 1.44 1994/10/20 12:47:22 matt
  28. * Replace old save files (MIN/SAV/HOT) with new LVL files
  29. *
  30. * Revision 1.43 1994/10/19 16:46:40 matt
  31. * Made tmap overrides for robots remap texture numbers
  32. *
  33. * Revision 1.42 1994/10/03 23:37:01 mike
  34. * Adapt to changed fuelcen_activate parameters.
  35. *
  36. * Revision 1.41 1994/09/23 22:14:49 matt
  37. * Took out obsolete structure fields
  38. *
  39. * Revision 1.40 1994/08/01 11:04:11 yuan
  40. * New materialization centers.
  41. *
  42. * Revision 1.39 1994/07/21 19:01:47 mike
  43. * Call Lsegment stuff.
  44. *
  45. *
  46. */
  47. #pragma off (unreferenced)
  48. static char rcsid[] = "$Id: gamemine.c 1.45 1994/10/27 18:51:42 john Exp $";
  49. #pragma on (unreferenced)
  50. #include <stdio.h>
  51. #include <stdlib.h>
  52. #include <math.h>
  53. #include <string.h>
  54. #include "mono.h"
  55. #include "inferno.h"
  56. #include "segment.h"
  57. #include "textures.h"
  58. #include "wall.h"
  59. #include "object.h"
  60. #include "gamemine.h"
  61. #include "error.h"
  62. #include "gameseg.h"
  63. #include "switch.h"
  64. #include "game.h"
  65. #ifdef EDITOR
  66. #include "editor\editor.h"
  67. #include "ui.h"
  68. #endif
  69. #include "nocfile.h"
  70. #include "fuelcen.h"
  71. #include "hash.h"
  72. #include "key.h"
  73. #include "piggy.h"
  74. //Structures for old mine versions
  75. #define V15_MAX_VERTICES_PER_SEGMENT 8
  76. #define V15_MAX_SIDES_PER_SEGMENT 6
  77. typedef struct v15_side {
  78. byte type; // replaces num_faces and tri_edge, 1 = quad, 2 = 0:2 triangulation, 3 = 1:3 triangulation
  79. short tmap_num;
  80. short tmap_num2;
  81. uvl uvls[4];
  82. short wall_num;
  83. vms_vector normals[2]; // 2 normals, if quadrilateral, both the same.
  84. } v15_side;
  85. typedef struct v15_segment {
  86. short segnum; // segment number, not sure what it means
  87. v15_side sides[V15_MAX_SIDES_PER_SEGMENT]; // 6 sides
  88. short children[V15_MAX_SIDES_PER_SEGMENT]; // indices of 6 children segments, front, left, top, right, bottom, back
  89. short verts[V15_MAX_VERTICES_PER_SEGMENT]; // vertex ids of 4 front and 4 back vertices
  90. short group; // group number to which the segment belongs.
  91. short objects; // pointer to objects in this segment
  92. short special; // special property of a segment (such as damaging, trigger, etc.)
  93. short value;
  94. } v15_segment;
  95. typedef struct {
  96. int num_segments;
  97. int num_vertices;
  98. short segments[MAX_SEGMENTS];
  99. short vertices[MAX_VERTICES];
  100. } v15_group;
  101. //End of old structures
  102. #define REMOVE_EXT(s) (*(strchr( (s), '.' ))='\0')
  103. struct mtfi mine_top_fileinfo; // Should be same as first two fields below...
  104. struct mfi mine_fileinfo;
  105. struct mh mine_header;
  106. struct me mine_editor;
  107. int CreateDefaultNewSegment();
  108. static char old_tmap_list[MAX_TEXTURES][13];
  109. short tmap_xlate_table[MAX_TEXTURES];
  110. static short tmap_times_used[MAX_TEXTURES];
  111. //void JohnError( char * s )
  112. //{
  113. // Int3();
  114. //}
  115. // -----------------------------------------------------------------------------
  116. // returns 1 if error, else 0
  117. int game_load_mine(char * filename)
  118. {
  119. CFILE * LoadFile;
  120. LoadFile = cfopen( filename, CF_READ_MODE );
  121. if (!LoadFile)
  122. {
  123. #ifdef EDITOR
  124. char ErrorMessage[200];
  125. sprintf( ErrorMessage, "ERROR: Unable to open mine %s\n", filename );
  126. stop_time();
  127. MessageBox( -2, -2, 1, ErrorMessage, "Ok" );
  128. start_time();
  129. #endif
  130. return 1;
  131. }
  132. load_mine_data(LoadFile);
  133. cfclose( LoadFile );
  134. return 0;
  135. }
  136. // -----------------------------------------------------------------------------
  137. //loads from an already-open file
  138. // returns 0=everything ok, 1=old version, -1=error
  139. int load_mine_data(CFILE *LoadFile)
  140. {
  141. int i, j;
  142. short tmap_xlate;
  143. int translate;
  144. char *temptr;
  145. int mine_start = cftell(LoadFile);
  146. fuelcen_reset();
  147. for (i=0; i<MAX_TEXTURES; i++ )
  148. tmap_times_used[i] = 0;
  149. #ifdef EDITOR
  150. // Create a new mine to initialize things.
  151. //texpage_goto_first();
  152. create_new_mine();
  153. #endif
  154. //===================== READ FILE INFO ========================
  155. // These are the default values... version and fileinfo_sizeof
  156. // don't have defaults.
  157. mine_fileinfo.header_offset = -1;
  158. mine_fileinfo.header_size = sizeof(mine_header);
  159. mine_fileinfo.editor_offset = -1;
  160. mine_fileinfo.editor_size = sizeof(mine_editor);
  161. mine_fileinfo.vertex_offset = -1;
  162. mine_fileinfo.vertex_howmany = 0;
  163. mine_fileinfo.vertex_sizeof = sizeof(vms_vector);
  164. mine_fileinfo.segment_offset = -1;
  165. mine_fileinfo.segment_howmany = 0;
  166. mine_fileinfo.segment_sizeof = sizeof(segment);
  167. mine_fileinfo.newseg_verts_offset = -1;
  168. mine_fileinfo.newseg_verts_howmany = 0;
  169. mine_fileinfo.newseg_verts_sizeof = sizeof(vms_vector);
  170. mine_fileinfo.group_offset = -1;
  171. mine_fileinfo.group_howmany = 0;
  172. mine_fileinfo.group_sizeof = sizeof(group);
  173. mine_fileinfo.texture_offset = -1;
  174. mine_fileinfo.texture_howmany = 0;
  175. mine_fileinfo.texture_sizeof = 13; // num characters in a name
  176. mine_fileinfo.walls_offset = -1;
  177. mine_fileinfo.walls_howmany = 0;
  178. mine_fileinfo.walls_sizeof = sizeof(wall);
  179. mine_fileinfo.triggers_offset = -1;
  180. mine_fileinfo.triggers_howmany = 0;
  181. mine_fileinfo.triggers_sizeof = sizeof(trigger);
  182. mine_fileinfo.object_offset = -1;
  183. mine_fileinfo.object_howmany = 1;
  184. mine_fileinfo.object_sizeof = sizeof(object);
  185. // Read in mine_top_fileinfo to get size of saved fileinfo.
  186. memset( &mine_top_fileinfo, 0, sizeof(mine_top_fileinfo) );
  187. if (cfseek( LoadFile, mine_start, SEEK_SET ))
  188. Error( "Error moving to top of file in gamemine.c" );
  189. if (cfread( &mine_top_fileinfo, sizeof(mine_top_fileinfo), 1, LoadFile )!=1)
  190. Error( "Error reading mine_top_fileinfo in gamemine.c" );
  191. if (mine_top_fileinfo.fileinfo_signature != 0x2884)
  192. return -1;
  193. // Check version number
  194. if (mine_top_fileinfo.fileinfo_version < COMPATIBLE_VERSION )
  195. return -1;
  196. // Now, Read in the fileinfo
  197. if (cfseek( LoadFile, mine_start, SEEK_SET ))
  198. Error( "Error seeking to top of file in gamemine.c" );
  199. if (cfread( &mine_fileinfo, mine_top_fileinfo.fileinfo_sizeof, 1, LoadFile )!=1)
  200. Error( "Error reading mine_fileinfo in gamemine.c" );
  201. //===================== READ HEADER INFO ========================
  202. // Set default values.
  203. mine_header.num_vertices = 0;
  204. mine_header.num_segments = 0;
  205. if (mine_fileinfo.header_offset > -1 )
  206. {
  207. if (cfseek( LoadFile, mine_fileinfo.header_offset, SEEK_SET ))
  208. Error( "Error seeking to header_offset in gamemine.c" );
  209. if (cfread( &mine_header, mine_fileinfo.header_size, 1, LoadFile )!=1)
  210. Error( "Error reading mine_header in gamemine.c" );
  211. }
  212. //===================== READ EDITOR INFO ==========================
  213. // Set default values
  214. mine_editor.current_seg = 0;
  215. mine_editor.newsegment_offset = -1; // To be written
  216. mine_editor.newsegment_size = sizeof(segment);
  217. mine_editor.Curside = 0;
  218. mine_editor.Markedsegp = -1;
  219. mine_editor.Markedside = 0;
  220. if (mine_fileinfo.editor_offset > -1 )
  221. {
  222. if (cfseek( LoadFile, mine_fileinfo.editor_offset, SEEK_SET ))
  223. Error( "Error seeking to editor_offset in gamemine.c" );
  224. if (cfread( &mine_editor, mine_fileinfo.editor_size, 1, LoadFile )!=1)
  225. Error( "Error reading mine_editor in gamemine.c" );
  226. }
  227. //===================== READ TEXTURE INFO ==========================
  228. if ( (mine_fileinfo.texture_offset > -1) && (mine_fileinfo.texture_howmany > 0))
  229. {
  230. if (cfseek( LoadFile, mine_fileinfo.texture_offset, SEEK_SET ))
  231. Error( "Error seeking to texture_offset in gamemine.c" );
  232. for (i=0; i< mine_fileinfo.texture_howmany; i++ )
  233. {
  234. if (cfread( &old_tmap_list[i], mine_fileinfo.texture_sizeof, 1, LoadFile )!=1)
  235. Error( "Error reading old_tmap_list[i] in gamemine.c" );
  236. }
  237. }
  238. //=============== GENERATE TEXTURE TRANSLATION TABLE ===============
  239. translate = 0;
  240. Assert (NumTextures < MAX_TEXTURES);
  241. {
  242. hashtable ht;
  243. hashtable_init( &ht, NumTextures );
  244. // Remove all the file extensions in the textures list
  245. for (i=0;i<NumTextures;i++) {
  246. temptr = strchr(TmapInfo[i].filename, '.');
  247. if (temptr) *temptr = '\0';
  248. hashtable_insert( &ht, TmapInfo[i].filename, i );
  249. }
  250. // For every texture, search through the texture list
  251. // to find a matching name.
  252. for (j=0;j<mine_fileinfo.texture_howmany;j++) {
  253. // Remove this texture name's extension
  254. temptr = strchr(old_tmap_list[j], '.');
  255. if (temptr) *temptr = '\0';
  256. tmap_xlate_table[j] = hashtable_search( &ht,old_tmap_list[j]);
  257. if (tmap_xlate_table[j] < 0 ) {
  258. tmap_xlate_table[j] = 0;
  259. mprintf( 0, "Couldn't find texture '%s'\n", old_tmap_list[j] );
  260. }
  261. if (tmap_xlate_table[j] != j ) translate = 1;
  262. tmap_times_used[tmap_xlate_table[j]]++;
  263. }
  264. {
  265. int count = 0;
  266. for (i=0; i<MAX_TEXTURES; i++ )
  267. if (tmap_times_used[i])
  268. count++;
  269. mprintf( 0, "This mine has %d unique textures in it (~%.2f MB)\n", count, ((float)(count*4096))/(1024.0*1024.0) );
  270. }
  271. mprintf( 0, "Translate=%d\n", translate );
  272. hashtable_free( &ht );
  273. }
  274. //====================== READ VERTEX INFO ==========================
  275. // New check added to make sure we don't read in too many vertices.
  276. if ( mine_fileinfo.vertex_howmany > MAX_VERTICES )
  277. {
  278. mprintf(0, "Num vertices exceeds maximum. Loading MAX %d vertices\n", MAX_VERTICES);
  279. mine_fileinfo.vertex_howmany = MAX_VERTICES;
  280. }
  281. if ( (mine_fileinfo.vertex_offset > -1) && (mine_fileinfo.vertex_howmany > 0))
  282. {
  283. if (cfseek( LoadFile, mine_fileinfo.vertex_offset, SEEK_SET ))
  284. Error( "Error seeking to vertex_offset in gamemine.c" );
  285. for (i=0; i< mine_fileinfo.vertex_howmany; i++ )
  286. {
  287. // Set the default values for this vertex
  288. Vertices[i].x = 1;
  289. Vertices[i].y = 1;
  290. Vertices[i].z = 1;
  291. if (cfread( &Vertices[i], mine_fileinfo.vertex_sizeof, 1, LoadFile )!=1)
  292. Error( "Error reading Vertices[i] in gamemine.c" );
  293. }
  294. }
  295. //==================== READ SEGMENT INFO ===========================
  296. // New check added to make sure we don't read in too many segments.
  297. if ( mine_fileinfo.segment_howmany > MAX_SEGMENTS ) {
  298. mprintf(0, "Num segments exceeds maximum. Loading MAX %d segments\n", MAX_SEGMENTS);
  299. mine_fileinfo.segment_howmany = MAX_SEGMENTS;
  300. }
  301. fuelcen_reset();
  302. if ( (mine_fileinfo.segment_offset > -1) && (mine_fileinfo.segment_howmany > 0)) {
  303. if (cfseek( LoadFile, mine_fileinfo.segment_offset,SEEK_SET ))
  304. Error( "Error seeking to segment_offset in gamemine.c" );
  305. for (i=0; i< mine_fileinfo.segment_howmany; i++ ) {
  306. segment v16_seg;
  307. v15_segment v15_seg;
  308. // Set the default values for this segment (clear to zero )
  309. //memset( &Segments[i], 0, sizeof(segment) );
  310. if (mine_top_fileinfo.fileinfo_version >= 16) {
  311. Assert(mine_fileinfo.segment_sizeof == sizeof(v16_seg));
  312. if (cfread( &v16_seg, mine_fileinfo.segment_sizeof, 1, LoadFile )!=1)
  313. Error( "Error reading segments in gamemine.c" );
  314. }
  315. else if (mine_top_fileinfo.fileinfo_version < 16) {
  316. int t;
  317. Assert(mine_fileinfo.segment_sizeof == sizeof(v15_seg));
  318. if (cfread( &v15_seg, mine_fileinfo.segment_sizeof, 1, LoadFile )!=1)
  319. Error( "Error reading segments in gamemine.c" );
  320. v16_seg.segnum = v15_seg.segnum;
  321. v16_seg.group = v15_seg.group;
  322. v16_seg.objects = v15_seg.objects;
  323. v16_seg.special = v15_seg.special;
  324. v16_seg.value = v15_seg.value;
  325. for (t=0;t<MAX_SIDES_PER_SEGMENT;t++) {
  326. int n;
  327. v16_seg.children[t] = v15_seg.children[t];
  328. v16_seg.sides[t].type = v15_seg.sides[t].type;
  329. v16_seg.sides[t].wall_num = v15_seg.sides[t].wall_num;
  330. v16_seg.sides[t].tmap_num = v15_seg.sides[t].tmap_num;
  331. v16_seg.sides[t].tmap_num2 = v15_seg.sides[t].tmap_num2;
  332. v16_seg.sides[t].pad = 0;
  333. for (n=0;n<4;n++)
  334. v16_seg.sides[t].uvls[n] = v15_seg.sides[t].uvls[n];
  335. for (n=0;n<2;n++)
  336. v16_seg.sides[t].normals[n] = v15_seg.sides[t].normals[n];
  337. }
  338. for (t=0;t<MAX_VERTICES_PER_SEGMENT;t++)
  339. v16_seg.verts[t] = v15_seg.verts[t];
  340. v16_seg.static_light = 0;
  341. }
  342. Segments[i] = v16_seg;
  343. Segments[i].objects = -1;
  344. Segments[i].group = -1;
  345. if (mine_top_fileinfo.fileinfo_version < 15) { //used old uvl ranges
  346. int sn,uvln;
  347. for (sn=0;sn<MAX_SIDES_PER_SEGMENT;sn++)
  348. for (uvln=0;uvln<4;uvln++) {
  349. Segments[i].sides[sn].uvls[uvln].u /= 64;
  350. Segments[i].sides[sn].uvls[uvln].v /= 64;
  351. Segments[i].sides[sn].uvls[uvln].l /= 32;
  352. }
  353. }
  354. fuelcen_activate( &Segments[i], Segments[i].special );
  355. if (translate == 1)
  356. for (j=0;j<MAX_SIDES_PER_SEGMENT;j++) {
  357. unsigned short orient;
  358. tmap_xlate = Segments[i].sides[j].tmap_num;
  359. Segments[i].sides[j].tmap_num = tmap_xlate_table[tmap_xlate];
  360. tmap_xlate = Segments[i].sides[j].tmap_num2 & 0x3FFF;
  361. orient = Segments[i].sides[j].tmap_num2 & (~0x3FFF);
  362. if (tmap_xlate != 0)
  363. Segments[i].sides[j].tmap_num2 = tmap_xlate_table[tmap_xlate] | orient;
  364. }
  365. }
  366. }
  367. //===================== READ NEWSEGMENT INFO =====================
  368. #ifdef EDITOR
  369. { // Default segment created.
  370. vms_vector sizevec;
  371. med_create_new_segment(vm_vec_make(&sizevec,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE)); // New_segment = Segments[0];
  372. //memset( &New_segment, 0, sizeof(segment) );
  373. }
  374. if (mine_editor.newsegment_offset > -1)
  375. {
  376. if (cfseek( LoadFile, mine_editor.newsegment_offset,SEEK_SET ))
  377. Error( "Error seeking to newsegment_offset in gamemine.c" );
  378. if (cfread( &New_segment, mine_editor.newsegment_size,1,LoadFile )!=1)
  379. Error( "Error reading new_segment in gamemine.c" );
  380. }
  381. if ( (mine_fileinfo.newseg_verts_offset > -1) && (mine_fileinfo.newseg_verts_howmany > 0))
  382. {
  383. if (cfseek( LoadFile, mine_fileinfo.newseg_verts_offset, SEEK_SET ))
  384. Error( "Error seeking to newseg_verts_offset in gamemine.c" );
  385. for (i=0; i< mine_fileinfo.newseg_verts_howmany; i++ )
  386. {
  387. // Set the default values for this vertex
  388. Vertices[NEW_SEGMENT_VERTICES+i].x = 1;
  389. Vertices[NEW_SEGMENT_VERTICES+i].y = 1;
  390. Vertices[NEW_SEGMENT_VERTICES+i].z = 1;
  391. if (cfread( &Vertices[NEW_SEGMENT_VERTICES+i], mine_fileinfo.newseg_verts_sizeof,1,LoadFile )!=1)
  392. Error( "Error reading Vertices[NEW_SEGMENT_VERTICES+i] in gamemine.c" );
  393. New_segment.verts[i] = NEW_SEGMENT_VERTICES+i;
  394. }
  395. }
  396. #endif
  397. //========================= UPDATE VARIABLES ======================
  398. #ifdef EDITOR
  399. // Setting to Markedsegp to NULL ignores Curside and Markedside, which
  400. // we want to do when reading in an old file.
  401. Markedside = mine_editor.Markedside;
  402. Curside = mine_editor.Curside;
  403. for (i=0;i<10;i++)
  404. Groupside[i] = mine_editor.Groupside[i];
  405. if ( mine_editor.current_seg != -1 )
  406. Cursegp = mine_editor.current_seg + Segments;
  407. else
  408. Cursegp = NULL;
  409. if (mine_editor.Markedsegp != -1 )
  410. Markedsegp = mine_editor.Markedsegp + Segments;
  411. else
  412. Markedsegp = NULL;
  413. num_groups = 0;
  414. current_group = -1;
  415. #endif
  416. Num_vertices = mine_fileinfo.vertex_howmany;
  417. Num_segments = mine_fileinfo.segment_howmany;
  418. Highest_vertex_index = Num_vertices-1;
  419. Highest_segment_index = Num_segments-1;
  420. reset_objects(1); //one object, the player
  421. #ifdef EDITOR
  422. Highest_vertex_index = MAX_SEGMENT_VERTICES-1;
  423. Highest_segment_index = MAX_SEGMENTS-1;
  424. set_vertex_counts();
  425. Highest_vertex_index = Num_vertices-1;
  426. Highest_segment_index = Num_segments-1;
  427. warn_if_concave_segments();
  428. #endif
  429. #ifdef EDITOR
  430. med_validate_segment_all();
  431. #endif
  432. create_local_segment_data();
  433. gamemine_find_textures();
  434. if (mine_top_fileinfo.fileinfo_version < MINE_VERSION )
  435. return 1; //old version
  436. else
  437. return 0;
  438. }
  439. ubyte texcount[MAX_TEXTURES];
  440. void gamemine_find_textures()
  441. {
  442. int s, sn;
  443. int unique = 0;
  444. memset( texcount, 0, MAX_TEXTURES );
  445. for (s=0; s<=Highest_segment_index; s++) {
  446. if (Segments[s].segnum != -1) {
  447. for (sn=0;sn<MAX_SIDES_PER_SEGMENT;sn++) {
  448. //if (Segments[s].sides[sn].wall_num > -1 ) {
  449. // mprintf( 0, "Segment %d, side %d has wall_num %d\n", s, sn, Segments[s].sides[sn].wall_num );
  450. //}
  451. if (Segments[s].sides[sn].tmap_num>-1) {
  452. //mprintf( 0, "Segment %d, side %d has tmap_num %d\n", s, sn, Segments[s].sides[sn].tmap_num );
  453. if (!texcount[Segments[s].sides[sn].tmap_num]) {
  454. piggy_read_bitmap_data(Textures[Segments[s].sides[sn].tmap_num]);
  455. unique++;
  456. }
  457. texcount[Segments[s].sides[sn].tmap_num]++;
  458. }
  459. if ((Segments[s].sides[sn].tmap_num2 & 0x3FFF)>0) {
  460. //mprintf( 0, "Segment %d, side %d has tmap_num2 %d\n", s, sn, Segments[s].sides[sn].tmap_num2 & 0x3FFF );
  461. if (!texcount[Segments[s].sides[sn].tmap_num2&0x3FFF]) {
  462. piggy_read_bitmap_data(Textures[Segments[s].sides[sn].tmap_num2&0x3FFF]);
  463. unique++;
  464. }
  465. texcount[Segments[s].sides[sn].tmap_num2&0x3FFF]++;
  466. }
  467. }
  468. }
  469. }
  470. //mprintf( 0, "Mine used %d textures\n", unique );
  471. }