from inc_noesis import * def registerNoesisTypes(): handle = noesis.register("Desert Strike Graphic", ".dsg") noesis.setHandlerTypeCheck(handle, dsgCheckType) noesis.setHandlerLoadRGBA(handle, dsgLoadRGBA) return 1 class DSGSpriteInfo: def __init__(self, reader): self.bgW = reader.readUShort() self.bgH = reader.readUShort() self.ofsX = reader.readUShort() self.ofsY = reader.readUShort() self.w = reader.readUShort() self.h = reader.readUShort() self.dataOfs = reader.readInt() self.data = None class DSGFile: def __init__(self, reader): self.reader = reader self.imageColorScale = (4.0, 4.0, 4.0, 1.0) def parseImageInfo(self): bs = self.reader if bs.getSize() < 32: return 0 idA = bs.readInt() idB = bs.readInt() if idA != 0x50415247 or idB != 0x53434948: return 0 self.unkA = bs.readShort() self.unkB = bs.readShort() self.sizeA = bs.readInt() self.unkC = bs.readInt() self.sizeB = bs.readInt() self.unkC = bs.readInt() self.unkD = bs.readInt() self.picOfs = bs.tell() picA = bs.readInt() picB = bs.readInt() if picA != 0x54434950 or picB != 0x20455255: #picture if picA != 0x49525053 or picB != 0x20534554: #sprites return 0 return 1 def loadPalette(self): bs = self.reader palA = bs.readInt() palB = bs.readInt() if palA != 0x454C4150 or palB != 0x20455454: return None numColors = bs.readInt() palSize = bs.readInt() resvA = bs.readInt() resvB = bs.readInt() resvC = bs.readInt() resvD = bs.readInt() pal = bytearray() palNum = palSize // 3 for i in range(0, palNum): palEntry = bs.readBytes(3) pal += palEntry + noePack("B", 255) pal += noePack("BBBB", 0, 0, 0, 0) #clear entry return pal def loadPicture(self): bs = self.reader cofs = bs.tell() picA = bs.readInt() picB = bs.readInt() if picA != 0x54434950 or picB != 0x20455255: bs.seek(cofs) return None unk = bs.readInt() width = bs.readUShort() height = bs.readUShort() pix = bs.readBytes(width*height) pal = self.loadPalette() if pal is None: bs.seek(cofs) return None data = rapi.imageDecodeRawPal(pix, pal, width, height, 8, "r8g8b8a8") data = rapi.imageScaleRGBA32(data, self.imageColorScale, width, height) tex = NoeTexture("dsgtex", width, height, data, noesis.NOESISTEX_RGBA32) tex.flags |= noesis.NTEXFLAG_FILTER_NEAREST | noesis.NTEXFLAG_WRAP_CLAMP return tex def loadSprites(self, texList): bs = self.reader cofs = bs.tell() sprA = bs.readInt() sprB = bs.readInt() if sprA != 0x49525053 or sprB != 0x20534554: return 0 numSpr = bs.readUShort() useTransparency = bs.readUShort() unkB = bs.readInt() spriteInfos = [] for i in range(0, numSpr): spriteInfos.append(DSGSpriteInfo(bs)) bs.seek(cofs+self.sizeA) pal = self.loadPalette() if pal is None: return 0 clearIdx = (len(pal) // 4) - 1 for spriteInfo in spriteInfos: if spriteInfo.w <= 0 or spriteInfo.h <= 0: continue #seems to be a valid case width = spriteInfo.w height = spriteInfo.h bs.seek(cofs+spriteInfo.dataOfs) if useTransparency & 1: pix = bytearray() if width & 7: width += (8 - (width&7)) while len(pix) < width*height: b = bs.readUByte() for i in range(0, 8): if b & (1<<(7-i)): pix += bs.readBytes(1) else: pix += noePack("B", clearIdx) else: pix = bs.readBytes(width*height) data = rapi.imageDecodeRawPal(pix, pal, width, height, 8, "r8g8b8a8") data = rapi.imageScaleRGBA32(data, self.imageColorScale, width, height) tex = NoeTexture("dsgtex", width, height, data, noesis.NOESISTEX_RGBA32) tex.flags |= noesis.NTEXFLAG_FILTER_NEAREST | noesis.NTEXFLAG_WRAP_CLAMP texList.append(tex) return 1 def loadPictures(self, texList): bs = self.reader bs.seek(self.picOfs) while bs.getOffset() < bs.getSize(): tex = self.loadPicture() if tex is not None: texList.append(tex) else: if self.loadSprites(texList) != 1: break #noesis passes in data as a bytearray def dsgCheckType(data): dsg = DSGFile(NoeBitStream(data)) if dsg.parseImageInfo() == 0: return 0 return 1 def dsgLoadRGBA(data, texList): dsg = DSGFile(NoeBitStream(data)) if dsg.parseImageInfo() == 0: return 0 dsg.loadPictures(texList) if len(texList) > 0: return 1 return 0