Refactored BitmapImageSource (moved core functionality into a new class - BitmapImage). Changed BitmapTransitionSource to use BitmapImage - implements #102
parent
6a46761c3c
commit
96e400fd91
|
@ -62,7 +62,8 @@
|
|||
<WindowsSDK80Path Condition="('$(WindowsSDK80Path)'=='')And(!Exists('C:\Program Files (x86)\Windows Kits\8.0\'))">$(WindowsSdkDir)</WindowsSDK80Path>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="MSBuild Dynamic Preprocessor Definitions">
|
||||
<DynamicDefines> </DynamicDefines>
|
||||
<DynamicDefines>
|
||||
</DynamicDefines>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
|
@ -252,6 +253,7 @@
|
|||
<ItemGroup>
|
||||
<ClCompile Include="Source\API.cpp" />
|
||||
<ClCompile Include="Source\BandwidthAnalysis.cpp" />
|
||||
<ClCompile Include="Source\BitmapImage.cpp" />
|
||||
<ClCompile Include="Source\BitmapImageSource.cpp" />
|
||||
<ClCompile Include="Source\BitmapTransitionSource.cpp" />
|
||||
<ClCompile Include="Source\BlankAudioPlayback.cpp" />
|
||||
|
@ -300,6 +302,7 @@
|
|||
<ClCompile Include="Source\WindowStuff.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Source\BitmapImage.h" />
|
||||
<ClInclude Include="Source\CodeTokenizer.h" />
|
||||
<ClInclude Include="Source\CrashDumpHandler.h" />
|
||||
<ClInclude Include="Source\D3D10System.h" />
|
||||
|
|
|
@ -145,6 +145,9 @@
|
|||
<ClCompile Include="Source\Encoder_NVENC.cpp">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Source\BitmapImage.cpp">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Source\D3D10System.h">
|
||||
|
@ -186,6 +189,9 @@
|
|||
<ClInclude Include="Source\Settings.h">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Source\BitmapImage.h">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="cursor1.cur">
|
||||
|
|
|
@ -0,0 +1,284 @@
|
|||
#include "BitmapImage.h"
|
||||
|
||||
void *BI_def_bitmap_create(int width, int height) {return Allocate(width * height * 4);}
|
||||
void BI_def_bitmap_set_opaque(void *bitmap, BOOL opaque) {}
|
||||
BOOL BI_def_bitmap_test_opaque(void *bitmap) {return false;}
|
||||
unsigned char *BI_def_bitmap_get_buffer(void *bitmap) {return (unsigned char*)bitmap;}
|
||||
void BI_def_bitmap_destroy(void *bitmap) {Free(bitmap);}
|
||||
void BI_def_bitmap_modified(void *bitmap) {}
|
||||
|
||||
|
||||
BitmapImage::BitmapImage()
|
||||
{
|
||||
bitmap_callbacks.bitmap_create = BI_def_bitmap_create;
|
||||
bitmap_callbacks.bitmap_destroy = BI_def_bitmap_destroy;
|
||||
bitmap_callbacks.bitmap_get_buffer = BI_def_bitmap_get_buffer;
|
||||
bitmap_callbacks.bitmap_modified = BI_def_bitmap_modified;
|
||||
bitmap_callbacks.bitmap_set_opaque = BI_def_bitmap_set_opaque;
|
||||
bitmap_callbacks.bitmap_test_opaque = BI_def_bitmap_test_opaque;
|
||||
}
|
||||
|
||||
BitmapImage::~BitmapImage()
|
||||
{
|
||||
if(bIsAnimatedGif)
|
||||
{
|
||||
gif_finalise(&gif);
|
||||
Free(animationFrameCache);
|
||||
Free(animationFrameData);
|
||||
}
|
||||
|
||||
if(lpGifData)
|
||||
Free(lpGifData);
|
||||
|
||||
EnableFileMonitor(false);
|
||||
|
||||
delete texture;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void BitmapImage::CreateErrorTexture(void)
|
||||
{
|
||||
LPBYTE textureData = (LPBYTE)Allocate(32*32*4);
|
||||
msetd(textureData, 0xFF0000FF, 32*32*4);
|
||||
|
||||
texture = CreateTexture(32, 32, GS_RGB, textureData, FALSE);
|
||||
fullSize.Set(32.0f, 32.0f);
|
||||
|
||||
Free(textureData);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void BitmapImage::SetPath(String path)
|
||||
{
|
||||
filePath = path;
|
||||
}
|
||||
|
||||
void BitmapImage::EnableFileMonitor(bool bMonitor)
|
||||
{
|
||||
if (changeMonitor)
|
||||
{
|
||||
OSMonitorFileDestroy(changeMonitor);
|
||||
changeMonitor = NULL;
|
||||
}
|
||||
|
||||
if (bMonitor)
|
||||
changeMonitor = OSMonitorFileStart(filePath);
|
||||
}
|
||||
|
||||
void BitmapImage::Init(void)
|
||||
{
|
||||
if(bIsAnimatedGif)
|
||||
{
|
||||
bIsAnimatedGif = false;
|
||||
gif_finalise(&gif);
|
||||
|
||||
Free(animationFrameCache);
|
||||
animationFrameCache = NULL;
|
||||
Free(animationFrameData);
|
||||
animationFrameData = NULL;
|
||||
}
|
||||
|
||||
if(lpGifData)
|
||||
{
|
||||
Free(lpGifData);
|
||||
lpGifData = NULL;
|
||||
}
|
||||
|
||||
animationTimes.Clear();
|
||||
|
||||
delete texture;
|
||||
texture = NULL;
|
||||
|
||||
CTSTR lpBitmap = filePath;
|
||||
if(!lpBitmap || !*lpBitmap)
|
||||
{
|
||||
AppWarning(TEXT("BitmapImage::Init: Empty path"));
|
||||
CreateErrorTexture();
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
|
||||
if(GetPathExtension(lpBitmap).CompareI(TEXT("gif")))
|
||||
{
|
||||
bool bFail = false;
|
||||
|
||||
gif_create(&gif, &bitmap_callbacks);
|
||||
|
||||
XFile gifFile;
|
||||
if(!gifFile.Open(lpBitmap, XFILE_READ, XFILE_OPENEXISTING))
|
||||
{
|
||||
AppWarning(TEXT("BitmapImage::Init: could not open gif file '%s'"), lpBitmap);
|
||||
CreateErrorTexture();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
DWORD fileSize = (DWORD)gifFile.GetFileSize();
|
||||
lpGifData = (LPBYTE)Allocate(fileSize);
|
||||
gifFile.Read(lpGifData, fileSize);
|
||||
|
||||
gif_result result;
|
||||
do
|
||||
{
|
||||
result = gif_initialise(&gif, fileSize, lpGifData);
|
||||
if(result != GIF_OK && result != GIF_WORKING)
|
||||
{
|
||||
bFail = true;
|
||||
break;
|
||||
}
|
||||
}while(result != GIF_OK);
|
||||
|
||||
if(gif.frame_count > 1)
|
||||
{
|
||||
if(result == GIF_OK || result == GIF_WORKING)
|
||||
bIsAnimatedGif = true;
|
||||
}
|
||||
|
||||
if(bIsAnimatedGif)
|
||||
{
|
||||
gif_decode_frame(&gif, 0);
|
||||
texture = CreateTexture(gif.width, gif.height, GS_RGBA, gif.frame_image, FALSE, FALSE);
|
||||
|
||||
animationFrameCache = (BYTE **)Allocate(gif.frame_count * sizeof(BYTE *));
|
||||
memset(animationFrameCache, 0, gif.frame_count * sizeof(BYTE *));
|
||||
|
||||
animationFrameData = (BYTE *)Allocate(gif.frame_count * gif.width * gif.height * 4);
|
||||
memset(animationFrameData, 0, gif.frame_count * gif.width * gif.height * 4);
|
||||
|
||||
for(UINT i=0; i<gif.frame_count; i++)
|
||||
{
|
||||
float frameTime = float(gif.frames[i].frame_delay)*0.01f;
|
||||
if (frameTime == 0.0f)
|
||||
frameTime = 0.1f;
|
||||
animationTimes << frameTime;
|
||||
|
||||
if (gif_decode_frame(&gif, i) != GIF_OK)
|
||||
Log (TEXT("BitmapImage: Warning, couldn't decode frame %d of %s"), i, lpBitmap);
|
||||
}
|
||||
|
||||
gif_decode_frame(&gif, 0);
|
||||
|
||||
fullSize.x = float(gif.width);
|
||||
fullSize.y = float(gif.height);
|
||||
|
||||
curTime = 0.0f;
|
||||
curFrame = 0;
|
||||
lastDecodedFrame = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gif_finalise(&gif);
|
||||
Free(lpGifData);
|
||||
lpGifData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(!bIsAnimatedGif)
|
||||
{
|
||||
texture = GS->CreateTextureFromFile(lpBitmap, TRUE);
|
||||
if(!texture)
|
||||
{
|
||||
AppWarning(TEXT("BitmapImage::Init: could not create texture '%s'"), lpBitmap);
|
||||
CreateErrorTexture();
|
||||
return;
|
||||
}
|
||||
|
||||
fullSize.x = float(texture->Width());
|
||||
fullSize.y = float(texture->Height());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Vect2 BitmapImage::GetSize(void) const
|
||||
{
|
||||
return fullSize;
|
||||
}
|
||||
|
||||
Texture* BitmapImage::GetTexture(void) const
|
||||
{
|
||||
return texture;
|
||||
}
|
||||
|
||||
void BitmapImage::Tick(float fSeconds)
|
||||
{
|
||||
if(bIsAnimatedGif)
|
||||
{
|
||||
UINT totalLoops = (UINT)gif.loop_count;
|
||||
if(totalLoops >= 0xFFFF)
|
||||
totalLoops = 0;
|
||||
|
||||
if(!totalLoops || curLoop < totalLoops)
|
||||
{
|
||||
UINT newFrame = curFrame;
|
||||
|
||||
curTime += fSeconds;
|
||||
while(curTime > animationTimes[newFrame])
|
||||
{
|
||||
curTime -= animationTimes[newFrame];
|
||||
if(++newFrame == animationTimes.Num())
|
||||
{
|
||||
if(!totalLoops || ++curLoop < totalLoops)
|
||||
newFrame = 0;
|
||||
else if (curLoop == totalLoops)
|
||||
{
|
||||
newFrame--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(newFrame != curFrame)
|
||||
{
|
||||
UINT lastFrame;
|
||||
|
||||
if (!animationFrameCache[newFrame])
|
||||
{
|
||||
//animation might have looped, if so make sure we decode from frame 0
|
||||
if (newFrame < lastDecodedFrame)
|
||||
lastFrame = 0;
|
||||
else
|
||||
lastFrame = lastDecodedFrame + 1;
|
||||
|
||||
//we need to decode any frames we missed for consistency
|
||||
for (UINT i = lastFrame; i < newFrame; i++)
|
||||
{
|
||||
if (gif_decode_frame(&gif, i) != GIF_OK)
|
||||
return;
|
||||
}
|
||||
|
||||
//now decode and display the actual frame we want
|
||||
int ret = gif_decode_frame(&gif, newFrame);
|
||||
if (ret == GIF_OK)
|
||||
{
|
||||
animationFrameCache[newFrame] = animationFrameData + (newFrame * (gif.width * gif.height * 4));
|
||||
memcpy(animationFrameCache[newFrame], gif.frame_image, gif.width * gif.height * 4);
|
||||
}
|
||||
|
||||
lastDecodedFrame = newFrame;
|
||||
}
|
||||
|
||||
if (animationFrameCache[newFrame])
|
||||
texture->SetImage(animationFrameCache[newFrame], GS_IMAGEFORMAT_RGBA, gif.width*4);
|
||||
|
||||
curFrame = newFrame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (updateImageTime)
|
||||
{
|
||||
updateImageTime -= fSeconds;
|
||||
if (updateImageTime <= 0.0f)
|
||||
{
|
||||
updateImageTime = 0.0f;
|
||||
Init();
|
||||
}
|
||||
}
|
||||
|
||||
if (changeMonitor && OSFileHasChanged(changeMonitor))
|
||||
updateImageTime = 1.0f;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
|
||||
#include "Main.h"
|
||||
#include "libnsgif.h"
|
||||
|
||||
|
||||
class BitmapImage{
|
||||
Texture *texture;
|
||||
Vect2 fullSize;
|
||||
|
||||
bool bIsAnimatedGif;
|
||||
gif_animation gif;
|
||||
LPBYTE lpGifData;
|
||||
List<float> animationTimes;
|
||||
BYTE **animationFrameCache;
|
||||
BYTE *animationFrameData;
|
||||
UINT curFrame, curLoop, lastDecodedFrame;
|
||||
float curTime;
|
||||
float updateImageTime;
|
||||
|
||||
String filePath;
|
||||
OSFileChangeData *changeMonitor;
|
||||
|
||||
gif_bitmap_callback_vt bitmap_callbacks;
|
||||
|
||||
void CreateErrorTexture(void);
|
||||
|
||||
public:
|
||||
BitmapImage();
|
||||
~BitmapImage();
|
||||
|
||||
void SetPath(String path);
|
||||
void EnableFileMonitor(bool bMonitor);
|
||||
void Init(void);
|
||||
|
||||
Vect2 GetSize(void) const;
|
||||
Texture* GetTexture(void) const;
|
||||
|
||||
void Tick(float fSeconds);
|
||||
};
|
|
@ -18,16 +18,9 @@
|
|||
|
||||
|
||||
#include "Main.h"
|
||||
#include "libnsgif.h"
|
||||
#include "BitmapImage.h"
|
||||
|
||||
|
||||
void *def_bitmap_create(int width, int height) {return Allocate(width * height * 4);}
|
||||
void def_bitmap_set_opaque(void *bitmap, BOOL opaque) {}
|
||||
BOOL def_bitmap_test_opaque(void *bitmap) {return false;}
|
||||
unsigned char *def_bitmap_get_buffer(void *bitmap) {return (unsigned char*)bitmap;}
|
||||
void def_bitmap_destroy(void *bitmap) {Free(bitmap);}
|
||||
void def_bitmap_modified(void *bitmap) {return;}
|
||||
|
||||
struct ColorSelectionData
|
||||
{
|
||||
HDC hdcDesktop;
|
||||
|
@ -121,22 +114,11 @@ struct ConfigDesktopSourceInfo
|
|||
StringList strClasses;
|
||||
};
|
||||
|
||||
gif_bitmap_callback_vt bitmap_callbacks =
|
||||
{
|
||||
def_bitmap_create,
|
||||
def_bitmap_destroy,
|
||||
def_bitmap_get_buffer,
|
||||
def_bitmap_set_opaque,
|
||||
def_bitmap_test_opaque,
|
||||
def_bitmap_modified
|
||||
};
|
||||
|
||||
|
||||
class BitmapImageSource : public ImageSource
|
||||
{
|
||||
Texture *texture;
|
||||
BitmapImage bitmapImage;
|
||||
|
||||
Vect2 fullSize;
|
||||
XElement *data;
|
||||
|
||||
bool bUseColorKey;
|
||||
|
@ -146,35 +128,14 @@ class BitmapImageSource : public ImageSource
|
|||
DWORD opacity;
|
||||
DWORD color;
|
||||
|
||||
bool bIsAnimatedGif;
|
||||
gif_animation gif;
|
||||
LPBYTE lpGifData;
|
||||
List<float> animationTimes;
|
||||
BYTE **animationFrameCache;
|
||||
BYTE *animationFrameData;
|
||||
UINT curFrame, curLoop, lastDecodedFrame;
|
||||
float curTime;
|
||||
float updateImageTime;
|
||||
|
||||
Shader *colorKeyShader, *alphaIgnoreShader;
|
||||
OSFileChangeData *changeMonitor;
|
||||
|
||||
void CreateErrorTexture()
|
||||
{
|
||||
LPBYTE textureData = (LPBYTE)Allocate(32*32*4);
|
||||
msetd(textureData, 0xFF0000FF, 32*32*4);
|
||||
|
||||
texture = CreateTexture(32, 32, GS_RGB, textureData, FALSE);
|
||||
fullSize.Set(32.0f, 32.0f);
|
||||
|
||||
Free(textureData);
|
||||
}
|
||||
|
||||
public:
|
||||
BitmapImageSource(XElement *data)
|
||||
{
|
||||
//EnableMemoryTracking(true);
|
||||
this->data = data;
|
||||
|
||||
UpdateSettings();
|
||||
|
||||
colorKeyShader = CreatePixelShaderFromFile(TEXT("shaders\\ColorKey_RGB.pShader"));
|
||||
|
@ -185,107 +146,19 @@ public:
|
|||
|
||||
~BitmapImageSource()
|
||||
{
|
||||
if(bIsAnimatedGif)
|
||||
{
|
||||
gif_finalise(&gif);
|
||||
Free(animationFrameCache);
|
||||
Free(animationFrameData);
|
||||
}
|
||||
|
||||
if(lpGifData)
|
||||
Free(lpGifData);
|
||||
|
||||
delete colorKeyShader;
|
||||
delete alphaIgnoreShader;
|
||||
|
||||
if (changeMonitor)
|
||||
OSMonitorFileDestroy(changeMonitor);
|
||||
|
||||
delete texture;
|
||||
}
|
||||
|
||||
void Tick(float fSeconds)
|
||||
{
|
||||
if(bIsAnimatedGif)
|
||||
{
|
||||
UINT totalLoops = (UINT)gif.loop_count;
|
||||
if(totalLoops >= 0xFFFF)
|
||||
totalLoops = 0;
|
||||
|
||||
if(!totalLoops || curLoop < totalLoops)
|
||||
{
|
||||
UINT newFrame = curFrame;
|
||||
|
||||
curTime += fSeconds;
|
||||
while(curTime > animationTimes[newFrame])
|
||||
{
|
||||
curTime -= animationTimes[newFrame];
|
||||
if(++newFrame == animationTimes.Num())
|
||||
{
|
||||
if(!totalLoops || ++curLoop < totalLoops)
|
||||
newFrame = 0;
|
||||
else if (curLoop == totalLoops)
|
||||
{
|
||||
newFrame--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(newFrame != curFrame)
|
||||
{
|
||||
UINT lastFrame;
|
||||
|
||||
if (!animationFrameCache[newFrame])
|
||||
{
|
||||
//animation might have looped, if so make sure we decode from frame 0
|
||||
if (newFrame < lastDecodedFrame)
|
||||
lastFrame = 0;
|
||||
else
|
||||
lastFrame = lastDecodedFrame + 1;
|
||||
|
||||
//we need to decode any frames we missed for consistency
|
||||
for (UINT i = lastFrame; i < newFrame; i++)
|
||||
{
|
||||
if (gif_decode_frame(&gif, i) != GIF_OK)
|
||||
return;
|
||||
}
|
||||
|
||||
//now decode and display the actual frame we want
|
||||
int ret = gif_decode_frame(&gif, newFrame);
|
||||
if (ret == GIF_OK)
|
||||
{
|
||||
animationFrameCache[newFrame] = animationFrameData + (newFrame * (gif.width * gif.height * 4));
|
||||
memcpy(animationFrameCache[newFrame], gif.frame_image, gif.width * gif.height * 4);
|
||||
}
|
||||
|
||||
lastDecodedFrame = newFrame;
|
||||
}
|
||||
|
||||
if (animationFrameCache[newFrame])
|
||||
texture->SetImage(animationFrameCache[newFrame], GS_IMAGEFORMAT_RGBA, gif.width*4);
|
||||
|
||||
curFrame = newFrame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (updateImageTime)
|
||||
{
|
||||
updateImageTime -= fSeconds;
|
||||
if (updateImageTime <= 0.0f)
|
||||
{
|
||||
updateImageTime = 0.0f;
|
||||
UpdateSettings();
|
||||
}
|
||||
}
|
||||
|
||||
if (changeMonitor && OSFileHasChanged(changeMonitor))
|
||||
updateImageTime = 1.0f;
|
||||
bitmapImage.Tick(fSeconds);
|
||||
}
|
||||
|
||||
void Render(const Vect2 &pos, const Vect2 &size)
|
||||
{
|
||||
Texture *texture = bitmapImage.GetTexture();
|
||||
|
||||
if(texture)
|
||||
{
|
||||
if(bUseColorKey)
|
||||
|
@ -316,126 +189,9 @@ public:
|
|||
|
||||
void UpdateSettings()
|
||||
{
|
||||
if(bIsAnimatedGif)
|
||||
{
|
||||
bIsAnimatedGif = false;
|
||||
gif_finalise(&gif);
|
||||
|
||||
Free(animationFrameCache);
|
||||
animationFrameCache = NULL;
|
||||
Free(animationFrameData);
|
||||
animationFrameData = NULL;
|
||||
}
|
||||
|
||||
if(lpGifData)
|
||||
{
|
||||
Free(lpGifData);
|
||||
lpGifData = NULL;
|
||||
}
|
||||
|
||||
animationTimes.Clear();
|
||||
|
||||
delete texture;
|
||||
texture = NULL;
|
||||
|
||||
CTSTR lpBitmap = data->GetString(TEXT("path"));
|
||||
if(!lpBitmap || !*lpBitmap)
|
||||
{
|
||||
AppWarning(TEXT("BitmapImageSource::UpdateSettings: Empty path"));
|
||||
CreateErrorTexture();
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
|
||||
if(GetPathExtension(lpBitmap).CompareI(TEXT("gif")))
|
||||
{
|
||||
bool bFail = false;
|
||||
|
||||
gif_create(&gif, &bitmap_callbacks);
|
||||
|
||||
XFile gifFile;
|
||||
if(!gifFile.Open(lpBitmap, XFILE_READ, XFILE_OPENEXISTING))
|
||||
{
|
||||
AppWarning(TEXT("BitmapImageSource::UpdateSettings: could not open gif file '%s'"), lpBitmap);
|
||||
CreateErrorTexture();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
DWORD fileSize = (DWORD)gifFile.GetFileSize();
|
||||
lpGifData = (LPBYTE)Allocate(fileSize);
|
||||
gifFile.Read(lpGifData, fileSize);
|
||||
|
||||
gif_result result;
|
||||
do
|
||||
{
|
||||
result = gif_initialise(&gif, fileSize, lpGifData);
|
||||
if(result != GIF_OK && result != GIF_WORKING)
|
||||
{
|
||||
bFail = true;
|
||||
break;
|
||||
}
|
||||
}while(result != GIF_OK);
|
||||
|
||||
if(gif.frame_count > 1)
|
||||
{
|
||||
if(result == GIF_OK || result == GIF_WORKING)
|
||||
bIsAnimatedGif = true;
|
||||
}
|
||||
|
||||
if(bIsAnimatedGif)
|
||||
{
|
||||
gif_decode_frame(&gif, 0);
|
||||
texture = CreateTexture(gif.width, gif.height, GS_RGBA, gif.frame_image, FALSE, FALSE);
|
||||
|
||||
animationFrameCache = (BYTE **)Allocate(gif.frame_count * sizeof(BYTE *));
|
||||
memset(animationFrameCache, 0, gif.frame_count * sizeof(BYTE *));
|
||||
|
||||
animationFrameData = (BYTE *)Allocate(gif.frame_count * gif.width * gif.height * 4);
|
||||
memset(animationFrameData, 0, gif.frame_count * gif.width * gif.height * 4);
|
||||
|
||||
for(UINT i=0; i<gif.frame_count; i++)
|
||||
{
|
||||
float frameTime = float(gif.frames[i].frame_delay)*0.01f;
|
||||
if (frameTime == 0.0f)
|
||||
frameTime = 0.1f;
|
||||
animationTimes << frameTime;
|
||||
|
||||
if (gif_decode_frame(&gif, i) != GIF_OK)
|
||||
Log (TEXT("BitmapImageSource: Warning, couldn't decode frame %d of %s"), i, data->GetString(TEXT("path")));
|
||||
}
|
||||
|
||||
gif_decode_frame(&gif, 0);
|
||||
|
||||
fullSize.x = float(gif.width);
|
||||
fullSize.y = float(gif.height);
|
||||
|
||||
curTime = 0.0f;
|
||||
curFrame = 0;
|
||||
lastDecodedFrame = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gif_finalise(&gif);
|
||||
Free(lpGifData);
|
||||
lpGifData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(!bIsAnimatedGif)
|
||||
{
|
||||
texture = GS->CreateTextureFromFile(lpBitmap, TRUE);
|
||||
if(!texture)
|
||||
{
|
||||
AppWarning(TEXT("BitmapImageSource::UpdateSettings: could not create texture '%s'"), lpBitmap);
|
||||
CreateErrorTexture();
|
||||
return;
|
||||
}
|
||||
|
||||
fullSize.x = float(texture->Width());
|
||||
fullSize.y = float(texture->Height());
|
||||
}
|
||||
bitmapImage.SetPath(data->GetString(TEXT("path")));
|
||||
bitmapImage.EnableFileMonitor(data->GetInt(TEXT("monitor"), 0) == 1);
|
||||
bitmapImage.Init();
|
||||
|
||||
//------------------------------------
|
||||
|
||||
|
@ -444,16 +200,6 @@ public:
|
|||
if(opacity > 100)
|
||||
opacity = 100;
|
||||
|
||||
if (changeMonitor)
|
||||
{
|
||||
OSMonitorFileDestroy(changeMonitor);
|
||||
changeMonitor = NULL;
|
||||
}
|
||||
|
||||
int monitor = data->GetInt(TEXT("monitor"), 0);
|
||||
if (monitor)
|
||||
changeMonitor = OSMonitorFileStart(lpBitmap);
|
||||
|
||||
bool bNewUseColorKey = data->GetInt(TEXT("useColorKey"), 0) != 0;
|
||||
keyColor = data->GetInt(TEXT("keyColor"), 0xFFFFFFFF);
|
||||
keySimilarity = data->GetInt(TEXT("keySimilarity"), 10);
|
||||
|
@ -462,7 +208,7 @@ public:
|
|||
bUseColorKey = bNewUseColorKey;
|
||||
}
|
||||
|
||||
Vect2 GetSize() const {return fullSize;}
|
||||
Vect2 GetSize() const {return bitmapImage.GetSize();}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "Main.h"
|
||||
#include <time.h>
|
||||
|
||||
#include "BitmapImage.h"
|
||||
|
||||
#define MIN_TRANSITION_TIME 3
|
||||
#define MAX_TRANSITION_TIME 600
|
||||
|
||||
|
@ -29,7 +31,7 @@ extern "C" double round(double val);
|
|||
|
||||
class BitmapTransitionSource : public ImageSource
|
||||
{
|
||||
List<Texture*> textures;
|
||||
List<BitmapImage*> bitmapImages;
|
||||
|
||||
Vect2 fullSize;
|
||||
double baseAspect;
|
||||
|
@ -55,17 +57,6 @@ class BitmapTransitionSource : public ImageSource
|
|||
return int( ( (double)rand() / (RAND_MAX + 1) ) * limit );
|
||||
}
|
||||
|
||||
void CreateErrorTexture()
|
||||
{
|
||||
LPBYTE textureData = (LPBYTE)Allocate(32*32*4);
|
||||
msetd(textureData, 0xFF0000FF, 32*32*4);
|
||||
|
||||
textures << CreateTexture(32, 32, GS_RGB, textureData, FALSE);
|
||||
fullSize.Set(32.0f, 32.0f);
|
||||
|
||||
Free(textureData);
|
||||
}
|
||||
|
||||
public:
|
||||
BitmapTransitionSource(XElement *data)
|
||||
{
|
||||
|
@ -76,13 +67,16 @@ public:
|
|||
|
||||
~BitmapTransitionSource()
|
||||
{
|
||||
for(UINT i=0; i<textures.Num(); i++)
|
||||
delete textures[i];
|
||||
for(UINT i=0; i<bitmapImages.Num(); i++)
|
||||
delete bitmapImages[i];
|
||||
}
|
||||
|
||||
void Tick(float fSeconds)
|
||||
{
|
||||
if(bTransitioning && textures.Num() > 1)
|
||||
for(UINT i=0; i<bitmapImages.Num(); i++)
|
||||
bitmapImages[i]->Tick(fSeconds);
|
||||
|
||||
if(bTransitioning && bitmapImages.Num() > 1)
|
||||
{
|
||||
if(bDisableFading)
|
||||
curFadeValue = fadeTime;
|
||||
|
@ -97,14 +91,14 @@ public:
|
|||
if(bRandomize)
|
||||
{
|
||||
curTexture = nextTexture;
|
||||
while((nextTexture = lrand(textures.Num())) == curTexture);
|
||||
while((nextTexture = lrand(bitmapImages.Num())) == curTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(++curTexture == textures.Num())
|
||||
if(++curTexture == bitmapImages.Num())
|
||||
curTexture = 0;
|
||||
|
||||
nextTexture = (curTexture == textures.Num()-1) ? 0 : curTexture+1;
|
||||
nextTexture = (curTexture == bitmapImages.Num()-1) ? 0 : curTexture+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +120,7 @@ public:
|
|||
Vect2 pos = Vect2(0.0f, 0.0f);
|
||||
Vect2 size = fullSize;
|
||||
|
||||
Vect2 itemSize = Vect2((float)textures[texID]->Width(), (float)textures[texID]->Height());
|
||||
Vect2 itemSize = bitmapImages[texID]->GetSize();
|
||||
|
||||
double sourceAspect = double(itemSize.x)/double(itemSize.y);
|
||||
if(!CloseDouble(baseAspect, sourceAspect))
|
||||
|
@ -151,14 +145,14 @@ public:
|
|||
Vect2 lr;
|
||||
lr = pos + (size/fullSize*startSize);
|
||||
|
||||
DrawSprite(textures[texID], (curAlpha<<24) | 0xFFFFFF, pos.x, pos.y, lr.x, lr.y);
|
||||
DrawSprite(bitmapImages[texID]->GetTexture(), (curAlpha<<24) | 0xFFFFFF, pos.x, pos.y, lr.x, lr.y);
|
||||
}
|
||||
|
||||
void Render(const Vect2 &pos, const Vect2 &size)
|
||||
{
|
||||
if(textures.Num())
|
||||
if(bitmapImages.Num())
|
||||
{
|
||||
if(bTransitioning && textures.Num() > 1)
|
||||
if(bTransitioning && bitmapImages.Num() > 1)
|
||||
{
|
||||
float curAlpha = MIN(curFadeValue/fadeTime, 1.0f);
|
||||
if(bFadeInOnly)
|
||||
|
@ -175,9 +169,9 @@ public:
|
|||
|
||||
void UpdateSettings()
|
||||
{
|
||||
for(UINT i=0; i<textures.Num(); i++)
|
||||
delete textures[i];
|
||||
textures.Clear();
|
||||
for(UINT i=0; i<bitmapImages.Num(); i++)
|
||||
delete bitmapImages[i];
|
||||
bitmapImages.Clear();
|
||||
|
||||
//------------------------------------
|
||||
|
||||
|
@ -194,27 +188,21 @@ public:
|
|||
continue;
|
||||
}
|
||||
|
||||
Texture *texture = GS->CreateTextureFromFile(strBitmap, TRUE);
|
||||
if(!texture)
|
||||
{
|
||||
AppWarning(TEXT("BitmapTransitionSource::UpdateSettings: could not create texture '%s'"), strBitmap.Array());
|
||||
continue;
|
||||
}
|
||||
BitmapImage *bitmapImage = new BitmapImage;
|
||||
bitmapImage->SetPath(strBitmap);
|
||||
bitmapImage->EnableFileMonitor(false);
|
||||
bitmapImage->Init();
|
||||
|
||||
if(bFirst)
|
||||
{
|
||||
fullSize.x = float(texture->Width());
|
||||
fullSize.y = float(texture->Height());
|
||||
fullSize = bitmapImage->GetSize();
|
||||
baseAspect = double(fullSize.x)/double(fullSize.y);
|
||||
bFirst = false;
|
||||
}
|
||||
|
||||
textures << texture;
|
||||
bitmapImages << bitmapImage;
|
||||
}
|
||||
|
||||
if(textures.Num() == 0)
|
||||
CreateErrorTexture();
|
||||
|
||||
//------------------------------------
|
||||
|
||||
transitionTime = data->GetFloat(TEXT("transitionTime"));
|
||||
|
@ -237,14 +225,14 @@ public:
|
|||
if(bRandomize)
|
||||
{
|
||||
srand( (unsigned)time( NULL ) );
|
||||
if(textures.Num() > 1)
|
||||
if(bitmapImages.Num() > 1)
|
||||
{
|
||||
curTexture = lrand(textures.Num());
|
||||
while((nextTexture = lrand(textures.Num())) == curTexture);
|
||||
curTexture = lrand(bitmapImages.Num());
|
||||
while((nextTexture = lrand(bitmapImages.Num())) == curTexture);
|
||||
}
|
||||
}
|
||||
else
|
||||
nextTexture = (curTexture == textures.Num()-1) ? 0 : curTexture+1;
|
||||
nextTexture = (curTexture == bitmapImages.Num()-1) ? 0 : curTexture+1;
|
||||
|
||||
bTransitioning = false;
|
||||
curFadeValue = 0.0f;
|
||||
|
|
Loading…
Reference in New Issue