home *** CD-ROM | disk | FTP | other *** search
- #include "doom.h"
- #include <io.h>
- #include <string.h>
- #include <stdio.h>
-
- #define MAXREAD 32768L
-
-
- DoomVertexObject * VertexPointer = NULL;
- DoomLineDefObject * LineDefPointer = NULL;
- DoomThingObject * ThingPointer = NULL;
- DoomSideDefObject * SideDefPointer = NULL;
- DoomSectorObject * SectorPointer = NULL;
-
-
- // ╔════════════════════════════════════════════════════════════════════════╗
- // ║ lread/lwrite ║
- // ║ ║
- // ║ Read and write large blocks of data to and from the disk. ║
- // ╚════════════════════════════════════════════════════════════════════════╝
-
- DWORD lread (int FileHandle,VOID FAR * pv,DWORD ul)
- {
- DWORD ulT = ul;
- char huge * hp = (char *) pv;
-
- // This procedure allows reading in of huge amounts of data from a file.
- while (ul > (DWORD) MAXREAD)
- {
- if (_lread (FileHandle,(LPSTR) hp,(WORD) MAXREAD) != MAXREAD)
- return 0;
- ul -= MAXREAD;
- hp += MAXREAD;
- }
-
- if (_lread (FileHandle,(LPSTR) hp,(WORD) ul) != (WORD) ul)
- return 0;
-
- return ulT;
- }
-
-
- DWORD lwrite (int FileHandle,VOID FAR * pv,DWORD ul)
- {
- DWORD ulT = ul;
- char huge *hp = (char *) pv;
-
- // This procedure allows writing out of huge amounts of data from a file.
- while (ul > MAXREAD)
- {
- if (_lwrite (FileHandle,(LPSTR) hp,(WORD) MAXREAD) != MAXREAD)
- return 0;
- ul -= MAXREAD;
- hp += MAXREAD;
- }
-
- if (_lwrite (FileHandle,(LPSTR) hp,(WORD) ul) != (WORD) ul)
- return 0;
-
- return ulT;
- }
-
- // ╔════════════════════════════════════════════════════════════════════════╗
- // ║ Base Class For Doom ║
- // ║ ║
- // ║ Using this base class allows us to read data from the file we do not ║
- // ║ specifically understand. We can subclass from here to handle data ║
- // ║ we are particularly interested in e.g. vertexes, linedefs. ║
- // ╚════════════════════════════════════════════════════════════════════════╝
-
- DoomObject::DoomObject ()
- {
- // Zeroing our fields.
- NoOfObjects = 0;
- NoOfSpareObjects = 200;
- MemHandle = NULL;
- MemPointer = NULL;
- }
-
-
- DoomObject::~DoomObject ()
- {
- GlobalUnlock (MemHandle);
- GlobalFree (MemHandle);
- }
-
-
- DoomObject::DoomObject (int FileHandle,DirectoryEntry * Entry)
- {
- // Zeroing our fields.
- NoOfObjects = 0;
- NoOfSpareObjects = 0;
- MemHandle = NULL;
- MemPointer = NULL;
-
- MemHandle = GlobalAlloc (GMEM_MOVEABLE,Entry->ResourceSize);
- MemPointer = (char *) GlobalLock (MemHandle);
- if (MemPointer)
- {
- lseek (FileHandle,Entry->ResourcePointer,SEEK_SET);
- lread (FileHandle,MemPointer,Entry->ResourceSize);
- }
- }
-
-
- void DoomObject::SaveObject (int FileHandle,DirectoryEntry * Entry)
- {
- Entry->ResourcePointer = tell (FileHandle);
- lwrite (FileHandle,MemPointer,Entry->ResourceSize);
- }
-
- // ╔════════════════════════════════════════════════════════════════════════╗
- // ║ Thing Class ║
- // ║ ║
- // ║ Add/edit/delete things. ║
- // ╚════════════════════════════════════════════════════════════════════════╝
-
- DoomThingObject::DoomThingObject ()
- {
- // Load in the current resource and spare room for more.
- MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (Thing) * long (NoOfSpareObjects));
- MemPointer = (char *) GlobalLock (MemHandle);
- Data = (Thing *) MemPointer;
- ThingPointer = this;
- }
-
-
- DoomThingObject::DoomThingObject (int FileHandle,DirectoryEntry * Entry)
- {
- // Load in the current resource and spare room for more.
- NoOfObjects = int (Entry->ResourceSize / (long) sizeof (Thing));
- MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (Thing) * long (NoOfObjects + NoOfSpareObjects));
- MemPointer = (char *) GlobalLock (MemHandle);
- if (MemPointer)
- {
- lseek (FileHandle,Entry->ResourcePointer,SEEK_SET);
- lread (FileHandle,MemPointer,Entry->ResourceSize);
- }
-
- Data = (Thing *) MemPointer;
- ThingPointer = this;
- }
-
-
- void DoomThingObject::SaveObject (int FileHandle,DirectoryEntry * Entry)
- {
- Entry->ResourcePointer = tell (FileHandle);
- Entry->ResourceSize = (long) sizeof (Thing) * long (NoOfObjects);
- lwrite (FileHandle,MemPointer,Entry->ResourceSize);
- }
-
-
- int DoomThingObject::Add (int EntryNo,int X,int Y)
- {
- // Copy old entry if available.
- if (EntryNo >= 0)
- Data [NoOfObjects] = Data [EntryNo];
- else
- {
- Data [NoOfObjects].Angle = 0;
- Data [NoOfObjects].Type = 1;
- Data [NoOfObjects].Bitset = 7;
- }
-
- Data [NoOfObjects].X = X;
- Data [NoOfObjects].Y = Y;
- NoOfObjects++;
- NoOfSpareObjects--;
-
- return NoOfObjects - 1;
- }
-
-
- void DoomThingObject::Delete (int EntryNo)
- {
- if (EntryNo < NoOfObjects - 1)
- Data [EntryNo] = Data [NoOfObjects - 1];
-
- NoOfObjects--;
- NoOfSpareObjects++;
- }
-
- // ╔════════════════════════════════════════════════════════════════════════╗
- // ║ Vertex Class ║
- // ║ ║
- // ║ Allow use of vertex data. ║
- // ╚════════════════════════════════════════════════════════════════════════╝
-
- DoomVertexObject::DoomVertexObject ()
- {
- // Load in the current resource and spare room for more.
- MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (Vertex) * long (NoOfSpareObjects));
- MemPointer = (char *) GlobalLock (MemHandle);
- Data = (Vertex *) MemPointer;
- VertexPointer = this;
- }
-
-
- DoomVertexObject::DoomVertexObject (int FileHandle,DirectoryEntry * Entry)
- {
- // Load in the current resource and spare room for more.
- NoOfObjects = int (Entry->ResourceSize / (long) sizeof (Vertex));
- MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (Vertex) * long (NoOfObjects + NoOfSpareObjects));
- MemPointer = (char *) GlobalLock (MemHandle);
- if (MemPointer)
- {
- lseek (FileHandle,Entry->ResourcePointer,SEEK_SET);
- lread (FileHandle,MemPointer,Entry->ResourceSize);
- }
-
- Data = (Vertex *) MemPointer;
- VertexPointer = this;
- }
-
-
- void DoomVertexObject::SaveObject (int FileHandle,DirectoryEntry * Entry)
- {
- Entry->ResourcePointer = tell (FileHandle);
- Entry->ResourceSize = (long) sizeof (Vertex) * long (NoOfObjects);
- lwrite (FileHandle,MemPointer,Entry->ResourceSize);
- }
-
-
- int DoomVertexObject::Add (int X,int Y)
- {
- // Create a new object.
- Data [NoOfObjects].X = X;
- Data [NoOfObjects].Y = Y;
- NoOfObjects++;
- NoOfSpareObjects--;
-
- return NoOfObjects - 1;
- }
-
-
- void DoomVertexObject::Delete (int EntryNo)
- {
- int Loop;
-
- // Now we delete our own entry.
- if (EntryNo < NoOfObjects - 1)
- {
- // Copy end entry to the space in the array.
- Data [EntryNo] = Data [NoOfObjects - 1];
-
- // Now update all references to the last vertex in the array.
- for (Loop = 0;Loop < LineDefPointer->NoOfObjects;Loop++)
- {
- if (LineDefPointer->Data [Loop].FromVertex == NoOfObjects - 1)
- LineDefPointer->Data [Loop].FromVertex = EntryNo;
- if (LineDefPointer->Data [Loop].ToVertex == NoOfObjects - 1)
- LineDefPointer->Data [Loop].ToVertex = EntryNo;
- }
- }
-
- NoOfObjects--;
- NoOfSpareObjects++;
- }
-
- // ╔════════════════════════════════════════════════════════════════════════╗
- // ║ SideDef Class ║
- // ║ ║
- // ║ ║
- // ╚════════════════════════════════════════════════════════════════════════╝
-
- DoomSideDefObject::DoomSideDefObject ()
- {
- // Load in the current resource and spare room for more.
- MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (SideDef) * long (NoOfSpareObjects));
- MemPointer = (char *) GlobalLock (MemHandle);
- Data = (SideDef *) MemPointer;
- SideDefPointer = this;
- }
-
-
- DoomSideDefObject::DoomSideDefObject (int FileHandle,DirectoryEntry * Entry)
- {
- // Load in the current resource and spare room for more.
- NoOfObjects = int (Entry->ResourceSize / (long) sizeof (SideDef));
- MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (SideDef) * long (NoOfObjects + NoOfSpareObjects));
- MemPointer = (char *) GlobalLock (MemHandle);
- if (MemPointer)
- {
- lseek (FileHandle,Entry->ResourcePointer,SEEK_SET);
- lread (FileHandle,MemPointer,Entry->ResourceSize);
- }
-
- Data = (SideDef *) MemPointer;
- SideDefPointer = this;
- }
-
-
- void DoomSideDefObject::SaveObject (int FileHandle,DirectoryEntry * Entry)
- {
- Entry->ResourcePointer = tell (FileHandle);
- Entry->ResourceSize = (long) sizeof (SideDef) * long (NoOfObjects);
- lwrite (FileHandle,MemPointer,Entry->ResourceSize);
- }
-
-
- int DoomSideDefObject::Add ()
- {
- // Create a new object.
- Data [NoOfObjects].X = 0;
- Data [NoOfObjects].Y = 0;
- strcpy (Data [NoOfObjects].Above,"-");
- strcpy (Data [NoOfObjects].Below,"-");
- strcpy (Data [NoOfObjects].Wall,"STARTAN3");
- Data [NoOfObjects].Sector = -1;
-
- NoOfObjects++;
- NoOfSpareObjects--;
-
- return NoOfObjects - 1;
- }
-
-
- void DoomSideDefObject::Delete (int EntryNo)
- {
- int Loop;
-
- // Remove all linedef references to this sidedef.
- for (Loop = 0;Loop < LineDefPointer->NoOfObjects;Loop++)
- {
- if (LineDefPointer->Data [Loop].Sidedef1 == EntryNo)
- LineDefPointer->Data [Loop].Sidedef1 = -1;
- if (LineDefPointer->Data [Loop].Sidedef2 == EntryNo)
- LineDefPointer->Data [Loop].Sidedef2 = -1;
- }
-
- // Now we delete our own entry.
- if (EntryNo < NoOfObjects - 1)
- {
- Data [EntryNo] = Data [NoOfObjects - 1];
- for (Loop = 0;Loop < LineDefPointer->NoOfObjects;Loop++)
- {
- // Swap the end sidedef for the middle one.
- if (LineDefPointer->Data [Loop].Sidedef1 == NoOfObjects - 1)
- LineDefPointer->Data [Loop].Sidedef1 = EntryNo;
- if (LineDefPointer->Data [Loop].Sidedef2 == NoOfObjects - 1)
- LineDefPointer->Data [Loop].Sidedef2 = EntryNo;
- }
- }
-
- NoOfObjects--;
- NoOfSpareObjects++;
- }
-
- // ╔════════════════════════════════════════════════════════════════════════╗
- // ║ LineDef Class ║
- // ║ ║
- // ║ Change the linedefs. ║
- // ╚════════════════════════════════════════════════════════════════════════╝
-
- DoomLineDefObject::DoomLineDefObject ()
- {
- // Load in the current resource and spare room for more.
- MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (LineDef) * long (NoOfSpareObjects));
- MemPointer = (char *) GlobalLock (MemHandle);
- Data = (LineDef *) MemPointer;
- LineDefPointer = this;
- }
-
-
- DoomLineDefObject::DoomLineDefObject (int FileHandle,DirectoryEntry * Entry)
- {
- NoOfObjects = int (Entry->ResourceSize / (long) sizeof (LineDef));
- MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (LineDef) * long (NoOfObjects + NoOfSpareObjects));
- MemPointer = (char *) GlobalLock (MemHandle);
- if (MemPointer)
- {
- lseek (FileHandle,Entry->ResourcePointer,SEEK_SET);
- lread (FileHandle,MemPointer,Entry->ResourceSize);
- }
-
- Data = (LineDef *) MemPointer;
- LineDefPointer = this;
- }
-
-
- void DoomLineDefObject::SaveObject (int FileHandle,DirectoryEntry * Entry)
- {
- Entry->ResourcePointer = tell (FileHandle);
- Entry->ResourceSize = (long) sizeof (LineDef) * long (NoOfObjects);
- lwrite (FileHandle,MemPointer,Entry->ResourceSize);
- }
-
-
- int DoomLineDefObject::Add (int FromVertex,int ToVertex)
- {
- int Loop;
-
- // If a linedef with these vertexes exists then skip the add.
- for (Loop = 0;Loop < LineDefPointer->NoOfObjects;Loop++)
- {
- // Copy of line going the same way.
- if (LineDefPointer->Data [Loop].FromVertex == FromVertex && LineDefPointer->Data [Loop].ToVertex == ToVertex)
- return -1;
-
- // Copy of line going the other way.
- if (LineDefPointer->Data [Loop].ToVertex == FromVertex && LineDefPointer->Data [Loop].FromVertex == ToVertex)
- return -1;
- }
-
- // Create a new object.
- Data [NoOfObjects].FromVertex = FromVertex;
- Data [NoOfObjects].ToVertex = ToVertex;
- Data [NoOfObjects].Bitset = 1;
- Data [NoOfObjects].Types = 0;
- Data [NoOfObjects].Trigger = 0;
- Data [NoOfObjects].Sidedef1 = SideDefPointer->Add ();
- Data [NoOfObjects].Sidedef2 = -1;
-
- NoOfObjects++;
- NoOfSpareObjects--;
-
- return NoOfObjects - 1;
- }
-
-
- void DoomLineDefObject::Delete (int EntryNo)
- {
- // Delete the sidedefs.
- SideDefPointer->Delete (LineDefPointer->Data [EntryNo].Sidedef1);
- if (LineDefPointer->Data [EntryNo].Sidedef2 >= 0)
- SideDefPointer->Delete (LineDefPointer->Data [EntryNo].Sidedef2);
-
- // Copy last entry to this entry to save it.
- if (EntryNo < NoOfObjects - 1)
- Data [EntryNo] = Data [NoOfObjects - 1];
-
- NoOfObjects--;
- NoOfSpareObjects++;
- }
-
- // ╔════════════════════════════════════════════════════════════════════════╗
- // ║ Sector Class ║
- // ║ ║
- // ║ ║
- // ╚════════════════════════════════════════════════════════════════════════╝
-
- DoomSectorObject::DoomSectorObject ()
- {
- // Load in the current resource and spare room for more.
- MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (Sector) * long (NoOfSpareObjects));
- MemPointer = (char *) GlobalLock (MemHandle);
- Data = (Sector *) MemPointer;
- SectorPointer = this;
- }
-
-
- DoomSectorObject::DoomSectorObject (int FileHandle,DirectoryEntry * Entry)
- {
- NoOfObjects = int (Entry->ResourceSize / (long) sizeof (Sector));
- MemHandle = GlobalAlloc (GMEM_MOVEABLE,(long) sizeof (Sector) * long (NoOfObjects + NoOfSpareObjects));
- MemPointer = (char *) GlobalLock (MemHandle);
- if (MemPointer)
- {
- lseek (FileHandle,Entry->ResourcePointer,SEEK_SET);
- lread (FileHandle,MemPointer,Entry->ResourceSize);
- }
-
- Data = (Sector *) MemPointer;
- SectorPointer = this;
- }
-
-
- void DoomSectorObject::SaveObject (int FileHandle,DirectoryEntry * Entry)
- {
- Entry->ResourcePointer = tell (FileHandle);
- Entry->ResourceSize = (long) sizeof (Sector) * long (NoOfObjects);
- lwrite (FileHandle,MemPointer,Entry->ResourceSize);
- }
-
-
- int DoomSectorObject::Add ()
- {
- // Create a new object.
- Data [NoOfObjects].FloorHeight = 0;
- Data [NoOfObjects].CeilingHeight = 128;
- Data [NoOfObjects].Brightness = 255;
- Data [NoOfObjects].Special = 0;
- Data [NoOfObjects].Trigger = 0;
- strncpy (Data [NoOfObjects].FloorTexture,"FLOOR4_8",8);
- strncpy (Data [NoOfObjects].CeilingTexture,"CEIL3_5",8);
-
- NoOfObjects++;
- NoOfSpareObjects--;
-
- return NoOfObjects - 1;
- }
-
-
- void DoomSectorObject::Delete (int EntryNo)
- {
- int Loop;
-
- // Update the pointers to the sector.
- for (Loop = 0;Loop < LineDefPointer->NoOfObjects;Loop++)
- {
- // Remove all right sidedefs with this as their sector.
- if (SideDefPointer->Data [LineDefPointer->Data [Loop].Sidedef1].Sector == EntryNo)
- SideDefPointer->Data [LineDefPointer->Data [Loop].Sidedef1].Sector = -1;
-
- // Remove all left sidedefs with this sector as theirs.
- if (LineDefPointer->Data [Loop].Sidedef2 >= 0)
- if (SideDefPointer->Data [LineDefPointer->Data [Loop].Sidedef2].Sector == EntryNo)
- SideDefPointer->Delete (LineDefPointer->Data [Loop].Sidedef2);
- }
-
- // Copy bottom sector to the deleted entry if needed.
- if (EntryNo < NoOfObjects - 1)
- {
- Data [EntryNo] = Data [NoOfObjects - 1];
- for (Loop = 0;Loop < LineDefPointer->NoOfObjects;Loop++)
- {
- if (SideDefPointer->Data [LineDefPointer->Data [Loop].Sidedef1].Sector == NoOfObjects - 1)
- SideDefPointer->Data [LineDefPointer->Data [Loop].Sidedef1].Sector = EntryNo;
- if (LineDefPointer->Data [Loop].Sidedef2 >= 0)
- if (SideDefPointer->Data [LineDefPointer->Data [Loop].Sidedef2].Sector == NoOfObjects - 1)
- SideDefPointer->Data [LineDefPointer->Data [Loop].Sidedef2].Sector = EntryNo;
- }
- }
-
- NoOfObjects--;
- NoOfSpareObjects++;
- }