home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Doom I/II Collection
/
DM12.ISO
/
edit
/
dhtk100
/
maps.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1994-05-26
|
9KB
|
273 lines
{****************************************************************************
* The DOOM Hacker's Tool Kit *
*****************************************************************************
* Unit: MAPS *
* Purpose: Loading and displaying the Maps from the WAD File *
* Date: 4/28/94 *
* Author: Joshua Jackson Internet: joshjackson@delphi.com *
****************************************************************************}
{$O+,F+}
unit Maps;
interface
uses Wad,WadDecl,DOOMGUI,GUIObj;
type PWadMapViewer=^TWadMapViewer;
TWadMapViewer=TGraphGroup;
PWadMap=^TWadMap;
TWadMap=Object(TGraphView)
LevelEntries:PLevelEntries;
ThingList :PThingList;
VertexList :PVertexList;
LineDefList :PLineDefList;
ViewerMask :word;
ThingMask :word;
ScaleInc,XOffset,YOffset:word;
Constructor Init(WDir:PWadDirectory;LevelName:ObjNameStr);
Procedure Draw; virtual;
Procedure SetScale(NewScaleInc,NewXOffset,NewYOffset:word);
Function GetThingInArea(x1,y1,x2,y2:word):word;
Destructor Done; virtual;
end;
implementation
uses crt,graph;
Function OnSkillLevel(Attr,ViewerMask:word):boolean;
var TempAttr:word;
begin
TempAttr:=(ViewerMask and 64);
if (TempAttr=0) and ((Attr and 16) = 16) then begin
OnSkillLevel:=False;
exit;
end;
TempAttr:=(ViewerMask and 56) shr 3;
if (TempAttr and (Attr and 7)) = TempAttr then
OnSkillLevel:=True
else
OnSkillLevel:=False;
end;
Constructor TWadMap.Init(WDir:PWadDirectory;LevelName:ObjNameStr);
var Entry,LevelPos:word;
R:TGraphRect;
begin
Owner:=Nil;
Next:=Nil;
ScaleInc:=1;
XOffset:=0;
YOffset:=0;
R.Assign(0,0,639,479);
Bounds:=R;
New(LevelEntries);
LevelPos:=WDir^.FindObject(LevelName);
if LevelPos=0 then begin
writeln('TWapMap_Init: Invalid Level Name ',LevelName);
halt;
end;
LevelEntries^.MapID:=WDir^.DirEntry^[LevelPos];
LevelEntries^.Things:=WDir^.DirEntry^[LevelPos+1];
LevelEntries^.LineDefs:=WDir^.DirEntry^[LevelPos+2];
LevelEntries^.SideDefs:=WDir^.DirEntry^[LevelPos+3];
LevelEntries^.Vertexes:=WDir^.DirEntry^[LevelPos+4];
LevelEntries^.Segs:=WDir^.DirEntry^[LevelPos+5];
LevelEntries^.SSectors:=WDir^.DirEntry^[LevelPos+6];
LevelEntries^.Nodes:=WDir^.DirEntry^[LevelPos+7];
LevelEntries^.Sectors:=WDir^.DirEntry^[LevelPos+8];
LevelEntries^.Reject:=WDir^.DirEntry^[LevelPos+9];
LevelEntries^.BlockMap:=WDir^.DirEntry^[LevelPos+10];
GetMem(ThingList,LevelEntries^.Things.ObjLength);
Seek(WDir^.WadFile,LevelEntries^.Things.ObjStart);
BlockRead(WDir^.WadFile,ThingList^,LevelEntries^.Things.ObjLength);
GetMem(VertexList,LevelEntries^.Vertexes.ObjLength);
Seek(WDir^.WadFile,LevelEntries^.Vertexes.ObjStart);
BlockRead(WDir^.WadFile,VertexList^,LevelEntries^.Vertexes.ObjLength);
GetMem(LineDefList,LevelEntries^.LineDefs.ObjLength);
Seek(WDir^.WadFile,LevelEntries^.LineDefs.ObjStart);
BlockRead(WDir^.WadFile,LineDefList^,LevelEntries^.LineDefs.ObjLength);
end;
Procedure TWadMap.Draw;
var MidX,MidY,MaxX,MaxY,MinX,MinY:integer;
ScaleX,ScaleY,Scale:real;
IntScale:Longint;
x,y,NumThings,NumLines,gd,gm,t:integer;
ch,SkillLevel:Char;
TempStr:String;
TT:word;
SubView:PGraphView;
begin
MinX:=32000;
MinY:=32000;
MaxX:=-32000;
MaxY:=-32000;
for t:=0 to ((LevelEntries^.Vertexes.ObjLength div 4) -1) do begin
if VertexList^[t].x < MinX then
MinX:=VertexList^[t].x;
if VertexList^[t].x > MaxX then
MaxX:=VertexList^[t].x;
if VertexList^[t].y < MinY then
MinY:=VertexList^[t].y;
if VertexList^[t].y > Maxy then
MaxY:=VertexList^[t].y;
end;
MidX:=(MinX+MaxX) div 2;
MidY:=(MinY+MaxY) div 2;
SkillLevel:=' ';
ScaleX:=(320 / (MaxX - MidX)) * 0.90;
ScaleY:=(240 / (MaxY - MidY)) * 0.90;
if ScaleX < ScaleY then
Scale:=ScaleX
else
Scale:=ScaleY;
Scale:=Scale * ScaleInc;
IntScale:=Round(Scale * 65536);
NumLines:=((LevelEntries^.LineDefs.ObjLength div 14) - 1);
for t:=0 to NumLines do begin
SetColor(wcBlue);
case LineDefList^[t].LineDefType of
1,26..28,31..34:SetColor(wcLtBlue); {Doors}
end;
if ((LineDefList^[t].Attributes and 32) = 32) and ((ViewerMask and 128)=128) then
SetColor(wcLtGrey);
x:=(((VertexList^[LineDefList^[t].StartVertex].x-MidX) * IntScale div 65536) + 320)+(XOffset * ScaleInc);
y:=(((VertexList^[LineDefList^[t].StartVertex].Y-MidY) * (-IntScale) div 65536) + 240)+(YOffset * ScaleInc);
MoveTo(x,y);
x:=(((VertexList^[LineDefList^[t].EndVertex].x-MidX) * IntScale div 65536) + 320)+(XOffset * ScaleInc);
y:=(((VertexList^[LineDefList^[t].EndVertex].Y-MidY) * (-IntScale) div 65536) + 240)+(YOffset * ScaleInc);
LineTo(x,y);
end;
NumThings:=((LevelEntries^.Things.ObjLength div 10) -1);
for t:=0 to NumThings do begin
x:=(((ThingList^[t].x-MidX) * IntScale div 65536)+320)+(XOffset * ScaleInc);
y:=(((ThingList^[t].y-MidY) * (-IntScale) div 65536)+240)+(YOffset * ScaleInc);
SetColor(wcRed);
TT:=ThingList^[t].ThingType;
if (ThingMask=0) or (TT=ThingMask) then begin
if OnSkillLevel(ThingList^[t].Attributes,ViewerMask) then begin
if (ViewerMask and 1) = 1 then {Monsters}
if (TT=$7) or (TT=$9) or (TT=$10) or (TT=$3A) or ((TT > $BB8) and (TT<$BBF)) then begin
SetColor(wcRed);
Circle(x,y,ScaleInc);
end;
if (ViewerMask and 2) = 2 then begin {Goodies}
if (TT=$5) or (TT=$6) or (TT=$8) or (TT=$d) or (TT=$26) or (TT=$27) then begin
SetColor(wcLtGreen);
Circle(x,y,ScaleInc);
end;
if ((TT>$7D6) and (TT<$7EB)) or ((TT>$7FC) and (TT<$802)) then begin
SetColor(wcLtGreen);
Circle(x,y,ScaleInc);
end;
end;
if (ViewerMask and 4) = 4 then {Weapons}
if (TT > $7D0) and (TT<$7D7) then begin
SetColor(wcYellow);
Circle(x,y,ScaleInc);
end;
end;
end;
end;
OutTextXY(560,1,LevelEntries^.MapID.ObjName);
str(ScaleInc,TempStr);
OutTextXY(1,465,'Scale: '+TempStr+'x');
end;
Procedure TWadMap.SetScale(NewScaleInc,NewXOffset,NewYOffset:word);
begin
ScaleInc:=NewScaleInc;
XOffset:=NewXOffset;
YOffset:=NewYOffset;
end;
Function TWadMap.GetThingInArea(x1,y1,x2,y2:word):word;
var MidX,MidY,MaxX,MaxY,MinX,MinY:integer;
ScaleX,ScaleY,Scale:real;
IntScale:Longint;
x,y,NumThings,NumLines,gd,gm,t:integer;
ch,SkillLevel:Char;
TT:word;
begin
MinX:=32000;
MinY:=32000;
MaxX:=-32000;
MaxY:=-32000;
for t:=0 to ((LevelEntries^.Vertexes.ObjLength div 4) -1) do begin
if VertexList^[t].x < MinX then
MinX:=VertexList^[t].x;
if VertexList^[t].x > MaxX then
MaxX:=VertexList^[t].x;
if VertexList^[t].y < MinY then
MinY:=VertexList^[t].y;
if VertexList^[t].y > Maxy then
MaxY:=VertexList^[t].y;
end;
MidX:=(MinX+MaxX) div 2;
MidY:=(MinY+MaxY) div 2;
SkillLevel:=' ';
ScaleX:=(320 / (MaxX - MidX)) * 0.90;
ScaleY:=(240 / (MaxY - MidY)) * 0.90;
if ScaleX < ScaleY then
Scale:=ScaleX
else
Scale:=ScaleY;
Scale:=Scale * ScaleInc;
IntScale:=Round(Scale * 65536);
NumThings:=((LevelEntries^.Things.ObjLength div 10) -1);
for t:=0 to NumThings do begin
x:=(((ThingList^[t].x-MidX) * IntScale div 65536)+320)+(XOffset * ScaleInc);
y:=(((ThingList^[t].y-MidY) * (-IntScale) div 65536)+240)+(YOffset * ScaleInc);
if ((x >= x1) and (x <= x2)) and ((y >= y1) and (y <= y2)) then begin
TT:=ThingList^[t].ThingType;
if (ThingMask=0) or (TT=ThingMask) then begin
if (ViewerMask and 1) = 1 then {Monsters}
if (TT=$7) or (TT=$9) or (TT=$10) or (TT=$3A) or ((TT > $BB8) and (TT<$BBF)) then begin
GetThingInArea:=TT;
exit;
end;
if (ViewerMask and 2) = 2 then begin {Goodies}
if (TT=$5) or (TT=$6) or (TT=$8) or (TT=$d) or (TT=$26) or (TT=$27) then begin
GetThingInArea:=TT;
exit;
end;
if ((TT>$7D6) and (TT<$7EB)) or ((TT>$7FC) and (TT<$802)) then begin
GetThingInArea:=TT;
exit;
end;
end;
if (ViewerMask and 4) = 4 then {Weapons}
if (TT > $7D0) and (TT<$7D7) then begin
GetThingInArea:=TT;
exit;
end;
end;
end;
end;
GetThingInArea:=0;
end;
Destructor TWadMap.Done;
var TempView,SubView:PGraphView;
begin
FreeMem(ThingList,LevelEntries^.Things.ObjLength);
FreeMem(VertexList,LevelEntries^.Vertexes.ObjLength);
FreeMem(LineDefList,LevelEntries^.LineDefs.ObjLength);
Dispose(LevelEntries);
end;
end.