mirror of
https://github.com/crskycode/GARbro.git
synced 2026-07-08 01:30:18 +08:00
Add support of 256 color BIP
This commit is contained in:
@@ -1,11 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.Composition;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Media3D;
|
using System.Windows.Media.Imaging;
|
||||||
|
|
||||||
namespace GameRes.Formats.Kid
|
namespace GameRes.Formats.Kid
|
||||||
{
|
{
|
||||||
@@ -38,9 +34,18 @@ namespace GameRes.Formats.Kid
|
|||||||
return null; // throw new NotSupportedException(string.Format("BIP Chara format not supported."));
|
return null; // throw new NotSupportedException(string.Format("BIP Chara format not supported."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file.Seek(0x0C, SeekOrigin.Begin);
|
||||||
|
uint palettestart = file.ReadUInt16();
|
||||||
|
|
||||||
file.Seek(0x10, SeekOrigin.Begin);
|
file.Seek(0x10, SeekOrigin.Begin);
|
||||||
uint fstart = file.ReadUInt16(); // usually 0x100
|
uint fstart = file.ReadUInt16(); // usually 0x100
|
||||||
|
|
||||||
|
byte bpp = 32;
|
||||||
|
if (fstart - palettestart == 1024)
|
||||||
|
{
|
||||||
|
bpp = 8;
|
||||||
|
}
|
||||||
|
|
||||||
// Non-Sequential read
|
// Non-Sequential read
|
||||||
file.Seek(0x88, SeekOrigin.Begin); // next one +20
|
file.Seek(0x88, SeekOrigin.Begin); // next one +20
|
||||||
uint width = file.ReadUInt16();
|
uint width = file.ReadUInt16();
|
||||||
@@ -49,7 +54,7 @@ namespace GameRes.Formats.Kid
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
file.Seek(real_sign, SeekOrigin.Begin); // usually 0x14
|
file.Seek(real_sign, SeekOrigin.Begin); // usually 0x14
|
||||||
if ((file.ReadUInt16() & 0x7FFF) != fstart)
|
if ((file.ReadUInt16() & 0x3FFF) != fstart)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -105,6 +110,11 @@ namespace GameRes.Formats.Kid
|
|||||||
}
|
}
|
||||||
|
|
||||||
// uint dx = dy * 32;
|
// uint dx = dy * 32;
|
||||||
|
if (bpp == 8) //PSP format
|
||||||
|
{
|
||||||
|
dy = 16;
|
||||||
|
sliced = true;
|
||||||
|
}
|
||||||
|
|
||||||
return new BipImageMetaData
|
return new BipImageMetaData
|
||||||
{
|
{
|
||||||
@@ -113,6 +123,7 @@ namespace GameRes.Formats.Kid
|
|||||||
BlockSize = dy,
|
BlockSize = dy,
|
||||||
Sliced = sliced,
|
Sliced = sliced,
|
||||||
Multi = multi,
|
Multi = multi,
|
||||||
|
BPP = bpp,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
public override ImageData Read(IBinaryStream file, ImageMetaData info)
|
public override ImageData Read(IBinaryStream file, ImageMetaData info)
|
||||||
@@ -120,17 +131,19 @@ namespace GameRes.Formats.Kid
|
|||||||
if (info == null)
|
if (info == null)
|
||||||
throw new NotSupportedException(string.Format("Not BIP texture format."));
|
throw new NotSupportedException(string.Format("Not BIP texture format."));
|
||||||
var bipheader = (BipImageMetaData)info;
|
var bipheader = (BipImageMetaData)info;
|
||||||
|
|
||||||
|
byte m_bpp = (byte)(bipheader.BPP / 8);
|
||||||
file.Seek(0x10, SeekOrigin.Begin);
|
file.Seek(0x10, SeekOrigin.Begin);
|
||||||
uint fstart = file.ReadUInt16(); // usually 0x100
|
uint fstart = file.ReadUInt16(); // usually 0x100
|
||||||
file.Seek(fstart, SeekOrigin.Begin);
|
file.Seek(fstart, SeekOrigin.Begin);
|
||||||
byte[] pixels = new byte[bipheader.iWidth * bipheader.iHeight * 4];
|
byte[] pixels = new byte[bipheader.iWidth * bipheader.iHeight * m_bpp];
|
||||||
uint dy = bipheader.BlockSize;
|
uint dy = bipheader.BlockSize;
|
||||||
uint dx = dy * 32;
|
uint dx = dy * 32;
|
||||||
if (bipheader.Sliced)
|
if (bipheader.Sliced && m_bpp == 4)
|
||||||
{
|
{
|
||||||
long dwidth = ((bipheader.iWidth + (dy - 2) - 1) / (dy - 2)) * dy;
|
long dwidth = ((bipheader.iWidth + (dy - 2) - 1) / (dy - 2)) * dy;
|
||||||
long dheight = ((bipheader.iHeight + (dy - 2) - 1) / (dy - 2)) * dy;
|
long dheight = ((bipheader.iHeight + (dy - 2) - 1) / (dy - 2)) * dy;
|
||||||
long focus_H = (dwidth* dheight + dx - 1) / dx;
|
long focus_H = (dwidth * dheight + dx - 1) / dx;
|
||||||
long focus_T = (focus_H + dy - 1) / dy;
|
long focus_T = (focus_H + dy - 1) / dy;
|
||||||
|
|
||||||
for (int t = 0; t < focus_T; t++)
|
for (int t = 0; t < focus_T; t++)
|
||||||
@@ -139,7 +152,7 @@ namespace GameRes.Formats.Kid
|
|||||||
{
|
{
|
||||||
for (int x = 0; x < dx; x++)
|
for (int x = 0; x < dx; x++)
|
||||||
{
|
{
|
||||||
var pixel = file.ReadBytes(4); //RGBA with wrong A
|
var pixel = file.ReadBytes(m_bpp); //RGBA with wrong A
|
||||||
long i2x = x + t * dx;
|
long i2x = x + t * dx;
|
||||||
long i3t = i2x / dwidth;
|
long i3t = i2x / dwidth;
|
||||||
long i3x = i2x - i3t * dwidth;
|
long i3x = i2x - i3t * dwidth;
|
||||||
@@ -147,7 +160,7 @@ namespace GameRes.Formats.Kid
|
|||||||
long i4x = i3x - i3x / dy * dy + i3x / dy * (dy - 2);
|
long i4x = i3x - i3x / dy * dy + i3x / dy * (dy - 2);
|
||||||
if (i3x >= dwidth || i4x >= bipheader.iWidth || i3y >= bipheader.iHeight)
|
if (i3x >= dwidth || i4x >= bipheader.iWidth || i3y >= bipheader.iHeight)
|
||||||
continue;
|
continue;
|
||||||
long target = (i4x + i3y * bipheader.iWidth) * 4;
|
long target = (i4x + i3y * bipheader.iWidth) * m_bpp;
|
||||||
//BGRA
|
//BGRA
|
||||||
pixels[target] = pixel[2];
|
pixels[target] = pixel[2];
|
||||||
pixels[target + 1] = pixel[1];
|
pixels[target + 1] = pixel[1];
|
||||||
@@ -160,7 +173,36 @@ namespace GameRes.Formats.Kid
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if(bipheader.Sliced && m_bpp == 1)
|
||||||
|
{
|
||||||
|
long dwidth = ((bipheader.iWidth + (dy - 1) - 1) / (dy - 1)) * dy;
|
||||||
|
long dheight = ((bipheader.iHeight + (dy - 1) - 1) / (dy - 1)) * dy;
|
||||||
|
long focus_H = (dwidth * dheight + dx - 1) / dx;
|
||||||
|
long focus_T = (focus_H + dy - 1) / dy;
|
||||||
|
|
||||||
|
for (int t = 0; t < focus_T; t++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < dy; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < dx; x++)
|
||||||
|
{
|
||||||
|
var pixel = file.ReadUInt8();
|
||||||
|
var dytemp = dy * 2;
|
||||||
|
long i2x = x + (t >> 1) * dx;
|
||||||
|
long i3t = i2x / dwidth;
|
||||||
|
long i3x = i2x - i3t * dwidth;
|
||||||
|
long i3y = i3t * (dytemp - 2) + y + (t % 2) * dy - 1;
|
||||||
|
long i4x = i3x - i3x / dytemp * dytemp + i3x / dytemp * (dytemp - 2) - 1;
|
||||||
|
if (i3x >= dwidth || i4x >= bipheader.iWidth || i3y >= bipheader.iHeight || i4x < 0 || i3y < 0)
|
||||||
|
continue;
|
||||||
|
long target = i4x + i3y * bipheader.iWidth;
|
||||||
|
|
||||||
|
pixels[target] = pixel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else //if(!bipheader.Sliced)
|
||||||
{
|
{
|
||||||
long focus_H = (bipheader.iWidth * bipheader.iHeight + dx - 1) / dx;
|
long focus_H = (bipheader.iWidth * bipheader.iHeight + dx - 1) / dx;
|
||||||
long focus_T = (focus_H + dy - 1) / dy;
|
long focus_T = (focus_H + dy - 1) / dy;
|
||||||
@@ -170,27 +212,45 @@ namespace GameRes.Formats.Kid
|
|||||||
{
|
{
|
||||||
for (int x = 0; x < dx; x++)
|
for (int x = 0; x < dx; x++)
|
||||||
{
|
{
|
||||||
var pixel = file.ReadBytes(4); //RGBA with wrong A
|
var pixel = file.ReadBytes(m_bpp); //RGBA with wrong A
|
||||||
long i2x = x + t * dx;
|
long i2x = x + t * dx;
|
||||||
long i3t = i2x / bipheader.iWidth;
|
long i3t = i2x / bipheader.iWidth;
|
||||||
long i3x = i2x - i3t * bipheader.iWidth;
|
long i3x = i2x - i3t * bipheader.iWidth;
|
||||||
long i3y = i3t * dy + y;
|
long i3y = i3t * dy + y;
|
||||||
if (i3x >= bipheader.iWidth || i3y >= bipheader.iHeight)
|
if (i3x >= bipheader.iWidth || i3y >= bipheader.iHeight)
|
||||||
continue;
|
continue;
|
||||||
long target = (i3x + i3y * bipheader.iWidth) * 4;
|
long target = (i3x + i3y * bipheader.iWidth) * m_bpp;
|
||||||
//BGRA
|
if (m_bpp == 4)
|
||||||
pixels[target] = pixel[2];
|
{
|
||||||
pixels[target + 1] = pixel[1];
|
//BGRA
|
||||||
pixels[target + 2] = pixel[0];
|
pixels[target] = pixel[2];
|
||||||
if (pixel[3] >= byte.MaxValue / 2)
|
pixels[target + 1] = pixel[1];
|
||||||
pixels[target + 3] = byte.MaxValue;
|
pixels[target + 2] = pixel[0];
|
||||||
|
if (pixel[3] >= byte.MaxValue / 2)
|
||||||
|
pixels[target + 3] = byte.MaxValue;
|
||||||
|
else
|
||||||
|
pixels[target + 3] = (byte)(pixel[3] << 1);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
pixels[target + 3] = (byte)(pixel[3] << 1);
|
{
|
||||||
|
pixels[target] = pixel[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ImageData.Create(info, PixelFormats.Bgra32, null, pixels); ;
|
|
||||||
|
if (m_bpp == 1)
|
||||||
|
{
|
||||||
|
file.Seek(0x0C, SeekOrigin.Begin);
|
||||||
|
uint palettestart = file.ReadUInt16(); // usually 0x100
|
||||||
|
file.Seek(palettestart, SeekOrigin.Begin);
|
||||||
|
var color_map = ImageFormat.ReadColorMap(file.AsStream, 256, PaletteFormat.RgbA);
|
||||||
|
BitmapPalette Palette = new BitmapPalette(color_map);
|
||||||
|
|
||||||
|
return ImageData.Create(info, PixelFormats.Indexed8, Palette, pixels);
|
||||||
|
}
|
||||||
|
return ImageData.Create(info, PixelFormats.Bgra32, null, pixels);
|
||||||
}
|
}
|
||||||
public override void Write(Stream file, ImageData image)
|
public override void Write(Stream file, ImageData image)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user