Advertisement
Chdata

Model.nif wav Extractor

Aug 23rd, 2015
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; Extracts .wav files that Microvolts embedded into a 3D modeling file
  2. ; By: Chdata
  3. ; 8/23/2015
  4. ; Massive help from a few stock functions made by various members of the ahk community
  5. ; No help from ahk's horrid syntax
  6.  
  7. #NoEnv
  8. #SingleInstance, force
  9.  
  10. global pointer
  11.  
  12. FileRead, binary, Model.nif
  13. if not ErrorLevel ; Successfully loaded.
  14. {
  15.     offset := &binary
  16.     offset += 0x220f*2 ; filenames
  17.     offset2 := &binary
  18.     offset2 += 0x12f69*2 ; wavdata
  19.  
  20.     ;MsgBox, % ExtractName()
  21.     Loop
  22.     {
  23.         if (offset == -1000)
  24.         {
  25.             Break
  26.         }
  27.         TheFileName := ExtractName()
  28.         ;MsgBox, % "Extracting """ . TheFileName . """"
  29.  
  30.         FileDelete, .\save\%TheFileName%
  31.  
  32.         TheFileData := ExtractWav()
  33.  
  34.         ;FileAppend, %TheFileData%, .\save\%TheFileName%
  35.     }
  36. }
  37. ExitApp
  38.  
  39. ExtractName()
  40. {
  41.     global offset
  42.     nulls = 0
  43.     eofs = 0
  44.     Loop
  45.     {
  46.         pointer := ( offset+((A_Index-1)*2) )
  47.         Asc := *( pointer )
  48.         IfEqual, Asc, 0
  49.         {
  50.             if (++nulls >= 3)
  51.             {
  52.                 StringTrimRight, String, String, 1
  53.                 Break
  54.             }
  55.         }
  56.         Else IfEqual, Asc, 255
  57.         {
  58.             if (++eofs >= 4)
  59.             {
  60.                 StringTrimRight, String, String, 1
  61.                 MsgBox % "Files Done."
  62.                 offset = -1000
  63.                 Break
  64.             }
  65.         }
  66.         else
  67.         {
  68.             if (nulls > 0)
  69.             {
  70.                 nulls--
  71.             }
  72.             if (eofs > 0)
  73.             {
  74.                 eofs--
  75.             }
  76.             String .= Chr(Asc)
  77.         }
  78.     }
  79.     if (offset != -1000)
  80.         offset := pointer
  81.     Return String
  82. }
  83.  
  84. ExtractWav()
  85. {
  86.     global offset2
  87.     global TheFileName
  88.     Loop
  89.     {
  90.         pointer := ( offset2+((A_Index-1)*2) )
  91.         Asc := Chr(*( pointer ))
  92.         NextAsc2 := Chr(*( pointer+2 ))
  93.         NextAsc4 := Chr(*( pointer+4 ))
  94.         NextAsc6 := Chr(*( pointer+6 ))
  95.  
  96.         if (Asc == "R" && NextAsc2 == "I" && NextAsc4 == "F" && NextAsc6 == "F")
  97.         {
  98.             offset2 := pointer + 8
  99.             ;MsgBox % "Found RIFF"
  100.             ;String .= "RIFF"
  101.             FileAppend, RIFF, .\save\%TheFileName%
  102.             Loop
  103.             {
  104.                 pointer2 := ( offset2+((A_Index-1)*2) )
  105.                 Asc := *( pointer2 )
  106.                 Hex := NumToHex(Asc)
  107.                 FullFilePath := ".\save\" . TheFileName
  108.                 BinAppend(FullFilePath, Hex)
  109.                 ;FileAppend, %Asc%, .\save\%TheFileName%
  110.  
  111.                 NextAsc2 := Chr(*( pointer2+2 ))
  112.                 NextAsc4 := Chr(*( pointer2+4 ))
  113.                 NextAsc6 := Chr(*( pointer2+6 ))
  114.                 NextAsc8 := Chr(*( pointer2+8 ))
  115.                 NextAsc10 := Chr(*( pointer2+10 ))
  116.                 NextAsc12 := Chr(*( pointer2+12 ))
  117.                 NextAsc14 := Chr(*( pointer2+14 ))
  118.                 NextAsc16 := Chr(*( pointer2+16 ))
  119.                 NextAsc18 := Chr(*( pointer2+18 ))
  120.                 NextAsc20 := Chr(*( pointer2+20 ))
  121.                 NextAsc22 := Chr(*( pointer2+22 ))
  122.                 NextAsc24 := Chr(*( pointer2+24 ))
  123.                 NextAsc26 := Chr(*( pointer2+26 ))
  124.                 NextAsc28 := Chr(*( pointer2+28 ))
  125.                 NextAsc30 := Chr(*( pointer2+30 ))
  126.                 NextAsc32 := Chr(*( pointer2+32 ))
  127.                 NextAsc34 := Chr(*( pointer2+34 ))
  128.                 NextAsc36 := Chr(*( pointer2+36 ))
  129.                 NextAsc38 := Chr(*( pointer2+38 ))
  130.  
  131.                 ;MsgBox % Asc . NextAsc2 . NextAsc4 . NextAsc6 . NextAsc8 . NextAsc10 . NextAsc12 . NextAsc14 . NextAsc16 . NextAsc18 . NextAsc20
  132.  
  133.                 if (NextAsc2 == "<" && NextAsc4 == "?" && NextAsc6 == "x" && NextAsc8 == "p" && NextAsc10 == "a" && NextAsc12 == "c" && NextAsc14 == "k" && NextAsc16 == "e" && NextAsc18 == "t" && NextAsc20 == " " && NextAsc22 == "e" && NextAsc24 == "n" && NextAsc26 == "d" && NextAsc28 == "=" && NextAsc30 == """" && NextAsc32 == "w" && NextAsc34 == """" && NextAsc36 == "?" && NextAsc38 == ">")
  134.                 {
  135.                     pointer2 := offset2 + 40
  136.                     ;MsgBox % "Found <?xpacket end=""w""?>"
  137.                     FileAppend, <?xpacket end="w"?>, .\save\%TheFileName%
  138.                     ;String .= "<?xpacket end=""w""?>"
  139.                     offset2 := pointer2
  140.                     Return
  141.                 }
  142.             }
  143.         }
  144.     }
  145.     offset2 := pointer2
  146.     ;Return String
  147.     Return
  148. }
  149.  
  150. BinAppend(file, data)
  151. {
  152.     FileGetSize iSize, .\save\%TheFileName%
  153.     BinWrite(file, data, 0, iSize)
  154. }
  155.  
  156. /* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BinWrite ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  157. |  - Open binary file
  158. |  - (Over)Write n bytes (n = 0: all)
  159. |  - From offset (offset < 0: counted from end)
  160. |  - Close file
  161. |  data -> file[offset + 0..n-1], rest of file unchanged
  162. |  Return #bytes actually written
  163. */ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  164.  
  165. BinWrite(file, data, n=0, offset=0)
  166. {
  167.    ; Open file for WRITE (0x40..), OPEN_ALWAYS (4): creates only if it does not exists
  168.    h := DllCall("CreateFile","str",file,"Uint",0x40000000,"Uint",0,"UInt",0,"UInt",4,"Uint",0,"UInt",0)
  169.    IfEqual h,-1, SetEnv, ErrorLevel, -1
  170.    IfNotEqual ErrorLevel,0,Return,0 ; couldn't create the file
  171.  
  172.    m = 0                            ; seek to offset
  173.    IfLess offset,0, SetEnv,m,2
  174.    r := DllCall("SetFilePointerEx","Uint",h,"Int64",offset,"UInt *",p,"Int",m)
  175.    IfEqual r,0, SetEnv, ErrorLevel, -3
  176.    IfNotEqual ErrorLevel,0, {
  177.       t = %ErrorLevel%              ; save ErrorLevel to be returned
  178.       DllCall("CloseHandle", "Uint", h)
  179.       ErrorLevel = %t%              ; return seek error
  180.       Return 0
  181.    }
  182.  
  183.    TotalWritten = 0
  184.    m := Ceil(StrLen(data)/2)
  185.    If (n <= 0 or n > m)
  186.        n := m
  187.    Loop %n%
  188.    {
  189.       StringLeft c, data, 2         ; extract next byte
  190.       StringTrimLeft data, data, 2  ; remove  used byte
  191.       c = 0x%c%                     ; make it number
  192.       result := DllCall("WriteFile","UInt",h,"UChar *",c,"UInt",1,"UInt *",Written,"UInt",0)
  193.       TotalWritten += Written       ; count written
  194.       if (!result or Written < 1 or ErrorLevel)
  195.          break
  196.    }
  197.  
  198.    IfNotEqual ErrorLevel,0, SetEnv,t,%ErrorLevel%
  199.  
  200.    h := DllCall("CloseHandle", "Uint", h)
  201.    IfEqual h,-1, SetEnv, ErrorLevel, -2
  202.    IfNotEqual t,,SetEnv, ErrorLevel, %t%
  203.  
  204.    Return TotalWritten
  205. }
  206.  
  207. ; format is ##
  208. NumToHex(num)
  209. {
  210.     div = -1
  211.     while (div != 0)
  212.     {
  213.         div := floor(num / 16)
  214.         rmn := mod(num, 16)
  215.         if (rmn == "10")
  216.         {
  217.             rmn := "a"
  218.         }
  219.         if (rmn == "11")
  220.         {
  221.             rmn := "b"
  222.         }
  223.         if (rmn == "12")
  224.         {
  225.             rmn := "c"
  226.         }
  227.         if (rmn == "13")
  228.         {
  229.             rmn := "d"
  230.         }
  231.         if (rmn == "14")
  232.         {
  233.             rmn := "e"
  234.         }
  235.         if (rmn == "15")
  236.         {
  237.             rmn := "f"
  238.         }
  239.         num := div
  240.         hex .= rmn
  241.     }
  242.     hex := Flip(hex)
  243.     if (StrLen(hex) == 1)
  244.     {
  245.         hex := "0" . hex
  246.     }
  247.     Return hex
  248. }
  249.  
  250. Flip(Str)
  251. {
  252.     Loop, Parse, Str
  253.         nStr=%A_LoopField%%nStr%
  254.     Return nStr
  255. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement