mirror of
https://github.com/ModOrganizer2/libbsarch.git
synced 2026-07-27 14:06:31 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7acca3d47d | ||
|
|
0f114677b1 | ||
|
|
f276cd1825 |
@@ -30,6 +30,15 @@ bool mkdirp(const std::wstring& directory, bool basedir = true) {
|
||||
}
|
||||
}
|
||||
|
||||
void dds_info(bsa_archive_t archive, const wchar_t* file_path, bsa_dds_info_t* dds_info, void* context) {
|
||||
// Mock result
|
||||
dds_info->width = 2048;
|
||||
dds_info->height = 2048;
|
||||
dds_info->mipmaps = 12;
|
||||
|
||||
printf("ba2 dds_info callback file: %ls, context: %s\n", file_path, (char*)context);
|
||||
}
|
||||
|
||||
int main() {
|
||||
bsa_result_message_t result = { 0 };
|
||||
bsa_archive_t archive = bsa_create();
|
||||
@@ -37,23 +46,26 @@ int main() {
|
||||
{
|
||||
result = bsa_load_from_file(archive, L"test_read.bsa");
|
||||
if(result.code < 0)
|
||||
printf("%ls\n", result.text);
|
||||
printf("ba1 %ls\n", result.text);
|
||||
|
||||
bsa_entry_list_t entries = bsa_entry_list_create();
|
||||
bsa_get_resource_list(archive, entries, L"");
|
||||
|
||||
for(size_t index = 0; index < bsa_entry_list_count(entries); index++) {
|
||||
wchar_t filename[2048];
|
||||
wchar_t dest_filename[2048] = L"test_ba1\\";
|
||||
|
||||
bsa_entry_list_get(entries, index, 2048, filename);
|
||||
wcscat_s(dest_filename, 2048, filename);
|
||||
|
||||
printf("file: %ls\n", filename);
|
||||
printf("ba1 file: %ls %ls\n", filename, dest_filename);
|
||||
|
||||
if(mkdirp(dirname(filename))) {
|
||||
result = bsa_extract_file(archive, filename, filename);
|
||||
if(mkdirp(dirname(dest_filename))) {
|
||||
result = bsa_extract_file(archive, filename, dest_filename);
|
||||
if(result.code < 0)
|
||||
printf("%ls\n", result.text);
|
||||
printf("ba1 %ls\n", result.text);
|
||||
} else {
|
||||
printf("could not create: %ls\n", dirname(filename).c_str());
|
||||
printf("ba1 could not create: %ls\n", dirname(dest_filename).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,15 +80,95 @@ int main() {
|
||||
bsa_entry_list_add(entries, L"textures\\grass\\test2.dds");
|
||||
|
||||
bsa_create_archive(archive, L"test_write.bsa", baSSE, entries);
|
||||
bsa_add_file_from_disk_root(archive, L"", L"textures\\grass\\test.dds");
|
||||
result = bsa_add_file_from_disk(archive, L"textures\\grass\\test2.dds", L"textures\\grass\\test.dds");
|
||||
bsa_add_file_from_disk_root(archive, L"test_ba1\\", L"test_ba1\\textures\\grass\\test.dds");
|
||||
result = bsa_add_file_from_disk(archive, L"textures\\grass\\test2.dds", L"test_ba1\\textures\\grass\\test.dds");
|
||||
if (result.code < 0)
|
||||
printf("%ls\n", result.text);
|
||||
printf("ba1 %ls\n", result.text);
|
||||
bsa_save(archive);
|
||||
bsa_close(archive);
|
||||
|
||||
bsa_entry_list_free(entries);
|
||||
}
|
||||
|
||||
bsa_file_dds_info_callback_set(archive, dds_info, (void*)"I was shared");
|
||||
|
||||
{
|
||||
result = bsa_load_from_file(archive, L"test_read.ba2");
|
||||
if (result.code < 0)
|
||||
printf("ba2 %ls\n", result.text);
|
||||
|
||||
bsa_entry_list_t entries = bsa_entry_list_create();
|
||||
bsa_get_resource_list(archive, entries, L"");
|
||||
|
||||
for (size_t index = 0; index < bsa_entry_list_count(entries); index++) {
|
||||
wchar_t filename[2048];
|
||||
wchar_t dest_filename[2048] = L"test_ba2\\";
|
||||
|
||||
bsa_entry_list_get(entries, index, 2048, filename);
|
||||
wcscat_s(dest_filename, 2048, filename);
|
||||
|
||||
printf("ba2 file: %ls %ls\n", filename, dest_filename);
|
||||
|
||||
if (mkdirp(dirname(dest_filename))) {
|
||||
result = bsa_extract_file(archive, filename, dest_filename);
|
||||
if (result.code < 0)
|
||||
printf("ba2 %ls\n", result.text);
|
||||
}
|
||||
else {
|
||||
printf("ba2 could not create: %ls\n", dirname(dest_filename).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
bsa_entry_list_free(entries);
|
||||
|
||||
bsa_close(archive);
|
||||
}
|
||||
|
||||
{
|
||||
bsa_entry_list_t entries = bsa_entry_list_create();
|
||||
bsa_entry_list_add(entries, L"textures\\grass\\test.dds");
|
||||
bsa_entry_list_add(entries, L"textures\\grass\\test2.dds");
|
||||
|
||||
bsa_create_archive(archive, L"test_write.ba2", baFO4dds, entries);
|
||||
bsa_add_file_from_disk_root(archive, L"test_ba2\\", L"test_ba2\\textures\\grass\\test.dds");
|
||||
result = bsa_add_file_from_disk(archive, L"textures\\grass\\test2.dds", L"test_ba2\\textures\\grass\\test.dds");
|
||||
if (result.code < 0)
|
||||
printf("ba2 %ls\n", result.text);
|
||||
bsa_save(archive);
|
||||
bsa_close(archive);
|
||||
|
||||
bsa_entry_list_free(entries);
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
result = bsa_load_from_file(archive, L"test_large.ba2");
|
||||
if (result.code < 0)
|
||||
printf("ba2 large %ls\n", result.text);
|
||||
|
||||
bsa_entry_list_t entries = bsa_entry_list_create();
|
||||
bsa_get_resource_list(archive, entries, L"");
|
||||
|
||||
for (size_t index = 0; index < bsa_entry_list_count(entries); index++) {
|
||||
wchar_t filename[2048];
|
||||
wchar_t dest_filename[2048] = L"test_ba2_large\\";
|
||||
|
||||
bsa_entry_list_get(entries, index, 2048, filename);
|
||||
wcscat_s(dest_filename, 2048, filename);
|
||||
|
||||
printf("ba2 file large: %ls %ls\n", filename, dest_filename);
|
||||
|
||||
if (mkdirp(dirname(dest_filename))) {
|
||||
result = bsa_extract_file(archive, filename, dest_filename);
|
||||
if (result.code < 0)
|
||||
printf("ba2 large %ls\n", result.text);
|
||||
}
|
||||
else {
|
||||
printf("ba2 large could not create: %ls\n", dirname(dest_filename).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
bsa_free(archive);
|
||||
}
|
||||
|
||||
+1
-1
@@ -148,6 +148,6 @@ BSARCH_DLL_API(void) bsa_share_data_set(bsa_archive_t archive, bool flags) {
|
||||
return;
|
||||
}
|
||||
|
||||
BSARCH_DLL_API(void) bsa_file_dds_info_callback_set(bsa_archive_t archive, bsa_file_dds_info_proc_t file_dds_info_proc) {
|
||||
BSARCH_DLL_API(void) bsa_file_dds_info_callback_set(bsa_archive_t archive, bsa_file_dds_info_proc_t file_dds_info_proc, void *context) {
|
||||
return;
|
||||
}
|
||||
|
||||
+2
-1
@@ -374,9 +374,10 @@ begin
|
||||
TwbBSArchive(obj).ShareData := shareData;
|
||||
end;
|
||||
|
||||
procedure bsa_file_dds_info_callback_set(obj: Pointer; aProc: TBSFileDDSInfoProcCompat); stdcall;
|
||||
procedure bsa_file_dds_info_callback_set(obj: Pointer; aProc: TBSFileDDSInfoProcCompat; aContext: Pointer); stdcall;
|
||||
begin
|
||||
TwbBSArchive(obj).DDSInfoProc := aProc;
|
||||
TwbBSArchive(obj).DDSInfoProcContext := aContext;
|
||||
end;
|
||||
|
||||
exports
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
<AppType>Library</AppType>
|
||||
<FrameworkType>None</FrameworkType>
|
||||
<ProjectVersion>18.6</ProjectVersion>
|
||||
<Platform Condition="'$(Platform)'==''">Win32</Platform>
|
||||
<Platform Condition="'$(Platform)'==''">Win64</Platform>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
|
||||
<Base>true</Base>
|
||||
|
||||
+2
-2
@@ -73,7 +73,7 @@ typedef enum bsa_archive_type_e {
|
||||
baNone, baTES3, baTES4, baFO3, baSSE, baFO4, baFO4dds
|
||||
} bsa_archive_type_t;
|
||||
|
||||
typedef void (*bsa_file_dds_info_proc_t)(bsa_archive_t archive, const wchar_t *file_path, bsa_dds_info_t dds_info);
|
||||
typedef void (*bsa_file_dds_info_proc_t)(bsa_archive_t archive, const wchar_t *file_path, bsa_dds_info_t *dds_info, void *context);
|
||||
typedef bool (*bsa_file_iteration_proc_t)(bsa_archive_t archive, const wchar_t *file_path, bsa_file_record_t file_record, bsa_folder_record_t folder_record, void *context);
|
||||
|
||||
BSARCH_DLL_API(bsa_entry_list_t) bsa_entry_list_create();
|
||||
@@ -115,4 +115,4 @@ BSARCH_DLL_API(void) bsa_compress_set(bsa_archive_t archive, bool flags);
|
||||
BSARCH_DLL_API(bool) bsa_share_data_get(bsa_archive_t archive);
|
||||
BSARCH_DLL_API(void) bsa_share_data_set(bsa_archive_t archive, bool flags);
|
||||
|
||||
BSARCH_DLL_API(void) bsa_file_dds_info_callback_set(bsa_archive_t archive, bsa_file_dds_info_proc_t file_dds_info_proc);
|
||||
BSARCH_DLL_API(void) bsa_file_dds_info_callback_set(bsa_archive_t archive, bsa_file_dds_info_proc_t file_dds_info_proc, void *context);
|
||||
|
||||
+21
-11
@@ -198,7 +198,7 @@ type
|
||||
|
||||
TDDSInfo = record Width, Height, MipMaps: Integer; end;
|
||||
TBSFileDDSInfoProcCompat = procedure(aArchive: Pointer; const aFilePath: PChar;
|
||||
var aInfo: TDDSInfo); stdcall;
|
||||
var aInfo: TDDSInfo; aContext: Pointer); stdcall;
|
||||
|
||||
TwbBSHeaderTES3 = packed record
|
||||
HashOffset: Cardinal;
|
||||
@@ -308,7 +308,9 @@ type
|
||||
fVersion: Cardinal;
|
||||
fCompress: Boolean;
|
||||
fShareData: Boolean;
|
||||
|
||||
fDDSInfoProc: TBSFileDDSInfoProcCompat;
|
||||
fDDSInfoProcContext: Pointer;
|
||||
|
||||
fHeaderTES3: TwbBSHeaderTES3;
|
||||
fFilesTES3: array of TwbBSFileTES3;
|
||||
@@ -370,6 +372,7 @@ type
|
||||
property Compress: Boolean read fCompress write fCompress;
|
||||
property ShareData: Boolean read fShareData write fShareData;
|
||||
property DDSInfoProc: TBSFileDDSInfoProcCompat read fDDSInfoProc write fDDSInfoProc;
|
||||
property DDSInfoProcContext: Pointer read fDDSInfoProcContext write fDDSInfoProcContext;
|
||||
end;
|
||||
|
||||
function SplitDirName(const aFilePath: string; var Dir, Name: string): Integer;
|
||||
@@ -1364,14 +1367,13 @@ begin
|
||||
raise Exception.Create('DDS archive requires DDS file information callback');
|
||||
|
||||
for i := 0 to Pred(aFilesList.Count) do begin
|
||||
fDDSInfoProc(Self, PChar(aFilesList[i]), ddsinfo);
|
||||
fDDSInfoProc(Self, PChar(aFilesList[i]), ddsinfo, Self.fDDSInfoProcContext);
|
||||
fDataOffset := fDataOffset + 24 {size of file record} + 24 {size of each texchunk} * GetDDSMipChunkNum(ddsinfo);
|
||||
end;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
fStream := TwbWriteCachedFileStream.Create(aFilePath, fmCreate);
|
||||
fFileName := aFilePath;
|
||||
Include(fStates, stWriting);
|
||||
@@ -1547,7 +1549,8 @@ begin
|
||||
|
||||
stream := TFileStream.Create(aSourcePath, fmOpenRead + fmShareDenyNone);
|
||||
try
|
||||
GetMem(buffer, stream.Size);
|
||||
// Modified: Make sure memory is zeroed when allocated
|
||||
buffer := AllocMem(stream.Size);
|
||||
try
|
||||
stream.Read(buffer^, stream.Size);
|
||||
AddFileDataCompat(aFilePath, stream.Size, buffer);
|
||||
@@ -1904,8 +1907,8 @@ begin
|
||||
FileTES3 := aFileRecord;
|
||||
fStream.Position := fDataOffset + FileTES3.Offset;
|
||||
Result.size := FileTES3.Size;
|
||||
GetMem(Result.data, FileTES3.Size);
|
||||
fStream.ReadBuffer(Result.data[0], Result.size);
|
||||
// Modified: Make sure memory is zeroed when allocated
|
||||
Result.data := AllocMem(FileTES3.Size);
|
||||
end;
|
||||
|
||||
baTES4, baFO3, baSSE: begin
|
||||
@@ -1926,7 +1929,8 @@ begin
|
||||
if bCompressed then begin
|
||||
// reading uncompressed size
|
||||
Result.size := fStream.ReadCardinal;
|
||||
GetMem(Result.data, Result.size);
|
||||
// Modified: Make sure memory is zeroed when allocated
|
||||
Result.data := AllocMem(Result.size);
|
||||
dec(size, SizeOf(Cardinal));
|
||||
if (Result.size > 0) and (size > 0) then begin
|
||||
SetLength(Buffer, size);
|
||||
@@ -1951,7 +1955,8 @@ begin
|
||||
end
|
||||
else begin
|
||||
Result.size := size;
|
||||
GetMem(Result.data, Result.size);
|
||||
// Modified: Make sure memory is zeroed when allocated
|
||||
Result.data := AllocMem(Result.size);
|
||||
if size > 0 then
|
||||
fStream.ReadBuffer(Result.data[0], Result.size);
|
||||
end;
|
||||
@@ -1964,7 +1969,8 @@ begin
|
||||
SetLength(Buffer, FileFO4.PackedSize);
|
||||
fStream.ReadBuffer(Buffer[0], Length(Buffer));
|
||||
Result.size := FileFO4.Size;
|
||||
GetMem(Result.data, Result.size);
|
||||
// Modified: Make sure memory is zeroed when allocated
|
||||
Result.data := AllocMem(Result.size);
|
||||
if Assigned(Sync) then
|
||||
Sync.EndWrite;
|
||||
try
|
||||
@@ -1976,7 +1982,8 @@ begin
|
||||
end
|
||||
else begin
|
||||
Result.size := FileFO4.Size;
|
||||
GetMem(Result.data, Result.size);
|
||||
// Modified: Make sure memory is zeroed when allocated
|
||||
Result.data := AllocMem(Result.size);
|
||||
fStream.ReadBuffer(Result.data[0], Result.size);
|
||||
end;
|
||||
end;
|
||||
@@ -1985,11 +1992,14 @@ begin
|
||||
FileFO4 := aFileRecord;
|
||||
|
||||
TexSize := SizeOf(TDDSHeader);
|
||||
|
||||
for i := Low(FileFO4.TexChunks) to High(FileFO4.TexChunks) do
|
||||
Inc(TexSize, FileFO4.TexChunks[i].Size);
|
||||
|
||||
Result.size := Texsize;
|
||||
GetMem(Result.data, Result.size);
|
||||
|
||||
// Modified: Make sure memory is zeroed when allocated
|
||||
Result.data := AllocMem(Result.size);
|
||||
|
||||
DDSHeader := @Result.data[0];
|
||||
DDSHeader.Magic := MAGIC_DDS;
|
||||
|
||||
Reference in New Issue
Block a user