public void Convert() { string directory = Path.GetFullPath(@"data\levels\ehz"); Landscape landscape = new Landscape(); int chunkId = 0; foreach (LayoutBlock chunk in mLayoutBlocks) { Landscape.Chunk lchunk = new Landscape.Chunk(); for (int layer = 0; layer < 2; layer++) { Landscape.Chunk.Layer lclayer = new Landscape.Chunk.Layer(); // Angles for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { LayoutBlock.LayoutBlockTile chunkBlock = chunk.Tiles[x, y]; if (chunkBlock.Index >= mTileBlocks.Count) { lclayer.Angles[x, y] = 0; continue; } TileBlock block = mTileBlocks[chunkBlock.Index]; int ci = (layer == 0 ? block.SecondaryCollision : block.PrimaryCollision); sbyte angle = mCurveMapping[ci]; if (chunkBlock.X) { angle = (sbyte)-angle; } if (chunkBlock.Y) { angle = (sbyte)(-(angle + 64) - 64); } lclayer.Angles[x, y] = angle; } } // LRB for (int y = 0; y < 128; y++) { for (int x = 0; x < 128; x++) { int blockX = x / 16; int blockY = y / 16; int tileX = (x % 16) / 2; int tileY = (y % 16) / 2; LayoutBlock.LayoutBlockTile chunkBlock = chunk.Tiles[blockX, blockY]; if (layer == 0) { if ((chunkBlock.SS & 2) == 0) { lclayer.CollisionLRB[x, y] = false; continue; } } else { if ((chunkBlock.TT & 2) == 0) { lclayer.CollisionLRB[x, y] = false; continue; } } if (chunkBlock.Index >= mTileBlocks.Count) { lclayer.CollisionLRB[x, y] = false; continue; } int px = x % 16; int py = y % 16; if (chunkBlock.X) { px = 15 - px; } if (chunkBlock.Y) { py = 15 - py; } TileBlock block = mTileBlocks[chunkBlock.Index]; int ci = (layer == 0 ? block.SecondaryCollision : block.PrimaryCollision); sbyte collision = mCollisionArray1[ci * 16 + px]; bool solid; if (collision == 0) { solid = false; } else if (collision > 0) { solid = collision >= (16 - py); } else { throw new Exception(); } lclayer.CollisionLRB[x, y] = solid; } } // TOP for (int y = 0; y < 128; y++) { for (int x = 0; x < 128; x++) { int blockX = x / 16; int blockY = y / 16; int tileX = (x % 16) / 2; int tileY = (y % 16) / 2; LayoutBlock.LayoutBlockTile chunkBlock = chunk.Tiles[blockX, blockY]; if (layer == 0) { if ((chunkBlock.SS & 1) == 0) { lclayer.CollisionT[x, y] = false; continue; } } else { if ((chunkBlock.TT & 1) == 0) { lclayer.CollisionT[x, y] = false; continue; } } if (chunkBlock.Index >= mTileBlocks.Count) { lclayer.CollisionT[x, y] = false; continue; } int px = x % 16; int py = y % 16; if (chunkBlock.X) { px = 15 - px; } if (chunkBlock.Y) { py = 15 - py; } TileBlock block = mTileBlocks[chunkBlock.Index]; int ci = (layer == 0 ? block.SecondaryCollision : block.PrimaryCollision); sbyte collision = mCollisionArray1[ci * 16 + px]; bool solid; if (collision == 0) { solid = false; } else if (collision > 0) { solid = collision >= (16 - py); } else { throw new Exception(); } lclayer.CollisionT[x, y] = solid; } } // Art Landscape.Chunk.Layer.Image lcli = new Landscape.Chunk.Layer.Image(); lcli.AnimationDuration = 0; lcli.AnimationFrames = 1; Color[] bits128 = GetFGChunkArt(chunkId, (layer == 0), (layer == 1)); Color[] bits512 = new Color[512 * 512]; for (int y = 0; y < 512; y++) { for (int x = 0; x < 512; x++) { bits512[y * 512 + x] = bits128[(y / 4) * 128 + (x / 4)]; } } lcli.FrameData = new byte[1][]; MemoryStream ms2 = new MemoryStream(); BinaryWriter bw2 = new BinaryWriter(ms2); for (int i = 0; i < 512 * 512; i++) { bw2.Write(bits512[i].R); bw2.Write(bits512[i].G); bw2.Write(bits512[i].B); bw2.Write(bits512[i].A); } lcli.FrameData[0] = ms2.ToArray(); ms2.Close(); lclayer.Art = lcli; if (layer == 0) { lchunk.BackLayer = lclayer; } else { lchunk.FrontLayer = lclayer; } } landscape.Chunks.Add(lchunk); chunkId++; } landscape.Save(directory + "\\landscape.dat"); return; // Level MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); // Layout bw.Write("Emerald Hill, Act 1"); bw.Write("Sega"); bw.Write(88); bw.Write(8); for (int y = 0; y < 8; y++) { for (int x = 0; x < 88; x++) { bw.Write(mFGLayoutTiles[x, y]); } } // Objects List <object> objects = new List <object>(); // Player start objects.Add(new { Id = 1, Subtype = 0, X = 0x0060, Y = 0x028F, Respawn = false, Xflip = false, Yflip = false }); for (int i = 0; i < mObjects.Length; i += 6) { short x = BitConverter.ToInt16(new byte[] { mObjects[i + 1], mObjects[i + 0] }, 0); short y = BitConverter.ToInt16(new byte[] { mObjects[i + 3], (byte)(mObjects[i + 2] & 0x0F) }, 0); byte id = mObjects[i + 4]; byte subtype = mObjects[i + 5]; bool respawn = ((mObjects[i + 2] & 0x80) == 0); bool xflip = ((mObjects[i + 2] & 0x40) != 0); bool yflip = ((mObjects[i + 2] & 0x20) != 0); objects.Add(new { Id = (int)id, Subtype = (int)subtype, X = (int)x, Y = (int)y, Respawn = respawn, Xflip = xflip, Yflip = yflip }); } for (int i = 0; i < mRings.Length; i += 4) { short x = BitConverter.ToInt16(new byte[] { mRings[i + 1], mRings[i + 0] }, 0); if (x == -1) { break; } short y = BitConverter.ToInt16(new byte[] { mRings[i + 3], (byte)(mRings[i + 2] & 0x0F) }, 0); int t = mRings[i + 2] >> 4; bool column = ((t & 8) != 0); int c = (t & 7) + 1; for (int j = 0; j < c; j++) { objects.Add(new { Id = 37, Subtype = 0, X = (int)x, Y = (int)y, Respawn = false, Xflip = false, Yflip = false }); if (column) { y += 24; } else { x += 24; } } } bw.Write(objects.Count); foreach (dynamic obj in objects) { bw.Write(obj.Id); bw.Write(obj.Subtype); bw.Write(obj.X); bw.Write(obj.Y); bw.Write(obj.Respawn); bw.Write(obj.Xflip); bw.Write(obj.Yflip); } bw.Close(); File.WriteAllBytes(directory + "\\act1.dat", ms.ToArray()); }