mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-03 21:45:32 +02:00
Experimental giflib support
This commit is contained in:
parent
cc3392d896
commit
3b447e5efb
5 changed files with 111 additions and 5 deletions
13
meson.build
13
meson.build
|
@ -28,6 +28,19 @@ if discord_libpath != ''
|
|||
endif
|
||||
endif
|
||||
|
||||
# GIFLIB
|
||||
|
||||
gif = false
|
||||
gif_prefix = get_option('giflib_prefix')
|
||||
if gif_prefix != ''
|
||||
giflib = compiler.find_library('gif', required: false, dirs: gif_prefix+'/lib')
|
||||
if giflib.found() == true
|
||||
add_project_arguments(['-I@0@/include'.format(gif_prefix), '-DHAVE_GIFLIB'], language: 'cpp')
|
||||
ext_dependencies += giflib
|
||||
gif = true
|
||||
endif
|
||||
endif
|
||||
|
||||
# ====================
|
||||
# Main source
|
||||
# ====================
|
||||
|
|
|
@ -10,4 +10,5 @@ option('default_framerate', type: 'boolean', value: false, description: 'Disable
|
|||
option('no_preload_scripts', type: 'boolean', value: false, description: 'Disable the preloadScript configuration option')
|
||||
option('workdir_current', type: 'boolean', value: false, description: 'Keep current directory on startup')
|
||||
|
||||
option('discord_sdk_path', type: 'string', value: '', description: 'Path to Discord GameSDK')
|
||||
option('discord_sdk_path', type: 'string', value: '', description: 'Path to Discord GameSDK')
|
||||
option('giflib_prefix', type: 'string', value: '', description: 'Path to the prefix where giflib is installed')
|
|
@ -44,6 +44,10 @@
|
|||
#include "font.h"
|
||||
#include "eventthread.h"
|
||||
|
||||
#ifdef HAVE_GIFLIB
|
||||
#include <gif_lib.h>
|
||||
#endif
|
||||
|
||||
#define GUARD_MEGA \
|
||||
{ \
|
||||
if (p->megaSurface) \
|
||||
|
@ -101,11 +105,22 @@ struct BitmapPrivate
|
|||
* in the texture and blit to it directly, saving
|
||||
* ourselves the expensive blending calculation */
|
||||
pixman_region16_t tainted;
|
||||
|
||||
/* If the image is a gif, its frames are located here. */
|
||||
#ifdef HAVE_GIFLIB
|
||||
SDL_Surface* gifSurfaces[256];
|
||||
int nFrames;
|
||||
int currentFrame;
|
||||
#endif
|
||||
|
||||
BitmapPrivate(Bitmap *self)
|
||||
: self(self),
|
||||
megaSurface(0),
|
||||
surface(0)
|
||||
surface(0),
|
||||
#ifdef HAVE_GIFLIB
|
||||
nFrames(1),
|
||||
currentFrame(0)
|
||||
#endif
|
||||
{
|
||||
format = SDL_AllocFormat(SDL_PIXELFORMAT_ABGR8888);
|
||||
|
||||
|
@ -117,6 +132,10 @@ struct BitmapPrivate
|
|||
{
|
||||
SDL_FreeFormat(format);
|
||||
pixman_region_fini(&tainted);
|
||||
#ifdef HAVE_GIFLIB
|
||||
if (nFrames > 1)
|
||||
for (int i = 0; i < nFrames; i++) SDL_FreeSurface(gifSurfaces[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void allocSurface()
|
||||
|
@ -251,6 +270,53 @@ struct BitmapOpenHandler : FileSystem::OpenHandler
|
|||
Bitmap::Bitmap(const char *filename)
|
||||
{
|
||||
BitmapOpenHandler handler;
|
||||
|
||||
// If the file is a gif, try opening it with giflib first
|
||||
// and read every frame
|
||||
#ifdef HAVE_GIFLIB
|
||||
char *extension = strrchr((char*)filename, '.');
|
||||
int *rc{};
|
||||
if (extension && !strcmp((extension+1), "gif"))
|
||||
{
|
||||
GifFileType *gif = DGifOpenFileName(filename, rc);
|
||||
if (rc && DGifSlurp(gif) == GIF_OK)
|
||||
{
|
||||
p->nFrames = gif->ImageCount;
|
||||
int colorReso = gif->SColorResolution;
|
||||
for (int i = 0; i < p->nFrames; i++)
|
||||
{
|
||||
SDL_Surface *frame = SDL_CreateRGBSurface(0,
|
||||
gif->SWidth,
|
||||
gif->SHeight,
|
||||
colorReso,
|
||||
p->format->Rmask,
|
||||
p->format->Gmask,
|
||||
p->format->Bmask,
|
||||
p->format->Amask);
|
||||
if (frame)
|
||||
{
|
||||
memcpy(frame->pixels,
|
||||
gif->SavedImages[i].RasterBits,
|
||||
frame->w*frame->h*(colorReso/8));
|
||||
p->gifSurfaces[i] = frame;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int b = i; b >= 0; b--)
|
||||
{
|
||||
SDL_FreeSurface(p->gifSurfaces[b]);
|
||||
p->gifSurfaces[b] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
GifFreeSavedImages(gif);
|
||||
handler.surf = p->gifSurfaces[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (!handler.surf)
|
||||
#endif
|
||||
shState->fileSystem().openRead(handler, filename);
|
||||
SDL_Surface *imgSurf = handler.surf;
|
||||
|
||||
|
@ -814,6 +880,31 @@ void Bitmap::clear()
|
|||
p->onModified();
|
||||
}
|
||||
|
||||
void Bitmap::update()
|
||||
{
|
||||
#ifdef HAVE_GIFLIB
|
||||
if (p->nFrames < 2) return;
|
||||
|
||||
guardDisposed();
|
||||
|
||||
GUARD_MEGA;
|
||||
|
||||
if (p->currentFrame >= p->nFrames)
|
||||
{
|
||||
p->currentFrame = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->currentFrame++;
|
||||
}
|
||||
SDL_Surface *surf = p->gifSurfaces[p->currentFrame];
|
||||
|
||||
replaceRaw(surf->pixels, surf->w, surf->h);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint32_t &getPixelAt(SDL_Surface *surf, SDL_PixelFormat *form, int x, int y)
|
||||
{
|
||||
size_t offset = x*form->BytesPerPixel + y*surf->pitch;
|
||||
|
@ -902,6 +993,7 @@ void Bitmap::replaceRaw(void *pixel_data, int w, int h)
|
|||
TEXFBO::fini(buf);
|
||||
|
||||
taintArea(IntRect(0,0,w,h));
|
||||
p->onModified();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -78,6 +78,8 @@ public:
|
|||
void radialBlur(int angle, int divisions);
|
||||
|
||||
void clear();
|
||||
|
||||
void update();
|
||||
|
||||
Color getPixel(int x, int y) const;
|
||||
void setPixel(int x, int y, const Color &color);
|
||||
|
|
|
@ -974,8 +974,7 @@ void Graphics::screenshot(const char *filename)
|
|||
#ifdef __WIN32__
|
||||
SDL_Surface *img = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, 0,0,0,0);
|
||||
if (!img) throw Exception(Exception::SDLError, "%s", SDL_GetError());
|
||||
|
||||
glReadBuffer(GL_FRONT);
|
||||
|
||||
glReadPixels(0,0,w,h,GL_BGRA,GL_UNSIGNED_BYTE, img->pixels);
|
||||
#else
|
||||
SDL_Surface *tmp, *img;
|
||||
|
@ -988,7 +987,6 @@ void Graphics::screenshot(const char *filename)
|
|||
throw Exception(Exception::SDLError, "%s", SDL_GetError());
|
||||
}
|
||||
|
||||
glReadBuffer(GL_FRONT);
|
||||
glReadPixels(0,0,w,h,GL_BGRA,GL_UNSIGNED_BYTE, tmp->pixels);
|
||||
|
||||
for (int i = 0; i < h; i++)
|
||||
|
|
Loading…
Add table
Reference in a new issue