| 1 | UNIT Unit2_functions;
 | 
|---|
| 2 | INTERFACE
 | 
|---|
| 3 | USES Classes, SysUtils, StrUtils, Math, SQLiteTable3, Unit3_data, Unit4_Exporters;
 | 
|---|
| 4 | 
 | 
|---|
| 5 | FUNCTION Decode_Int(buffer:Tdata):LongWord;
 | 
|---|
| 6 | FUNCTION Encode_Int(input:LongWord):Tdata;
 | 
|---|
| 7 | FUNCTION Decode_Float(buffer:Tdata):Single;
 | 
|---|
| 8 | FUNCTION Encode_Float(input:Single):Tdata;
 | 
|---|
| 9 | FUNCTION LoadDatInfos(filename:String):Boolean;
 | 
|---|
| 10 | FUNCTION LoadDatFile(fileid:LongWord):Tdata;
 | 
|---|
| 11 | PROCEDURE SaveDatFile(fileid:LongWord; data:Tdata);
 | 
|---|
| 12 | FUNCTION LoadDatFilePart(fileid,offset,size:LongWord; target:Pointer):Boolean;
 | 
|---|
| 13 | FUNCTION LoadRawFilePart(address,size:LongWord; target:Pointer):Boolean;
 | 
|---|
| 14 | FUNCTION FormatNumber(value:LongWord; width:Byte; leadingzeros:Char):String;
 | 
|---|
| 15 | FUNCTION FormatFileSize(size:LongWord):String;
 | 
|---|
| 16 | FUNCTION CreateHexString(data:Tdata; HexOnly:Boolean):String;
 | 
|---|
| 17 | FUNCTION ExportFile(fileid:LongWord; convert:Boolean):Integer;
 | 
|---|
| 18 | FUNCTION GetWinFileName(fileid:LongWord; substring:String):String;
 | 
|---|
| 19 | FUNCTION GetExtractPath:String;
 | 
|---|
| 20 | 
 | 
|---|
| 21 | 
 | 
|---|
| 22 | 
 | 
|---|
| 23 | IMPLEMENTATION
 | 
|---|
| 24 | 
 | 
|---|
| 25 | TYPE
 | 
|---|
| 26 |   TValueSwitcher=Record
 | 
|---|
| 27 |     CASE IsFloat: Boolean OF
 | 
|---|
| 28 |       True: (ValueFloat:Single);
 | 
|---|
| 29 |       False: (ValueInt:LongWord);
 | 
|---|
| 30 |   END;
 | 
|---|
| 31 | 
 | 
|---|
| 32 | 
 | 
|---|
| 33 | FUNCTION Decode_Int(buffer:Tdata):LongWord;
 | 
|---|
| 34 |   BEGIN
 | 
|---|
| 35 |     Result:=buffer[0]+buffer[1]*256+buffer[2]*256*256+buffer[3]*256*256*256;
 | 
|---|
| 36 |   END;
 | 
|---|
| 37 | FUNCTION Encode_Int(input:LongWord):Tdata;
 | 
|---|
| 38 |   BEGIN
 | 
|---|
| 39 |     Result[0]:=input MOD 256;
 | 
|---|
| 40 |     input:=input DIV 256;
 | 
|---|
| 41 |     Result[1]:=input MOD 256;
 | 
|---|
| 42 |     input:=input DIV 256;
 | 
|---|
| 43 |     Result[2]:=input MOD 256;
 | 
|---|
| 44 |     input:=input DIV 256;
 | 
|---|
| 45 |     Result[3]:=input MOD 256;
 | 
|---|
| 46 |   END;
 | 
|---|
| 47 | FUNCTION Decode_Float(buffer:Tdata):Single;
 | 
|---|
| 48 |   VAR _valueswitcher:TValueSwitcher;
 | 
|---|
| 49 |   BEGIN
 | 
