public TIM2(byte[] buffer, uint offset = 0) { pbs = new PseudoBufferedStream(buffer); timOffset = offset; pbs.Seek(offset, System.IO.SeekOrigin.Begin); pbs.Seek(4, System.IO.SeekOrigin.Current); //clutID byte bppIndicator = pbs.ReadByte(); bppIndicator = (byte)(bppIndicator == 0x08 ? 4 : bppIndicator == 0x09 ? 8 : bppIndicator == 0x02 ? 16 : bppIndicator == 0x03 ? 24 : 8); bpp = bppIndicator; texture = new Texture(); ReadParameters(bppIndicator); }
private static void ReadData() { ArchiveWorker aw = new ArchiveWorker(Memory.Archives.A_BATTLE); string[] test = aw.GetListOfFiles(); battlename = test.First(x => x.ToLower().Contains(battlename)); stageBuffer = ArchiveWorker.GetBinaryFile(Memory.Archives.A_BATTLE, battlename); pbs = new PseudoBufferedStream(stageBuffer); bs_cameraPointer = GetCameraPointer(); pbs.Seek(bs_cameraPointer, 0); ReadCamera(); uint sectionCounter = pbs.ReadUInt(); if (sectionCounter != 6) { Console.WriteLine($"BS_PARSER_PRE_OBJECTSECTION: Main geometry section has no 6 pointers at: {pbs.Tell()}"); battleModule++; return; } MainGeometrySection MainSection = ReadObjectGroupPointers(); ObjectsGroup[] objectsGroups = new ObjectsGroup[4] { ReadObjectsGroup(MainSection.Group1Pointer), ReadObjectsGroup(MainSection.Group2Pointer), ReadObjectsGroup(MainSection.Group3Pointer), ReadObjectsGroup(MainSection.Group4Pointer) }; modelGroups = new ModelGroup[4] { ReadModelGroup(objectsGroups[0].objectListPointer), ReadModelGroup(objectsGroups[1].objectListPointer), ReadModelGroup(objectsGroups[2].objectListPointer), ReadModelGroup(objectsGroups[3].objectListPointer) }; ReadTexture(MainSection.TexturePointer); ReadCharacters(); ReadMonster(); //for frames indexes monsters are first, then after n monsters characters appear with weapons frame = new int[monstersData.Length + charactersData.Length * 2]; battleModule++; }
private static void ParseBackground(byte[] mimb, byte[] mapb) { if (mimb == null || mapb == null) { return; } int type1Width = 1664; tiles = new List <Tile>(); int palletes = 24; //128x256 PseudoBufferedStream pbsmap = new PseudoBufferedStream(mapb); PseudoBufferedStream pbsmim = new PseudoBufferedStream(mimb); while (pbsmap.Tell() + 16 < pbsmap.Length) { Tile tile = new Tile { x = pbsmap.ReadShort() }; if (tile.x == 0x7FFF) { break; } tile.y = pbsmap.ReadShort(); tile.z = pbsmap.ReadUShort();// (ushort)(4096 - pbsmap.ReadUShort()); byte texIdBuffer = pbsmap.ReadByte(); tile.texID = (byte)(texIdBuffer & 0xF); pbsmap.Seek(1, SeekOrigin.Current); //short testz = pbsmap.ReadShort(); //testz = (short)(testz >> 6); //testz &= 0xF; tile.pallID = (byte)((pbsmap.ReadShort() >> 6) & 0xF); tile.srcx = pbsmap.ReadByte(); tile.srcy = pbsmap.ReadByte(); tile.layId = (byte)(pbsmap.ReadByte() & 0x7F); tile.blendType = pbsmap.ReadByte(); tile.parameter = pbsmap.ReadByte(); tile.state = pbsmap.ReadByte(); tile.blend1 = (byte)((texIdBuffer >> 4) & 0x1); tile.blend2 = (byte)(texIdBuffer >> 5); tiles.Add(tile); //srcY = srcX == texID * 128 + srcX; } int lowestY = tiles.Min(x => x.y); int maximumY = tiles.Max(x => x.y); int lowestX = tiles.Min(x => x.x); //-160; int maximumX = tiles.Max(x => x.x); height = Math.Abs(lowestY) + maximumY + 16; //224 width = Math.Abs(lowestX) + maximumX + 16; //320 byte[] finalImage = new byte[height * width * 4]; //ARGB; byte[] finalOverlapImage = new byte[height * width * 4]; tex = new Texture2D(Memory.graphics.GraphicsDevice, width, height); texOverlap = new Texture2D(Memory.graphics.GraphicsDevice, width, height); var MaximumLayer = tiles.Max(x => x.layId); var MinimumLayer = tiles.Min(x => x.layId); List <ushort> BufferDepth = tiles.GroupBy(x => x.z).Select(group => group.First()).Select(x => x.z).ToList(); BufferDepth.Sort(); for (int LayerId = 1; LayerId <= MaximumLayer + 1; LayerId++) { foreach (Tile tile in tiles) { if (LayerId != MaximumLayer + 1) { if (tile.layId != LayerId) { continue; } //if (tile.z != BufferDepth[LayerId]) // continue; } else if (tile.layId != 0) { continue; } int palettePointer = 4096 + ((tile.pallID) * 512); int sourceImagePointer = 512 * palletes; int realX = Math.Abs(lowestX) + tile.x; //baseX int realY = Math.Abs(lowestY) + tile.y; //*width int realDestinationPixel = ((realY * width) + realX) * 4; if (tile.blend2 >= 4) { int startPixel = sourceImagePointer + tile.srcx + 128 * tile.texID + (type1Width * tile.srcy); for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { byte pixel = mimb[startPixel + x + (y * 1664)]; ushort pixels = BitConverter.ToUInt16(mimb, 2 * pixel + palettePointer); if (pixels == 00) { continue; } byte red = (byte)((pixels) & 0x1F); byte green = (byte)((pixels >> 5) & 0x1F); byte blue = (byte)((pixels >> 10) & 0x1F); red = (byte)MathHelper.Clamp((red * 8), 0, 255); green = (byte)MathHelper.Clamp((green * 8), 0, 255); blue = (byte)MathHelper.Clamp((blue * 8), 0, 255); if (tile.blendType < 4) { if (true)//!bSaveToOverlapBuffer) { byte baseColorR = finalImage[realDestinationPixel + (x * 4) + (y * width * 4)]; byte baseColorG = finalImage[realDestinationPixel + (x * 4) + (y * width * 4) + 1]; byte baseColorB = finalImage[realDestinationPixel + (x * 4) + (y * width * 4) + 2]; Blend(baseColorR, baseColorG, baseColorB, red, green, blue, tile, finalImage, realDestinationPixel, x, y); } else { byte baseColorR = finalOverlapImage[realDestinationPixel + (x * 4) + (y * width * 4)]; byte baseColorG = finalOverlapImage[realDestinationPixel + (x * 4) + (y * width * 4) + 1]; byte baseColorB = finalOverlapImage[realDestinationPixel + (x * 4) + (y * width * 4) + 2]; Blend(baseColorR, baseColorG, baseColorB, red, green, blue, tile, finalOverlapImage, realDestinationPixel, x, y); } } else { if (true)//!bSaveToOverlapBuffer) { finalImage[realDestinationPixel + (x * 4) + (y * width * 4)] = red; finalImage[realDestinationPixel + (x * 4) + (y * width * 4) + 1] = green; finalImage[realDestinationPixel + (x * 4) + (y * width * 4) + 2] = blue; finalImage[realDestinationPixel + (x * 4) + (y * width * 4) + 3] = 0xFF; } else { finalOverlapImage[realDestinationPixel + (x * 4) + (y * width * 4)] = red; finalOverlapImage[realDestinationPixel + (x * 4) + (y * width * 4) + 1] = green; finalOverlapImage[realDestinationPixel + (x * 4) + (y * width * 4) + 2] = blue; finalOverlapImage[realDestinationPixel + (x * 4) + (y * width * 4) + 3] = 0xFF; } } } } } else { // int startPixel = sourceImagePointer + tile.srcx / 2 + 128 * tile.texID + (type1Width * tile.srcy); // for (int y = 0; y < 16; y++) // for (int x = 0; x < 16; x++) // { // byte index = mimb[startPixel + x + (y * 1664)]; // ushort pixels = BitConverter.ToUInt16(mimb, 2 * (index & 0xF) + palettePointer); // byte red = (byte)((pixels) & 0x1F); // byte green = (byte)((pixels >> 5) & 0x1F); // byte blue = (byte)((pixels >> 10) & 0x1F); // red = (byte)MathHelper.Clamp((red * 8), 0, 255); // green = (byte)MathHelper.Clamp((green * 8), 0, 255); // blue = (byte)MathHelper.Clamp((blue * 8), 0, 255); // if (pixels != 0) // { // if (tile.blendType < 4) // { // byte baseColorR = finalImage[realDestinationPixel + (x * 4) + (y * width * 4)]; // byte baseColorG = finalImage[realDestinationPixel + (x * 4) + (y * width * 4) + 1]; // byte baseColorB = finalImage[realDestinationPixel + (x * 4) + (y * width * 4) + 2]; // Blend(baseColorR, baseColorG, baseColorB, red, green, blue, tile, finalImage, realDestinationPixel, x, y); // } // } // pixels = BitConverter.ToUInt16(mimb, 2 * (index >> 4) + palettePointer); // red = (byte)((pixels) & 0x1F); // green = (byte)((pixels >> 5) & 0x1F); // blue = (byte)((pixels >> 10) & 0x1F); // red = (byte)MathHelper.Clamp((red * 8), 0, 255); // green = (byte)MathHelper.Clamp((green * 8), 0, 255); // blue = (byte)MathHelper.Clamp((blue * 8), 0, 255); // if (pixels != 0) // { // if (tile.blendType < 4) // { // byte baseColorR = finalImage[realDestinationPixel + (x * 4) + (y * width * 4)]; // byte baseColorG = finalImage[realDestinationPixel + (x * 4) + (y * width * 4) + 1]; // byte baseColorB = finalImage[realDestinationPixel + (x * 4) + (y * width * 4) + 2]; // Blend(baseColorR, baseColorG, baseColorB, red, green, blue, tile, finalImage, realDestinationPixel, x, y); // } // } // else // { // finalImage[realDestinationPixel + (x * 4) + (y * width * 4)] = red; // finalImage[realDestinationPixel + (x * 4) + (y * width * 4) + 1] = green; // finalImage[realDestinationPixel + (x * 4) + (y * width * 4) + 2] = blue; // finalImage[realDestinationPixel + (x * 4) + (y * width * 4) + 3] = 0xFF; // } // } } } } tex.SetData(finalImage); texOverlap.SetData(finalOverlapImage); }