unit RawList; interface uses TypeDefs; type THandler = function(ConnectionID, FileID: Integer): TRawDataList; TRawListHandler = record Ext: String[4]; needed: Boolean; Handler: THandler; end; TRawListHandlers = array of TRawListHandler; TRawLists = class private FRawListHandlers: TRawListHandlers; public property RawListHandlers: TRawListHandlers read FRawListHandlers; procedure InsertRawListHandler(ext: String; needed: Boolean; handler: THandler); function GetRawList(ConnectionID, FileID: Integer): TRawDataList; function GetRawInfo(ConnectionID, FileID, DatOffset: Integer): TRawDataInfo; end; var RawLists: TRawLists; implementation uses ConnectionManager, Access_OniArchive, Classes, SysUtils, Math, _TemplateFile; function AGDB(ConnectionID, FileID: Integer): TRawDataList; var link: Integer; links: Integer; i: Integer; begin ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $1C, 4, @links); links := links * 2; SetLength(Result, links); for i := 0 to links - 1 do begin Result[i].Name := ''; Result[i].SrcOffset := $20 + i * 4; ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $20 + i * 4, 4, @link); Result[i].RawAddr := link; Result[i].RawSize := 32; Result[i].LocSep := False; end; end; function AKVA(ConnectionID, FileID: Integer): TRawDataList; var link: Integer; links: Integer; i: Integer; begin ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $1C, 4, @links); SetLength(Result, links); for i := 0 to links - 1 do begin Result[i].Name := ''; Result[i].SrcOffset := $20 + i * $74 + $24; ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $20 + i * $74 + $24, 4, @link); Result[i].RawAddr := link; ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $20 + i * $74 + $28, 4, @link); Result[i].RawSize := link; Result[i].LocSep := False; end; end; function BINA(ConnectionID, FileID: Integer): TRawDataList; var link: Integer; datasize: Integer; begin ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $0C, 4, @link); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $08, 4, @datasize); SetLength(Result, 1); Result[0].Name := 'BinaryData'; Result[0].SrcOffset := $0C; Result[0].RawAddr := link; Result[0].RawSize := datasize; Result[0].LocSep := not (ConManager.Connection[ConnectionID].DataOS = DOS_WIN); end; function OSBD(ConnectionID, FileID: Integer): TRawDataList; var link: Integer; datasize: Integer; begin ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $08, 4, @datasize); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $0C, 4, @link); SetLength(Result, 1); Result[0].Name := 'SoundBinaryData'; Result[0].SrcOffset := $0C; Result[0].RawAddr := link; Result[0].RawSize := datasize; Result[0].LocSep := not (ConManager.Connection[ConnectionID].DataOS = DOS_WIN); end; function SNDD(ConnectionID, FileID: Integer): TRawDataList; var link: Integer; datasize: Integer; begin SetLength(Result, 1); if ConManager.Connection[ConnectionID].DataOS in [DOS_MACBETA, DOS_MAC] then begin ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $10, 4, @datasize); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $14, 4, @link); Result[0].SrcOffset := $14; end else begin ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $40, 4, @datasize); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $44, 4, @link); Result[0].SrcOffset := $44; end; Result[0].Name := 'SoundData'; Result[0].RawAddr := link; Result[0].RawSize := datasize; Result[0].LocSep := False; end; function SUBT(ConnectionID, FileID: Integer): TRawDataList; var baselink, lastlink: Integer; links: Integer; Data: TStream; read: Integer; char: Byte; foundzeros: Byte; begin SetLength(Result, 0); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $18, 4, @baselink); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $1C, 4, @links); if links > 0 then begin ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $20 + (links - 1) * 4, 4, @lastlink); Data := nil; TAccess_OniArchive(ConManager.Connection[ConnectionID]).LoadRawOffset( False, baselink, lastlink + 1024, Data); Data.Seek(lastlink, soFromBeginning); foundzeros := 0; repeat read := Data.Read(char, 1); if (read > 0) and (char = 0) then begin Inc(foundzeros); end; until (read = 0) or (foundzeros = 2); if foundzeros = 2 then begin SetLength(Result, 1); Result[0].Name := 'Subtitles'; Result[0].SrcID := FileID; Result[0].SrcOffset := $18; Result[0].RawAddr := baselink; Result[0].RawSize := Data.Position; Result[0].LocSep := False; end; end; end; function TRAM(ConnectionID, FileID: Integer): TRawDataList; var i: Integer; link: Integer; frames: Word; tempb: Byte; tempw: Word; templ: Integer; Data: TByteData; offset: Word; frame_count: Integer; begin SetLength(Result, 13); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $16C, 2, @frames); {y-pos} ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $0C, 4, @link); Result[0].Name := 'y-pos'; Result[0].SrcOffset := $0C; Result[0].RawAddr := link; Result[0].RawSize := frames * 4; {x-z-pos} ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $10, 4, @link); Result[1].Name := 'x-z-pos'; Result[1].SrcOffset := $10; Result[1].RawAddr := link; Result[1].RawSize := frames * 8; {attacks} ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $182, 1, @tempb); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $14, 4, @link); Result[2].Name := 'Attacks'; Result[2].SrcOffset := $14; Result[2].RawAddr := link; Result[2].RawSize := tempb * 32; {damage} ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $183, 1, @tempb); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $18, 4, @link); Result[3].Name := 'Damage'; Result[3].SrcOffset := $18; Result[3].RawAddr := link; Result[3].RawSize := tempb * 8; {motionblur} ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $184, 1, @tempb); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $1C, 4, @link); Result[4].Name := 'MotionBlur'; Result[4].SrcOffset := $1C; Result[4].RawAddr := link; Result[4].RawSize := tempb * 12; {shortcut} ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $185, 1, @tempb); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $20, 4, @link); Result[5].Name := 'Shortcut'; Result[5].SrcOffset := $20; Result[5].RawAddr := link; Result[5].RawSize := tempb * 8; {throw} ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $24, 4, @link); Result[6].Name := 'Throw'; Result[6].SrcOffset := $24; Result[6].RawAddr := link; Result[6].RawSize := 24; {footstep} ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $186, 1, @tempb); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $28, 4, @link); Result[7].Name := 'Footstep'; Result[7].SrcOffset := $28; Result[7].RawAddr := link; Result[7].RawSize := tempb * 4; {particle} ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $187, 1, @tempb); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $2C, 4, @link); Result[8].Name := 'Particle'; Result[8].SrcOffset := $2C; Result[8].RawAddr := link; Result[8].RawSize := tempb * 24; {position} ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $30, 4, @link); Result[9].Name := 'Position'; Result[9].SrcOffset := $30; Result[9].RawAddr := link; Result[9].RawSize := frames * 8; {sound} ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $154, 2, @tempw); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $38, 4, @link); Result[11].Name := 'Sound'; Result[11].SrcOffset := $38; Result[11].RawAddr := link; Result[11].RawSize := tempw * 34; {extent} ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $138, 4, @templ); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $13C, 4, @link); Result[12].Name := 'Extent'; Result[12].SrcOffset := $13C; Result[12].RawAddr := link; Result[12].RawSize := templ * 12; ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $34, 4, @link); if link > 0 then begin ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $160, 2, @tempw); frame_count := 0; i := 0; SetLength(Data, $FFFF); TAccess_OniArchive(ConManager.Connection[ConnectionID]).LoadRawOffset( False, link, $FFFF, Data); offset := Data[$24] + Data[$25] * 256; while (offset + i < Length(Data)) and (frame_count < frames - 1) do begin Inc(i, tempw); frame_count := frame_count + Data[offset + i]; Inc(i); end; if offset + i < Length(Data) then begin Inc(i, tempw); Result[10].RawSize := offset + i; end else begin Result[10].RawSize := 0; end; end; Result[10].Name := 'BodyParts Animation'; Result[10].SrcOffset := $34; Result[10].RawAddr := link; end; function TXMP(ConnectionID, FileID: Integer): TRawDataList; var link_pc: Integer; link_mac: Integer; x, y: Word; storetype: Byte; datasize: Integer; mipmap: Byte; function GetImgSize(w,h, storetype: Integer): Integer; begin case storetype of 0, 1, 2: Result := w*h*2; 8: Result := w*h*4; 9: Result := Max(1, w div 4) * Max(1, h div 4) * 8; else Result := -1; end; end; begin ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $88, SizeOf(mipmap), @mipmap); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $8C, SizeOf(x), @x); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $8E, SizeOf(y), @y); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $90, SizeOf(storetype), @storetype); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $9C, 4, @link_pc); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $A0, 4, @link_mac); datasize := GetImgSize(x, y, storetype); if (mipmap and $01) > 0 then begin repeat x := Max(x div 2, 1); y := Max(y div 2, 1); datasize := datasize + GetImgSize(x, y, storetype); until (x = 1) and (y = 1); end; SetLength(Result, 1); if ConManager.Connection[ConnectionID].DataOS = DOS_WIN then begin Result[0].SrcOffset := $9C; Result[0].RawAddr := link_pc; end else begin Result[0].SrcOffset := $A0; Result[0].RawAddr := link_mac; end; Result[0].Name := 'ImageData'; Result[0].RawSize := datasize; Result[0].LocSep := not (ConManager.Connection[ConnectionID].DataOS = DOS_WIN); end; function TRawLists.GetRawInfo(ConnectionID, FileID, DatOffset: Integer): TRawDataInfo; var i: Integer; RawList: TRawDataList; begin RawList := GetRawList(ConnectionID, FileID); Result.Name := ''; Result.SrcID := -1; Result.SrcOffset := -1; Result.RawAddr := -1; Result.RawSize := -1; if Length(RawList) > 0 then begin for i := 0 to High(RawList) do begin if RawList[i].SrcOffset = DatOffset then begin Result.Name := RawList[i].Name; Result.SrcID := FileID; Result.SrcOffset := RawList[i].SrcOffset; Result.RawAddr := RawList[i].RawAddr; Result.RawSize := RawList[i].RawSize; Result.LocSep := RawList[i].LocSep; Break; end; end; end; end; function TRawLists.GetRawList(ConnectionID, FileID: Integer): TRawDataList; var i: Integer; fileinfo: TFileInfo; begin SetLength(Result, 0); fileinfo := ConManager.Connection[ConnectionID].GetFileInfo(FileID); for i := 0 to High(FRawListHandlers) do if UpperCase(FRawListHandlers[i].Ext) = UpperCase(fileinfo.extension) then begin if FRawListHandlers[i].needed then Result := FRawListHandlers[i].Handler(ConnectionID, FileID); Break; end; if Length(Result) > 0 then for i := 0 to High(Result) do if Result[i].RawAddr = 0 then Result[i].RawSize := 0; end; procedure TRawLists.InsertRawListHandler(ext: String; needed: Boolean; handler: THandler); begin SetLength(FRawListHandlers, Length(FRawListHandlers) + 1); FRawListHandlers[High(FRawListHandlers)].Ext := ext; FRawListHandlers[High(FRawListHandlers)].needed := needed; FRawListHandlers[High(FRawListHandlers)].handler := handler; // Raws := Raws + ext; AddToolListEntry('rawedit', '', ext); end; initialization RawLists := TRawLists.Create; RawLists.InsertRawListHandler('AGDB', False, AGDB); RawLists.InsertRawListHandler('AKVA', True, AKVA); RawLists.InsertRawListHandler('BINA', True, BINA); RawLists.InsertRawListHandler('OSBD', True, OSBD); RawLists.InsertRawListHandler('SNDD', True, SNDD); RawLists.InsertRawListHandler('SUBT', True, SUBT); RawLists.InsertRawListHandler('TRAM', True, TRAM); RawLists.InsertRawListHandler('TXMP', True, TXMP); end.