mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-17 13:38:18 +00:00
Merge pull request #9014 from Robyt3/Editor-External-Mapres-Error-Handling
Fix editor crashes when images/sounds cannot be loaded, fix editor crashes with external RGB images
This commit is contained in:
commit
ec768b2269
|
@ -4358,13 +4358,10 @@ bool CEditor::ReplaceImage(const char *pFileName, int StorageType, bool CheckDup
|
|||
str_copy(pImg->m_aName, aBuf);
|
||||
pImg->m_External = IsVanillaImage(pImg->m_aName);
|
||||
|
||||
if(!pImg->m_External)
|
||||
ConvertToRgba(*pImg);
|
||||
if(g_Config.m_ClEditorDilate == 1)
|
||||
{
|
||||
ConvertToRgba(*pImg);
|
||||
if(g_Config.m_ClEditorDilate == 1)
|
||||
{
|
||||
DilateImage(*pImg);
|
||||
}
|
||||
DilateImage(*pImg);
|
||||
}
|
||||
|
||||
pImg->m_AutoMapper.Load(pImg->m_aName);
|
||||
|
@ -4425,13 +4422,10 @@ bool CEditor::AddImage(const char *pFileName, int StorageType, void *pUser)
|
|||
pImg->m_pData = ImgInfo.m_pData;
|
||||
pImg->m_External = IsVanillaImage(aBuf);
|
||||
|
||||
if(!pImg->m_External)
|
||||
ConvertToRgba(*pImg);
|
||||
if(g_Config.m_ClEditorDilate == 1)
|
||||
{
|
||||
ConvertToRgba(*pImg);
|
||||
if(g_Config.m_ClEditorDilate == 1)
|
||||
{
|
||||
DilateImage(*pImg);
|
||||
}
|
||||
DilateImage(*pImg);
|
||||
}
|
||||
|
||||
int TextureLoadFlag = pEditor->Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
|
||||
|
@ -8726,7 +8720,11 @@ bool CEditor::Save(const char *pFilename)
|
|||
if(std::any_of(std::begin(m_WriterFinishJobs), std::end(m_WriterFinishJobs), [pFilename](const std::shared_ptr<CDataFileWriterFinishJob> &Job) { return str_comp(pFilename, Job->GetRealFileName()) == 0; }))
|
||||
return false;
|
||||
|
||||
return m_Map.Save(pFilename);
|
||||
const auto &&ErrorHandler = [this](const char *pErrorMessage) {
|
||||
ShowFileDialogError("%s", pErrorMessage);
|
||||
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "editor/save", pErrorMessage);
|
||||
};
|
||||
return m_Map.Save(pFilename, ErrorHandler);
|
||||
}
|
||||
|
||||
bool CEditor::HandleMapDrop(const char *pFileName, int StorageType)
|
||||
|
|
|
@ -200,7 +200,8 @@ public:
|
|||
void CreateDefault(IGraphics::CTextureHandle EntitiesTexture);
|
||||
|
||||
// io
|
||||
bool Save(const char *pFilename);
|
||||
bool Save(const char *pFilename, const std::function<void(const char *pErrorMessage)> &ErrorHandler);
|
||||
bool PerformPreSaveSanityChecks(const std::function<void(const char *pErrorMessage)> &ErrorHandler);
|
||||
bool Load(const char *pFilename, int StorageType, const std::function<void(const char *pErrorMessage)> &ErrorHandler);
|
||||
void PerformSanityChecks(const std::function<void(const char *pErrorMessage)> &ErrorHandler);
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ struct CSoundSource_DEPRECATED
|
|||
int m_SoundEnvOffset;
|
||||
};
|
||||
|
||||
bool CEditorMap::Save(const char *pFileName)
|
||||
bool CEditorMap::Save(const char *pFileName, const std::function<void(const char *pErrorMessage)> &ErrorHandler)
|
||||
{
|
||||
char aFileNameTmp[IO_MAX_PATH_LENGTH];
|
||||
IStorage::FormatTmpPath(aFileNameTmp, sizeof(aFileNameTmp), pFileName);
|
||||
|
@ -42,11 +42,17 @@ bool CEditorMap::Save(const char *pFileName)
|
|||
char aBuf[IO_MAX_PATH_LENGTH + 64];
|
||||
str_format(aBuf, sizeof(aBuf), "saving to '%s'...", aFileNameTmp);
|
||||
m_pEditor->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "editor", aBuf);
|
||||
|
||||
if(!PerformPreSaveSanityChecks(ErrorHandler))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CDataFileWriter Writer;
|
||||
if(!Writer.Open(m_pEditor->Storage(), aFileNameTmp))
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), "failed to open file '%s'...", aFileNameTmp);
|
||||
m_pEditor->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "editor", aBuf);
|
||||
str_format(aBuf, sizeof(aBuf), "Error: Failed to open file '%s' for writing.", aFileNameTmp);
|
||||
ErrorHandler(aBuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -402,11 +408,42 @@ bool CEditorMap::Save(const char *pFileName)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CEditorMap::PerformPreSaveSanityChecks(const std::function<void(const char *pErrorMessage)> &ErrorHandler)
|
||||
{
|
||||
bool Success = true;
|
||||
char aErrorMessage[256];
|
||||
|
||||
for(const std::shared_ptr<CEditorImage> &pImage : m_vpImages)
|
||||
{
|
||||
if(!pImage->m_External && pImage->m_pData == nullptr)
|
||||
{
|
||||
str_format(aErrorMessage, sizeof(aErrorMessage), "Error: Saving is not possible because the image '%s' could not be loaded. Remove or replace this image.", pImage->m_aName);
|
||||
ErrorHandler(aErrorMessage);
|
||||
Success = false;
|
||||
}
|
||||
}
|
||||
|
||||
for(const std::shared_ptr<CEditorSound> &pSound : m_vpSounds)
|
||||
{
|
||||
if(pSound->m_pData == nullptr)
|
||||
{
|
||||
str_format(aErrorMessage, sizeof(aErrorMessage), "Error: Saving is not possible because the sound '%s' could not be loaded. Remove or replace this sound.", pSound->m_aName);
|
||||
ErrorHandler(aErrorMessage);
|
||||
Success = false;
|
||||
}
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
bool CEditorMap::Load(const char *pFileName, int StorageType, const std::function<void(const char *pErrorMessage)> &ErrorHandler)
|
||||
{
|
||||
CDataFileReader DataFile;
|
||||
if(!DataFile.Open(m_pEditor->Storage(), pFileName, StorageType))
|
||||
{
|
||||
ErrorHandler("Error: Failed to open map file. See local console for details.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// check version
|
||||
const CMapItemVersion *pItemVersion = static_cast<CMapItemVersion *>(DataFile.FindItem(MAPITEMTYPE_VERSION, 0));
|
||||
|
@ -513,11 +550,15 @@ bool CEditorMap::Load(const char *pFileName, int StorageType, const std::functio
|
|||
ConvertToRgba(*pImg);
|
||||
|
||||
int TextureLoadFlag = m_pEditor->Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
|
||||
if(ImgInfo.m_Width % 16 != 0 || ImgInfo.m_Height % 16 != 0)
|
||||
if(pImg->m_Width % 16 != 0 || pImg->m_Height % 16 != 0)
|
||||
TextureLoadFlag = 0;
|
||||
pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(ImgInfo, TextureLoadFlag, aBuf);
|
||||
ImgInfo.m_pData = nullptr;
|
||||
pImg->m_External = 1;
|
||||
pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(*pImg, TextureLoadFlag, aBuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), "Error: Failed to load external image '%s'.", pImg->m_aName);
|
||||
ErrorHandler(aBuf);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -579,6 +620,11 @@ bool CEditorMap::Load(const char *pFileName, int StorageType, const std::functio
|
|||
{
|
||||
pSound->m_SoundId = m_pEditor->Sound()->LoadOpusFromMem(pSound->m_pData, pSound->m_DataSize, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), "Error: Failed to load external sound '%s'.", pSound->m_aName);
|
||||
ErrorHandler(aBuf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1655,6 +1655,11 @@ CUi::EPopupMenuFunctionResult CEditor::PopupImage(void *pContext, CUIRect View,
|
|||
{
|
||||
if(pEditor->DoButton_MenuItem(&s_ExternalButton, "Embed", 0, &Slot, 0, "Embeds the image into the map file."))
|
||||
{
|
||||
if(pImg->m_pData == nullptr)
|
||||
{
|
||||
pEditor->ShowFileDialogError("Embedding is not possible because the image could not be loaded.");
|
||||
return CUi::POPUP_KEEP_OPEN;
|
||||
}
|
||||
pImg->m_External = 0;
|
||||
return CUi::POPUP_CLOSE_CURRENT;
|
||||
}
|
||||
|
@ -1730,6 +1735,11 @@ CUi::EPopupMenuFunctionResult CEditor::PopupImage(void *pContext, CUIRect View,
|
|||
View.HSplitTop(RowHeight, &Slot, &View);
|
||||
if(pEditor->DoButton_MenuItem(&s_ExportButton, "Export", 0, &Slot, 0, "Export the image"))
|
||||
{
|
||||
if(pImg->m_pData == nullptr)
|
||||
{
|
||||
pEditor->ShowFileDialogError("Exporting is not possible because the image could not be loaded.");
|
||||
return CUi::POPUP_KEEP_OPEN;
|
||||
}
|
||||
pEditor->InvokeFileDialog(IStorage::TYPE_SAVE, FILETYPE_IMG, "Save image", "Save", "mapres", false, CallbackSaveImage, pEditor);
|
||||
pEditor->m_FileDialogFileNameInput.Set(pImg->m_aName);
|
||||
return CUi::POPUP_CLOSE_CURRENT;
|
||||
|
@ -1825,6 +1835,11 @@ CUi::EPopupMenuFunctionResult CEditor::PopupSound(void *pContext, CUIRect View,
|
|||
View.HSplitTop(RowHeight, &Slot, &View);
|
||||
if(pEditor->DoButton_MenuItem(&s_ExportButton, "Export", 0, &Slot, 0, "Export sound"))
|
||||
{
|
||||
if(pSound->m_pData == nullptr)
|
||||
{
|
||||
pEditor->ShowFileDialogError("Exporting is not possible because the sound could not be loaded.");
|
||||
return CUi::POPUP_KEEP_OPEN;
|
||||
}
|
||||
pEditor->InvokeFileDialog(IStorage::TYPE_SAVE, FILETYPE_SOUND, "Save sound", "Save", "mapres", false, CallbackSaveSound, pEditor);
|
||||
pEditor->m_FileDialogFileNameInput.Set(pSound->m_aName);
|
||||
return CUi::POPUP_CLOSE_CURRENT;
|
||||
|
|
Loading…
Reference in a new issue