|---|
| 50 |     _valueswitcher.ValueInt:=Decode_Int(buffer);
 | 
|---|
| 51 |     Result:=_valueswitcher.ValueFloat;
 | 
|---|
| 52 |   END;
 | 
|---|
| 53 | FUNCTION Encode_Float(input:Single):Tdata;
 | 
|---|
| 54 |   VAR _valueswitcher:TValueSwitcher;
 | 
|---|
| 55 |   BEGIN
 | 
|---|
| 56 |     _valueswitcher.ValueFloat:=input;
 | 
|---|
| 57 |     Result:=Encode_Int(_valueswitcher.ValueInt);
 | 
|---|
| 58 |   END;
 | 
|---|
| 59 | 
 | 
|---|
| 60 | 
 | 
|---|
| 61 | FUNCTION LoadDatInfos(filename:String):Boolean;
 | 
|---|
| 62 |   VAR i:LongWord;
 | 
|---|
| 63 |     dat_file:TFileStream;
 | 
|---|
| 64 |   BEGIN
 | 
|---|
| 65 |     Result:=True;
 | 
|---|
| 66 |     dat_filename:=filename;
 | 
|---|
| 67 |     raw_filename:=MidStr(filename,1,Length(filename)-3)+'raw';
 | 
|---|
| 68 |     dat_file:=TFileStream.Create(filename, fmOpenRead);
 | 
|---|
| 69 |     dat_file.Read(dat_header,SizeOf(dat_header));
 | 
|---|
| 70 |     FOR i:=0 TO High(dat_header.Ident) DO
 | 
|---|
| 71 |       IF dat_header.Ident[i]<>header_ident1[i] THEN BEGIN
 | 
|---|
| 72 |         Result:=False;
 | 
|---|
| 73 |         Exit;
 | 
|---|
| 74 |       END;
 | 
|---|
| 75 | {    FOR i:=0 TO High(dat_header.Ident2) DO
 | 
|---|
| 76 |       IF dat_header.Ident2[i]<>header_ident2[i] THEN BEGIN
 | 
|---|
| 77 |         Result:=False;
 | 
|---|
| 78 |         Exit;
 | 
|---|
| 79 |      END;
 | 
|---|
| 80 | }
 | 
|---|
| 81 |     SetLength(dat_filesmap,dat_header.Files);
 | 
|---|
| 82 |     SetLength(dat_files,dat_header.Files);
 | 
|---|
| 83 |     FOR i:=0 TO dat_header.Files-1 DO dat_file.Read(dat_filesmap[i],SizeOf(dat_filesmap[i]));
 | 
|---|
| 84 |     FOR i:=0 TO dat_header.Files-1 DO BEGIN
 | 
|---|
| 85 |       dat_files[i].Extension:=dat_filesmap[i].Extension;
 | 
|---|
| 86 |       dat_files[i].Extension:=ReverseString(dat_files[i].Extension);
 | 
|---|
| 87 |       dat_files[i].Size:=dat_filesmap[i].FileSize;
 | 
|---|
| 88 |       dat_files[i].FileType:=dat_filesmap[i].FileType;
 | 
|---|
| 89 |       dat_files[i].DatAddr:=dat_filesmap[i].DataAddr-8+dat_header.DataAddr;
 | 
|---|
| 90 |       IF (dat_filesmap[i].FileType AND $01)=0 THEN BEGIN
 | 
|---|
| 91 |         dat_file.Seek(dat_filesmap[i].NameAddr+dat_header.NamesAddr,soFromBeginning);
 | 
|---|
| 92 |         SetLength(dat_files[i].Name,100);
 | 
|---|
| 93 |         dat_file.Read(dat_files[i].Name[1],100);
 | 
