home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deathday Collection
/
dday.bin
/
edit
/
gdr_doom
/
doom.cpp
< prev
next >
Wrap
Text File
|
1994-06-03
|
16KB
|
528 lines
#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++;
}