/// <summary> /// loads, using a provided tcolor, the 32bpp raw image data with the specified pointer and dimensions. pitch should equal width /// </summary> internal unsafe Image LoadImage32(int width, int height, void* data, Color tcolor) { SoftGraphics sg = new SoftGraphics(); Softimage si = sg.newImage(width, height); si.load((int*)data); int* dptr = si.data; pr2.Common.Lib.alpha32(dptr, width * height, toArgb(tcolor)); Image img = NewImage(width, height); img.loadSoftimage(si); si.Dispose(); sg.Dispose(); return img; }
public unsafe VSP(string fname) { Stream s = ResourceManager.Open(fname); BinaryReader br = new BinaryReader(s); //signature if(br.ReadInt32() != 5264214) throw new NotAVspFileException(fname); //version int version = br.ReadInt32(); if(version != 6) throw new VspFileBrokenException("Wrong version; expected 6; received " + version.ToString(),fname); //tilesize int tilesize = br.ReadInt32(); if(tilesize != 16) throw new VspFileBrokenException("Wrong tilesize; expected 16; received " + tilesize.ToString(),fname); //miscstuff int format = br.ReadInt32(); int numTiles = br.ReadInt32(); int compression = br.ReadInt32(); tileIndex = new int[numTiles]; flipped = new bool[numTiles]; for (int i = 0; i < numTiles; i++) { tileIndex[i] = i; flipped[i] = false; } //find the size of texture we need. //our theory is that the minimal texture memory wastage is achieved by finding the smallest //square that can contain all the tiles int square = (int)Math.Sqrt(numTiles); if(square * square != numTiles) square++; tilesW = tilesH = square; tilesW = 128; tilesH = (numTiles / tilesW) + 1; BinaryReader zipbr = new BinaryReader(new CodecInputStream(s)); byte[] tilebuf = zipbr.ReadBytes(numTiles*16*16*3); SoftGraphics sg = new SoftGraphics(); //dice it up. Softimage si = sg.newImage(tilesW<<4,tilesH<<4); Softimage siVsp = sg.imageFrom24bpp(16, 16 * numTiles, tilebuf); for(int ty = 0, t = 0; ty < tilesH; ty++) for(int tx = 0; tx < tilesW; tx++, t++) //for(int i=0;i<numTiles;i++) if(t >= numTiles) break; else //sg.blitSubrect(0,i*16,16,16,(i&127)<<4,(i>>7)<<4,siVsp,si); sg.blitSubrect(0,t*16,16,16,tx<<4,ty<<4,siVsp,si); tiles = GameEngine.Game.LoadSoftimage(si); tiles.Alphafy(Color.Magenta); si.Dispose(); siVsp.Dispose(); // Animations int animationCount = br.ReadInt32(); animation = new VSPAnimation[animationCount]; for (int i = 0; i < animationCount; i++) { string name = StringBufferReader.read(s, 256); // Start index int start = br.ReadInt32(); // End index int end = br.ReadInt32(); // Delay between frames int delay = br.ReadInt32() * 10; // Animation mode. int mode = br.ReadInt32(); animation[i] = new VSPAnimation(name, start, end, delay, mode); } // Obstruction data int obsCount = br.ReadInt32(); zipbr = new BinaryReader(new CodecInputStream(s)); byte[] obspixels = zipbr.ReadBytes(obsCount * 16 * 16); Softimage siObs = sg.newImage(2048, ((numTiles + 128) >> 7) << 4); for (int tile = 0; tile < obsCount; tile++) { Softimage tileImage = sg.newImage(16, 16); for (int i = 0; i < 16 * 16; i++) { int idx = tile * 16 * 16 + i; int pixel = (obspixels[idx] != 0 ? sg.makeColor(255, 255, 255) : 0); tileImage.putPixel(i % tilesize, i / tilesize, pixel); } sg.blitSubrect(0, 0, 16, 16, (tile & 127) << 4, (tile >> 7) << 4, tileImage, siObs); tileImage.Dispose(); } obs = GameEngine.Game.LoadSoftimage(siObs); obs.Alphafy(Color.Black); siObs.Dispose(); br.Close(); }