summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
m---------data0
-rw-r--r--desktop/CMakeLists.txt10
-rw-r--r--po/CMakeLists.txt2
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/app/app.cpp12
-rw-r--r--src/app/app.h7
-rw-r--r--src/app/main.cpp62
-rw-r--r--src/common/misc.cpp38
-rw-r--r--src/common/misc.h1
-rw-r--r--src/common/profile.cpp49
-rw-r--r--src/common/profile.h20
-rw-r--r--src/common/resources/inputstreambuffer.cpp4
-rw-r--r--src/common/resources/outputstreambuffer.cpp4
-rw-r--r--src/common/resources/resourcemanager.cpp25
-rw-r--r--src/common/resources/resourcemanager.h2
-rw-r--r--src/graphics/engine/engine.cpp5
-rw-r--r--src/graphics/engine/modelfile.cpp38
-rw-r--r--src/graphics/engine/terrain.cpp3
-rw-r--r--src/graphics/opengl/gldevice.cpp156
-rw-r--r--src/graphics/opengl/gldevice.h14
-rw-r--r--src/object/level/parser.cpp6
-rw-r--r--src/object/level/parser.h2
-rw-r--r--src/object/level/parserparam.cpp2
-rw-r--r--src/object/robotmain.cpp88
-rw-r--r--src/ui/maindialog.cpp163
26 files changed, 392 insertions, 326 deletions
diff --git a/.gitignore b/.gitignore
index 3dae3d9..40d97d0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@ Makefile
/CTestTestfile.cmake
/CPackConfig.cmake
/CPackSourceConfig.cmake
+/src/libcolobotbase.a
# Ignore the generated documentation
/doc
diff --git a/data b/data
-Subproject f071d2403aab82830a3df2b89e32122b57cba17
+Subproject 2660c69a52411ca68a2cd6d61f6147f0efbfcc1
diff --git a/desktop/CMakeLists.txt b/desktop/CMakeLists.txt
index 87c8a4b..c63b80e 100644
--- a/desktop/CMakeLists.txt
+++ b/desktop/CMakeLists.txt
@@ -127,11 +127,11 @@ endif(PLATFORM_WINDOWS)
##
# Packaging
##
-set(CPACK_BUNDLE_NAME "Colobot")
+set(CPACK_BUNDLE_NAME "Colobot: Gold Edition")
set(CPACK_PACKAGE_FILE_NAME "colobot-${COLOBOT_VERSION_FULL}")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../README.md")
-set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Colobot - Colonize with Bots")
-set(CPACK_PACKAGE_VENDOR "Polish Portal of Colobot")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Colobot: Gold Edition")
+set(CPACK_PACKAGE_VENDOR "Terranova Team")
set(CPACK_PACKAGE_VERSION_MAJOR ${COLOBOT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${COLOBOT_VERSION_MINOR})
@@ -142,10 +142,10 @@ if(PLATFORM_WINDOWS)
# Don't version the install directory, and allow overwriting
set(CPACK_PACKAGE_INSTALL_DIRECTORY "Colobot")
- set(CPACK_NSIS_DEFINES "SetOverwrite on\nBrandingText \\\"Colobot ${COLOBOT_VERSION_CODENAME} (${COLOBOT_VERSION_FULL})\\\"")
+ set(CPACK_NSIS_DEFINES "SetOverwrite on\nBrandingText \\\"Colobot: Gold Edition (${COLOBOT_VERSION_FULL})\\\"")
# Install the executable directly in Program Files/Colobot/
set(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
- set(CPACK_PACKAGE_EXECUTABLES "colobot" "Colobot ${COLOBOT_VERSION_CODENAME}")
+ set(CPACK_PACKAGE_EXECUTABLES "colobot" "Colobot: Gold Edition")
# Branding
## Installation and uninstallation icons
diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt
index 78a63b7..def5473 100644
--- a/po/CMakeLists.txt
+++ b/po/CMakeLists.txt
@@ -7,7 +7,7 @@ find_program(XGETTEXT_CMD xgettext)
add_custom_command(OUTPUT ${_potFile}
COMMAND ${XGETTEXT_CMD} ${colobot_SOURCE_DIR}/src/app/app.cpp --output=${_potFile}
COMMAND ${XGETTEXT_CMD} ${colobot_SOURCE_DIR}/src/common/restext.cpp --output=${_potFile} --join-existing --keyword=TR --no-location
- COMMAND sed -i -E "s|^(\"POT-Creation-Date:).*$|\\1 DATE\\\\n\"|" ${_potFile}
+ COMMAND sed -i -e "s|^\\(\"POT-Creation-Date:\\).*$|\\1 DATE\\\\n\"|" ${_potFile}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Extract translatable messages to ${_potFile}"
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 869f0cb..a8914e1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -215,7 +215,7 @@ set(LIBS
${LIBSNDFILE_LIBRARY}
${OPTIONAL_LIBS}
${PLATFORM_LIBS}
-${PHYSFS_LIBRARY}
+ ${PHYSFS_LIBRARY}
)
set(COLOBOT_LIBS ${LIBS} PARENT_SCOPE)
@@ -239,7 +239,7 @@ set(SYSTEM_INCLUDES
${LOCALENAME_INCLUDE_DIR}
${OPTIONAL_INCLUDE_DIRS}
${CLIPBOARD_INCLUDE_DIR}
-${PHYSFS_INCLUDE_PATH}
+ ${PHYSFS_INCLUDE_PATH}
)
set(COLOBOT_LOCAL_INCLUDES ${LOCAL_INCLUDES} PARENT_SCOPE)
diff --git a/src/app/app.cpp b/src/app/app.cpp
index 1b53a28..ea54cf1 100644
--- a/src/app/app.cpp
+++ b/src/app/app.cpp
@@ -113,6 +113,7 @@ CApplication::CApplication()
m_exitCode = 0;
m_active = false;
m_debugModes = 0;
+ m_restart = false;
m_windowTitle = "COLOBOT: Gold Edition";
@@ -675,6 +676,17 @@ void CApplication::Destroy()
SDL_Quit();
}
+void CApplication::Restart()
+{
+ m_restart = true;
+ m_eventQueue->AddEvent(Event(EVENT_SYS_QUIT));
+}
+
+bool CApplication::IsRestarting()
+{
+ return m_restart;
+}
+
bool CApplication::ChangeVideoConfig(const Gfx::GLDeviceConfig &newConfig)
{
static bool restore = false;
diff --git a/src/app/app.h b/src/app/app.h
index c73cb53..500cb2f 100644
--- a/src/app/app.h
+++ b/src/app/app.h
@@ -227,6 +227,11 @@ public:
//! Cleans up before exit
void Destroy();
+
+ //! Restart
+ void Restart();
+ //! Should we restart after app quits?
+ bool IsRestarting();
//! Returns a list of possible video modes
VideoQueryResult GetVideoResolutionList(std::vector<Math::IntPoint> &resolutions,
@@ -413,6 +418,8 @@ protected:
bool m_active;
//! Bit array of active debug modes
long m_debugModes;
+ //! If we are restarting the app
+ bool m_restart;
//! Message to be displayed as error to the user
std::string m_errorMessage;
diff --git a/src/app/main.cpp b/src/app/main.cpp
index e30a83d..88a7a73 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -86,42 +86,46 @@ int SDL_MAIN_FUNC(int argc, char *argv[])
InitializeRestext();
InitializeEventTypeTexts();
- CSystemUtils* systemUtils = CSystemUtils::Create(); // platform-specific utils
- systemUtils->Init();
-
logger.Info("Colobot starting\n");
-
- CApplication* app = new CApplication(); // single instance of the application
-
- ParseArgsStatus status = app->ParseArguments(argc, argv);
- if (status == PARSE_ARGS_FAIL)
- {
- systemUtils->SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", "Invalid commandline arguments!\n");
- return app->GetExitCode();
- }
- else if (status == PARSE_ARGS_HELP)
- {
- return app->GetExitCode();
- }
-
+
int code = 0;
+ while(true) {
+ CSystemUtils* systemUtils = CSystemUtils::Create(); // platform-specific utils
+ systemUtils->Init();
+
+ CApplication* app = new CApplication(); // single instance of the application
+
+ ParseArgsStatus status = app->ParseArguments(argc, argv);
+ if (status == PARSE_ARGS_FAIL)
+ {
+ systemUtils->SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", "Invalid commandline arguments!\n");
+ return app->GetExitCode();
+ }
+ else if (status == PARSE_ARGS_HELP)
+ {
+ return app->GetExitCode();
+ }
- if (! app->Create())
- {
- app->Destroy(); // ensure a clean exit
- code = app->GetExitCode();
- if ( code != 0 && !app->GetErrorMessage().empty() )
+
+ if (! app->Create())
{
- systemUtils->SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", app->GetErrorMessage());
+ app->Destroy(); // ensure a clean exit
+ code = app->GetExitCode();
+ if ( code != 0 && !app->GetErrorMessage().empty() )
+ {
+ systemUtils->SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", app->GetErrorMessage());
+ }
+ logger.Info("Didn't run main loop. Exiting with code %d\n", code);
+ return code;
}
- logger.Info("Didn't run main loop. Exiting with code %d\n", code);
- return code;
- }
- code = app->Run();
+ code = app->Run();
+ bool restarting = app->IsRestarting();
- delete app;
- delete systemUtils;
+ delete app;
+ delete systemUtils;
+ if(!restarting) break;
+ }
logger.Info("Exiting with code %d\n", code);
return code;
diff --git a/src/common/misc.cpp b/src/common/misc.cpp
index 1cbd3b1..4954fc0 100644
--- a/src/common/misc.cpp
+++ b/src/common/misc.cpp
@@ -232,44 +232,6 @@ void TimeToAsciiClean(time_t time, char *buffer)
when.tm_hour, when.tm_min);
}
-// Copy a list of numbered files into the temporary folder.
-
-bool CopyFileListToTemp(char* filename, int* list, int total)
-{
- /*char name[100];
- char ext[10];
- char file[100];
- char save[100];
- char* p;
- int i;
-
- strcpy(name, filename);
- p = strchr(name, '.');
- if ( p == 0 )
- {
- strcpy(ext, ".tga");
- }
- else
- {
- strcpy(ext, p);
- *p = 0;
- }
-
- for ( i=0 ; i<total ; i++ )
- {
- sprintf(file, "%s%.3d%s", name, list[i], ext); // nameNNN.ext
- CopyFileToTemp(file);
- }
-
- strcpy(save, g_userDir);
- strcpy(g_userDir, "temp");
- UserDir(file, filename, "textures");
- strcpy(filename, file);
- strcpy(g_userDir, save);
-*/
- return false;
-}
-
// Adds an extension to file, if doesn't already one.
diff --git a/src/common/misc.h b/src/common/misc.h
index a079ba6..4b75ae3 100644
--- a/src/common/misc.h
+++ b/src/common/misc.h
@@ -33,6 +33,5 @@ extern char GetToLower(char letter);
extern void TimeToAscii(time_t time, char *buffer);
extern void TimeToAsciiClean(time_t time, char *buffer);
-extern bool CopyFileListToTemp(char* filename, int* list, int total);
extern void AddExt(char* filename, const char* ext);
diff --git a/src/common/profile.cpp b/src/common/profile.cpp
index 92fc1d6..75ab135 100644
--- a/src/common/profile.cpp
+++ b/src/common/profile.cpp
@@ -247,52 +247,3 @@ std::vector< std::string > CProfile::GetSection(std::string section, std::string
return ret_list;
}
-
-void CProfile::SetUserDir(std::string dir)
-{
- m_userDirectory = dir;
-}
-
-
-std::string CProfile::GetUserBasedPath(std::string dir, std::string defaultDir)
-{
- std::string path = dir;
- boost::replace_all(path, "\\", "/");
- if (dir.find("/") == std::string::npos)
- {
- path = defaultDir + "/" + dir;
- }
-
- if (m_userDirectory.length() > 0)
- {
- boost::replace_all(path, "%user%", m_userDirectory);
- }
- else
- {
- boost::replace_all(path, "%user%", defaultDir);
- }
-
- return fs::path(path).make_preferred().string();
-}
-
-
-bool CProfile::CopyFileToTemp(std::string filename)
-{
- std::string src, dst;
- std::string tmp_user_dir = m_userDirectory;
-
- src = GetUserBasedPath(filename, "textures");
- SetUserDir("temp");
- dst = GetUserBasedPath(filename, "textures");
- SetUserDir(tmp_user_dir);
-
- fs::create_directory(fs::path(dst).parent_path().make_preferred().string());
- fs::copy_file(src, dst, fs::copy_option::overwrite_if_exists);
- if (fs::exists(dst))
- {
- return true;
- }
-
- return false;
-}
-
diff --git a/src/common/profile.h b/src/common/profile.h
index 444975c..d89c5d1 100644
--- a/src/common/profile.h
+++ b/src/common/profile.h
@@ -116,29 +116,9 @@ public:
*/
std::vector< std::string > GetSection(std::string section, std::string key);
- /** Sets current user directory
- * \param dir
- */
- void SetUserDir(std::string dir);
-
- /** Returns path based on current user. Replaces %user% in path with current user dir or
- * uses default_dir param if no user dir is specified
- * \param dir
- * \param default_dir
- * \return path
- */
- std::string GetUserBasedPath(std::string dir, std::string defaultDir);
-
- /** Copy a file into the temporary folder.
- * \param filename
- * \return true on success
- */
- bool CopyFileToTemp(std::string filename);
-
private:
boost::property_tree::ptree m_propertyTree;
bool m_profileNeedSave;
- std::string m_userDirectory;
bool m_useCurrentDirectory;
};
diff --git a/src/common/resources/inputstreambuffer.cpp b/src/common/resources/inputstreambuffer.cpp
index 7059d60..9ac1fec 100644
--- a/src/common/resources/inputstreambuffer.cpp
+++ b/src/common/resources/inputstreambuffer.cpp
@@ -19,6 +19,8 @@
#include "common/resources/inputstreambuffer.h"
+#include "common/resources/resourcemanager.h"
+
#include <stdexcept>
#include <sstream>
@@ -44,7 +46,7 @@ CInputStreamBuffer::~CInputStreamBuffer()
void CInputStreamBuffer::open(const std::string &filename)
{
if (PHYSFS_isInit())
- m_file = PHYSFS_openRead(filename.c_str());
+ m_file = PHYSFS_openRead(CResourceManager::CleanPath(filename).c_str());
}
diff --git a/src/common/resources/outputstreambuffer.cpp b/src/common/resources/outputstreambuffer.cpp
index f8b4100..157e17d 100644
--- a/src/common/resources/outputstreambuffer.cpp
+++ b/src/common/resources/outputstreambuffer.cpp
@@ -19,6 +19,8 @@
#include "common/resources/outputstreambuffer.h"
+#include "common/resources/resourcemanager.h"
+
#include <stdexcept>
#include <sstream>
@@ -40,7 +42,7 @@ COutputStreamBuffer::~COutputStreamBuffer()
void COutputStreamBuffer::open(const std::string &filename)
{
if (PHYSFS_isInit())
- m_file = PHYSFS_openWrite(filename.c_str());
+ m_file = PHYSFS_openWrite(CResourceManager::CleanPath(filename).c_str());
}
diff --git a/src/common/resources/resourcemanager.cpp b/src/common/resources/resourcemanager.cpp
index 42f9634..475d71e 100644
--- a/src/common/resources/resourcemanager.cpp
+++ b/src/common/resources/resourcemanager.cpp
@@ -26,6 +26,7 @@
#include <physfs.h>
#include <boost/filesystem.hpp>
+#include <boost/regex.hpp>
namespace fs = boost::filesystem;
@@ -55,6 +56,11 @@ CResourceManager::~CResourceManager()
}
}
+std::string CResourceManager::CleanPath(const std::string& path)
+{
+ return boost::regex_replace(path, boost::regex("(.*)/\\.\\./"), "");
+}
+
bool CResourceManager::AddLocation(const std::string &location, bool prepend)
{
@@ -121,7 +127,7 @@ SDL_RWops* CResourceManager::GetSDLFileHandler(const std::string &filename)
return nullptr;
}
- PHYSFS_File *file = PHYSFS_openRead(filename.c_str());
+ PHYSFS_File *file = PHYSFS_openRead(CleanPath(filename).c_str());
if (!file)
{
SDL_FreeRW(handler);
@@ -141,32 +147,33 @@ SDL_RWops* CResourceManager::GetSDLFileHandler(const std::string &filename)
CSNDFile* CResourceManager::GetSNDFileHandler(const std::string &filename)
{
- return new CSNDFile(filename);
+ return new CSNDFile(CleanPath(filename));
}
bool CResourceManager::Exists(const std::string &filename)
{
- return PHYSFS_exists(filename.c_str());
+ return PHYSFS_exists(CleanPath(filename).c_str());
}
bool CResourceManager::DirectoryExists(const std::string& directory)
{
- return PHYSFS_exists(directory.c_str()) && PHYSFS_isDirectory(directory.c_str());
+ return PHYSFS_exists(CleanPath(directory).c_str()) && PHYSFS_isDirectory(CleanPath(directory).c_str());
}
bool CResourceManager::CreateDirectory(const std::string& directory)
{
- return PHYSFS_mkdir(directory.c_str());
+ return PHYSFS_mkdir(CleanPath(directory).c_str());
}
+//TODO: Don't use boost filesystem here
bool CResourceManager::RemoveDirectory(const std::string& directory)
{
bool success = true;
std::string writeDir = PHYSFS_getWriteDir();
try
{
- fs::remove_all(writeDir + "/" + directory);
+ fs::remove_all(writeDir + "/" + CleanPath(directory));
}
catch (std::exception & e)
{
@@ -179,7 +186,7 @@ std::vector<std::string> CResourceManager::ListFiles(const std::string &director
{
std::vector<std::string> result;
- char **files = PHYSFS_enumerateFiles(directory.c_str());
+ char **files = PHYSFS_enumerateFiles(CleanPath(directory).c_str());
for (char **i = files; *i != nullptr; i++)
{
@@ -195,11 +202,11 @@ std::vector<std::string> CResourceManager::ListDirectories(const std::string &di
{
std::vector<std::string> result;
- char **files = PHYSFS_enumerateFiles(directory.c_str());
+ char **files = PHYSFS_enumerateFiles(CleanPath(directory).c_str());
for (char **i = files; *i != nullptr; i++)
{
- std::string path = directory + "/" + (*i);
+ std::string path = CleanPath(directory) + "/" + (*i);
if (PHYSFS_isDirectory(path.c_str()))
{
result.push_back(*i);
diff --git a/src/common/resources/resourcemanager.h b/src/common/resources/resourcemanager.h
index 730cf3e..4d79e9b 100644
--- a/src/common/resources/resourcemanager.h
+++ b/src/common/resources/resourcemanager.h
@@ -30,6 +30,8 @@ class CResourceManager
public:
CResourceManager(const char *argv0);
~CResourceManager();
+
+ static std::string CleanPath(const std::string &path);
static bool AddLocation(const std::string &location, bool prepend = true);
static bool RemoveLocation(const std::string &location);
diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp
index db702b7..ae6f238 100644
--- a/src/graphics/engine/engine.cpp
+++ b/src/graphics/engine/engine.cpp
@@ -295,6 +295,9 @@ bool CEngine::Create()
void CEngine::Destroy()
{
m_text->Destroy();
+
+ delete m_pause;
+ m_pause = nullptr;
delete m_lightMan;
m_lightMan = nullptr;
@@ -325,6 +328,8 @@ void CEngine::ResetAfterDeviceChanged()
m_text->FlushCache();
FlushTextureCache();
+
+ LoadAllTextures();
}
bool CEngine::ProcessEvent(const Event &event)
diff --git a/src/graphics/engine/modelfile.cpp b/src/graphics/engine/modelfile.cpp
index 09c7bbd..c422f18 100644
--- a/src/graphics/engine/modelfile.cpp
+++ b/src/graphics/engine/modelfile.cpp
@@ -24,7 +24,9 @@
#include "common/logger.h"
#include "common/stringutils.h"
+#ifndef MODELFILE_NO_ENGINE
#include "common/resources/inputstream.h"
+#endif
#include "graphics/engine/engine.h"
@@ -436,13 +438,23 @@ bool CModelFile::ReadModel(const std::string& fileName)
{
m_triangles.clear();
+ #ifndef MODELFILE_NO_ENGINE
CInputStream stream;
- stream.open(fileName.c_str());
+ stream.open(fileName);
if (!stream.is_open())
{
GetLogger()->Error("Could not open file '%s'\n", fileName.c_str());
return false;
}
+ #else
+ std::ifstream stream;
+ stream.open(fileName);
+ if (!stream.good())
+ {
+ GetLogger()->Error("Could not open file '%s'\n", fileName.c_str());
+ return false;
+ }
+ #endif
return ReadModel(stream);
}
@@ -827,13 +839,23 @@ struct NewModelTriangle1
bool CModelFile::ReadTextModel(const std::string& fileName)
{
+ #ifndef MODELFILE_NO_ENGINE
CInputStream stream;
- stream.open(fileName.c_str());
+ stream.open(fileName);
if (!stream.is_open())
{
GetLogger()->Error("Could not open file '%s'\n", fileName.c_str());
return false;
}
+ #else
+ std::ifstream stream;
+ stream.open(fileName);
+ if (!stream.good())
+ {
+ GetLogger()->Error("Could not open file '%s'\n", fileName.c_str());
+ return false;
+ }
+ #endif
return ReadTextModel(stream);
}
@@ -1024,13 +1046,23 @@ bool CModelFile::WriteTextModel(std::ostream& stream)
bool CModelFile::ReadBinaryModel(const std::string& fileName)
{
+ #ifndef MODELFILE_NO_ENGINE
CInputStream stream;
- stream.open(fileName.c_str());
+ stream.open(fileName);
if (!stream.is_open())
{
GetLogger()->Error("Could not open file '%s'\n", fileName.c_str());
return false;
}
+ #else
+ std::ifstream stream;
+ stream.open(fileName);
+ if (!stream.good())
+ {
+ GetLogger()->Error("Could not open file '%s'\n", fileName.c_str());
+ return false;
+ }
+ #endif
return ReadBinaryModel(stream);
}
diff --git a/src/graphics/engine/terrain.cpp b/src/graphics/engine/terrain.cpp
index 21d7446..b58685b 100644
--- a/src/graphics/engine/terrain.cpp
+++ b/src/graphics/engine/terrain.cpp
@@ -123,7 +123,8 @@ bool CTerrain::InitTextures(const std::string& baseName, int* table, int dx, int
m_useMaterials = false;
m_texBaseName = baseName;
- size_t pos = baseName.find('.');
+ size_t pos = baseName.rfind('.');
+ if(pos < baseName.find_last_of('/')) pos = std::string::npos; // If last . is not a part of filename (some directory, possibly . or ..)
if (pos == std::string::npos)
{
diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp
index 0ae6f88..a197b18 100644
--- a/src/graphics/opengl/gldevice.cpp
+++ b/src/graphics/opengl/gldevice.cpp
@@ -68,6 +68,7 @@ CGLDevice::CGLDevice(const GLDeviceConfig &config)
m_lastVboId = 0;
m_multitextureAvailable = false;
m_vboAvailable = false;
+ m_vertexBufferType = VBT_DISPLAY_LIST;
}
@@ -186,7 +187,7 @@ bool CGLDevice::Create()
{
GetLogger()->Info("Creating CDevice\n");
- static bool glewInited = false;
+ /*static*/ bool glewInited = false;
if (!glewInited)
{
@@ -207,12 +208,12 @@ bool CGLDevice::Create()
if (m_config.vboMode == VBO_MODE_ENABLE)
{
GetLogger()->Info("VBO enabled by override - using VBOs\n");
- m_vboAvailable = true;
+ SetVertexBufferType(VBT_VBO_CORE);
}
else if (m_config.vboMode == VBO_MODE_DISABLE)
{
GetLogger()->Info("VBO disabled by override - using display lists\n");
- m_vboAvailable = false;
+ SetVertexBufferType(VBT_DISPLAY_LIST);
}
else
{
@@ -223,18 +224,26 @@ bool CGLDevice::Create()
int major = 0, minor = 0;
sscanf(version, "%d.%d", &major, &minor);
+
+ // detecting VBO ARB extension
+ bool vboARB = glewIsSupported("GL_ARB_vertex_buffer_object");
// VBO is core OpenGL feature since 1.5
// everything below 1.5 means no VBO support
if(major > 1 || minor > 4)
{
GetLogger()->Info("OpenGL %d.%d, VBO supported\n", major, minor);
- m_vboAvailable = true;
+ SetVertexBufferType(VBT_VBO_CORE);
}
- else
+ else if(vboARB) // VBO ARB extension available
+ {
+ GetLogger()->Info("OpenGL %d.%d with GL_ARB_vertex_buffer_object, VBO supported\n", major, minor);
+ SetVertexBufferType(VBT_VBO_ARB);
+ }
+ else // no VBO support
{
- GetLogger()->Info("OpenGL %d.%d, VBO not supported\n", major, minor);
- m_vboAvailable = false;
+ GetLogger()->Info("OpenGL %d.%d without GL_ARB_vertex_buffer_object, VBO not supported\n", major, minor);
+ SetVertexBufferType(VBT_DISPLAY_LIST);
}
}
}
@@ -304,6 +313,13 @@ void CGLDevice::ConfigChanged(const GLDeviceConfig& newConfig)
void CGLDevice::SetUseVbo(bool vboAvailable)
{
m_vboAvailable = vboAvailable;
+ m_vertexBufferType = vboAvailable ? VBT_VBO_CORE : VBT_DISPLAY_LIST;
+}
+
+void CGLDevice::SetVertexBufferType(VertexBufferType type)
+{
+ m_vertexBufferType = type;
+ m_vboAvailable = (type != VBT_DISPLAY_LIST);
}
void CGLDevice::BeginScene()
@@ -787,13 +803,13 @@ void CGLDevice::UpdateTextureParams(int index)
glActiveTexture(GL_TEXTURE0 + index);
if (params.wrapS == TEX_WRAP_CLAMP)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
else if (params.wrapS == TEX_WRAP_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
else assert(false);
if (params.wrapT == TEX_WRAP_CLAMP)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
else if (params.wrapT == TEX_WRAP_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
else assert(false);
@@ -926,13 +942,13 @@ void CGLDevice::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode wr
glActiveTexture(GL_TEXTURE0 + index);
if (wrapS == TEX_WRAP_CLAMP)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
else if (wrapS == TEX_WRAP_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
else assert(false);
if (wrapT == TEX_WRAP_CLAMP)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
else if (wrapT == TEX_WRAP_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
else assert(false);
@@ -1046,10 +1062,20 @@ unsigned int CGLDevice::CreateStaticBuffer(PrimitiveType primitiveType, const Ve
info.vertexCount = vertexCount;
info.bufferId = 0;
- glGenBuffers(1, &info.bufferId);
- glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
- glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ if(m_vertexBufferType == VBT_VBO_CORE)
+ {
+ glGenBuffers(1, &info.bufferId);
+ glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
+ glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+ else
+ {
+ glGenBuffersARB(1, &info.bufferId);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, info.bufferId);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW_ARB);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+ }
m_vboObjects[id] = info;
}
@@ -1080,10 +1106,20 @@ unsigned int CGLDevice::CreateStaticBuffer(PrimitiveType primitiveType, const Ve
info.vertexCount = vertexCount;
info.bufferId = 0;
- glGenBuffers(1, &info.bufferId);
- glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
- glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexTex2), vertices, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ if(m_vertexBufferType == VBT_VBO_CORE)
+ {
+ glGenBuffers(1, &info.bufferId);
+ glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
+ glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexTex2), vertices, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+ else
+ {
+ glGenBuffersARB(1, &info.bufferId);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, info.bufferId);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB, vertexCount * sizeof(VertexTex2), vertices, GL_STATIC_DRAW_ARB);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+ }
m_vboObjects[id] = info;
}
@@ -1113,11 +1149,21 @@ unsigned int CGLDevice::CreateStaticBuffer(PrimitiveType primitiveType, const Ve
info.vertexType = VERTEX_TYPE_COL;
info.vertexCount = vertexCount;
info.bufferId = 0;
-
- glGenBuffers(1, &info.bufferId);
- glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
- glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexCol), vertices, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ if(m_vertexBufferType == VBT_VBO_CORE)
+ {
+ glGenBuffers(1, &info.bufferId);
+ glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
+ glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexCol), vertices, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+ else
+ {
+ glGenBuffersARB(1, &info.bufferId);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, info.bufferId);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB, vertexCount * sizeof(VertexCol), vertices, GL_STATIC_DRAW_ARB);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+ }
m_vboObjects[id] = info;
}
@@ -1148,9 +1194,18 @@ void CGLDevice::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiv
info.vertexType = VERTEX_TYPE_NORMAL;
info.vertexCount = vertexCount;
- glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
- glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ if(m_vertexBufferType == VBT_VBO_CORE)
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
+ glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+ else
+ {
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, info.bufferId);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW_ARB);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+ }
}
else
{
@@ -1175,9 +1230,18 @@ void CGLDevice::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiv
info.vertexType = VERTEX_TYPE_TEX2;
info.vertexCount = vertexCount;
- glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
- glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexTex2), vertices, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ if(m_vertexBufferType == VBT_VBO_CORE)
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
+ glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexTex2), vertices, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+ else
+ {
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, info.bufferId);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB, vertexCount * sizeof(VertexTex2), vertices, GL_STATIC_DRAW_ARB);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+ }
}
else
{
@@ -1202,9 +1266,18 @@ void CGLDevice::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiv
info.vertexType = VERTEX_TYPE_COL;
info.vertexCount = vertexCount;
- glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
- glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexCol), vertices, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ if(m_vertexBufferType == VBT_VBO_CORE)
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
+ glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexCol), vertices, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+ else
+ {
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, info.bufferId);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB, vertexCount * sizeof(VertexCol), vertices, GL_STATIC_DRAW_ARB);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+ }
}
else
{
@@ -1225,7 +1298,11 @@ void CGLDevice::DrawStaticBuffer(unsigned int bufferId)
return;
glEnable(GL_VERTEX_ARRAY);
- glBindBuffer(GL_ARRAY_BUFFER, (*it).second.bufferId);
+
+ if(m_vertexBufferType == VBT_VBO_CORE)
+ glBindBuffer(GL_ARRAY_BUFFER, (*it).second.bufferId);
+ else
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, (*it).second.bufferId);
if ((*it).second.vertexType == VERTEX_TYPE_NORMAL)
{
@@ -1297,7 +1374,11 @@ void CGLDevice::DrawStaticBuffer(unsigned int bufferId)
glDisableClientState(GL_COLOR_ARRAY);
}
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ if(m_vertexBufferType == VBT_VBO_CORE)
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ else
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+
glDisable(GL_VERTEX_ARRAY);
}
else
@@ -1314,7 +1395,10 @@ void CGLDevice::DestroyStaticBuffer(unsigned int bufferId)
if (it == m_vboObjects.end())
return;
- glDeleteBuffers(1, &(*it).second.bufferId);
+ if(m_vertexBufferType == VBT_VBO_CORE)
+ glDeleteBuffers(1, &(*it).second.bufferId);
+ else
+ glDeleteBuffersARB(1, &(*it).second.bufferId);
m_vboObjects.erase(it);
}
diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h
index 723b0f2..1174367 100644
--- a/src/graphics/opengl/gldevice.h
+++ b/src/graphics/opengl/gldevice.h
@@ -48,6 +48,17 @@ enum VBOMode
};
/**
+ \enum VertexBufferType
+ \brief Specifies type of vertex buffer to use
+ */
+enum VertexBufferType
+{
+ VBT_DISPLAY_LIST, //! use display lists
+ VBT_VBO_CORE, //! use core OpenGL 1.5 VBOs
+ VBT_VBO_ARB //! use ARB extension VBOs
+};
+
+/**
\struct GLDeviceConfig
\brief Additional config with OpenGL-specific settings */
struct GLDeviceConfig : public DeviceConfig
@@ -104,6 +115,7 @@ public:
void ConfigChanged(const GLDeviceConfig &newConfig);
void SetUseVbo(bool useVbo);
+ void SetVertexBufferType(VertexBufferType type);
virtual void BeginScene() override;
virtual void EndScene() override;
@@ -235,6 +247,8 @@ private:
bool m_multitextureAvailable;
//! Whether to use VBOs or display lists
bool m_vboAvailable;
+ //! Which vertex buffer type to use
+ VertexBufferType m_vertexBufferType;
//! Map of saved VBO objects
std::map<unsigned int, VboObjectInfo> m_vboObjects;
//! Last ID of VBO object
diff --git a/src/object/level/parser.cpp b/src/object/level/parser.cpp
index ab3e6bc..3a0449a 100644
--- a/src/object/level/parser.cpp
+++ b/src/object/level/parser.cpp
@@ -22,6 +22,7 @@
#include "app/app.h"
+#include "common/resources/resourcemanager.h"
#include "common/resources/inputstream.h"
#include "object/level/parserexceptions.h"
@@ -115,6 +116,11 @@ std::string CLevelParser::BuildSceneName(std::string category, int chapter, int
return outstream.str();
}
+bool CLevelParser::Exists()
+{
+ return CResourceManager::Exists(m_filename);
+}
+
void CLevelParser::Load()
{
CInputStream file;
diff --git a/src/object/level/parser.h b/src/object/level/parser.h
index 7e87e2d..ca2bf6f 100644
--- a/src/object/level/parser.h
+++ b/src/object/level/parser.h
@@ -46,6 +46,8 @@ public:
//! Build level filename
static std::string BuildSceneName(std::string category, int chapter, int rank, bool sceneFile = true);
+ //! Check if level file exists
+ bool Exists();
//! Load file
void Load();
//! Save file
diff --git a/src/object/level/parserparam.cpp b/src/object/level/parserparam.cpp
index aa5a963..ee080b2 100644
--- a/src/object/level/parserparam.cpp
+++ b/src/object/level/parserparam.cpp
@@ -170,7 +170,7 @@ std::string CLevelParserParam::InjectLevelDir(std::string path, const std::strin
boost::replace_all(newPath, "%lvl%", lvlDir);
std::string chapDir = CLevelParser::BuildSceneName(CRobotMain::GetInstancePointer()->GetSceneName(), CRobotMain::GetInstancePointer()->GetSceneRank()/100, 0, false);
boost::replace_all(newPath, "%chap%", chapDir);
- if(newPath == path)
+ if(newPath == path && !path.empty())
{
newPath = defaultDir + (!defaultDir.empty() ? "/" : "") + newPath;
}
diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp
index 1ad3c6d..adbe81d 100644
--- a/src/object/robotmain.cpp
+++ b/src/object/robotmain.cpp
@@ -3864,7 +3864,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
if (line->GetCommand() == "CacheAudio" && !resetObject && m_version >= 2)
{
- m_sound->CacheMusic(line->GetParam("filename")->AsPath("").c_str()); //TODO: don't make this relative to music/
+ m_sound->CacheMusic(std::string("../")+line->GetParam("filename")->AsPath("music"));
continue;
}
@@ -3882,7 +3882,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_audioChange[i].powermax = line->GetParam("powermax")->AsFloat(100);
m_audioChange[i].tool = line->GetParam("tool")->AsToolType(TOOL_OTHER);
m_audioChange[i].drive = line->GetParam("drive")->AsDriveType(DRIVE_OTHER);
- strcpy(m_audioChange[i].music, line->GetParam("filename")->AsPath("").c_str()); //TODO: don't make this relative to music/
+ strcpy(m_audioChange[i].music, (std::string("../")+line->GetParam("filename")->AsPath("music")).c_str());
m_audioChange[i].repeat = line->GetParam("repeat")->AsBool(true);
m_audioChange[i].changed = false;
m_sound->CacheMusic(m_audioChange[i].music);
@@ -3906,14 +3906,26 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
}
else
{
- m_audioTrack = line->GetParam("main")->AsPath("", ""); //TODO: don't make this relative to music/
- m_audioRepeat = line->GetParam("mainRepeat")->AsBool(true);
+ if(line->GetParam("main")->IsDefined()) {
+ m_audioTrack = std::string("../")+line->GetParam("main")->AsPath("music");
+ m_audioRepeat = line->GetParam("mainRepeat")->AsBool(true);
+ } else {
+ m_audioTrack = "";
+ }
- m_satcomTrack = line->GetParam("satcom")->AsPath("", ""); //TODO: don't make this relative to music/
- m_satcomRepeat = line->GetParam("satcomRepeat")->AsBool(true);
+ if(line->GetParam("satcom")->IsDefined()) {
+ m_satcomTrack = std::string("../")+line->GetParam("satcom")->AsPath("music");
+ m_satcomRepeat = line->GetParam("satcomRepeat")->AsBool(true);
+ } else {
+ m_satcomTrack = "";
+ }
- m_editorTrack = line->GetParam("editor")->AsPath("", ""); //TODO: don't make this relative to music/
- m_editorRepeat = line->GetParam("editorRepeat")->AsBool(true);
+ if(line->GetParam("editor")->IsDefined()) {
+ m_editorTrack = std::string("../")+line->GetParam("editor")->AsPath("music");
+ m_editorRepeat = line->GetParam("editorRepeat")->AsBool(true);
+ } else {
+ m_editorTrack = "";
+ }
}
if (m_audioTrack != "") m_sound->CacheMusic(m_audioTrack);
if (m_satcomTrack != "") m_sound->CacheMusic(m_satcomTrack);
@@ -3975,7 +3987,10 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
if (line->GetCommand() == "Background" && !resetObject)
{
- m_engine->SetBackground(line->GetParam("image")->AsPath("", "").c_str(), //TODO: don't make this relative to textures/
+ std::string path = "";
+ if(line->GetParam("image")->IsDefined())
+ path = "../"+line->GetParam("image")->AsPath("textures");
+ m_engine->SetBackground(path.c_str(),
line->GetParam("up")->AsColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f)),
line->GetParam("down")->AsColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f)),
line->GetParam("cloudUp")->AsColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f)),
@@ -3996,17 +4011,17 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
line->GetParam("dim")->AsFloat(0.2f),
line->GetParam("speed")->AsFloat(0.0f),
line->GetParam("dir")->AsFloat(0.0f),
- line->GetParam("image")->AsPath(""), //TODO: don't make this relative to textures/
+ "../"+line->GetParam("image")->AsPath("textures"),
Math::Point(uv1.x, uv1.z),
Math::Point(uv2.x, uv2.z),
- line->GetParam("image")->AsPath("").find("planet") != std::string::npos // TODO: add transparent op or modify textures
+ line->GetParam("image")->AsPath("textures").find("planet") != std::string::npos // TODO: add transparent op or modify textures
);
continue;
}
if (line->GetCommand() == "ForegroundName" && !resetObject)
{
- m_engine->SetForegroundName(line->GetParam("image")->AsPath("")); //TODO: don't make this relative to textures/
+ m_engine->SetForegroundName("../"+line->GetParam("image")->AsPath("textures"));
continue;
}
@@ -4069,7 +4084,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
pos.z = pos.x;
m_water->Create(line->GetParam("air")->AsWaterType(Gfx::WATER_TT),
line->GetParam("water")->AsWaterType(Gfx::WATER_TT),
- line->GetParam("image")->AsPath(""), //TODO: don't make this relative to textures/
+ "../"+line->GetParam("image")->AsPath("textures"),
line->GetParam("diffuse")->AsColor(Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
line->GetParam("ambient")->AsColor(Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
line->GetParam("level")->AsFloat(100.0f)*g_unit,
@@ -4088,7 +4103,10 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
if (line->GetCommand() == "TerrainCloud" && !resetObject)
{
- m_cloud->Create(line->GetParam("image")->AsPath("", ""), //TODO: don't make this relative to textures/
+ std::string path = "";
+ if(line->GetParam("image")->IsDefined())
+ path = "../"+line->GetParam("image")->AsPath("textures");
+ m_cloud->Create(path,
line->GetParam("diffuse")->AsColor(Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
line->GetParam("ambient")->AsColor(Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
line->GetParam("level")->AsFloat(500.0f)*g_unit);
@@ -4105,7 +4123,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
if (line->GetCommand() == "TerrainInitTextures" && !resetObject)
{
- std::string name = line->GetParam("image")->AsPath(""); //TODO: don't make this relative to textures/
+ std::string name = "../"+line->GetParam("image")->AsPath("textures");
if(name.find(".") == std::string::npos)
name += ".png";
unsigned int dx = line->GetParam("dx")->AsInt(1);
@@ -4136,11 +4154,6 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
}
}
- /*TODO: ???
- if (strstr(name, "%user%") != 0)
- CopyFileListToTemp(name, tt, dx*dy);
- */
-
m_terrain->InitTextures(name.c_str(), tt, dx, dy);
continue;
}
@@ -4153,15 +4166,10 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
if (line->GetCommand() == "TerrainMaterial" && !resetObject)
{
- std::string name = line->GetParam("image")->AsPath(""); //TODO: don't make this relative to textures/
+ std::string name = line->GetParam("image")->AsPath("textures");
if(name.find(".") == std::string::npos)
name += ".png";
- /*TODO: ???
- if (strstr(name, "%user%") != 0)
- {
- GetProfile().CopyFileToTemp(std::string(name));
- }
- */
+ name = "../"+name;
m_terrain->AddMaterial(line->GetParam("id")->AsInt(0),
name.c_str(),
@@ -4229,7 +4237,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
CBrain* brain = m_controller->GetBrain();
if (brain != nullptr)
{
- std::string name = line->GetParam("script")->AsPath(""); //TODO: Don't make this relative to ai/
+ std::string name = "../"+line->GetParam("script")->AsPath("ai");
if (!name.empty())
brain->SetScriptName(0, const_cast<char*>(name.c_str()));
brain->SetScriptRun(0);
@@ -4394,7 +4402,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
{
std::string op = "script"+boost::lexical_cast<std::string>(i+1); // script1..script10
if(line->GetParam(op)->IsDefined()) {
- brain->SetScriptName(i, const_cast<char*>(line->GetParam(op)->AsPath("").c_str())); //TODO: don't make this relative to ai/
+ brain->SetScriptName(i, const_cast<char*>(("../"+line->GetParam(op)->AsPath("ai")).c_str()));
}
}
@@ -4416,7 +4424,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
std::string op = "autoValue"+boost::lexical_cast<std::string>(i+1); // autoValue1..autoValue5
automat->SetValue(i, line->GetParam(op)->AsFloat(0.0f));
}
- automat->SetString(const_cast<char*>(line->GetParam("autoString")->AsString("").c_str()));
+ automat->SetString(const_cast<char*>(line->GetParam("autoString")->AsPath("ai", "").c_str()));
int i = line->GetParam("run")->AsInt(-1);
if (i != -1)
@@ -4539,7 +4547,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
if (m_mapImage)
{
Math::Vector offset;
- strcpy(m_mapFilename, line->GetParam("filename")->AsPath("").c_str()); //TODO: don't make this relative to textures/
+ strcpy(m_mapFilename, ("../"+line->GetParam("filename")->AsPath("textures")).c_str());
offset = line->GetParam("offset")->AsPoint(Math::Vector(0.0f, 0.0f, 0.0f));
m_map->SetFixParam(line->GetParam("zoom")->AsFloat(1.0f),
offset.x, offset.z,
@@ -4675,13 +4683,11 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
if (line->GetCommand() == "NewScript" && !resetObject)
{
- char name[200];
- strcpy(name, line->GetParam("name")->AsPath("").c_str()); //TODO: don't make this relative to ai/
- AddNewScriptName(line->GetParam("type")->AsObjectType(OBJECT_NULL), name);
+ AddNewScriptName(line->GetParam("type")->AsObjectType(OBJECT_NULL), const_cast<char*>(line->GetParam("name")->AsPath("ai").c_str()));
continue;
}
- if(read[0] != 0) continue; // ignore errors when loading saevd game (TODO: don't report ones that are just not loaded when loading saved game)
+ if(read[0] != 0) continue; // ignore errors when loading saved game (TODO: don't report ones that are just not loaded when loading saved game)
if(resetObject) continue; // ignore when reseting just objects (TODO: see above)
throw CLevelParserException("Unknown command: '"+line->GetCommand()+"' in "+line->GetLevel()->GetFilename()+":"+boost::lexical_cast<std::string>(line->GetLineNumber()));
@@ -5459,9 +5465,12 @@ void CRobotMain::LoadFileScript(CObject *obj, const char* filename, int objRank,
ObjectType type = obj->GetType();
if (type == OBJECT_HUMAN) return;
-
+
+ std::string fnstr = filename;
+ boost::replace_all(fnstr, m_dialog->GetSavegameDir(), m_dialog->GetPHYSFSSavegameDir()); //TODO: Refactor to get physfs path here
+ //TODO: Refactor to std::string
char fn[MAX_FNAME];
- strcpy(fn, filename);
+ strcpy(fn, fnstr.c_str());
char* ldir = SearchLastDir(fn);
if (ldir == 0) return;
@@ -5528,8 +5537,11 @@ void CRobotMain::SaveFileScript(CObject *obj, const char* filename, int objRank)
ObjectType type = obj->GetType();
if (type == OBJECT_HUMAN) return;
+ std::string fnstr = filename;
+ boost::replace_all(fnstr, m_dialog->GetSavegameDir(), m_dialog->GetPHYSFSSavegameDir()); //TODO: Refactor to get physfs path here
+ //TODO: Refactor to std::string
char fn[MAX_FNAME];
- strcpy(fn, filename);
+ strcpy(fn, fnstr.c_str());
char* ldir = SearchLastDir(fn);
if (ldir == 0) return;
diff --git a/src/ui/maindialog.cpp b/src/ui/maindialog.cpp
index fe40609..6c25902 100644
--- a/src/ui/maindialog.cpp
+++ b/src/ui/maindialog.cpp
@@ -322,6 +322,21 @@ void CMainDialog::ChangePhase(Phase phase)
ddim.x = 0.09f;
pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_USER);
pb->SetState(STATE_SHADOW);
+
+ try {
+ CLevelParser* level = new CLevelParser("levels/custom/config.txt");
+ if(level->Exists()) {
+ level->Load();
+ CLevelParserLine* line = level->Get("Button");
+ if(line->GetParam("name")->IsDefined())
+ pb->SetName(line->GetParam("name")->AsString());
+ if(line->GetParam("tooltip")->IsDefined())
+ pb->SetTooltip(line->GetParam("tooltip")->AsString());
+ }
+ }
+ catch(CLevelParserException& e) {
+ CLogger::GetInstancePointer()->Error("Failed loading userlevel button name: %s\n", e.what());
+ }
}
/*pos.x = 139.0f/640.0f;
@@ -953,6 +968,9 @@ void CMainDialog::ChangePhase(Phase phase)
pb->SetState(STATE_SHADOW);
pb->SetState(STATE_CARD);
pb->SetState(STATE_CHECK, (m_phase == PHASE_SETUPd || m_phase == PHASE_SETUPds));
+ #if PLATFORM_WINDOWS
+ pb->SetState(STATE_ENABLE, !m_bSimulSetup);
+ #endif
pos.x += ddim.x+0.01f;
pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPg);
@@ -1035,6 +1053,14 @@ void CMainDialog::ChangePhase(Phase phase)
pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_FULL);
pc->SetState(STATE_SHADOW);
pc->SetState(STATE_CHECK, m_setupFull);
+
+ #if !PLATFORM_LINUX
+ ddim.x = 0.9f;
+ ddim.y = 0.1f;
+ pos.x = 0.05f;
+ pos.y = 0.20f;
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, "The game will be restarted in order to apply changes. All unsaved progress will be lost.");
+ #endif
ddim.x = dim.x*6;
ddim.y = dim.y*1;
@@ -1559,7 +1585,7 @@ void CMainDialog::ChangePhase(Phase phase)
m_engine->SetOverColor(Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f), Gfx::ENG_RSTATE_TCOLOR_BLACK); // TODO: color ok?
m_engine->SetOverFront(true);
- m_engine->SetBackground("interface/ppc.png",
+ m_engine->SetBackground("interface/intro1.png",
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
@@ -1578,7 +1604,7 @@ void CMainDialog::ChangePhase(Phase phase)
m_engine->SetOverColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f), Gfx::ENG_RSTATE_TCOLOR_WHITE); // TODO: color ok?
m_engine->SetOverFront(true);
- m_engine->SetBackground("interface/colobot.png",
+ m_engine->SetBackground("interface/intro2.png",
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
@@ -1597,7 +1623,7 @@ void CMainDialog::ChangePhase(Phase phase)
m_engine->SetOverColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f), Gfx::ENG_RSTATE_TCOLOR_WHITE); // TODO: color ok?
m_engine->SetOverFront(true);
- m_engine->SetBackground("interface/epsitec.png",
+ m_engine->SetBackground("interface/intro3.png",
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
@@ -1873,6 +1899,9 @@ bool CMainDialog::EventProcess(const Event &event)
{
StopDialog();
StartSuspend();
+ #if PLATFORM_WINDOWS
+ if ( m_phaseSetup == PHASE_SETUPd ) m_phaseSetup = PHASE_SETUPg;
+ #endif
if ( m_phaseSetup == PHASE_SETUPd ) ChangePhase(PHASE_SETUPds);
if ( m_phaseSetup == PHASE_SETUPg ) ChangePhase(PHASE_SETUPgs);
if ( m_phaseSetup == PHASE_SETUPp ) ChangePhase(PHASE_SETUPps);
@@ -4136,6 +4165,8 @@ void CMainDialog::IOUpdateList()
return;
std::string filename = (m_saveList.at(sel) / "screen.png").make_preferred().string();
+ boost::replace_all(filename, GetSavegameDir(), GetPHYSFSSavegameDir()); //TODO: Refactor everything to PHYSFS, see issue #334
+ filename = "../"+filename;
if ( m_phase == PHASE_WRITE || m_phase == PHASE_WRITEs )
{
if ( sel < max-1 )
@@ -4378,17 +4409,11 @@ void CMainDialog::UpdateSceneChap(int &chap)
CList* pl;
std::string fileName;
- char op[100];
- char op_i18n[100];
char line[500];
- char name[100];
- int i, j;
+ int j;
bool bPassed;
- memset(op, 0, 100);
- memset(op_i18n, 0, 100);
memset(line, 0, 500);
- memset(name, 0, 100);
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
if ( pw == 0 ) return;
@@ -4425,41 +4450,19 @@ void CMainDialog::UpdateSceneChap(int &chap)
{
for ( j=0 ; j<9 ; j++ )
{
- BuildSceneName(fileName, m_sceneName, (j+1)*100);
- CInputStream stream;
- stream.open(fileName);
- if (!stream.is_open()) break;
-
- BuildResumeName(name, m_sceneName, j+1); // default name
- sprintf(op, "Title.E");
- sprintf(op_i18n, "Title.%c", m_app->GetLanguageChar());
-
- while (stream.getline(line, 500))
- {
- for ( i=0 ; i<500 ; i++ )
- {
- if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space
- if ( line[i] == '/' && line[i+1] == '/' )
- {
- line[i] = 0;
- break;
- }
- }
-
- if ( Cmd(line, op) )
- {
- OpString(line, "text", name);
- }
- if ( Cmd(line, op_i18n) )
- {
- OpString(line, "text", name);
- break;
- }
+ CLevelParser* level = new CLevelParser(m_sceneName, j+1, 0);
+ if(!level->Exists())
+ break;
+ try {
+ level->Load();
+ sprintf(line, "%d: %s", j+1, level->Get("Title")->GetParam("text")->AsString().c_str());
+ }
+ catch(CLevelParserException& e) {
+ sprintf(line, "%s", (std::string("[ERROR]: ")+e.what()).c_str());
}
- stream.close();
+ delete level;
bPassed = GetGamerInfoPassed((j+1)*100);
- sprintf(line, "%d: %s", j+1, name);
pl->SetItemName(j, line);
pl->SetCheck(j, bPassed);
pl->SetEnable(j, true);
@@ -4491,17 +4494,11 @@ void CMainDialog::UpdateSceneList(int chap, int &sel)
CWindow* pw;
CList* pl;
std::string fileName;
- char op[100];
- char op_i18n[100];
char line[500];
- char name[100];
- int i, j;
+ int j;
bool bPassed;
- memset(op, 0, 100);
- memset(op_i18n, 0, 100);
memset(line, 0, 500);
- memset(name, 0, 100);
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
if ( pw == 0 ) return;
@@ -4512,68 +4509,45 @@ void CMainDialog::UpdateSceneList(int chap, int &sel)
if(chap < 0) return;
+ bool readAll = true;
for ( j=0 ; j<99 ; j++ )
{
- BuildSceneName(fileName, m_sceneName, (chap+1)*100+(j+1));
-
- CInputStream stream;
- stream.open(fileName);
- if (!stream.is_open()) break;
-
- BuildResumeName(name, m_sceneName, j+1); // default name
- sprintf(op, "Title.E");
- sprintf(op_i18n, "Title.%c", m_app->GetLanguageChar());
-
- while (stream.getline(line, 500))
- {
- for ( i=0 ; i<500 ; i++ )
- {
- if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space
- if ( line[i] == '/' && line[i+1] == '/' )
- {
- line[i] = 0;
- break;
- }
- }
-
- if ( Cmd(line, op) )
- {
- OpString(line, "text", name);
- }
- if ( Cmd(line, op_i18n) )
- {
- OpString(line, "text", name);
+ CLevelParser* level = new CLevelParser(m_sceneName, chap+1, j+1);
+ if(!level->Exists()) {
+ readAll = true;
+ break;
+ } else {
+ if(!readAll)
break;
- }
}
- stream.close();
+ try {
+ level->Load();
+ sprintf(line, "%d: %s", j+1, level->Get("Title")->GetParam("text")->AsString().c_str());
+ }
+ catch(CLevelParserException& e) {
+ sprintf(line, "%s", (std::string("[ERROR]: ")+e.what()).c_str());
+ }
+ delete level;
bPassed = GetGamerInfoPassed((chap+1)*100+(j+1));
- sprintf(line, "%d: %s", j+1, name);
pl->SetItemName(j, line);
pl->SetCheck(j, bPassed);
pl->SetEnable(j, true);
if ( m_phase == PHASE_MISSION && !m_main->GetShowAll() && !bPassed )
{
- j ++;
- break;
+ readAll = false;
}
}
- /* TODO: ?????
- BuildSceneName(fileName, m_sceneName, (chap+1)*100+(j+1));
- file = fopen(fileName.c_str(), "r");
- if ( file == NULL )
+ if(readAll)
{
m_maxList = j;
}
else
{
m_maxList = j+1; // this is not the last!
- fclose(file);
- }*/
- m_maxList = j;
+ }
if ( sel > j-1 ) sel = j-1;
@@ -4716,7 +4690,13 @@ void CMainDialog::ChangeDisplay()
bFull = pc->TestState(STATE_CHECK);
m_setupFull = bFull;
+ SetupMemorize();
+ #if !PLATFORM_LINUX
+ // Windows causes problems, so we'll restart the game
+ // Mac OS was not tested so let's restart just to be sure
+ m_app->Restart();
+ #else
std::vector<Math::IntPoint> modes;
m_app->GetVideoResolutionList(modes, true, true);
@@ -4724,6 +4704,7 @@ void CMainDialog::ChangeDisplay()
config.size = modes[m_setupSelMode];
config.fullScreen = bFull;
m_app->ChangeVideoConfig(config);
+ #endif
}
@@ -6269,7 +6250,7 @@ bool CMainDialog::WriteGamerInfo()
for ( i=0 ; i<MAXSCENE ; i++ )
{
- if ( m_sceneInfo[i].numTry == 0 ) continue;
+ if ( m_sceneInfo[i].numTry == 0 && !m_sceneInfo[i].bPassed ) continue;
sprintf(line, "Chapter %d: Scene %d: numTry=%d passed=%d\n",
i/100, i%100, m_sceneInfo[i].numTry, m_sceneInfo[i].bPassed);