mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-12-25 16:37:42 +01:00
avoid memory leak at sound play
Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
This commit is contained in:
parent
1f85d633c4
commit
0733b704ff
@ -3739,8 +3739,8 @@ XTheme::GetThemeTagSettings (void* DictP)
|
|||||||
#if XCINEMA
|
#if XCINEMA
|
||||||
Dict = GetProperty (DictPointer, "Anime");
|
Dict = GetProperty (DictPointer, "Anime");
|
||||||
if (Dict != NULL) {
|
if (Dict != NULL) {
|
||||||
INTN i, Count = GetTagCount (Dict);
|
INTN Count = GetTagCount (Dict);
|
||||||
for (i = 0; i < Count; i++) {
|
for (INTN i = 0; i < Count; i++) {
|
||||||
FILM *NewFilm = new FILM();
|
FILM *NewFilm = new FILM();
|
||||||
if (EFI_ERROR (GetElement (Dict, i, &Dict3))) {
|
if (EFI_ERROR (GetElement (Dict, i, &Dict3))) {
|
||||||
continue;
|
continue;
|
||||||
@ -3797,10 +3797,13 @@ XTheme::GetThemeTagSettings (void* DictP)
|
|||||||
Dict2 = GetProperty (Dict3, "Once");
|
Dict2 = GetProperty (Dict3, "Once");
|
||||||
NewFilm->RunOnce = IsPropertyTrue (Dict2);
|
NewFilm->RunOnce = IsPropertyTrue (Dict2);
|
||||||
|
|
||||||
|
NewFilm->GetFrames(ThemeX); //used properties: ID, Path, NumFrames
|
||||||
ThemeX.Cinema.AddFilm(NewFilm);
|
ThemeX.Cinema.AddFilm(NewFilm);
|
||||||
// delete NewFilm; //looks like already deleted
|
// delete NewFilm; //looks like already deleted
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
Dict = GetProperty (DictPointer, "Anime");
|
Dict = GetProperty (DictPointer, "Anime");
|
||||||
@ -4165,7 +4168,7 @@ finish:
|
|||||||
Status = StartupSoundPlay(ThemeX.ThemeDir, NULL);
|
Status = StartupSoundPlay(ThemeX.ThemeDir, NULL);
|
||||||
} else { // theme loaded successfully
|
} else { // theme loaded successfully
|
||||||
ThemeX.embedded = false;
|
ThemeX.embedded = false;
|
||||||
ThemeX.Theme.takeValueFrom(GlobalConfig.Theme);
|
ThemeX.Theme.takeValueFrom(GlobalConfig.Theme); //XStringW from CHAR16*)
|
||||||
// read theme settings
|
// read theme settings
|
||||||
if (!ThemeX.TypeSVG) {
|
if (!ThemeX.TypeSVG) {
|
||||||
TagPtr DictPointer = GetProperty(ThemeDict, "Theme");
|
TagPtr DictPointer = GetProperty(ThemeDict, "Theme");
|
||||||
|
@ -69,25 +69,34 @@ StartupSoundPlay(EFI_FILE *Dir, CONST CHAR16* SoundFile)
|
|||||||
UINT8 OutputIndex = (OldChosenAudio & 0xFF);
|
UINT8 OutputIndex = (OldChosenAudio & 0xFF);
|
||||||
UINT8 OutputVolume = DefaultAudioVolume;
|
UINT8 OutputVolume = DefaultAudioVolume;
|
||||||
UINT16 *TempData = NULL;
|
UINT16 *TempData = NULL;
|
||||||
|
BOOLEAN AllocAsPage = FALSE;
|
||||||
|
|
||||||
|
if (!AudioIo) {
|
||||||
|
Status = EFI_DEVICE_ERROR;
|
||||||
|
// DBG("not found AudioIo to play\n");
|
||||||
|
goto DONE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (SoundFile) {
|
if (SoundFile) {
|
||||||
Status = egLoadFile(Dir, SoundFile, &FileData, &FileDataLength);
|
Status = egLoadFile(Dir, SoundFile, &FileData, &FileDataLength);
|
||||||
if (EFI_ERROR(Status)) {
|
if (EFI_ERROR(Status)) {
|
||||||
DBG("file sound read: %ls %s\n", SoundFile, strerror(Status));
|
// DBG("file sound read: %ls %s\n", SoundFile, strerror(Status));
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
FileData = EmbeddedSound;
|
FileData = EmbeddedSound;
|
||||||
FileDataLength = EmbeddedSoundLength;
|
FileDataLength = EmbeddedSoundLength;
|
||||||
DBG("got embedded sound\n");
|
// DBG("got embedded sound\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
WaveData.Samples = NULL;
|
WaveData.Samples = NULL;
|
||||||
Status = WaveGetFileData(FileData, (UINT32)FileDataLength, &WaveData);
|
Status = WaveGetFileData(FileData, (UINT32)FileDataLength, &WaveData); //
|
||||||
if (EFI_ERROR(Status)) {
|
if (EFI_ERROR(Status)) {
|
||||||
MsgLog(" wrong sound file, wave status=%s\n", strerror(Status));
|
MsgLog(" wrong sound file, wave status=%s\n", strerror(Status));
|
||||||
|
//if error then data not allocated
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
AllocAsPage = TRUE;
|
||||||
MsgLog(" Channels: %u Sample rate: %u Hz Bits: %u\n", WaveData.Format->Channels, WaveData.Format->SamplesPerSec, WaveData.Format->BitsPerSample);
|
MsgLog(" Channels: %u Sample rate: %u Hz Bits: %u\n", WaveData.Format->Channels, WaveData.Format->SamplesPerSec, WaveData.Format->BitsPerSample);
|
||||||
|
|
||||||
EFI_AUDIO_IO_PROTOCOL_BITS bits;
|
EFI_AUDIO_IO_PROTOCOL_BITS bits;
|
||||||
@ -108,7 +117,7 @@ StartupSoundPlay(EFI_FILE *Dir, CONST CHAR16* SoundFile)
|
|||||||
bits = EfiAudioIoBits32;
|
bits = EfiAudioIoBits32;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return EFI_UNSUPPORTED;
|
goto DONE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
EFI_AUDIO_IO_PROTOCOL_FREQ freq;
|
EFI_AUDIO_IO_PROTOCOL_FREQ freq;
|
||||||
@ -144,14 +153,14 @@ StartupSoundPlay(EFI_FILE *Dir, CONST CHAR16* SoundFile)
|
|||||||
freq = EfiAudioIoFreq192kHz;
|
freq = EfiAudioIoFreq192kHz;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return EFI_UNSUPPORTED;
|
goto DONE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG("output to channel %d with volume %d, len=%d\n", OutputIndex, OutputVolume, WaveData.SamplesLength);
|
DBG("output to channel %d with volume %d, len=%d\n", OutputIndex, OutputVolume, WaveData.SamplesLength);
|
||||||
DBG(" sound channels=%d bits=%d freq=%d\n", WaveData.Format->Channels, WaveData.Format->BitsPerSample, WaveData.Format->SamplesPerSec);
|
DBG(" sound channels=%d bits=%d freq=%d\n", WaveData.Format->Channels, WaveData.Format->BitsPerSample, WaveData.Format->SamplesPerSec);
|
||||||
|
|
||||||
if (!WaveData.SamplesLength || !OutputVolume) {
|
if (!WaveData.SamplesLength || !OutputVolume) {
|
||||||
// DBG("nothing to play\n");
|
// DBG("nothing to play\n"); //but data allocated
|
||||||
Status = EFI_NOT_FOUND;
|
Status = EFI_NOT_FOUND;
|
||||||
goto DONE_ERROR;
|
goto DONE_ERROR;
|
||||||
}
|
}
|
||||||
@ -185,16 +194,11 @@ StartupSoundPlay(EFI_FILE *Dir, CONST CHAR16* SoundFile)
|
|||||||
WaveData.SamplesLength *= 6;
|
WaveData.SamplesLength *= 6;
|
||||||
DBG("sound converted to 48kHz\n");
|
DBG("sound converted to 48kHz\n");
|
||||||
WaveData.Samples = (UINT8*)TempData;
|
WaveData.Samples = (UINT8*)TempData;
|
||||||
|
AllocAsPage = FALSE;
|
||||||
} else {
|
} else {
|
||||||
TempData = (UINT16*)WaveData.Samples;
|
TempData = (UINT16*)WaveData.Samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AudioIo) {
|
|
||||||
Status = EFI_DEVICE_ERROR;
|
|
||||||
// DBG("not found AudioIo to play\n");
|
|
||||||
goto DONE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup playback.
|
// Setup playback.
|
||||||
if (OutputIndex > AudioNum) {
|
if (OutputIndex > AudioNum) {
|
||||||
OutputIndex = 0;
|
OutputIndex = 0;
|
||||||
@ -210,13 +214,13 @@ StartupSoundPlay(EFI_FILE *Dir, CONST CHAR16* SoundFile)
|
|||||||
// Start playback.
|
// Start playback.
|
||||||
if (gSettings.PlayAsync) {
|
if (gSettings.PlayAsync) {
|
||||||
Status = AudioIo->StartPlaybackAsync(AudioIo, (UINT8*)TempData, WaveData.SamplesLength, 0, NULL, NULL);
|
Status = AudioIo->StartPlaybackAsync(AudioIo, (UINT8*)TempData, WaveData.SamplesLength, 0, NULL, NULL);
|
||||||
DBG("async started, status=%s\n", strerror(Status));
|
// DBG("async started, status=%s\n", strerror(Status));
|
||||||
} else {
|
} else {
|
||||||
Status = AudioIo->StartPlayback(AudioIo, (UINT8*)TempData, WaveData.SamplesLength, 0);
|
Status = AudioIo->StartPlayback(AudioIo, (UINT8*)TempData, WaveData.SamplesLength, 0);
|
||||||
// DBG("sync started, status=%s\n", strerror(Status));
|
// DBG("sync started, status=%s\n", strerror(Status));
|
||||||
if (!EFI_ERROR(Status)) {
|
// if (!EFI_ERROR(Status)) {
|
||||||
FreePool(TempData);
|
// FreePool(TempData);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EFI_ERROR(Status)) {
|
if (EFI_ERROR(Status)) {
|
||||||
@ -224,10 +228,20 @@ StartupSoundPlay(EFI_FILE *Dir, CONST CHAR16* SoundFile)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DONE_ERROR:
|
DONE_ERROR:
|
||||||
|
// here we have memory leak with TempData == WaveData.Samples
|
||||||
|
// TempData allocated as AllocatePool while Samples allocated as AllocatePages
|
||||||
|
// and we can't keep the info up to stop AsyncPlay
|
||||||
if (FileData && SoundFile) { //dont free embedded sound
|
if (FileData && SoundFile) { //dont free embedded sound
|
||||||
// DBG("free sound\n");
|
// DBG("free sound\n");
|
||||||
FreePool(FileData);
|
FreePool(FileData);
|
||||||
}
|
}
|
||||||
|
if (!gSettings.PlayAsync) { //dont free sound when async play
|
||||||
|
if (AllocAsPage) {
|
||||||
|
FreePages(WaveData.Samples,EFI_SIZE_TO_PAGES(WaveData.SamplesLength+4095));
|
||||||
|
} else {
|
||||||
|
FreePool(TempData);
|
||||||
|
}
|
||||||
|
}
|
||||||
DBG("sound play end with status=%s\n", strerror(Status));
|
DBG("sound play end with status=%s\n", strerror(Status));
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -11,17 +11,20 @@
|
|||||||
#include "XCinema.h"
|
#include "XCinema.h"
|
||||||
#include "../gui/REFIT_MENU_SCREEN.h"
|
#include "../gui/REFIT_MENU_SCREEN.h"
|
||||||
|
|
||||||
|
#ifndef DEBUG_ALL
|
||||||
|
#define DEBUG_CINEMA 1
|
||||||
|
#else
|
||||||
|
#define DEBUG_CINEMA DEBUG_ALL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DEBUG_CINEMA == 0
|
||||||
|
#define DBG(...)
|
||||||
|
#else
|
||||||
|
#define DBG(...) DebugLog(DEBUG_CINEMA, __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//Screen.UpdateAnime(); called from Menu cycle wait for event
|
//Screen.UpdateAnime(); called from Menu cycle wait for event
|
||||||
//Now = AsmReadTsc();
|
|
||||||
//if (TimeDiff(LastDraw, Now) < FrameTime) return;
|
|
||||||
//if (Film[CurrentFrame]) { Draw }
|
|
||||||
// else skip draw
|
|
||||||
// CurrentFrame++;
|
|
||||||
//if (CurrentFrame >= Frames) {
|
|
||||||
// AnimeRun = !Once;
|
|
||||||
// CurrentFrame = 0;
|
|
||||||
//}
|
|
||||||
//LastDraw = Now;
|
|
||||||
|
|
||||||
// object XCinema::Cinema is a part of Theme
|
// object XCinema::Cinema is a part of Theme
|
||||||
// object FILM::FilmX is a part or current Screen. Must be initialized from Cinema somewhere on Screen init
|
// object FILM::FilmX is a part or current Screen. Must be initialized from Cinema somewhere on Screen init
|
||||||
@ -51,7 +54,9 @@ VOID REFIT_MENU_SCREEN::UpdateFilm()
|
|||||||
#endif
|
#endif
|
||||||
FILM* XCinema::GetFilm(INTN Id)
|
FILM* XCinema::GetFilm(INTN Id)
|
||||||
{
|
{
|
||||||
|
DBG("ask film %lld\n", Id);
|
||||||
for (size_t i = 0; i < Cinema.size(); ++i) {
|
for (size_t i = 0; i < Cinema.size(); ++i) {
|
||||||
|
DBG("check film %lld\n", Cinema[i].GetIndex());
|
||||||
if (Cinema[i].GetIndex() == Id) {
|
if (Cinema[i].GetIndex() == Id) {
|
||||||
return &Cinema[i];
|
return &Cinema[i];
|
||||||
}
|
}
|
||||||
@ -67,8 +72,10 @@ void XCinema::AddFilm(FILM* NewFilm)
|
|||||||
static XImage NullImage;
|
static XImage NullImage;
|
||||||
const XImage& FILM::GetImage(INTN Index) const
|
const XImage& FILM::GetImage(INTN Index) const
|
||||||
{
|
{
|
||||||
|
DBG("ask for frame #%lld\n", Index);
|
||||||
for (size_t i = 0; i < Frames.size(); ++i) {
|
for (size_t i = 0; i < Frames.size(); ++i) {
|
||||||
if (Frames[i].getIndex() == Index) {
|
if (Frames[i].getIndex() == Index) {
|
||||||
|
DBG("...found\n");
|
||||||
return Frames[i].getImage();
|
return Frames[i].getImage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,7 +92,6 @@ const XImage& FILM::GetImage() const
|
|||||||
return NullImage;
|
return NullImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FILM::AddFrame(XImage* Frame, INTN Index)
|
void FILM::AddFrame(XImage* Frame, INTN Index)
|
||||||
{
|
{
|
||||||
IndexedImage* NewFrame = new IndexedImage(Index);
|
IndexedImage* NewFrame = new IndexedImage(Index);
|
||||||
@ -107,9 +113,11 @@ void FILM::GetFrames(XTheme& TheTheme /*, const XStringW& Path*/) // Path alread
|
|||||||
Status = TheTheme.LoadSvgFrame(Index, &NewImage);
|
Status = TheTheme.LoadSvgFrame(Index, &NewImage);
|
||||||
} else {
|
} else {
|
||||||
XStringW Name = SWPrintf("%ls\\%ls_%03lld.png", Path.wc_str(), Path.wc_str(), Index);
|
XStringW Name = SWPrintf("%ls\\%ls_%03lld.png", Path.wc_str(), Path.wc_str(), Index);
|
||||||
|
// DBG("try to load %ls\n", Name.wc_str()); //fine
|
||||||
if (FileExists(ThemeDir, Name.wc_str())) {
|
if (FileExists(ThemeDir, Name.wc_str())) {
|
||||||
Status = NewImage.LoadXImage(ThemeDir, Name);
|
Status = NewImage.LoadXImage(ThemeDir, Name);
|
||||||
}
|
}
|
||||||
|
// DBG(" read status=%s\n", strerror(Status));
|
||||||
}
|
}
|
||||||
if (!EFI_ERROR(Status)) {
|
if (!EFI_ERROR(Status)) {
|
||||||
AddFrame(&NewImage, Index);
|
AddFrame(&NewImage, Index);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include "../refit/menu.h"
|
#include "../refit/menu.h"
|
||||||
|
|
||||||
#ifndef DEBUG_ALL
|
#ifndef DEBUG_ALL
|
||||||
#define DEBUG_MOUSE 1
|
#define DEBUG_MOUSE 0
|
||||||
#else
|
#else
|
||||||
#define DEBUG_MOUSE DEBUG_ALL
|
#define DEBUG_MOUSE DEBUG_ALL
|
||||||
#endif
|
#endif
|
||||||
|
@ -2861,7 +2861,7 @@ static void nsvg__parseText(NSVGparser* p, const char** dict)
|
|||||||
fontChain = fontChain->next;
|
fontChain = fontChain->next;
|
||||||
}
|
}
|
||||||
if (!fontChain && fontChainSimilar) { //font with this style is not found but we have same font with other style
|
if (!fontChain && fontChainSimilar) { //font with this style is not found but we have same font with other style
|
||||||
DBG("found similar font with style=%c\n", fontChainSimilar->font->fontStyle);
|
// DBG("found similar font with style=%c\n", fontChainSimilar->font->fontStyle);
|
||||||
fontChain = fontChainSimilar;
|
fontChain = fontChainSimilar;
|
||||||
fontSVG = fontChain->font;
|
fontSVG = fontChain->font;
|
||||||
}
|
}
|
||||||
@ -2871,13 +2871,11 @@ static void nsvg__parseText(NSVGparser* p, const char** dict)
|
|||||||
UINTN FileDataLength = 0;
|
UINTN FileDataLength = 0;
|
||||||
NSVGparser *p1 = NULL;
|
NSVGparser *p1 = NULL;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
DBG("required font %s not found, try to load external\n", text->fontFace->fontFamily);
|
// DBG("required font %s not found, try to load external\n", text->fontFace->fontFamily);
|
||||||
// CONST CHAR16 *FontFileName = PoolPrint(L"%a.svg", text->fontFace->fontFamily);
|
|
||||||
XStringW FontFileName = XStringW().takeValueFrom(text->fontFace->fontFamily) + L".svg"_XSW;
|
XStringW FontFileName = XStringW().takeValueFrom(text->fontFace->fontFamily) + L".svg"_XSW;
|
||||||
DBG(" file name =%ls\n", FontFileName.wc_str());
|
// DBG(" file name =%ls\n", FontFileName.wc_str());
|
||||||
Status = egLoadFile(ThemeX.ThemeDir, FontFileName.wc_str(), &FileData, &FileDataLength);
|
Status = egLoadFile(ThemeX.ThemeDir, FontFileName.wc_str(), &FileData, &FileDataLength);
|
||||||
// FreePool(FontFileName);
|
// DBG(" font %s loaded status=%lld, %s\n", text->fontFace->fontFamily, Status, strerror(Status));
|
||||||
DBG(" font %s loaded status=%lld, %s\n", text->fontFace->fontFamily, Status, strerror(Status));
|
|
||||||
if (!EFI_ERROR(Status)) {
|
if (!EFI_ERROR(Status)) {
|
||||||
p1 = nsvgParse((CHAR8*)FileData, 72, 1.0f); //later we will free parser p1
|
p1 = nsvgParse((CHAR8*)FileData, 72, 1.0f); //later we will free parser p1
|
||||||
if (!p1) {
|
if (!p1) {
|
||||||
@ -2923,7 +2921,7 @@ static void nsvg__parseText(NSVGparser* p, const char** dict)
|
|||||||
textFace[1].size = (INTN)text->fontSize;
|
textFace[1].size = (INTN)text->fontSize;
|
||||||
textFace[1].color = text->fontColor;
|
textFace[1].color = text->fontColor;
|
||||||
textFace[1].valid = TRUE;
|
textFace[1].valid = TRUE;
|
||||||
DBG("set message->font=%s color=%X size=%f as in MessageRow\n", fontSVG->fontFamily, text->fontColor, text->fontSize);
|
DBG("set message_night->font=%s color=%X size=%f as in MessageRow\n", fontSVG->fontFamily, text->fontColor, text->fontSize);
|
||||||
break;
|
break;
|
||||||
} else if (strcmp(group->id, "MenuRows") == 0) {
|
} else if (strcmp(group->id, "MenuRows") == 0) {
|
||||||
if (!textFace[2].valid) {
|
if (!textFace[2].valid) {
|
||||||
@ -2954,15 +2952,12 @@ static void nsvg__parseText(NSVGparser* p, const char** dict)
|
|||||||
textFace[0].size = (INTN)text->fontSize;
|
textFace[0].size = (INTN)text->fontSize;
|
||||||
textFace[0].color = text->fontColor;
|
textFace[0].color = text->fontColor;
|
||||||
textFace[0].valid = TRUE;
|
textFace[0].valid = TRUE;
|
||||||
DBG("set help->font=%s color=%X size=%f as in HelpRows\n", fontSVG->fontFamily, text->fontColor, text->fontSize);
|
DBG("set help_night->font=%s color=%X size=%f as in HelpRows\n", fontSVG->fontFamily, text->fontColor, text->fontSize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
group = group->next;
|
group = group->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if ((!text->font || !text->font->glyphs) && fontsDB) {
|
|
||||||
// text->font = fontsDB->font; //first found
|
|
||||||
// }
|
|
||||||
|
|
||||||
//add to head
|
//add to head
|
||||||
text->next = p->text;
|
text->next = p->text;
|
||||||
|
@ -482,11 +482,13 @@ INTN HybridRepositioning(INTN Edge, INTN Value, INTN ImageDimension, INTN Screen
|
|||||||
BOOLEAN REFIT_MENU_SCREEN::GetAnime()
|
BOOLEAN REFIT_MENU_SCREEN::GetAnime()
|
||||||
{
|
{
|
||||||
FilmC = ThemeX.Cinema.GetFilm(ID);
|
FilmC = ThemeX.Cinema.GetFilm(ID);
|
||||||
|
DBG("ScreenID=%lld Film found=%d\n", ID, (FilmC != nullptr)?1:0);
|
||||||
return FilmC != nullptr;
|
return FilmC != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID REFIT_MENU_SCREEN::InitAnime()
|
VOID REFIT_MENU_SCREEN::InitAnime()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (FilmC && (FilmC->FilmX >=0) && (FilmC->FilmX <=100) &&
|
if (FilmC && (FilmC->FilmX >=0) && (FilmC->FilmX <=100) &&
|
||||||
(FilmC->FilmY >=0) && (FilmC->FilmY <=100)) {
|
(FilmC->FilmY >=0) && (FilmC->FilmY <=100)) {
|
||||||
// Check if screen size being used is different from theme origination size.
|
// Check if screen size being used is different from theme origination size.
|
||||||
|
Loading…
Reference in New Issue
Block a user