📄 dedewpjalf.pas
字号:
unit DeDeWpjAlf;
///////////////////////////////////////////////////////
// Win32DASM WPJ and ALF files editing
//
// This unit has been coded to be used with DeDe 2.40
//
// (c) 2000 DaFixer
///////////////////////////////////////////////////////
interface
uses Classes, DeDeConstants;
Type DWORD = LongWord;
const sCopyrightString = #13#10'Including DeDe '+GlobsCurrDeDeVersion+' references (c) DaFixer '#13#10;
WPJ_MAGIC1 = $00455845;
WPJ_MAGIC2 = $00657865;
DATA_MAGIC = 2.51930465558271833E93;
DATA_MAGIC1 = $35002C2C;
DATA_MAGIC2 = $53535300;
DELTA_OFFSET = $63;
Color_R_BLK = $01; // normal = Red && selection = Black
Color_B_BLK = $02; // normal = Blue && selection = Black
Color_R_B = $03; // normal = Red && selection = Blue
Color_DB_BLK = $04; // normal = DarkBlue && selection = Black
Color_R_DB = $05; // normal = Red && selection = DarkBlue
Color_G_BLK = $08; // normal = Green && selection = Black
Color_R_G = $09; // normal = Red && selection = Green
Type TWPJColorRec = Packed Record
LineNum : DWORD;
Color : Word;
Size : Byte;
End;
Type TWPJALF = Class (TObject)
private
protected
procedure ReadHeader;
procedure ReadWPJData;
procedure LoadALFListing;
public
WPJ, ALF : TMemoryStream;
dwLineNum, dwColorNum, dwPEP, dwNewPEP : DWORD;
LineDataPos, EndLineDataPos, ColorPos, EndColorPos, SizePos : DWORD;
LinesData : Array of Byte;
ColorData : Array of TWPJColorRec;
sTargetName : String;
Listing : TStringList;
ReffStrings : TStringList;
constructor Create;
destructor Destroy; override;
function OpenWPJFile(sWPJFileName : String) : boolean;
procedure NewReferences;
procedure AddRefference(dwRVA : String; color : Word; sReference : String = 'Should be passed by increasing order of RVA');
procedure SaveCopy(sWPJFileName : String);
End;
implementation
uses SysUtils, HexTools;
{ TWPJALF }
procedure TWPJALF.AddRefference(dwRVA: String; color: Word;
sReference: String);
var s : String;
begin
// dont add trash
if dwRVA='' then Exit;
if dwRVA='00000000' then Exit;
sReference:=sReference+#13#10;
while length(dwRVA)<8 do dwRVA:='0'+dwRVA;
s:=IntToStr(color);
while length(s)<2 do s:='0'+s;
s:=Copy(s,1,2);
s:=dwRVA+s+sReference;
If ReffStrings.IndexOf(s)=-1 then ReffStrings.Add(s);
end;
constructor TWPJALF.Create;
begin
Inherited Create;
WPJ:=TMemoryStream.Create;
ALF:=TMemoryStream.Create;
Listing:=TStringList.Create;
ReffStrings:=TStringList.Create;
end;
destructor TWPJALF.Destroy;
begin
ReffStrings.Free;
Listing.Free;
if ALF<>nil then ALF.Free;
if WPJ<>nil then WPJ.Free;
Inherited Destroy;
end;
procedure TWPJALF.LoadALFListing;
var s : String;
b : Byte;
cnt : Cardinal;
begin
Listing.Clear;
ALF.Seek(0,soFromBeginning);
cnt:=0;
b:=LinesData[cnt]+2;
SetLength(s,b);
ALF.ReadBuffer(s[1],b);
Listing.Add(s);
Inc(cnt);
b:=LinesData[cnt]+2;
SetLength(s,b);
ALF.ReadBuffer(s[1],b);
Listing.Add(s);
Inc(cnt);
Repeat
b:=LinesData[cnt]+2;
SetLength(s,b);
ALF.ReadBuffer(s[1],b);
Listing.Add(s);
Inc(cnt);
Until (ALF.Position>=ALF.Size) or (cnt>dwLineNum);
end;
procedure TWPJALF.NewReferences;
begin
ReffStrings.Clear;
end;
function TWPJALF.OpenWPJFile(sWPJFileName: String) : Boolean;
var b : Byte;
s : String;
begin
if alf=nil then alf:=TMemoryStream.Create;
WPJ.LoadFromFile(sWPJFileName);
ALF.LoadFromFile(ChangeFileExt(sWPJFileName,'.alf'));
repeat
ALF.ReadBuffer(b,1);
until b=10;
SetLength(s,14);
ALF.ReadBuffer(s[1],14);
if s='Including DeDe' then
begin
alf.free;
alf:=nil;
result:=False;
exit;
end;
ReadHeader;
ReadWPJData;
LoadALFListing;
Result:=True;
end;
procedure TWPJALF.ReadHeader;
var dw : DWORD;
w : WORD;
begin
WPJ.Seek(0,soFromBeginning);
WPJ.ReadBuffer(dw,4);
if (DW<>WPJ_MAGIC1)
and (DW<>WPJ_MAGIC2) then Raise Exception.Create('Invalid WPJ File');
WPJ.ReadBuffer(w,2);
SetLength(sTargetName,w);
WPJ.Seek(2,soFromCurrent);
WPJ.ReadBuffer(sTargetName[1],w);
SizePos:=WPJ.Position;
WPJ.ReadBuffer(dwLineNum,4);
SetLength(LinesData,dwLineNum);
WPJ.Seek(4,soFromCurrent);
WPJ.ReadBuffer(dwPEP,4);
end;
procedure TWPJALF.ReadWPJData;
var ext : DWORD;
bt : Byte;
i,n : DWORD;
ColRec : TWPJColorRec;
bkupPos : DWORD;
begin
// Seek the magic
Repeat
Repeat
WPJ.ReadBuffer(ext,4);
WPJ.Seek(-3,soFromCurrent);
Until (ext=DATA_MAGIC1) or (WPJ.Position+4>=WPJ.Size);
WPJ.Seek(3,soFromCurrent);
WPJ.ReadBuffer(ext,4);
WPJ.Seek(-4,soFromCurrent);
Until (ext=DATA_MAGIC2) or (WPJ.Position+4>=WPJ.Size);
WPJ.Seek(-3,soFromCurrent);
// find the beginning
WPJ.Seek(-2,soFromCurrent);
LineDataPos:=WPJ.Position;
// Read line Info
For i:=1 To dwLineNum Do
WPJ.ReadBuffer(LinesData[i-1],1);
EndLineDataPos:=WPJ.Position;
// find the beginning
Repeat
WPJ.ReadBuffer(bt,1);
Until bt=0;
// find the beginning
Repeat
WPJ.ReadBuffer(bt,1);
Until bt<>0;
WPJ.Seek(-1,soFromCurrent);
// enum color data
bkupPos:=WPJ.Position;
ColorPos:=bkupPos;
n:=0;
Repeat
WPJ.ReadBuffer(ColRec.LineNum,4);
WPJ.ReadBuffer(ColRec.Color,2);
WPJ.ReadBuffer(ColRec.Size,1);
Inc(n);
Until ColRec.LineNum+ColRec.Color+ColRec.Size=0;
// Read color data
Dec(n,2);
dwColorNum:=n+1;
SetLength(ColorData,dwColorNum);
WPJ.Seek(bkupPos,soFromBeginning);
For i:=0 to n do
begin
WPJ.ReadBuffer(ColRec.LineNum,4);
WPJ.ReadBuffer(ColRec.Color,2);
WPJ.ReadBuffer(ColRec.Size,1);
ColorData[i]:=ColRec;
end;
EndColorPos:=WPJ.Position;
end;
procedure TWPJALF.SaveCopy(sWPJFileName: String);
var i, iCol : Integer;
s, rva, rva1, sline : String;
color : Word;
delta_lines,cnt, boza, dw : DWORD;
Colors, LineData : TMemoryStream;
wpj1, alf1 : TFileStream;
ColDTA : TWPJColorRec;
bt : Byte;
procedure GetRVACol(var s : String);
begin
rva:=copy(s,1,8);
color:=StrToInt(Copy(s,9,2));
s:=Copy(s,11,Length(s)-10);
end;
begin
//Free some memory
Alf.Free; alf:=nil;
wpj1:=TFileStream.Create(sWPJFileName,fmCreate);
alf1:=TFileStream.Create(ChangeFileExt(sWPJFileName,'.alf'),fmCreate);
Colors:=TMemoryStream.Create;
LineData:=TMemoryStream.Create;
// copyright line will be inserted later
delta_lines:=1;
cnt:=0;
i:=-1;
iCol:=-1;
Try
if i<ReffStrings.Count-1 then Inc(i);
s:=ReffStrings[i];
GetRVACol(s);
if iCol<dwColorNum-1 then Inc(iCol);
ColDTA:=ColorData[iCol];
// first line
sline:=Listing[0];
bt:=LinesData[cnt];
LineData.WriteBuffer(bt,1);
alf1.WriteBuffer(sLine[1],bt);
//copyright string
ALF1.WriteBuffer(sCopyrightString,Length(sCopyrightString));
rva:='';
for cnt:=1 to dwLineNum-1 Do
begin
sline:=Listing[cnt];
if Copy(sLine,1,1)=':' then rva1:=DWORD2HEX(HEX2DWORD(Copy(sline,2,8)))
else rva1:='00000000';
// correcting entry point line num when reached
if dwPEP=cnt then
dwNewPEP:=dwPEP+delta_lines;
if rva=rva1 then
repeat
// add comment here
bt:=Length(s);
alf1.WriteBuffer(s[1],bt);
Dec(bt,2);
LineData.WriteBuffer(bt,1);
boza:=cnt+delta_lines;
Colors.WriteBuffer(boza,4);
Colors.WriteBuffer(Color,2);
Colors.WriteBuffer(bt,1);
Inc(delta_lines);
// getnext line for reference
if i<ReffStrings.Count-1 then
begin
Inc(i);
s:=ReffStrings[i];
GetRVACol(s);
end
else rva:='FFFFFFFE';
until rva<>rva1;
if rva<rva1 then
begin
// getnext line for reference
if i<ReffStrings.Count-1 then
begin
Inc(i);
s:=ReffStrings[i];
GetRVACol(s);
end
else rva:='FFFFFFFE';
end;
ALF1.WriteBuffer(sline[1],Length(sline));
bt:=LinesData[cnt];
LineData.WriteBuffer(bt,1);
if ColDta.LineNum<=cnt then
begin
if iCol<=dwColorNum-1 then
begin
ColDta.LineNum:=ColDta.LineNum+delta_lines;
Colors.WriteBuffer(ColDta.LineNum,4);
Colors.WriteBuffer(ColDta.Color,2);
Colors.WriteBuffer(ColDta.Size,1);
if iCol=dwColorNum-1 then Inc(iCol);
end;
if iCol<dwColorNum-1 then
begin
Inc(iCol);
ColDTA:=ColorData[iCol];
end;
end;
end;
// Copyright string color data
ColDta.LineNum:=1;ColDta.Color:=2;ColDta.Size:=Length(sCopyrightString)-2;
Colors.WriteBuffer(ColDta.LineNum,4);
Colors.WriteBuffer(ColDta.Color,2);
Colors.WriteBuffer(ColDta.Size,1);
// Save WPJ1 File
LineData.Seek(0,soFromBeginning);
WPJ.Seek(0,soFrombeginning);
// move all to sizePos
Repeat
WPJ.ReadBuffer(bt,1);
WPJ1.WriteBuffer(bt,1);
Until WPJ.Position=SizePos;
// Update line num
WPJ.Seek(4,soFromCurrent);
dwLineNum:=dwLineNum+delta_lines;
WPJ1.WriteBuffer(dwLineNum,4);
// Update code start
WPJ.ReadBuffer(dw,4); Inc(dw);
WPJ1.WriteBuffer(bt,4);
// Correction of program entry point line num
WPJ.Seek(4,soFromCurrent);
WPJ1.WriteBuffer(dwNewPEP,4);
// move all to LineDataPos
Repeat
WPJ.ReadBuffer(bt,1);
WPJ1.WriteBuffer(bt,1);
Until WPJ.Position=LineDataPos;
// adding line length data
cnt:=0;
Repeat
LineData.ReadBuffer(bt,1);
if cnt=1 then begin
bt:=$2C;
WPJ1.WriteBuffer(bt,1);
end;
WPJ1.WriteBuffer(bt,1);
Inc(cnt);
Until LineData.Position>=LineData.Size;
// move all to ColorDataPos
WPJ.Seek(EndLineDataPos,soFromBeginning);
Repeat
WPJ.ReadBuffer(bt,1);
WPJ1.WriteBuffer(bt,1);
Until WPJ.Position=ColorPos;
// Adding ColorData
Colors.Seek(0,soFromBeginning);
Repeat
Colors.ReadBuffer(bt,1);
WPJ1.WriteBuffer(bt,1);
Until Colors.Position>=Colors.Size;
// moving all the rest
WPJ.Seek(EndColorPos,soFromBeginning);
Repeat
WPJ.ReadBuffer(bt,1);
WPJ1.WriteBuffer(bt,1);
Until WPJ.Position>=WPJ.Size;
//WPJ1.SaveToFile(sWPJFileName);
//ALF1.SaveToFile(ChangeFileExt(sWPJFileName,'.alf'));
Finally
ALF1.Free;
WPJ1.Free;
Colors.free;
LineData.free;
End;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -