mirror of
https://github.com/aap/librw.git
synced 2024-11-25 05:05:42 +00:00
xbox raster to image
This commit is contained in:
parent
c60cecbd02
commit
9b56671186
@ -3,6 +3,9 @@ namespace xbox {
|
|||||||
|
|
||||||
void registerPlatformPlugins(void);
|
void registerPlatformPlugins(void);
|
||||||
|
|
||||||
|
extern int v3dFormatMap[6];
|
||||||
|
extern int v2dFormatMap[6];
|
||||||
|
|
||||||
struct InstanceData
|
struct InstanceData
|
||||||
{
|
{
|
||||||
uint32 minVert;
|
uint32 minVert;
|
||||||
|
@ -5,6 +5,7 @@ void rasterCreate(Raster *raster);
|
|||||||
uint8 *rasterLock(Raster *raster, int32 level);
|
uint8 *rasterLock(Raster *raster, int32 level);
|
||||||
void rasterUnlock(Raster*, int32);
|
void rasterUnlock(Raster*, int32);
|
||||||
int32 rasterNumLevels(Raster *raster);
|
int32 rasterNumLevels(Raster *raster);
|
||||||
|
Image *rasterToImage(Raster *raster);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
177
src/d3d/xbox.cpp
177
src/d3d/xbox.cpp
@ -28,7 +28,7 @@ driverOpen(void *o, int32, int32)
|
|||||||
engine->driver[PLATFORM_XBOX]->rasterLock = rasterLock;
|
engine->driver[PLATFORM_XBOX]->rasterLock = rasterLock;
|
||||||
engine->driver[PLATFORM_XBOX]->rasterUnlock = rasterUnlock;
|
engine->driver[PLATFORM_XBOX]->rasterUnlock = rasterUnlock;
|
||||||
engine->driver[PLATFORM_XBOX]->rasterNumLevels = rasterNumLevels;
|
engine->driver[PLATFORM_XBOX]->rasterNumLevels = rasterNumLevels;
|
||||||
// TODO: from image
|
engine->driver[PLATFORM_XBOX]->rasterToImage = rasterToImage;
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
@ -187,14 +187,14 @@ registerNativeDataPlugin(void)
|
|||||||
getSizeNativeData);
|
getSizeNativeData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
D3DPT_TRIANGLELIST = 5,
|
||||||
|
D3DPT_TRIANGLESTRIP = 6,
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
{
|
{
|
||||||
enum {
|
|
||||||
D3DPT_TRIANGLELIST = 5,
|
|
||||||
D3DPT_TRIANGLESTRIP = 6,
|
|
||||||
};
|
|
||||||
|
|
||||||
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
|
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
|
||||||
Geometry *geo = atomic->geometry;
|
Geometry *geo = atomic->geometry;
|
||||||
// TODO: allow for REINSTANCE (or not, xbox can't render)
|
// TODO: allow for REINSTANCE (or not, xbox can't render)
|
||||||
@ -214,7 +214,8 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
|||||||
header->data = rwNewT(uint8, header->size + 0x18, MEMDUR_EVENT | ID_GEOMETRY);
|
header->data = rwNewT(uint8, header->size + 0x18, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
header->serialNumber = 0;
|
header->serialNumber = 0;
|
||||||
header->numMeshes = meshh->numMeshes;
|
header->numMeshes = meshh->numMeshes;
|
||||||
header->primType = meshh->flags == 1 ? D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST;
|
header->primType = meshh->flags == MeshHeader::TRISTRIP ?
|
||||||
|
D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST;
|
||||||
header->numVertices = geo->numVertices;
|
header->numVertices = geo->numVertices;
|
||||||
header->vertexAlpha = 0;
|
header->vertexAlpha = 0;
|
||||||
// set by the instanceCB
|
// set by the instanceCB
|
||||||
@ -251,13 +252,25 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
|||||||
return;
|
return;
|
||||||
assert(geo->instData != nil);
|
assert(geo->instData != nil);
|
||||||
assert(geo->instData->platform == PLATFORM_XBOX);
|
assert(geo->instData->platform == PLATFORM_XBOX);
|
||||||
geo->numTriangles = geo->meshHeader->guessNumTriangles();
|
|
||||||
geo->allocateData();
|
|
||||||
geo->allocateMeshes(geo->meshHeader->numMeshes, geo->meshHeader->totalIndices, 0);
|
|
||||||
|
|
||||||
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
|
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
|
||||||
InstanceData *inst = header->begin;
|
InstanceData *inst = header->begin;
|
||||||
Mesh *mesh = geo->meshHeader->getMeshes();
|
Mesh *mesh = geo->meshHeader->getMeshes();
|
||||||
|
// For some reason numIndices in mesh and instance data are not always equal
|
||||||
|
// And primitive isn't always correct either. Maybe some internal conversion...
|
||||||
|
geo->meshHeader->totalIndices = 0;
|
||||||
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
|
mesh[i].numIndices = inst[i].numIndices;
|
||||||
|
geo->meshHeader->totalIndices += mesh[i].numIndices;
|
||||||
|
}
|
||||||
|
geo->meshHeader->flags = header->primType == D3DPT_TRIANGLESTRIP ?
|
||||||
|
MeshHeader::TRISTRIP : 0;
|
||||||
|
|
||||||
|
geo->numTriangles = geo->meshHeader->guessNumTriangles();
|
||||||
|
geo->allocateData();
|
||||||
|
geo->allocateMeshes(geo->meshHeader->numMeshes, geo->meshHeader->totalIndices, 0);
|
||||||
|
|
||||||
|
mesh = geo->meshHeader->getMeshes();
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
uint16 *indices = (uint16*)inst->indexBuffer;
|
uint16 *indices = (uint16*)inst->indexBuffer;
|
||||||
memcpy(mesh->indices, indices, inst->numIndices*2);
|
memcpy(mesh->indices, indices, inst->numIndices*2);
|
||||||
@ -587,6 +600,149 @@ rasterNumLevels(Raster *raster)
|
|||||||
return levels->numlevels;
|
return levels->numlevels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
unswizzle(uint8 *dst, uint8 *src, int32 w, int32 h, int32 bpp)
|
||||||
|
{
|
||||||
|
uint32 maskU = 0;
|
||||||
|
uint32 maskV = 0;
|
||||||
|
int32 i = 1;
|
||||||
|
int32 j = 1;
|
||||||
|
int32 c;
|
||||||
|
do{
|
||||||
|
c = 0;
|
||||||
|
if(i < w){
|
||||||
|
maskU |= j;
|
||||||
|
j <<= 1;
|
||||||
|
c = j;
|
||||||
|
}
|
||||||
|
if(i < h){
|
||||||
|
maskV |= j;
|
||||||
|
j <<= 1;
|
||||||
|
c = j;
|
||||||
|
}
|
||||||
|
i <<= 1;
|
||||||
|
}while(c);
|
||||||
|
int32 x, y, u, v;
|
||||||
|
v = 0;
|
||||||
|
for(y = 0; y < h; y++){
|
||||||
|
u = 0;
|
||||||
|
for(x = 0; x < w; x++){
|
||||||
|
memcpy(&dst[(y*w + x)*bpp], &src[(u|v)*bpp], bpp);
|
||||||
|
u = (u - maskU) & maskU;
|
||||||
|
}
|
||||||
|
v = (v - maskV) & maskV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Image*
|
||||||
|
rasterToImage(Raster *raster)
|
||||||
|
{
|
||||||
|
int32 depth;
|
||||||
|
Image *image;
|
||||||
|
XboxRaster *natras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset);
|
||||||
|
|
||||||
|
if(natras->format){
|
||||||
|
image = Image::create(raster->width, raster->height, 32);
|
||||||
|
image->allocate();
|
||||||
|
uint8 *pix = raster->lock(0);
|
||||||
|
switch(natras->format){
|
||||||
|
case D3DFMT_DXT1:
|
||||||
|
image->setPixelsDXT(1, pix);
|
||||||
|
// TODO: is this correct?
|
||||||
|
if(!natras->hasAlpha)
|
||||||
|
image->removeMask();
|
||||||
|
break;
|
||||||
|
case D3DFMT_DXT3:
|
||||||
|
image->setPixelsDXT(3, pix);
|
||||||
|
break;
|
||||||
|
case D3DFMT_DXT5:
|
||||||
|
image->setPixelsDXT(5, pix);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0 && "unknown format");
|
||||||
|
raster->unlock(0);
|
||||||
|
image->destroy();
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
raster->unlock(0);
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(raster->format & 0xF00){
|
||||||
|
case Raster::C1555:
|
||||||
|
depth = 16;
|
||||||
|
break;
|
||||||
|
case Raster::C8888:
|
||||||
|
depth = 32;
|
||||||
|
break;
|
||||||
|
case Raster::C888:
|
||||||
|
depth = 24;
|
||||||
|
break;
|
||||||
|
case Raster::C555:
|
||||||
|
depth = 16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case Raster::C565:
|
||||||
|
case Raster::C4444:
|
||||||
|
case Raster::LUM8:
|
||||||
|
assert(0 && "unsupported raster format");
|
||||||
|
}
|
||||||
|
int32 pallength = 0;
|
||||||
|
if((raster->format & Raster::PAL4) == Raster::PAL4){
|
||||||
|
depth = 4;
|
||||||
|
pallength = 16;
|
||||||
|
}else if((raster->format & Raster::PAL8) == Raster::PAL8){
|
||||||
|
depth = 8;
|
||||||
|
pallength = 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 *in, *out;
|
||||||
|
image = Image::create(raster->width, raster->height, depth);
|
||||||
|
image->allocate();
|
||||||
|
|
||||||
|
if(pallength){
|
||||||
|
out = image->palette;
|
||||||
|
in = (uint8*)natras->palette;
|
||||||
|
for(int32 i = 0; i < pallength; i++){
|
||||||
|
out[0] = in[2];
|
||||||
|
out[1] = in[1];
|
||||||
|
out[2] = in[0];
|
||||||
|
out[3] = in[3];
|
||||||
|
in += 4;
|
||||||
|
out += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out = image->pixels;
|
||||||
|
in = raster->lock(0);
|
||||||
|
|
||||||
|
unswizzle(out, in, image->width, image->height, depth < 8 ? 1 : depth/8);
|
||||||
|
// Fix RGB order
|
||||||
|
// TODO: stride
|
||||||
|
uint8 tmp;
|
||||||
|
if(depth > 8)
|
||||||
|
for(int32 y = 0; y < image->height; y++)
|
||||||
|
for(int32 x = 0; x < image->width; x++)
|
||||||
|
switch(raster->format & 0xF00){
|
||||||
|
case Raster::C8888:
|
||||||
|
tmp = out[0];
|
||||||
|
out[0] = out[2];
|
||||||
|
out[2] = tmp;
|
||||||
|
out += 4;
|
||||||
|
break;
|
||||||
|
case Raster::C888:
|
||||||
|
tmp = out[0];
|
||||||
|
out[0] = out[2];
|
||||||
|
out[2] = tmp;
|
||||||
|
out += 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
raster->unlock(0);
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
getLevelSize(Raster *raster, int32 level)
|
getLevelSize(Raster *raster, int32 level)
|
||||||
{
|
{
|
||||||
@ -675,6 +831,7 @@ readNativeTexture(Stream *stream)
|
|||||||
int32 compression = stream->readU8();
|
int32 compression = stream->readU8();
|
||||||
int32 totalSize = stream->readI32();
|
int32 totalSize = stream->readI32();
|
||||||
|
|
||||||
|
// isn't this the cube map flag?
|
||||||
assert(unknownFlag == 0);
|
assert(unknownFlag == 0);
|
||||||
Raster *raster;
|
Raster *raster;
|
||||||
if(compression){
|
if(compression){
|
||||||
|
Loading…
Reference in New Issue
Block a user