mirror of https://github.com/aap/librw.git
277 lines
5.5 KiB
C++
277 lines
5.5 KiB
C++
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
|
|
#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 {
|
|
|
|
int32 Raster::numAllocated;
|
|
|
|
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);
|
|
numAllocated++;
|
|
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);
|
|
return engine->driver[raster->platform]->rasterCreate(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);
|
|
rwFree(this);
|
|
numAllocated--;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
bool32
|
|
Raster::imageFindRasterFormat(Image *image, int32 type,
|
|
int32 *pWidth, int32 *pHeight, int32 *pDepth, int32 *pFormat,
|
|
int32 platform)
|
|
{
|
|
return engine->driver[platform ? platform : rw::platform]->imageFindRasterFormat(
|
|
image, type, pWidth, pHeight, pDepth, pFormat);
|
|
}
|
|
|
|
Raster*
|
|
Raster::setFromImage(Image *image, int32 platform)
|
|
{
|
|
if(engine->driver[platform ? platform : rw::platform]->rasterFromImage(this, image))
|
|
return this;
|
|
return nil;
|
|
}
|
|
|
|
Raster*
|
|
Raster::createFromImage(Image *image, int32 platform)
|
|
{
|
|
Raster *raster;
|
|
int32 width, height, depth, format;
|
|
if(!imageFindRasterFormat(image, TEXTURE, &width, &height, &depth, &format, platform))
|
|
return nil;
|
|
raster = Raster::create(width, height, depth, format, platform);
|
|
if(raster == nil)
|
|
return nil;
|
|
return raster->setFromImage(image, platform);
|
|
}
|
|
|
|
Image*
|
|
Raster::toImage(void)
|
|
{
|
|
return engine->driver[this->platform]->rasterToImage(this);
|
|
}
|
|
|
|
void
|
|
Raster::show(uint32 flags)
|
|
{
|
|
engine->device.showRaster(this, flags);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
void
|
|
conv_RGBA8888_to_RGBA8888(uint8 *out, uint8 *in)
|
|
{
|
|
out[0] = in[0];
|
|
out[1] = in[1];
|
|
out[2] = in[2];
|
|
out[3] = in[3];
|
|
}
|
|
|
|
void
|
|
conv_RGB888_to_RGBA8888(uint8 *out, uint8 *in)
|
|
{
|
|
out[0] = in[0];
|
|
out[1] = in[1];
|
|
out[2] = in[2];
|
|
out[3] = 0xFF;
|
|
}
|
|
|
|
void
|
|
conv_RGB888_to_RGB888(uint8 *out, uint8 *in)
|
|
{
|
|
out[0] = in[0];
|
|
out[1] = in[1];
|
|
out[2] = in[2];
|
|
}
|
|
|
|
void
|
|
conv_RGBA1555_to_RGBA5551(uint8 *out, uint8 *in)
|
|
{
|
|
uint32 r, g, b, a;
|
|
a = (in[1]>>7) & 1;
|
|
r = (in[1]>>2) & 0x1F;
|
|
g = (in[1]&3)<<3 | (in[0]>>5)&7;
|
|
b = in[0] & 0x1F;
|
|
out[0] = a | b<<1 | g<<6;
|
|
out[1] = g>>2 | r<<3;
|
|
}
|
|
|
|
void
|
|
conv_RGBA1555_to_RGBA8888(uint8 *out, uint8 *in)
|
|
{
|
|
uint32 r, g, b, a;
|
|
a = (in[1]>>7) & 1;
|
|
r = (in[1]>>2) & 0x1F;
|
|
g = (in[1]&3)<<3 | (in[0]>>5)&7;
|
|
b = in[0] & 0x1F;
|
|
out[0] = r*0xFF/0x1f;
|
|
out[1] = g*0xFF/0x1f;
|
|
out[2] = b*0xFF/0x1f;
|
|
out[3] = a*0xFF;
|
|
}
|
|
|
|
}
|