home *** CD-ROM | disk | FTP | other *** search
/ Deathday Collection / dday.bin / edit / gdr_doom / doom.cpp < prev    next >
Text File  |  1994-06-03  |  16KB  |  528 lines

  1. #include "doom.h"
  2. #include <io.h>
  3. #include <string.h>
  4. #include <stdio.h>
  5.  
  6. #define MAXREAD        32768L
  7.  
  8.  
  9. DoomVertexObject *        VertexPointer = NULL;
  10. DoomLineDefObject *        LineDefPointer = NULL;
  11. DoomThingObject *        ThingPointer = NULL;
  12. DoomSideDefObject *        SideDefPointer = NULL;
  13. DoomSectorObject *        SectorPointer = NULL;
  14.  
  15.  
  16. // ╔════════════════════════════════════════════════════════════════════════╗
  17. // ║                             lread/lwrite                               ║
  18. // ║                                                                        ║
  19. // ║ Read and write large blocks of data to and from the disk.              ║
  20. // ╚════════════════════════════════════════════════════════════════════════╝
  21.  
  22. DWORD lread (int FileHandle,VOID FAR * pv,DWORD ul)
  23. {
  24.     DWORD            ulT = ul;
  25.     char huge *        hp = (char *) pv;
  26.  
  27.     // This procedure allows reading in of huge amounts of data from a file.
  28.     while (ul > (DWORD) MAXREAD)
  29.     {
  30.         if (_lread (FileHandle,(LPSTR) hp,(WORD) MAXREAD) != MAXREAD)
  31.             return 0;
  32.         ul -= MAXREAD;
  33.         hp += MAXREAD;
  34.     }
  35.     
  36.     if (_lread (FileHandle,(LPSTR) hp,(WORD) ul) != (WORD) ul)
  37.         return 0;
  38.         
  39.     return ulT;
  40. }
  41.  
  42.  
  43. DWORD lwrite (int FileHandle,VOID FAR * pv,DWORD ul)
  44. {
  45.     DWORD     ulT = ul;
  46.     char huge *hp = (char *) pv;
  47.  
  48.     // This procedure allows writing out of huge amounts of data from a file.
  49.     while (ul > MAXREAD)
  50.     {
  51.         if (_lwrite (FileHandle,(LPSTR) hp,(WORD) MAXREAD) != MAXREAD)
  52.             return 0;
  53.         ul -= MAXREAD;
  54.         hp += MAXREAD;
  55.     }
  56.  
  57.     if (_lwrite (FileHandle,(LPSTR) hp,(WORD) ul) != (WORD) ul)
  58.         return 0;
  59.  
  60.     return ulT;
  61. }
  62.  
  63. // ╔════════════════════════════════════════════════════════════════════════╗
  64. // ║                             Base Class For Doom                        ║
  65. // ║                                                                        ║
  66. // ║ Using this base class allows us to read data from the file we do not   ║
  67. // ║ specifically understand. We can subclass from here to handle data      ║
  68. // ║ we are particularly interested in e.g. vertexes, linedefs.             ║
  69. // ╚════════════════════════════════════════════════════════════════════════╝
  70.  
  71. DoomObject::DoomObject ()
  72. {
  73.     // Zeroing our fields.
  74.     NoOfObjects = 0;
  75.     NoOfSpareObjects = 200;
  76.     MemHandle = NULL;
  77.     MemPointer = NULL;
  78. }
  79.  
  80.  
  81. DoomObject::~DoomObject ()
  82. {
  83.     GlobalUnlock (MemHandle);
  84.     GlobalFree (MemHandle);
  85. }
  86.  
  87.  
  88. DoomObject::DoomObject (int FileHandle,DirectoryEntry * Entry)
  89. {
  90.     // Zeroing our fields.
  91.     NoOfObjects = 0;
  92.     NoOfSpareObjects = 0;
  93.     MemHandle = NULL;
  94.     MemPointer = NULL;
  95.  
  96.     MemHandle = GlobalAlloc (GMEM_MOVEABLE,Entry->ResourceSize);
  97.     MemPointer = (char *) GlobalLock (MemHandle);
  98.     if (MemPointer)
  99.     {
  100.         lseek (FileHandle,Entry->ResourcePointer,SEEK_SET);
  101.         lread (FileHandle,MemPointer,Entry->ResourceSize);
  102.     }
  103. }
  104.  
  105.  
  106. void DoomObject::SaveObject (int FileHandle,DirectoryEntry * Entry)
  107. {
  108.     Entry->ResourcePointer = tell (FileHandle);
  109.     lwrite (FileHandle,MemPointer,Entry->ResourceSize);
  110. }
  111.  
  112. // ╔════════════════════════════════════════════════════════════════════════╗
  113. // ║                             Thing Class                                ║
  114. // ║                                                                        ║
  115. // ║ Add/edit/delete things.                                                ║
  116. // ╚════════════════════════════════════════════════════════════════════════╝
  117.  
  118. DoomThingObject::DoomThingObject ()
  119. {
  120.     // Load in the current resource and spare room for more.
  121.     MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (Thing) * long (NoOfSpareObjects));
  122.     MemPointer = (char *) GlobalLock (MemHandle);
  123.     Data = (Thing *) MemPointer;
  124.     ThingPointer = this;
  125. }
  126.  
  127.  
  128. DoomThingObject::DoomThingObject (int FileHandle,DirectoryEntry * Entry)
  129. {
  130.     // Load in the current resource and spare room for more.
  131.     NoOfObjects = int (Entry->ResourceSize / (long) sizeof (Thing));
  132.     MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (Thing) * long (NoOfObjects + NoOfSpareObjects));
  133.     MemPointer = (char *) GlobalLock (MemHandle);
  134.     if (MemPointer)
  135.     {
  136.         lseek (FileHandle,Entry->ResourcePointer,SEEK_SET);
  137.         lread (FileHandle,MemPointer,Entry->ResourceSize);
  138.     }
  139.  
  140.     Data = (Thing *) MemPointer;
  141.     ThingPointer = this;
  142. }
  143.  
  144.  
  145. void DoomThingObject::SaveObject (int FileHandle,DirectoryEntry * Entry)
  146. {
  147.     Entry->ResourcePointer = tell (FileHandle);
  148.     Entry->ResourceSize = (long) sizeof (Thing) * long (NoOfObjects);
  149.     lwrite (FileHandle,MemPointer,Entry->ResourceSize);
  150. }
  151.  
  152.  
  153. int DoomThingObject::Add (int EntryNo,int X,int Y)
  154. {
  155.     // Copy old entry if available.
  156.     if (EntryNo >= 0)
  157.         Data [NoOfObjects] = Data [EntryNo];
  158.     else
  159.     {
  160.         Data [NoOfObjects].Angle = 0;
  161.         Data [NoOfObjects].Type = 1;
  162.         Data [NoOfObjects].Bitset = 7;
  163.     }
  164.  
  165.     Data [NoOfObjects].X = X;
  166.     Data [NoOfObjects].Y = Y;
  167.     NoOfObjects++;
  168.     NoOfSpareObjects--;
  169.     
  170.     return NoOfObjects - 1;
  171. }
  172.  
  173.  
  174. void DoomThingObject::Delete (int EntryNo)
  175. {
  176.     if (EntryNo < NoOfObjects - 1)
  177.         Data [EntryNo] = Data [NoOfObjects - 1];
  178.     
  179.     NoOfObjects--;
  180.     NoOfSpareObjects++;
  181. }
  182.  
  183. // ╔════════════════════════════════════════════════════════════════════════╗
  184. // ║                             Vertex Class                               ║
  185. // ║                                                                        ║
  186. // ║ Allow use of vertex data.                                              ║
  187. // ╚════════════════════════════════════════════════════════════════════════╝
  188.  
  189. DoomVertexObject::DoomVertexObject ()
  190. {
  191.     // Load in the current resource and spare room for more.
  192.     MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (Vertex) * long (NoOfSpareObjects));
  193.     MemPointer = (char *) GlobalLock (MemHandle);
  194.     Data = (Vertex *) MemPointer;
  195.     VertexPointer = this;
  196. }
  197.  
  198.  
  199. DoomVertexObject::DoomVertexObject (int FileHandle,DirectoryEntry * Entry)
  200. {
  201.     // Load in the current resource and spare room for more.
  202.     NoOfObjects = int (Entry->ResourceSize / (long) sizeof (Vertex));
  203.     MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (Vertex) * long (NoOfObjects + NoOfSpareObjects));
  204.     MemPointer = (char *) GlobalLock (MemHandle);
  205.     if (MemPointer)
  206.     {
  207.         lseek (FileHandle,Entry->ResourcePointer,SEEK_SET);
  208.         lread (FileHandle,MemPointer,Entry->ResourceSize);
  209.     }
  210.  
  211.     Data = (Vertex *) MemPointer;
  212.     VertexPointer = this;
  213. }
  214.  
  215.  
  216. void DoomVertexObject::SaveObject (int FileHandle,DirectoryEntry * Entry)
  217. {
  218.     Entry->ResourcePointer = tell (FileHandle);
  219.     Entry->ResourceSize = (long) sizeof (Vertex) * long (NoOfObjects);
  220.     lwrite (FileHandle,MemPointer,Entry->ResourceSize);
  221. }
  222.  
  223.  
  224. int DoomVertexObject::Add (int X,int Y)
  225. {
  226.     // Create a new object.
  227.     Data [NoOfObjects].X = X;
  228.     Data [NoOfObjects].Y = Y;
  229.     NoOfObjects++;
  230.     NoOfSpareObjects--;
  231.     
  232.     return NoOfObjects - 1;
  233. }
  234.  
  235.  
  236. void DoomVertexObject::Delete (int EntryNo)
  237. {
  238.     int        Loop;
  239.     
  240.     // Now we delete our own entry.
  241.     if (EntryNo < NoOfObjects - 1)
  242.     {
  243.         // Copy end entry to the space in the array.
  244.         Data [EntryNo] = Data [NoOfObjects - 1];
  245.         
  246.         // Now update all references to the last vertex in the array.
  247.         for (Loop = 0;Loop < LineDefPointer->NoOfObjects;Loop++)
  248.         {
  249.             if (LineDefPointer->Data [Loop].FromVertex == NoOfObjects - 1)
  250.                 LineDefPointer->Data [Loop].FromVertex = EntryNo;
  251.             if (LineDefPointer->Data [Loop].ToVertex == NoOfObjects - 1)
  252.                 LineDefPointer->Data [Loop].ToVertex = EntryNo;
  253.         }
  254.     }
  255.     
  256.     NoOfObjects--;
  257.     NoOfSpareObjects++;
  258. }
  259.  
  260. // ╔════════════════════════════════════════════════════════════════════════╗
  261. // ║                           SideDef Class                                ║
  262. // ║                                                                        ║
  263. // ║                                                                        ║
  264. // ╚════════════════════════════════════════════════════════════════════════╝
  265.  
  266. DoomSideDefObject::DoomSideDefObject ()
  267. {
  268.     // Load in the current resource and spare room for more.
  269.     MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (SideDef) * long (NoOfSpareObjects));
  270.     MemPointer = (char *) GlobalLock (MemHandle);
  271.     Data = (SideDef *) MemPointer;
  272.     SideDefPointer = this;
  273. }
  274.  
  275.  
  276. DoomSideDefObject::DoomSideDefObject (int FileHandle,DirectoryEntry * Entry)
  277. {
  278.     // Load in the current resource and spare room for more.
  279.     NoOfObjects = int (Entry->ResourceSize / (long) sizeof (SideDef));
  280.     MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (SideDef) * long (NoOfObjects + NoOfSpareObjects));
  281.     MemPointer = (char *) GlobalLock (MemHandle);
  282.     if (MemPointer)
  283.     {
  284.         lseek (FileHandle,Entry->ResourcePointer,SEEK_SET);
  285.         lread (FileHandle,MemPointer,Entry->ResourceSize);
  286.     }
  287.  
  288.     Data = (SideDef *) MemPointer;
  289.     SideDefPointer = this;
  290. }
  291.  
  292.  
  293. void DoomSideDefObject::SaveObject (int FileHandle,DirectoryEntry * Entry)
  294. {
  295.     Entry->ResourcePointer = tell (FileHandle);
  296.     Entry->ResourceSize = (long) sizeof (SideDef) * long (NoOfObjects);
  297.     lwrite (FileHandle,MemPointer,Entry->ResourceSize);
  298. }
  299.  
  300.  
  301. int DoomSideDefObject::Add ()
  302. {
  303.     // Create a new object.
  304.     Data [NoOfObjects].X = 0;
  305.     Data [NoOfObjects].Y = 0;
  306.     strcpy (Data [NoOfObjects].Above,"-");
  307.     strcpy (Data [NoOfObjects].Below,"-");
  308.     strcpy (Data [NoOfObjects].Wall,"STARTAN3");
  309.     Data [NoOfObjects].Sector = -1;
  310.  
  311.     NoOfObjects++;
  312.     NoOfSpareObjects--;
  313.     
  314.     return NoOfObjects - 1;
  315. }
  316.  
  317.  
  318. void DoomSideDefObject::Delete (int EntryNo)
  319. {
  320.     int        Loop;
  321.     
  322.     // Remove all linedef references to this sidedef.
  323.     for (Loop = 0;Loop < LineDefPointer->NoOfObjects;Loop++)
  324.     {
  325.         if (LineDefPointer->Data [Loop].Sidedef1 == EntryNo)
  326.             LineDefPointer->Data [Loop].Sidedef1 = -1;
  327.         if (LineDefPointer->Data [Loop].Sidedef2 == EntryNo)
  328.             LineDefPointer->Data [Loop].Sidedef2 = -1;
  329.     }
  330.     
  331.     // Now we delete our own entry.
  332.     if (EntryNo < NoOfObjects - 1)
  333.     {
  334.         Data [EntryNo] = Data [NoOfObjects - 1];
  335.         for (Loop = 0;Loop < LineDefPointer->NoOfObjects;Loop++)
  336.         {
  337.             // Swap the end sidedef for the middle one.
  338.             if (LineDefPointer->Data [Loop].Sidedef1 == NoOfObjects - 1)
  339.                 LineDefPointer->Data [Loop].Sidedef1 = EntryNo;
  340.             if (LineDefPointer->Data [Loop].Sidedef2 == NoOfObjects - 1)
  341.                 LineDefPointer->Data [Loop].Sidedef2 = EntryNo;
  342.         }
  343.     }
  344.     
  345.     NoOfObjects--;
  346.     NoOfSpareObjects++;
  347. }
  348.  
  349. // ╔════════════════════════════════════════════════════════════════════════╗
  350. // ║                             LineDef Class                              ║
  351. // ║                                                                        ║
  352. // ║ Change the linedefs.                                                   ║
  353. // ╚════════════════════════════════════════════════════════════════════════╝
  354.  
  355. DoomLineDefObject::DoomLineDefObject ()
  356. {
  357.     // Load in the current resource and spare room for more.
  358.     MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (LineDef) * long (NoOfSpareObjects));
  359.     MemPointer = (char *) GlobalLock (MemHandle);
  360.     Data = (LineDef *) MemPointer;
  361.     LineDefPointer = this;
  362. }
  363.  
  364.  
  365. DoomLineDefObject::DoomLineDefObject (int FileHandle,DirectoryEntry * Entry)
  366. {
  367.     NoOfObjects = int (Entry->ResourceSize / (long) sizeof (LineDef));
  368.     MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (LineDef) * long (NoOfObjects + NoOfSpareObjects));
  369.     MemPointer = (char *) GlobalLock (MemHandle);
  370.     if (MemPointer)
  371.     {
  372.         lseek (FileHandle,Entry->ResourcePointer,SEEK_SET);
  373.         lread (FileHandle,MemPointer,Entry->ResourceSize);
  374.     }
  375.     
  376.     Data = (LineDef *) MemPointer;
  377.     LineDefPointer = this;
  378. }
  379.  
  380.  
  381. void DoomLineDefObject::SaveObject (int FileHandle,DirectoryEntry * Entry)
  382. {
  383.     Entry->ResourcePointer = tell (FileHandle);
  384.     Entry->ResourceSize = (long) sizeof (LineDef) * long (NoOfObjects);
  385.     lwrite (FileHandle,MemPointer,Entry->ResourceSize);
  386. }
  387.  
  388.  
  389. int DoomLineDefObject::Add (int FromVertex,int ToVertex)
  390. {
  391.     int        Loop;
  392.     
  393.     // If a linedef with these vertexes exists then skip the add.
  394.     for (Loop = 0;Loop < LineDefPointer->NoOfObjects;Loop++)
  395.     {
  396.         // Copy of line going the same way.
  397.         if (LineDefPointer->Data [Loop].FromVertex == FromVertex && LineDefPointer->Data [Loop].ToVertex == ToVertex)
  398.             return -1;
  399.             
  400.         // Copy of line going the other way.
  401.         if (LineDefPointer->Data [Loop].ToVertex == FromVertex && LineDefPointer->Data [Loop].FromVertex == ToVertex)
  402.             return -1;
  403.     }
  404.     
  405.     // Create a new object.
  406.     Data [NoOfObjects].FromVertex = FromVertex;
  407.     Data [NoOfObjects].ToVertex = ToVertex;
  408.     Data [NoOfObjects].Bitset = 1;
  409.     Data [NoOfObjects].Types = 0;
  410.     Data [NoOfObjects].Trigger = 0;
  411.     Data [NoOfObjects].Sidedef1 = SideDefPointer->Add ();
  412.     Data [NoOfObjects].Sidedef2 = -1;
  413.  
  414.     NoOfObjects++;
  415.     NoOfSpareObjects--;
  416.     
  417.     return NoOfObjects - 1;
  418. }
  419.  
  420.  
  421. void DoomLineDefObject::Delete (int EntryNo)
  422. {
  423.     // Delete the sidedefs.
  424.     SideDefPointer->Delete (LineDefPointer->Data [EntryNo].Sidedef1);
  425.     if (LineDefPointer->Data [EntryNo].Sidedef2 >= 0)
  426.         SideDefPointer->Delete (LineDefPointer->Data [EntryNo].Sidedef2);
  427.     
  428.     // Copy last entry to this entry to save it.
  429.     if (EntryNo < NoOfObjects - 1)
  430.         Data [EntryNo] = Data [NoOfObjects - 1];
  431.     
  432.     NoOfObjects--;
  433.     NoOfSpareObjects++;
  434. }
  435.  
  436. // ╔════════════════════════════════════════════════════════════════════════╗
  437. // ║                            Sector Class                                ║
  438. // ║                                                                        ║
  439. // ║                                                                        ║
  440. // ╚════════════════════════════════════════════════════════════════════════╝
  441.  
  442. DoomSectorObject::DoomSectorObject ()
  443. {
  444.     // Load in the current resource and spare room for more.
  445.     MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (Sector) * long (NoOfSpareObjects));
  446.     MemPointer = (char *) GlobalLock (MemHandle);
  447.     Data = (Sector *) MemPointer;
  448.     SectorPointer = this;
  449. }
  450.  
  451.  
  452. DoomSectorObject::DoomSectorObject (int FileHandle,DirectoryEntry * Entry)
  453. {
  454.     NoOfObjects = int (Entry->ResourceSize / (long) sizeof (Sector));
  455.     MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (Sector) * long (NoOfObjects + NoOfSpareObjects));
  456.     MemPointer = (char *) GlobalLock (MemHandle);
  457.     if (MemPointer)
  458.     {
  459.         lseek (FileHandle,Entry->ResourcePointer,SEEK_SET);
  460.         lread (FileHandle,MemPointer,Entry->ResourceSize);
  461.     }
  462.  
  463.     Data = (Sector *) MemPointer;
  464.     SectorPointer = this;
  465. }
  466.  
  467.  
  468. void DoomSectorObject::SaveObject (int FileHandle,DirectoryEntry * Entry)
  469. {
  470.     Entry->ResourcePointer = tell (FileHandle);
  471.     Entry->ResourceSize = (long) sizeof (Sector) * long (NoOfObjects);
  472.     lwrite (FileHandle,MemPointer,Entry->ResourceSize);
  473. }
  474.  
  475.  
  476. int DoomSectorObject::Add ()
  477. {
  478.     // Create a new object.
  479.     Data [NoOfObjects].FloorHeight = 0;
  480.     Data [NoOfObjects].CeilingHeight = 128;
  481.     Data [NoOfObjects].Brightness = 255;
  482.     Data [NoOfObjects].Special = 0;
  483.     Data [NoOfObjects].Trigger = 0;
  484.     strncpy (Data [NoOfObjects].FloorTexture,"FLOOR4_8",8);
  485.     strncpy (Data [NoOfObjects].CeilingTexture,"CEIL3_5",8);
  486.  
  487.     NoOfObjects++;
  488.     NoOfSpareObjects--;
  489.     
  490.     return NoOfObjects - 1;
  491. }
  492.  
  493.  
  494. void DoomSectorObject::Delete (int EntryNo)
  495. {
  496.     int        Loop;
  497.     
  498.     // Update the pointers to the sector.
  499.     for (Loop = 0;Loop < LineDefPointer->NoOfObjects;Loop++)
  500.     {
  501.         // Remove all right sidedefs with this as their sector.
  502.         if (SideDefPointer->Data [LineDefPointer->Data [Loop].Sidedef1].Sector == EntryNo)
  503.             SideDefPointer->Data [LineDefPointer->Data [Loop].Sidedef1].Sector = -1;
  504.  
  505.         // Remove all left sidedefs with this sector as theirs.
  506.         if (LineDefPointer->Data [Loop].Sidedef2 >= 0)
  507.             if (SideDefPointer->Data [LineDefPointer->Data [Loop].Sidedef2].Sector == EntryNo)
  508.                 SideDefPointer->Delete (LineDefPointer->Data [Loop].Sidedef2);
  509.     }
  510.  
  511.     // Copy bottom sector to the deleted entry if needed.
  512.     if (EntryNo < NoOfObjects - 1)
  513.     {
  514.         Data [EntryNo] = Data [NoOfObjects - 1];
  515.         for (Loop = 0;Loop < LineDefPointer->NoOfObjects;Loop++)
  516.         {
  517.             if (SideDefPointer->Data [LineDefPointer->Data [Loop].Sidedef1].Sector == NoOfObjects - 1)
  518.                 SideDefPointer->Data [LineDefPointer->Data [Loop].Sidedef1].Sector = EntryNo;
  519.             if (LineDefPointer->Data [Loop].Sidedef2 >= 0)
  520.                 if (SideDefPointer->Data [LineDefPointer->Data [Loop].Sidedef2].Sector == NoOfObjects - 1)
  521.                     SideDefPointer->Data [LineDefPointer->Data [Loop].Sidedef2].Sector = EntryNo;
  522.         }
  523.     }
  524.     
  525.     NoOfObjects--;
  526.     NoOfSpareObjects++;
  527. }
  528.