|---|
| 94 |         dat_files[i].Name:=MidStr(dat_files[i].Name,1+4,Pos(#0,dat_files[i].Name)-1-4);
 | 
|---|
| 95 |       END ELSE BEGIN
 | 
|---|
| 96 |         dat_files[i].Name:='';
 | 
|---|
| 97 |       END;
 | 
|---|
| 98 |       dat_files[i].FileName:=FormatNumber(i,5,'0')+'-'+dat_files[i].Name+'.'+dat_files[i].Extension;
 | 
|---|
| 99 |     END;
 | 
|---|
| 100 |     dat_file.Seek($40+dat_header.Files*$14,soFromBeginning);
 | 
|---|
| 101 |     SetLength(dat_namedfilesmap,dat_header.NamedFiles);
 | 
|---|
| 102 |     FOR i:=0 TO dat_header.NamedFiles-1 DO dat_file.Read(dat_namedfilesmap[i],SizeOf(dat_namedfilesmap[i]));
 | 
|---|
| 103 | 
 | 
|---|
| 104 |     dat_file.Seek($40+dat_header.Files*$14+dat_header.NamedFiles*$8,soFromBeginning);
 | 
|---|
| 105 |     SetLength(dat_extensionsmap,dat_header.Extensions);
 | 
|---|
| 106 |     FOR i:=0 TO dat_header.Extensions-1 DO dat_file.Read(dat_extensionsmap[i],SizeOf(dat_extensionsmap[i]));
 | 
|---|
| 107 | 
 | 
|---|
| 108 |     dat_file.Free;
 | 
|---|
| 109 |   END;
 | 
|---|
| 110 | 
 | 
|---|
| 111 | 
 | 
|---|
| 112 | FUNCTION LoadDatFile(fileid:LongWord):Tdata;
 | 
|---|
| 113 |   VAR dat_file:TFileStream;
 | 
|---|
| 114 |   BEGIN
 | 
|---|
| 115 |     dat_file:=TFileStream.Create(dat_filename, fmOpenRead);
 | 
|---|
| 116 |     dat_file.Seek(dat_files[fileid].DatAddr,soFromBeginning);
 | 
|---|
| 117 |     SetLength(Result,dat_files[fileid].Size);
 | 
|---|
| 118 |     dat_file.Read(Result[0],dat_files[fileid].Size);
 | 
|---|
| 119 |     dat_file.Free;
 | 
|---|
| 120 |   END;
 | 
|---|
| 121 | 
 | 
|---|
| 122 | 
 | 
|---|
| 123 | PROCEDURE SaveDatFile(fileid:LongWord; data:Tdata);
 | 
|---|
| 124 |   VAR dat_file:TFileStream;
 | 
|---|
| 125 |   BEGIN
 | 
|---|
| 126 |     dat_file:=TFileStream.Create(dat_filename, fmOpenReadWrite);
 | 
|---|
| 127 |     dat_file.Seek(dat_files[fileid].DatAddr,soFromBeginning);
 | 
|---|
| 128 |     dat_file.Write(data[0],Length(data));
 | 
|---|
| 129 |     dat_file.Free;
 | 
|---|
| 130 |   END;
 | 
|---|
| 131 | 
 | 
|---|
| 132 | 
 | 
|---|
| 133 | FUNCTION LoadDatFilePart(fileid,offset,size:LongWord; target:Pointer):Boolean;
 | 
|---|
| 134 |   VAR dat_file:TFileStream;
 | 
|---|
| 135 |   BEGIN
 | 
|---|
| 136 |     dat_file:=TFileStream.Create(dat_filename, fmOpenRead);
 | 
|---|
| 137 |     Result:=True;
 | 
|---|
| 138 |     dat_file.Seek(dat_files[fileid].DatAddr+offset,soFromBeginning);
 | 
|---|
| 139 |     dat_file.Read(target^,size);
 | 
|---|
| 140 |     dat_file.Free;
 | 
|---|
| 141 |   END;
 | 
|---|
| 142 | 
 | 
|---|
| 143 | 
 | 
|---|
| 144 | FUNCTION LoadRawFilePart(address,size:LongWord; target:Pointer):Boolean;
 | 
|---|
| 145 |   VAR
 | 
|---|
| 146 |     filestream:TFileStream;
 | 
|---|
| 147 |   BEGIN
 | 
|---|
| 148 |     Result:=True;
 | 
|---|
| 149 |     filestream:=TFileStream.Create(AnsiReplaceStr(dat_filename,'.dat','.raw'),fmOpenRead);
 | 
|---|
| 150 |     filestream.Seek(address,soFromBeginning);
 | 
|---|
| 151 |     filestream.Read(target^,size);
 | 
|---|
| 152 |     filestream.Free;
 | 
|---|
| 153 |   END;
 | 
|---|
| 154 | 
 | 
|---|
| 155 | 
 | 
|---|
| 156 | FUNCTION FormatNumber(value:LongWord; width:Byte; leadingzeros:Char):String;
 | 
|---|
| 157 |   BEGIN
 | 
|---|
| 158 |     Result:=AnsiReplaceStr(Format('%'+IntToStr(width)+'u',[value]),' ',leadingzeros);
 | 
|---|
| 159 |   END;
 | 
|---|
| 160 | 
 | 
|---|
| 161 | 
 | 
|---|
| 162 | FUNCTION FormatFileSize(size:LongWord):String;
 | 
|---|
| 163 |   BEGIN
 | 
|---|
| 164 |     IF size>=1024*1024*1024 THEN BEGIN
 | 
|---|
| 165 |       Result:=FloatToStrF(size/1024/1024/1024,ffFixed,5,1)+' GB';
 | 
|---|
| 166 |     END ELSE BEGIN
 | 
|---|
| 167 |       IF size>=1024*1024 THEN BEGIN
 | 
|---|
| 168 |         Result:=FloatToStrF(size/1024/1024,ffFixed,5,1)+' MB';
 | 
|---|
| 169 |       END ELSE BEGIN
 | 
|---|
| 170 |         IF size>=1024 THEN BEGIN
 | 
|---|
| 171 |           Result:=FloatToStrF(size/1024,ffFixed,5,1)+' KB';
 | 
|---|
| 172 |         END ELSE BEGIN
 | 
|---|
| 173 |           Result:=IntToStr(size)+' B';
 | 
|---|
| 174 |         END;
 | 
|---|
| 175 |       END;
 | 
|---|
| 176 |     END;
 | 
|---|
| 177 |   END;
 | 
|---|
| 178 | 
 | 
|---|
| 179 | 
 | 
|---|
| 180 | FUNCTION CreateHexString(data:Tdata; HexOnly:Boolean):String;
 | 
|---|
| 181 |   VAR
 | 
|---|
| 182 |     string_build,ascii_version:String;
 | 
|---|
| 183 |     i:LongWord;
 | 
|---|
| 184 |   BEGIN
 | 
|---|
| 185 |     string_build:='';
 | 
|---|
| 186 |     ascii_version:='';
 | 
|---|
| 187 |     FOR i:=0 TO High(data) DO BEGIN
 | 
|---|
| 188 |       IF NOT HexOnly THEN
 | 
|---|
| 189 |         IF (i MOD 16)=0 THEN
 | 
|---|
| 190 |           string_build:=string_build+'0x'+IntToHex(i,6)+'  ';
 | 
|---|
| 191 |       string_build:=string_build+IntToHex(data[i],2);
 | 
|---|
| 192 |       IF NOT HexOnly THEN BEGIN
 | 
|---|
| 193 |         IF data[i]>=32 THEN ascii_version:=ascii_version+Chr(data[i])
 | 
|---|
| 194 |         ELSE ascii_version:=ascii_version+'.';
 | 
|---|
| 195 |         IF ((i+1) MOD 2)=0 THEN string_build:=string_build+#32;
 | 
|---|
| 196 |         IF ((i+1) MOD 16)=0 THEN BEGIN
 | 
|---|
| 197 |           string_build:=string_build+#32+ascii_version+CrLf;
 | 
|---|
| 198 |           ascii_version:='';
 | 
|---|
| 199 |         END;
 | 
|---|
| 200 |       END;
 | 
|---|
| 201 |     END;
 | 
|---|
| 202 |     Result:=string_build;
 | 
|---|
| 203 |   END;
 | 
|---|
| 204 | 
 | 
|---|
| 205 | 
 | 
|---|
| 206 | FUNCTION ExportFile(fileid:LongWord; convert:Boolean):Integer;
 | 
|---|
| 207 |   VAR
 | 
|---|
| 208 |     i:Byte;
 | 
|---|
| 209 |   BEGIN
 | 
|---|
| 210 |     Result:=export_noerror;
 | 
|---|
| 211 | 
 | 
|---|
| 212 |     //ExportDefFileHeader(fileid);
 | 
|---|
| 213 | 
 | 
|---|
| 214 |     IF (dat_files[fileid].FileType AND $02)=0 THEN BEGIN
 | 
|---|
| 215 |       //ExportDatFile(fileid);
 | 
|---|
| 216 | 
 | 
|---|
| 217 |       FOR i:=1 TO Length(ExportHandlers)+1 DO BEGIN
 | 
|---|
| 218 |         IF i<=Length(ExportHandlers) THEN BEGIN
 | 
|---|
| 219 |           IF ExportHandlers[i].Ext=dat_files[fileid].Extension THEN BEGIN
 | 
|---|
| 220 |             IF ExportHandlers[i].needed THEN BEGIN
 | 
|---|
| 221 |               CASE ExportHandlers[i].Handler(fileid,convert) OF
 | 
|---|
| 222 |                 0: Result:=0;
 | 
|---|
| 223 |               ELSE
 | 
|---|
| 224 |                 Result:=export_handlererror;
 | 
|---|
| 225 |               END;
 | 
|---|
| 226 |             END;
 | 
|---|
| 227 |             Break;
 | 
|---|
| 228 |           END;
 | 
|---|
| 229 |         END ELSE BEGIN
 | 
|---|
| 230 |           Result:=export_nohandler;
 | 
|---|
| 231 |         END;
 | 
|---|
| 232 |       END;
 | 
|---|
| 233 |     END;
 | 
|---|
| 234 |   END;
 | 
|---|
| 235 | 
 | 
|---|
| 236 | 
 | 
|---|
| 237 | FUNCTION GetWinFileName(fileid:LongWord; substring:String):String;
 | 
|---|
| 238 |   VAR
 | 
|---|
| 239 |     name:String;
 | 
|---|
| 240 |   BEGIN
 | 
|---|
| 241 |     name:=dat_files[fileid].Name;
 | 
|---|
| 242 |     name:=AnsiReplaceStr(name,'\','__');
 | 
|---|
| 243 |     name:=AnsiReplaceStr(name,'/','__');
 | 
|---|
| 244 |     name:=AnsiReplaceStr(name,'>','__');
 | 
|---|
| 245 |     name:=AnsiReplaceStr(name,'<','__');
 | 
|---|
| 246 |     Result:=FormatNumber(fileid,5,'0')+'-'+name+'.'+substring+'.'+dat_files[fileid].Extension;
 | 
|---|
| 247 |   END;
 | 
|---|
| 248 | 
 | 
|---|
| 249 | FUNCTION GetExtractPath:String;
 | 
|---|
| 250 |   BEGIN
 | 
|---|
| 251 |     Result:=ExtractFilePath(dat_filename)+'\extracted_'+ExtractFileName(dat_filename);
 | 
|---|
| 252 |   END;
 | 
|---|
| 253 | 
 | 
|---|
| 254 | 
 | 
|---|
| 255 | END.
 | 
|---|