Mod Tool/Scripting: Difference between revisions

From OniGalore
Jump to navigation Jump to search
(there's a problem with reading some registry keys on a 64-bit OS with an 32-bit program)
(not a fan of VbsEdit (especially since testing the code is delayed to force annoyance onto the user to buy the god damn license) but it can compile scripts to a program)
Line 1: Line 1:
===build an vbs executable===
[[Image:VbsEdit_for_scripting_and_compiling.png|thumb]]
Executable, app(lication), program. Whatever you call it, sometimes it might be necessary to compile the script into an actual program.
Even though vbs is a script language and not a programming language, it can be done.
VbsEdit is an editor to fulfill such task with ease.
: Just goto ''File > Convert into Executable''. Choose output path, 32/64-bit version and hit OK.
===OS bit version===
===OS bit version===
  if GetObject("winmgmts:root\cimv2:Win32_Processor='cpu0'").AddressWidth = 64 then
  if GetObject("winmgmts:root\cimv2:Win32_Processor='cpu0'").AddressWidth = 64 then
Line 27: Line 38:
  wText.WriteLine AE_path
  wText.WriteLine AE_path
  wText.Close
  wText.Close
===read file===
====as binary====
scan_AKEV_file_table
sub scan_AKEV_file_table
' ##############################################
OniInputFile =  "H:\Oni\AE\GameDataFolder\level1_Final\AKEVEnvWarehouse.oni"
' ##############################################
   
Set OniInputFileStream = CreateObject("ADODB.Stream")
OniInputFileStream.Type = 1
OniInputFileStream.Open
OniInputFileStream.LoadFromFile OniInputFile
' ### read AKEV textures table offset and size
ByteNum = 4
' ##############################################
TOffset = cLng("&H" & "28")
' ##############################################
OniInputFileStream.Position = TOffset
BArr1 = OniInputFileStream.Read(ByteNum)
ByteNum = 4
' ##############################################
TSize = cLng ("&H" & "2C")
' ##############################################
OniInputFileStream.Position = TSize
BArr2 = OniInputFileStream.Read(ByteNum)
' ### get AKEV textures table offset and size
TOffsetHex = SimpleBinaryToString(BArr1)
for i = ubound(TOffsetHex ) - 1 to 0 step -1
newhex = newhex & hex(Asc(TOffsetHex(i)))
next
logmessage newhex
logmessage "name table offset: " & cLng("&H" & newhex)
TOffsetInt = cLng("&H" & newhex)
newhex = ""
TSizeHex = SimpleBinaryToString(BArr2)
for i = ubound(TSizeHex) - 1 to 0 step -1
newhex = newhex & hex(Asc(TSizeHex(i)))
next
logmessage newhex
logmessage "name table size: " & cLng("&H" & newhex)
TSizeInt = cLng("&H" & newhex)
  logmessage "------------------------------"
 
' ### read table content
ByteNum = TSizeInt
OniInputFileStream.Position = TOffsetInt
BArr3 = OniInputFileStream.Read(ByteNum)
TContent = SimpleBinaryToString(BArr3)
' ### name grapper
NG = ""
for each n in TContent
if not Asc(n) = 0 then
NG = NG & n
else
'if instr(NG, "TXMP") = 1 then
' write TXMP to array ?
logmessage NG
'end if
NG = ""
end if
next
end sub
Function SimpleBinaryToString(Binary)
ReDim tmpArr(LenB(Binary) - 1)
For I = 1 To LenB(Binary)
S = Chr(AscB(MidB(Binary, I, 1)))
tmpArr(I - 1) = S
Next
SimpleBinaryToString = tmpArr
End Function
Output:
' INFO : 0E40
' INFO : name table offset: 3648
' INFO : 0A4A
' INFO : name table size: 2634
' INFO : ------------------------------
' INFO : AKEVEnvWarehouse
' INFO : AGDBEnvWarehouse
' INFO : TXMP_DOOR_FRAME
' INFO : TXMPNONE
' INFO : TXMPSUMI_1
' INFO : TXMPTC_CONTROL_01
' [...]
' INFO : TXMPWH_DCTRBND




Line 203: Line 311:
  'qW = ... * -1
  'qW = ... * -1
  'set qRotation = XSIMath.CreateQuaternion (qW, qX, qY, qZ)
  'set qRotation = XSIMath.CreateQuaternion (qW, qX, qY, qZ)
===read file===
====as binary====
scan_AKEV_file_table
sub scan_AKEV_file_table
' ##############################################
OniInputFile =  "H:\Oni\AE\GameDataFolder\level1_Final\AKEVEnvWarehouse.oni"
' ##############################################
   
Set OniInputFileStream = CreateObject("ADODB.Stream")
OniInputFileStream.Type = 1
OniInputFileStream.Open
OniInputFileStream.LoadFromFile OniInputFile
' ### read AKEV textures table offset and size
ByteNum = 4
' ##############################################
TOffset = cLng("&H" & "28")
' ##############################################
OniInputFileStream.Position = TOffset
BArr1 = OniInputFileStream.Read(ByteNum)
ByteNum = 4
' ##############################################
TSize = cLng ("&H" & "2C")
' ##############################################
OniInputFileStream.Position = TSize
BArr2 = OniInputFileStream.Read(ByteNum)
' ### get AKEV textures table offset and size
TOffsetHex = SimpleBinaryToString(BArr1)
for i = ubound(TOffsetHex ) - 1 to 0 step -1
newhex = newhex & hex(Asc(TOffsetHex(i)))
next
logmessage newhex
logmessage "name table offset: " & cLng("&H" & newhex)
TOffsetInt = cLng("&H" & newhex)
newhex = ""
TSizeHex = SimpleBinaryToString(BArr2)
for i = ubound(TSizeHex) - 1 to 0 step -1
newhex = newhex & hex(Asc(TSizeHex(i)))
next
logmessage newhex
logmessage "name table size: " & cLng("&H" & newhex)
TSizeInt = cLng("&H" & newhex)
  logmessage "------------------------------"
 
' ### read table content
ByteNum = TSizeInt
OniInputFileStream.Position = TOffsetInt
BArr3 = OniInputFileStream.Read(ByteNum)
TContent = SimpleBinaryToString(BArr3)
' ### name grapper
NG = ""
for each n in TContent
if not Asc(n) = 0 then
NG = NG & n
else
'if instr(NG, "TXMP") = 1 then
' write TXMP to array ?
logmessage NG
'end if
NG = ""
end if
next
end sub
Function SimpleBinaryToString(Binary)
ReDim tmpArr(LenB(Binary) - 1)
For I = 1 To LenB(Binary)
S = Chr(AscB(MidB(Binary, I, 1)))
tmpArr(I - 1) = S
Next
SimpleBinaryToString = tmpArr
End Function
Output:
' INFO : 0E40
' INFO : name table offset: 3648
' INFO : 0A4A
' INFO : name table size: 2634
' INFO : ------------------------------
' INFO : AKEVEnvWarehouse
' INFO : AGDBEnvWarehouse
' INFO : TXMP_DOOR_FRAME
' INFO : TXMPNONE
' INFO : TXMPSUMI_1
' INFO : TXMPTC_CONTROL_01
' [...]
' INFO : TXMPWH_DCTRBND




[[Category:Windows-only modding tools]]
[[Category:Windows-only modding tools]]

Revision as of 21:09, 8 September 2014

build an vbs executable

VbsEdit for scripting and compiling.png

Executable, app(lication), program. Whatever you call it, sometimes it might be necessary to compile the script into an actual program.

Even though vbs is a script language and not a programming language, it can be done.

VbsEdit is an editor to fulfill such task with ease.

Just goto File > Convert into Executable. Choose output path, 32/64-bit version and hit OK.


OS bit version

if GetObject("winmgmts:root\cimv2:Win32_Processor='cpu0'").AddressWidth = 64 then
	logmessage "64"
else
	logmessage "32"
end if

faster

Set WshShell = CreateObject("WScript.Shell")
if instr(WshShell.RegRead("HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0\Identifier"), "x86") = 1 then
	logmessage "32"
else
	logmessage "64"
end if


read registry

Mod Tool (because 32-bit) fails to execute following code properly on 64-bit operation systems. So the code must be build as 64-bit and 32-bit application.

Set WshShell = CreateObject("WScript.Shell")
AE_path = WshShell.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{B67333BB-1CF9-4EFD-A40B-E25B5CB4C8A7}}_is1\InstallLocation")
MsgBox AE_path

