From 47fcb3001a36eb13ff8403f2c0391ce3b15b6055 Mon Sep 17 00:00:00 2001 From: aap Date: Thu, 16 Apr 2020 09:10:11 +0200 Subject: [PATCH] worked on raters; fixed a few issues --- src/base.cpp | 11 ++- src/clump.cpp | 2 +- src/d3d/d3d.cpp | 208 +++++++++++++++++++++++++++++++-------- src/d3d/d3ddevice.cpp | 64 ++++++++---- src/d3d/rwd3dimpl.h | 26 +++++ src/engine.cpp | 6 +- src/frame.cpp | 48 ++++++--- src/gl/gl3device.cpp | 8 ++ src/ps2/ps2device.cpp | 4 + src/raster.cpp | 198 +++++++++++++++++++++++++++++++++++++ src/rwbase.h | 1 + src/rwengine.h | 2 + src/rwobjects.h | 12 ++- src/texture.cpp | 114 --------------------- tools/clumpview/main.cpp | 44 ++++++++- 15 files changed, 544 insertions(+), 204 deletions(-) create mode 100644 src/raster.cpp diff --git a/src/base.cpp b/src/base.cpp index d48f4c5..5458ccc 100644 --- a/src/base.cpp +++ b/src/base.cpp @@ -536,7 +536,10 @@ Matrix::invertGeneral(Matrix *dst, const Matrix *src) void Matrix::makeRotation(Matrix *dst, const V3d *axis, float32 angle) { - V3d v = normalize(*axis); +// V3d v = normalize(*axis); + float32 len = dot(*axis, *axis); + if(len != 0.0f) len = 1.0f/sqrtf(len); + V3d v = rw::scale(*axis, len); angle = angle*(float)M_PI/180.0f; float32 s = sin(angle); float32 c = cos(angle); @@ -880,13 +883,13 @@ StreamFile::close(void) uint32 StreamFile::write(const void *data, uint32 length) { - return (uint32)fwrite(data, length, 1, this->file); + return (uint32)fwrite(data, 1, length, this->file); } uint32 StreamFile::read(void *data, uint32 length) { - return (uint32)fread(data, length, 1, this->file); + return (uint32)fread(data, 1, length, this->file); } void @@ -974,7 +977,7 @@ getFileContents(char *name, uint32 *len) *len = ftell(cf); fseek(cf, 0, SEEK_SET); uint8 *data = rwNewT(uint8, *len, MEMDUR_EVENT); - fread(data, *len, 1, cf); + fread(data, 1, *len, cf); fclose(cf); return data; } diff --git a/src/clump.cpp b/src/clump.cpp index 07cddc8..24ad720 100644 --- a/src/clump.cpp +++ b/src/clump.cpp @@ -40,7 +40,7 @@ Clump* Clump::clone(void) { Clump *clump = Clump::create(); - Frame *root = this->getFrame()->cloneHierarchy(); + Frame *root = this->getFrame()->cloneAndLink(); clump->setFrame(root); FORLIST(lnk, this->atomics){ Atomic *a = Atomic::fromClump(lnk); diff --git a/src/d3d/d3d.cpp b/src/d3d/d3d.cpp index e1eb01f..d0fec04 100644 --- a/src/d3d/d3d.cpp +++ b/src/d3d/d3d.cpp @@ -10,6 +10,7 @@ #include "../rwobjects.h" #include "../rwengine.h" #include "rwd3d.h" +#include "rwd3dimpl.h" namespace rw { namespace d3d { @@ -358,40 +359,139 @@ struct RasterFormatInfo uint32 d3dformat; int32 depth; bool32 hasAlpha; + uint32 rwFormat; }; -static RasterFormatInfo formatInfo[16] = { + +// indexed directly by RW format +static RasterFormatInfo formatInfoRW[16] = { { 0, 0, 0}, - { D3DFMT_A1R5G5B5, 16, 1 }, // C1555 - { D3DFMT_R5G6B5, 16, 0 }, // C565 - { D3DFMT_A4R4G4B4, 16, 1 }, // C4444 - { D3DFMT_L8, 8, 0 }, // LUM8 - { D3DFMT_A8R8G8B8, 32, 1 }, // C8888 - { D3DFMT_X8R8G8B8, 32, 0 }, // C888 - { D3DFMT_D16, 16, 0 }, // D16 - { D3DFMT_D24X8, 32, 0 }, // D24 - { D3DFMT_D32, 32, 0 }, // D32 - { D3DFMT_X1R5G5B5, 16, 0 }, // C555 + { D3DFMT_A1R5G5B5, 16, 1, Raster::C1555 }, + { D3DFMT_R5G6B5, 16, 0, Raster::C565 }, + { D3DFMT_A4R4G4B4, 16, 1, Raster::C4444 }, + { D3DFMT_L8, 8, 0, Raster::LUM8 }, + { D3DFMT_A8R8G8B8, 32, 1, Raster::C8888 }, + { D3DFMT_X8R8G8B8, 32, 0, Raster::C888 }, + { D3DFMT_D16, 16, 0, Raster::D16 }, + { D3DFMT_D24X8, 32, 0, Raster::D24 }, + { D3DFMT_D32, 32, 0, Raster::D32 }, + { D3DFMT_X1R5G5B5, 16, 0, Raster::C555 }, }; +static RasterFormatInfo formatInfoFull[] = { + { D3DFMT_R8G8B8, 0, 24, 0 }, + { D3DFMT_A8R8G8B8, 1, 32, Raster::C8888 }, + { D3DFMT_X8R8G8B8, 0, 32, Raster::C888 }, + { D3DFMT_R5G6B5, 0, 16, Raster::C565 }, + { D3DFMT_X1R5G5B5, 0, 16, Raster::C555 }, + { D3DFMT_A1R5G5B5, 1, 16, Raster::C1555 }, + { D3DFMT_A4R4G4B4, 1, 16, Raster::C4444 }, + { D3DFMT_R3G3B2, 0, 8, 0 }, + { D3DFMT_A8, 1, 8, 0 }, + { D3DFMT_A8R3G3B2, 1, 16, 0 }, + { D3DFMT_X4R4G4B4, 0, 16, 0 }, + { D3DFMT_A2B10G10R10, 1, 32, 0 }, + { D3DFMT_A8B8G8R8, 1, 32, 0 }, + { D3DFMT_X8B8G8R8, 0, 32, 0 }, + { D3DFMT_G16R16, 0, 32, 0 }, + { D3DFMT_A2R10G10B10, 1, 32, 0 }, + { D3DFMT_A16B16G16R16, 1, 64, 0 }, + { D3DFMT_A8P8, 1, 16, 0 }, +// { D3DFMT_P8, 0, 8, ... }, +// { D3DFMT_L8, 0, 8, ... }, + { D3DFMT_A8L8, 1, 16, 0 }, + { D3DFMT_A4L4, 1, 8, 0 }, + { D3DFMT_V8U8, 0, 16, 0 }, + { D3DFMT_L6V5U5, 0, 16, 0 }, + { D3DFMT_X8L8V8U8, 0, 32, 0 }, + { D3DFMT_Q8W8V8U8, 0, 32, 0 }, + { D3DFMT_V16U16, 0, 32, 0 }, + { D3DFMT_A2W10V10U10, 1, 32, 0 }, + { D3DFMT_D16_LOCKABLE, 0, 16, Raster::D16 }, + { D3DFMT_D32, 0, 32, Raster::D32 }, + { D3DFMT_D15S1, 0, 16, Raster::D16 }, + { D3DFMT_D24S8, 0, 32, Raster::D32 }, + { D3DFMT_D24X8, 0, 32, Raster::D32 }, + { D3DFMT_D24X4S4, 0, 32, Raster::D32 }, + { D3DFMT_D16, 0, 16, Raster::D16 }, + { D3DFMT_D32F_LOCKABLE, 0, 32, Raster::D32 }, + { D3DFMT_D24FS8, 0, 32, Raster::D32 }, + { D3DFMT_L16, 0, 16, 0 }, + { D3DFMT_Q16W16V16U16, 0, 64, 0 }, + { D3DFMT_R16F, 0, 16, 0 }, + { D3DFMT_G16R16F, 0, 32, 0 }, + { D3DFMT_A16B16G16R16F, 1, 64, 0 }, + { D3DFMT_R32F, 0, 32, 0 }, + { D3DFMT_G32R32F, 0, 64, 0 }, + { D3DFMT_A32B32G32R32F, 1, 128, 0 }, + { D3DFMT_CxV8U8, 0, 16, 0 }, +}; + +RasterFormatInfo* +findFormatInfoD3D(uint32 d3dformat) +{ + static RasterFormatInfo fake = { 0, 0, 0, 0 }; + int i; + for(i = 0; i < nelem(formatInfoFull); i++) + if(formatInfoFull[i].d3dformat == d3dformat) + return &formatInfoFull[i]; + return &fake; +} + + +static void +rasterSetFormat(Raster *raster) +{ + if(raster->format == 0){ + // have to find a format first + // this could perhaps be a bit more intelligent + + switch(raster->type){ + case Raster::NORMAL: + case Raster::TEXTURE: + raster->format = Raster::C8888; + break; + +#ifdef RW_D3D9 + case Raster::ZBUFFER: + raster->format = findFormatInfoD3D(d3d9Globals.present.AutoDepthStencilFormat)->rwFormat; + // can this even happen? just do something... + if(raster->format == 0) + raster->format = Raster::D32; + break; + + case Raster::CAMERATEXTURE: + case Raster::CAMERA: + raster->format = findFormatInfoD3D(d3d9Globals.present.BackBufferFormat)->rwFormat; + // can this even happen? just do something... + if(raster->format == 0) + raster->format = Raster::C8888; + break; +#endif + } + } + + + D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); + if(raster->format & (Raster::PAL4 | Raster::PAL8)) + natras->format = D3DFMT_P8; + else + natras->format = formatInfoRW[(raster->format >> 8) & 0xF].d3dformat; + raster->depth = formatInfoRW[(raster->format >> 8) & 0xF].depth; + natras->hasAlpha = formatInfoRW[(raster->format >> 8) & 0xF].hasAlpha; +} + static void rasterCreateTexture(Raster *raster) { - uint32 format; int32 levels; D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - if(raster->format & (Raster::PAL4 | Raster::PAL8)){ - format = D3DFMT_P8; + if(natras->format == D3DFMT_P8) natras->palette = (uint8*)rwNew(4*256, MEMDUR_EVENT | ID_DRIVER); - }else - format = formatInfo[(raster->format >> 8) & 0xF].d3dformat; - natras->format = format; - raster->depth = formatInfo[(raster->format >> 8) & 0xF].depth; - natras->hasAlpha = formatInfo[(raster->format >> 8) & 0xF].hasAlpha; levels = Raster::calculateNumLevels(raster->width, raster->height); natras->texture = createTexture(raster->width, raster->height, raster->format & Raster::MIPMAP ? levels : 1, - format); + natras->format); assert(natras->texture && "couldn't create d3d texture"); } @@ -404,8 +504,6 @@ rasterCreateCameraTexture(Raster *raster) int32 levels; D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - natras->format = formatInfo[(raster->format >> 8) & 0xF].d3dformat; - natras->hasAlpha = formatInfo[(raster->format >> 8) & 0xF].hasAlpha; levels = Raster::calculateNumLevels(raster->width, raster->height); #ifdef RW_D3D9 @@ -421,43 +519,73 @@ rasterCreateCameraTexture(Raster *raster) #endif } +static void +rasterCreateCamera(Raster *raster) +{ + D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); + raster->flags |= Raster::DONTALLOCATE; + raster->originalWidth = raster->width; + raster->originalHeight = raster->height; + raster->stride = 0; + raster->pixels = nil; + +#ifdef RW_D3D9 + natras->format = d3d9Globals.present.BackBufferFormat; + raster->depth = findFormatDepth(natras->format); +#endif +} + +static void +rasterCreateZbuffer(Raster *raster) +{ + D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); + raster->flags |= Raster::DONTALLOCATE; + raster->originalWidth = raster->width; + raster->originalHeight = raster->height; + raster->stride = 0; + raster->pixels = nil; + +#ifdef RW_D3D9 + natras->format = d3d9Globals.present.AutoDepthStencilFormat; + raster->depth = findFormatDepth(natras->format); +#endif +} + void rasterCreate(Raster *raster) { D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - // Dummy to use as subraster - if(raster->width == 0 || raster->height == 0){ - raster->flags |= Raster::DONTALLOCATE; - raster->stride = 0; - return; - } + rasterSetFormat(raster); switch(raster->type){ case Raster::NORMAL: case Raster::TEXTURE: + // Dummy to use as subraster + // ^ what did i do there? + if(raster->width == 0 || raster->height == 0){ + raster->flags |= Raster::DONTALLOCATE; + raster->stride = 0; + return; + } + if(raster->flags & Raster::DONTALLOCATE) return; rasterCreateTexture(raster); break; - case Raster::ZBUFFER: - raster->flags |= Raster::DONTALLOCATE; - // TODO - break; - case Raster::CAMERA: - // TODO: get stuff from video mode - raster->flags |= Raster::DONTALLOCATE; - raster->originalWidth = raster->width; - raster->originalHeight = raster->height; - raster->stride = 0; - raster->pixels = nil; - break; case Raster::CAMERATEXTURE: if(raster->flags & Raster::DONTALLOCATE) return; rasterCreateCameraTexture(raster); break; + + case Raster::ZBUFFER: + rasterCreateZbuffer(raster); + break; + case Raster::CAMERA: + rasterCreateCamera(raster); + break; } } diff --git a/src/d3d/d3ddevice.cpp b/src/d3d/d3ddevice.cpp index e9aefd1..d99a702 100644 --- a/src/d3d/d3ddevice.cpp +++ b/src/d3d/d3ddevice.cpp @@ -21,26 +21,7 @@ namespace d3d { #ifdef RW_D3D9 -struct DisplayMode -{ - D3DDISPLAYMODE mode; - uint32 flags; -}; - -struct D3d9Globals -{ - HWND window; - - IDirect3D9 *d3d9; - int numAdapters; - int adapter; - D3DCAPS9 caps; - DisplayMode *modes; - int numModes; - int currentMode; - - D3DPRESENT_PARAMETERS present; -} d3d9Globals; +D3d9Globals d3d9Globals; // Keep track of rasters exclusively in video memory // as they need special treatment sometimes @@ -761,12 +742,52 @@ showRaster(Raster *raster) d3ddevice->Present(nil, nil, 0, nil); } +static bool32 +rasterRenderFast(Raster *raster, int32 x, int32 y) +{ + IDirect3DTexture9 *dsttex; + IDirect3DSurface9 *srcsurf, *dstsurf; + D3DSURFACE_DESC srcdesc, dstdesc; + RECT rect = { x, y, x, y }; + + Raster *src = raster; + Raster *dst = Raster::getCurrentContext(); + D3dRaster *natdst = PLUGINOFFSET(D3dRaster, dst, nativeRasterOffset); + D3dRaster *natsrc = PLUGINOFFSET(D3dRaster, src, nativeRasterOffset); + + switch(dst->type){ + case Raster::CAMERATEXTURE: + switch(src->type){ + case Raster::CAMERA: + dsttex = (IDirect3DTexture9*)natdst->texture; + dsttex->GetSurfaceLevel(0, &dstsurf); + assert(dstsurf); + dstsurf->GetDesc(&dstdesc); + + d3ddevice->GetRenderTarget(0, &srcsurf); + assert(srcsurf); + srcsurf->GetDesc(&srcdesc); + + rect.right += srcdesc.Width; + rect.bottom += srcdesc.Height; + + d3ddevice->StretchRect(srcsurf, &rect, dstsurf, &rect, D3DTEXF_NONE); + dstsurf->Release(); + srcsurf->Release(); + return 1; + } + break; + } + + return 0; +} + // // Device // -static int +int findFormatDepth(uint32 format) { // not all formats actually @@ -1241,6 +1262,7 @@ Device renderdevice = { d3d::endUpdate, d3d::clearCamera, d3d::showRaster, + d3d::rasterRenderFast, d3d::setRwRenderState, d3d::getRwRenderState, d3d::im2DRenderLine, diff --git a/src/d3d/rwd3dimpl.h b/src/d3d/rwd3dimpl.h index 640a391..d4ffe17 100644 --- a/src/d3d/rwd3dimpl.h +++ b/src/d3d/rwd3dimpl.h @@ -18,6 +18,32 @@ void closeIm3D(void); void im3DTransform(void *vertices, int32 numVertices, Matrix *world); void im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices); void im3DEnd(void); + + +struct DisplayMode +{ + D3DDISPLAYMODE mode; + uint32 flags; +}; + +struct D3d9Globals +{ + HWND window; + + IDirect3D9 *d3d9; + int numAdapters; + int adapter; + D3DCAPS9 caps; + DisplayMode *modes; + int numModes; + int currentMode; + + D3DPRESENT_PARAMETERS present; +}; + +extern D3d9Globals d3d9Globals; + +int findFormatDepth(uint32 format); #endif void rasterCreate(Raster *raster); diff --git a/src/engine.cpp b/src/engine.cpp index 8cd671d..0b5650e 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -84,6 +84,7 @@ Engine::init(void) // core plugin attach here Frame::registerModule(); + Raster::registerModule(); Texture::registerModule(); // driver plugin attach @@ -124,10 +125,8 @@ Engine::open(EngineOpenParams *p) engine->device = null::renderdevice; #endif - // TODO: create d3d object/get video mode engine->device.system(DEVICEOPEN, (void*)p, 0); - // TODO: init driver functions ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL); for(uint i = 0; i < NUM_PLATFORMS; i++){ rw::engine->driver[i] = (Driver*)rwNew(Driver::s_plglist[i].size, @@ -279,6 +278,8 @@ void showRaster(Raster*) { } void setRenderState(int32, void*) { } void *getRenderState(int32) { return 0; } +bool32 rasterRenderFast(Raster *raster, int32 x, int32 y) { return 0; } + void im2DRenderLine(void*, int32, int32, int32) { } void im2DRenderTriangle(void*, int32, int32, int32, int32) { } void im2DRenderPrimitive(PrimitiveType, void*, int32) { } @@ -360,6 +361,7 @@ Device renderdevice = { null::endUpdate, null::clearCamera, null::showRaster, + null::rasterRenderFast, null::setRenderState, null::getRenderState, null::im2DRenderLine, diff --git a/src/frame.cpp b/src/frame.cpp index 8f7f6c1..0ff9b6f 100644 --- a/src/frame.cpp +++ b/src/frame.cpp @@ -44,8 +44,8 @@ Frame::create(void) Frame* Frame::cloneHierarchy(void) { - Frame *frame = this->cloneAndLink(nil); - frame->purgeClone(); + Frame *frame = this->cloneAndLink(); + this->purgeClone(); return frame; } @@ -129,8 +129,12 @@ Frame::removeChild(void) Frame* Frame::forAllChildren(Callback cb, void *data) { - for(Frame *f = this->child; f; f = f->next) - cb(f, data); + Frame *next; + for(Frame *f = this->child; f; f = next){ + next = f->next; + if(cb(f, data) == nil) + return this; + } return this; } @@ -304,27 +308,39 @@ Frame::setHierarchyRoot(Frame *root) child->setHierarchyRoot(root); } -// Clone a frame hierarchy. Link cloned frames into Frame::root of the originals. -Frame* -Frame::cloneAndLink(Frame *clonedroot) +static Frame* +cloneRecurse(Frame *old, Frame *newroot) { Frame *frame = Frame::create(); - if(clonedroot == nil) - clonedroot = frame; - frame->object.copy(&this->object); - frame->matrix = this->matrix; - frame->root = clonedroot; - this->root = frame; // Remember cloned frame - for(Frame *child = this->child; child; child = child->next){ - Frame *clonedchild = child->cloneAndLink(clonedroot); + if(newroot == nil) + newroot = frame; + frame->object.copy(&old->object); + frame->matrix = old->matrix; + frame->root = newroot; + old->root = frame; // Remember cloned frame + for(Frame *child = old->child; child; child = child->next){ + Frame *clonedchild = cloneRecurse(child, newroot); clonedchild->next = frame->child; frame->child = clonedchild; clonedchild->object.parent = frame; } - s_plglist.copy(frame, this); + Frame::s_plglist.copy(frame, old); return frame; } +// Clone a frame hierarchy. Link cloned frames into Frame::root of the originals. +Frame* +Frame::cloneAndLink(void) +{ + Frame *newhier = cloneRecurse(this, nil); + if(newhier){ + // frame is not in dirty list so important to get this flag right + newhier->object.privateFlags &= ~HIERARCHYSYNC; + newhier->updateObjects(); + } + return newhier; +} + // Remove links to cloned frames from hierarchy. void Frame::purgeClone(void) diff --git a/src/gl/gl3device.cpp b/src/gl/gl3device.cpp index 375e6d8..62de0bb 100644 --- a/src/gl/gl3device.cpp +++ b/src/gl/gl3device.cpp @@ -662,6 +662,13 @@ showRaster(Raster *raster) #endif } +static bool32 +rasterRenderFast(Raster *raster, int32 x, int32 y) +{ + // use glCopyTexSubImage2D + return 0; +} + static void beginUpdate(Camera *cam) { @@ -1123,6 +1130,7 @@ Device renderdevice = { null::endUpdate, gl3::clearCamera, gl3::showRaster, + gl3::rasterRenderFast, gl3::setRenderState, gl3::getRenderState, gl3::im2DRenderLine, diff --git a/src/ps2/ps2device.cpp b/src/ps2/ps2device.cpp index b2e7285..c5f4bdf 100644 --- a/src/ps2/ps2device.cpp +++ b/src/ps2/ps2device.cpp @@ -29,8 +29,12 @@ Device renderdevice = { null::endUpdate, null::clearCamera, null::showRaster, + null::rasterRenderFast, null::setRenderState, null::getRenderState, + null::im2DRenderLine, + null::im2DRenderTriangle, + null::im2DRenderPrimitive, null::im2DRenderIndexedPrimitive, null::im3DTransform, null::im3DRenderIndexed, diff --git a/src/raster.cpp b/src/raster.cpp new file mode 100644 index 0000000..3115bfe --- /dev/null +++ b/src/raster.cpp @@ -0,0 +1,198 @@ +#include +#include +#include +#include + +#include "rwbase.h" +#include "rwerror.h" +#include "rwplg.h" +#include "rwpipeline.h" +#include "rwobjects.h" +#include "rwengine.h" +//#include "ps2/rwps2.h" +//#include "d3d/rwd3d.h" +//#include "d3d/rwxbox.h" +//#include "d3d/rwd3d8.h" +//#include "d3d/rwd3d9.h" + +#define PLUGIN_ID 0 + +namespace rw { + +struct RasterGlobals +{ + int32 sp; + Raster *stack[32]; +}; +int32 rasterModuleOffset; + +#define RASTERGLOBAL(v) (PLUGINOFFSET(RasterGlobals, engine, rasterModuleOffset)->v) + +static void* +rasterOpen(void *object, int32 offset, int32 size) +{ + int i; + rasterModuleOffset = offset; + RASTERGLOBAL(sp) = -1; + for(i = 0; i < nelem(RASTERGLOBAL(stack)); i++) + RASTERGLOBAL(stack)[i] = nil; + return object; +} + +static void* +rasterClose(void *object, int32 offset, int32 size) +{ + return object; +} + +void +Raster::registerModule(void) +{ + Engine::registerPlugin(sizeof(RasterGlobals), ID_RASTERMODULE, rasterOpen, rasterClose); +} + +Raster* +Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platform) +{ + // TODO: pass arguments through to the driver and create the raster there + Raster *raster = (Raster*)rwMalloc(s_plglist.size, MEMDUR_EVENT); // TODO + assert(raster != nil); + raster->parent = raster; + raster->offsetX = 0; + raster->offsetY = 0; + 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; + raster->depth = depth; + raster->pixels = raster->palette = nil; + s_plglist.construct(raster); + +// printf("%d %d %d %d\n", raster->type, raster->width, raster->height, raster->depth); + engine->driver[raster->platform]->rasterCreate(raster); + return raster; +} + +void +Raster::subRaster(Raster *parent, Rect *r) +{ + if((this->flags & DONTALLOCATE) == 0) + return; + this->width = r->w; + this->height = r->h; + this->offsetX += r->x; + this->offsetY += r->y; + this->parent = parent->parent; +} + +void +Raster::destroy(void) +{ + s_plglist.destruct(this); +// delete[] this->texels; +// delete[] this->palette; + rwFree(this); +} + +uint8* +Raster::lock(int32 level, int32 lockMode) +{ + return engine->driver[this->platform]->rasterLock(this, level, lockMode); +} + +void +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) +{ + return engine->driver[this->platform]->rasterNumLevels(this); +} + +int32 +Raster::calculateNumLevels(int32 width, int32 height) +{ + int32 size = width >= height ? width : height; + int32 n; + for(n = 0; size != 0; n++) + size /= 2; + return n; +} + +bool +Raster::formatHasAlpha(int32 format) +{ + return (format & 0xF00) == Raster::C8888 || + (format & 0xF00) == Raster::C1555 || + (format & 0xF00) == Raster::C4444; +} + +Raster* +Raster::createFromImage(Image *image, int32 platform) +{ + Raster *raster = Raster::create(image->width, image->height, + image->depth, TEXTURE | DONTALLOCATE, + platform); + engine->driver[raster->platform]->rasterFromImage(raster, image); + return raster; +} + +Image* +Raster::toImage(void) +{ + return engine->driver[this->platform]->rasterToImage(this); +} + +Raster* +Raster::pushContext(Raster *raster) +{ + RasterGlobals *g = PLUGINOFFSET(RasterGlobals, engine, rasterModuleOffset); + if(g->sp >= (int32)nelem(g->stack)-1) + return nil; + return g->stack[++g->sp] = raster; +} + +Raster* +Raster::popContext(void) +{ + RasterGlobals *g = PLUGINOFFSET(RasterGlobals, engine, rasterModuleOffset); + if(g->sp < 0) + return nil; + return g->stack[g->sp--]; +} + +Raster* +Raster::getCurrentContext(void) +{ + RasterGlobals *g = PLUGINOFFSET(RasterGlobals, engine, rasterModuleOffset); + if(g->sp < 0 || g->sp >= (int32)nelem(g->stack)) + return nil; + return g->stack[g->sp]; +} + +bool32 +Raster::renderFast(int32 x, int32 y) +{ + return engine->device.rasterRenderFast(this,x, y); +} + + +} diff --git a/src/rwbase.h b/src/rwbase.h index 255dd6a..1a06d0b 100644 --- a/src/rwbase.h +++ b/src/rwbase.h @@ -566,6 +566,7 @@ enum CoreModuleID { ID_NAMODULE = MAKEPLUGINID(VEND_CRITERIONINT, 0x00), ID_FRAMEMODULE = MAKEPLUGINID(VEND_CRITERIONINT, 0x03), + ID_RASTERMODULE = MAKEPLUGINID(VEND_CRITERIONINT, 0x07), ID_TEXTUREMODULE = MAKEPLUGINID(VEND_CRITERIONINT, 0x08) }; diff --git a/src/rwengine.h b/src/rwengine.h index 503bc57..755f162 100644 --- a/src/rwengine.h +++ b/src/rwengine.h @@ -1,5 +1,6 @@ namespace rw { +// uhhhm..... why are these not actual functions? enum DeviceReq { // Device initialization before Engine/Driver plugins are opened @@ -45,6 +46,7 @@ struct Device void (*endUpdate)(Camera*); void (*clearCamera)(Camera*, RGBA *col, uint32 mode); void (*showRaster)(Raster *raster); + bool32 (*rasterRenderFast)(Raster *raster, int32 x, int32 y); void (*setRenderState)(int32 state, void *value); void *(*getRenderState)(int32 state); diff --git a/src/rwobjects.h b/src/rwobjects.h index 4accfb5..ed38d38 100644 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -77,7 +77,7 @@ struct Frame void syncHierarchyLTM(void); void setHierarchyRoot(Frame *root); - Frame *cloneAndLink(Frame *clonedroot); + Frame *cloneAndLink(void); void purgeClone(void); #ifndef RWPUBLIC @@ -200,6 +200,15 @@ struct Raster static int32 calculateNumLevels(int32 width, int32 height); static bool formatHasAlpha(int32 format); + static Raster *pushContext(Raster *raster); + static Raster *popContext(void); + static Raster *getCurrentContext(void); + bool32 renderFast(int32 x, int32 y); + +#ifndef RWPUBLIC + static void registerModule(void); +#endif + enum Format { DEFAULT = 0, C1555 = 0x0100, @@ -233,6 +242,7 @@ struct Raster }; }; + #define IGNORERASTERIMP 0 struct TexDictionary; diff --git a/src/texture.cpp b/src/texture.cpp index 8a6b882..e292e2d 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -454,118 +454,4 @@ Texture::streamGetSizeNative(void) return 0; } -// -// Raster -// - -Raster* -Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platform) -{ - // TODO: pass arguments through to the driver and create the raster there - Raster *raster = (Raster*)rwMalloc(s_plglist.size, MEMDUR_EVENT); // TODO - assert(raster != nil); - raster->parent = raster; - raster->offsetX = 0; - raster->offsetY = 0; - 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; - raster->depth = depth; - raster->pixels = raster->palette = nil; - s_plglist.construct(raster); - -// printf("%d %d %d %d\n", raster->type, raster->width, raster->height, raster->depth); - engine->driver[raster->platform]->rasterCreate(raster); - return raster; -} - -void -Raster::subRaster(Raster *parent, Rect *r) -{ - if((this->flags & DONTALLOCATE) == 0) - return; - this->width = r->w; - this->height = r->h; - this->offsetX += r->x; - this->offsetY += r->y; - this->parent = parent->parent; -} - -void -Raster::destroy(void) -{ - s_plglist.destruct(this); -// delete[] this->texels; -// delete[] this->palette; - rwFree(this); -} - -uint8* -Raster::lock(int32 level, int32 lockMode) -{ - return engine->driver[this->platform]->rasterLock(this, level, lockMode); -} - -void -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) -{ - return engine->driver[this->platform]->rasterNumLevels(this); -} - -int32 -Raster::calculateNumLevels(int32 width, int32 height) -{ - int32 size = width >= height ? width : height; - int32 n; - for(n = 0; size != 0; n++) - size /= 2; - return n; -} - -bool -Raster::formatHasAlpha(int32 format) -{ - return (format & 0xF00) == Raster::C8888 || - (format & 0xF00) == Raster::C1555 || - (format & 0xF00) == Raster::C4444; -} - -Raster* -Raster::createFromImage(Image *image, int32 platform) -{ - Raster *raster = Raster::create(image->width, image->height, - image->depth, TEXTURE | DONTALLOCATE, - platform); - engine->driver[raster->platform]->rasterFromImage(raster, image); - return raster; -} - -Image* -Raster::toImage(void) -{ - return engine->driver[this->platform]->rasterToImage(this); -} - } diff --git a/tools/clumpview/main.cpp b/tools/clumpview/main.cpp index 13df56f..8afce48 100644 --- a/tools/clumpview/main.cpp +++ b/tools/clumpview/main.cpp @@ -14,6 +14,8 @@ rw::Texture *tex, *tex2; rw::Raster *testras; rw::EngineOpenParams engineOpenParams; +rw::Texture *frontbuffer; + bool dosoftras = 0; namespace gen { @@ -28,6 +30,11 @@ void printScreen(const char *s, float x, float y); void Init(void) { +// AllocConsole(); +// freopen("CONIN$", "r", stdin); +// freopen("CONOUT$", "w", stdout); +// freopen("CONOUT$", "w", stderr); + sk::globals.windowtitle = "Clump viewer"; sk::globals.width = 640; sk::globals.height = 448; @@ -318,7 +325,8 @@ im3dtest(void) verts[i].setV(vs[i].v); } - rw::SetRenderStatePtr(rw::TEXTURERASTER, tex->raster); +// rw::SetRenderStatePtr(rw::TEXTURERASTER, tex->raster); + rw::SetRenderStatePtr(rw::TEXTURERASTER, frontbuffer->raster); rw::SetRenderState(rw::TEXTUREADDRESS, rw::Texture::WRAP); rw::SetRenderState(rw::TEXTUREFILTER, rw::Texture::NEAREST); @@ -332,10 +340,35 @@ im3dtest(void) rw::im3d::End(); } +void +getFrontBuffer(void) +{ + rw::Raster *fb = Scene.camera->frameBuffer; + + if(frontbuffer == nil || fb->width > frontbuffer->raster->width || fb->height > frontbuffer->raster->height){ + int w, h; + for(w = 1; w < fb->width; w <<= 1); + for(h = 1; h < fb->height; h <<= 1); + rw::Raster *ras = rw::Raster::create(w, h, fb->depth, rw::Raster::CAMERATEXTURE); + if(frontbuffer){ + frontbuffer->raster->destroy(); + frontbuffer->raster = ras; + }else + frontbuffer = rw::Texture::create(ras); + printf("created FB with %d %d %d\n", ras->width, ras->height, ras->depth); + } + + rw::Raster::pushContext(frontbuffer->raster); + fb->renderFast(0, 0); + rw::Raster::popContext(); +} + void Draw(float timeDelta) { - static rw::RGBA clearcol = { 0x80, 0x80, 0x80, 0xFF }; + getFrontBuffer(); + + static rw::RGBA clearcol = { 0x60, 0x60, 0x60, 0xFF }; camera->m_rwcam->clear(&clearcol, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ); camera->update(); camera->m_rwcam->beginUpdate(); @@ -343,7 +376,7 @@ Draw(float timeDelta) extern void beginSoftras(void); beginSoftras(); - gen::tlTest(Scene.clump); +// gen::tlTest(Scene.clump); void drawtest(void); // drawtest(); @@ -351,14 +384,15 @@ extern void endSoftras(void); if(dosoftras){ endSoftras(); } - im2dtest(); + // im2dtest(); // Scene.clump->render(); -// im3dtest(); + im3dtest(); // printScreen("Hello, World!", 10, 10); camera->m_rwcam->endUpdate(); + camera->m_rwcam->showRaster(); }