Improve UTF-8 character handling in Atlas
(Also prevents the compile-time warnings reported in the abandoned D1432) Accepted by: Itms Patch linting by: Stan, Vladislav, wraitii Also tested by: Imarok Fixes: #4936 Differential Revision: https://code.wildfiregames.com/D1395 This was SVN commit r22335.
This commit is contained in:
parent
4b65cc0317
commit
800bf0da24
@ -1,8 +1,8 @@
|
||||
{
|
||||
"settings" : {
|
||||
"Name" : "Fields of Meroe",
|
||||
"Name" : "Fields of Meroë",
|
||||
"Script" : "fields_of_meroe.js",
|
||||
"Description" : "The \"Island of Meroe\", a vast peninsula flanked by the Nile and Atbarah rivers, formed the heartland of ancient Kush. Where the harsh deserts start making way for the semi-arid savannahs and small acacia forests dot the landscape. The area is rich in resources and the ever-present Nile brings life, but grave threats loom on the opposite riverbank.",
|
||||
"Description" : "The \"Island of Meroë\", a vast peninsula flanked by the Nile and Atbarah rivers, formed the heartland of ancient Kush. Where the harsh deserts start making way for the semi-arid savannahs and small acacia forests dot the landscape. The area is rich in resources and the ever-present Nile brings life, but grave threats loom on the opposite riverbank.",
|
||||
"Preview" : "fields_of_meroe_dry.png",
|
||||
"Keywords": [],
|
||||
"CircularMap" : true,
|
||||
|
@ -1100,8 +1100,7 @@ function setup_atlas_projects()
|
||||
},{ -- extern_libs
|
||||
"boost",
|
||||
"iconv",
|
||||
"libxml2",
|
||||
"wxwidgets"
|
||||
"libxml2"
|
||||
},{ -- extra_params
|
||||
no_pch = 1
|
||||
})
|
||||
@ -1346,7 +1345,6 @@ function setup_tests()
|
||||
links { "mocks_test" }
|
||||
if _OPTIONS["atlas"] then
|
||||
links { "AtlasObject" }
|
||||
project_add_extern_libs({"wxwidgets"}, target_type)
|
||||
end
|
||||
extra_params = {
|
||||
extra_files = { "test_setup.cpp" },
|
||||
|
@ -28,7 +28,6 @@
|
||||
# define _CRT_SECURE_NO_WARNINGS // Disable deprecation warning in VS2008
|
||||
#endif
|
||||
|
||||
#include <wchar.h> // for wchar_t
|
||||
#include <string>
|
||||
|
||||
class wxString;
|
||||
@ -119,7 +118,7 @@ public:
|
||||
const AtObj operator* () const;
|
||||
|
||||
// Return the string value of the AtObj currently pointed to by this iterator
|
||||
operator const wchar_t* () const;
|
||||
operator const char* () const;
|
||||
|
||||
// Private implementation. (But not 'private:', because it's a waste of time
|
||||
// adding loads of friend functions)
|
||||
@ -137,13 +136,14 @@ public:
|
||||
const AtIter operator[] (const char* key) const;
|
||||
|
||||
// Return the string value of this object
|
||||
operator const wchar_t* () const;
|
||||
operator const char* () const;
|
||||
|
||||
// Return the floating point value of this object
|
||||
double getDouble() const;
|
||||
|
||||
// Return the integer value of this object
|
||||
int getInt() const;
|
||||
long getLong() const;
|
||||
|
||||
// Check whether the object contains anything (even if those things are empty)
|
||||
bool defined() const { return static_cast<bool>(m_Node); }
|
||||
@ -151,22 +151,20 @@ public:
|
||||
// Check recursively whether there's actually any non-empty data in the object
|
||||
bool hasContent() const;
|
||||
|
||||
// Add or set a child. The wchar_t* and wxString& versions create a new
|
||||
// AtObj with the appropriate string value, then use that as the child.
|
||||
// Add or set a child. The char* version creates a new AtObj with
|
||||
// the appropriate string value, then uses that as the child.
|
||||
//
|
||||
// These alter the AtObj's internal pointer, and the pointed-to data is
|
||||
// never actually altered. Copies of this AtObj (including copies stored
|
||||
// inside other AtObjs) will not be affected.
|
||||
void add(const char* key, const wchar_t* value);
|
||||
void add(const char* key, const wxString& value);
|
||||
void add(const char* key, const char* value);
|
||||
void add(const char* key, AtObj& data);
|
||||
void set(const char* key, const wchar_t* value);
|
||||
void set(const char* key, const wxString& value);
|
||||
void set(const char* key, const char* value);
|
||||
void set(const char* key, AtObj& data);
|
||||
void setBool(const char* key, bool value);
|
||||
void setDouble(const char* key, double value);
|
||||
void setInt(const char* key, int value);
|
||||
void setString(const wchar_t* value);
|
||||
void setString(const char* value);
|
||||
void addOverlay(AtObj& data);
|
||||
|
||||
AtSmartPtr<const AtNode> m_Node;
|
||||
|
@ -21,8 +21,6 @@
|
||||
#include <assert.h>
|
||||
#include <sstream>
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
#define ATSMARTPTR_IMPL(T) \
|
||||
template<> void AtSmartPtr<T>::inc_ref() \
|
||||
{ \
|
||||
@ -53,12 +51,9 @@ const AtIter AtIter::operator [] (const char* key) const
|
||||
return AtIter();
|
||||
}
|
||||
|
||||
AtIter::operator const wchar_t* () const
|
||||
AtIter::operator const char* () const
|
||||
{
|
||||
if (m_Impl)
|
||||
return m_Impl->iter->second->m_Value.c_str();
|
||||
else
|
||||
return L"";
|
||||
return m_Impl ? m_Impl->iter->second->m_Value.c_str() : "";
|
||||
}
|
||||
|
||||
//AtIter::operator const AtObj () const
|
||||
@ -122,23 +117,16 @@ const AtIter AtObj::operator [] (const char* key) const
|
||||
return AtIter();
|
||||
}
|
||||
|
||||
AtObj::operator const wchar_t* () const
|
||||
AtObj::operator const char* () const
|
||||
{
|
||||
if (m_Node)
|
||||
return m_Node->m_Value.c_str();
|
||||
else
|
||||
return L"";
|
||||
return m_Node ? m_Node->m_Value.c_str() : "";
|
||||
}
|
||||
|
||||
double AtObj::getDouble() const
|
||||
{
|
||||
double val = 0;
|
||||
if (m_Node)
|
||||
{
|
||||
std::wstringstream s;
|
||||
s << m_Node->m_Value;
|
||||
s >> val;
|
||||
}
|
||||
static_cast<std::stringstream>(m_Node->m_Value) >> val;
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -146,11 +134,15 @@ int AtObj::getInt() const
|
||||
{
|
||||
int val = 0;
|
||||
if (m_Node)
|
||||
{
|
||||
std::wstringstream s;
|
||||
s << m_Node->m_Value;
|
||||
s >> val;
|
||||
}
|
||||
static_cast<std::stringstream>(m_Node->m_Value) >> val;
|
||||
return val;
|
||||
}
|
||||
|
||||
long AtObj::getLong() const
|
||||
{
|
||||
long val = 0;
|
||||
if (m_Node)
|
||||
static_cast<std::stringstream>(m_Node->m_Value) >> val;
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -162,12 +154,7 @@ void AtObj::add(const char* key, AtObj& data)
|
||||
m_Node = m_Node->addChild(key, data.m_Node);
|
||||
}
|
||||
|
||||
void AtObj::add(const char* key, const wxString& value)
|
||||
{
|
||||
add(key, value.wc_str());
|
||||
}
|
||||
|
||||
void AtObj::add(const char* key, const wchar_t* value)
|
||||
void AtObj::add(const char* key, const char* value)
|
||||
{
|
||||
const AtNode* o = new AtNode(value);
|
||||
|
||||
@ -185,12 +172,7 @@ void AtObj::set(const char* key, AtObj& data)
|
||||
m_Node = m_Node->setChild(key, data.m_Node);
|
||||
}
|
||||
|
||||
void AtObj::set(const char* key, const wxString& value)
|
||||
{
|
||||
set(key, value.wc_str());
|
||||
}
|
||||
|
||||
void AtObj::set(const char* key, const wchar_t* value)
|
||||
void AtObj::set(const char* key, const char* value)
|
||||
{
|
||||
const AtNode* o = new AtNode(value);
|
||||
|
||||
@ -202,7 +184,7 @@ void AtObj::set(const char* key, const wchar_t* value)
|
||||
|
||||
void AtObj::setBool(const char* key, bool value)
|
||||
{
|
||||
AtNode* o = new AtNode(value ? L"true" : L"false");
|
||||
AtNode* o = new AtNode(value ? "true" : "false");
|
||||
o->m_Children.insert(AtNode::child_pairtype("@boolean", AtNode::Ptr(new AtNode())));
|
||||
|
||||
if (!m_Node)
|
||||
@ -213,7 +195,7 @@ void AtObj::setBool(const char* key, bool value)
|
||||
|
||||
void AtObj::setDouble(const char* key, double value)
|
||||
{
|
||||
std::wstringstream str;
|
||||
std::stringstream str;
|
||||
str << value;
|
||||
AtNode* o = new AtNode(str.str().c_str());
|
||||
o->m_Children.insert(AtNode::child_pairtype("@number", AtNode::Ptr(new AtNode())));
|
||||
@ -226,7 +208,7 @@ void AtObj::setDouble(const char* key, double value)
|
||||
|
||||
void AtObj::setInt(const char* key, int value)
|
||||
{
|
||||
std::wstringstream str;
|
||||
std::stringstream str;
|
||||
str << value;
|
||||
AtNode* o = new AtNode(str.str().c_str());
|
||||
o->m_Children.insert(AtNode::child_pairtype("@number", AtNode::Ptr(new AtNode())));
|
||||
@ -237,7 +219,7 @@ void AtObj::setInt(const char* key, int value)
|
||||
m_Node = m_Node->setChild(key, AtNode::Ptr(o));
|
||||
}
|
||||
|
||||
void AtObj::setString(const wchar_t* value)
|
||||
void AtObj::setString(const char* value)
|
||||
{
|
||||
if (!m_Node)
|
||||
m_Node = new AtNode();
|
||||
@ -289,7 +271,7 @@ bool AtNode::hasContent() const
|
||||
return false;
|
||||
}
|
||||
|
||||
const AtNode::Ptr AtNode::setValue(const wchar_t* value) const
|
||||
const AtNode::Ptr AtNode::setValue(const char* value) const
|
||||
{
|
||||
AtNode* newNode = new AtNode();
|
||||
newNode->m_Children = m_Children;
|
||||
|
@ -41,11 +41,11 @@ public:
|
||||
|
||||
AtNode() : m_Refcount(0) {}
|
||||
explicit AtNode(const AtNode* n) { *this = *n; m_Refcount = 0; }
|
||||
explicit AtNode(const wchar_t* text) : m_Refcount(0), m_Value(text) {}
|
||||
explicit AtNode(const char* text) : m_Refcount(0), m_Value(text) {}
|
||||
|
||||
// Create a new AtNode (since AtNodes are immutable, so it's not possible
|
||||
// to just change this one), with the relevant alterations to its content.
|
||||
const AtNode::Ptr setValue(const wchar_t* value) const;
|
||||
const AtNode::Ptr setValue(const char* value) const;
|
||||
const AtNode::Ptr addChild(const char* key, const AtNode::Ptr &data) const;
|
||||
const AtNode::Ptr setChild(const char* key, const AtNode::Ptr &data) const;
|
||||
const AtNode::Ptr addOverlay(const AtNode::Ptr &data) const;
|
||||
@ -57,7 +57,7 @@ public:
|
||||
//private: // (but not actually private, since I'm still too lazy to waste
|
||||
// time with dozens of friends)
|
||||
|
||||
std::wstring m_Value;
|
||||
std::string m_Value;
|
||||
|
||||
typedef std::multimap<std::string, AtNode::Ptr> child_maptype;
|
||||
typedef std::pair<std::string, AtNode::Ptr> child_pairtype;
|
||||
|
@ -24,8 +24,6 @@
|
||||
# pragma warning(disable:4996) // deprecated CRT
|
||||
#endif
|
||||
|
||||
#include "wx/log.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
static AtSmartPtr<AtNode> ConvertNode(json_spirit::Value node);
|
||||
@ -47,11 +45,11 @@ static AtSmartPtr<AtNode> ConvertNode(json_spirit::Value node)
|
||||
|
||||
if (node.type() == json_spirit::str_type)
|
||||
{
|
||||
obj->m_Value = std::wstring(node.get_str().begin(),node.get_str().end());
|
||||
obj->m_Value = node.get_str();
|
||||
}
|
||||
else if (node.type() == json_spirit::int_type || node.type() == json_spirit::real_type)
|
||||
{
|
||||
std::wstringstream stream;
|
||||
std::stringstream stream;
|
||||
if (node.type() == json_spirit::int_type)
|
||||
stream << node.get_int();
|
||||
if (node.type() == json_spirit::real_type)
|
||||
@ -64,10 +62,7 @@ static AtSmartPtr<AtNode> ConvertNode(json_spirit::Value node)
|
||||
}
|
||||
else if (node.type() == json_spirit::bool_type)
|
||||
{
|
||||
if (node.get_bool())
|
||||
obj->m_Value = L"true";
|
||||
else
|
||||
obj->m_Value = L"false";
|
||||
obj->m_Value = node.get_bool() ? "true" : "false";
|
||||
|
||||
obj->m_Children.insert(AtNode::child_pairtype(
|
||||
"@boolean", AtSmartPtr<AtNode>(new AtNode())
|
||||
@ -125,10 +120,8 @@ json_spirit::Value BuildJSONNode(AtNode::Ptr p)
|
||||
if (p->m_Children.count("@number"))
|
||||
{
|
||||
// Convert to double
|
||||
std::wstringstream str;
|
||||
str << p->m_Value;
|
||||
double val = 0;
|
||||
str >> val;
|
||||
static_cast<std::stringstream>(p->m_Value) >> val;
|
||||
|
||||
json_spirit::Value rval(val);
|
||||
return rval;
|
||||
@ -136,7 +129,7 @@ json_spirit::Value BuildJSONNode(AtNode::Ptr p)
|
||||
else if (p->m_Children.count("@boolean"))
|
||||
{
|
||||
bool val = false;
|
||||
if (p->m_Value == L"true")
|
||||
if (p->m_Value == "true")
|
||||
val = true;
|
||||
|
||||
json_spirit::Value rval(val);
|
||||
@ -146,7 +139,7 @@ json_spirit::Value BuildJSONNode(AtNode::Ptr p)
|
||||
// If no children, then use the value string instead
|
||||
if (p->m_Children.empty())
|
||||
{
|
||||
json_spirit::Value rval(std::string(p->m_Value.begin(), p->m_Value.end()));
|
||||
json_spirit::Value rval(p->m_Value);
|
||||
return rval;
|
||||
}
|
||||
|
||||
@ -190,5 +183,5 @@ json_spirit::Value BuildJSONNode(AtNode::Ptr p)
|
||||
std::string AtlasObject::SaveToJSON(AtObj& obj)
|
||||
{
|
||||
json_spirit::Value root = BuildJSONNode(obj.m_Node);
|
||||
return json_spirit::write_string(root, 0);
|
||||
return json_spirit::write_string(root, json_spirit::raw_utf8);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "AtlasObjectImpl.h"
|
||||
#include "AtlasObject.h"
|
||||
|
||||
static std::wstring ConvertRecursive(const AtNode::Ptr obj, bool use_brackets = true)
|
||||
static std::string ConvertRecursive(const AtNode::Ptr obj, bool use_brackets = true)
|
||||
{
|
||||
// Convert (1, ()) into "1"
|
||||
// Convert (3, (d: (...), e: (...))) into "3 (conv(...), conv(...))"
|
||||
@ -27,31 +27,31 @@ static std::wstring ConvertRecursive(const AtNode::Ptr obj, bool use_brackets =
|
||||
// resulting in data-loss [because of the key names], and a rather arbitrary
|
||||
// [alphabetical by key] ordering of children, but at least it's fairly readable
|
||||
|
||||
if (! obj)
|
||||
return L"";
|
||||
if (!obj)
|
||||
return "";
|
||||
|
||||
std::wstring result;
|
||||
std::string result;
|
||||
|
||||
bool has_value = !obj->m_Value.empty();
|
||||
bool has_children = !obj->m_Children.empty();
|
||||
|
||||
if (has_value && has_children)
|
||||
result = obj->m_Value + L" ";
|
||||
result = obj->m_Value + " ";
|
||||
else if (has_value)
|
||||
result = obj->m_Value;
|
||||
// else no value; result = L""
|
||||
// else no value; result = ""
|
||||
|
||||
if (has_children)
|
||||
{
|
||||
if (use_brackets)
|
||||
result += L"(";
|
||||
result += "(";
|
||||
|
||||
bool first_child = true; // so we can add ", " in appropriate places
|
||||
|
||||
for (const AtNode::child_maptype::value_type& child : obj->m_Children)
|
||||
{
|
||||
if (!first_child)
|
||||
result += L", ";
|
||||
result += ", ";
|
||||
else
|
||||
first_child = false;
|
||||
|
||||
@ -59,13 +59,13 @@ static std::wstring ConvertRecursive(const AtNode::Ptr obj, bool use_brackets =
|
||||
}
|
||||
|
||||
if (use_brackets)
|
||||
result += L")";
|
||||
result += ")";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring AtlasObject::ConvertToString(const AtObj& obj)
|
||||
std::string AtlasObject::ConvertToString(const AtObj& obj)
|
||||
{
|
||||
return ConvertRecursive(obj.m_Node, false);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2009 Wildfire Games.
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -15,18 +15,12 @@
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Public interface to text-related functions that make use of std::wstring
|
||||
// Public interface to text-related functions that make use of std::string
|
||||
//
|
||||
// (This is done in order to avoid forcing inclusion of all the
|
||||
// STL headers when they're not needed)
|
||||
|
||||
//#ifdef new // HACK: to make the STL headers happy with a redefined 'new'
|
||||
//# undef new
|
||||
//# include <string>
|
||||
//# define new new(_NORMAL_BLOCK ,__FILE__, __LINE__)
|
||||
//#else
|
||||
# include <string>
|
||||
//#endif
|
||||
|
||||
class AtObj;
|
||||
|
||||
@ -35,5 +29,5 @@ namespace AtlasObject
|
||||
// Generate a human-readable string representation of the AtObj,
|
||||
// as an easy way of visualising the data (without any horridly ugly
|
||||
// XML junk)
|
||||
std::wstring ConvertToString(const AtObj& obj);
|
||||
std::string ConvertToString(const AtObj& obj);
|
||||
}
|
||||
|
@ -26,89 +26,6 @@
|
||||
|
||||
#include <libxml/parser.h>
|
||||
|
||||
// UTF conversion code adapted from http://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c
|
||||
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||
static const char trailingBytesForUTF8[256] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
|
||||
static const unsigned long offsetsFromUTF8[6] = {
|
||||
0x00000000UL, 0x00003080UL, 0x000E2080UL,
|
||||
0x03C82080UL, 0xFA082080UL, 0x82082080UL };
|
||||
class toXmlChar
|
||||
{
|
||||
public:
|
||||
toXmlChar(const std::wstring& str)
|
||||
{
|
||||
for(wchar_t ch : str)
|
||||
{
|
||||
unsigned short bytesToWrite;
|
||||
|
||||
if (ch < 0x80) bytesToWrite = 1;
|
||||
else if (ch < 0x800) bytesToWrite = 2;
|
||||
else if (ch < 0x10000) bytesToWrite = 3;
|
||||
else if (ch < 0x110000) bytesToWrite = 4;
|
||||
else bytesToWrite = 3, ch = 0xFFFD; // replacement character
|
||||
|
||||
char buf[4];
|
||||
char* target = &buf[bytesToWrite];
|
||||
// GCC sometimes warns "array subscript is above array bounds [-Warray-bounds]"
|
||||
// for the above line, which is a false positive - the C++ standard allows a
|
||||
// pointer to just after the last element in an array, as long as it's not
|
||||
// dereferenced (which it isn't here)
|
||||
switch (bytesToWrite)
|
||||
{
|
||||
case 4: *--target = ((ch | 0x80) & 0xBF); ch >>= 6;
|
||||
case 3: *--target = ((ch | 0x80) & 0xBF); ch >>= 6;
|
||||
case 2: *--target = ((ch | 0x80) & 0xBF); ch >>= 6;
|
||||
case 1: *--target = (char)(ch | firstByteMark[bytesToWrite]);
|
||||
}
|
||||
data += std::string(buf, bytesToWrite);
|
||||
}
|
||||
}
|
||||
operator const xmlChar*()
|
||||
{
|
||||
return (const xmlChar*)data.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string data;
|
||||
};
|
||||
|
||||
std::wstring fromXmlChar(const xmlChar* str)
|
||||
{
|
||||
std::wstring result;
|
||||
const xmlChar* source = str;
|
||||
const xmlChar* sourceEnd = str + strlen((const char*)str);
|
||||
while (source < sourceEnd)
|
||||
{
|
||||
unsigned long ch = 0;
|
||||
int extraBytesToRead = trailingBytesForUTF8[*source];
|
||||
assert(source + extraBytesToRead < sourceEnd);
|
||||
switch (extraBytesToRead)
|
||||
{
|
||||
case 5: ch += *source++; ch <<= 6;
|
||||
case 4: ch += *source++; ch <<= 6;
|
||||
case 3: ch += *source++; ch <<= 6;
|
||||
case 2: ch += *source++; ch <<= 6;
|
||||
case 1: ch += *source++; ch <<= 6;
|
||||
case 0: ch += *source++;
|
||||
}
|
||||
ch -= offsetsFromUTF8[extraBytesToRead];
|
||||
// Make sure it fits in a 16-bit wchar_t
|
||||
if (ch > 0xFFFF)
|
||||
ch = 0xFFFD;
|
||||
|
||||
result += (wchar_t)ch;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// TODO: replace most of the asserts below (e.g. for when it fails to load
|
||||
// a file) with some proper logging/reporting system
|
||||
|
||||
@ -142,9 +59,9 @@ static AtSmartPtr<AtNode> ConvertNode(xmlNodePtr node)
|
||||
for (xmlAttrPtr cur_attr = node->properties; cur_attr; cur_attr = cur_attr->next)
|
||||
{
|
||||
std::string name ("@");
|
||||
name += (const char*)cur_attr->name;
|
||||
name += reinterpret_cast<const char*>(cur_attr->name);
|
||||
xmlChar* content = xmlNodeGetContent(cur_attr->children);
|
||||
std::wstring value (fromXmlChar(content));
|
||||
std::string value = reinterpret_cast<char*>(content);
|
||||
xmlFree(content);
|
||||
|
||||
AtNode* newNode = new AtNode(value.c_str());
|
||||
@ -159,23 +76,23 @@ static AtSmartPtr<AtNode> ConvertNode(xmlNodePtr node)
|
||||
if (cur_node->type == XML_ELEMENT_NODE)
|
||||
{
|
||||
obj->m_Children.insert(AtNode::child_pairtype(
|
||||
(const char*)cur_node->name, ConvertNode(cur_node)
|
||||
reinterpret_cast<const char*>(cur_node->name), ConvertNode(cur_node)
|
||||
));
|
||||
}
|
||||
else if (cur_node->type == XML_TEXT_NODE)
|
||||
{
|
||||
xmlChar* content = xmlNodeGetContent(cur_node);
|
||||
std::wstring value (fromXmlChar(content));
|
||||
std::string value = reinterpret_cast<char*>(content);
|
||||
xmlFree(content);
|
||||
obj->m_Value += value;
|
||||
}
|
||||
}
|
||||
|
||||
// Trim whitespace surrounding the string value
|
||||
const std::wstring whitespace = L" \t\r\n";
|
||||
const std::string whitespace = " \t\r\n";
|
||||
size_t first = obj->m_Value.find_first_not_of(whitespace);
|
||||
if (first == std::wstring::npos)
|
||||
obj->m_Value = L"";
|
||||
if (first == std::string::npos)
|
||||
obj->m_Value = "";
|
||||
else
|
||||
{
|
||||
size_t last = obj->m_Value.find_last_not_of(whitespace);
|
||||
@ -191,7 +108,7 @@ static void BuildDOMNode(xmlDocPtr doc, xmlNodePtr node, AtNode::Ptr p)
|
||||
if (p)
|
||||
{
|
||||
if (p->m_Value.length())
|
||||
xmlNodeAddContent(node, toXmlChar(p->m_Value));
|
||||
xmlNodeAddContent(node, reinterpret_cast<const xmlChar*>(p->m_Value.c_str()));
|
||||
|
||||
for (const AtNode::child_maptype::value_type& child : p->m_Children)
|
||||
{
|
||||
@ -202,7 +119,7 @@ static void BuildDOMNode(xmlDocPtr doc, xmlNodePtr node, AtNode::Ptr p)
|
||||
{
|
||||
assert(child.second);
|
||||
assert(child.second->m_Children.empty());
|
||||
xmlNewProp(node, first_child + 1, toXmlChar(child.second->m_Value));
|
||||
xmlNewProp(node, first_child + 1, reinterpret_cast<const xmlChar*>(child.second->m_Value.c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2009 Wildfire Games.
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -141,7 +141,7 @@ public:
|
||||
try_parse_save(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?><foo>�𐀀</foo>",
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
||||
"<foo>\xEF\xBF\xBC\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD</foo>\n"
|
||||
"<foo>\xEF\xBF\xBC\xEF\xBF\xBD\xF0\x90\x80\x80\xF4\x8F\xBF\xBF</foo>\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2014 Wildfire Games.
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -17,6 +17,8 @@
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include "ActorEditor.h"
|
||||
|
||||
#include "ActorEditorListCtrl.h"
|
||||
@ -123,10 +125,10 @@ AtObj ActorEditor::FreezeData()
|
||||
AtObj actor (m_ActorEditorListCtrl->FreezeData());
|
||||
|
||||
if (m_CastShadows->IsChecked())
|
||||
actor.set("castshadow", L"");
|
||||
actor.set("castshadow", "");
|
||||
|
||||
if (m_Float->IsChecked())
|
||||
actor.set("float", L"");
|
||||
actor.set("float", "");
|
||||
|
||||
if (m_Material->GetValue().length())
|
||||
actor.set("material", m_Material->GetValue());
|
||||
@ -142,7 +144,7 @@ static AtObj ConvertToLatestFormat(AtObj in)
|
||||
{
|
||||
// 'Importing' a new blank file. Fill it in with default values:
|
||||
AtObj actor;
|
||||
actor.add("@version", L"1");
|
||||
actor.add("@version", "1");
|
||||
in.add("actor", actor);
|
||||
}
|
||||
|
||||
@ -155,12 +157,7 @@ static AtObj ConvertToLatestFormat(AtObj in)
|
||||
version = -1;
|
||||
}
|
||||
else if (in["actor"].defined())
|
||||
{
|
||||
if (in["actor"]["@version"].defined())
|
||||
wxString(in["actor"]["@version"]).ToLong(&version);
|
||||
else
|
||||
version = 0;
|
||||
}
|
||||
version = (in["actor"]["@version"].defined()) ? (*in["actor"]["@version"]).getLong() : 0;
|
||||
else
|
||||
{
|
||||
wxLogError(_("Failed to determine actor file format version"));
|
||||
@ -175,47 +172,44 @@ static AtObj ConvertToLatestFormat(AtObj in)
|
||||
AtObj actor;
|
||||
|
||||
// Handle the global actor properties
|
||||
if (wxString(in["Object"]["Properties"]["@autoflatten"]) == _T("1"))
|
||||
actor.add("autoflatten", L"");
|
||||
if (in["Object"]["Properties"]["@autoflatten"] == "1")
|
||||
actor.add("autoflatten", "");
|
||||
|
||||
if (wxString(in["Object"]["Properties"]["@castshadows"]) == _T("1"))
|
||||
actor.add("castshadow", L"");
|
||||
if (in["Object"]["Properties"]["@castshadows"] == "1")
|
||||
actor.add("castshadow", "");
|
||||
|
||||
// Things to strip leading strings (for converting filenames, since the
|
||||
// new format doesn't store the entire path)
|
||||
#define THING1(out,outname, in,inname, prefix) \
|
||||
wxASSERT( wxString(in["Object"][inname]).StartsWith(_T(prefix)) ); \
|
||||
out.add(outname, wxString(in["Object"][inname]).Mid(wxString(_T(prefix)).Length()))
|
||||
wxASSERT( wxString::FromUTF8(in["Object"][inname]).StartsWith(_T(prefix)) ); \
|
||||
out.add(outname, wxString::FromUTF8(in["Object"][inname]).Mid(wxString(_T(prefix)).Length()))
|
||||
#define THING2(out,outname, in,inname, prefix) \
|
||||
wxASSERT( wxString(in[inname]).StartsWith(_T(prefix)) ); \
|
||||
out.add(outname, wxString(in[inname]).Mid(wxString(_T(prefix)).Length()))
|
||||
wxASSERT( wxString::FromUTF8(in[inname]).StartsWith(_T(prefix)) ); \
|
||||
out.add(outname, wxString::FromUTF8(in[inname]).Mid(wxString(_T(prefix)).Length()))
|
||||
|
||||
if (wxString(in["Object"]["Material"]).Len())
|
||||
if (wxString::FromUTF8(in["Object"]["Material"]).Len())
|
||||
{
|
||||
THING1(actor,"material", in,"Material", "art/materials/");
|
||||
}
|
||||
|
||||
// Create a single variant to contain all the old data
|
||||
AtObj var;
|
||||
var.add("@name", L"Base");
|
||||
var.add("@frequency", L"100"); // 100 == default frequency
|
||||
var.add("@name", "Base");
|
||||
var.add("@frequency", "100"); // 100 == default frequency
|
||||
|
||||
THING1(var,"mesh", in,"ModelName", "art/meshes/");
|
||||
|
||||
// XXX
|
||||
if (wxString(in["Object"]["TextureName"]).StartsWith(_T("art/textures/ui/session/portraits/ui_portrait_sheet_civ_")))
|
||||
{
|
||||
var.add("texture", L"temp/" + wxString(in["Object"]["TextureName"]).Mid(strlen("art/textures/ui/session/portraits/")));
|
||||
}
|
||||
std::string textureName(in["Object"]["TextureName"]);
|
||||
if (boost::algorithm::starts_with(textureName, "art/textures/ui/session/portraits/ui_portrait_sheet_civ_"))
|
||||
var.add("texture", ("temp/" + textureName.substr(strlen("art/textures/ui/session/portraits/"))).c_str());
|
||||
else
|
||||
{
|
||||
THING1(var,"texture", in,"TextureName", "art/textures/skins/");
|
||||
}
|
||||
|
||||
AtObj anims;
|
||||
for (AtIter animit = in["Object"]["Animations"]["Animation"]; animit.defined(); ++animit)
|
||||
{
|
||||
if (wcslen(animit["@file"]))
|
||||
if (strlen(animit["@file"]))
|
||||
{
|
||||
AtObj anim;
|
||||
anim.add("@name", animit["@name"]);
|
||||
@ -245,7 +239,7 @@ static AtObj ConvertToLatestFormat(AtObj in)
|
||||
#undef THING1
|
||||
#undef THING2
|
||||
|
||||
actor.set("@version", L"1");
|
||||
actor.set("@version", "1");
|
||||
in = AtObj();
|
||||
in.set("actor", actor);
|
||||
}
|
||||
@ -295,7 +289,7 @@ static AtObj ConvertToLatestFormat(AtObj in)
|
||||
actor.add("group", grp);
|
||||
}
|
||||
|
||||
actor.set("@version", L"1");
|
||||
actor.set("@version", "1");
|
||||
in.set("actor", actor);
|
||||
}
|
||||
else if (version == 1)
|
||||
@ -333,13 +327,13 @@ AtObj ActorEditor::ExportData()
|
||||
// Export the group/variant/etc data
|
||||
AtObj actor (m_ActorEditorListCtrl->ExportData());
|
||||
|
||||
actor.set("@version", L"1");
|
||||
actor.set("@version", "1");
|
||||
|
||||
if (m_CastShadows->IsChecked())
|
||||
actor.set("castshadow", L"");
|
||||
actor.set("castshadow", "");
|
||||
|
||||
if (m_Float->IsChecked())
|
||||
actor.set("float", L"");
|
||||
actor.set("float", "");
|
||||
|
||||
if (m_Material->GetValue().length())
|
||||
actor.set("material", m_Material->GetValue());
|
||||
|
@ -514,7 +514,7 @@ ScenarioEditor::ScenarioEditor(wxWindow* parent)
|
||||
menuHelp->Append(ID_##id, _(wxString(data[#id]["title"])), _(wxString(data[#id]["tooltip"]))); \
|
||||
m_HelpData.insert(std::make_pair( \
|
||||
ID_##id, \
|
||||
HelpItem(wxString(data[#id]["title"]), wxString(data[#id]["tooltip"]), wxString(data[#id]["url"])) \
|
||||
HelpItem(wxString::FromUTF8(data[#id]["title"]), wxString::FromUTF8(data[#id]["tooltip"]), wxString::FromUTF8(data[#id]["url"])) \
|
||||
)); \
|
||||
} while (0)
|
||||
ADD_HELP_ITEM(Manual);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2018 Wildfire Games.
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -112,8 +112,8 @@ private:
|
||||
OnConquestChanged();
|
||||
}
|
||||
|
||||
std::set<std::wstring> m_MapSettingsKeywords;
|
||||
std::set<std::wstring> m_MapSettingsVictoryConditions;
|
||||
std::set<std::string> m_MapSettingsKeywords;
|
||||
std::set<std::string> m_MapSettingsVictoryConditions;
|
||||
std::vector<wxChoice*> m_PlayerCivChoices;
|
||||
Observable<AtObj>& m_MapSettings;
|
||||
|
||||
@ -203,21 +203,21 @@ void MapSettingsControl::ReadFromEngine()
|
||||
}
|
||||
|
||||
// map name
|
||||
wxDynamicCast(FindWindow(ID_MapName), wxTextCtrl)->ChangeValue(wxString(m_MapSettings["Name"]));
|
||||
wxDynamicCast(FindWindow(ID_MapName), wxTextCtrl)->ChangeValue(wxString::FromUTF8(m_MapSettings["Name"]));
|
||||
|
||||
// map description
|
||||
wxDynamicCast(FindWindow(ID_MapDescription), wxTextCtrl)->ChangeValue(wxString(m_MapSettings["Description"]));
|
||||
wxDynamicCast(FindWindow(ID_MapDescription), wxTextCtrl)->ChangeValue(wxString::FromUTF8(m_MapSettings["Description"]));
|
||||
|
||||
// map preview
|
||||
wxDynamicCast(FindWindow(ID_MapPreview), wxTextCtrl)->ChangeValue(wxString(m_MapSettings["Preview"]));
|
||||
wxDynamicCast(FindWindow(ID_MapPreview), wxTextCtrl)->ChangeValue(wxString::FromUTF8(m_MapSettings["Preview"]));
|
||||
|
||||
// reveal map
|
||||
wxDynamicCast(FindWindow(ID_MapReveal), wxCheckBox)->SetValue(wxString(m_MapSettings["RevealMap"]) == L"true");
|
||||
wxDynamicCast(FindWindow(ID_MapReveal), wxCheckBox)->SetValue(wxString::FromUTF8(m_MapSettings["RevealMap"]) == "true");
|
||||
|
||||
// victory conditions
|
||||
m_MapSettingsVictoryConditions.clear();
|
||||
for (AtIter victoryCondition = m_MapSettings["VictoryConditions"]["item"]; victoryCondition.defined(); ++victoryCondition)
|
||||
m_MapSettingsVictoryConditions.insert(std::wstring(victoryCondition));
|
||||
m_MapSettingsVictoryConditions.insert(std::string(victoryCondition));
|
||||
|
||||
wxWindow* window;
|
||||
#define INIT_CHECKBOX(ID, mapSettings, value) \
|
||||
@ -225,25 +225,25 @@ void MapSettingsControl::ReadFromEngine()
|
||||
if (window != nullptr) \
|
||||
wxDynamicCast(window, wxCheckBox)->SetValue(mapSettings.count(value) != 0);
|
||||
|
||||
INIT_CHECKBOX(ID_VC_Conquest, m_MapSettingsVictoryConditions, L"conquest");
|
||||
INIT_CHECKBOX(ID_VC_ConquestUnits, m_MapSettingsVictoryConditions, L"conquest_units");
|
||||
INIT_CHECKBOX(ID_VC_ConquestStructures, m_MapSettingsVictoryConditions, L"conquest_structures");
|
||||
INIT_CHECKBOX(ID_VC_CaptureTheRelic, m_MapSettingsVictoryConditions, L"capture_the_relic");
|
||||
INIT_CHECKBOX(ID_VC_Wonder, m_MapSettingsVictoryConditions, L"wonder");
|
||||
INIT_CHECKBOX(ID_VC_Regicide, m_MapSettingsVictoryConditions, L"regicide");
|
||||
INIT_CHECKBOX(ID_VC_Conquest, m_MapSettingsVictoryConditions, "conquest");
|
||||
INIT_CHECKBOX(ID_VC_ConquestUnits, m_MapSettingsVictoryConditions, "conquest_units");
|
||||
INIT_CHECKBOX(ID_VC_ConquestStructures, m_MapSettingsVictoryConditions, "conquest_structures");
|
||||
INIT_CHECKBOX(ID_VC_CaptureTheRelic, m_MapSettingsVictoryConditions, "capture_the_relic");
|
||||
INIT_CHECKBOX(ID_VC_Wonder, m_MapSettingsVictoryConditions, "wonder");
|
||||
INIT_CHECKBOX(ID_VC_Regicide, m_MapSettingsVictoryConditions, "regicide");
|
||||
OnConquestChanged();
|
||||
|
||||
// lock teams
|
||||
wxDynamicCast(FindWindow(ID_MapTeams), wxCheckBox)->SetValue(wxString(m_MapSettings["LockTeams"]) == L"true");
|
||||
wxDynamicCast(FindWindow(ID_MapTeams), wxCheckBox)->SetValue(wxString::FromUTF8(m_MapSettings["LockTeams"]) == "true");
|
||||
|
||||
// keywords
|
||||
{
|
||||
m_MapSettingsKeywords.clear();
|
||||
for (AtIter keyword = m_MapSettings["Keywords"]["item"]; keyword.defined(); ++keyword)
|
||||
m_MapSettingsKeywords.insert(std::wstring(keyword));
|
||||
m_MapSettingsKeywords.insert(std::string(keyword));
|
||||
|
||||
INIT_CHECKBOX(ID_MapKW_Demo, m_MapSettingsKeywords, L"demo");
|
||||
INIT_CHECKBOX(ID_MapKW_Naval, m_MapSettingsKeywords, L"naval");
|
||||
INIT_CHECKBOX(ID_MapKW_Demo, m_MapSettingsKeywords, "demo");
|
||||
INIT_CHECKBOX(ID_MapKW_Naval, m_MapSettingsKeywords, "naval");
|
||||
}
|
||||
|
||||
#undef INIT_CHECKBOX
|
||||
@ -276,13 +276,13 @@ void MapSettingsControl::OnConquestChanged()
|
||||
AtObj MapSettingsControl::UpdateSettingsObject()
|
||||
{
|
||||
// map name
|
||||
m_MapSettings.set("Name", wxDynamicCast(FindWindow(ID_MapName), wxTextCtrl)->GetValue());
|
||||
m_MapSettings.set("Name", wxDynamicCast(FindWindow(ID_MapName), wxTextCtrl)->GetValue().utf8_str());
|
||||
|
||||
// map description
|
||||
m_MapSettings.set("Description", wxDynamicCast(FindWindow(ID_MapDescription), wxTextCtrl)->GetValue());
|
||||
m_MapSettings.set("Description", wxDynamicCast(FindWindow(ID_MapDescription), wxTextCtrl)->GetValue().utf8_str());
|
||||
|
||||
// map preview
|
||||
m_MapSettings.set("Preview", wxDynamicCast(FindWindow(ID_MapPreview), wxTextCtrl)->GetValue());
|
||||
m_MapSettings.set("Preview", wxDynamicCast(FindWindow(ID_MapPreview), wxTextCtrl)->GetValue().utf8_str());
|
||||
|
||||
// reveal map
|
||||
m_MapSettings.setBool("RevealMap", wxDynamicCast(FindWindow(ID_MapReveal), wxCheckBox)->GetValue());
|
||||
@ -294,37 +294,37 @@ AtObj MapSettingsControl::UpdateSettingsObject()
|
||||
else \
|
||||
m_MapSettingsVictoryConditions.erase(name);
|
||||
|
||||
INSERT_VICTORY_CONDITION_CHECKBOX(L"conquest", ID_VC_Conquest);
|
||||
INSERT_VICTORY_CONDITION_CHECKBOX(L"conquest_units", ID_VC_ConquestUnits);
|
||||
INSERT_VICTORY_CONDITION_CHECKBOX(L"conquest_structures", ID_VC_ConquestStructures);
|
||||
INSERT_VICTORY_CONDITION_CHECKBOX(L"capture_the_relic", ID_VC_CaptureTheRelic);
|
||||
INSERT_VICTORY_CONDITION_CHECKBOX(L"wonder", ID_VC_Wonder);
|
||||
INSERT_VICTORY_CONDITION_CHECKBOX(L"regicide", ID_VC_Regicide);
|
||||
INSERT_VICTORY_CONDITION_CHECKBOX("conquest", ID_VC_Conquest);
|
||||
INSERT_VICTORY_CONDITION_CHECKBOX("conquest_units", ID_VC_ConquestUnits);
|
||||
INSERT_VICTORY_CONDITION_CHECKBOX("conquest_structures", ID_VC_ConquestStructures);
|
||||
INSERT_VICTORY_CONDITION_CHECKBOX("capture_the_relic", ID_VC_CaptureTheRelic);
|
||||
INSERT_VICTORY_CONDITION_CHECKBOX("wonder", ID_VC_Wonder);
|
||||
INSERT_VICTORY_CONDITION_CHECKBOX("regicide", ID_VC_Regicide);
|
||||
|
||||
#undef INSERT_VICTORY_CONDITION_CHECKBOX
|
||||
|
||||
AtObj victoryConditions;
|
||||
victoryConditions.set("@array", L"");
|
||||
for (std::set<std::wstring>::iterator it = m_MapSettingsVictoryConditions.begin(); it != m_MapSettingsVictoryConditions.end(); ++it)
|
||||
victoryConditions.add("item", it->c_str());
|
||||
victoryConditions.set("@array", "");
|
||||
for (const std::string& victoryCondition : m_MapSettingsVictoryConditions)
|
||||
victoryConditions.add("item", victoryCondition.c_str());
|
||||
m_MapSettings.set("VictoryConditions", victoryConditions);
|
||||
|
||||
// keywords
|
||||
{
|
||||
if (wxDynamicCast(FindWindow(ID_MapKW_Demo), wxCheckBox)->GetValue())
|
||||
m_MapSettingsKeywords.insert(L"demo");
|
||||
m_MapSettingsKeywords.insert("demo");
|
||||
else
|
||||
m_MapSettingsKeywords.erase(L"demo");
|
||||
m_MapSettingsKeywords.erase("demo");
|
||||
|
||||
if (wxDynamicCast(FindWindow(ID_MapKW_Naval), wxCheckBox)->GetValue())
|
||||
m_MapSettingsKeywords.insert(L"naval");
|
||||
m_MapSettingsKeywords.insert("naval");
|
||||
else
|
||||
m_MapSettingsKeywords.erase(L"naval");
|
||||
m_MapSettingsKeywords.erase("naval");
|
||||
|
||||
AtObj keywords;
|
||||
keywords.set("@array", L"");
|
||||
for (std::set<std::wstring>::iterator it = m_MapSettingsKeywords.begin(); it != m_MapSettingsKeywords.end(); ++it)
|
||||
keywords.add("item", it->c_str());
|
||||
keywords.set("@array", "");
|
||||
for (const std::string& keyword : m_MapSettingsKeywords)
|
||||
keywords.add("item", keyword.c_str());
|
||||
m_MapSettings.set("Keywords", keywords);
|
||||
}
|
||||
|
||||
@ -447,11 +447,7 @@ void MapSidebar::OnFirstDisplay()
|
||||
AtObj sizes = AtlasObject::LoadFromJSON(*qrySizes.sizes);
|
||||
wxChoice* sizeChoice = wxDynamicCast(FindWindow(ID_RandomSize), wxChoice);
|
||||
for (AtIter s = sizes["Data"]["item"]; s.defined(); ++s)
|
||||
{
|
||||
long tiles = 0;
|
||||
wxString(s["Tiles"]).ToLong(&tiles);
|
||||
sizeChoice->Append(wxString(s["Name"]), (void*)(intptr_t)tiles);
|
||||
}
|
||||
sizeChoice->Append(wxString::FromUTF8(s["Name"]), reinterpret_cast<void*>((*s["Tiles"]).getLong()));
|
||||
sizeChoice->SetSelection(0);
|
||||
|
||||
// Load the RMS script list
|
||||
@ -463,7 +459,7 @@ void MapSidebar::OnFirstDisplay()
|
||||
for (size_t i = 0; i < scripts.size(); ++i)
|
||||
{
|
||||
AtObj data = AtlasObject::LoadFromJSON(scripts[i]);
|
||||
wxString name(data["settings"]["Name"]);
|
||||
wxString name = wxString::FromUTF8(data["settings"]["Name"]);
|
||||
if (!name.IsEmpty())
|
||||
scriptChoice->Append(name, new AtObjClientData(*data["settings"]));
|
||||
}
|
||||
@ -616,7 +612,7 @@ void MapSidebar::OnRandomGenerate(wxCommandEvent& WXUNUSED(evt))
|
||||
wxBusyInfo busy(_("Generating map"));
|
||||
wxBusyCursor busyc;
|
||||
|
||||
wxString scriptName(settings["Script"]);
|
||||
wxString scriptName = wxString::FromUTF8(settings["Script"]);
|
||||
|
||||
// Copy the old map settings, so we don't lose them if the map generation fails
|
||||
AtObj oldSettings = settings;
|
||||
@ -627,7 +623,7 @@ void MapSidebar::OnRandomGenerate(wxCommandEvent& WXUNUSED(evt))
|
||||
if (qry.status < 0)
|
||||
{
|
||||
// Display error message and revert to old map settings
|
||||
wxLogError(_("Random map script '%ls' failed"), scriptName.wc_str());
|
||||
wxLogError(_("Random map script '%s' failed"), scriptName.c_str());
|
||||
m_MapSettingsCtrl->SetMapSettings(oldSettings);
|
||||
}
|
||||
|
||||
|
@ -99,8 +99,8 @@ struct ObjectSidebarImpl
|
||||
{
|
||||
ObjectSidebarImpl(ScenarioEditor& scenarioEditor) :
|
||||
m_ObjectListBox(NULL), m_ActorViewerActive(false),
|
||||
m_ActorViewerEntity(_T("actor|structures/fndn_1x1.xml")),
|
||||
m_ActorViewerAnimation(_T("idle")), m_ActorViewerSpeed(0.f),
|
||||
m_ActorViewerEntity(L"actor|structures/fndn_1x1.xml"),
|
||||
m_ActorViewerAnimation("idle"), m_ActorViewerSpeed(0.f),
|
||||
m_ObjectSettings(scenarioEditor.GetObjectSettings())
|
||||
{
|
||||
}
|
||||
@ -110,14 +110,14 @@ struct ObjectSidebarImpl
|
||||
ObservableScopedConnection m_ToolConn;
|
||||
|
||||
bool m_ActorViewerActive;
|
||||
wxString m_ActorViewerEntity;
|
||||
wxString m_ActorViewerAnimation;
|
||||
std::wstring m_ActorViewerEntity;
|
||||
std::string m_ActorViewerAnimation;
|
||||
float m_ActorViewerSpeed;
|
||||
Observable<ObjectSettings>& m_ObjectSettings;
|
||||
|
||||
void ActorViewerPostToGame()
|
||||
{
|
||||
POST_MESSAGE(SetActorViewer, ((std::wstring)m_ActorViewerEntity.wc_str(), (std::wstring)m_ActorViewerAnimation.wc_str(), m_ObjectSettings.GetPlayerID(), m_ActorViewerSpeed, false));
|
||||
POST_MESSAGE(SetActorViewer, (m_ActorViewerEntity.c_str(), m_ActorViewerAnimation.c_str(), m_ObjectSettings.GetPlayerID(), m_ActorViewerSpeed, false));
|
||||
}
|
||||
};
|
||||
|
||||
@ -545,7 +545,7 @@ void ObjectBottomBar::OnFirstDisplay()
|
||||
AtObj playerData = AtlasObject::LoadFromJSON(*qryPlayers.defaults);
|
||||
AtObj playerDefs = *playerData["PlayerData"];
|
||||
for (AtIter iterator = playerDefs["item"]; iterator.defined(); ++iterator)
|
||||
players.Add(wxString(iterator["Name"]));
|
||||
players.Add(wxString::FromUTF8(iterator["Name"]));
|
||||
|
||||
wxDynamicCast(FindWindow(ID_PlayerSelect), PlayerComboBox)->SetPlayers(players);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -587,8 +587,8 @@ void PlayerSettingsControl::CreateWidgets()
|
||||
for (size_t i = 0; i < civData.size(); ++i)
|
||||
{
|
||||
AtObj civ = AtlasObject::LoadFromJSON(civData[i]);
|
||||
civNames.Add(wxString(civ["Name"]));
|
||||
civCodes.Add(wxString(civ["Code"]));
|
||||
civNames.Add(wxString::FromUTF8(civ["Name"]));
|
||||
civCodes.Add(wxString::FromUTF8(civ["Code"]));
|
||||
}
|
||||
|
||||
// Load AI data
|
||||
@ -598,7 +598,7 @@ void PlayerSettingsControl::CreateWidgets()
|
||||
AtObj aiData = AtlasObject::LoadFromJSON(*qryAI.data);
|
||||
for (AtIter a = aiData["AIData"]["item"]; a.defined(); ++a)
|
||||
{
|
||||
ais.Add(new AIData(wxString(a["id"]), wxString(a["data"]["name"])));
|
||||
ais.Add(new AIData(wxString::FromUTF8(a["id"]), wxString::FromUTF8(a["data"]["name"])));
|
||||
}
|
||||
|
||||
// Create player pages
|
||||
@ -695,21 +695,17 @@ void PlayerSettingsControl::ReadFromEngine()
|
||||
wxString name(_("Unknown"));
|
||||
bool defined = player["Name"].defined();
|
||||
if (defined)
|
||||
name = wxString(player["Name"]);
|
||||
name = wxString::FromUTF8(player["Name"]);
|
||||
else if (playerDefs["Name"].defined())
|
||||
name = wxString(playerDefs["Name"]);
|
||||
name = wxString::FromUTF8(playerDefs["Name"]);
|
||||
|
||||
controls.name->SetValue(name);
|
||||
wxDynamicCast(FindWindowById(ID_DefaultName, controls.page), DefaultCheckbox)->SetValue(defined);
|
||||
|
||||
// civ
|
||||
wxChoice* choice = controls.civ;
|
||||
wxString civCode;
|
||||
defined = player["Civ"].defined();
|
||||
if (defined)
|
||||
civCode = wxString(player["Civ"]);
|
||||
else
|
||||
civCode = wxString(playerDefs["Civ"]);
|
||||
wxString civCode = wxString::FromUTF8(defined ? player["Civ"] : playerDefs["Civ"]);
|
||||
|
||||
for (size_t j = 0; j < choice->GetCount(); ++j)
|
||||
{
|
||||
@ -733,12 +729,8 @@ void PlayerSettingsControl::ReadFromEngine()
|
||||
wxDynamicCast(FindWindowById(ID_DefaultColor, controls.page), DefaultCheckbox)->SetValue(defined);
|
||||
|
||||
// player type
|
||||
wxString aiID;
|
||||
defined = player["AI"].defined();
|
||||
if (defined)
|
||||
aiID = wxString(player["AI"]);
|
||||
else
|
||||
aiID = wxString(playerDefs["AI"]);
|
||||
wxString aiID = wxString::FromUTF8(defined ? player["AI"] : playerDefs["AI"]);
|
||||
|
||||
choice = controls.ai;
|
||||
if (!aiID.empty())
|
||||
@ -762,28 +754,28 @@ void PlayerSettingsControl::ReadFromEngine()
|
||||
AtObj resObj = *player["Resources"];
|
||||
defined = resObj.defined() && resObj["food"].defined();
|
||||
if (defined)
|
||||
controls.food->SetValue(wxString(resObj["food"]));
|
||||
controls.food->SetValue((*resObj["food"]).getInt());
|
||||
else
|
||||
controls.food->SetValue(0);
|
||||
wxDynamicCast(FindWindowById(ID_DefaultFood, controls.page), DefaultCheckbox)->SetValue(defined);
|
||||
|
||||
defined = resObj.defined() && resObj["wood"].defined();
|
||||
if (defined)
|
||||
controls.wood->SetValue(wxString(resObj["wood"]));
|
||||
controls.wood->SetValue((*resObj["wood"]).getInt());
|
||||
else
|
||||
controls.wood->SetValue(0);
|
||||
wxDynamicCast(FindWindowById(ID_DefaultWood, controls.page), DefaultCheckbox)->SetValue(defined);
|
||||
|
||||
defined = resObj.defined() && resObj["metal"].defined();
|
||||
if (defined)
|
||||
controls.metal->SetValue(wxString(resObj["metal"]));
|
||||
controls.metal->SetValue((*resObj["metal"]).getInt());
|
||||
else
|
||||
controls.metal->SetValue(0);
|
||||
wxDynamicCast(FindWindowById(ID_DefaultMetal, controls.page), DefaultCheckbox)->SetValue(defined);
|
||||
|
||||
defined = resObj.defined() && resObj["stone"].defined();
|
||||
if (defined)
|
||||
controls.stone->SetValue(wxString(resObj["stone"]));
|
||||
controls.stone->SetValue((*resObj["stone"]).getInt());
|
||||
else
|
||||
controls.stone->SetValue(0);
|
||||
wxDynamicCast(FindWindowById(ID_DefaultStone, controls.page), DefaultCheckbox)->SetValue(defined);
|
||||
@ -791,7 +783,7 @@ void PlayerSettingsControl::ReadFromEngine()
|
||||
// population limit
|
||||
defined = player["PopulationLimit"].defined();
|
||||
if (defined)
|
||||
controls.pop->SetValue(wxString(player["PopulationLimit"]));
|
||||
controls.pop->SetValue((*player["PopulationLimit"]).getInt());
|
||||
else
|
||||
controls.pop->SetValue(0);
|
||||
wxDynamicCast(FindWindowById(ID_DefaultPop, controls.page), DefaultCheckbox)->SetValue(defined);
|
||||
@ -842,7 +834,7 @@ AtObj PlayerSettingsControl::UpdateSettingsObject()
|
||||
{
|
||||
// Update player data in the map settings
|
||||
AtObj players;
|
||||
players.set("@array", L"");
|
||||
players.set("@array", "");
|
||||
|
||||
wxASSERT(m_NumPlayers <= MAX_NUM_PLAYERS);
|
||||
|
||||
@ -859,7 +851,7 @@ AtObj PlayerSettingsControl::UpdateSettingsObject()
|
||||
// name
|
||||
wxTextCtrl* text = controls.name;
|
||||
if (text->IsEnabled())
|
||||
player.set("Name", text->GetValue());
|
||||
player.set("Name", text->GetValue().utf8_str());
|
||||
|
||||
// civ
|
||||
wxChoice* choice = controls.civ;
|
||||
@ -893,7 +885,7 @@ AtObj PlayerSettingsControl::UpdateSettingsObject()
|
||||
player.set("AI", str->GetData());
|
||||
}
|
||||
else // human
|
||||
player.set("AI", _T(""));
|
||||
player.set("AI", _(""));
|
||||
}
|
||||
|
||||
// resources
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -294,10 +294,8 @@ void TerrainSidebar::OnResizeMap(wxCommandEvent& WXUNUSED(evt))
|
||||
AtObj sizes = AtlasObject::LoadFromJSON(*qrySizes.sizes);
|
||||
for (AtIter s = sizes["Data"]["item"]; s.defined(); ++s)
|
||||
{
|
||||
long tiles = 0;
|
||||
wxString(s["Tiles"]).ToLong(&tiles);
|
||||
sizeNames.Add(wxString(s["Name"]));
|
||||
sizeTiles.push_back((size_t)tiles);
|
||||
sizeNames.Add(wxString::FromUTF8(s["Name"]));
|
||||
sizeTiles.push_back((*s["Tiles"]).getLong());
|
||||
}
|
||||
|
||||
// TODO: set default based on current map size
|
||||
|
@ -77,7 +77,7 @@ public:
|
||||
|
||||
entity_id_t Entity;
|
||||
CStrW CurrentUnitID;
|
||||
CStrW CurrentUnitAnim;
|
||||
CStr CurrentUnitAnim;
|
||||
float CurrentSpeed;
|
||||
bool WalkEnabled;
|
||||
bool GroundEnabled;
|
||||
@ -328,7 +328,7 @@ void ActorViewer::UnloadObjects()
|
||||
m.ObjectManager.UnloadObjects();
|
||||
}
|
||||
|
||||
void ActorViewer::SetActor(const CStrW& name, const CStrW& animation, player_id_t playerID)
|
||||
void ActorViewer::SetActor(const CStrW& name, const CStr& animation, player_id_t playerID)
|
||||
{
|
||||
bool needsAnimReload = false;
|
||||
|
||||
@ -376,7 +376,7 @@ void ActorViewer::SetActor(const CStrW& name, const CStrW& animation, player_id_
|
||||
|
||||
if (needsAnimReload)
|
||||
{
|
||||
CStr anim = animation.ToUTF8().LowerCase();
|
||||
CStr anim = animation.LowerCase();
|
||||
|
||||
// Emulate the typical simulation animation behaviour
|
||||
float speed;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -35,7 +35,7 @@ public:
|
||||
|
||||
CSimulation2* GetSimulation2();
|
||||
entity_id_t GetEntity();
|
||||
void SetActor(const CStrW& id, const CStrW& animation, player_id_t playerID);
|
||||
void SetActor(const CStrW& id, const CStr& animation, player_id_t playerID);
|
||||
void SetEnabled(bool enabled);
|
||||
void UnloadObjects();
|
||||
void SetBackgroundColor(const SColor4ub& color);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -162,7 +162,7 @@ MESSAGEHANDLER(SetActorViewer)
|
||||
// alright.)
|
||||
// Should replace this with proper actor hot-loading system, or something.
|
||||
|
||||
AtlasView::GetView_Actor()->GetActorViewer().SetActor(L"", L"", -1);
|
||||
AtlasView::GetView_Actor()->GetActorViewer().SetActor(L"", "", -1);
|
||||
AtlasView::GetView_Actor()->GetActorViewer().UnloadObjects();
|
||||
// vfs_reload_changed_files();
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "graphics/Terrain.h"
|
||||
#include "graphics/Unit.h"
|
||||
#include "lib/ogl.h"
|
||||
#include "lib/utf8.h"
|
||||
#include "maths/MathUtil.h"
|
||||
#include "maths/Matrix3D.h"
|
||||
#include "ps/CLogger.h"
|
||||
@ -299,7 +300,7 @@ QUERYHANDLER(GetObjectMapSettings)
|
||||
}
|
||||
|
||||
const CStr& data = exampleFile.GetOutput();
|
||||
msg->xmldata = std::wstring(data.begin(), data.end());
|
||||
msg->xmldata = data.FromUTF8();
|
||||
}
|
||||
|
||||
|
||||
@ -417,9 +418,8 @@ MESSAGEHANDLER(ObjectPreviewToEntity)
|
||||
//I need to re create the objects finally delete preview objects
|
||||
for (entity_id_t ent : g_PreviewEntitiesID)
|
||||
{
|
||||
//Get template
|
||||
std::string templateName = cmpTemplateManager->GetCurrentTemplateName(ent);
|
||||
std::wstring wTemplateName(templateName.begin() + 8, templateName.end());
|
||||
//Get template name (without the "preview|" prefix)
|
||||
std::wstring wTemplateName = wstring_from_utf8(cmpTemplateManager->GetCurrentTemplateName(ent).substr(8));
|
||||
//Create new entity
|
||||
entity_id_t new_ent = g_Game->GetSimulation2()->AddEntity(wTemplateName);
|
||||
if (new_ent == INVALID_ENTITY)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2018 Wildfire Games.
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -393,7 +393,7 @@ COMMAND(CreateObject, NOMERGE,
|
||||
// (Use RenderEnable to make it visible.)
|
||||
MESSAGE(SetActorViewer,
|
||||
((std::wstring, id))
|
||||
((std::wstring, animation))
|
||||
((std::string, animation))
|
||||
((int, playerID))
|
||||
((float, speed))
|
||||
((bool, flushcache)) // true => unload all actor files before starting the preview (because we don't have proper hotloading yet)
|
||||
|
Loading…
Reference in New Issue
Block a user