#-------------------------------------------------------------------------------
# Purpose: convert all DoAO gsr files to dds (or only the _DXT doubles, to make a blacklist of bad _DXT files)
#-------------------------------------------------------------------------------
## options
path = "D:\games\DoA Online\data" # #WRITE HERE THE PATH TO THE DOAONLINE DATA FOLDER LOCATION
convert_doubles_only = True # True - convert only '_DXT.gsr' + doubles, False - converts ALL gsr to dds
save_to_output_folder = True # True - saves dss to the original folders, False - save all to 'GSR_textures' folder
import os, struct
##create folder
outdir = path[:-4]+"GSR_textures/"
testlist = []
##dds headers
ddsha = b"\x44\x44\x53\x20\x7C\x00\x00\x00\x07\x10\x0A\x00"# this + height + width + size + DXT*
tempdds = [0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0x20, 4,b'DXT1',0,0, 0,0,0,0x1000, 0,0,0,0]
ddshc = {
b'DXT1': struct.pack("<15L4s10L", *tempdds),
b'DXT3': struct.pack("<15L4s10L", *tempdds[:15]+[b'DXT3']+tempdds[16:]),
b'DXT5': struct.pack("<15L4s10L", *tempdds[:15]+[b'DXT5']+tempdds[16:]),
b'\x15\x00\x00\x00': struct.pack("<26L", *tempdds[:14]+[0x41,0,0x20,0xff0000, 0xff00,0xff,0xff000000,0x1000, 0,0,0,0]),
b'\x16\x00\x00\x00': struct.pack("<26L", *tempdds[:14]+[0x41,0,0x20,0xff0000, 0xff00,0xff,0xff000000,0x1000, 0,0,0,0])}
def main():
parsedir(path)
print(testlist)
if testlist:
if type(testlist[0])==bytes:
for tst in testlist:
print("".join(["%2s "%hex(c)[2:] for c in tst]))
elif type(testlist[0])==int:
print((len(testlist)*"%4xh ")%tuple(testlist))
def parsedir(path):
if not (os.path.exists(outdir) and os.path.isdir(outdir)):
os.makedirs(outdir)
filenames= os.listdir(path)
for filename in filenames: # loop through all the files and folders
fpath = os.path.join(path, filename)
if os.path.isdir(fpath):
parsedir(fpath)
else:
if not convert_doubles_only:
if len(filename) > 3 and filename[-4:] == '.gsr':
gsr2dds(fpath, outdir + filename[:-4] + '.dds')
elif len(filename) > 7 and filename[-8:] == '_dxt.gsr':
nondxtname = fpath[:-8] + '.gsr'
if os.path.isfile(nondxtname):
#copy these pairs to outdir; convert them to dds for visual comparison; make a blacklist of bad dxts
#get the gsr header
dxtdata = gsr2dds(fpath, outdir + filename[:-4] + '.dds')
gsrdata = gsr2dds(nondxtname, outdir + filename[:-8] + '.dds')
def gsr2dds(gsrpath, ddspath):
if os.path.isfile(ddspath):#if the file already exists then skip; TODO: add option to rename the file if already exists
print('dds already exist, skip:', gsrpath)
else:
with open(gsrpath, "rb") as f:
txheader = struct.unpack('<2L4s5L4s3L', f.read(0x30))#
if txheader[0] == 0x20 and txheader[2] == b'gsr\x00' and txheader[8] == b'tex\x00':#gsr header size, gsr0 magic, tex0 magic
f.seek(txheader[-1])
txmagic, txwidth, txheight, txun1, txsize, txoffset, pad1, pad2 = struct.unpack('<4s5L2L', f.read(0x20))#[b'DXT1', b'DXT3', b'DXT5', b'\x15\x00\x00\x00', b'\x16\x00\x00\x00'], width, height, [1 2 3 4 5], size, offset0
with open(ddspath, "wb") as fs:
fs.write(ddsha)
fs.write(struct.pack('<3L', txheight, txwidth, txsize))
fs.write(ddshc[txmagic])
fs.write(f.read())
return ''
if __name__ == '__main__':
main()