| 1 | unit Unit1; | 
 
 
 
 
 | 2 | interface | 
 
 
 
 
 | 3 | uses | 
 
 
 
 
 | 4 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, | 
 
 
 
 
 | 5 | Dialogs, StdCtrls, VirtualTrees, StrUtils, ExtCtrls; | 
 
 
 
 
 | 6 |  | 
 
 
 
 
 | 7 | type | 
 
 
 
 
 | 8 | TForm1 = class(TForm) | 
 
 
 
 
 | 9 | vst: TVirtualStringTree; | 
 
 
 
 
 | 10 | list: TListBox; | 
 
 
 
 
 | 11 | Splitter1: TSplitter; | 
 
 
 
 
 | 12 | procedure FormCreate(Sender: TObject); | 
 
 
 
 
 | 13 | procedure listClick(Sender: TObject); | 
 
 
 
 
 | 14 | procedure vstGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; | 
 
 
 
 
 | 15 | Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString); | 
 
 
 
 
 | 16 | private | 
 
 
 
 
 | 17 | public | 
 
 
 
 
 | 18 | end; | 
 
 
 
 
 | 19 |  | 
 
 
 
 
 | 20 | TSwapList = class; | 
 
 
 
 
 | 21 |  | 
 
 
 
 
 | 22 | TSwapItem = class | 
 
 
 
 
 | 23 | name: String; | 
 
 
 
 
 | 24 | size: Integer; | 
 
 
 
 
 | 25 | parent: TSwapList; | 
 
 
 
 
 | 26 | end; | 
 
 
 
 
 | 27 |  | 
 
 
 
 
 | 28 | TSwapList = class(TSwapItem) | 
 
 
 
 
 | 29 | childs: array of TSwapItem; | 
 
 
 
 
 | 30 | count: Integer; | 
 
 
 
 
 | 31 | constructor Create; | 
 
 
 
 
 | 32 | function AddElem(name: String; size: Integer): Integer; | 
 
 
 
 
 | 33 | function AddArray(name: String; count: Integer): Integer; | 
 
 
 
 
 | 34 | function CloseArray: TSwapList; | 
 
 
 
 
 | 35 | function Child(index: Integer): TSwapItem; | 
 
 
 
 
 | 36 | end; | 
 
 
 
 
 | 37 |  | 
 
 
 
 
 | 38 | TType = record | 
 
 
 
 
 | 39 | name: String; | 
 
 
 
 
 | 40 | SwapList: TSwapList; | 
 
 
 
 
 | 41 | end; | 
 
 
 
 
 | 42 |  | 
 
 
 
 
 | 43 | TTypes = array of TType; | 
 
 
 
 
 | 44 |  | 
 
 
 
 
 | 45 | PNodeData = ^TNodeData; | 
 
 
 
 
 | 46 | TNodeData = record | 
 
 
 
 
 | 47 | TypeName:  String; | 
 
 
 
 
 | 48 | Address:   Integer; | 
 
 
 
 
 | 49 | Size:      Integer; | 
 
 
 
 
 | 50 | end; | 
 
 
 
 
 | 51 |  | 
 
 
 
 
 | 52 | var | 
 
 
 
 
 | 53 | Form1: TForm1; | 
 
 
 
 
 | 54 | Types: TTypes; | 
 
 
 
 
 | 55 | descfile: Text; | 
 
 
 
 
 | 56 |  | 
 
 
 
 
 | 57 | implementation | 
 
 
 
 
 | 58 |  | 
 
 
 
 
 | 59 | {$R *.dfm} | 
 
 
 
 
 | 60 |  | 
 
 
 
 
 | 61 | function AddVSTEntry(AVST: TCustomVirtualStringTree; ANode: PVirtualNode; | 
 
 
 
 
 | 62 | ARecord: TNodeData): PVirtualNode; | 
 
 
 
 
 | 63 | var | 
 
 
 
 
 | 64 | Data: PNodeData; | 
 
 
 
 
 | 65 | begin | 
 
 
 
 
 | 66 | Result := AVST.AddChild(ANode); | 
 
 
 
 
 | 67 | Data   := AVST.GetNodeData(Result); | 
 
 
 
 
 | 68 | AVST.ValidateNode(Result, False); | 
 
 
 
 
 | 69 | Data^ := ARecord; | 
 
 
 
 
 | 70 | end; | 
 
 
 
 
 | 71 |  | 
 
 
 
 
 | 72 | procedure TForm1.FormCreate(Sender: TObject); | 
 
 
 
 
 | 73 | var | 
 
 
 
 
 | 74 | state: Integer; | 
 
 
 
 
 | 75 | line, datas: String; | 
 
 
 
 
 | 76 | i: Integer; | 
 
 
 
 
 | 77 | current_list: TSwapList; | 
 
 
 
 
 | 78 | begin | 
 
 
 
 
 | 79 | VST.NodeDataSize := SizeOf(TNodeData); | 
 
 
 
 
 | 80 |  | 
 
 
 
 
 | 81 | state := 0; | 
 
 
 
 
 | 82 | current_list := nil; | 
 
 
 
 
 | 83 | AssignFile(descfile, ExtractFilePath(Application.ExeName)+'\templates.txt.gz'); | 
 
 
 
 
 | 84 | Reset(descfile); | 
 
 
 
 
 | 85 | while not EoF(descfile) do | 
 
 
 
 
 | 86 | begin | 
 
 
 
 
 | 87 | ReadLn(descfile, line); | 
 
 
 
 
 | 88 | if state = 0 then | 
 
 
 
 
 | 89 | begin | 
 
 
 
 
 | 90 | if Pos('gSwapCodes_', line) = 1 then | 
 
 
 
 
 | 91 | begin | 
 
 
 
 
 | 92 | SetLength(Types, Length(Types) + 1); | 
 
 
 
 
 | 93 | Types[High(Types)].name := MidStr(line, Pos('_', line)+1, 4); | 
 
 
 
 
 | 94 | Types[High(Types)].SwapList := TSwapList.Create; | 
 
 
 
 
 | 95 | Types[High(Types)].SwapList.parent := nil; | 
 
 
 
 
 | 96 | current_list := Types[High(Types)].SwapList; | 
 
 
 
 
 | 97 | state := 1; | 
 
 
 
 
 | 98 | datas := MidStr(line, Pos('db ', line) + 3, PosEx(' ', line, Pos('db ', line) + 3) - Pos('db ', line) - 3 ); | 
 
 
 
 
 | 99 | if datas = 'SWAPC_8BYTE' then | 
 
 
 
 
 | 100 | current_list.AddElem('SWAPC_8BYTE', 8) | 
 
 
 
 
 | 101 | else if datas = 'SWAPC_4BYTE' then | 
 
 
 
 
 | 102 | current_list.AddElem('SWAPC_4BYTE', 4) | 
 
 
 
 
 | 103 | else if datas = 'SWAPC_2BYTE' then | 
 
 
 
 
 | 104 | current_list.AddElem('SWAPC_2BYTE', 2) | 
 
 
 
 
 | 105 | else if datas = 'SWAPC_1BYTE' then | 
 
 
 
 
 | 106 | current_list.AddElem('SWAPC_1BYTE', 1); | 
 
 
 
 
 | 107 | end; | 
 
 
 
 
 | 108 | if Pos('gTemplate_', line) = 1 then | 
 
 
 
 
 | 109 | begin | 
 
 
 
 
 | 110 | datas := MidStr(line, Pos('_', line)+1, 4); | 
 
 
 
 
 | 111 | for i := 0 to High(Types) do | 
 
 
 
 
 | 112 | if Types[i].name = datas then | 
 
 
 
 
 | 113 | Break; | 
 
 
 
 
 | 114 | if i < Length(Types) then | 
 
 
 
 
 | 115 | begin | 
 
 
 
 
 | 116 | if Pos('"', line) = 0 then | 
 
 
 
 
 | 117 | ReadLn(descfile, line); | 
 
 
 
 
 | 118 | datas := MidStr(line, Pos('"', line) + 1, PosEx('"', line, Pos('"', line) + 1) - (Pos('"', line) + 1) ); | 
 
 
 
 
 | 119 | Types[i].name := Types[i].name + ' - ' + datas; | 
 
 
 
 
 | 120 | end; | 
 
 
 
 
 | 121 | end; | 
 
 
 
 
 | 122 | end else begin | 
 
 
 
 
 | 123 | if PosEx(' ', line, Pos(' d', line) + 4) > 0 then | 
 
 
 
 
 | 124 | datas := MidStr(line, Pos(' d', line) + 4, PosEx(' ', line, Pos(' d', line) + 4) - (Pos(' d', line) + 4) ) | 
 
 
 
 
 | 125 | else | 
 
 
 
 
 | 126 | datas := MidStr(line, Pos(' d', line) + 4, Length(line) - Pos(' d', line) ); | 
 
 
 
 
 | 127 | if datas = 'SWAPC_8BYTE' then | 
 
 
 
 
 | 128 | current_list.AddElem('SWAPC_8BYTE', 8) | 
 
 
 
 
 | 129 | else if datas = 'SWAPC_4BYTE' then | 
 
 
 
 
 | 130 | current_list.AddElem('SWAPC_4BYTE', 4) | 
 
 
 
 
 | 131 | else if datas = 'SWAPC_2BYTE' then | 
 
 
 
 
 | 132 | current_list.AddElem('SWAPC_2BYTE', 2) | 
 
 
 
 
 | 133 | else if datas = 'SWAPC_1BYTE' then | 
 
 
 
 
 | 134 | current_list.AddElem('SWAPC_1BYTE', 1) | 
 
 
 
 
 | 135 | else if datas = 'SWAPC_FIXARR_S' then | 
 
 
 
 
 | 136 | begin | 
 
 
 
 
 | 137 | ReadLn(descfile, line); | 
 
 
 
 
 | 138 | if Pos('h', line) > 0 then | 
 
 
 
 
 | 139 | datas := MidStr(line, Pos('db ', line) + 3, Pos('h', line) - (Pos('db ', line) + 3) ) | 
 
 
 
 
 | 140 | else | 
 
 
 
 
 | 141 | datas := MidStr(line, Pos('db ', line) + 3, Length(Line) - (Pos('db ', line) + 2) ); | 
 
 
 
 
 | 142 | i := current_list.AddArray('SWAPC_FIXARR_S', StrToInt('$'+datas)); | 
 
 
 
 
 | 143 | current_list := TSwapList(current_list.Child(i)); | 
 
 
 
 
 | 144 | Inc(State); | 
 
 
 
 
 | 145 | end else if datas = 'SWAPC_FIXARR_E' then | 
 
 
 
 
 | 146 | begin | 
 
 
 
 
 | 147 | Dec(State); | 
 
 
 
 
 | 148 | current_list := current_list.CloseArray; | 
 
 
 
 
 | 149 | end else if datas = 'SWAPC_VARARR_S' then | 
 
 
 
 
 | 150 | begin | 
 
 
 
 
 | 151 | ReadLn(descfile, line); | 
 
 
 
 
 | 152 | datas := MidStr(line, Pos(' d', line) + 4, Length(line) - (Pos(' d', line) + 3)); | 
 
 
 
 
 | 153 | if datas = 'SWAPC_8BYTE' then | 
 
 
 
 
 | 154 | i := current_list.AddArray('SWAPC_VARARR_S', 8) | 
 
 
 
 
 | 155 | else if datas = 'SWAPC_4BYTE' then | 
 
 
 
 
 | 156 | i := current_list.AddArray('SWAPC_VARARR_S', 4) | 
 
 
 
 
 | 157 | else if datas = 'SWAPC_2BYTE' then | 
 
 
 
 
 | 158 | i := current_list.AddArray('SWAPC_VARARR_S', 2) | 
 
 
 
 
 | 159 | else if datas = 'SWAPC_1BYTE' then | 
 
 
 
 
 | 160 | i := current_list.AddArray('SWAPC_VARARR_S', 1); | 
 
 
 
 
 | 161 | current_list := TSwapList(current_list.Child(i)); | 
 
 
 
 
 | 162 | end else if datas = 'SWAPC_VARARR_E' then | 
 
 
 
 
 | 163 | begin | 
 
 
 
 
 | 164 | Dec(State); | 
 
 
 
 
 | 165 | current_list := current_list.CloseArray; | 
 
 
 
 
 | 166 | end else if datas = 'SWAPC_TMPL_PTR' then | 
 
 
 
 
 | 167 | begin | 
 
 
 
 
 | 168 | ReadLn(descfile, line); | 
 
 
 
 
 | 169 | datas := MidStr(line, Pos('dd ', line) + 4, 4); | 
 
 
 
 
 | 170 | current_list.AddElem('SWAPC_TMPL_PTR: ' + datas, 4); | 
 
 
 
 
 | 171 | end; | 
 
 
 
 
 | 172 | end; | 
 
 
 
 
 | 173 | end; | 
 
 
 
 
 | 174 | CloseFile(descfile); | 
 
 
 
 
 | 175 |  | 
 
 
 
 
 | 176 | list.Items.Clear; | 
 
 
 
 
 | 177 | for i := 0 to High(Types) do | 
 
 
 
 
 | 178 | list.Items.Add(Types[i].name); | 
 
 
 
 
 | 179 | end; | 
 
 
 
 
 | 180 |  | 
 
 
 
 
 | 181 |  | 
 
 
 
 
 | 182 | { TSwapList } | 
 
 
 
 
 | 183 |  | 
 
 
 
 
 | 184 | function TSwapList.AddArray(name: String; count: Integer): Integer; | 
 
 
 
 
 | 185 | begin | 
 
 
 
 
 | 186 | SetLength(childs, Length(childs) + 1); | 
 
 
 
 
 | 187 | Result := High(childs); | 
 
 
 
 
 | 188 | childs[Result] := TSwapList.Create; | 
 
 
 
 
 | 189 | childs[Result].name := name; | 
 
 
 
 
 | 190 | childs[Result].size := 0; | 
 
 
 
 
 | 191 | childs[Result].parent := Self; | 
 
 
 
 
 | 192 | TSwapList(childs[Result]).count := count; | 
 
 
 
 
 | 193 | end; | 
 
 
 
 
 | 194 |  | 
 
 
 
 
 | 195 | function TSwapList.AddElem(name: String; size: Integer): Integer; | 
 
 
 
 
 | 196 | begin | 
 
 
 
 
 | 197 | SetLength(childs, Length(childs) + 1); | 
 
 
 
 
 | 198 | Result := High(childs); | 
 
 
 
 
 | 199 | childs[Result] := TSwapItem.Create; | 
 
 
 
 
 | 200 | childs[Result].name := name; | 
 
 
 
 
 | 201 | childs[Result].size := size; | 
 
 
 
 
 | 202 | childs[Result].parent := Self; | 
 
 
 
 
 | 203 | Self.size := Self.size + size; | 
 
 
 
 
 | 204 | end; | 
 
 
 
 
 | 205 |  | 
 
 
 
 
 | 206 | function TSwapList.Child(index: Integer): TSwapItem; | 
 
 
 
 
 | 207 | begin | 
 
 
 
 
 | 208 | Result := childs[index]; | 
 
 
 
 
 | 209 | end; | 
 
 
 
 
 | 210 |  | 
 
 
 
 
 | 211 | function TSwapList.CloseArray: TSwapList; | 
 
 
 
 
 | 212 | begin | 
 
 
 
 
 | 213 | if Self.name = 'SWAPC_FIXARR_S' then | 
 
 
 
 
 | 214 | Self.size := Self.size * Self.count | 
 
 
 
 
 | 215 | else | 
 
 
 
 
 | 216 | Self.size := Self.count; | 
 
 
 
 
 | 217 | Result := Self.parent; | 
 
 
 
 
 | 218 | end; | 
 
 
 
 
 | 219 |  | 
 
 
 
 
 | 220 | constructor TSwapList.Create; | 
 
 
 
 
 | 221 | begin | 
 
 
 
 
 | 222 | SetLength(childs, 0); | 
 
 
 
 
 | 223 | count := -1; | 
 
 
 
 
 | 224 | end; | 
 
 
 
 
 | 225 |  | 
 
 
 
 
 | 226 | procedure TForm1.listClick(Sender: TObject); | 
 
 
 
 
 | 227 | var | 
 
 
 
 
 | 228 | i:    LongWord; | 
 
 
 
 
 | 229 | Data:    TNodeData; | 
 
 
 
 
 | 230 | node:    PVirtualNode; | 
 
 
 
 
 | 231 | name:    String; | 
 
 
 
 
 | 232 |  | 
 
 
 
 
 | 233 | procedure AddChilds(parent: PVirtualNode; SwapList: TSwapList; address: Integer); | 
 
 
 
 
 | 234 | var | 
 
 
 
 
 | 235 | i: Integer; | 
 
 
 
 
 | 236 | begin | 
 
 
 
 
 | 237 | if Length(SwapList.childs) > 0 then | 
 
 
 
 
 | 238 | begin | 
 
 
 
 
 | 239 | for i := 0 to High(SwapList.childs) do | 
 
 
 
 
 | 240 | begin | 
 
 
 
 
 | 241 | data.TypeName := SwapList.Child(i).name; | 
 
 
 
 
 | 242 | data.Size := SwapList.Child(i).size; | 
 
 
 
 
 | 243 | data.Address := address; | 
 
 
 
 
 | 244 | address := address + data.Size; | 
 
 
 
 
 | 245 | node := AddVSTEntry(VST, parent, data); | 
 
 
 
 
 | 246 | if SwapList.Child(i) is TSwapList then | 
 
 
 
 
 | 247 | AddChilds(node, TSwapList(SwapList.Child(i)), address); | 
 
 
 
 
 | 248 | end; | 
 
 
 
 
 | 249 | end; | 
 
 
 
 
 | 250 | end; | 
 
 
 
 
 | 251 |  | 
 
 
 
 
 | 252 | begin | 
 
 
 
 
 | 253 | VST.Clear; | 
 
 
 
 
 | 254 | VST.BeginUpdate; | 
 
 
 
 
 | 255 |  | 
 
 
 
 
 | 256 | name := list.Items.Strings[list.ItemIndex]; | 
 
 
 
 
 | 257 | for i := 0 to High(Types) do | 
 
 
 
 
 | 258 | if Types[i].name = name then | 
 
 
 
 
 | 259 | Break; | 
 
 
 
 
 | 260 |  | 
 
 
 
 
 | 261 | if i < Length(Types) then | 
 
 
 
 
 | 262 | begin | 
 
 
 
 
 | 263 | AddChilds(nil, Types[i].SwapList, 0); | 
 
 
 
 
 | 264 | end; | 
 
 
 
 
 | 265 |  | 
 
 
 
 
 | 266 | VST.EndUpdate; | 
 
 
 
 
 | 267 | end; | 
 
 
 
 
 | 268 |  | 
 
 
 
 
 | 269 | procedure TForm1.vstGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; | 
 
 
 
 
 | 270 | Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString); | 
 
 
 
 
 | 271 | var | 
 
 
 
 
 | 272 | data: PNodeData; | 
 
 
 
 
 | 273 | begin | 
 
 
 
 
 | 274 | data := vst.GetNodeData(node); | 
 
 
 
 
 | 275 | if TextType = ttNormal then | 
 
 
 
 
 | 276 | begin | 
 
 
 
 
 | 277 | case Column of | 
 
 
 
 
 | 278 | 0: CellText := data.TypeName; | 
 
 
 
 
 | 279 | 1: CellText := '0x' + IntToHex(data.Address, 8); | 
 
 
 
 
 | 280 | 2: CellText := IntToStr(data.Size); | 
 
 
 
 
 | 281 | end; | 
 
 
 
 
 | 282 | end; | 
 
 
 
 
 | 283 | end; | 
 
 
 
 
 | 284 |  | 
 
 
 
 
 | 285 | end. |