Dim fso
Set fso = CreateObject ("Scripting.FileSystemObject")
txt_location = fso.GetAbsolutePathName(".") & "\AE_path.txt"
Set wText = fso.CreateTextFile (txt_location, 1)
wText.WriteLine AE_path
wText.Close


read file

as binary

scan_AKEV_file_table

sub scan_AKEV_file_table
	' ##############################################
	OniInputFile =  "H:\Oni\AE\GameDataFolder\level1_Final\AKEVEnvWarehouse.oni"
	' ##############################################
    
	Set OniInputFileStream = CreateObject("ADODB.Stream")
	OniInputFileStream.Type = 1
	OniInputFileStream.Open
	OniInputFileStream.LoadFromFile OniInputFile

	' ### read AKEV textures table offset and size
	ByteNum = 4
	' ##############################################
	TOffset = cLng("&H" & "28")
	' ##############################################
	OniInputFileStream.Position = TOffset
	BArr1 = OniInputFileStream.Read(ByteNum)

	ByteNum = 4
	' ##############################################
	TSize = cLng ("&H" & "2C")
	' ##############################################
	OniInputFileStream.Position = TSize
	BArr2 = OniInputFileStream.Read(ByteNum)


	' ### get AKEV textures table offset and size
	TOffsetHex = SimpleBinaryToString(BArr1)
	for i = ubound(TOffsetHex ) - 1 to 0 step -1
		newhex = newhex & hex(Asc(TOffsetHex(i)))
	next
	logmessage newhex
	logmessage "name table offset: " & cLng("&H" & newhex)
	TOffsetInt = cLng("&H" & newhex)
	newhex = ""
	
	TSizeHex = SimpleBinaryToString(BArr2)
	for i = ubound(TSizeHex) - 1 to 0 step -1
		newhex = newhex & hex(Asc(TSizeHex(i)))
	next
	logmessage newhex
	logmessage "name table size: " & cLng("&H" & newhex)
	TSizeInt = cLng("&H" & newhex) 
	
  	logmessage "------------------------------"
  	

	' ### read table content
	ByteNum = TSizeInt
	OniInputFileStream.Position = TOffsetInt
	BArr3 = OniInputFileStream.Read(ByteNum)
	TContent = SimpleBinaryToString(BArr3)
	
	' ### name grapper
	NG = ""
	for each n in TContent
		if not Asc(n) = 0 then
			NG = NG & n
		else
			'if instr(NG, "TXMP") = 1 then
				' write TXMP to array ?
				logmessage NG
			'end if
			NG = ""
		end if
	next
