Skip to content

Instantly share code, notes, and snippets.

@aziascreations
Created November 18, 2018 11:47
Show Gist options
  • Save aziascreations/b477e52fe19559a4edc6cc621603de39 to your computer and use it in GitHub Desktop.
Save aziascreations/b477e52fe19559a4edc6cc621603de39 to your computer and use it in GitHub Desktop.
; http://www.unrealtexture.com/Unreal/Downloads/3DEditing/UnrealEd/Tutorials/unrealwiki-offline/umod-file-format.html
#UMOD_DECALSTAY$ = "DecalStay.umod"
#UMOD_EXCESSIVE$ = "Excessive100.umod"
; .l type (4bytes)
#UMOD_MAGIC_NBR = $9FE3C5A3
;#UMOD_MAGIC_NBR = $A3C5E3FE
#UMOD_FILE_REGULAR = $00
#UMOD_FILE_MANIFEST = $03
; All variables using the .l type are technically unsigned in the format...
; And it is located at the end of the file, because header==footer...
Structure UMOD_HEADER
DirectoryOffset.l
UmodSize.l
UmodFileVersion.l
CRC32.l ; Not sure.
EndStructure
Structure UMOD_DIRECTORY_ENTRY
FilenameLength.a ; 0x00 is counted in !
Filename$
FileByteOffset.l
FileLength.l
FileBitFields.l
EndStructure
Structure Umod
Header.UMOD_HEADER
Array DirectoryEntries.UMOD_DIRECTORY_ENTRY(0)
Array *FileData(0)
EndStructure
; Umod thingy
Procedure ReadUmod(Path$)
Protected i.i, *Umod.Umod = AllocateStructure(Umod)
If Not *Umod : ProcedureReturn 0 : EndIf
Protected FileId = ReadFile(#PB_Any, Path$)
If Not FileId : ProcedureReturn 0 : EndIf
;Protected Header.UMOD_HEADER
FileSeek(FileId, Lof(FileId)-SizeOf(UMOD_HEADER)-4, #PB_Absolute)
If UCase(Hex(ReadLong(FileId), #PB_Long)) = UCase("9FE3C5A3")
*Umod\Header\DirectoryOffset = ReadLong(FileId)
*Umod\Header\UmodSize = ReadLong(FileId)
*Umod\Header\UmodFileVersion = ReadLong(FileId)
*Umod\Header\CRC32 = ReadLong(FileId)
FileSeek(FileId, *Umod\Header\DirectoryOffset + 1, #PB_Absolute)
Repeat
Protected Filename$ = "", CurrentArrayIndex = ArraySize(*Umod\DirectoryEntries())
ReDim *Umod\DirectoryEntries(CurrentArrayIndex+1)
ReDim *Umod\FileData(CurrentArrayIndex+1)
*Umod\DirectoryEntries(CurrentArrayIndex)\FilenameLength = ReadAsciiCharacter(FileId)
For i=0 To *Umod\DirectoryEntries(CurrentArrayIndex)\FilenameLength -2
Filename$ = Filename$ + Chr(ReadAsciiCharacter(FileId))
Next
ReadAsciiCharacter(FileId)
*Umod\DirectoryEntries(CurrentArrayIndex)\Filename$ = Filename$
*Umod\DirectoryEntries(CurrentArrayIndex)\FileByteOffset = ReadLong(FileId)
*Umod\DirectoryEntries(CurrentArrayIndex)\FileLength = ReadLong(FileId)
*Umod\DirectoryEntries(CurrentArrayIndex)\FileBitFields = ReadLong(FileId)
Until Loc(FileId) >= Lof(FileId)-SizeOf(UMOD_HEADER)-4
; for over files
For i=0 To ArraySize(*Umod\DirectoryEntries())-1
*Umod\FileData(i) = AllocateMemory(*Umod\DirectoryEntries(i)\FileLength, #PB_Memory_NoClear)
FileSeek(FileId, *Umod\DirectoryEntries(i)\FileByteOffset, #PB_Absolute)
ReadData(FileId, *Umod\FileData(i), MemorySize(*Umod\FileData(i)))
Next
Else
FreeStructure(*Umod)
*Umod = 0
EndIf
CloseFile(FileId)
ProcedureReturn *Umod
EndProcedure
Procedure DebugUmodStructure(*Umod.Umod)
Protected i.i
If Not *Umod
ProcedureReturn
EndIf
Debug "Header:"
Debug #TAB$+"Dir. Offset: 0x" + Hex(*Umod\Header\DirectoryOffset)
Debug #TAB$+"Size (B): " + Str(*Umod\Header\UmodSize)
Debug #TAB$+"UMOD Ver.: 0x" + Hex(*Umod\Header\UmodFileVersion) + " ("+Str(*Umod\Header\UmodFileVersion)+")"
Debug #TAB$+"CRC?: 0x" + Hex(*Umod\Header\CRC32)
Debug ""
Debug "File directory:"
For i=0 To ArraySize(*Umod\DirectoryEntries())-1
Debug #TAB$+"Filename len.: "+*Umod\DirectoryEntries(i)\FilenameLength
Debug #TAB$+"Filename: "+*Umod\DirectoryEntries(i)\Filename$
Debug #TAB$+"Data offset: 0x"+Hex(*Umod\DirectoryEntries(i)\FileByteOffset) + " ("+Str(*Umod\DirectoryEntries(i)\FileByteOffset)+")"
Debug #TAB$+"Data length: "+*Umod\DirectoryEntries(i)\FileLength+" (bytes)"
Debug #TAB$+"Bit fields: 0x"+Hex(*Umod\DirectoryEntries(i)\FileBitFields)+" | 0b"+Bin(*Umod\DirectoryEntries(i)\FileBitFields)
Debug ""
Next
Debug "File content: (Base64)"
For i=0 To ArraySize(*Umod\DirectoryEntries())-1
Debug #TAB$+*Umod\DirectoryEntries(i)\Filename$+":"
Debug Base64Encoder(*Umod\FileData(i), MemorySize(*Umod\FileData(i)))
Debug ""
Next
Debug "END"
EndProcedure
DebugUmodStructure(ReadUmod(#UMOD_DECALSTAY$))
Debug #CRLF$+#CRLF$+"###############################"+#CRLF$+#CRLF$
DebugUmodStructure(ReadUmod(#UMOD_EXCESSIVE$))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment