From 5685e6109ee525faf9213bcb904f5a63b31a512d Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 7 Aug 2019 22:37:43 +0200 Subject: [PATCH] work on rasters --- src/camera.cpp | 2 +- src/d3d/d3d.cpp | 16 +- src/d3d/d3d8.cpp | 4 +- src/d3d/d3d9.cpp | 4 +- src/d3d/rwd3dimpl.h | 2 +- src/d3d/rwxboximpl.h | 2 +- src/d3d/xbox.cpp | 13 +- src/engine.cpp | 17 +- src/gl/gl3raster.cpp | 2 +- src/gl/rwgl3impl.h | 2 +- src/ps2/ps2.cpp | 2 + src/ps2/ps2raster.cpp | 442 ++++++++++++++++++----------------- src/ps2/rwps2impl.h | 6 +- src/rwengine.h | 8 +- src/rwobjects.h | 13 +- src/texture.cpp | 17 +- tools/clumpview/ras_test.cpp | 2 +- 17 files changed, 314 insertions(+), 240 deletions(-) diff --git a/src/camera.cpp b/src/camera.cpp index 6311cc5..5109d22 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -500,7 +500,7 @@ Camera::setFOV(float32 hfov, float32 ratio) } hfov = hfov*3.14159f/360.0f; // deg to rad and halved - float ar1 = 4.0/3.0; + float ar1 = 4.0f/3.0f; float ar2 = w/h; float vfov = atanf(tanf(hfov/2) / ar1) *2; hfov = atanf(tanf(vfov/2) * ar2) *2; diff --git a/src/d3d/d3d.cpp b/src/d3d/d3d.cpp index a613fbe..ed1fa22 100644 --- a/src/d3d/d3d.cpp +++ b/src/d3d/d3d.cpp @@ -309,8 +309,10 @@ createTexture(int32 width, int32 height, int32 numlevels, uint32 format) } uint8* -lockTexture(void *texture, int32 level) +lockTexture(void *texture, int32 level, int32 lockMode) { + // TODO: don't ignore this + (void)lockMode; #ifdef RW_D3D9 IDirect3DTexture9 *tex = (IDirect3DTexture9*)texture; D3DLOCKED_RECT lr; @@ -458,10 +460,10 @@ rasterCreate(Raster *raster) } uint8* -rasterLock(Raster *raster, int32 level) +rasterLock(Raster *raster, int32 level, int32 lockMode) { D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - return lockTexture(natras->texture, level); + return lockTexture(natras->texture, level, lockMode); } void @@ -546,7 +548,7 @@ rasterFromImage(Raster *raster, Image *image) int32 inc = image->bpp; in = image->pixels; - out = raster->lock(0); + out = raster->lock(0, Raster::LOCKWRITE|Raster::LOCKNOFETCH); if(pallength) memcpy(out, in, raster->width*raster->height); else @@ -592,7 +594,7 @@ rasterToImage(Raster *raster) if(natras->customFormat){ image = Image::create(raster->width, raster->height, 32); image->allocate(); - uint8 *pix = raster->lock(0); + uint8 *pix = raster->lock(0, Raster::LOCKREAD); switch(natras->format){ case D3DFMT_DXT1: image->setPixelsDXT(1, pix); @@ -660,7 +662,7 @@ rasterToImage(Raster *raster) } out = image->pixels; - in = raster->lock(0); + in = raster->lock(0, Raster::LOCKREAD); if(pallength) memcpy(out, in, raster->width*raster->height); else @@ -745,7 +747,7 @@ setPalette(Raster *raster, void *palette, int32 size) void setTexels(Raster *raster, void *texels, int32 level) { - uint8 *dst = raster->lock(level); + uint8 *dst = raster->lock(level, Raster::LOCKWRITE|Raster::LOCKNOFETCH); memcpy(dst, texels, getLevelSize(raster, level)); raster->unlock(level); } diff --git a/src/d3d/d3d8.cpp b/src/d3d/d3d8.cpp index 5227129..e207550 100644 --- a/src/d3d/d3d8.cpp +++ b/src/d3d/d3d8.cpp @@ -549,7 +549,7 @@ readNativeTexture(Stream *stream) for(int32 i = 0; i < numLevels; i++){ size = stream->readU32(); if(i < raster->getNumLevels()){ - data = raster->lock(i); + data = raster->lock(i, Raster::LOCKWRITE|Raster::LOCKNOFETCH); stream->read(data, size); raster->unlock(i); }else @@ -612,7 +612,7 @@ writeNativeTexture(Texture *tex, Stream *stream) for(int32 i = 0; i < numLevels; i++){ size = getLevelSize(raster, i); stream->writeU32(size); - data = raster->lock(i); + data = raster->lock(i, Raster::LOCKREAD); stream->write(data, size); raster->unlock(i); } diff --git a/src/d3d/d3d9.cpp b/src/d3d/d3d9.cpp index c8566f7..f67abfb 100644 --- a/src/d3d/d3d9.cpp +++ b/src/d3d/d3d9.cpp @@ -669,7 +669,7 @@ readNativeTexture(Stream *stream) for(int32 i = 0; i < numLevels; i++){ size = stream->readU32(); if(i < raster->getNumLevels()){ - data = raster->lock(i); + data = raster->lock(i, Raster::LOCKWRITE|Raster::LOCKNOFETCH); stream->read(data, size); raster->unlock(i); }else @@ -719,7 +719,7 @@ writeNativeTexture(Texture *tex, Stream *stream) for(int32 i = 0; i < numLevels; i++){ size = getLevelSize(raster, i); stream->writeU32(size); - data = raster->lock(i); + data = raster->lock(i, Raster::LOCKREAD); stream->write(data, size); raster->unlock(i); } diff --git a/src/d3d/rwd3dimpl.h b/src/d3d/rwd3dimpl.h index 5f2751e..640a391 100644 --- a/src/d3d/rwd3dimpl.h +++ b/src/d3d/rwd3dimpl.h @@ -21,7 +21,7 @@ void im3DEnd(void); #endif void rasterCreate(Raster *raster); -uint8 *rasterLock(Raster *raster, int32 level); +uint8 *rasterLock(Raster *raster, int32 level, int32 lockMode); void rasterUnlock(Raster *raster, int32 level); int32 rasterNumLevels(Raster *raster); void rasterFromImage(Raster *raster, Image *image); diff --git a/src/d3d/rwxboximpl.h b/src/d3d/rwxboximpl.h index f421118..92514a8 100644 --- a/src/d3d/rwxboximpl.h +++ b/src/d3d/rwxboximpl.h @@ -2,7 +2,7 @@ namespace rw { namespace xbox { void rasterCreate(Raster *raster); -uint8 *rasterLock(Raster *raster, int32 level); +uint8 *rasterLock(Raster *raster, int32 level, int32 lockMode); void rasterUnlock(Raster*, int32); int32 rasterNumLevels(Raster *raster); Image *rasterToImage(Raster *raster); diff --git a/src/d3d/xbox.cpp b/src/d3d/xbox.cpp index a798241..cb50b18 100644 --- a/src/d3d/xbox.cpp +++ b/src/d3d/xbox.cpp @@ -580,8 +580,11 @@ rasterCreate(Raster *raster) } uint8* -rasterLock(Raster *raster, int32 level) +rasterLock(Raster *raster, int32 level, int32 lockMode) { + // TODO? + (void)lockMode; + XboxRaster *natras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset); RasterLevels *levels = (RasterLevels*)natras->texture; return levels->levels[level].data; @@ -644,7 +647,7 @@ rasterToImage(Raster *raster) if(natras->format){ image = Image::create(raster->width, raster->height, 32); image->allocate(); - uint8 *pix = raster->lock(0); + uint8 *pix = raster->lock(0, Raster::LOCKREAD); switch(natras->format){ case D3DFMT_DXT1: image->setPixelsDXT(1, pix); @@ -715,7 +718,7 @@ rasterToImage(Raster *raster) } out = image->pixels; - in = raster->lock(0); + in = raster->lock(0, Raster::LOCKREAD); unswizzle(out, in, image->width, image->height, depth < 8 ? 1 : depth/8); // Fix RGB order @@ -854,7 +857,7 @@ readNativeTexture(Stream *stream) stream->read(ras->palette, 4*256); // exploit the fact that mipmaps are allocated consecutively - uint8 *data = raster->lock(0); + uint8 *data = raster->lock(0, Raster::LOCKWRITE|Raster::LOCKNOFETCH); stream->read(data, totalSize); raster->unlock(0); @@ -899,7 +902,7 @@ writeNativeTexture(Texture *tex, Stream *stream) stream->write(ras->palette, 4*256); // exploit the fact that mipmaps are allocated consecutively - uint8 *data = raster->lock(0); + uint8 *data = raster->lock(0, Raster::LOCKREAD); stream->write(data, totalSize); raster->unlock(0); } diff --git a/src/engine.cpp b/src/engine.cpp index 3b33d04..d89d524 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -138,6 +138,8 @@ Engine::open(void) engine->driver[i]->rasterCreate = null::rasterCreate; engine->driver[i]->rasterLock = null::rasterLock; engine->driver[i]->rasterUnlock = null::rasterUnlock; + engine->driver[i]->rasterLockPalette = null::rasterLockPalette; + engine->driver[i]->rasterUnlockPalette = null::rasterUnlockPalette; engine->driver[i]->rasterNumLevels = null::rasterNumLevels; engine->driver[i]->rasterFromImage = null::rasterFromImage; engine->driver[i]->rasterToImage = null::rasterToImage; @@ -225,7 +227,7 @@ rasterCreate(Raster*) } uint8* -rasterLock(Raster*, int32) +rasterLock(Raster*, int32, int32) { assert(0 && "lockRaster not implemented"); return nil; @@ -237,6 +239,19 @@ rasterUnlock(Raster*, int32) assert(0 && "unlockRaster not implemented"); } +uint8* +rasterLockPalette(Raster*, int32) +{ + assert(0 && "rasterLockPalette not implemented"); + return nil; +} + +void +rasterUnlockPalette(Raster*) +{ + assert(0 && "rasterUnlockPalette not implemented"); +} + int32 rasterNumLevels(Raster*) { diff --git a/src/gl/gl3raster.cpp b/src/gl/gl3raster.cpp index a3f7591..d9826f0 100644 --- a/src/gl/gl3raster.cpp +++ b/src/gl/gl3raster.cpp @@ -95,7 +95,7 @@ rasterCreate(Raster *raster) } uint8* -rasterLock(Raster*, int32 level) +rasterLock(Raster*, int32 level, int32 lockMode) { printf("locking\n"); return nil; diff --git a/src/gl/rwgl3impl.h b/src/gl/rwgl3impl.h index ecf7f8d..2f89f2e 100644 --- a/src/gl/rwgl3impl.h +++ b/src/gl/rwgl3impl.h @@ -23,7 +23,7 @@ void im3DEnd(void); #endif void rasterCreate(Raster *raster); -uint8 *rasterLock(Raster*, int32 level); +uint8 *rasterLock(Raster*, int32 level, int32 lockMode); void rasterUnlock(Raster*, int32); int32 rasterNumLevels(Raster*); void rasterFromImage(Raster *raster, Image *image); diff --git a/src/ps2/ps2.cpp b/src/ps2/ps2.cpp index 30f2f35..60e9489 100644 --- a/src/ps2/ps2.cpp +++ b/src/ps2/ps2.cpp @@ -32,6 +32,8 @@ driverOpen(void *o, int32, int32) engine->driver[PLATFORM_PS2]->rasterCreate = rasterCreate; engine->driver[PLATFORM_PS2]->rasterLock = rasterLock; engine->driver[PLATFORM_PS2]->rasterUnlock = rasterUnlock; + engine->driver[PLATFORM_PS2]->rasterLockPalette = rasterLockPalette; + engine->driver[PLATFORM_PS2]->rasterUnlockPalette = rasterUnlockPalette; engine->driver[PLATFORM_PS2]->rasterNumLevels = rasterNumLevels; engine->driver[PLATFORM_PS2]->rasterFromImage = rasterFromImage; engine->driver[PLATFORM_PS2]->rasterToImage = rasterToImage; diff --git a/src/ps2/ps2raster.cpp b/src/ps2/ps2raster.cpp index 16ae48e..a448d69 100644 --- a/src/ps2/ps2raster.cpp +++ b/src/ps2/ps2raster.cpp @@ -19,6 +19,15 @@ namespace rw { namespace ps2 { +enum +{ + // from RW + PS2LOCK_READ = 0x02, + PS2LOCK_WRITE = 0x04, + PS2LOCK_READ_PALETTE = 0x08, + PS2LOCK_WRITE_PALETTE = 0x10, +}; + int32 nativeRasterOffset; #define MAXLEVEL(r) ((r)->tex1low >> 2) @@ -1345,168 +1354,217 @@ rasterCreate(Raster *raster) } -uint8* -rasterLock(Raster *raster, int32 level) +static uint32 +swizzle(uint32 x, uint32 y, uint32 logw) { +#define X(n) ((x>>(n))&1) +#define Y(n) ((y>>(n))&1) + + uint32 nx, ny, n; + x ^= (Y(1)^Y(2))<<2; + nx = x&7 | (x>>1)&~7; + ny = y&1 | (y>>1)&~1; + n = Y(1) | X(3)<<1; + return n | nx<<2 | ny<format & (Raster::PAL4|Raster::PAL8)) == 0) + return; + + int minw, minh; + transferMinSize(raster->format & Raster::PAL4 ? PSMT4 : PSMT8, natras->flags, &minw, &minh); + w = max(raster->width, minw); + h = max(raster->height, minh); + px = raster->pixels; + logw = 0; + for(i = 1; i < raster->width; i *= 2) logw++; + mask = (1<format & Raster::PAL4 && natras->flags & Ps2Raster::SWIZZLED4){ + for(y = 0; y < h; y += 4){ + memcpy(tmpbuf, &px[y<>1] >> 4 : tmpbuf[s>>1] & 0xF; + px[a>>1] = a & 1 ? px[a>>1]&0xF | c<<4 : px[a>>1]&0xF0 | c; + } + } + }else if(raster->format & Raster::PAL8 && natras->flags & Ps2Raster::SWIZZLED8){ + for(y = 0; y < h; y += 4){ + memcpy(tmpbuf, &px[y<format & (Raster::PAL4|Raster::PAL8)) == 0) + return; + + int minw, minh; + transferMinSize(raster->format & Raster::PAL4 ? PSMT4 : PSMT8, natras->flags, &minw, &minh); + w = max(raster->width, minw); + h = max(raster->height, minh); + px = raster->pixels; + logw = 0; + for(i = 1; i < raster->width; i *= 2) logw++; + mask = (1<format & Raster::PAL4 && natras->flags & Ps2Raster::SWIZZLED4){ + for(y = 0; y < h; y += 4){ + for(i = 0; i < 4; i++) + for(x = 0; x < w; x++){ + uint32 a = (y+i<>1] >> 4 : px[a>>1] & 0xF; + tmpbuf[s>>1] = s & 1 ? tmpbuf[s>>1]&0xF | c<<4 : tmpbuf[s>>1]&0xF0 | c; + } + memcpy(&px[y<format & Raster::PAL8 && natras->flags & Ps2Raster::SWIZZLED8){ + for(y = 0; y < h; y += 4){ + for(i = 0; i < 4; i++) + for(x = 0; x < w; x++){ + uint32 a = (y+i< 0){ + int32 minw, minh; + int32 mipw, miph; + transferMinSize(raster->format & Raster::PAL4 ? PSMT4 : PSMT8, natras->flags, &minw, &minh); + while(level--){ + mipw = max(raster->width, minw); + miph = max(raster->height, minh); + raster->pixels += ALIGN16(mipw*miph*raster->depth/8) + 0x50; + raster->width /= 2; + raster->height /= 2; + } + } + + if((lockMode & Raster::LOCKNOFETCH) == 0) + unswizzleRaster(raster); + if(lockMode & Raster::LOCKREAD) raster->privateFlags |= PS2LOCK_READ; + if(lockMode & Raster::LOCKWRITE) raster->privateFlags |= PS2LOCK_WRITE; return raster->pixels; } void rasterUnlock(Raster *raster, int32 level) { - // TODO - (void)raster; - (void)level; + Ps2Raster *natras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset); + if(raster->format & (Raster::PAL4 | Raster::PAL8)) + swizzleRaster(raster); + + raster->width = raster->originalWidth; + raster->height = raster->originalHeight; + raster->pixels = raster->originalPixels; + raster->stride = raster->originalStride; + if(natras->flags & Ps2Raster::NEWSTYLE) + raster->pixels = ((Ps2Raster::PixelPtr*)raster->pixels)->pixels + 0x50; + + raster->privateFlags &= ~(PS2LOCK_READ|PS2LOCK_WRITE); + // TODO: generate mipmaps } +static void +convertCSM1_16(uint32 *pal) +{ + int i, j; + uint32 tmp; + for(i = 0; i < 256; i++) + // palette index bits 0x08 and 0x10 are flipped + if((i & 0x18) == 0x10){ + j = i ^ 0x18; + tmp = pal[i]; + pal[i] = pal[j]; + pal[j] = tmp; + } +} + +static void +convertCSM1_32(uint32 *pal) +{ + int i, j; + uint32 tmp; + for(i = 0; i < 256; i++) + // palette index bits 0x08 and 0x10 are flipped + if((i & 0x18) == 0x10){ + j = i ^ 0x18; + tmp = pal[i]; + pal[i] = pal[j]; + pal[j] = tmp; + } +} + +static void +convertPalette(Raster *raster) +{ + if(raster->format & Raster::PAL8){ + if((raster->format & 0xF00) == Raster::C8888) + convertCSM1_32((uint32*)raster->palette); + else if((raster->format & 0xF00) == Raster::C8888) + convertCSM1_16((uint32*)raster->palette); + } +} + +// NB: RW doesn't convert the palette when locking/unlocking uint8* -paletteLock(Raster *raster) +rasterLockPalette(Raster *raster, int32 lockMode) { if((raster->format & (Raster::PAL4 | Raster::PAL8)) == 0) return nil; + if((lockMode & Raster::LOCKNOFETCH) == 0) + convertPalette(raster); + if(lockMode & Raster::LOCKREAD) raster->privateFlags |= PS2LOCK_READ_PALETTE; + if(lockMode & Raster::LOCKWRITE) raster->privateFlags |= PS2LOCK_WRITE_PALETTE; return raster->palette; } void -paletteUnlock(Raster *raster) +rasterUnlockPalette(Raster *raster) { - // TODO - (void)raster; -} - -static void -convertCSM1_16(uint16 *dst, uint16 *src) -{ - // palette index bits 0x08 and 0x10 are flipped - int i, j; - for(i = 0; i < 256; i++){ - j = i&~0x18 | (i&0x10)>>1 | (i&0x8)<<1; - dst[i] = src[j]; - } -} - -static void -convertCSM1_32(uint32 *dst, uint32 *src) -{ - // palette index bits 0x08 and 0x10 are flipped - int i, j; - for(i = 0; i < 256; i++){ - j = i&~0x18 | (i&0x10)>>1 | (i&0x8)<<1; - dst[i] = src[j]; - } -} - -// Unswizzle PSMT8 from PSMCT32 format -// Original code from http://ps2linux.no-ip.info/playstation2-linux.com/docs/howto/display_docef7c.html?docid=75 -static void -unswizzle32to8(uint8 *dst, uint8 *src, int32 w, int32 h) -{ - int32 x, y; - for(y = 0; y < h; y++) - for(x = 0; x < w; x++) { - // byte address of beginning of PSMCT32 block - // yblock = y/16 * w/16 * 256 - int32 block_loc = (y&(~0xF))*w + (x&(~0xF))*2; - // y coordinate in PSMCT32 block - int32 ypos = (((y&~3)>>1) // column number - + (y&1))&0x7; // row inside column - // indices are swapped in groups of 4 every 4 - // pixel rows in a block, first at y = 2 - int32 swap_sel = (y+2)&4; - // byte address of word in PSMCT32 block - int32 word_loc = ypos*w*2 + ((x+swap_sel)&0x7)*4; - // byte offset in 32 bit word - int32 byte_loc = ((y>>1)&1) + ((x>>2)&2); - int32 swizzled = block_loc + word_loc + byte_loc; - dst[y*w+x] = src[swizzled]; - } -} -static void -swizzle8to32(uint8 *dst, uint8 *src, int32 w, int32 h) -{ - int32 x, y; - for(y = 0; y < h; y++) - for(x = 0; x < w; x++) { - // byte address of beginning of PSMCT32 block - // yblock = y/16 * w/16 * 256 - int32 block_loc = (y&(~0xF))*w + (x&(~0xF))*2; - // y coordinate in PSMCT32 block - int32 ypos = (((y&~3)>>1) // column number - + (y&1))&0x7; // row inside column - // indices are swapped in groups of 4 every 4 - // pixel rows in a block, first at y = 2 - int32 swap_sel = (y+2)&4; - // byte address of word in PSMCT32 block - int32 word_loc = ypos*w*2 + ((x+swap_sel)&0x7)*4; - // byte offset in 32 bit word - int32 byte_loc = ((y>>1)&1) + ((x>>2)&2); - int32 swizzled = block_loc + word_loc + byte_loc; - dst[swizzled] = src[y*w+x]; - } -} - - -// Unswizzle PSMT4 from PSMCT16 format -static void -unswizzle16to4(uint8 *dst, uint8 *src, int32 w, int32 h) -{ - int32 x, y; - for(y = 0; y < h; y++) - for(x = 0; x < w; x++){ - // byte address of beginning of PSMCT16 block - // yblock = y/16 * w/32 * 256 - int32 block_loc = (y&(~0xF))*w/2 + (x&(~0x1F)); - // y coordinate in PSMCT16 block - int32 ypos = (((y&~3)>>1) // column number - + (y&1))&0x7; // row inside column - // indices are swapped in groups of 4 every 4 - // pixel rows in a block, first at y = 2 - int32 swap_sel = (y+2)&4; - // byte address of halfword in PSMCT16 block - int32 hword_loc = ypos*w - + (((x+swap_sel) & 0x7) + ((x & 0x10)>>1))*2; - // byte offset in 16 bit word - int32 byte_loc = (x>>3)&1; - uint32 swizzled = block_loc + hword_loc + byte_loc; - // y&2 selects nibbles - int8 c = y & 2 ? src[swizzled] >> 4 : src[swizzled] & 0xF; - int32 addr = y*w + x; - if(addr & 1) - dst[addr>>1] = dst[addr>>1]&0xF | c<<4; - else - dst[addr>>1] = dst[addr>>1]&0xF0 | c; - } -} -static void -swizzle4to16(uint8 *dst, uint8 *src, int32 w, int32 h) -{ - int32 x, y; - for(y = 0; y < h; y++) - for(x = 0; x < w; x++){ - // byte address of beginning of PSMCT16 block - // yblock = y/16 * w/32 * 256 - int32 block_loc = (y&(~0xF))*w/2 + (x&(~0x1F)); - // y coordinate in PSMCT16 block - int32 ypos = (((y&~3)>>1) // column number - + (y&1))&0x7; // row inside column - // indices are swapped in groups of 4 every 4 - // pixel rows in a block, first at y = 2 - int32 swap_sel = (y+2)&4; - // byte address of halfword in PSMCT16 block - int32 hword_loc = ypos*w - + (((x+swap_sel) & 0x7) + ((x & 0x10)>>1))*2; - // byte offset in 16 bit word - int32 byte_loc = (x>>3)&1; - uint32 swizzled = block_loc + hword_loc + byte_loc; - - int32 addr = y*w + x; - int8 c = addr & 1 ? src[addr>>1] >> 4 : src[addr>>1] & 0xF; - // y&2 selects nibbles - if(y & 2) - dst[swizzled] = dst[swizzled]&0xF | c<<4; - else - dst[swizzled] = dst[swizzled]&0xF0 | c; - } + if(raster->format & (Raster::PAL4 | Raster::PAL8)) + convertPalette(raster); + raster->privateFlags &= ~(PS2LOCK_READ_PALETTE|PS2LOCK_WRITE_PALETTE); } void @@ -1550,44 +1608,34 @@ rasterFromImage(Raster *raster, Image *image) } rasterCreate(raster); + int32 pallength = 0; + if(raster->format & Raster::PAL4) + pallength = 16; + else if(raster->format & Raster::PAL8) + pallength = 256; + uint8 *in, *out; if(image->depth <= 8){ in = image->palette; - out = paletteLock(raster); - if(image->depth == 4) - memcpy(out, in, 4*16); - else - convertCSM1_32((uint32*)out, (uint32*)in); - paletteUnlock(raster); + out = raster->lockPalette(Raster::LOCKWRITE|Raster::LOCKNOFETCH); + memcpy(out, in, 4*pallength); + for(int32 i = 0; i < pallength; i++){ + out[3] = out[3]*128/255; + out += 4; + } + raster->unlockPalette(); } - int32 w, h; - w = image->width; - h = image->height; - int minw, minh; - int th, tw; + int tw; transferMinSize(image->depth == 4 ? PSMT4 : PSMT8, natras->flags, &minw, &minh); - tw = max(w, minw); - th = max(h, minh); + tw = max(image->width, minw); in = image->pixels; - out = raster->lock(0); + out = raster->lock(0, Raster::LOCKWRITE|Raster::LOCKNOFETCH); if(image->depth == 4){ - if(natras->flags & Ps2Raster::SWIZZLED4){ - uint8 *tmp = rwNewT(uint8, tw*th/2, MEMDUR_FUNCTION | ID_RASTERPS2); - compressPSMT4(tmp, in, w, h, tw); - swizzle4to16(out, tmp, tw, th); - rwFree(tmp); - }else - compressPSMT4(out, in, w, h, tw); + compressPSMT4(out, in, image->width, image->height, tw); }else if(image->depth == 8){ - if(natras->flags & Ps2Raster::SWIZZLED8){ - uint8 *tmp = rwNewT(uint8, tw*th, MEMDUR_FUNCTION | ID_RASTERPS2); - copyPSMT8(tmp, in, w, h, tw); - swizzle8to32(out, tmp, tw, th); - rwFree(tmp); - }else - copyPSMT8(out, in, w, h, tw); + copyPSMT8(out, in, image->width, image->height, tw); }else{ // TODO: stride for(int32 y = 0; y < image->height; y++) @@ -1666,52 +1714,28 @@ rasterToImage(Raster *raster) if(pallength){ out = image->palette; - in = paletteLock(raster); - if(rasterFormat == Raster::C1555){ - if(depth == 8) - convertCSM1_16((uint16*)out, (uint16*)in); - else - memcpy(out, in, pallength*2); - }else if(rasterFormat == Raster::C8888){ - if(depth == 8) - convertCSM1_32((uint32*)out, (uint32*)in); - else - memcpy(out, in, pallength*4); + in = raster->lockPalette(Raster::LOCKREAD); + if(rasterFormat == Raster::C8888){ + memcpy(out, in, pallength*4); for(int32 i = 0; i < pallength; i++){ out[3] = out[3]*255/128; out += 4; } - } - paletteUnlock(raster); + }else + memcpy(out, in, pallength*2); + raster->unlockPalette(); } - int32 w, h; - w = raster->width; - h = raster->height; - int minw, minh; - int th, tw; + int tw; transferMinSize(depth == 4 ? PSMT4 : PSMT8, natras->flags, &minw, &minh); - tw = max(w, minw); - th = max(h, minh); + tw = max(raster->width, minw); out = image->pixels; - in = raster->lock(0); + in = raster->lock(0, Raster::LOCKREAD); if(depth == 4){ - if(natras->flags & Ps2Raster::SWIZZLED4){ - uint8 *tmp = rwNewT(uint8, tw*th/2, MEMDUR_FUNCTION | ID_RASTERPS2); - unswizzle16to4(tmp, in, tw, th); - expandPSMT4(out, tmp, w, h, tw); - rwFree(tmp); - }else - expandPSMT4(out, in, w, h, tw); + expandPSMT4(out, in, raster->width, raster->height, tw); }else if(depth == 8){ - if(natras->flags & Ps2Raster::SWIZZLED8){ - uint8 *tmp = rwNewT(uint8, tw*th, MEMDUR_FUNCTION | ID_RASTERPS2); - unswizzle32to8(tmp, in, tw, th); - copyPSMT8(out, tmp, w, h, tw); - rwFree(tmp); - }else - copyPSMT8(out, in, w, h, tw); + copyPSMT8(out, in, raster->width, raster->height, tw); }else // TODO: stride for(int32 y = 0; y < image->height; y++) @@ -1787,8 +1811,8 @@ createNativeRaster(void *object, int32 offset, int32) static void* destroyNativeRaster(void *object, int32 offset, int32) { - // TODO - (void)offset; + Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, object, offset); + freealign(raster->data); return object; } diff --git a/src/ps2/rwps2impl.h b/src/ps2/rwps2impl.h index a134ecb..dc0e716 100644 --- a/src/ps2/rwps2impl.h +++ b/src/ps2/rwps2impl.h @@ -2,8 +2,10 @@ namespace rw { namespace ps2 { void rasterCreate(Raster *raster); -uint8 *rasterLock(Raster*, int32 level); -void rasterUnlock(Raster*, int32); +uint8 *rasterLock(Raster*, int32 level, int32 lockMode); +void rasterUnlock(Raster*, int32 level); +uint8 *rasterLockPalette(Raster*, int32 lockMode); +void rasterUnlockPalette(Raster*); int32 rasterNumLevels(Raster*); void rasterFromImage(Raster *raster, Image *image); Image *rasterToImage(Raster *raster); diff --git a/src/rwengine.h b/src/rwengine.h index fcfd48b..b2892fe 100644 --- a/src/rwengine.h +++ b/src/rwengine.h @@ -59,8 +59,10 @@ struct Driver int32 rasterNativeOffset; void (*rasterCreate)(Raster*); - uint8 *(*rasterLock)(Raster*, int32 level); + uint8 *(*rasterLock)(Raster*, int32 level, int32 lockMode); void (*rasterUnlock)(Raster*, int32 level); + uint8 *(*rasterLockPalette)(Raster*, int32 lockMode); + void (*rasterUnlockPalette)(Raster*); int32 (*rasterNumLevels)(Raster*); void (*rasterFromImage)(Raster*, Image*); Image *(*rasterToImage)(Raster*); @@ -158,8 +160,10 @@ namespace null { void *getRenderState(int32 state); void rasterCreate(Raster*); - uint8 *rasterLock(Raster*, int32 level); + uint8 *rasterLock(Raster*, int32 level, int32 lockMode); void rasterUnlock(Raster*, int32 level); + uint8 *rasterLockPalette(Raster*, int32 lockMode); + void rasterUnlockPalette(Raster*); int32 rasterNumLevels(Raster*); void rasterFromImage(Raster*, Image*); Image *rasterToImage(Raster*); diff --git a/src/rwobjects.h b/src/rwobjects.h index 7b6cbd1..a7b92e5 100644 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -170,13 +170,14 @@ struct Raster // TODO: use bytes int32 type; int32 flags; + int32 privateFlags; int32 format; int32 width, height, depth; int32 stride; uint8 *pixels; uint8 *palette; + // remember for locked rasters uint8 *originalPixels; - // TODO: use them (for locking mainly) int32 originalWidth; int32 originalHeight; int32 originalStride; @@ -190,8 +191,10 @@ struct Raster void destroy(void); static Raster *createFromImage(Image *image, int32 platform = 0); Image *toImage(void); - uint8 *lock(int32 level); + uint8 *lock(int32 level, int32 lockMode); void unlock(int32 level); + uint8 *lockPalette(int32 lockMode); + void unlockPalette(void); int32 getNumLevels(void); static int32 calculateNumLevels(int32 width, int32 height); static bool formatHasAlpha(int32 format); @@ -221,6 +224,12 @@ struct Raster CAMERATEXTURE = 0x05, DONTALLOCATE = 0x80 }; + enum LockMode { + LOCKWRITE = 1, + LOCKREAD = 2, + LOCKNOFETCH = 4, // don't fetch pixel data + LOCKRAW = 8, + }; }; #define IGNORERASTERIMP 0 diff --git a/src/texture.cpp b/src/texture.cpp index 0a9517c..fd97217 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -464,6 +464,7 @@ Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platf raster->platform = platform ? platform : rw::platform; raster->type = format & 0x7; raster->flags = format & 0xF8; + raster->privateFlags = 0; raster->format = format & 0xFF00; raster->width = width; raster->height = height; @@ -498,9 +499,9 @@ Raster::destroy(void) } uint8* -Raster::lock(int32 level) +Raster::lock(int32 level, int32 lockMode) { - return engine->driver[this->platform]->rasterLock(this, level); + return engine->driver[this->platform]->rasterLock(this, level, lockMode); } void @@ -509,6 +510,18 @@ Raster::unlock(int32 level) engine->driver[this->platform]->rasterUnlock(this, level); } +uint8* +Raster::lockPalette(int32 lockMode) +{ + return engine->driver[this->platform]->rasterLockPalette(this, lockMode); +} + +void +Raster::unlockPalette(void) +{ + engine->driver[this->platform]->rasterUnlockPalette(this); +} + int32 Raster::getNumLevels(void) { diff --git a/tools/clumpview/ras_test.cpp b/tools/clumpview/ras_test.cpp index 853e10e..d9db39d 100644 --- a/tools/clumpview/ras_test.cpp +++ b/tools/clumpview/ras_test.cpp @@ -842,7 +842,7 @@ void endSoftras(void) { int i; - uint8 *dst = testras->lock(0); + uint8 *dst = testras->lock(0, Raster::LOCKWRITE|Raster::LOCKNOFETCH); uint8 *src = rs::canvas->fb; for(i = 0; i < rs::canvas->w*rs::canvas->h; i++){ dst[0] = src[1];