龙之谷-提高加载资源速度

2019年12月11日08:01:14 发表评论 37
广告也精彩

 

本期是无关紧要的内容

提高加载资源速度

用于龙之谷资源解析的

昨晚开发了这一段代码,代码量小,加载资源速度极快,
加载:Resource00.pak的平均值为16ms[包含显示到文件夹列表的时间]
加载:Resource01.pak的平均值为32ms[包含显示到文件夹列表的时间]
加载:Resource02.pak的平均值为16ms[包含显示到文件夹列表的时间]
调试与打包成EXE的速度差不多;

超速度的龙之谷-提高加载资源速度

;虚拟文件的结构
Structure TypeVirFile
VirName$          ; 虚拟文件的虚拟全路径
VirSize.l         ; 虚拟文件的大小
ExtSize.l         ; 虚拟文件解压后的大小
KeepSize.l        ; 虚拟文件占用的空间的大小
VirAddress.l      ; 虚拟文件内容在资源中的指针地址
IdxAddress.l      ; 虚拟文件索引在资源文件的指针地址
EndStructure

;虚拟文件的结构
Structure TypeVirFolder
VirPath$          ; 虚拟文件的虚拟路径
Start.l           ; 符合虚拟路径的虚拟文件的Index
Count.l           ; 符合虚拟路径的虚拟文件的数量;
EndStructure

Global NewList _ListAllVirFile.TypeVirFile()          ;虚拟文件的索引集
Global NewList _ListAllVirFolder.TypeVirFolder()      ;虚拟文件的路径集
Global _ResFileFullName$                               ;虚拟文件的全名[绝对路径]

Global _GetTime.l

;加载虚拟文件,并加载与整理虚拟文件夹的路径
Procedure VirFileToNewList()

StandardFile$ = _ResFileFullName$
Pattern$      = "[龙之谷]资源文件(*.pak)|*.pak"
FileName$ = OpenFileRequester("请选择[龙之谷]的资源文件", StandardFile$, Pattern$, 0 )

If FileSize(FileName$) < 1 : ProcedureReturn #False : EndIf
*MemTempID = AllocateMemory( $110 ) : _ResFileFullName$ = FileName$
FileHandle = CreateFile_( FileName$, $40000000 | $80000000, 3, 0, 3, 0, 0 )

If FileHandle <1 : ProcedureReturn #False : EndIf
Paddress = SetFilePointer_(FileHandle, $100, 0, 0 )                        ;获取资源文件起始地址的指针
ReadFile_( FileHandle, *MemTempID, $10, @Paddress, 0 )                     ;加载资源文件
FileCount      = PeekL(*MemTempID + $4)                                 ;获取文件的数量
IndexAddress   = PeekL(*MemTempID + $8)                                 ;获取文件索引的起始位置
Size           = FileCount * $13C
*MemTempID = ReAllocateMemory(*MemTempID,Size )
Paddress = SetFilePointer_(FileHandle, IndexAddress, 0, 0 )             ;获取资源文件起始地址的指针
ReadFile_( FileHandle, *MemTempID, Size, @Paddress, 0 )                 ;加载资源文件
CloseHandle_( FileHandle )

If FileCount < 1 : ProcedureReturn #False : EndIf                       ;没有文件则退出
ClearList( _ListAllVirFile() )                                             ;清空链表
_GetTime = GetTickCount_()          ;<<<<<<<<<<<<<<<<<<<<<<<获取时间
;======== 加载资源中所有虚拟文件的信息
For i = 1 To FileCount
AddElement( _ListAllVirFile() )
_ListAllVirFile()\VirName$   = PeekS(*MemTempID + Pos, $100)           ;获取虚拟文件的全名称
_ListAllVirFile()\IdxAddress = IndexAddress + Pos                       ;获取虚拟文件解压所的大小
CopyMemory_(@_ListAllVirFile()\VirSize, *MemTempID + Pos + $100, $10 )
Pos = Pos + $13C
Next
SortStructuredList( _ListAllVirFile(), 0, OffsetOf(TypeVirFile\VirName$), #PB_Sort_String ) ;按 VirName$进行链表排序;

;======== 整理文件夹路径;指出文件夹包含的文件的相对起始索引及数量
ForEach _ListAllVirFile()
PathPart$ = GetPathPart(_ListAllVirFile()\VirName$)                     ;获取虚拟文件的路径
If TempPath$ <> PathPart$                                               ;对比虚拟文件的路径与上一个虚拟文件的路径是否一样
TempPath$ = PathPart$
AddElement( _ListAllVirFolder() )                                    ;添加虚拟文件的路径
_ListAllVirFolder()\VirPath$ = TempPath$
_ListAllVirFolder()\Start    = Index

EndIf
If _ListAllVirFile()\VirName$ <> "" : _ListAllVirFolder()\Count+1 : EndIf
Next

EndProcedure

Dim TempFolderPath$(9)        ;存放临时的文件夹列表的节点名称

If OpenWindow(0, 0, 0, 800, 600, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
TreeGadget(0, 10, 10, 780, 580)
VirFileToNewList() ;加载虚拟文件,并加载与整理虚拟文件夹的路径
AddGadgetItem(0, -1, "龙之谷资源 - " + GetFilePart(_ResFileFullName$),0,0)
ForEach _ListAllVirFolder()
Count = CountString(_ListAllVirFolder()\VirPath$,"\")
For i = 2 To Count
If TempFolderPath$(i) = StringField(_ListAllVirFolder()\VirPath$, i, "\") : Continue : EndIf
For k = i To 9
TempFolderPath$(k) = StringField(_ListAllVirFolder()\VirPath$, k, "\")
If TempFolderPath$(k)<>"" : AddGadgetItem(0, -1, TempFolderPath$(k), 0, k-1 ) : EndIf
Next
Break
Next
Next

;Debug "加载龙之谷 " + _ResFileFullName$ + " 历时: " + Str(GetTickCount_()-_GetTime) + "ms"
MessageRequester( "","加载龙之谷 " + _ResFileFullName$ + " 历时: " + Str(GetTickCount_()-_GetTime) + "ms")
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

以下附上相关工具下载文章链接

工具

老周工具包(龙之谷全功能工具)

工具

老周工具包 DNTⅡTOOL 最终版

DNT编辑工具

榴莲大神写的一个龙之谷DNT编辑工具 DNTEditor

PAK工具

龙之谷补丁工坊 v2.4 用于打包和解包龙之谷客户端PAK的工具

DNT ACT编辑器

龙之谷 超级DNT ACT编辑器1.5.2

广告也精彩
七玩网(admin)
广告也精彩

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: