Merge pull request #717 from Erihel/dev

Fix crash related to TTF and PHYSFS
dev-time-step
krzys_h 2016-02-11 18:49:11 +01:00
commit e647500ebf
7 changed files with 132 additions and 9 deletions

View File

@ -98,6 +98,7 @@ set(BASE_SOURCES
common/resources/outputstreambuffer.cpp
common/resources/resourcemanager.cpp
common/resources/sdl_file_wrapper.cpp
common/resources/sdl_memory_wrapper.cpp
common/resources/sndfile_wrapper.cpp
common/restext.cpp
common/settings.cpp

View File

@ -114,6 +114,11 @@ std::unique_ptr<CSDLFileWrapper> CResourceManager::GetSDLFileHandler(const std::
return MakeUnique<CSDLFileWrapper>(CleanPath(filename));
}
std::unique_ptr<CSDLMemoryWrapper> CResourceManager::GetSDLMemoryHandler(const std::string &filename)
{
return MakeUnique<CSDLMemoryWrapper>(CleanPath(filename));
}
std::unique_ptr<CSNDFileWrapper> CResourceManager::GetSNDFileHandler(const std::string &filename)
{
return MakeUnique<CSNDFileWrapper>(CleanPath(filename));

View File

@ -20,6 +20,7 @@
#pragma once
#include "common/resources/sdl_file_wrapper.h"
#include "common/resources/sdl_memory_wrapper.h"
#include "common/resources/sndfile_wrapper.h"
#include <memory>
@ -41,6 +42,7 @@ public:
static std::string GetSaveLocation();
static std::unique_ptr<CSDLFileWrapper> GetSDLFileHandler(const std::string &filename);
static std::unique_ptr<CSDLMemoryWrapper> GetSDLMemoryHandler(const std::string &filename);
static std::unique_ptr<CSNDFileWrapper> GetSNDFileHandler(const std::string &filename);
//! Check if file exists

View File

@ -24,10 +24,6 @@
#include <physfs.h>
namespace
{
const Uint32 PHYSFS_RWOPS_TYPE = 0xc010b04f;
}
CSDLFileWrapper::CSDLFileWrapper(const std::string& filename)
: m_rwops(nullptr)
@ -52,7 +48,7 @@ CSDLFileWrapper::CSDLFileWrapper(const std::string& filename)
return;
}
m_rwops->type = PHYSFS_RWOPS_TYPE; //TODO: Documentation recommends to leave SDL_RWOPS_UNKNOWN here for application-defined RWops. Did that change in SDL2?
m_rwops->type = SDL_RWOPS_UNKNOWN;
m_rwops->hidden.unknown.data1 = file;
m_rwops->seek = SDLSeek;
m_rwops->read = SDLRead;
@ -109,7 +105,7 @@ int CSDLFileWrapper::SDLCloseWithFreeRW(SDL_RWops *context)
bool CSDLFileWrapper::CheckSDLContext(SDL_RWops *context)
{
if (context->type != PHYSFS_RWOPS_TYPE)
if (context->type != SDL_RWOPS_UNKNOWN)
{
SDL_SetError("Wrong kind of RWops");
return false;

View File

@ -0,0 +1,77 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://gnu.org/licenses
*/
#include "common/resources/sdl_memory_wrapper.h"
#include "common/logger.h"
#include <physfs.h>
CSDLMemoryWrapper::CSDLMemoryWrapper(const std::string& filename)
: m_rwops(nullptr)
{
if (!PHYSFS_isInit())
{
GetLogger()->Error("PHYSFS not initialized!\n");
return;
}
PHYSFS_File *file = PHYSFS_openRead(filename.c_str());
if (file == nullptr)
{
GetLogger()->Error("Error opening file with PHYSFS: \"%s\"\n", filename.c_str());
return;
}
PHYSFS_sint64 length = PHYSFS_fileLength(file);
m_buffer = new char[length];
if (PHYSFS_read(file, m_buffer, 1, length) != length)
{
GetLogger()->Error("Unable to read data for \"%s\"\n", filename.c_str());
PHYSFS_close(file);
return;
}
PHYSFS_close(file);
m_rwops = SDL_RWFromMem(m_buffer, length);
if (m_rwops == nullptr)
{
GetLogger()->Error("Unable to allocate SDL_RWops for \"%s\"\n", filename.c_str());
return;
}
}
CSDLMemoryWrapper::~CSDLMemoryWrapper()
{
SDL_FreeRW(m_rwops);
delete []m_buffer;
}
SDL_RWops* CSDLMemoryWrapper::GetHandler()
{
return m_rwops;
}
bool CSDLMemoryWrapper::IsOpen() const
{
return m_rwops != nullptr;
}

View File

@ -0,0 +1,42 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://gnu.org/licenses
*/
#pragma once
#include <string>
#include <SDL.h>
class CSDLMemoryWrapper
{
public:
CSDLMemoryWrapper(const std::string& filename);
~CSDLMemoryWrapper();
CSDLMemoryWrapper(const CSDLMemoryWrapper&) = delete;
CSDLMemoryWrapper& operator=(const CSDLMemoryWrapper&) = delete;
bool IsOpen() const;
SDL_RWops* GetHandler();
private:
SDL_RWops* m_rwops;
char *m_buffer;
};

View File

@ -60,11 +60,11 @@ struct MultisizeFont
*/
struct CachedFont
{
std::unique_ptr<CSDLFileWrapper> fontFile;
std::unique_ptr<CSDLMemoryWrapper> fontFile;
TTF_Font* font = nullptr;
std::map<UTF8Char, CharTexture> cache;
CachedFont(std::unique_ptr<CSDLFileWrapper> fontFile, int pointSize)
CachedFont(std::unique_ptr<CSDLMemoryWrapper> fontFile, int pointSize)
: fontFile(std::move(fontFile))
{
font = TTF_OpenFontRW(this->fontFile->GetHandler(), 0, pointSize);
@ -980,7 +980,7 @@ CachedFont* CText::GetOrOpenFont(FontType font, float size)
return m_lastCachedFont;
}
auto file = CResourceManager::GetSDLFileHandler(mf->fileName);
auto file = CResourceManager::GetSDLMemoryHandler(mf->fileName);
if (!file->IsOpen())
{
m_error = std::string("Unable to open file");