This commit is contained in:
Splendide Imaginarius 2025-03-26 07:48:49 +00:00 committed by GitHub
commit 8ab2b90ba2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 89 additions and 15 deletions

View file

@ -66,16 +66,49 @@ void bitmapInitProps(Bitmap *b, VALUE self) {
RB_METHOD_GUARD(bitmapInitialize) {
Bitmap *b = 0;
if (argc == 1) {
char *filename;
rb_get_args(argc, argv, "z", &filename RB_ARG_END);
GFX_GUARD_EXC(b = new Bitmap(filename);)
} else {
int width, height;
rb_get_args(argc, argv, "ii", &width, &height RB_ARG_END);
VALUE arg1;
VALUE arg2;
VALUE kwargs;
rb_scan_args(argc, argv, "11:", &arg1, &arg2, &kwargs);
ID table[1];
table[0] = rb_intern("device_affinity");
VALUE deviceAffinity;
rb_get_kwargs(kwargs, table, 0, 1, &deviceAffinity);
if (RB_TYPE_P(arg1, RUBY_T_STRING)) {
// filename constructor, arg1 is filename
SafeStringValue(arg1);
int affinity = 0;
if (deviceAffinity != Qundef && deviceAffinity != Qnil) {
affinity = NUM2INT(deviceAffinity);
}
bool forceMega = false;
if (affinity == 1) {
forceMega = true;
}
if (forceMega) {
#if RAPI_MAJOR >= 2
b = (Bitmap*)drop_gvl_guard([](void* fn) -> void* {
Bitmap *bmp = new Bitmap((const char*)fn, true);
return (void*)bmp;
}, (void*)RSTRING_PTR(arg1), 0, 0);
#else
b = new Bitmap(RSTRING_PTR(arg1), forceMega);
#endif
} else {
GFX_GUARD_EXC(b = new Bitmap(RSTRING_PTR(arg1), forceMega);)
}
}
else {
// width,height constructor
int width = NUM2INT(arg1);
int height = NUM2INT(arg2);
GFX_GUARD_EXC(b = new Bitmap(width, height);)
}

View file

@ -60,9 +60,13 @@ extern "C" {
#define GUARD_MEGA \
{ \
if (p->megaSurface) \
if (p->megaSurface) { \
p->ensureNonMega(); \
if (p->megaSurface) { \
throw Exception(Exception::MKXPError, \
"Operation not supported for mega surfaces"); \
} \
} \
}
#define GUARD_ANIMATED \
@ -408,6 +412,43 @@ struct BitmapPrivate
SDL_FreeSurface(surf);
surf = surfConv;
}
void ensureNonMega()
{
if (selfHires != nullptr) {
if (selfHires->width() > glState.caps.maxTexSize || selfHires->height() > glState.caps.maxTexSize) {
return;
}
selfHires->ensureNonMega();
}
if (megaSurface->w > glState.caps.maxTexSize || megaSurface->h > glState.caps.maxTexSize)
{
return;
}
TEXFBO tex;
try
{
tex = shState->texPool().request(megaSurface->w, megaSurface->h);
}
catch (const Exception &e)
{
return;
}
gl = tex;
if (selfHires != nullptr) {
gl.selfHires = &selfHires->getGLTypes();
}
TEX::bind(gl.tex);
TEX::uploadImage(gl.width, gl.height, megaSurface->pixels, GL_RGBA);
SDL_FreeSurface(megaSurface);
megaSurface = nullptr;
}
void onModified(bool freeSurface = true)
{
@ -488,7 +529,7 @@ struct BitmapOpenHandler : FileSystem::OpenHandler
}
};
Bitmap::Bitmap(const char *filename)
Bitmap::Bitmap(const char *filename, bool forceMega)
{
std::string hiresPrefix = "Hires/";
std::string filenameStd = filename;
@ -498,7 +539,7 @@ Bitmap::Bitmap(const char *filename)
// Look for a high-res version of the file.
std::string hiresFilename = hiresPrefix + filenameStd;
try {
hiresBitmap = new Bitmap(hiresFilename.c_str());
hiresBitmap = new Bitmap(hiresFilename.c_str(), forceMega);
hiresBitmap->setLores(this);
}
catch (const Exception &e)
@ -631,7 +672,7 @@ Bitmap::Bitmap(const char *filename)
SDL_Surface *imgSurf = handler.surface;
initFromSurface(imgSurf, hiresBitmap, false);
initFromSurface(imgSurf, hiresBitmap, forceMega);
}
Bitmap::Bitmap(int width, int height, bool isHires)

View file

@ -38,7 +38,7 @@ struct BitmapPrivate;
class Bitmap : public Disposable
{
public:
Bitmap(const char *filename);
Bitmap(const char *filename, bool forceMega = false);
Bitmap(int width, int height, bool isHires = false);
Bitmap(void *pixeldata, int width, int height);
Bitmap(TEXFBO &other);