protected override void PrepareDrawBitmap(ImageData img, VirtScreen vs, Point p, int width, int height, int stripnr, int numstrip) { if (_objectMode) { var imgData = (ImageData1)img; objectMap = imgData.ObjectMap; } }
public virtual ImageData Clone() { var data = new ImageData{ IsBomp = IsBomp }; data.Data = new byte[Data.Length]; Array.Copy(Data, data.Data, Data.Length); foreach (var zplane in ZPlanes) { data.ZPlanes.Add(zplane.Clone()); } return data; }
byte[] GrabPixels(ImageData im, int w, int h) { // Backup the screen content var backup = (byte[])MainVirtScreen.Surfaces[0].Pixels.Clone(); // Do some drawing DrawBox(0, 0, w - 1, h - 1, 0xFF); MainVirtScreen.HasTwoBuffers = false; Gdi.IsZBufferEnabled = false; Gdi.DrawBitmap(im, MainVirtScreen, _screenStartStrip, 0, w, h, 0, w / 8, MainVirtScreen.Width, DrawBitmaps.None); MainVirtScreen.HasTwoBuffers = true; Gdi.IsZBufferEnabled = true; // Grab the data we just drew and setup the cursor with it var pixels = Capture(MainVirtScreen, MainVirtScreen.XStart, 0, w, h); // Restore the screen content Array.Copy(backup, MainVirtScreen.Surfaces[0].Pixels, backup.Length); return pixels; }
ImageData ReadImage(Stream stream, int numStrips) { var br = new BinaryReader(stream); var img = new ImageData(); var size = br.ReadInt32(); br.BaseStream.Seek(-4, SeekOrigin.Current); if (size != 0) { img.Data = br.ReadBytes(size + 2); br.BaseStream.Seek(-2, SeekOrigin.Current); size = br.ReadUInt16(); if (br.BaseStream.Position == br.BaseStream.Length) { size = 0; } } while (size != 0 && img.ZPlanes.Count < 3) { var zPlane = ReadZPlane(br, size, numStrips); img.ZPlanes.Add(zPlane); size = 0; br.BaseStream.Seek(-2, SeekOrigin.Current); if ((br.BaseStream.Position + 2) < br.BaseStream.Length) { size = br.ReadUInt16(); } } return img; }
protected ImageData ReadImage(long size, int numStrips) { var img = new ImageData(); var it = CreateChunkIterator(size); while (it.MoveNext()) { if (it.Current.Tag == "SMAP") { img.Data = _reader.ReadBytes((int)(it.Current.Size)); } else if (it.Current.Tag.StartsWith("ZP", StringComparison.Ordinal)) { var zpNum = int.Parse(it.Current.Tag.Substring(2), System.Globalization.NumberStyles.HexNumber); ZPlane zplane; using (var ms = new MemoryStream(_reader.ReadBytes((int)(it.Current.Size)))) { var br = new BinaryReader(ms); zplane = ReadZPlane(br, (int)(it.Current.Size), numStrips); } img.ZPlanes.Add(zplane); } else if (it.Current.Tag == "BOMP") { img = ReadBomp(it.Current.Size - 8); } else { UnknownChunk(it.Current); } } return img; }
protected IList<ImageData> ReadImages(long size) { var images = new List<ImageData>(); var it = CreateChunkIterator(size); while (it.MoveNext()) { if (it.Current.Tag == "WRAP") { it = CreateChunkIterator(it.Current.Size); } else if (it.Current.Tag == "OFFS") { // skip it } else if (it.Current.Tag == "BOMP") { var img = ReadBomp(it.Current.Size - 8); images.Add(img); } else if (it.Current.Tag == "OBIM") { // Object Image var obj = ReadObjectImages(it.Current.Size - 8); images.AddRange(obj.Images); } else if (it.Current.Tag == "SMAP") { var img = new ImageData(); img.Data = _reader.ReadBytes((int)(it.Current.Size - 8)); images.Add(img); } else { UnknownChunk(it.Current); } } return images; }
protected virtual ImageData ReadBomp(long size) { var id = _reader.ReadUInt16(); var width = _reader.ReadUInt16(); var height = _reader.ReadUInt16(); var padding = _reader.ReadUInt32(); var img = new ImageData(); img.Data = _reader.ReadBytes((int)(size - 10)); img.IsBomp = true; return img; }
protected override void PrepareDrawBitmap(ImageData img, VirtScreen vs, Point p, int width, int height, int stripnr, int numstrip) { var ptr = img.Data; // // Since V3, all graphics data was encoded in strips, which is very efficient // for redrawing only parts of the screen. However, V2 is different: here // the whole graphics are encoded as one big chunk. That makes it rather // difficult to draw only parts of a room/object. We handle the V2 graphics // differently from all other (newer) graphic formats for this reason. // var table = (_objectMode ? null : _roomStrips); int left = (stripnr * 8); int right = left + (numstrip * 8); PixelNavigator navDst; var srcOffset = 0; byte color, data = 0; int run; bool dither = false; byte[] dither_table = new byte[128]; var ditherOffset = 0; int theX, theY, maxX; var surface = vs.HasTwoBuffers ? vs.Surfaces[1] : vs.Surfaces[0]; navDst = new PixelNavigator(surface); navDst.GoTo(p.X * 8, p.Y); var mask_ptr = GetMaskBuffer(p.X, p.Y, 1); if (table != null) { run = table.run[stripnr]; color = (byte)table.color[stripnr]; srcOffset = table.offsets[stripnr]; theX = left; maxX = right; } else { run = 1; color = 0; srcOffset = 0; theX = 0; maxX = width; } // Decode and draw the image data. Debug.Assert(height <= 128); for (; theX < maxX; theX++) { ditherOffset = 0; for (theY = 0; theY < height; theY++) { if (--run == 0) { data = ptr[srcOffset++]; if ((data & 0x80) != 0) { run = data & 0x7f; dither = true; } else { run = data >> 4; dither = false; } color = RoomPalette[data & 0x0f]; if (run == 0) { run = ptr[srcOffset++]; } } if (!dither) { dither_table[ditherOffset] = color; } if (left <= theX && theX < right) { navDst.Write(dither_table[ditherOffset++]); navDst.OffsetY(1); } } if (left <= theX && theX < right) { navDst.Offset(1, -height); } } // Draw mask (zplane) data theY = 0; if (table != null) { srcOffset = table.zoffsets[stripnr]; run = table.zrun[stripnr]; theX = left; } else { run = ptr[srcOffset++]; theX = 0; } while (theX < right) { byte runFlag = (byte)(run & 0x80); if (runFlag != 0) { run &= 0x7f; data = ptr[srcOffset++]; } do { if (runFlag == 0) data = ptr[srcOffset++]; if (left <= theX) { mask_ptr.Write(data); mask_ptr.OffsetY(1); } theY++; if (theY >= height) { if (left <= theX) { mask_ptr.Offset(1, -height); } theY = 0; theX += 8; if (theX >= right) break; } } while ((--run) != 0); run = ptr[srcOffset++]; } }
public Room() { Boxes = new List<Box>(); Objects = new List<ObjectData>(); BoxMatrix = new List<byte>(); EntryScript = new ScriptData(); ExitScript = new ScriptData(); LocalScripts = new ScriptData[1024]; TransparentColor = 255; Scales = new ScaleSlot[0]; ColorCycle = new ColorCycle[16]; for (int i = 0; i < ColorCycle.Length; i++) { ColorCycle[i] = new ColorCycle(); } Image = new ImageData(); Palettes = new List<Palette>(); Palettes.Add(new Palette()); }
protected override ImageData ReadBomp(long size) { var width = _reader.ReadUInt32(); var height = _reader.ReadUInt32(); var img = new ImageData(); img.Data = _reader.ReadBytes((int)(size - 8)); img.IsBomp = true; return img; }
protected virtual void PrepareDrawBitmap(ImageData img, VirtScreen vs, Point p, int width, int height, int stripnr, int numstrip) { }
public void DrawBitmap(ImageData img, VirtScreen vs, Point p, int width, int height, int stripnr, int numstrip, int roomWidth, DrawBitmaps flags, bool isLightOn) { var x = p.X; var y = p.Y; if ((_vm.TownsPaletteFlags & 2) != 0) { int cx = (x - _vm.ScreenStartStrip) << 3; Gdi.Fill(_vm.TextSurface, new Rect(cx * _vm.TextSurfaceMultiplier, y * _vm.TextSurfaceMultiplier, (cx + width - 1) * _vm.TextSurfaceMultiplier, (y + height - 1) * _vm.TextSurfaceMultiplier), 0); } _objectMode = flags.HasFlag(DrawBitmaps.ObjectMode); PrepareDrawBitmap(img, vs, p, width, height, stripnr, numstrip); int sx = x - vs.XStart / 8; if (sx < 0) { numstrip -= -sx; x += -sx; stripnr += -sx; sx = 0; } // Compute the number of strips we have to iterate over. // TODO/FIXME: The computation of its initial value looks very fishy. // It was added as a kind of hack to fix some corner cases, but it compares // the room width to the virtual screen width; but the former should always // be bigger than the latter (except for MM NES, maybe)... strange int limit = Math.Max(roomWidth, vs.Width) / 8 - x; if (limit > numstrip) limit = numstrip; if (limit > NumStrips - sx) limit = NumStrips - sx; for (int k = 0; k < limit; ++k, ++stripnr, ++sx, ++x) { if (y < vs.TDirty[sx]) vs.TDirty[sx] = y; if (y + height > vs.BDirty[sx]) vs.BDirty[sx] = y + height; // In the case of a double buffered virtual screen, we draw to // the backbuffer, otherwise to the primary surface memory. var surface = vs.HasTwoBuffers ? vs.Surfaces[1] : vs.Surfaces[0]; var navDst = new PixelNavigator(surface); navDst.GoTo(x * 8, y); bool transpStrip; using (var smapReader = new BinaryReader(new MemoryStream(img.Data))) { transpStrip = DrawStrip(navDst, width, height, stripnr, smapReader); } // COMI and HE games only uses flag value if (game.Version == 8) transpStrip = true; if (vs.HasTwoBuffers) { var navFrontBuf = new PixelNavigator(vs.Surfaces[0]); navFrontBuf.GoTo(x * 8, y); if (isLightOn) Copy8Col(navFrontBuf, navDst, height); else Clear8Col(navFrontBuf, height); } DecodeMask(x, y, width, height, stripnr, img.ZPlanes, transpStrip, flags); } }
public void DrawBitmap(ImageData img, VirtScreen vs, int x, int y, int width, int height, int stripnr, int numstrip, int roomWidth, DrawBitmaps flags) { // Check whether lights are turned on or not var lightsOn = _vm.IsLightOn(); DrawBitmap(img, vs, new Point(x, y), width, height, stripnr, numstrip, roomWidth, flags, lightsOn); }