Advertisement
Guest User

Untitled

a guest
Apr 15th, 2017
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 31.61 KB | None | 0 0
  1. #!/usr/bin/python
  2. # created using python 3.6
  3.  
  4. import math
  5. import os
  6. from struct import pack, unpack, calcsize
  7. import subprocess
  8. import sys
  9. import tempfile
  10. from zipfile import ZipFile
  11.  
  12. ImageMagicConvert = '/usr/bin/convert'
  13.  
  14. decalsArchivePath = '/home/b2ag/PlayOnLinux virtual drives/Supreme_Commander/drive_c/Program Files/THQ/Gas Powered Games/Supreme Commander - Forged Alliance/gamedata/env.scd'
  15.  
  16. SCMAPMAGIC = b'\x4d\x61\x70\x1a'
  17. DDSMAGIC = b'DDS '
  18.  
  19. debugEnabled = False
  20.  
  21. class MapParsingException(Exception):
  22.     def __init__( self, subject, fileObject ):
  23.         self.offset = fileObject.tell()
  24.         self.message = "Couldn't parse {} before offset {} ".format( subject, self.offset )
  25.         super(Exception, self).__init__( self.message )
  26.  
  27. def readcstr(f):
  28.     buf = b''
  29.     while True:
  30.         b = f.read(1)
  31.         if b is None or b == b'\0':
  32.             return buf
  33.         else:
  34.             buf += b
  35.  
  36. def getOffsetsFromMap( pathToScmap, offsets ):
  37.     if type( offsets ) is not dict:
  38.         raise Exception("Offsets parameter needs to have type of dict.")
  39.  
  40. def debugPrint( label, text ):
  41.     if debugEnabled:
  42.         print("{}: {}".format(label,text))
  43.  
  44. #mirrorMode = "Diagonal Top-Left to Bottom-Right"
  45. mirrorMode = "Left-Right"
  46.  
  47. if mirrorMode == "Diagonal Top-Left to Bottom-Right":
  48.     def mirrorPropPosition( position, mapSize ):
  49.         return ( position[2], position[1], position[0] )
  50.     def mirrorDecalPosition( position, mapSize ):
  51.         return ( position[2], position[1], position[0] )
  52.     def mirrorDecalRotation(rotation):
  53.         return ( rotation[0], -rotation[1], rotation[2] )
  54.     def mirrorDecalScale(scale):
  55.         return ( scale[0], scale[1], scale[2] )
  56.     def mirrorDecal( decalsArchive, decalToMirror  ):
  57.         if not decalToMirror:
  58.             return b''
  59.         newDecalPath = outDirectory + '/mdtlbr' + decalToMirror
  60.         newDecalIngamePath = '/maps/{}/mdtlbr{}'.format( outMapNameWithVersion, decalToMirror )
  61.         if os.path.exists( newDecalPath ):
  62.             #print("{} already exists. Not going to overwrite.".format(newDecalPath))
  63.             return newDecalIngamePath.encode()
  64.        
  65.         with decalsArchive.open(decalsArchive.decalsCaseInsensitiveLookup[decalToMirror[1:].lower()]) as decalTexture:
  66.             with tempfile.NamedTemporaryFile() as originalDecalTempFile:
  67.                 originalDecalTempFile.write( decalTexture.read() )
  68.                
  69.                 os.makedirs( os.path.dirname( newDecalPath ), exist_ok = True )
  70.                 subprocess.run([ImageMagicConvert, originalDecalTempFile.name, "-flop","-rotate","-90", newDecalPath])
  71.                 print(newDecalPath)
  72.  
  73.         return newDecalIngamePath.encode()
  74.  
  75.     # not really posible to mirror the mesh by rotation...
  76.     def mirrorPropRotation( rotationX, rotationY, rotationZ ):
  77.         newRotationX = ( -rotationX[0],  rotationX[1], -rotationX[2] )
  78.         newRotationY = (  rotationY[0],  rotationY[1],  rotationY[2] )
  79.         newRotationZ = ( -rotationZ[0],  rotationZ[1], -rotationZ[2] )
  80.         return ( newRotationX, newRotationY, newRotationZ )
  81.    
  82. elif mirrorMode == "Left-Right":
  83.     def mirrorPropPosition( position, mapSize ):
  84.         return ( ( mapSize[0] - position[0] ), position[1], position[2] )
  85.     def mirrorDecalPosition( position, mapSize ):
  86.         return ( ( mapSize[0] - position[0] ), position[1], position[2] )
  87.     def mirrorDecalRotation(rotation):
  88.         return ( -rotation[0], math.pi/2 - rotation[1], rotation[2] )
  89.     def mirrorDecalScale(scale):
  90.         return ( scale[0], scale[1], scale[2] )
  91.     def mirrorDecal( decalsArchive, decalToMirror  ):
  92.         if not decalToMirror:
  93.             return b''
  94.         newDecalPath = outDirectory + '/mflop' + decalToMirror
  95.         newDecalIngamePath = '/maps/{}/mflop{}'.format( outMapNameWithVersion, decalToMirror )
  96.         if os.path.exists( newDecalPath ):
  97.             #print("{} already exists. Not going to overwrite.".format(newDecalPath))
  98.             return newDecalIngamePath.encode()
  99.  
  100.         print("Converting {}".format(newDecalPath))
  101.        
  102.         with decalsArchive.open(decalsArchive.decalsCaseInsensitiveLookup[decalToMirror[1:].lower()]) as decalTexture:
  103.             with tempfile.NamedTemporaryFile() as originalDecalTempFile:
  104.                 originalDecalTempFile.write( decalTexture.read() )
  105.                
  106.                 os.makedirs( os.path.dirname( newDecalPath ), exist_ok = True )
  107.                 cmd = [ImageMagicConvert,
  108.                        "-define","dds:compression=dxt5",
  109.                        "-define","dds:cluster-fit=true",
  110.                        "-define","dds:mipmaps=3",
  111.                        originalDecalTempFile.name,
  112.                        "-flop","-rotate","-90",
  113.                        newDecalPath]
  114.                 print("running {}".format(' '.join(cmd)))
  115.                 subprocess.run(cmd)
  116.  
  117.         return newDecalIngamePath.encode()
  118.  
  119.     # not really posible to mirror the mesh by rotation...
  120.     def mirrorPropRotation( rotationX, rotationY, rotationZ ):
  121.         newRotationX = ( math.pi/2 + rotationX[0],  rotationX[1], math.pi/2 + rotationX[2] )
  122.         newRotationY = (  rotationY[0],  rotationY[1],  rotationY[2] )
  123.         newRotationZ = ( math.pi/2 + rotationZ[0],  rotationZ[1], math.pi/2 + rotationZ[2] )
  124.         return ( newRotationX, newRotationY, newRotationZ )
  125.    
  126.  
  127. def readMap( pathToScmap, decalsArchive ):
  128.     infos = {}
  129.     listOfDebugProps = []
  130.     with open(pathToScmap,'rb') as scmap:
  131.        
  132.         scmapMagic = scmap.read(4)
  133.         if scmapMagic != SCMAPMAGIC:
  134.             raise MapParsingException( "file magic", scmap )
  135.  
  136.         fileVersionMajor = unpack('I', scmap.read(4) )[0]
  137.         if not fileVersionMajor:
  138.             raise MapParsingException( "file major version", scmap )
  139.         debugPrint( "fileVersionMajor", fileVersionMajor )
  140.  
  141.         # always 0xbeeffeed and other always 2
  142.         (unknown3,unknown4) = ( scmap.read(4), scmap.read(4) )
  143.         debugPrint( "unknown3", unknown3 )
  144.         debugPrint( "unknown4", unknown4 )
  145.        
  146.         (scaledMapWidth,scaledMapHeight) = unpack('ff', scmap.read(calcsize('ff')) )
  147.         if not scaledMapWidth or not scaledMapHeight:
  148.             raise MapParsingException( "scaled map size", scmap )
  149.         debugPrint( "scaledMapWidth", scaledMapWidth )
  150.         debugPrint( "scaledMapHeight", scaledMapHeight )
  151.        
  152.         # always 0
  153.         (unknown5,unknown6) = ( scmap.read(4), scmap.read(2) )
  154.         debugPrint( "unknown5", unknown5 )
  155.         debugPrint( "unknown6", unknown6 )
  156.        
  157.         #######################################################################
  158.         ### Preview Image
  159.         #######################################################################
  160.  
  161.         previewImageDataLength = unpack('I', scmap.read(4) )[0]
  162.         if not previewImageDataLength:
  163.             raise MapParsingException( "preview image data length", scmap )
  164.         previewImageData = scmap.read(previewImageDataLength)
  165.         if len(previewImageData) != previewImageDataLength:
  166.             raise MapParsingException( "preview image data ({} bytes)".format(previewImageDataLength), scmap )
  167.         debugPrint( "previewImageDataLength", "{} bytes".format(previewImageDataLength) )
  168.         debugPrint( "previewImageDataMagic", previewImageData[0:4].decode( ))
  169.         #if previewImageData[0:4] == DDSMAGIC:
  170.             #previewDataPath = "{}_preview.dds".format( scmap.name )
  171.             #with open(previewDataPath,'wb') as previewDumpFile:
  172.                 #previewDumpFile.write( previewImageData )
  173.             #print("preview image dumped to \"{}\"".format(previewDataPath))
  174.        
  175.         fileVersionMinor = unpack('I', scmap.read(4) )[0]
  176.         if not fileVersionMinor:
  177.             raise MapParsingException( "file minor version", scmap )
  178.         debugPrint( "fileVersionMinor", fileVersionMinor )
  179.        
  180.         if fileVersionMinor not in [60, 59, 56, 53]:
  181.             raise MapParsingException( "unsupported file minor version", scmap )
  182.        
  183.         #######################################################################
  184.        
  185.         mapSize = (mapWidth,mapHeight) = unpack('II', scmap.read(8) )
  186.         if not mapWidth or not mapHeight:
  187.             raise MapParsingException( "map size", scmap )
  188.         debugPrint( "mapWidth", mapWidth )
  189.         debugPrint( "mapHeight", mapHeight )
  190.        
  191.         #######################################################################
  192.         ### Height Map
  193.         #######################################################################
  194.  
  195.         # Height Scale, usually 1/128
  196.         heightScale = unpack('f', scmap.read(4) )[0]
  197.         debugPrint( "heightScale", heightScale )
  198.         heightMapDataLength = ( mapHeight + 1 ) * ( mapWidth + 1 ) * calcsize('h')
  199.         debugPrint( "heightMapDataLength", heightMapDataLength )
  200.         heightMapData = scmap.read(heightMapDataLength)
  201.  
  202.         #######################################################################
  203.         ### Some Shader
  204.         #######################################################################
  205.        
  206.         if fileVersionMinor >= 56:
  207.             unknown7 = readcstr(scmap)
  208.             debugPrint( "unknown7", unknown7 )
  209.        
  210.         terrain = readcstr(scmap)
  211.         debugPrint( "terrain", terrain )
  212.        
  213.         texPathBackground = readcstr(scmap)
  214.         debugPrint( "texPathBackground", texPathBackground )
  215.        
  216.         texPathSkyCubemap = readcstr(scmap)
  217.         debugPrint( "texPathSkyCubemap", texPathSkyCubemap )
  218.  
  219.         if fileVersionMinor < 56:
  220.        
  221.             texPathEnvCubemap = readcstr(scmap)
  222.             debugPrint( "texPathEnvCubemap", texPathEnvCubemap )            
  223.        
  224.         elif fileVersionMinor >= 56:
  225.  
  226.             environmentLookupTexturesCount = unpack('I', scmap.read(4) )[0]
  227.             debugPrint( "environmentLookupTexturesCount", environmentLookupTexturesCount )
  228.            
  229.             for i in range(environmentLookupTexturesCount):
  230.                 environmentLookupTexturesLabel = readcstr(scmap)
  231.                 debugPrint( "environmentLookupTexturesLabel", environmentLookupTexturesLabel )
  232.                 environmentLookupTexturesFile = readcstr(scmap)
  233.                 debugPrint( "environmentLookupTexturesFile", environmentLookupTexturesFile )
  234.        
  235.         #######################################################################
  236.         ### Render Settings
  237.         #######################################################################
  238.  
  239.         lightingMultiplier = unpack('f', scmap.read(4) )[0]
  240.         debugPrint( "lightingMultiplier", lightingMultiplier )
  241.  
  242.         lightDirection = unpack('fff', scmap.read(12) )
  243.         debugPrint( "lightDirection", lightDirection )
  244.  
  245.         ambienceLightColor = unpack('fff', scmap.read(12) )
  246.         debugPrint( "ambienceLightColor", ambienceLightColor )
  247.  
  248.         lightColor = unpack('fff', scmap.read(12) )
  249.         debugPrint( "lightColor", lightColor )
  250.  
  251.         shadowFillColor = unpack('fff', scmap.read(12) )
  252.         debugPrint( "shadowFillColor", shadowFillColor )
  253.  
  254.         specularColor = unpack('ffff', scmap.read(16) )
  255.         debugPrint( "specularColor", specularColor )
  256.  
  257.         bloom = unpack('f', scmap.read(4) )[0]
  258.         debugPrint( "bloom", bloom )
  259.  
  260.         fogColor = unpack('fff', scmap.read(12) )
  261.         debugPrint( "fogColor", fogColor )
  262.        
  263.         fogStart = unpack('f', scmap.read(4) )[0]
  264.         debugPrint( "fogStart", fogStart )
  265.  
  266.         fogEnd = unpack('f', scmap.read(4) )[0]
  267.         debugPrint( "fogEnd", fogEnd )
  268.  
  269.         hasWater = unpack('c', scmap.read(1) )[0]
  270.         debugPrint( "hasWater", hasWater )
  271.  
  272.         waterElevation = unpack('f', scmap.read(4) )[0]
  273.         debugPrint( "waterElevation", waterElevation )
  274.  
  275.         waterElevationDeep = unpack('f', scmap.read(4) )[0]
  276.         debugPrint( "waterElevationDeep", waterElevationDeep )
  277.  
  278.         waterElevationAbyss = unpack('f', scmap.read(4) )[0]
  279.         debugPrint( "waterElevationAbyss", waterElevationAbyss )
  280.        
  281.        
  282.         surfaceColor = unpack('fff', scmap.read(12) )
  283.         debugPrint( "surfaceColor", surfaceColor )
  284.        
  285.         colorLerpMin = unpack('f', scmap.read(4) )[0]
  286.         debugPrint( "colorLerpMin", colorLerpMin )
  287.        
  288.         colorLerpMax = unpack('f', scmap.read(4) )[0]
  289.         debugPrint( "colorLerpMax", colorLerpMax )
  290.        
  291.         refraction = unpack('f', scmap.read(4) )[0]
  292.         debugPrint( "refraction", refraction )
  293.        
  294.         fresnelBias = unpack('f', scmap.read(4) )[0]
  295.         debugPrint( "fresnelBias", fresnelBias )
  296.        
  297.         fresnelPower = unpack('f', scmap.read(4) )[0]
  298.         debugPrint( "fresnelPower", fresnelPower )
  299.        
  300.         reflectionUnit = unpack('f', scmap.read(4) )[0]
  301.         debugPrint( "reflectionUnit", reflectionUnit )
  302.        
  303.         reflectionSky = unpack('f', scmap.read(4) )[0]
  304.         debugPrint( "reflectionSky", reflectionSky )
  305.        
  306.         sunShininess = unpack('f', scmap.read(4) )[0]
  307.         debugPrint( "sunShininess", sunShininess )
  308.        
  309.         sunStrength = unpack('f', scmap.read(4) )[0]
  310.         debugPrint( "sunStrength", sunStrength )
  311.        
  312.         sunGlow = unpack('f', scmap.read(4) )[0]
  313.         debugPrint( "sunGlow", sunGlow )
  314.        
  315.         unknown8 = unpack('f', scmap.read(4) )[0]
  316.         debugPrint( "unknown8", unknown8 )
  317.        
  318.         unknown9 = unpack('f', scmap.read(4) )[0]
  319.         debugPrint( "unknown9", unknown9 )
  320.        
  321.         sunColor = unpack('fff', scmap.read(12) )
  322.         debugPrint( "sunColor", sunColor )
  323.        
  324.         reflectionSun = unpack('f', scmap.read(4) )[0]
  325.         debugPrint( "reflectionSun", reflectionSun )
  326.  
  327.         unknown10 = unpack('f', scmap.read(4) )[0]
  328.         debugPrint( "unknown10", unknown10 )
  329.  
  330.         ### Texture Maps
  331.  
  332.         texPathWaterCubemap = readcstr(scmap)
  333.         debugPrint( "texPathWaterCubemap", texPathWaterCubemap )
  334.  
  335.         texPathWaterRamp = readcstr(scmap)
  336.         debugPrint( "texPathWaterRamp", texPathWaterRamp )
  337.  
  338.         for i in range(4):
  339.             debugPrint( "waveTexture", i )
  340.             normalsFrequency = unpack('f', scmap.read(4) )[0]
  341.             debugPrint( "normalsFrequency", normalsFrequency )
  342.  
  343.         for i in range(4):
  344.             debugPrint( "waveTexture", i )
  345.             waveTextureScaleX = unpack('f', scmap.read(4) )[0]
  346.             debugPrint( "waveTextureScaleX", waveTextureScaleX )
  347.             waveTextureScaleY = unpack('f', scmap.read(4) )[0]
  348.             debugPrint( "waveTextureScaleY", waveTextureScaleY )
  349.             waveTexturePath = readcstr(scmap)
  350.             debugPrint( "waveTexturePath", waveTexturePath )
  351.  
  352.         waveGeneratorCount = unpack('I', scmap.read(4) )[0]
  353.         debugPrint( "waveGeneratorCount", waveGeneratorCount )
  354.         for i in range(waveGeneratorCount):
  355.             debugPrint( "waveGenerator", i )
  356.             textureName = readcstr(scmap)
  357.             debugPrint( "textureName", textureName )
  358.             rampName = readcstr(scmap)
  359.             debugPrint( "rampName", rampName )
  360.             position = unpack('fff', scmap.read(12) )
  361.             debugPrint( "position", position )
  362.             rotation = unpack('f', scmap.read(4) )[0]
  363.             debugPrint( "rotation", rotation )
  364.             velocity = unpack('fff', scmap.read(12) )
  365.             debugPrint( "velocity", velocity )
  366.             lifetimeFirst = unpack('f', scmap.read(4) )[0]
  367.             debugPrint( "lifetimeFirst", lifetimeFirst )
  368.             lifetimeSecond = unpack('f', scmap.read(4) )[0]
  369.             debugPrint( "lifetimeSecond", lifetimeSecond )
  370.             periodFirst = unpack('f', scmap.read(4) )[0]
  371.             debugPrint( "periodFirst", periodFirst )
  372.             periodSecond = unpack('f', scmap.read(4) )[0]
  373.             debugPrint( "periodSecond", periodSecond )
  374.             scaleFirst = unpack('f', scmap.read(4) )[0]
  375.             debugPrint( "scaleFirst", scaleFirst )
  376.             scaleSecond = unpack('f', scmap.read(4) )[0]
  377.             debugPrint( "scaleSecond", scaleSecond )
  378.             frameCount = unpack('f', scmap.read(4) )[0]
  379.             debugPrint( "frameCount", frameCount )
  380.             frameRateFirst = unpack('f', scmap.read(4) )[0]
  381.             debugPrint( "frameRateFirst", frameRateFirst )
  382.             frameRateSecond = unpack('f', scmap.read(4) )[0]
  383.             debugPrint( "frameRateSecond", frameRateSecond )
  384.             stripCount = unpack('f', scmap.read(4) )[0]
  385.             debugPrint( "stripCount", stripCount )
  386.        
  387.         if fileVersionMinor >= 59:
  388.             unkownData12 = scmap.read(28)
  389.             debugPrint( "unkownData12", unkownData12.hex( ))
  390.         elif fileVersionMinor > 53:
  391.             unkownData12 = scmap.read(24)
  392.             debugPrint( "unkownData12", unkownData12.hex( ))
  393.         else:
  394.             noTileset = readcstr(scmap)
  395.             debugPrint( "noTileset", noTileset )
  396.            
  397.        
  398.         if fileVersionMinor > 53:
  399.  
  400.             strata = ['LowerStratum','Stratum1','Stratum2','Stratum3','Stratum4','Stratum5','Stratum6','Stratum7','Stratum8','UpperStratum']
  401.             debugPrint( "strata", strata )
  402.  
  403.             for stratum in strata:
  404.                 debugPrint( "stratum", stratum )
  405.                 albedoFile = readcstr(scmap)
  406.                 debugPrint( "albedoFile", albedoFile )
  407.                 albedoScale = unpack('f', scmap.read(4) )[0]
  408.                 debugPrint( "albedoScale", albedoScale )
  409.            
  410.             for stratum in strata:
  411.                 # fucking special cases
  412.                 if stratum == 'UpperStratum':
  413.                     # no Normal for UpperStratum
  414.                     continue
  415.                 debugPrint( "stratum", stratum )
  416.                 normalFile = readcstr(scmap)
  417.                 debugPrint( "normalFile", normalFile )
  418.                 normalScale = unpack('f', scmap.read(4) )[0]
  419.                 debugPrint( "normalScale", normalScale )
  420.        
  421.         else:
  422.  
  423.             strataCount = unpack('I', scmap.read(4) )[0]
  424.             debugPrint( "strataCount", strataCount )
  425.             for stratum in range(strataCount):
  426.                 debugPrint( "stratum", stratum )
  427.                 albedoFile = readcstr(scmap)
  428.                 debugPrint( "albedoFile", albedoFile )
  429.                 normalFile = readcstr(scmap)
  430.                 debugPrint( "normalFile", normalFile )
  431.                 albedoScale = unpack('f', scmap.read(4) )[0]
  432.                 debugPrint( "albedoScale", albedoScale )
  433.                 normalScale = unpack('f', scmap.read(4) )[0]
  434.                 debugPrint( "normalScale", normalScale )
  435.            
  436.         unknown13 = unpack('I', scmap.read(4) )[0]
  437.         debugPrint( "unknown13", unknown13 )
  438.  
  439.         unknown14 = unpack('I', scmap.read(4) )[0]
  440.         debugPrint( "unknown14", unknown14 )
  441.        
  442.         #######################################################################
  443.         ### Decals
  444.         #######################################################################
  445.  
  446.         decalsBlockStartOffset = scmap.tell()
  447.         infos["decalsBlockStartOffset"] = decalsBlockStartOffset
  448.  
  449.         decalsCount = unpack('I', scmap.read(4) )[0]
  450.         debugPrint( "decalsCount", decalsCount )
  451.  
  452.         decalsList = []
  453.         for decalIndex in range(decalsCount):
  454.  
  455.             decalId = unpack('I', scmap.read(4) )[0]
  456.             debugPrint( "decalId", decalId )
  457.  
  458.             unknown15 = unpack('I', scmap.read(4) )[0]
  459.             debugPrint( "unknown15", unknown15 )
  460.  
  461.             decalType = unpack('I', scmap.read(4) )[0]
  462.             debugPrint( "decalType", decalType )
  463.  
  464.             decalsTexture1PathLength = unpack('I', scmap.read(4) )[0]
  465.             debugPrint( "decalsTexture1PathLength", decalsTexture1PathLength )
  466.                
  467.             if decalsTexture1PathLength > 1024:
  468.                 raise MapParsingException( "decalsTexture1PathLength", scmap )
  469.  
  470.             decalsTexture1Path = scmap.read(decalsTexture1PathLength)
  471.             debugPrint( "decalsTexture1Path", decalsTexture1Path )
  472.  
  473.             decalsTexture2PathLength = unpack('I', scmap.read(4) )[0]
  474.             debugPrint( "decalsTexture2PathLength", decalsTexture2PathLength )
  475.                
  476.             if decalsTexture2PathLength > 1024:
  477.                 raise MapParsingException( "decalsTexture2PathLength", scmap )
  478.            
  479.             if decalsTexture2PathLength > 0:
  480.                 decalsTexture2Path = scmap.read(decalsTexture2PathLength)
  481.                 debugPrint( "decalsTexture2Path", decalsTexture2Path )
  482.             else:
  483.                 decalsTexture2Path = b''
  484.  
  485.             scale = unpack('fff', scmap.read(12) )
  486.             debugPrint( "scale", scale )
  487.  
  488.             position = unpack('fff', scmap.read(12) )
  489.             debugPrint( "position", position )
  490.  
  491.             rotation = unpack('fff', scmap.read(12) )
  492.             debugPrint( "rotation", rotation )
  493.  
  494.             cutOffLOD = unpack('f', scmap.read(4) )[0]
  495.             debugPrint( "cutOffLOD", cutOffLOD )
  496.  
  497.             nearCutOffLOD = unpack('f', scmap.read(4) )[0]
  498.             debugPrint( "nearCutOffLOD", nearCutOffLOD )
  499.  
  500.             removeTick = unpack('I', scmap.read(4) )[0]
  501.             debugPrint( "removeTick", removeTick )
  502.            
  503.             decalDebug = False
  504.             if decalDebug:
  505.                 unknown15 = 1
  506.            
  507.             decal = pack('IIII',decalId,unknown15,decalType,len(decalsTexture1Path))
  508.             decal += decalsTexture1Path
  509.             decal += pack('I',len(decalsTexture2Path))
  510.             if decalsTexture2Path:
  511.                 decal += decalsTexture2Path
  512.             decal += pack('fffffffff',*scale,*position,*rotation)
  513.             decal += pack('ffI',cutOffLOD,nearCutOffLOD,removeTick)
  514.            
  515.             newPosition = mirrorDecalPosition( position, mapSize )
  516.             newRotation = mirrorDecalRotation( rotation )
  517.             newScale = mirrorDecalScale( scale )
  518.  
  519.             if decalDebug:
  520.                 listOfDebugProps += [(
  521.                         b'/env/redrocks/props/thetabridge01_prop.bp',
  522.                         *position,
  523.                         *(-math.cos(rotation[1]),0,-math.sin(rotation[1])),
  524.                         *(0,1,0),
  525.                         *(math.sin(rotation[1]),0,-math.cos(rotation[1])),
  526.                         *(1,1,1))]
  527.                 listOfDebugProps += [(
  528.                         b'/env/redrocks/props/thetabridge01_prop.bp',
  529.                         *newPosition,
  530.                         *(-math.cos(newRotation[1]),0,-math.sin(newRotation[1])),
  531.                         *(0,1,0),
  532.                         *(math.sin(newRotation[1]),0,-math.cos(newRotation[1])),
  533.                         *(1,1,1))]
  534.            
  535.             newDecalsTexture1Path = mirrorDecal( decalsArchive, decalToMirror=decalsTexture1Path.decode() )
  536.             newDecalsTexture2Path = mirrorDecal( decalsArchive, decalToMirror=decalsTexture2Path.decode() )
  537.             newdecal = pack('IIII',decalsCount+decalId,unknown15,decalType,len(newDecalsTexture1Path))
  538.             newdecal += newDecalsTexture1Path
  539.             newdecal += pack('I',len(newDecalsTexture2Path))
  540.             if newDecalsTexture2Path:
  541.                 newdecal += newDecalsTexture2Path
  542.             newdecal += pack('fffffffff',*newScale,*newPosition,*newRotation)
  543.             newdecal += pack('ffI',cutOffLOD,nearCutOffLOD,removeTick)
  544.            
  545.             decalsList += [decal,newdecal]
  546.            
  547.             #infos["decalsBlockFormat"] = 'IIII{}sI{}sfffffffffffI'.format(decalsTexture1PathLength,decalsTexture2PathLength)
  548.  
  549.         infos["decalsList"] = decalsList
  550.  
  551.         decalsBlockEndOffset = scmap.tell()
  552.         infos["decalsBlockEndOffset"] = decalsBlockEndOffset
  553.  
  554.         decalGroupsCount = unpack('I', scmap.read(4) )[0]
  555.         debugPrint( "decalGroupsCount", decalGroupsCount )
  556.         for decalGroupIndex in range(decalGroupsCount):
  557.             decalGroupId = unpack('I', scmap.read(4) )[0]
  558.             debugPrint( "decalGroupId", decalGroupId )
  559.             decalGroupName = readcstr(scmap)
  560.             debugPrint( "decalGroupName", decalGroupName )
  561.             decalGroupEntriesCount = unpack('I', scmap.read(4) )[0]
  562.             debugPrint( "decalGroupEntriesCount", decalGroupEntriesCount )
  563.             for i in range(decalGroupEntriesCount):
  564.                 decalGroupEntry = unpack('I', scmap.read(4) )[0]
  565.                 debugPrint( "decalGroupEntry", decalGroupEntry )
  566.            
  567.         (unknown19Width,unknown19Height) = unpack('II', scmap.read(8) )
  568.         debugPrint( "unknown19Width", unknown19Width )
  569.         debugPrint( "unknown19Height", unknown19Height )
  570.  
  571.         # most often 1, sometimes 4
  572.         normalMapsCount = unpack('I', scmap.read(4) )[0]
  573.         debugPrint( "normalMapsCount", normalMapsCount )
  574.         for normalMapIndex in range(normalMapsCount):
  575.        
  576.             normalMapDataLength = unpack('I', scmap.read(4) )[0]
  577.             debugPrint( "normalMapDataLength", normalMapDataLength )
  578.             normalMapData = scmap.read(normalMapDataLength)
  579.             debugPrint( "normalMapData", "{}...".format(normalMapData[:4]) )
  580.  
  581.             #if normalMapData[0:4] == DDSMAGIC:
  582.                 #pnormalMapDataPath = "{}_normalMap{}.dds".format( scmap.name, normalMapIndex )
  583.                 #with open(pnormalMapDataPath,'wb') as dumpFile:
  584.                     #dumpFile.write( normalMapData )
  585.                 #print("normalMapData dumped to \"{}\"".format(pnormalMapDataPath))
  586.  
  587.         if fileVersionMinor < 56:
  588.             unknown20 = unpack('I', scmap.read(4) )[0]
  589.             debugPrint( "unknown20", unknown20 )
  590.  
  591.         textureMapDataLength = unpack('I', scmap.read(4) )[0]
  592.         debugPrint( "textureMapDataLength", textureMapDataLength )
  593.         textureMapData = scmap.read(textureMapDataLength)
  594.         debugPrint( "textureMapData", "{}...".format(textureMapData[:4]) )
  595.  
  596.         if fileVersionMinor < 56:
  597.             unknown21 = unpack('I', scmap.read(4) )[0]
  598.             debugPrint( "unknown21", unknown21 )
  599.  
  600.         waterMapDataLength = unpack('I', scmap.read(4) )[0]
  601.         debugPrint( "waterMapDataLength", waterMapDataLength )
  602.         waterMapData = scmap.read(waterMapDataLength)
  603.         debugPrint( "waterMapData", "{}...".format(waterMapData[:4]) )
  604.        
  605.         if fileVersionMinor > 53:
  606.             unknown22 = unpack('I', scmap.read(4) )[0]
  607.             debugPrint( "unknown22", unknown22 )
  608.  
  609.             unknown23MapDataLength = unpack('I', scmap.read(4) )[0]
  610.             debugPrint( "unknown23MapDataLength", unknown23MapDataLength )
  611.             unknown23MapData = scmap.read(unknown23MapDataLength)
  612.             debugPrint( "unknown23MapData", "{}...".format(unknown23MapData[:4]) )
  613.  
  614.         someWaterMapLength = int( (mapWidth / 2) * (mapHeight / 2) )
  615.         waterFoamMapData = scmap.read(someWaterMapLength)
  616.         debugPrint( "waterFoamMapData", "{}...".format(waterFoamMapData[:4]) )
  617.         waterFlatnessMapData = scmap.read(someWaterMapLength)
  618.         debugPrint( "waterFlatnessMapData", "{}...".format(waterFlatnessMapData[:4]) )
  619.         waterDepthBiasMapData = scmap.read(someWaterMapLength)
  620.         debugPrint( "waterDepthBiasMapData", "{}...".format(waterDepthBiasMapData[:4]) )
  621.        
  622.         terrainTypeDataLength = mapWidth * mapHeight
  623.         debugPrint( "terrainTypeDataLength", "{}...".format(terrainTypeDataLength) )
  624.         terrainTypeData = scmap.read(terrainTypeDataLength)
  625.         debugPrint( "terrainTypeData", "{}...".format(terrainTypeData[:4]) )
  626.  
  627.         if fileVersionMinor < 53:
  628.             unknown24 = unpack('h', scmap.read(2) )[0]
  629.             debugPrint( "unknown24", unknown24 )
  630.        
  631.  
  632.         if fileVersionMinor >= 59:
  633.             unknown25 = scmap.read(64)
  634.             debugPrint( "unknown25", unknown25[:4] )
  635.             unknown26String = readcstr(scmap)
  636.             debugPrint( "unknown26String", unknown26String )
  637.             unknown27String = readcstr(scmap)
  638.             debugPrint( "unknown27String", unknown27String )
  639.             unknown28 = unpack('I', scmap.read(4) )[0]
  640.             debugPrint( "unknown28", unknown28 )
  641.             unknown28MagicFactor = 40
  642.             if unknown28 > 0:
  643.                 unknown29 = scmap.read( unknown28 * unknown28MagicFactor )
  644.                 debugPrint( "unknown29", unknown29[:4] )
  645.             unknown30 = scmap.read(19)
  646.             debugPrint( "unknown30", unknown30 )
  647.             unknown31String = readcstr(scmap)
  648.             debugPrint( "unknown31String", unknown31String )
  649.            
  650.             unknown31 = scmap.read(88)
  651.             debugPrint( "unknown31", unknown31[:4] )
  652.  
  653.         propsBlockStartOffset = scmap.tell()
  654.         infos["propsBlockStartOffset"] = propsBlockStartOffset
  655.  
  656.         propsCount = unpack('I', scmap.read(4) )[0]
  657.         debugPrint( "propsCount", propsCount )
  658.  
  659.         propsList = []
  660.         for propIndex in range( 0, propsCount ):
  661.             blueprintPath = readcstr(scmap)
  662.             debugPrint( "blueprintPath", blueprintPath )
  663.             position = unpack('fff', scmap.read(12) )
  664.             debugPrint( "position", position )
  665.             rotationX = unpack('fff', scmap.read(12) )
  666.             debugPrint( "rotationX", rotationX )
  667.             rotationY = unpack('fff', scmap.read(12) )
  668.             debugPrint( "rotationY", rotationY )
  669.             rotationZ = unpack('fff', scmap.read(12) )
  670.             debugPrint( "rotationZ", rotationZ )
  671.             scale = unpack('fff', scmap.read(12) )
  672.             debugPrint( "scale", scale )
  673.             # add this prop to prop to props list
  674.             propsList += [(blueprintPath,*position,*rotationX,*rotationY,*rotationZ,*scale)]
  675.             # create mirrored parameters
  676.             newPosition = mirrorPropPosition( position, mapSize )
  677.             #(newRotationX,newRotationY,newRotationZ) = (rotationX,rotationY,rotationZ)
  678.             (newRotationX,newRotationY,newRotationZ) = mirrorPropRotation(rotationX,rotationY,rotationZ)
  679.             # add version with mirrored parameters to props list
  680.             propsList += [(blueprintPath,*newPosition,*newRotationX,*newRotationY,*newRotationZ,*scale)]
  681.        
  682.         infos["propsList"] = propsList + listOfDebugProps
  683.            
  684.     return infos
  685.  
  686. def writeMirroredMap( pathToScmap, pathToNewScmap, infos ):
  687.     with open(pathToScmap,'rb') as scmap:
  688.         with open(pathToNewScmap,'wb') as newscmap:
  689.             newscmap.write(scmap.read(infos["decalsBlockStartOffset"]))
  690.             writeDecals( newscmap, infos["decalsList"] )
  691.             scmap.seek(infos["decalsBlockEndOffset"])
  692.             newscmap.write(scmap.read( infos["propsBlockStartOffset"] -infos["decalsBlockEndOffset"] ))
  693.             writeProps( newscmap, infos["propsList"] )
  694.            
  695. def writeDecals( newscmap, decalsList ):
  696.  
  697.     newscmap.write(pack('I',len(decalsList)))
  698.    
  699.     for decal in decalsList:
  700.         newscmap.write(decal)
  701.  
  702. def writeProps( newscmap, propsList ):
  703.  
  704.     newscmap.write(pack('I',len(propsList)))
  705.  
  706.     for prop in propsList:
  707.         newscmap.write(prop[0])
  708.         newscmap.write(b'\0')
  709.         newscmap.write(pack('fffffffffffffff',*prop[1:]))
  710.  
  711. if __name__ == '__main__':
  712.  
  713.     if len(sys.argv) < 3:
  714.         print("Usage: {} <infile> <outfile>".format(sys.argv[0]))
  715.         sys.exit(1)
  716.    
  717.     with ZipFile( decalsArchivePath, 'r' ) as decalsArchive:
  718.         decalsArchive.decalsCaseInsensitiveLookup = { s.lower():s for s in decalsArchive.namelist() }
  719.  
  720.         pathToNewScmap = sys.argv[2]
  721.         outDirectory = os.path.dirname( pathToNewScmap )
  722.         outMapNameWithVersion = os.path.basename( outDirectory )
  723.  
  724.         infos = readMap( pathToScmap = sys.argv[1], decalsArchive = decalsArchive )
  725.         writeMirroredMap( pathToScmap = sys.argv[1], pathToNewScmap = pathToNewScmap, infos = infos )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement