O
O01eg
Guest
I read FS as described in Xeno-gears.htm, found some packs with 5 files, but cannot neither unpack them such LZS nor use them directly.
Last edited:
void * decompress_lzs(void * src, unsigned int srcLen, void * dst, unsigned int dstLen){ int iofs = 0, oofs = 0; u8 cmd=0, bit=0; while ((iofs < srcLen) && (oofs < dstLen)) { if (bit == 0) { cmd = ((u8*)src)[iofs++]; bit = 8; } if (~cmd&1) { ((u8*)dst)[oofs++]=((u8*)src)[iofs++]; } else { int a = ((u8*)src)[iofs++]; int b = ((u8*)src)[iofs++]; u16 o = ((u16)(b&0x0F)<<8) | a; u8 len = ((b&0xF0)>>4)+3; int rofs = oofs - o; for (int j=0; j<len; j++) { if (rofs < 0) { ((u8*)dst)[oofs++]=0; } else { ((u8*)dst)[oofs++]=((u8*)dst)[rofs]; } rofs++; } } cmd>>=1; bit--; } return dst;}
I think it is for all files I remember right now. Even for field maps where several compressed files are packed together each individual file starts with the length.Where can I get dstLen? First 4 bytes of blocks don't mean uncompressed size.


It depends on bpp (bits per pixel). Width of VRAM is 512 in case of 16bpp. Xenogears as I remember mostly use 4bpp so it gives you 2048 pixel width.There are some files, which I got from Chu-Chu model (28st file in dir19, sector 0x3ae5d, length 47032). Is X position of textures in vram can be 832 when width of vram is 512?
Is 4bpp texture use CLUT such pallete? But CLUT have 128 colors (more then 16, which can be address by 4 bits) and you store texures in 32bpp class Surface without converting.It depends on bpp (bits per pixel). Width of VRAM is 512 in case of 16bpp. Xenogears as I remember mostly use 4bpp so it gives you 2048 pixel width.
Yes it use palette. CLUT can have 16 or 256 colours.Is 4bpp texture use CLUT such pallete? But CLUT have 128 colors (more then 16, which can be address by 4 bits) and you store texures in 32bpp class Surface without converting.It depends on bpp (bits per pixel). Width of VRAM is 512 in case of 16bpp. Xenogears as I remember mostly use 4bpp so it gives you 2048 pixel width.
voidTextureFile::GetSurfaces(Surface* pClut, Surface* pVram){ TextureHeader* texture_header = (TextureHeader*)(mpBuffer); // palette if (texture_header->id == 0x00001101) { u16 vram_x = texture_header->vram_x + texture_header->move_x; u16 vram_y = texture_header->vram_y + texture_header->move_y; for (int y = vram_y; y < vram_y + texture_header->height; ++y) { for (int x = vram_x; x < vram_x + texture_header->width; ++x) { u16 src1 = GetU16LE(0x10 + (x - vram_x) * 0x02 + (y - vram_y) * texture_header->width * 0x02); *(pClut->pixels + x * 4 + pClut->width * 4 * y + 0) = ((src1 ) & 31) * 255 / 31; *(pClut->pixels + x * 4 + pClut->width * 4 * y + 1) = ((src1 >> 5) & 31) * 255 / 31; *(pClut->pixels + x * 4 + pClut->width * 4 * y + 2) = ((src1 >> 10) & 31) * 255 / 31; // set alpha only for first entry in clut if byte is set or all zero *(pClut->pixels + x * 4 + pClut->width * 4 * y + 3) = (x == vram_x && (src1 & 0x8000) || (src1 == 0)) ? 0 : 255; } } } // textures else if (texture_header->id == 0x00001100) { u16 vram_x = texture_header->vram_x + texture_header->move_x; u16 vram_y = texture_header->vram_y + texture_header->move_y; for (int y = vram_y; y < vram_y + texture_header->height; y++) { for (int x = vram_x * 2; x < vram_x * 2 + texture_header->width * 2; x++) { *(pVram->pixels + x + pVram->width * 4 * y) = GetU8(0x10 + (x - vram_x * 2) + (y - vram_y) * texture_header->width * 2); } } }}
Yup this is where it is converted.{SVN Q-gears}/trunk/src/xeno/filetypes/model/TextureFile.cpp:
Code: [Select]And for Surface:Code:voidTextureFile::GetSurfaces(Surface* pClut, Surface* pVram){ TextureHeader* texture_header = (TextureHeader*)(mpBuffer); // palette if (texture_header->id == 0x00001101) { u16 vram_x = texture_header->vram_x + texture_header->move_x; u16 vram_y = texture_header->vram_y + texture_header->move_y; for (int y = vram_y; y < vram_y + texture_header->height; ++y) { for (int x = vram_x; x < vram_x + texture_header->width; ++x) { u16 src1 = GetU16LE(0x10 + (x - vram_x) * 0x02 + (y - vram_y) * texture_header->width * 0x02); *(pClut->pixels + x * 4 + pClut->width * 4 * y + 0) = ((src1 ) & 31) * 255 / 31; *(pClut->pixels + x * 4 + pClut->width * 4 * y + 1) = ((src1 >> 5) & 31) * 255 / 31; *(pClut->pixels + x * 4 + pClut->width * 4 * y + 2) = ((src1 >> 10) & 31) * 255 / 31; // set alpha only for first entry in clut if byte is set or all zero *(pClut->pixels + x * 4 + pClut->width * 4 * y + 3) = (x == vram_x && (src1 & 0x8000) || (src1 == 0)) ? 0 : 255; } } } // textures else if (texture_header->id == 0x00001100) { u16 vram_x = texture_header->vram_x + texture_header->move_x; u16 vram_y = texture_header->vram_y + texture_header->move_y; for (int y = vram_y; y < vram_y + texture_header->height; y++) { for (int x = vram_x * 2; x < vram_x * 2 + texture_header->width * 2; x++) { *(pVram->pixels + x + pVram->width * 4 * y) = GetU8(0x10 + (x - vram_x * 2) + (y - vram_y) * texture_header->width * 2); } } }}ixels you create array of heigth*width*4 size, I understood that you use 32bpp. I clearly see converting to 32bpp in CLUT's part of code.
It'll look greater when I'll apply alpha channel and remove invisible blocks, but information about this is in unknown parts of animation files.That looks great!