end sub

Function SimpleBinaryToString(Binary)
	ReDim tmpArr(LenB(Binary) - 1)
	For I = 1 To LenB(Binary)
		S = Chr(AscB(MidB(Binary, I, 1)))
		tmpArr(I - 1) = S
	Next
	SimpleBinaryToString = tmpArr
End Function

Output:

' INFO : 0E40
' INFO : name table offset: 3648
' INFO : 0A4A
' INFO : name table size: 2634
' INFO : ------------------------------
' INFO : AKEVEnvWarehouse
' INFO : AGDBEnvWarehouse
' INFO : TXMP_DOOR_FRAME
' INFO : TXMPNONE
' INFO : TXMPSUMI_1
' INFO : TXMPTC_CONTROL_01
' [...]
' INFO : TXMPWH_DCTRBND


Math

Euler rotation -> matrix

function cosn (n)
	cosn = cos(XSIMath.DegreesToRadians(n))
end function
function sinn (n)
	sinn = sin(XSIMath.DegreesToRadians(n))
end function

' ################
logmessage "input"
x = 60 : logmessage x
y = 60 : logmessage y
z = 60 : logmessage z

logmessage "##################"
logmessage "converted"

set RotMatX = XSIMath.CreateMatrix3(1, 0, 0, 0, cosn(x), sinn(x), 0, -sinn(x), cosn(x))
set RotMatY = XSIMath.CreateMatrix3(cosn(y), 0, -sinn(y), 0, 1, 0, sinn(y), 0, cosn(y))
set RotMatZ = XSIMath.CreateMatrix3(cosn(z), sinn(z), 0, -sinn(z), cosn(z), 0, 0, 0, 1)

RotMatZ.MulInPlace RotMatY
RotMatZ.MulInPlace RotMatX

