#include "doom.h" #include #include #include #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++; }