Merge pull request #139 from Splendide-Imaginarius/mkxp-z-bitmap-constructors

Refactor Bitmap constructors
This commit is contained in:
Splendide Imaginarius 2023-11-29 10:10:58 +00:00 committed by GitHub
commit 9bdb70bc04
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 136 additions and 55 deletions

View file

@ -460,4 +460,10 @@
// "x": ...
// }
// Dump tile atlas (for debugging purposes)
// (default: false)
//
// "dumpAtlas": false,
}

View file

@ -188,6 +188,7 @@ void Config::read(int argc, char *argv[]) {
{"JITMaxCache", 100},
{"JITMinCalls", 10000},
{"YJITEnable", false},
{"dumpAtlas", false},
{"bindingNames", json::object({
{"a", "A"},
{"b", "B"},
@ -296,6 +297,7 @@ try { exp } catch (...) {}
SET_OPT_CUSTOMKEY(BGM.trackCount, BGMTrackCount, integer);
SET_STRINGOPT(customScript, customScript);
SET_OPT(useScriptNames, boolean);
SET_OPT(dumpAtlas, boolean);
fillStringVec(opts["preloadScript"], preloadScripts);
fillStringVec(opts["RTP"], rtps);

View file

@ -111,7 +111,7 @@ struct Config {
std::vector<std::string> fontSubs;
std::vector<std::string> rubyLoadpaths;
/* Editor flags */
struct {
bool debug;
@ -137,6 +137,8 @@ struct Config {
bool enabled;
} yjit;
bool dumpAtlas;
// Keybinding action name mappings
struct {
std::string a;

View file

@ -618,49 +618,10 @@ Bitmap::Bitmap(const char *filename)
p->addTaintedArea(rect());
return;
}
SDL_Surface *imgSurf = handler.surface;
p->ensureFormat(imgSurf, SDL_PIXELFORMAT_ABGR8888);
if (imgSurf->w > glState.caps.maxTexSize || imgSurf->h > glState.caps.maxTexSize)
{
/* Mega surface */
p = new BitmapPrivate(this);
p->selfHires = hiresBitmap;
p->megaSurface = imgSurf;
SDL_SetSurfaceBlendMode(p->megaSurface, SDL_BLENDMODE_NONE);
}
else
{
/* Regular surface */
TEXFBO tex;
try
{
tex = shState->texPool().request(imgSurf->w, imgSurf->h);
}
catch (const Exception &e)
{
SDL_FreeSurface(imgSurf);
throw e;
}
p = new BitmapPrivate(this);
p->selfHires = hiresBitmap;
p->gl = tex;
if (p->selfHires != nullptr) {
p->gl.selfHires = &p->selfHires->getGLTypes();
}
TEX::bind(p->gl.tex);
TEX::uploadImage(p->gl.width, p->gl.height, imgSurf->pixels, GL_RGBA);
SDL_FreeSurface(imgSurf);
}
p->addTaintedArea(rect());
initFromSurface(imgSurf, hiresBitmap, true);
}
Bitmap::Bitmap(int width, int height, bool isHires)
@ -683,10 +644,10 @@ Bitmap::Bitmap(int width, int height, bool isHires)
p = new BitmapPrivate(this);
p->gl = tex;
p->selfHires = hiresBitmap;
if (p->selfHires != nullptr) {
p->gl.selfHires = &p->selfHires->getGLTypes();
}
p->selfHires = hiresBitmap;
clear();
}
@ -798,11 +759,104 @@ Bitmap::Bitmap(const Bitmap &other, int frame)
p->addTaintedArea(rect());
}
Bitmap::Bitmap(TEXFBO &other)
{
Bitmap *hiresBitmap = nullptr;
if (other.selfHires != nullptr) {
// Create a high-res version as well.
hiresBitmap = new Bitmap(*other.selfHires);
hiresBitmap->setLores(this);
}
p = new BitmapPrivate(this);
p->gl = shState->texPool().request(other.width, other.height);
p->selfHires = hiresBitmap;
if (p->selfHires != nullptr) {
p->gl.selfHires = &p->selfHires->getGLTypes();
}
// Skip blitting to lores texture, since only the hires one will be displayed.
if (p->selfHires == nullptr) {
GLMeta::blitBegin(p->gl);
GLMeta::blitSource(other);
GLMeta::blitRectangle(rect(), rect(), true);
GLMeta::blitEnd();
}
p->addTaintedArea(rect());
}
Bitmap::Bitmap(SDL_Surface *imgSurf, SDL_Surface *imgSurfHires)
{
Bitmap *hiresBitmap = nullptr;
if (imgSurfHires != nullptr) {
// Create a high-res version as well.
hiresBitmap = new Bitmap(imgSurfHires, nullptr);
hiresBitmap->setLores(this);
}
initFromSurface(imgSurf, hiresBitmap, false);
}
Bitmap::~Bitmap()
{
dispose();
}
void Bitmap::initFromSurface(SDL_Surface *imgSurf, Bitmap *hiresBitmap, bool freeSurface)
{
p->ensureFormat(imgSurf, SDL_PIXELFORMAT_ABGR8888);
if (imgSurf->w > glState.caps.maxTexSize || imgSurf->h > glState.caps.maxTexSize)
{
/* Mega surface */
if(!freeSurface) {
throw Exception(Exception::RGSSError, "Cloning Mega Bitmap from Surface not supported");
}
p = new BitmapPrivate(this);
p->selfHires = hiresBitmap;
p->megaSurface = imgSurf;
SDL_SetSurfaceBlendMode(p->megaSurface, SDL_BLENDMODE_NONE);
}
else
{
/* Regular surface */
TEXFBO tex;
try
{
tex = shState->texPool().request(imgSurf->w, imgSurf->h);
}
catch (const Exception &e)
{
SDL_FreeSurface(imgSurf);
throw e;
}
p = new BitmapPrivate(this);
p->selfHires = hiresBitmap;
p->gl = tex;
if (p->selfHires != nullptr) {
p->gl.selfHires = &p->selfHires->getGLTypes();
}
TEX::bind(p->gl.tex);
TEX::uploadImage(p->gl.width, p->gl.height, imgSurf->pixels, GL_RGBA);
if (freeSurface) {
SDL_FreeSurface(imgSurf);
}
}
p->addTaintedArea(rect());
}
int Bitmap::width() const
{
guardDisposed();

View file

@ -40,13 +40,18 @@ class Bitmap : public Disposable
public:
Bitmap(const char *filename);
Bitmap(int width, int height, bool isHires = false);
Bitmap(void *pixeldata, int width, int height);
Bitmap(void *pixeldata, int width, int height);
Bitmap(TEXFBO &other);
Bitmap(SDL_Surface *imgSurf, SDL_Surface *imgSurfHires);
/* Clone constructor */
// frame is -2 for "any and all", -1 for "current", anything else for a specific frame
Bitmap(const Bitmap &other, int frame = -2);
~Bitmap();
void initFromSurface(SDL_Surface *imgSurf, Bitmap *hiresBitmap, bool freeSurface);
int width() const;
int height() const;
bool hasHires() const;

View file

@ -179,7 +179,9 @@ struct Movie
SDL_Delay(VIDEO_DELAY);
}
}
videoBitmap = new Bitmap(video->width, video->height);
// Create this Bitmap without a hires replacement, because we don't
// support hires replacement for Movies yet.
videoBitmap = new Bitmap(video->width, video->height, true);
audioQueueHead = NULL;
audioQueueTail = NULL;
@ -1401,17 +1403,17 @@ void Graphics::fadein(int duration) {
}
Bitmap *Graphics::snapToBitmap() {
Bitmap *bitmap = new Bitmap(width(), height());
if (bitmap->hasHires()) {
p->compositeToBufferScaled(bitmap->getHires()->getGLTypes(), bitmap->getHires()->width(), bitmap->getHires()->height());
if (shState->config().enableHires) {
// TODO: Maybe don't reconstruct this struct every time?
TEXFBO tf;
tf.width = width();
tf.height = height();
tf.selfHires = &p->screen.getPP().frontBuffer();
return new Bitmap(tf);
}
p->compositeToBufferScaled(bitmap->getGLTypes(), bitmap->width(), bitmap->height());
/* Taint entire bitmap */
bitmap->taintArea(IntRect(0, 0, width(), height()));
return bitmap;
return new Bitmap(p->screen.getPP().frontBuffer());
}
int Graphics::width() const { return p->scResLores.x; }

View file

@ -190,6 +190,16 @@ struct TilemapVXPrivate : public ViewportElement, TileAtlasVX::Reader
void rebuildAtlas()
{
TileAtlasVX::build(atlas, bitmaps);
if (shState->config().dumpAtlas)
{
Bitmap dump(atlas);
dump.saveToFile("dumped_atlas.png");
if (dump.hasHires())
{
dump.getHires()->saveToFile("dumped_atlas_hires.png");
}
}
}
void updateMapViewport()