for i=0 to 2
	for j=0 to 2
		logmessage RotMatZ (i, j)
	next
next 

' INFO : input
' INFO : 60
' INFO : 60
' INFO : 60
' INFO : ##################
' INFO : converted
' INFO : 0,25
' INFO : 0,808012701892219
' INFO : 0,53349364905389
' INFO : -0,433012701892219
' INFO : -0,399519052838329
' INFO : 0,808012701892219
' INFO : 0,866025403784439
' INFO : -0,433012701892219
' INFO : 0,25


Matrix -> Euler rotation

Function Atan2(y, x)
  If x > 0 Then
    Atan2 = Atn(y / x)
  ElseIf x < 0 Then
    Atan2 = Sgn(y) * (XSIMath.PI - Atn(Abs(y / x)))
  ElseIf y = 0 Then
    Atan2 = 0
  Else
    Atan2 = Sgn(y) * XSIMath.PI / 2
  End If
End Function


function ToEuler(M00, M10, M20, M21, M22)
            a = M00
            b = M10
            dim c, s, r

            if b = 0 then
                c = Sgn(a)
                s = 0
                r = Abs(a)

            elseif a = 0 then
                c = 0
                s = Sgn(b)
                r = Abs(b)
                
            elseif Abs(b) > Abs(a) then
                t = a / b
                u = Sgn(b) * Sqr(1 + t * t)
                s = 1 / u
                c = s * t
                r = b * u

            else
                t = b / a
                u = Sgn(a) * Sqr(1 + t * t)
                c = 1 / u
                s = c * t
                r = a * u

	    end if

            Z = -Atan2(s, c)
            Y = Atan2(M20, r)
            X = -Atan2(M21, M22)

	    X = XSIMath.RadiansToDegrees(X)
	    Y = XSIMath.RadiansToDegrees(Y)
	    Z = XSIMath.RadiansToDegrees(Z)

	    ToEuler = array(X, Y, Z)
end function

' ################################
set RotMat = XSIMath.CreateMatrix3( _
		0.25, 0.808012701892219, 0.53349364905389, _
		-0.433012701892219, -0.399519052838329, 0.808012701892219, _
		0.866025403784439, -0.433012701892219, 0.25 )


' convert matrix to euler rotation and store values to array
ReXYZ = ToEuler(RotMat(0,0), RotMat(1,0), RotMat(2,0), RotMat(2,1), RotMat(2,2))

logmessage "reconverted"
logmessage ReXYZ(0)
logmessage ReXYZ(1)
logmessage ReXYZ(2)

' INFO : 60
' INFO : 60
' INFO : 60


Euler rotation -> quaternion

dim x, y, z, dRotation, qRotation
x = 90
y = 0
z = 0

set dRotation = XSIMath.CreateRotation(XSIMath.DegreesToRadians(x), XSIMath.DegreesToRadians(y), XSIMath.DegreesToRadians(z)) 
set qRotation = XSIMath.CreateQuaternion() 

	dRotation.GetQuaternion (qRotation) 
	LogMessage qRotation.W
	LogMessage qRotation.X
	LogMessage qRotation.Y
	LogMessage qRotation.Z
	' INFO : 0,707106781186548
	' INFO : 0,707106781186547
	' INFO : 0
	' INFO : 0

' to calculate oni quaternions from euler rotations use this setup:
' 	LogMessage qRotation.X
'	LogMessage qRotation.Y
'	LogMessage qRotation.Z
'	LogMessage qRotation.W * -1


Quaternion -> Euler rotation

dim qW, qX, qY, qZ, qRotation, x, y, z

	qW = 0.707106781186548
	qX = 0.707106781186547
	qY = 0
	qZ = 0

set qRotation = XSIMath.CreateQuaternion (qW, qX , qY, qZ)

	qRotation.GetXYZAngleValues x, y, z
	logmessage XSIMath.RadiansToDegrees(x)
	logmessage XSIMath.RadiansToDegrees(y)
	logmessage XSIMath.RadiansToDegrees(z)
	' INFO : 89,9999999999999
	' INFO : 0
	' INFO : 0

' to calculate euler rotations from oni quaternions use this setup:
	'qX = ...
	'qY = ...
	'qZ = ...
	'qW = ... * -1
'set qRotation = XSIMath.CreateQuaternion (qW, qX, qY, qZ)